blob: 5510ae1363f3fb448fb6007464fca01a361cda38 [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 Scull66616612021-06-17 16:41:03 +000016#include <aidl/android/system/keystore2/IKeystoreService.h>
Andrew Scull11cf0902021-06-22 12:08:10 +000017#include <android-base/result.h>
Andrew Scull66616612021-06-17 16:41:03 +000018#include <android/binder_auto_utils.h>
19#include <android/binder_manager.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090020#include <stdio.h>
Jiyong Park23934392021-06-16 01:59:10 +090021#include <sys/system_properties.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090022
Andrew Scull11cf0902021-06-22 12:08:10 +000023using aidl::android::hardware::security::keymint::Algorithm;
24using aidl::android::hardware::security::keymint::Digest;
25using aidl::android::hardware::security::keymint::KeyParameter;
26using aidl::android::hardware::security::keymint::KeyParameterValue;
27using aidl::android::hardware::security::keymint::KeyPurpose;
Andrew Scull66616612021-06-17 16:41:03 +000028using aidl::android::hardware::security::keymint::SecurityLevel;
Andrew Scull11cf0902021-06-22 12:08:10 +000029using aidl::android::hardware::security::keymint::Tag;
Andrew Scull66616612021-06-17 16:41:03 +000030
Andrew Scull11cf0902021-06-22 12:08:10 +000031using aidl::android::system::keystore2::CreateOperationResponse;
32using aidl::android::system::keystore2::Domain;
Andrew Scull66616612021-06-17 16:41:03 +000033using aidl::android::system::keystore2::IKeystoreSecurityLevel;
34using aidl::android::system::keystore2::IKeystoreService;
Andrew Scull11cf0902021-06-22 12:08:10 +000035using aidl::android::system::keystore2::KeyDescriptor;
36using aidl::android::system::keystore2::KeyMetadata;
37
38using android::base::Error;
39using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000040
41namespace {
42
Andrew Scull11cf0902021-06-22 12:08:10 +000043Result<void> test_keystore() {
44 // Connect to Keystore.
Andrew Scull66616612021-06-17 16:41:03 +000045 ndk::SpAIBinder binder(
46 AServiceManager_getService("android.system.keystore2.IKeystoreService/default"));
47 auto service = IKeystoreService::fromBinder(binder);
48 if (service == nullptr) {
Andrew Scull11cf0902021-06-22 12:08:10 +000049 return Error() << "Failed to find Keystore";
Andrew Scull66616612021-06-17 16:41:03 +000050 }
51 std::shared_ptr<IKeystoreSecurityLevel> securityLevel;
52 auto status = service->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &securityLevel);
53 if (!status.isOk()) {
Andrew Scull11cf0902021-06-22 12:08:10 +000054 return Error() << "Failed to get security level";
Andrew Scull66616612021-06-17 16:41:03 +000055 }
Andrew Scull11cf0902021-06-22 12:08:10 +000056
57 // Create a signing key.
58 std::vector<KeyParameter> params;
59
60 KeyParameter algo;
61 algo.tag = Tag::ALGORITHM;
62 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
63 params.push_back(algo);
64
65 KeyParameter key_size;
66 key_size.tag = Tag::KEY_SIZE;
67 key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
68 params.push_back(key_size);
69
70 KeyParameter min_mac_length;
71 min_mac_length.tag = Tag::MIN_MAC_LENGTH;
72 min_mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
73 params.push_back(min_mac_length);
74
75 KeyParameter digest;
76 digest.tag = Tag::DIGEST;
77 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
78 params.push_back(digest);
79
80 KeyParameter purposeSign;
81 purposeSign.tag = Tag::PURPOSE;
82 purposeSign.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
83 params.push_back(purposeSign);
84
85 KeyParameter purposeVerify;
86 purposeVerify.tag = Tag::PURPOSE;
87 purposeVerify.value =
88 KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::VERIFY);
89 params.push_back(purposeVerify);
90
91 KeyParameter auth;
92 auth.tag = Tag::NO_AUTH_REQUIRED;
93 auth.value = KeyParameterValue::make<KeyParameterValue::boolValue>(true);
94 params.push_back(auth);
95
96 KeyDescriptor descriptor;
97 descriptor.domain = Domain::SELINUX;
98 descriptor.alias = "payload-test-key";
99 descriptor.nspace = 140; // vm_payload_key
100
101 KeyMetadata metadata;
102 status = securityLevel->generateKey(descriptor, {}, params, 0, {}, &metadata);
103 if (!status.isOk()) {
104 return Error() << "Failed to create new HMAC key";
105 }
106
107 // Sign something.
108 params.clear();
109 params.push_back(algo);
110 params.push_back(digest);
111 params.push_back(purposeSign);
112
113 KeyParameter mac_length;
114 mac_length.tag = Tag::MAC_LENGTH;
115 mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
116 params.push_back(mac_length);
117
118 CreateOperationResponse opResponse;
119 status = securityLevel->createOperation(descriptor, params, false, &opResponse);
120 if (!status.isOk()) {
121 return Error() << "Failed to create keystore signing operation: "
122 << status.getServiceSpecificError();
123 }
124 auto operation = opResponse.iOperation;
125
126 std::string message = "This is the message to sign";
127 std::optional<std::vector<uint8_t>> out;
128 status = operation->update({message.begin(), message.end()}, &out);
129 if (!status.isOk()) {
130 return Error() << "Failed to call keystore update operation.";
131 }
132
133 std::optional<std::vector<uint8_t>> signature;
134 status = operation->finish({}, {}, &signature);
135 if (!status.isOk()) {
136 return Error() << "Failed to call keystore finish operation.";
137 }
138
139 if (!signature.has_value()) {
140 return Error() << "Didn't receive a signature from keystore finish operation.";
141 }
142
143 // Verify the signature.
144 params.clear();
145 params.push_back(algo);
146 params.push_back(digest);
147 params.push_back(purposeVerify);
148
149 status = securityLevel->createOperation(descriptor, params, false, &opResponse);
150 if (!status.isOk()) {
151 return Error() << "Failed to create keystore verification operation: "
152 << status.getServiceSpecificError();
153 }
154 operation = opResponse.iOperation;
155
156 status = operation->update({message.begin(), message.end()}, &out);
157 if (!status.isOk()) {
158 return Error() << "Failed to call keystore update operation.";
159 }
160
161 std::optional<std::vector<uint8_t>> out_signature;
162 status = operation->finish({}, signature.value(), &out_signature);
163 if (!status.isOk()) {
164 return Error() << "Failed to call keystore finish operation.";
165 }
166
167 return {};
168}
169
170template <typename T>
171void report_test(std::string name, Result<T> result) {
172 auto property = "debug.microdroid.test." + name;
173 std::stringstream outcome;
174 if (result.ok()) {
175 outcome << "PASS";
176 } else {
177 outcome << "FAIL: " << result.error();
178 // Pollute stdout with the error in case the property is truncated.
179 std::cout << "[" << name << "] test failed: " << result.error() << "\n";
180 }
181 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Scull66616612021-06-17 16:41:03 +0000182}
183
184} // Anonymous namespace
185
Jiyong Park40699612021-05-24 16:55:06 +0900186extern "C" int android_native_main(int argc, char* argv[]) {
187 printf("Hello Microdroid ");
188 for (int i = 0; i < argc; i++) {
189 printf("%s", argv[i]);
190 bool last = i == (argc - 1);
191 if (!last) {
192 printf(" ");
193 }
194 }
195 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900196
197 __system_property_set("debug.microdroid.app.run", "true");
Andrew Scull11cf0902021-06-22 12:08:10 +0000198 report_test("keystore", test_keystore());
Jiyong Park40699612021-05-24 16:55:06 +0900199 return 0;
Jiyong Parka7266ac2021-05-17 21:57:24 +0900200}