1 /*
2 * Copyright 2017 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 "import_wrapped_key.h"
18 #include "macros.h"
19 #include "proto_utils.h"
20
21 #include <android-base/logging.h>
22
23 #include <openssl/bytestring.h>
24 #include <openssl/ec.h>
25 #include <openssl/evp.h>
26 #include <openssl/mem.h>
27 #include <openssl/rsa.h>
28 #include <openssl/pkcs8.h>
29
30 namespace android {
31 namespace hardware {
32 namespace keymaster {
33
34 // HAL
35 using ::android::hardware::keymaster::V4_0::Algorithm;
36 using ::android::hardware::keymaster::V4_0::BlockMode;
37 using ::android::hardware::keymaster::V4_0::Digest;
38 using ::android::hardware::keymaster::V4_0::EcCurve;
39 using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType;
40 using ::android::hardware::keymaster::V4_0::KeyFormat;
41 using ::android::hardware::keymaster::V4_0::KeyPurpose;
42 using ::android::hardware::keymaster::V4_0::PaddingMode;
43 using ::android::hardware::keymaster::V4_0::Tag;
44 using ::android::hardware::keymaster::V4_0::TagType;
45
46 // BoringSSL
47 using bssl::UniquePtr;
48
49 // std
50 using std::function;
51 using std::unique_ptr;
52
53 using parse_asn1_fn = function<ErrorCode(CBS *cbs, Tag tag,
54 ImportWrappedKeyRequest *request)>;
55
56 #define KM_WRAPPER_FORMAT_VERSION 0
57 #define KM_WRAPPER_GCM_IV_SIZE 12
58 #define KM_WRAPPER_GCM_TAG_SIZE 16
59 #define KM_WRAPPER_WRAPPED_AES_KEY_SIZE 32
60 #define KM_WRAPPER_WRAPPED_DES_KEY_SIZE 24
61 // TODO: update max once PKCS8 support is introduced.
62 #define KM_WRAPPER_WRAPPED_MAX_KEY_SIZE 32
63 #define KM_TAG_MASK 0x0FFFFFFF
64
65 // BoringSSL helpers.
CBS_get_optional_asn1_set(CBS * cbs,CBS * out,int * out_present,unsigned tag)66 static int CBS_get_optional_asn1_set(CBS *cbs, CBS *out, int *out_present,
67 unsigned tag) {
68 CBS child;
69 int present;
70 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
71 return 0;
72 }
73 if (present) {
74 if (!CBS_get_asn1(&child, out, CBS_ASN1_SET) ||
75 CBS_len(&child) != 0) {
76 return 0;
77 }
78 } else {
79 CBS_init(out, NULL, 0);
80 }
81 if (out_present) {
82 *out_present = present;
83 }
84 return 1;
85 }
86
CBS_get_optional_asn1_null(CBS * cbs,CBS * out,int * out_present,unsigned tag)87 static int CBS_get_optional_asn1_null(CBS *cbs, CBS *out, int *out_present,
88 unsigned tag) {
89 CBS child;
90 int present;
91 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
92 return 0;
93 }
94 if (present) {
95 if (!CBS_get_asn1(&child, out, CBS_ASN1_NULL) ||
96 CBS_len(&child) != 0) {
97 return 0;
98 }
99 } else {
100 CBS_init(out, NULL, 0);
101 }
102 if (out_present) {
103 *out_present = present;
104 }
105 return 1;
106 }
107
parse_asn1_set(CBS * auth,Tag tag,ImportWrappedKeyRequest * request)108 static ErrorCode parse_asn1_set(CBS *auth, Tag tag,
109 ImportWrappedKeyRequest *request)
110 {
111 CBS set;
112 int present;
113 if (!CBS_get_optional_asn1_set(
114 auth, &set, &present,
115 CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED |
116 (tag & 0x0fffffff))) {
117 return ErrorCode::INVALID_ARGUMENT;
118 }
119 if (!present) {
120 // This is optional parameter, so ok to be missing.
121 return ErrorCode::OK;
122 }
123 // TODO: are empty sets acceptable?
124
125 while (CBS_len(&set)) {
126 uint64_t val;
127 KeyParameter kp;
128 if (!CBS_get_asn1_uint64(&set, &val)) {
129 return ErrorCode::INVALID_ARGUMENT;
130 }
131
132 kp.tag = tag;
133 switch (tag) {
134 case Tag::PURPOSE:
135 kp.f.purpose = (KeyPurpose)val;
136 break;
137 case Tag::BLOCK_MODE:
138 kp.f.blockMode = (BlockMode)val;
139 break;
140 case Tag::DIGEST:
141 kp.f.digest = (Digest)val;
142 break;
143 case Tag::PADDING:
144 kp.f.paddingMode = (PaddingMode)val;
145 break;
146 case Tag::USER_SECURE_ID:
147 kp.f.longInteger = val;
148 break;
149 default:
150 return ErrorCode::INVALID_ARGUMENT;
151 }
152 nosapp::KeyParameter *param = request->mutable_params()->add_params();
153 if (key_parameter_to_pb(kp, param) != ErrorCode::OK) {
154 return ErrorCode::INVALID_ARGUMENT;
155 }
156 }
157
158 return ErrorCode::OK;
159 }
160
parse_asn1_integer(CBS * auth,Tag tag,ImportWrappedKeyRequest * request)161 static ErrorCode parse_asn1_integer(CBS *auth, Tag tag,
162 ImportWrappedKeyRequest *request)
163 {
164 uint64_t val;
165 if (!CBS_get_optional_asn1_uint64(
166 auth, &val,
167 CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED |
168 (tag & 0x0fffffff), (uint64_t)-1)) {
169 return ErrorCode::INVALID_ARGUMENT;
170 }
171 if (val == (uint64_t)-1) {
172 // This is optional parameter, so ok to be missing.
173 return ErrorCode::OK;
174 }
175
176 KeyParameter kp;
177 kp.tag = tag;
178 switch (tag) {
179 case Tag::ALGORITHM:
180 kp.f.algorithm = (Algorithm)val;
181 break;
182 case Tag::KEY_SIZE:
183 case Tag::MIN_MAC_LENGTH:
184 case Tag::RSA_PUBLIC_EXPONENT:
185 case Tag::MIN_SECONDS_BETWEEN_OPS:
186 case Tag::MAX_USES_PER_BOOT:
187 case Tag::AUTH_TIMEOUT:
188 if (val > UINT32_MAX) {
189 return ErrorCode::INVALID_ARGUMENT;
190 }
191 kp.f.integer = (uint32_t)val;
192 break;
193 case Tag::EC_CURVE:
194 kp.f.ecCurve = (EcCurve)val;
195 break;
196 case Tag::ACTIVE_DATETIME:
197 case Tag::ORIGINATION_EXPIRE_DATETIME:
198 case Tag::USAGE_EXPIRE_DATETIME:
199 case Tag::CREATION_DATETIME:
200 kp.f.longInteger = val;
201 break;
202 case Tag::USER_AUTH_TYPE:
203 kp.f.hardwareAuthenticatorType = (HardwareAuthenticatorType)val;
204 break;
205 default:
206 return ErrorCode::INVALID_ARGUMENT;
207 }
208
209 nosapp::KeyParameter *param = request->mutable_params()->add_params();
210 if (key_parameter_to_pb(kp, param) != ErrorCode::OK) {
211 return ErrorCode::INVALID_ARGUMENT;
212 }
213
214 return ErrorCode::OK;
215 }
216
parse_asn1_boolean(CBS * auth,Tag tag,ImportWrappedKeyRequest * request)217 static ErrorCode parse_asn1_boolean(CBS *auth, Tag tag,
218 ImportWrappedKeyRequest *request)
219 {
220 CBS null;
221 int present;
222 if (!CBS_get_optional_asn1_null(
223 auth, &null, &present,
224 CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED |
225 (tag & 0x0fffffff))) {
226 return ErrorCode::INVALID_ARGUMENT;
227 }
228 if (!present) {
229 // This is optional parameter, so ok to be missing.
230 return ErrorCode::OK;
231 }
232 if (CBS_len(&null) != 0) {
233 // NULL type should be empty.
234 return ErrorCode::INVALID_ARGUMENT;
235 }
236
237 KeyParameter kp;
238 kp.tag = tag;
239 switch (tag) {
240 case Tag::CALLER_NONCE:
241 case Tag::BOOTLOADER_ONLY:
242 case Tag::NO_AUTH_REQUIRED:
243 kp.f.boolValue = true;
244 break;
245 default:
246 return ErrorCode::INVALID_ARGUMENT;
247 }
248
249 nosapp::KeyParameter *param = request->mutable_params()->add_params();
250 if (key_parameter_to_pb(kp, param) != ErrorCode::OK) {
251 return ErrorCode::INVALID_ARGUMENT;
252 }
253
254 return ErrorCode::OK;
255 }
256
parse_asn1_octet_string(CBS * auth,Tag tag,ImportWrappedKeyRequest * request)257 static ErrorCode parse_asn1_octet_string(CBS *auth, Tag tag,
258 ImportWrappedKeyRequest *request)
259 {
260 CBS str;
261 int present;
262 if (!CBS_get_optional_asn1_octet_string(
263 auth, &str, &present,
264 CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED |
265 (tag & 0x0fffffff))) {
266 return ErrorCode::INVALID_ARGUMENT;
267 }
268 if (!present) {
269 // This is optional parameter, so ok to be missing.
270 return ErrorCode::OK;
271 }
272 if (CBS_len(&str) == 0) {
273 return ErrorCode::INVALID_ARGUMENT;
274 }
275
276 KeyParameter kp;
277 kp.tag = tag;
278 switch (tag) {
279 case Tag::APPLICATION_DATA:
280 case Tag::APPLICATION_ID:
281 kp.blob.setToExternal(
282 const_cast<uint8_t*>(CBS_data(&str)),
283 CBS_len(&str), false);
284 break;
285 default:
286 return ErrorCode::INVALID_ARGUMENT;
287 }
288
289 nosapp::KeyParameter *param = request->mutable_params()->add_params();
290 if (key_parameter_to_pb(kp, param) != ErrorCode::OK) {
291 return ErrorCode::INVALID_ARGUMENT;
292 }
293
294 return ErrorCode::OK;
295 }
296
import_wrapped_key_request(const hidl_vec<uint8_t> & wrappedKeyData,const hidl_vec<uint8_t> & wrappingKeyBlob,const hidl_vec<uint8_t> & maskingKey,ImportWrappedKeyRequest * request)297 ErrorCode import_wrapped_key_request(const hidl_vec<uint8_t>& wrappedKeyData,
298 const hidl_vec<uint8_t>& wrappingKeyBlob,
299 const hidl_vec<uint8_t>& maskingKey,
300 ImportWrappedKeyRequest *request)
301 {
302 /*
303 * Unwrap an ASN.1 DER wrapped key, as specified here:
304 * https://docs.google.com/document/d/165Jd6jumhOD2yB6MygKhqjOLuHm3YVZGTgFHmGc8HzA/edit#heading=h.ut6j2przg4ra
305 *
306 * AuthorizationList ::= SEQUENCE {
307 * purpose [1] EXPLICIT SET OF INTEGER OPTIONAL,
308 * algorithm [2] EXPLICIT INTEGER OPTIONAL,
309 * keySize [3] EXPLICIT INTEGER OPTIONAL,
310 * blockMode [4] EXPLICIT SET OF INTEGER OPTIONAL,
311 * digest [5] EXPLICIT SET OF INTEGER OPTIONAL,
312 * padding [6] EXPLICIT SET OF INTEGER OPTIONAL,
313 * callerNonce [7] EXPLICIT NULL OPTIONAL,
314 * minMacLength [8] EXPLICIT INTEGER OPTIONAL,
315 * ecCurve [10] EXPLICIT INTEGER OPTIONAL,
316 * rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL,
317 * includeUniqueId [202] EXPLICIT NULL OPTIONAL,
318 * blobUsageRequirements [301] EXPLICIT INTEGER OPTIONAL,
319 * bootloaderOnly [302] EXPLICIT NULL OPTIONAL,
320 * rollbackResistance [303] EXPLICIT NULL OPTIONAL,
321 * activeDateTime [400] EXPLICIT INTEGER OPTIONAL,
322 * originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL,
323 * usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL,
324 * minSecondsBetweenOps [403] EXPLICIT INTEGER OPTIONAL,
325 * maxUsesPerBoot [404] EXPLICIT INTEGER OPTIONAL,
326 * userSecureId [502] EXPLICIT SET OF INTEGER OPTIONAL,
327 * noAuthRequired [503] EXPLICIT NULL OPTIONAL,
328 * userAuthType [504] EXPLICIT INTEGER OPTIONAL,
329 * authTimeout [505] EXPLICIT INTEGER OPTIONAL,
330 * trustedUserPresenceReq [507] EXPLICIT NULL OPTIONAL,
331 * trustedConfirmationReq [508] EXPLICIT NULL OPTIONAL,
332 * unlockedDeviceReq [509] EXPLICIT NULL OPTIONAL,
333 * applicationId [601] EXPLICIT OCTET_STRING OPTIONAL,
334 * applicationData [700] EXPLICIT OCTET_STRING OPTIONAL,
335 * creationDateTime [701] EXPLICIT INTEGER OPTIONAL,
336 * }
337 *
338 * KeyDescription ::= SEQUENCE {
339 * keyFormat INTEGER,
340 * authorizationList AuthorizationList
341 * }
342 *
343 * SecureKeyWrapper ::= SEQUENCE {
344 * wrapperFormatVersion INTEGER,
345 * encryptedTransportKey OCTET_STRING,
346 * initializationVector OCTET_STRING,
347 * keyDescription KeyDescription,
348 * secureKey OCTET_STRING,
349 * tag OCTET_STRING,
350 * }
351 */
352
353 CBS cbs;
354 CBS child;
355 uint64_t wrapperFormatVersion;
356 CBS encryptedTransportKey;
357 CBS initializationVector;
358
359 CBS_init(&cbs, wrappedKeyData.data(), wrappedKeyData.size());
360 if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_SEQUENCE) ||
361 !CBS_get_asn1_uint64(&child, &wrapperFormatVersion)) {
362 LOG(ERROR) << "Failed to wrap outer sequence or wrapperFormatVersion";
363 return ErrorCode::INVALID_ARGUMENT;
364 }
365 if (wrapperFormatVersion != KM_WRAPPER_FORMAT_VERSION) {
366 LOG(ERROR) << "Invalid wrapper format version" << wrapperFormatVersion;
367 return ErrorCode::INVALID_ARGUMENT;
368 }
369 if (!CBS_get_asn1(&child, &encryptedTransportKey, CBS_ASN1_OCTETSTRING) ||
370 !CBS_get_asn1(&child, &initializationVector, CBS_ASN1_OCTETSTRING)) {
371 LOG(ERROR) <<
372 "Failed to parse encryptedTransportKey or initializationVector";
373 return ErrorCode::INVALID_ARGUMENT;
374 }
375
376 /* TODO: if the RSA key-size is known from the blob, use it to
377 * validate encryptedTransportKey (i.e. the RSA envelope) length.
378 */
379
380 if (CBS_len(&initializationVector) != KM_WRAPPER_GCM_IV_SIZE) {
381 LOG(ERROR) << "Invalid AAD length";
382 return ErrorCode::INVALID_ARGUMENT;
383 }
384
385 CBS aad;
386 if (!CBS_get_asn1_element(&child, &aad, CBS_ASN1_SEQUENCE)) {
387 LOG(ERROR) << "Failed to parse aad";
388 return ErrorCode::INVALID_ARGUMENT;
389 }
390 /* Assign over AAD before CBS gets consumed. */
391 request->set_aad(CBS_data(&aad), CBS_len(&aad));
392
393 CBS keyDescription;
394 if (!CBS_get_asn1(&aad, &keyDescription, CBS_ASN1_SEQUENCE)) {
395 LOG(ERROR) << "Failed to parse keyDescription";
396 return ErrorCode::INVALID_ARGUMENT;
397 }
398
399 uint64_t keyFormat;
400 if (!CBS_get_asn1_uint64(&keyDescription, &keyFormat)) {
401 LOG(ERROR) << "Failed to parse keyFormat";
402 return ErrorCode::INVALID_ARGUMENT;
403 }
404
405 CBS authorizationList;
406 if (!CBS_get_asn1(&keyDescription, &authorizationList, CBS_ASN1_SEQUENCE) ||
407 CBS_len(&keyDescription) != 0) {
408 LOG(ERROR) << "Failed to parse keyDescription, remaining length: "
409 << CBS_len(&keyDescription);
410 return ErrorCode::INVALID_ARGUMENT;
411 }
412
413 struct tag_parser_entry {
414 Tag tag;
415 const parse_asn1_fn fn;
416 };
417 const struct tag_parser_entry parser_table[] = {
418 {Tag::PURPOSE, parse_asn1_set},
419 {Tag::ALGORITHM, parse_asn1_integer},
420 {Tag::KEY_SIZE, parse_asn1_integer},
421 {Tag::BLOCK_MODE, parse_asn1_set},
422 {Tag::DIGEST, parse_asn1_set},
423 {Tag::PADDING, parse_asn1_set},
424 {Tag::CALLER_NONCE, parse_asn1_boolean},
425 {Tag::MIN_MAC_LENGTH, parse_asn1_integer},
426 {Tag::EC_CURVE, parse_asn1_integer},
427 {Tag::RSA_PUBLIC_EXPONENT, parse_asn1_integer},
428 {Tag::INCLUDE_UNIQUE_ID, parse_asn1_boolean},
429 {Tag::BLOB_USAGE_REQUIREMENTS, parse_asn1_integer},
430 {Tag::BOOTLOADER_ONLY, parse_asn1_boolean},
431 {Tag::ROLLBACK_RESISTANCE, parse_asn1_boolean},
432 {Tag::ACTIVE_DATETIME, parse_asn1_integer},
433 {Tag::ORIGINATION_EXPIRE_DATETIME, parse_asn1_integer},
434 {Tag::USAGE_EXPIRE_DATETIME, parse_asn1_integer},
435 {Tag::MIN_SECONDS_BETWEEN_OPS, parse_asn1_integer},
436 {Tag::MAX_USES_PER_BOOT, parse_asn1_integer},
437 {Tag::USER_SECURE_ID, parse_asn1_set},
438 {Tag::NO_AUTH_REQUIRED, parse_asn1_boolean},
439 {Tag::USER_AUTH_TYPE, parse_asn1_integer},
440 {Tag::AUTH_TIMEOUT, parse_asn1_integer},
441 {Tag::TRUSTED_USER_PRESENCE_REQUIRED, parse_asn1_boolean},
442 {Tag::TRUSTED_CONFIRMATION_REQUIRED, parse_asn1_boolean},
443 {Tag::UNLOCKED_DEVICE_REQUIRED, parse_asn1_boolean},
444 {Tag::APPLICATION_ID, parse_asn1_octet_string},
445 {Tag::APPLICATION_DATA, parse_asn1_octet_string},
446 {Tag::CREATION_DATETIME, parse_asn1_octet_string},
447 };
448
449 for (size_t i = 0; i < ARRAYSIZE(parser_table); i++) {
450 const struct tag_parser_entry *entry = &parser_table[i];
451
452 if (entry->fn(&authorizationList, entry->tag, request)
453 != ErrorCode::OK) {
454 LOG(ERROR) <<
455 "ImportWrappedKey authorization list parse failure: tag: "
456 << (uint32_t)entry->tag;
457 return ErrorCode::INVALID_ARGUMENT;
458 }
459 }
460
461 if (CBS_len(&authorizationList) != 0) {
462 LOG(ERROR) << "Authorization list not fully consumed, "
463 << CBS_len(&authorizationList)
464 << " bytes remaining";
465 return ErrorCode::INVALID_ARGUMENT;
466 }
467
468 CBS secureKey;
469 CBS tag;
470 if (!CBS_get_asn1(&child, &secureKey, CBS_ASN1_OCTETSTRING)) {
471 LOG(ERROR) << "Failed to parse secure key";
472 return ErrorCode::INVALID_ARGUMENT;
473 }
474
475 // TODO: check that the wrapped key size matches the algorithm.
476 if (CBS_len(&secureKey) > KM_WRAPPER_WRAPPED_MAX_KEY_SIZE) {
477 LOG(ERROR) << "Secure key len exceeded: "
478 << KM_WRAPPER_WRAPPED_MAX_KEY_SIZE
479 << " got: "
480 << CBS_len(&secureKey);
481 return ErrorCode::INVALID_ARGUMENT;
482 }
483
484 if (!CBS_get_asn1(&child, &tag, CBS_ASN1_OCTETSTRING)) {
485 LOG(ERROR) << "Failed to parse gcm tag";
486 return ErrorCode::INVALID_ARGUMENT;
487 }
488 if (CBS_len(&tag) != KM_WRAPPER_GCM_TAG_SIZE) {
489 LOG(ERROR) << "GCM tag len, expected: "
490 << KM_WRAPPER_GCM_TAG_SIZE
491 << " got: "
492 << CBS_len(&tag);
493 return ErrorCode::INVALID_ARGUMENT;
494 }
495
496 request->set_key_format(keyFormat);
497 request->set_rsa_envelope(CBS_data(&encryptedTransportKey),
498 CBS_len(&encryptedTransportKey));
499 request->set_initialization_vector(CBS_data(&initializationVector),
500 CBS_len(&initializationVector));
501 request->set_encrypted_import_key(CBS_data(&secureKey),
502 CBS_len(&secureKey));
503 request->set_gcm_tag(CBS_data(&tag), CBS_len(&tag));
504 request->mutable_wrapping_key_blob()->set_blob(wrappingKeyBlob.data(),
505 wrappingKeyBlob.size());
506
507 request->set_masking_key(maskingKey.data(), maskingKey.size());
508
509 return ErrorCode::OK;
510 }
511
512 } // namespace keymaster
513 } // hardware
514 } // android
515