blob: fd8e7769ea58ef188e9d0b0ee771f58b697c6329 [file] [log] [blame]
Jiyong Parka7266ac2021-05-17 21:57:24 +09001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andrew Scull2e6ab792022-01-30 16:04:08 +000016#include <aidl/android/security/dice/IDiceNode.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090017#include <aidl/com/android/microdroid/testservice/BnTestService.h>
Inseob Kimdb319702022-01-20 13:12:43 +090018#include <android-base/file.h>
Inseob Kim691df6a2022-01-20 12:54:30 +090019#include <android-base/properties.h>
Andrew Scull11cf0902021-06-22 12:08:10 +000020#include <android-base/result.h>
Andrew Scull66616612021-06-17 16:41:03 +000021#include <android/binder_auto_utils.h>
22#include <android/binder_manager.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090023#include <fcntl.h>
Inseob Kimdb319702022-01-20 13:12:43 +090024#include <fsverity_digests.pb.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090025#include <linux/vm_sockets.h>
26#include <stdint.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090027#include <stdio.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090028#include <sys/ioctl.h>
Jiyong Park23934392021-06-16 01:59:10 +090029#include <sys/system_properties.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090030#include <unistd.h>
31
32#include <binder_rpc_unstable.hpp>
Inseob Kim691df6a2022-01-20 12:54:30 +090033#include <string>
Jiyong Parka7266ac2021-05-17 21:57:24 +090034
Alice Wangfb46ee12022-09-30 13:08:52 +000035#include "vm_payload.h"
36
Andrew Scull2e6ab792022-01-30 16:04:08 +000037using aidl::android::hardware::security::dice::BccHandover;
38using aidl::android::security::dice::IDiceNode;
39
Inseob Kim06a64d62021-09-07 21:21:45 +090040using android::base::ErrnoError;
Andrew Scull11cf0902021-06-22 12:08:10 +000041using android::base::Error;
42using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000043
Jiyong Parkfe5b28e2021-06-24 00:19:02 +090044extern void testlib_sub();
45
Andrew Scull66616612021-06-17 16:41:03 +000046namespace {
47
Andrew Scull11cf0902021-06-22 12:08:10 +000048template <typename T>
Andrew Sculledbe75e2021-07-06 10:44:31 +000049Result<T> report_test(std::string name, Result<T> result) {
Andrew Scull11cf0902021-06-22 12:08:10 +000050 auto property = "debug.microdroid.test." + name;
51 std::stringstream outcome;
52 if (result.ok()) {
53 outcome << "PASS";
54 } else {
55 outcome << "FAIL: " << result.error();
Inseob Kimdb319702022-01-20 13:12:43 +090056 // Pollute stderr with the error in case the property is truncated.
57 std::cerr << "[" << name << "] test failed: " << result.error() << "\n";
Andrew Scull11cf0902021-06-22 12:08:10 +000058 }
59 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Sculledbe75e2021-07-06 10:44:31 +000060 return result;
Andrew Scull66616612021-06-17 16:41:03 +000061}
62
Inseob Kim06a64d62021-09-07 21:21:45 +090063Result<void> start_test_service() {
64 class TestService : public aidl::com::android::microdroid::testservice::BnTestService {
65 ndk::ScopedAStatus addInteger(int32_t a, int32_t b, int32_t* out) override {
66 *out = a + b;
67 return ndk::ScopedAStatus::ok();
68 }
Inseob Kim691df6a2022-01-20 12:54:30 +090069
70 ndk::ScopedAStatus readProperty(const std::string& prop, std::string* out) override {
71 *out = android::base::GetProperty(prop, "");
72 if (out->empty()) {
73 std::string msg = "cannot find property " + prop;
74 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
75 msg.c_str());
76 }
77
78 return ndk::ScopedAStatus::ok();
79 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000080
Andrew Scull1f6ca352022-02-20 22:51:12 +000081 ndk::ScopedAStatus insecurelyExposeSealingCdi(std::vector<uint8_t>* out) override {
Andrew Scull2e6ab792022-01-30 16:04:08 +000082 ndk::SpAIBinder binder(AServiceManager_getService("android.security.dice.IDiceNode"));
83 auto service = IDiceNode::fromBinder(binder);
84 if (service == nullptr) {
85 return ndk::ScopedAStatus::
86 fromServiceSpecificErrorWithMessage(0, "Failed to find diced");
87 }
88 BccHandover handover;
89 auto deriveStatus = service->derive({}, &handover);
90 if (!deriveStatus.isOk()) {
91 return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(0,
92 "Failed call diced");
93 }
94 *out = {handover.cdiSeal.begin(), handover.cdiSeal.end()};
95 return ndk::ScopedAStatus::ok();
96 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000097
98 ndk::ScopedAStatus insecurelyExposeAttestationCdi(std::vector<uint8_t>* out) override {
99 ndk::SpAIBinder binder(AServiceManager_getService("android.security.dice.IDiceNode"));
100 auto service = IDiceNode::fromBinder(binder);
101 if (service == nullptr) {
102 return ndk::ScopedAStatus::
103 fromServiceSpecificErrorWithMessage(0, "Failed to find diced");
104 }
105 BccHandover handover;
106 auto deriveStatus = service->derive({}, &handover);
107 if (!deriveStatus.isOk()) {
108 return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(0,
109 "Failed call diced");
110 }
111 *out = {handover.cdiAttest.begin(), handover.cdiAttest.end()};
112 return ndk::ScopedAStatus::ok();
113 }
Andrew Scull61892082022-02-21 00:07:25 +0000114
115 ndk::ScopedAStatus getBcc(std::vector<uint8_t>* out) override {
116 ndk::SpAIBinder binder(AServiceManager_getService("android.security.dice.IDiceNode"));
117 auto service = IDiceNode::fromBinder(binder);
118 if (service == nullptr) {
119 return ndk::ScopedAStatus::
120 fromServiceSpecificErrorWithMessage(0, "Failed to find diced");
121 }
122 BccHandover handover;
123 auto deriveStatus = service->derive({}, &handover);
124 if (!deriveStatus.isOk()) {
125 return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(0,
126 "Failed call diced");
127 }
128 *out = {handover.bcc.data.begin(), handover.bcc.data.end()};
129 return ndk::ScopedAStatus::ok();
130 }
Inseob Kim06a64d62021-09-07 21:21:45 +0900131 };
132 auto testService = ndk::SharedRefBase::make<TestService>();
133
134 auto callback = []([[maybe_unused]] void* param) {
Alice Wangfb46ee12022-09-30 13:08:52 +0000135 if (!notify_payload_ready()) {
136 std::cerr << "failed to notify payload ready to virtualizationservice" << std::endl;
Alan Stokesb62de262022-05-12 17:11:53 +0100137 abort();
Inseob Kim06a64d62021-09-07 21:21:45 +0900138 }
139 };
Inseob Kim06a64d62021-09-07 21:21:45 +0900140 if (!RunRpcServerCallback(testService->asBinder().get(), testService->SERVICE_PORT, callback,
141 nullptr)) {
142 return Error() << "RPC Server failed to run";
143 }
144
145 return {};
146}
147
Inseob Kimdb319702022-01-20 13:12:43 +0900148Result<void> verify_apk() {
149 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
150
151 std::string str;
152 if (!android::base::ReadFileToString(path, &str)) {
153 return ErrnoError() << "failed to read build_manifest.pb";
154 }
155
156 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
157 return Error() << "invalid build_manifest.pb";
158 }
159
160 return {};
161}
162
Andrew Scull66616612021-06-17 16:41:03 +0000163} // Anonymous namespace
164
Jiyong Park40699612021-05-24 16:55:06 +0900165extern "C" int android_native_main(int argc, char* argv[]) {
Inseob Kim06a64d62021-09-07 21:21:45 +0900166 // disable buffering to communicate seamlessly
167 setvbuf(stdin, nullptr, _IONBF, 0);
168 setvbuf(stdout, nullptr, _IONBF, 0);
169 setvbuf(stderr, nullptr, _IONBF, 0);
170
Inseob Kim3fe420c2022-07-13 17:20:58 +0900171 if (strcmp(argv[1], "crash") == 0) {
172 printf("test crash!!!!\n");
173 abort();
174 }
175
Jiyong Park40699612021-05-24 16:55:06 +0900176 printf("Hello Microdroid ");
177 for (int i = 0; i < argc; i++) {
178 printf("%s", argv[i]);
179 bool last = i == (argc - 1);
180 if (!last) {
181 printf(" ");
182 }
183 }
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900184 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900185 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900186
Inseob Kimdb319702022-01-20 13:12:43 +0900187 // Extra apks may be missing; this is not a fatal error
188 report_test("extra_apk", verify_apk());
189
Jiyong Park23934392021-06-16 01:59:10 +0900190 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000191
Inseob Kim06a64d62021-09-07 21:21:45 +0900192 if (auto res = start_test_service(); res.ok()) {
193 return 0;
194 } else {
Alan Stokesb62de262022-05-12 17:11:53 +0100195 std::cerr << "starting service failed: " << res.error() << "\n";
Inseob Kim06a64d62021-09-07 21:21:45 +0900196 return 1;
197 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900198}