blob: 76df5be76abe35bc01d83c6b0db47230bd850013 [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/android/system/virtualmachineservice/IVirtualMachineService.h>
18#include <aidl/com/android/microdroid/testservice/BnTestService.h>
Inseob Kimdb319702022-01-20 13:12:43 +090019#include <android-base/file.h>
Inseob Kim691df6a2022-01-20 12:54:30 +090020#include <android-base/properties.h>
Andrew Scull11cf0902021-06-22 12:08:10 +000021#include <android-base/result.h>
Andrew Scull66616612021-06-17 16:41:03 +000022#include <android/binder_auto_utils.h>
23#include <android/binder_manager.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090024#include <fcntl.h>
Inseob Kimdb319702022-01-20 13:12:43 +090025#include <fsverity_digests.pb.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090026#include <linux/vm_sockets.h>
27#include <stdint.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090028#include <stdio.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090029#include <sys/ioctl.h>
Jiyong Park23934392021-06-16 01:59:10 +090030#include <sys/system_properties.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090031#include <unistd.h>
32
33#include <binder_rpc_unstable.hpp>
Inseob Kim691df6a2022-01-20 12:54:30 +090034#include <string>
Jiyong Parka7266ac2021-05-17 21:57:24 +090035
Andrew Scull2e6ab792022-01-30 16:04:08 +000036using aidl::android::hardware::security::dice::BccHandover;
37using aidl::android::security::dice::IDiceNode;
38
Inseob Kim06a64d62021-09-07 21:21:45 +090039using aidl::android::system::virtualmachineservice::IVirtualMachineService;
40
41using android::base::ErrnoError;
Andrew Scull11cf0902021-06-22 12:08:10 +000042using android::base::Error;
43using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000044
Jiyong Parkfe5b28e2021-06-24 00:19:02 +090045extern void testlib_sub();
46
Andrew Scull66616612021-06-17 16:41:03 +000047namespace {
48
Andrew Scull11cf0902021-06-22 12:08:10 +000049template <typename T>
Andrew Sculledbe75e2021-07-06 10:44:31 +000050Result<T> report_test(std::string name, Result<T> result) {
Andrew Scull11cf0902021-06-22 12:08:10 +000051 auto property = "debug.microdroid.test." + name;
52 std::stringstream outcome;
53 if (result.ok()) {
54 outcome << "PASS";
55 } else {
56 outcome << "FAIL: " << result.error();
Inseob Kimdb319702022-01-20 13:12:43 +090057 // Pollute stderr with the error in case the property is truncated.
58 std::cerr << "[" << name << "] test failed: " << result.error() << "\n";
Andrew Scull11cf0902021-06-22 12:08:10 +000059 }
60 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Sculledbe75e2021-07-06 10:44:31 +000061 return result;
Andrew Scull66616612021-06-17 16:41:03 +000062}
63
Inseob Kim06a64d62021-09-07 21:21:45 +090064Result<void> start_test_service() {
65 class TestService : public aidl::com::android::microdroid::testservice::BnTestService {
66 ndk::ScopedAStatus addInteger(int32_t a, int32_t b, int32_t* out) override {
67 *out = a + b;
68 return ndk::ScopedAStatus::ok();
69 }
Inseob Kim691df6a2022-01-20 12:54:30 +090070
71 ndk::ScopedAStatus readProperty(const std::string& prop, std::string* out) override {
72 *out = android::base::GetProperty(prop, "");
73 if (out->empty()) {
74 std::string msg = "cannot find property " + prop;
75 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
76 msg.c_str());
77 }
78
79 return ndk::ScopedAStatus::ok();
80 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000081
Andrew Scull1f6ca352022-02-20 22:51:12 +000082 ndk::ScopedAStatus insecurelyExposeSealingCdi(std::vector<uint8_t>* out) override {
Andrew Scull2e6ab792022-01-30 16:04:08 +000083 ndk::SpAIBinder binder(AServiceManager_getService("android.security.dice.IDiceNode"));
84 auto service = IDiceNode::fromBinder(binder);
85 if (service == nullptr) {
86 return ndk::ScopedAStatus::
87 fromServiceSpecificErrorWithMessage(0, "Failed to find diced");
88 }
89 BccHandover handover;
90 auto deriveStatus = service->derive({}, &handover);
91 if (!deriveStatus.isOk()) {
92 return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(0,
93 "Failed call diced");
94 }
95 *out = {handover.cdiSeal.begin(), handover.cdiSeal.end()};
96 return ndk::ScopedAStatus::ok();
97 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000098
99 ndk::ScopedAStatus insecurelyExposeAttestationCdi(std::vector<uint8_t>* out) override {
100 ndk::SpAIBinder binder(AServiceManager_getService("android.security.dice.IDiceNode"));
101 auto service = IDiceNode::fromBinder(binder);
102 if (service == nullptr) {
103 return ndk::ScopedAStatus::
104 fromServiceSpecificErrorWithMessage(0, "Failed to find diced");
105 }
106 BccHandover handover;
107 auto deriveStatus = service->derive({}, &handover);
108 if (!deriveStatus.isOk()) {
109 return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(0,
110 "Failed call diced");
111 }
112 *out = {handover.cdiAttest.begin(), handover.cdiAttest.end()};
113 return ndk::ScopedAStatus::ok();
114 }
Inseob Kim06a64d62021-09-07 21:21:45 +0900115 };
116 auto testService = ndk::SharedRefBase::make<TestService>();
117
118 auto callback = []([[maybe_unused]] void* param) {
119 // Tell microdroid_manager that we're ready.
120 // Failing to notify is not a fatal error; the payload can continue.
121 ndk::SpAIBinder binder(
122 RpcClient(VMADDR_CID_HOST, IVirtualMachineService::VM_BINDER_SERVICE_PORT));
123 auto virtualMachineService = IVirtualMachineService::fromBinder(binder);
124 if (virtualMachineService == nullptr) {
125 std::cerr << "failed to connect VirtualMachineService";
126 return;
127 }
Inseob Kimc7d28c72021-10-25 14:28:10 +0000128 if (!virtualMachineService->notifyPayloadReady().isOk()) {
Inseob Kim06a64d62021-09-07 21:21:45 +0900129 std::cerr << "failed to notify payload ready to virtualizationservice";
130 }
131 };
132
133 if (!RunRpcServerCallback(testService->asBinder().get(), testService->SERVICE_PORT, callback,
134 nullptr)) {
135 return Error() << "RPC Server failed to run";
136 }
137
138 return {};
139}
140
Inseob Kimdb319702022-01-20 13:12:43 +0900141Result<void> verify_apk() {
142 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
143
144 std::string str;
145 if (!android::base::ReadFileToString(path, &str)) {
146 return ErrnoError() << "failed to read build_manifest.pb";
147 }
148
149 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
150 return Error() << "invalid build_manifest.pb";
151 }
152
153 return {};
154}
155
Andrew Scull66616612021-06-17 16:41:03 +0000156} // Anonymous namespace
157
Jiyong Park40699612021-05-24 16:55:06 +0900158extern "C" int android_native_main(int argc, char* argv[]) {
Inseob Kim06a64d62021-09-07 21:21:45 +0900159 // disable buffering to communicate seamlessly
160 setvbuf(stdin, nullptr, _IONBF, 0);
161 setvbuf(stdout, nullptr, _IONBF, 0);
162 setvbuf(stderr, nullptr, _IONBF, 0);
163
Jiyong Park40699612021-05-24 16:55:06 +0900164 printf("Hello Microdroid ");
165 for (int i = 0; i < argc; i++) {
166 printf("%s", argv[i]);
167 bool last = i == (argc - 1);
168 if (!last) {
169 printf(" ");
170 }
171 }
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900172 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900173 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900174
Inseob Kimdb319702022-01-20 13:12:43 +0900175 // Extra apks may be missing; this is not a fatal error
176 report_test("extra_apk", verify_apk());
177
Jiyong Park23934392021-06-16 01:59:10 +0900178 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000179
Inseob Kim06a64d62021-09-07 21:21:45 +0900180 if (auto res = start_test_service(); res.ok()) {
181 return 0;
182 } else {
183 std::cerr << "starting service failed: " << res.error();
184 return 1;
185 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900186}