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