blob: bda5dbeafbccc1df011f585b6d4db84002763028 [file] [log] [blame]
Shawn Willden0cb69422015-05-26 08:31:37 -06001/*
2 * Copyright 2015 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 <keymaster/soft_keymaster_context.h>
18
Shawn Willden2beb6282015-05-20 16:36:24 -060019#include <memory>
Shawn Willden0cb69422015-05-26 08:31:37 -060020#include <time.h>
21
22#include <openssl/aes.h>
23#include <openssl/rand.h>
24#include <openssl/sha.h>
25
26#include <keymaster/android_keymaster_utils.h>
27#include <keymaster/logger.h>
28
29#include "aes_key.h"
30#include "auth_encrypted_key_blob.h"
Shawn Willden6270aca2015-05-26 13:12:24 -060031#include "ec_keymaster0_key.h"
Shawn Willden0cb69422015-05-26 08:31:37 -060032#include "hmac_key.h"
Shawn Willden6270aca2015-05-26 13:12:24 -060033#include "integrity_assured_key_blob.h"
Shawn Willden2beb6282015-05-20 16:36:24 -060034#include "keymaster0_engine.h"
Shawn Willden0cb69422015-05-26 08:31:37 -060035#include "ocb_utils.h"
36#include "openssl_err.h"
Shawn Willden2beb6282015-05-20 16:36:24 -060037#include "rsa_keymaster0_key.h"
Shawn Willden2beb6282015-05-20 16:36:24 -060038
39using std::unique_ptr;
Shawn Willden0cb69422015-05-26 08:31:37 -060040
41namespace keymaster {
42
43namespace {
44static uint8_t master_key_bytes[AES_BLOCK_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
45const int NONCE_LENGTH = 12;
46const int TAG_LENGTH = 16;
47const KeymasterKeyBlob MASTER_KEY(master_key_bytes, array_length(master_key_bytes));
48} // anonymous namespace
49
Shawn Willden2beb6282015-05-20 16:36:24 -060050SoftKeymasterContext::SoftKeymasterContext(keymaster0_device_t* keymaster0_device) {
51 if (keymaster0_device && (keymaster0_device->flags & KEYMASTER_SOFTWARE_ONLY) == 0)
52 engine_.reset(new Keymaster0Engine(keymaster0_device));
Shawn Willden06298102015-05-25 23:12:48 -060053 rsa_factory_.reset(new RsaKeymaster0KeyFactory(this, engine_.get()));
54 ec_factory_.reset(new EcdsaKeymaster0KeyFactory(this, engine_.get()));
55 aes_factory_.reset(new AesKeyFactory(this));
56 hmac_factory_.reset(new HmacKeyFactory(this));
57}
58
59KeyFactory* SoftKeymasterContext::GetKeyFactory(keymaster_algorithm_t algorithm) const {
60 switch (algorithm) {
61 case KM_ALGORITHM_RSA:
62 return rsa_factory_.get();
63 case KM_ALGORITHM_EC:
64 return ec_factory_.get();
65 case KM_ALGORITHM_AES:
66 return aes_factory_.get();
67 case KM_ALGORITHM_HMAC:
68 return hmac_factory_.get();
69 default:
70 return nullptr;
71 }
72}
73
74static keymaster_algorithm_t supported_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC,
75 KM_ALGORITHM_AES, KM_ALGORITHM_HMAC};
76
77keymaster_algorithm_t*
78SoftKeymasterContext::GetSupportedAlgorithms(size_t* algorithms_count) const {
79 *algorithms_count = array_length(supported_algorithms);
80 return supported_algorithms;
81}
82
83OperationFactory* SoftKeymasterContext::GetOperationFactory(keymaster_algorithm_t algorithm,
84 keymaster_purpose_t purpose) const {
85 KeyFactory* key_factory = GetKeyFactory(algorithm);
86 if (!key_factory)
87 return nullptr;
88 return key_factory->GetOperationFactory(purpose);
Shawn Willden0cb69422015-05-26 08:31:37 -060089}
90
91static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
92 switch (err) {
93 case AuthorizationSet::OK:
94 return KM_ERROR_OK;
95 case AuthorizationSet::ALLOCATION_FAILURE:
96 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
97 case AuthorizationSet::MALFORMED_DATA:
98 return KM_ERROR_UNKNOWN_ERROR;
99 }
100 return KM_ERROR_OK;
101}
102
103static keymaster_error_t BuildHiddenAuthorizations(const AuthorizationSet& input_set,
104 AuthorizationSet* hidden) {
105 keymaster_blob_t entry;
106 if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
107 hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
108 if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
109 hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
110
111 keymaster_key_param_t root_of_trust;
112 root_of_trust.tag = KM_TAG_ROOT_OF_TRUST;
113 root_of_trust.blob.data = reinterpret_cast<const uint8_t*>("SW");
114 root_of_trust.blob.data_length = 2;
115 hidden->push_back(root_of_trust);
116
117 return TranslateAuthorizationSetError(hidden->is_valid());
118}
119
120static keymaster_error_t SetAuthorizations(const AuthorizationSet& key_description,
121 keymaster_key_origin_t origin,
122 AuthorizationSet* hw_enforced,
123 AuthorizationSet* sw_enforced) {
Shawn Willden0cb69422015-05-26 08:31:37 -0600124 sw_enforced->Clear();
Shawn Willden2beb6282015-05-20 16:36:24 -0600125
126 for (auto& entry : key_description) {
127 switch (entry.tag) {
Shawn Willden0cb69422015-05-26 08:31:37 -0600128 // These cannot be specified by the client.
129 case KM_TAG_ROOT_OF_TRUST:
130 case KM_TAG_ORIGIN:
131 LOG_E("Root of trust and origin tags may not be specified", 0);
132 return KM_ERROR_INVALID_TAG;
133
134 // These don't work.
135 case KM_TAG_ROLLBACK_RESISTANT:
136 LOG_E("KM_TAG_ROLLBACK_RESISTANT not supported", 0);
137 return KM_ERROR_UNSUPPORTED_TAG;
138
139 // These are hidden.
140 case KM_TAG_APPLICATION_ID:
141 case KM_TAG_APPLICATION_DATA:
142 break;
143
Shawn Willden2beb6282015-05-20 16:36:24 -0600144 // Everything else we just copy into sw_enforced, unless the KeyFactory has placed it in
145 // hw_enforced, in which case we defer to its decision.
Shawn Willden0cb69422015-05-26 08:31:37 -0600146 default:
Shawn Willden2beb6282015-05-20 16:36:24 -0600147 if (hw_enforced->GetTagCount(entry.tag) == 0)
148 sw_enforced->push_back(entry);
Shawn Willden0cb69422015-05-26 08:31:37 -0600149 break;
150 }
151 }
152
153 sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
154 sw_enforced->push_back(TAG_ORIGIN, origin);
155 return TranslateAuthorizationSetError(sw_enforced->is_valid());
156}
157
158keymaster_error_t SoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description,
159 const keymaster_key_origin_t origin,
160 const KeymasterKeyBlob& key_material,
161 KeymasterKeyBlob* blob,
162 AuthorizationSet* hw_enforced,
163 AuthorizationSet* sw_enforced) const {
Shawn Willden2beb6282015-05-20 16:36:24 -0600164 keymaster_error_t error = SetAuthorizations(key_description, origin, hw_enforced, sw_enforced);
Shawn Willden0cb69422015-05-26 08:31:37 -0600165 if (error != KM_ERROR_OK)
166 return error;
167
168 AuthorizationSet hidden;
169 error = BuildHiddenAuthorizations(key_description, &hidden);
170 if (error != KM_ERROR_OK)
171 return error;
172
Shawn Willden2beb6282015-05-20 16:36:24 -0600173 return SerializeIntegrityAssuredBlob(key_material, hidden, *hw_enforced, *sw_enforced, blob);
Shawn Willden0cb69422015-05-26 08:31:37 -0600174}
175
Shawn Willden2beb6282015-05-20 16:36:24 -0600176static keymaster_error_t ParseOcbAuthEncryptedBlob(const KeymasterKeyBlob& blob,
177 const AuthorizationSet& hidden,
178 KeymasterKeyBlob* key_material,
179 AuthorizationSet* hw_enforced,
180 AuthorizationSet* sw_enforced) {
Shawn Willden0cb69422015-05-26 08:31:37 -0600181 Buffer nonce, tag;
182 KeymasterKeyBlob encrypted_key_material;
183 keymaster_error_t error = DeserializeAuthEncryptedBlob(blob, &encrypted_key_material,
184 hw_enforced, sw_enforced, &nonce, &tag);
185 if (error != KM_ERROR_OK)
186 return error;
187
Shawn Willden0cb69422015-05-26 08:31:37 -0600188 if (nonce.available_read() != OCB_NONCE_LENGTH || tag.available_read() != OCB_TAG_LENGTH)
189 return KM_ERROR_INVALID_KEY_BLOB;
190
191 return OcbDecryptKey(*hw_enforced, *sw_enforced, hidden, MASTER_KEY, encrypted_key_material,
192 nonce, tag, key_material);
193}
194
Shawn Willden2beb6282015-05-20 16:36:24 -0600195// Note: This parsing code in below is from system/security/softkeymaster/keymaster_openssl.cpp's
196// unwrap_key function, modified for the preferred function signature and formatting. It does some
197// odd things, but they have been left unchanged to avoid breaking compatibility.
198static const uint8_t SOFT_KEY_MAGIC[] = {'P', 'K', '#', '8'};
199const uint64_t HUNDRED_YEARS = 1000LL * 60 * 60 * 24 * 365 * 100;
200static keymaster_error_t ParseOldSoftkeymasterBlob(const KeymasterKeyBlob& blob,
201 KeymasterKeyBlob* key_material,
202 AuthorizationSet* hw_enforced,
203 AuthorizationSet* sw_enforced) {
204 long publicLen = 0;
205 long privateLen = 0;
206 const uint8_t* p = blob.key_material;
207 const uint8_t* end = blob.key_material + blob.key_material_size;
208
209 int type = 0;
210 ptrdiff_t min_size =
211 sizeof(SOFT_KEY_MAGIC) + sizeof(type) + sizeof(publicLen) + 1 + sizeof(privateLen) + 1;
212 if (end - p < min_size) {
213 LOG_W("key blob appears to be truncated (if an old SW key)", 0);
214 return KM_ERROR_INVALID_KEY_BLOB;
215 }
216
217 if (memcmp(p, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC)) != 0)
218 return KM_ERROR_INVALID_KEY_BLOB;
219 p += sizeof(SOFT_KEY_MAGIC);
220
221 for (size_t i = 0; i < sizeof(type); i++)
222 type = (type << 8) | *p++;
223
224 for (size_t i = 0; i < sizeof(type); i++)
225 publicLen = (publicLen << 8) | *p++;
226
227 if (p + publicLen > end) {
228 LOG_W("public key length encoding error: size=%ld, end=%td", publicLen, end - p);
229 return KM_ERROR_INVALID_KEY_BLOB;
230 }
231 p += publicLen;
232
233 if (end - p < 2) {
234 LOG_W("key blob appears to be truncated (if an old SW key)", 0);
235 return KM_ERROR_INVALID_KEY_BLOB;
236 }
237
238 for (size_t i = 0; i < sizeof(type); i++)
239 privateLen = (privateLen << 8) | *p++;
240
241 if (p + privateLen > end) {
242 LOG_W("private key length encoding error: size=%ld, end=%td", privateLen, end - p);
243 return KM_ERROR_INVALID_KEY_BLOB;
244 }
245
246 // Just to be sure, make sure that the ASN.1 structure parses correctly. We don't actually use
247 // the EVP_PKEY here.
248 unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
249 if (pkey.get() == nullptr)
250 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
251
252 EVP_PKEY* tmp = pkey.get();
253 const uint8_t* key_start = p;
254 if (d2i_PrivateKey(type, &tmp, &p, privateLen) == NULL) {
255 LOG_W("Failed to parse PKCS#8 key material (if old SW key)", 0);
256 return KM_ERROR_INVALID_KEY_BLOB;
257 }
258
259 if (!key_material->Reset(privateLen))
260 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
261 memcpy(key_material->writable_data(), key_start, privateLen);
262
263 hw_enforced->Clear();
264 sw_enforced->Clear();
265
266 switch (type) {
267 case EVP_PKEY_RSA:
268 sw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
269 sw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
270 sw_enforced->push_back(TAG_PADDING, KM_PAD_NONE);
271 break;
272
273 case EVP_PKEY_EC:
274 sw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
275 sw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
276 break;
277
278 case EVP_PKEY_DSA:
279 return KM_ERROR_UNSUPPORTED_ALGORITHM;
280
281 default:
282 return KM_ERROR_INVALID_KEY_BLOB;
283 }
284
285 sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
286 sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
287 sw_enforced->push_back(TAG_ALL_USERS);
288 sw_enforced->push_back(TAG_NO_AUTH_REQUIRED);
289 uint64_t now = java_time(time(NULL));
290 sw_enforced->push_back(TAG_CREATION_DATETIME, now);
291 sw_enforced->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, now + HUNDRED_YEARS);
292 sw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
293 sw_enforced->push_back(TAG_PADDING, KM_PAD_NONE);
294
295 return KM_ERROR_OK;
296}
297
298keymaster_error_t SoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
299 const AuthorizationSet& additional_params,
300 KeymasterKeyBlob* key_material,
301 AuthorizationSet* hw_enforced,
302 AuthorizationSet* sw_enforced) const {
303 // This is a little bit complicated.
304 //
305 // The SoftKeymasterContext has to handle a lot of different kinds of key blobs.
306 //
307 // 1. New keymaster1 software key blobs. These are integrity-assured but not encrypted. The
308 // raw key material and auth sets should be extracted and returned. This is the kind
309 // produced by this context when the KeyFactory doesn't use keymaster0 to back the keys.
310 //
311 // 2. Old keymaster1 software key blobs. These are OCB-encrypted with an all-zero master key.
312 // They should be decrypted and the key material and auth sets extracted and returned.
313 //
314 // 3. Old keymaster0 software key blobs. These are raw key material with a small header tacked
315 // on the front. They don't have auth sets, so reasonable defaults are generated and
316 // returned along with the raw key material.
317 //
318 // 4. New keymaster0 hardware key blobs. These are integrity-assured but not encrypted (though
319 // they're protected by the keymaster0 hardware implementation). The keymaster0 key blob
320 // and auth sets should be extracted and returned.
321 //
322 // 5. Old keymaster0 hardware key blobs. These are raw hardware key blobs. They don't have
323 // auth sets so reasonable defaults are generated and returned along with the key blob.
324 //
325 // Determining what kind of blob has arrived is somewhat tricky. What helps is that
326 // integrity-assured and OCB-encrypted blobs are self-consistent and effectively impossible to
327 // parse as anything else. Old keymaster0 software key blobs have a header. It's reasonably
328 // unlikely that hardware keys would have the same header. So anything that is neither
329 // integrity-assured nor OCB-encrypted and lacks the old software key header is assumed to be
330 // keymaster0 hardware.
331
332 AuthorizationSet hidden;
333 keymaster_error_t error = BuildHiddenAuthorizations(additional_params, &hidden);
334 if (error != KM_ERROR_OK)
335 return error;
336
337 // Assume it's an integrity-assured blob (new software-only blob, or new keymaster0-backed
338 // blob).
339 error = DeserializeIntegrityAssuredBlob(blob, hidden, key_material, hw_enforced, sw_enforced);
340 if (error != KM_ERROR_INVALID_KEY_BLOB)
341 return error;
342
343 // Wasn't an integrity-assured blob. Maybe it's an OCB-encrypted blob.
344 error = ParseOcbAuthEncryptedBlob(blob, hidden, key_material, hw_enforced, sw_enforced);
345 if (error == KM_ERROR_OK)
346 LOG_D("Parsed an old keymaster1 software key", 0);
347 if (error != KM_ERROR_INVALID_KEY_BLOB)
348 return error;
349
350 // Wasn't an OCB-encrypted blob. Maybe it's an old softkeymaster blob.
351 error = ParseOldSoftkeymasterBlob(blob, key_material, hw_enforced, sw_enforced);
352 if (error == KM_ERROR_OK)
353 LOG_D("Parsed an old sofkeymaster key", 0);
354 if (error != KM_ERROR_INVALID_KEY_BLOB)
355 return error;
356
357 // Not an old softkeymaster blob, either. The only remaining option is old HW keymaster0.
358 if (!engine_)
359 return KM_ERROR_INVALID_KEY_BLOB;
360
361 // See if the HW thinks it's valid.
362 unique_ptr<EVP_PKEY, EVP_PKEY_Delete> tmp_key(engine_->GetKeymaster0PublicKey(blob));
363 if (!tmp_key)
364 return KM_ERROR_INVALID_KEY_BLOB;
365
366 *key_material = blob;
367 return KM_ERROR_OK;
368}
369
Shawn Willden0cb69422015-05-26 08:31:37 -0600370keymaster_error_t SoftKeymasterContext::AddRngEntropy(const uint8_t* buf, size_t length) const {
371 RAND_add(buf, length, 0 /* Don't assume any entropy is added to the pool. */);
372 return KM_ERROR_OK;
373}
374
375keymaster_error_t SoftKeymasterContext::GenerateRandom(uint8_t* buf, size_t length) const {
376 if (RAND_bytes(buf, length) != 1)
377 return KM_ERROR_UNKNOWN_ERROR;
378 return KM_ERROR_OK;
379}
380
381} // namespace keymaster