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