blob: 4e59c5837158d83f64a867f02cde15ffd56caad0 [file] [log] [blame]
Martijn Coenenba1c9dc2021-02-04 13:18:29 +01001/*
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 */
16
17#include <string>
18
19#include <android-base/file.h>
20#include <android-base/logging.h>
21#include <binder/IServiceManager.h>
22
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26
27#include "CertUtils.h"
28#include "KeyConstants.h"
29#include "KeystoreKey.h"
30
31using android::defaultServiceManager;
32using android::IServiceManager;
33using android::sp;
34using android::String16;
35
36using android::hardware::security::keymint::Algorithm;
37using android::hardware::security::keymint::Digest;
38using android::hardware::security::keymint::KeyParameter;
39using android::hardware::security::keymint::KeyParameterValue;
40using android::hardware::security::keymint::KeyPurpose;
41using android::hardware::security::keymint::PaddingMode;
42using android::hardware::security::keymint::SecurityLevel;
43using android::hardware::security::keymint::Tag;
44
45using android::system::keystore2::CreateOperationResponse;
46using android::system::keystore2::Domain;
47using android::system::keystore2::KeyDescriptor;
48using android::system::keystore2::KeyEntryResponse;
49using android::system::keystore2::KeyMetadata;
50
51using android::base::Error;
52using android::base::Result;
53
Martijn Coenen22da0522021-03-09 10:52:30 +010054// Keystore boot level that the odsign key uses
55static const int kOdsignBootLevel = 30;
56
Martijn Coenenba1c9dc2021-02-04 13:18:29 +010057static KeyDescriptor getKeyDescriptor() {
58 // AIDL parcelable objects don't have constructor
59 static KeyDescriptor descriptor;
60 static std::once_flag flag;
61 std::call_once(flag, [&]() {
62 descriptor.domain = Domain::SELINUX;
63 descriptor.alias = String16("ondevice-signing");
64 descriptor.nspace = 101; // odsign_key
65 });
66
67 return descriptor;
68}
69
70KeystoreKey::KeystoreKey() {}
71
72Result<KeyMetadata> KeystoreKey::createNewKey(const KeyDescriptor& descriptor) {
73 std::vector<KeyParameter> params;
74
75 KeyParameter algo;
76 algo.tag = Tag::ALGORITHM;
77 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
78 params.push_back(algo);
79
80 KeyParameter key_size;
81 key_size.tag = Tag::KEY_SIZE;
82 key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(kRsaKeySize);
83 params.push_back(key_size);
84
85 KeyParameter digest;
86 digest.tag = Tag::DIGEST;
87 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
88 params.push_back(digest);
89
90 KeyParameter padding;
91 padding.tag = Tag::PADDING;
92 padding.value =
93 KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
94 params.push_back(padding);
95
96 KeyParameter exponent;
97 exponent.tag = Tag::RSA_PUBLIC_EXPONENT;
98 exponent.value = KeyParameterValue::make<KeyParameterValue::longInteger>(kRsaKeyExponent);
99 params.push_back(exponent);
100
101 KeyParameter purpose;
102 purpose.tag = Tag::PURPOSE;
103 purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
104 params.push_back(purpose);
105
106 KeyParameter auth;
107 auth.tag = Tag::NO_AUTH_REQUIRED;
108 auth.value = KeyParameterValue::make<KeyParameterValue::boolValue>(true);
109 params.push_back(auth);
110
Martijn Coenen22da0522021-03-09 10:52:30 +0100111 KeyParameter boot_level;
112 boot_level.tag = Tag::MAX_BOOT_LEVEL;
113 boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(kOdsignBootLevel);
114 params.push_back(boot_level);
115
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100116 KeyMetadata metadata;
117 auto status = mSecurityLevel->generateKey(descriptor, {}, params, 0, {}, &metadata);
118 if (!status.isOk()) {
119 return Error() << "Failed to create new key";
120 }
121
122 return metadata;
123}
124
125bool KeystoreKey::initialize() {
126 sp<IServiceManager> sm = defaultServiceManager();
127 if (sm == nullptr) {
128 return false;
129 }
Janis Danisevskisf985e432021-03-22 15:12:58 -0700130 auto service = sm->getService(String16("android.system.keystore2.IKeystoreService/default"));
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100131 if (service == nullptr) {
132 return false;
133 }
134 mService = interface_cast<android::system::keystore2::IKeystoreService>(service);
135 if (mService == nullptr) {
136 return false;
137 }
138
139 auto status = mService->getSecurityLevel(SecurityLevel::STRONGBOX, &mSecurityLevel);
140 if (!status.isOk()) {
Martijn Coenen9b0630c2021-03-10 11:00:17 +0100141 status = mService->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &mSecurityLevel);
142 if (!status.isOk()) {
143 return false;
144 }
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100145 }
146
147 auto descriptor = getKeyDescriptor();
148 // See if we can fetch an existing key
149 KeyEntryResponse keyEntryResponse;
150 LOG(INFO) << "Trying to retrieve existing keystore key...";
151 status = mService->getKeyEntry(descriptor, &keyEntryResponse);
Martijn Coenen79985bd2021-04-16 10:36:00 +0200152 bool keyValid = false;
153
154 if (status.isOk()) {
155 // Make sure this is an early boot key
156 for (const auto& auth : keyEntryResponse.metadata.authorizations) {
157 if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
158 if (auth.keyParameter.value.get<KeyParameterValue::integer>() == kOdsignBootLevel) {
159 keyValid = true;
160 break;
161 }
162 }
163 }
164 if (!keyValid) {
165 LOG(WARNING) << "Found invalid keystore key without MAX_BOOT_LEVEL tag";
166 }
167 }
168
169 if (!keyValid) {
170 LOG(INFO) << "Existing keystore key not found or invalid, creating new key";
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100171 auto newKeyStatus = createNewKey(descriptor);
172 if (!newKeyStatus.ok()) {
173 LOG(ERROR) << "Failed to create new key";
174 return false;
175 }
176 mKeyMetadata = *newKeyStatus;
177 } else {
178 mKeyMetadata = keyEntryResponse.metadata;
179 }
180
181 LOG(ERROR) << "Initialized Keystore key.";
182 return true;
183}
184
185Result<SigningKey*> KeystoreKey::getInstance() {
186 static KeystoreKey keystoreKey;
187
188 if (!keystoreKey.initialize()) {
189 return Error() << "Failed to initialize keystore key.";
190 } else {
191 return &keystoreKey;
192 }
193}
194
195static std::vector<KeyParameter> getSignOpParameters() {
196 std::vector<KeyParameter> opParameters;
197
198 KeyParameter algo;
199 algo.tag = Tag::ALGORITHM;
200 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
201 opParameters.push_back(algo);
202
203 KeyParameter digest;
204 digest.tag = Tag::DIGEST;
205 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
206 opParameters.push_back(digest);
207
208 KeyParameter padding;
209 padding.tag = Tag::PADDING;
210 padding.value =
211 KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
212 opParameters.push_back(padding);
213
214 KeyParameter purpose;
215 purpose.tag = Tag::PURPOSE;
216 purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
217 opParameters.push_back(purpose);
218
219 return opParameters;
220}
221
222Result<std::string> KeystoreKey::sign(const std::string& message) const {
223 static auto opParameters = getSignOpParameters();
224
225 CreateOperationResponse opResponse;
226
227 auto status =
228 mSecurityLevel->createOperation(getKeyDescriptor(), opParameters, false, &opResponse);
229 if (!status.isOk()) {
230 return Error() << "Failed to create keystore signing operation: "
231 << status.serviceSpecificErrorCode();
232 }
233 auto operation = opResponse.iOperation;
234
235 std::optional<std::vector<uint8_t>> out;
236 status = operation->update({message.begin(), message.end()}, &out);
237 if (!status.isOk()) {
238 return Error() << "Failed to call keystore update operation.";
239 }
240
241 std::optional<std::vector<uint8_t>> signature;
242 status = operation->finish({}, {}, &signature);
243 if (!status.isOk()) {
244 return Error() << "Failed to call keystore finish operation.";
245 }
246
247 if (!signature.has_value()) {
248 return Error() << "Didn't receive a signature from keystore finish operation.";
249 }
250
251 std::string result{signature.value().begin(), signature.value().end()};
252
253 return result;
254}
255
256Result<std::vector<uint8_t>> KeystoreKey::getPublicKey() const {
A. Cody Schuffelenf74ca252021-04-08 20:58:04 -0700257 auto cert = mKeyMetadata.certificate;
258 if (cert) {
259 return extractPublicKeyFromX509(cert.value());
260 } else {
261 return Error() << "Key did not have a certificate";
262 }
Martijn Coenenba1c9dc2021-02-04 13:18:29 +0100263}