Home | History | Annotate | Download | only in keymaster
      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.
     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 
     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 
    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 
    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 
    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 
    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 
    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