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