• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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