blob: d43828a01472f6a7e35b57ad24ce90e2091dac3c [file] [log] [blame]
Martijn Coenen95194842020-09-24 16:56:46 +02001/*
2 * Copyright (C) 2020 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/logging.h>
20#include <keymasterV4_1/Keymaster.h>
21#include <keymasterV4_1/authorization_set.h>
22
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26
27#include "Keymaster.h"
28
29using AuthorizationSet = ::android::hardware::keymaster::V4_0::AuthorizationSet;
30using AuthorizationSetBuilder = ::android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
31using Digest = ::android::hardware::keymaster::V4_0::Digest;
32using ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
33using HardwareAuthToken = ::android::hardware::keymaster::V4_0::HardwareAuthToken;
34using HidlBuf = ::android::hardware::hidl_vec<uint8_t>;
35using KeyCharacteristics = ::android::hardware::keymaster::V4_0::KeyCharacteristics;
36using KeyFormat = ::android::hardware::keymaster::V4_0::KeyFormat;
37using KeyParameter = ::android::hardware::keymaster::V4_0::KeyParameter;
38using KeyPurpose = ::android::hardware::keymaster::V4_0::KeyPurpose;
39using KmSupport = ::android::hardware::keymaster::V4_1::support::Keymaster;
40using KmDevice = ::android::hardware::keymaster::V4_1::IKeymasterDevice;
41using OperationHandle = ::android::hardware::keymaster::V4_0::OperationHandle;
42using PaddingMode = ::android::hardware::keymaster::V4_0::PaddingMode;
43using VerificationToken = ::android::hardware::keymaster::V4_0::VerificationToken;
44
45using android::sp;
46using android::base::Error;
47using android::base::Result;
48using android::base::unique_fd;
49using android::hardware::hidl_vec;
50
51Keymaster::Keymaster() {}
52
53bool Keymaster::initialize() {
54 // TODO(b/165630556): Stop using Keymaster directly and migrate to keystore2
55 // (once available).
56 auto devices = KmSupport::enumerateAvailableDevices();
57 sp<KmDevice> devToUse = nullptr;
58 for (const auto& dev : devices) {
59 auto version = dev->halVersion();
60 if (version.majorVersion > 4 || (version.majorVersion == 4 && version.minorVersion >= 1)) {
61 // TODO we probably have a preference for the SE, hoping Keystore2 will provide this
62 LOG(INFO) << "Using keymaster " << version.keymasterName << " "
63 << (int)version.majorVersion << "." << (int)version.minorVersion;
64 devToUse = dev;
65 break;
66 }
67 }
68
69 mDevice = devToUse;
70
71 return true;
72}
73
74std::optional<Keymaster> Keymaster::getInstance() {
75 static Keymaster keymaster;
76
77 if (!keymaster.initialize()) {
78 return {};
79 } else {
80 return {keymaster};
81 }
82}
83
84Result<std::vector<uint8_t>> Keymaster::createKey() const {
85 ErrorCode error;
86 HidlBuf keyBlob;
87
88 auto params = AuthorizationSetBuilder()
89 .Authorization(::android::hardware::keymaster::V4_0::TAG_NO_AUTH_REQUIRED)
90 // TODO MAKE SURE WE ADD THE EARLY_BOOT_ONLY FLAG here
91 // currently doesn't work on cuttlefish (b/173618442)
92 //.Authorization(::android::hardware::keymaster::V4_1::TAG_EARLY_BOOT_ONLY)
93 .RsaSigningKey(2048, 65537)
94 .Digest(Digest::SHA_2_256)
95 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
96
97 mDevice->generateKey(params.hidl_data(), [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob,
98 const KeyCharacteristics&
99 /* hidl_key_characteristics */) {
100 error = hidl_error;
101 keyBlob = hidl_key_blob;
102 });
103
104 if (error != ErrorCode::OK) {
105 return Error() << "Error creating keymaster signing key: "
106 << static_cast<std::underlying_type<ErrorCode>::type>(error);
107 }
108
109 return keyBlob;
110}
111
112static ErrorCode Begin(const sp<KmDevice>& keymaster_, KeyPurpose purpose, const HidlBuf& key_blob,
113 const AuthorizationSet& in_params, AuthorizationSet* out_params,
114 OperationHandle* op_handle) {
115 ErrorCode error;
116 OperationHandle saved_handle = *op_handle;
117 CHECK(keymaster_
118 ->begin(purpose, key_blob, in_params.hidl_data(), HardwareAuthToken(),
119 [&](ErrorCode hidl_error, const hidl_vec<KeyParameter>& hidl_out_params,
120 uint64_t hidl_op_handle) {
121 error = hidl_error;
122 *out_params = hidl_out_params;
123 *op_handle = hidl_op_handle;
124 })
125 .isOk());
126 if (error != ErrorCode::OK) {
127 // Some implementations may modify *op_handle on error.
128 *op_handle = saved_handle;
129 }
130 return error;
131}
132
133static ErrorCode Update(const sp<KmDevice>& keymaster_, OperationHandle op_handle,
134 const AuthorizationSet& in_params, const std::string& input,
135 AuthorizationSet* out_params, std::string* output, size_t* input_consumed) {
136 ErrorCode error;
137 HidlBuf inputData(input.size());
138 memcpy(inputData.data(), input.c_str(), input.size());
139 CHECK(keymaster_
140 ->update(op_handle, in_params.hidl_data(), inputData, HardwareAuthToken(),
141 VerificationToken(),
142 [&](ErrorCode hidl_error, uint32_t hidl_input_consumed,
143 const hidl_vec<KeyParameter>& hidl_out_params,
144 const HidlBuf& hidl_output) {
145 error = hidl_error;
146 out_params->push_back(AuthorizationSet(hidl_out_params));
147 std::string retdata(reinterpret_cast<const char*>(hidl_output.data()),
148 hidl_output.size());
149 output->append(retdata);
150 *input_consumed = hidl_input_consumed;
151 })
152 .isOk());
153 return error;
154}
155
156static ErrorCode Finish(const sp<KmDevice>& keymaster_, OperationHandle op_handle,
157 const AuthorizationSet& in_params, const std::string& input,
158 const std::string& signature, AuthorizationSet* out_params,
159 std::string* output) {
160 ErrorCode error;
161 HidlBuf inputData(input.size());
162 memcpy(inputData.data(), input.c_str(), input.size());
163 HidlBuf signatureData(signature.size());
164 memcpy(signatureData.data(), signature.c_str(), signature.size());
165 // TODO still need to handle error -62 - key requires upgrade
166 CHECK(keymaster_
167 ->finish(op_handle, in_params.hidl_data(), inputData, signatureData,
168 HardwareAuthToken(), VerificationToken(),
169 [&](ErrorCode hidl_error, const hidl_vec<KeyParameter>& hidl_out_params,
170 const HidlBuf& hidl_output) {
171 error = hidl_error;
172 *out_params = hidl_out_params;
173 std::string retdata(reinterpret_cast<const char*>(hidl_output.data()),
174 hidl_output.size());
175 output->append(retdata);
176 })
177 .isOk());
178 return error;
179}
180
181static std::string ProcessMessage(const sp<KmDevice>& keymaster_, const HidlBuf& key_blob,
182 KeyPurpose operation, const std::string& message,
183 const AuthorizationSet& in_params, AuthorizationSet* out_params) {
184 AuthorizationSet begin_out_params;
185 OperationHandle op_handle_;
186 ErrorCode ec =
187 Begin(keymaster_, operation, key_blob, in_params, &begin_out_params, &op_handle_);
188
189 std::string output;
190 size_t consumed = 0;
191 AuthorizationSet update_params;
192 AuthorizationSet update_out_params;
193 ec = Update(keymaster_, op_handle_, update_params, message, &update_out_params, &output,
194 &consumed);
195
196 std::string unused;
197 AuthorizationSet finish_params;
198 AuthorizationSet finish_out_params;
199 ec = Finish(keymaster_, op_handle_, finish_params, message.substr(consumed), unused,
200 &finish_out_params, &output);
201
202 out_params->push_back(begin_out_params);
203 out_params->push_back(finish_out_params);
204 return output;
205}
206
207Result<std::vector<uint8_t>>
208Keymaster::extractPublicKey(const std::vector<uint8_t>& keyBlob) const {
209 std::vector<uint8_t> publicKey;
210 ErrorCode error;
211
212 mDevice->exportKey(KeyFormat::X509, keyBlob, {} /* clientId */, {} /* appData */,
213 [&](ErrorCode hidl_error, const HidlBuf& keyData) {
214 error = hidl_error;
215 publicKey = keyData;
216 });
217
218 if (error != ErrorCode::OK) {
219 return Error() << "Error extracting public key: "
220 << static_cast<std::underlying_type<ErrorCode>::type>(error);
221 }
222
223 return publicKey;
224}
225
226Result<KeymasterVerifyResult> Keymaster::verifyKey(const std::vector<uint8_t>& keyBlob) const {
227 ErrorCode error;
228 KeyCharacteristics characteristics;
229
230 mDevice->getKeyCharacteristics(
231 keyBlob, {} /* clientId */, {} /* appData */,
232 [&](ErrorCode hidl_error, const KeyCharacteristics& hidl_characteristics) {
233 error = hidl_error;
234 characteristics = hidl_characteristics;
235 });
236
237 if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
238 return KeymasterVerifyResult::UPGRADE;
239 }
240
241 if (error != ErrorCode::OK) {
242 return Error() << "Error getting key characteristics: "
243 << static_cast<std::underlying_type<ErrorCode>::type>(error);
244 }
245
246 // TODO(b/165630556)
247 // Verify this is an early boot key and the other key parameters
248 return KeymasterVerifyResult::OK;
249}
250
251Result<std::vector<uint8_t>> Keymaster::upgradeKey(const std::vector<uint8_t>& keyBlob) const {
252 ErrorCode error;
253 HidlBuf newKeyBlob;
254
255 // TODO deduplicate
256 auto params = AuthorizationSetBuilder()
257 .Authorization(::android::hardware::keymaster::V4_0::TAG_NO_AUTH_REQUIRED)
258 // TODO MAKE SURE WE ADD THE EARLY_BOOT_ONLY FLAG here
259 // currently doesn't work on cuttlefish (b/173618442)
260 //.Authorization(::android::hardware::keymaster::V4_1::TAG_EARLY_BOOT_ONLY)
261 .RsaSigningKey(2048, 65537)
262 .Digest(Digest::SHA_2_256)
263 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
264
265 mDevice->upgradeKey(keyBlob, params.hidl_data(),
266 [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob) {
267 error = hidl_error;
268 newKeyBlob = hidl_key_blob;
269 });
270
271 if (error != ErrorCode::OK) {
272 return Error() << "Error upgrading keymaster signing key: "
273 << static_cast<std::underlying_type<ErrorCode>::type>(error);
274 }
275
276 return newKeyBlob;
277}
278
279Result<std::string> Keymaster::sign(const std::vector<uint8_t>& keyBlob,
280 const std::string& message) const {
281 AuthorizationSet out_params;
282 auto params = AuthorizationSetBuilder()
283 .Digest(Digest::SHA_2_256)
284 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
285 std::string signature =
286 ProcessMessage(mDevice, keyBlob, KeyPurpose::SIGN, message, params, &out_params);
287 if (!out_params.empty()) {
288 return Error() << "Error signing key: expected empty out params.";
289 }
290 return signature;
291}