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 "atap_ops.h" 18 #include "atap_util.h" 19 #include "libatap.h" 20 21 static uint8_t session_shared_secret[ATAP_ECDH_SHARED_SECRET_LEN]; 22 static uint8_t session_key[ATAP_AES_128_KEY_LEN]; 23 static AtapOperation operation; 24 25 static AtapResult auth_key_signature_generate( 26 AtapOps* ops, 27 uint8_t device_pubkey[ATAP_ECDH_KEY_LEN], 28 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN], 29 uint8_t** signature, 30 uint32_t* signature_len) { 31 AtapResult ret = 0; 32 uint8_t nonce[ATAP_NONCE_LEN]; 33 *signature = (uint8_t*)atap_malloc(ATAP_SIGNATURE_LEN_MAX); 34 if (*signature == NULL) { 35 return ATAP_RESULT_ERROR_OOM; 36 } 37 /* deriving nonce uses same HKDF as deriving session key */ 38 ret = derive_session_key(ops, 39 device_pubkey, 40 ca_pubkey, 41 session_shared_secret, 42 "SIGN", 43 nonce, 44 ATAP_NONCE_LEN); 45 if (ret != ATAP_RESULT_OK) { 46 return ret; 47 } 48 return ops->auth_key_sign( 49 ops, nonce, ATAP_NONCE_LEN, *signature, signature_len); 50 } 51 52 static AtapResult read_available_public_keys( 53 AtapOps* ops, AtapInnerCaRequest* inner_ca_request) { 54 AtapResult ret = 0; 55 56 inner_ca_request->RSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX); 57 inner_ca_request->RSA_pubkey.data_length = ATAP_KEY_LEN_MAX; 58 inner_ca_request->ECDSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX); 59 inner_ca_request->ECDSA_pubkey.data_length = ATAP_KEY_LEN_MAX; 60 inner_ca_request->edDSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX); 61 inner_ca_request->edDSA_pubkey.data_length = ATAP_KEY_LEN_MAX; 62 63 if (inner_ca_request->RSA_pubkey.data == NULL || 64 inner_ca_request->ECDSA_pubkey.data == NULL || 65 inner_ca_request->edDSA_pubkey.data == NULL) { 66 return ATAP_RESULT_ERROR_OOM; 67 } 68 ret = ops->read_attestation_public_key( 69 ops, 70 ATAP_KEY_TYPE_RSA, 71 inner_ca_request->RSA_pubkey.data, 72 &inner_ca_request->RSA_pubkey.data_length); 73 if (ret != ATAP_RESULT_OK) { 74 return ret; 75 } 76 ret = ops->read_attestation_public_key( 77 ops, 78 ATAP_KEY_TYPE_ECDSA, 79 inner_ca_request->ECDSA_pubkey.data, 80 &inner_ca_request->ECDSA_pubkey.data_length); 81 if (ret != ATAP_RESULT_OK) { 82 return ret; 83 } 84 ret = ops->read_attestation_public_key( 85 ops, 86 ATAP_KEY_TYPE_edDSA, 87 inner_ca_request->edDSA_pubkey.data, 88 &inner_ca_request->edDSA_pubkey.data_length); 89 /* edDSA support is not required in the initial version */ 90 if (ret == ATAP_RESULT_ERROR_UNSUPPORTED_OPERATION) { 91 atap_free(inner_ca_request->edDSA_pubkey.data); 92 inner_ca_request->edDSA_pubkey.data = NULL; 93 inner_ca_request->edDSA_pubkey.data_length = 0; 94 ret = ATAP_RESULT_OK; 95 } 96 return ret; 97 } 98 99 static AtapResult initialize_session(AtapOps* ops, 100 const uint8_t* operation_start, 101 uint32_t operation_start_size, 102 AtapKeyType* auth_key_type, 103 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN], 104 AtapCaRequest* ca_request, 105 AtapInnerCaRequest* inner_ca_request) { 106 uint32_t message_length = 0; 107 AtapCurveType curve_type = 0; 108 AtapResult ret = 0; 109 uint8_t* buf_ptr = (uint8_t*)operation_start + 4; 110 111 atap_memset(ca_request, 0, sizeof(AtapCaRequest)); 112 atap_memset(inner_ca_request, 0, sizeof(AtapInnerCaRequest)); 113 114 if (operation_start_size != ATAP_OPERATION_START_LEN) { 115 return ATAP_RESULT_ERROR_INVALID_INPUT; 116 } 117 if (operation_start[0] != ATAP_PROTOCOL_VERSION) { 118 return ATAP_RESULT_ERROR_INVALID_INPUT; 119 } 120 copy_uint32_from_buf(&buf_ptr, &message_length); 121 if (message_length != ATAP_ECDH_KEY_LEN + 2) { 122 return ATAP_RESULT_ERROR_INVALID_INPUT; 123 } 124 curve_type = operation_start[ATAP_HEADER_LEN]; 125 operation = operation_start[ATAP_HEADER_LEN + 1]; 126 if (!validate_operation(operation)) { 127 return ATAP_RESULT_ERROR_UNSUPPORTED_OPERATION; 128 } 129 if (!validate_curve(curve_type)) { 130 return ATAP_RESULT_ERROR_UNSUPPORTED_ALGORITHM; 131 } 132 133 atap_memcpy(ca_pubkey, &operation_start[10], ATAP_ECDH_KEY_LEN); 134 135 ret = ops->get_auth_key_type(ops, auth_key_type); 136 if (ret != ATAP_RESULT_OK) { 137 return ret; 138 } 139 140 ret = ops->ecdh_shared_secret_compute(ops, 141 curve_type, 142 ca_pubkey, 143 ca_request->device_pubkey, 144 session_shared_secret); 145 if (ret != ATAP_RESULT_OK) { 146 return ret; 147 } 148 149 return derive_session_key(ops, 150 ca_request->device_pubkey, 151 ca_pubkey, 152 session_shared_secret, 153 "KEY", 154 session_key, 155 ATAP_AES_128_KEY_LEN); 156 } 157 158 static AtapResult compute_auth_signature( 159 AtapOps* ops, 160 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN], 161 uint8_t device_pubkey[ATAP_ECDH_KEY_LEN], 162 AtapInnerCaRequest* inner_ca_request) { 163 AtapResult ret = 0; 164 /* read auth key cert chain */ 165 ret = ops->read_auth_key_cert_chain(ops, 166 &inner_ca_request->auth_key_cert_chain); 167 if (ret != ATAP_RESULT_OK) { 168 return ret; 169 } 170 /* generate auth key signature */ 171 return auth_key_signature_generate(ops, 172 device_pubkey, 173 ca_pubkey, 174 &inner_ca_request->signature.data, 175 &inner_ca_request->signature.data_length); 176 } 177 178 static AtapResult read_product_id_hash(AtapOps* ops, 179 AtapInnerCaRequest* inner_ca_request) { 180 AtapResult ret = 0; 181 uint8_t product_id[ATAP_PRODUCT_ID_LEN]; 182 183 ret = ops->read_product_id(ops, product_id); 184 if (ret != ATAP_RESULT_OK) { 185 return ret; 186 } 187 return ops->sha256( 188 ops, product_id, ATAP_PRODUCT_ID_LEN, inner_ca_request->product_id_hash); 189 } 190 191 static AtapResult encrypt_inner_ca_request( 192 AtapOps* ops, 193 const AtapInnerCaRequest* inner_ca_request, 194 AtapCaRequest* ca_request) { 195 AtapResult ret = 0; 196 uint32_t inner_ca_request_len = 0; 197 uint8_t* inner_ca_request_buf = NULL; 198 199 inner_ca_request_len = inner_ca_request_serialized_size(inner_ca_request); 200 inner_ca_request_buf = (uint8_t*)atap_malloc(inner_ca_request_len); 201 ca_request->encrypted_inner_ca_request.data = 202 (uint8_t*)atap_malloc(inner_ca_request_len); 203 ca_request->encrypted_inner_ca_request.data_length = inner_ca_request_len; 204 if (inner_ca_request_buf == NULL || 205 ca_request->encrypted_inner_ca_request.data == NULL) { 206 return ATAP_RESULT_ERROR_OOM; 207 } 208 append_inner_ca_request_to_buf(inner_ca_request_buf, inner_ca_request); 209 210 /* generate IV */ 211 ret = ops->get_random_bytes(ops, ca_request->iv, ATAP_GCM_IV_LEN); 212 if (ret != ATAP_RESULT_OK) { 213 goto out; 214 } 215 216 /* encrypt inner CA request with shared key */ 217 ret = ops->aes_gcm_128_encrypt(ops, 218 inner_ca_request_buf, 219 inner_ca_request_len, 220 ca_request->iv, 221 session_key, 222 ca_request->encrypted_inner_ca_request.data, 223 ca_request->tag); 224 out: 225 atap_free(inner_ca_request_buf); 226 return ret; 227 } 228 229 static AtapResult decrypt_encrypted_message(AtapOps* ops, 230 const uint8_t* buf, 231 uint32_t buf_size, 232 uint8_t* key, 233 uint8_t** plaintext, 234 uint32_t* plaintext_len) { 235 const uint8_t *iv = NULL, *tag = NULL, *ciphertext = NULL; 236 uint32_t encrypted_len = 0; 237 uint8_t* buf_ptr = (uint8_t*)buf + ATAP_HEADER_LEN; 238 239 if (!validate_encrypted_message(buf, buf_size)) { 240 return ATAP_RESULT_ERROR_INVALID_INPUT; 241 } 242 243 iv = buf_ptr; 244 buf_ptr += ATAP_GCM_IV_LEN; 245 copy_uint32_from_buf(&buf_ptr, &encrypted_len); 246 ciphertext = buf_ptr; 247 buf_ptr += encrypted_len; 248 tag = buf_ptr; 249 250 *plaintext = (uint8_t*)atap_malloc(encrypted_len); 251 if (*plaintext == NULL) { 252 return ATAP_RESULT_ERROR_OOM; 253 } 254 *plaintext_len = encrypted_len; 255 256 return ops->aes_gcm_128_decrypt( 257 ops, ciphertext, *plaintext_len, iv, session_key, tag, *plaintext); 258 } 259 260 static AtapResult write_attestation_data(AtapOps* ops, 261 uint8_t** buf_ptr, 262 AtapKeyType key_type) { 263 AtapBlob key; 264 AtapCertChain cert_chain; 265 AtapResult ret = ATAP_RESULT_OK; 266 267 atap_memset(&key, 0, sizeof(key)); 268 atap_memset(&cert_chain, 0, sizeof(cert_chain)); 269 270 if (!copy_cert_chain_from_buf(buf_ptr, &cert_chain)) { 271 ret = ATAP_RESULT_ERROR_OOM; 272 goto out; 273 } 274 if (!copy_blob_from_buf(buf_ptr, &key)) { 275 ret = ATAP_RESULT_ERROR_OOM; 276 goto out; 277 } 278 if (key.data_length == 0 && cert_chain.entry_count) { 279 ret = ops->write_attestation_key(ops, key_type, NULL, &cert_chain); 280 } else if (key.data_length && cert_chain.entry_count) { 281 ret = ops->write_attestation_key(ops, key_type, &key, &cert_chain); 282 } else if (key.data_length && cert_chain.entry_count == 0) { 283 /* We never issue a key without a certificate chain */ 284 ret = ATAP_RESULT_ERROR_INVALID_INPUT; 285 } else if (key_type != ATAP_KEY_TYPE_edDSA && 286 key_type != ATAP_KEY_TYPE_SPECIAL && 287 key_type != ATAP_KEY_TYPE_EPID) { 288 /* edDSA, EPID, and special purpose key are optional in version 1*/ 289 ret = ATAP_RESULT_ERROR_INVALID_INPUT; 290 } 291 292 out: 293 free_blob(key); 294 free_cert_chain(cert_chain); 295 return ret; 296 } 297 298 static AtapResult write_inner_ca_response(AtapOps* ops, 299 uint8_t* inner_ca_resp_ptr, 300 uint32_t inner_ca_resp_len) { 301 AtapResult ret = 0; 302 uint8_t** buf_ptr = &inner_ca_resp_ptr; 303 304 if (!validate_inner_ca_response( 305 inner_ca_resp_ptr, inner_ca_resp_len, operation)) { 306 return ATAP_RESULT_ERROR_INVALID_INPUT; 307 } 308 ret = ops->write_hex_uuid(ops, &inner_ca_resp_ptr[ATAP_HEADER_LEN]); 309 if (ret != ATAP_RESULT_OK) { 310 return ret; 311 } 312 *buf_ptr += (ATAP_HEADER_LEN + ATAP_HEX_UUID_LEN); 313 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_RSA); 314 if (ret != ATAP_RESULT_OK) { 315 return ret; 316 } 317 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_ECDSA); 318 if (ret != ATAP_RESULT_OK) { 319 return ret; 320 } 321 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_edDSA); 322 /* Device may not support edDSA */ 323 if (ret != ATAP_RESULT_OK && ret != ATAP_RESULT_ERROR_UNSUPPORTED_ALGORITHM) { 324 return ret; 325 } 326 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_EPID); 327 if (ret != ATAP_RESULT_OK) { 328 return ret; 329 } 330 /* Device may not support Special Cast key */ 331 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_SPECIAL); 332 if (ret != ATAP_RESULT_OK) { 333 return ret; 334 } 335 return ATAP_RESULT_OK; 336 } 337 338 AtapResult atap_get_ca_request(AtapOps* ops, 339 const uint8_t* operation_start, 340 uint32_t operation_start_size, 341 uint8_t** ca_request_p, 342 uint32_t* ca_request_size_p) { 343 AtapResult ret = 0; 344 AtapKeyType auth_key_type = 0; 345 AtapCaRequest ca_request; 346 AtapInnerCaRequest inner_ca_request; 347 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN]; 348 349 ret = initialize_session(ops, 350 operation_start, 351 operation_start_size, 352 &auth_key_type, 353 ca_pubkey, 354 &ca_request, 355 &inner_ca_request); 356 if (ret != ATAP_RESULT_OK) { 357 goto err; 358 } 359 360 if (auth_key_type != ATAP_KEY_TYPE_NONE) { 361 ret = compute_auth_signature( 362 ops, ca_pubkey, ca_request.device_pubkey, &inner_ca_request); 363 if (ret != ATAP_RESULT_OK) { 364 goto err; 365 } 366 } 367 368 if (operation == ATAP_OPERATION_CERTIFY) { 369 ret = read_available_public_keys(ops, &inner_ca_request); 370 if (ret != ATAP_RESULT_OK) { 371 goto err; 372 } 373 } 374 375 ret = read_product_id_hash(ops, &inner_ca_request); 376 if (ret != ATAP_RESULT_OK) { 377 goto err; 378 } 379 380 ret = encrypt_inner_ca_request(ops, &inner_ca_request, &ca_request); 381 if (ret != ATAP_RESULT_OK) { 382 goto err; 383 } 384 385 *ca_request_size_p = ca_request_serialized_size(&ca_request); 386 *ca_request_p = (uint8_t*)atap_malloc(*ca_request_size_p); 387 if (*ca_request_p == NULL) { 388 *ca_request_size_p = 0; 389 ret = ATAP_RESULT_ERROR_OOM; 390 goto err; 391 } 392 append_ca_request_to_buf(*ca_request_p, &ca_request); 393 goto out; 394 395 err: 396 /* clear global secrets */ 397 atap_memset(session_shared_secret, 0, ATAP_ECDH_SHARED_SECRET_LEN); 398 atap_memset(session_key, 0, ATAP_AES_128_KEY_LEN); 399 *ca_request_p = NULL; 400 *ca_request_size_p = 0; 401 out: 402 free_inner_ca_request(inner_ca_request); 403 free_ca_request(ca_request); 404 return ret; 405 } 406 407 AtapResult atap_set_ca_response(AtapOps* ops, 408 const uint8_t* ca_response, 409 uint32_t ca_response_size) { 410 AtapResult ret = 0; 411 uint8_t* inner_ca_resp = NULL; 412 uint8_t* inner_inner_ca_resp = NULL; 413 uint8_t* inner_ca_resp_ptr = NULL; 414 uint32_t inner_ca_resp_len = 0; 415 uint32_t inner_inner_ca_resp_len = 0; 416 uint8_t soc_global_key[ATAP_AES_128_KEY_LEN]; 417 418 ret = decrypt_encrypted_message(ops, 419 ca_response, 420 ca_response_size, 421 session_key, 422 &inner_ca_resp, 423 &inner_ca_resp_len); 424 if (ret != ATAP_RESULT_OK) { 425 goto out; 426 } 427 inner_ca_resp_ptr = inner_ca_resp; 428 if (operation == ATAP_OPERATION_ISSUE_ENCRYPTED) { 429 /* Decrypt Encrypted Inner CA Response (encrypted) with SoC global key */ 430 ret = ops->read_soc_global_key(ops, soc_global_key); 431 if (ret != ATAP_RESULT_OK) { 432 goto out; 433 } 434 ret = decrypt_encrypted_message(ops, 435 inner_ca_resp, 436 inner_ca_resp_len, 437 soc_global_key, 438 &inner_inner_ca_resp, 439 &inner_inner_ca_resp_len); 440 if (ret != ATAP_RESULT_OK) { 441 goto out; 442 } 443 inner_ca_resp_ptr = inner_inner_ca_resp; 444 inner_ca_resp_len = inner_inner_ca_resp_len; 445 } 446 ret = write_inner_ca_response(ops, inner_ca_resp_ptr, inner_ca_resp_len); 447 448 out: 449 if (inner_ca_resp) { 450 atap_free(inner_ca_resp); 451 } 452 if (inner_inner_ca_resp) { 453 atap_free(inner_inner_ca_resp); 454 } 455 return ret; 456 } 457