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