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