1 /*
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 "KeystoreHmacKey.h"
30
31 using android::sp;
32 using android::String16;
33
34 using android::hardware::security::keymint::Algorithm;
35 using android::hardware::security::keymint::Digest;
36 using android::hardware::security::keymint::KeyParameter;
37 using android::hardware::security::keymint::KeyParameterValue;
38 using android::hardware::security::keymint::KeyPurpose;
39 using android::hardware::security::keymint::Tag;
40
41 using android::system::keystore2::CreateOperationResponse;
42 using android::system::keystore2::Domain;
43 using android::system::keystore2::KeyDescriptor;
44 using android::system::keystore2::KeyEntryResponse;
45 using android::system::keystore2::KeyMetadata;
46
47 using android::base::Error;
48 using android::base::Result;
49
50 using android::base::unique_fd;
51
getHmacKeyDescriptor(const android::String16 & keyAlias,int64_t keyNspace)52 static KeyDescriptor getHmacKeyDescriptor(const android::String16& keyAlias, int64_t keyNspace) {
53 // AIDL parcelable objects don't have constructor
54 static KeyDescriptor descriptor;
55 static std::once_flag flag;
56 std::call_once(flag, [&]() {
57 descriptor.domain = Domain::SELINUX;
58 descriptor.alias = keyAlias + android::String16("-hmac");
59 descriptor.nspace = keyNspace;
60 });
61
62 return descriptor;
63 }
64
createKey()65 Result<void> KeystoreHmacKey::createKey() {
66 std::vector<KeyParameter> params;
67
68 KeyParameter algo;
69 algo.tag = Tag::ALGORITHM;
70 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
71 params.push_back(algo);
72
73 KeyParameter key_size;
74 key_size.tag = Tag::KEY_SIZE;
75 key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(kHmacKeySize);
76 params.push_back(key_size);
77
78 KeyParameter min_mac_length;
79 min_mac_length.tag = Tag::MIN_MAC_LENGTH;
80 min_mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
81 params.push_back(min_mac_length);
82
83 KeyParameter digest;
84 digest.tag = Tag::DIGEST;
85 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
86 params.push_back(digest);
87
88 KeyParameter purposeSign;
89 purposeSign.tag = Tag::PURPOSE;
90 purposeSign.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
91 params.push_back(purposeSign);
92
93 KeyParameter purposeVerify;
94 purposeVerify.tag = Tag::PURPOSE;
95 purposeVerify.value =
96 KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::VERIFY);
97 params.push_back(purposeVerify);
98
99 KeyParameter auth;
100 auth.tag = Tag::NO_AUTH_REQUIRED;
101 auth.value = KeyParameterValue::make<KeyParameterValue::boolValue>(true);
102 params.push_back(auth);
103
104 KeyParameter boot_level;
105 boot_level.tag = Tag::MAX_BOOT_LEVEL;
106 boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(mKeyBootLevel);
107 params.push_back(boot_level);
108
109 KeyMetadata metadata;
110 auto status = mSecurityLevel->generateKey(mDescriptor, {}, params, 0, {}, &metadata);
111 if (!status.isOk()) {
112 return Error() << "Failed to create new HMAC key: " << status;
113 }
114
115 return {};
116 }
117
initialize(sp<IKeystoreService> service,sp<IKeystoreSecurityLevel> securityLevel)118 Result<void> KeystoreHmacKey::initialize(sp<IKeystoreService> service,
119 sp<IKeystoreSecurityLevel> securityLevel) {
120 mService = std::move(service);
121 mSecurityLevel = std::move(securityLevel);
122
123 // See if we can fetch an existing key
124 KeyEntryResponse keyEntryResponse;
125 LOG(INFO) << "Trying to retrieve existing HMAC key...";
126 auto status = mService->getKeyEntry(mDescriptor, &keyEntryResponse);
127 bool keyValid = false;
128
129 if (status.isOk()) {
130 // Make sure this is an early boot key
131 for (const auto& auth : keyEntryResponse.metadata.authorizations) {
132 if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
133 if (auth.keyParameter.value.get<KeyParameterValue::integer>() == mKeyBootLevel) {
134 keyValid = true;
135 break;
136 }
137 }
138 }
139 if (!keyValid) {
140 LOG(WARNING) << "Found invalid HMAC key without MAX_BOOT_LEVEL tag";
141 }
142 }
143
144 if (!keyValid) {
145 LOG(INFO) << "Existing HMAC key not found or invalid, creating new key";
146 return createKey();
147 } else {
148 return {};
149 }
150 }
151
KeystoreHmacKey(const android::String16 & keyAlias,int64_t keyNspace,int keyBootLevel)152 KeystoreHmacKey::KeystoreHmacKey(const android::String16& keyAlias, int64_t keyNspace,
153 int keyBootLevel)
154 : mDescriptor(getHmacKeyDescriptor(keyAlias, keyNspace)), mKeyBootLevel(keyBootLevel) {}
155
getVerifyOpParameters()156 static std::vector<KeyParameter> getVerifyOpParameters() {
157 std::vector<KeyParameter> opParameters;
158
159 KeyParameter algo;
160 algo.tag = Tag::ALGORITHM;
161 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
162 opParameters.push_back(algo);
163
164 KeyParameter digest;
165 digest.tag = Tag::DIGEST;
166 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
167 opParameters.push_back(digest);
168
169 KeyParameter purpose;
170 purpose.tag = Tag::PURPOSE;
171 purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::VERIFY);
172 opParameters.push_back(purpose);
173
174 return opParameters;
175 }
176
getSignOpParameters()177 static std::vector<KeyParameter> getSignOpParameters() {
178 std::vector<KeyParameter> opParameters;
179
180 KeyParameter algo;
181 algo.tag = Tag::ALGORITHM;
182 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
183 opParameters.push_back(algo);
184
185 KeyParameter mac_length;
186 mac_length.tag = Tag::MAC_LENGTH;
187 mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
188 opParameters.push_back(mac_length);
189
190 KeyParameter digest;
191 digest.tag = Tag::DIGEST;
192 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
193 opParameters.push_back(digest);
194
195 KeyParameter purpose;
196 purpose.tag = Tag::PURPOSE;
197 purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
198 opParameters.push_back(purpose);
199
200 return opParameters;
201 }
202
sign(const std::string & message) const203 Result<std::string> KeystoreHmacKey::sign(const std::string& message) const {
204 CreateOperationResponse opResponse;
205 static auto params = getSignOpParameters();
206
207 auto status = mSecurityLevel->createOperation(mDescriptor, params, false, &opResponse);
208 if (!status.isOk()) {
209 return Error() << "Failed to create keystore signing operation: " << status;
210 }
211 auto operation = opResponse.iOperation;
212
213 std::optional<std::vector<uint8_t>> out;
214 status = operation->update({message.begin(), message.end()}, &out);
215 if (!status.isOk()) {
216 return Error() << "Failed to call keystore update operation.";
217 }
218
219 std::optional<std::vector<uint8_t>> signature;
220 status = operation->finish({}, {}, &signature);
221 if (!status.isOk()) {
222 return Error() << "Failed to call keystore finish operation.";
223 }
224
225 if (!signature.has_value()) {
226 return Error() << "Didn't receive a signature from keystore finish operation.";
227 }
228
229 return std::string{signature.value().begin(), signature.value().end()};
230 }
231
verify(const std::string & message,const std::string & signature) const232 Result<void> KeystoreHmacKey::verify(const std::string& message,
233 const std::string& signature) const {
234 CreateOperationResponse opResponse;
235 static auto params = getVerifyOpParameters();
236
237 auto status = mSecurityLevel->createOperation(mDescriptor, params, false, &opResponse);
238 if (!status.isOk()) {
239 return Error() << "Failed to create keystore verification operation: " << status;
240 }
241 auto operation = opResponse.iOperation;
242
243 std::optional<std::vector<uint8_t>> out;
244 status = operation->update({message.begin(), message.end()}, &out);
245 if (!status.isOk()) {
246 return Error() << "Failed to call keystore update operation.";
247 }
248
249 std::optional<std::vector<uint8_t>> out_signature;
250 std::vector<uint8_t> in_signature{signature.begin(), signature.end()};
251 status = operation->finish({}, in_signature, &out_signature);
252 if (!status.isOk()) {
253 return Error() << "Failed to call keystore finish operation.";
254 }
255
256 return {};
257 }
258
deleteKey() const259 Result<void> KeystoreHmacKey::deleteKey() const {
260 auto status = mService->deleteKey(mDescriptor);
261 if (!status.isOk()) {
262 return Error() << "Failed to delete HMAC key: " << status;
263 }
264
265 return {};
266 }
267