1 /* 2 * Copyright 2018, Rockchip Electronics Co., Ltd 3 * qiujian, <qiujian@rock-chips.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include "attestation_key.h" 9 10 #include <common.h> 11 #include <malloc.h> 12 13 #include <keymaster.h> 14 15 /* attestation data offset */ 16 #define ATTESTATION_DATA_OFFSET 65536 17 18 /* block size */ 19 #define ATTESTATION_DATA_BLOCK_SIZE 512 20 21 /* attestation data block offset */ 22 #define ATTESTATION_DATA_BLOCK_OFFSET (ATTESTATION_DATA_OFFSET / ATTESTATION_DATA_BLOCK_SIZE) 23 24 #define ATAP_BLOB_LEN_MAX 2048 25 #define ATAP_CERT_CHAIN_LEN_MAX 8192 26 #define ATAP_CERT_CHAIN_ENTRIES_MAX 8 27 #define CA_HEADER_LEN 16 28 29 /* 30 * Name of the attestation key file is 31 * ATTESTATION_KEY_PREFIX.%algorithm, 32 * which include PrivateKey and CertificateChain, 33 * where algorithm is either "EC" or "RSA" 34 */ 35 #define ATTESTATION_KEY_FILE "AttestationKey" 36 37 /* 38 * Name of the attestation key file is 39 * ATTESTATION_KEY_PREFIX.%algorithm, 40 * where algorithm is either "EC" or "RSA" 41 */ 42 #define ATTESTATION_KEY_PREFIX "PrivateKey" 43 44 /* 45 * Name of the attestation certificate file is 46 * ATTESTATION_CERT_PREFIX.%algorithm.%index, 47 * where index is the index within the certificate chain. 48 */ 49 #define ATTESTATION_CERT_PREFIX "CertificateChain" 50 51 /* Maximum file name size.*/ 52 #define STORAGE_ID_LENGTH_MAX 64 53 54 typedef enum{ 55 KM_ALGORITHM_RSA = 1, 56 KM_ALGORITHM_EC = 3, 57 } keymaster_algorithm_t; 58 59 typedef struct { 60 uint8_t *data; 61 uint32_t data_length; 62 } atap_blob; 63 64 typedef struct { 65 atap_blob entries[ATAP_CERT_CHAIN_ENTRIES_MAX]; 66 uint32_t entry_count; 67 } atap_certchain; 68 69 uint32_t write_to_keymaster(uint8_t *filename, uint32_t filename_size, 70 uint8_t *data, uint32_t data_size); 71 72 static const char *get_keyslot_str(keymaster_algorithm_t key_type) 73 { 74 switch (key_type) { 75 case KM_ALGORITHM_RSA: 76 return "RSA"; 77 case KM_ALGORITHM_EC: 78 return "EC"; 79 default: 80 return ""; 81 } 82 } 83 84 static void free_blob(atap_blob blob) 85 { 86 if (blob.data) 87 free(blob.data); 88 89 blob.data_length = 0; 90 } 91 92 static void free_cert_chain(atap_certchain cert_chain) 93 { 94 unsigned int i = 0; 95 96 for (i = 0; i < cert_chain.entry_count; ++i) { 97 if (cert_chain.entries[i].data) 98 free(cert_chain.entries[i].data); 99 cert_chain.entries[i].data_length = 0; 100 } 101 memset(&cert_chain, 0, sizeof(atap_certchain)); 102 } 103 104 static void copy_from_buf(uint8_t **buf_ptr, void *data, uint32_t data_size) 105 { 106 memcpy(data, *buf_ptr, data_size); 107 *buf_ptr += data_size; 108 } 109 110 static void copy_uint32_from_buf(uint8_t **buf_ptr, uint32_t *x) 111 { 112 copy_from_buf(buf_ptr, x, sizeof(uint32_t)); 113 } 114 115 static bool copy_blob_from_buf(uint8_t **buf_ptr, atap_blob *blob) 116 { 117 memset(blob, 0, sizeof(atap_blob)); 118 copy_uint32_from_buf(buf_ptr, &blob->data_length); 119 120 if (blob->data_length > ATAP_BLOB_LEN_MAX) 121 return false; 122 123 if (blob->data_length) { 124 blob->data = (uint8_t *) malloc(blob->data_length); 125 if (blob->data == NULL) 126 return false; 127 128 copy_from_buf(buf_ptr, blob->data, blob->data_length); 129 } 130 return true; 131 } 132 133 static bool copy_cert_chain_from_buf(uint8_t **buf_ptr, 134 atap_certchain *cert_chain) 135 { 136 uint32_t cert_chain_size = 0; 137 int32_t bytes_remaining = 0; 138 size_t i = 0; 139 bool retval = true; 140 141 memset(cert_chain, 0, sizeof(atap_certchain)); 142 143 /* Copy size of cert chain, as it is a Variable field. */ 144 copy_from_buf(buf_ptr, &cert_chain_size, sizeof(cert_chain_size)); 145 146 if (cert_chain_size > ATAP_CERT_CHAIN_LEN_MAX) 147 return false; 148 149 if (cert_chain_size == 0) 150 return true; 151 152 bytes_remaining = cert_chain_size; 153 for (i = 0; i < ATAP_CERT_CHAIN_ENTRIES_MAX; ++i) { 154 if (!copy_blob_from_buf(buf_ptr, &cert_chain->entries[i])) { 155 retval = false; 156 break; 157 } 158 159 ++cert_chain->entry_count; 160 bytes_remaining -= (sizeof(uint32_t) + 161 cert_chain->entries[i].data_length); 162 163 if (bytes_remaining <= 0) { 164 retval = (bytes_remaining == 0); 165 break; 166 } 167 } 168 if (retval == false) 169 free_cert_chain(*cert_chain); 170 171 return retval; 172 } 173 174 /* validate attestation data head. */ 175 static bool validate_ca_header(const uint8_t *buf, uint32_t buf_size) 176 { 177 178 if (buf[0] != 'C' || buf[1] != 'A' || buf[2] != 0) 179 return false; 180 181 uint32_t data_size; 182 183 memcpy(&data_size, buf + 3, sizeof(uint32_t)); 184 185 if (data_size <= 0 || data_size > ATTESTATION_DATA_OFFSET) { 186 printf("invalide data_size:%d\n", data_size); 187 return false; 188 } 189 190 uint32_t real_size; 191 192 memcpy(&real_size, buf + 3 + sizeof(uint32_t), sizeof(uint32_t)); 193 if (real_size <= 0 || real_size > data_size) { 194 printf("invalide real_size:%d\n", real_size); 195 return false; 196 } 197 return true; 198 } 199 200 /* write key to security storage. */ 201 static uint32_t write_key(keymaster_algorithm_t key_type, 202 unsigned char *key_name, 203 const uint8_t *key, uint32_t key_size) 204 { 205 char key_file[STORAGE_ID_LENGTH_MAX] = {0}; 206 207 snprintf(key_file, STORAGE_ID_LENGTH_MAX, "%s.%s", key_name, 208 get_keyslot_str(key_type)); 209 TEEC_Result ret=write_to_keymaster((uint8_t *)key_file, strlen(key_file), 210 (uint8_t *)key, key_size); 211 printf("write_key key_file=%s ret=%d\n",key_file,ret); 212 return ret; 213 } 214 215 /* write cert to security storage. */ 216 static uint32_t write_cert(keymaster_algorithm_t key_type, const uint8_t *cert, 217 uint32_t cert_size, uint32_t index) 218 { 219 char cert_file[STORAGE_ID_LENGTH_MAX] = {0}; 220 221 snprintf(cert_file, STORAGE_ID_LENGTH_MAX, "%s.%s.%d", ATTESTATION_CERT_PREFIX, 222 get_keyslot_str(key_type), index); 223 write_to_keymaster((uint8_t *)cert_file, strlen(cert_file), 224 (uint8_t *)cert, cert_size); 225 return 0; 226 } 227 228 /* write cert chain length to security storage. */ 229 static uint32_t write_cert_chain_length(keymaster_algorithm_t key_type, 230 uint8_t chain_len) 231 { 232 char cert_chain_length_file[STORAGE_ID_LENGTH_MAX] = {0}; 233 uint8_t data = chain_len; 234 uint32_t len = 1; 235 236 snprintf(cert_chain_length_file, STORAGE_ID_LENGTH_MAX, "%s.%s.length", 237 ATTESTATION_CERT_PREFIX, get_keyslot_str(key_type)); 238 write_to_keymaster((uint8_t *)cert_chain_length_file, 239 strlen(cert_chain_length_file), &data, len); 240 241 return 0; 242 } 243 244 atap_result load_attestation_key(struct blk_desc *dev_desc, 245 disk_partition_t *misc_partition) 246 { 247 int ret; 248 unsigned char key_name[STORAGE_ID_LENGTH_MAX] = {0}; 249 250 if (!dev_desc) { 251 printf("%s: Could not find device\n", __func__); 252 return ATAP_RESULT_ERROR_DEVICE_NOT_FOUND; 253 } 254 255 if (misc_partition == NULL) { 256 printf("misc partition not found!\n"); 257 return ATAP_RESULT_ERROR_PARTITION_NOT_FOUND; 258 } 259 260 /* get attestation data offset from misc partition */ 261 lbaint_t key_offset = misc_partition->start + 262 misc_partition->size - ATTESTATION_DATA_BLOCK_OFFSET; 263 264 /* read ca head from attestation data offset */ 265 uint8_t ca_headr[ATTESTATION_DATA_BLOCK_SIZE]; 266 267 ret = blk_dread(dev_desc, key_offset, 1, ca_headr); 268 if (ret != 1) { 269 printf("failed to read ca head from misc\n"); 270 return ATAP_RESULT_ERROR_BLOCK_READ; 271 } 272 273 if (!validate_ca_header(ca_headr, sizeof(ca_headr))) { 274 debug("ca head not found\n"); 275 return ATAP_RESULT_ERROR_INVALID_HEAD; 276 } 277 278 /* get attestation data size from ca head */ 279 uint32_t real_size; 280 281 memcpy(&real_size, ca_headr + 3 + sizeof(uint32_t), sizeof(uint32_t)); 282 283 /* calculate real block size of attestation data */ 284 int real_block_num = real_size / ATTESTATION_DATA_BLOCK_SIZE; 285 286 if (real_size % ATTESTATION_DATA_BLOCK_SIZE != 0) 287 real_block_num++; 288 289 unsigned char keybuf[ATTESTATION_DATA_OFFSET] = {0}; 290 291 /* check block size */ 292 if (real_block_num <= 0 || real_block_num > ATTESTATION_DATA_BLOCK_OFFSET) { 293 printf("invalidate real_block_num:%d\n", real_block_num); 294 return ATAP_RESULT_ERROR_INVALID_BLOCK_NUM; 295 } 296 297 /* read all attestation data from misc */ 298 if (blk_dread(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) { 299 printf("failed to read misc key\n"); 300 return ATAP_RESULT_ERROR_BLOCK_READ; 301 } 302 303 /* read device id from buf*/ 304 uint32_t device_id_size = 0; 305 uint8_t device_id[32] = {0}; 306 307 memcpy(&device_id_size, keybuf + 16, sizeof(uint32_t)); 308 if (device_id_size < 0 || device_id_size > sizeof(device_id)) { 309 printf("invalidate device_id_size:%d\n", device_id_size); 310 return ATAP_RESULT_ERROR_INVALID_DEVICE_ID; 311 } 312 313 memcpy(device_id, keybuf + 16 + sizeof(uint32_t), device_id_size); 314 debug("device_id:%s\n", device_id); 315 316 /* read algorithm from buf */ 317 uint8_t *key_buf = keybuf + 16 + sizeof(uint32_t) + device_id_size; 318 uint32_t algorithm; 319 320 copy_uint32_from_buf(&key_buf, &algorithm); 321 debug("\n algorithm:%d\n", algorithm); 322 323 /* read rsa private key */ 324 atap_blob key; 325 326 if (copy_blob_from_buf(&key_buf, &key) == false) { 327 printf("copy_blob_from_buf failed!\n"); 328 return ATAP_RESULT_ERROR_BUF_COPY; 329 } 330 /* write rsa private key to security storage*/ 331 memcpy(key_name, ATTESTATION_KEY_PREFIX, 332 sizeof(ATTESTATION_KEY_PREFIX)); 333 write_key(KM_ALGORITHM_RSA, key_name, key.data, key.data_length); 334 335 /* read rsa cert chain */ 336 atap_certchain certchain; 337 338 if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) { 339 printf("copy_cert_chain_from_buf failed!\n"); 340 return ATAP_RESULT_ERROR_BUF_COPY; 341 } 342 343 /* write rsa cert chain size to security storage*/ 344 write_cert_chain_length(KM_ALGORITHM_RSA, 345 (uint8_t) certchain.entry_count); 346 347 /* write rsa cert chain data to security storage*/ 348 int i = 0; 349 350 for (i = 0; i < certchain.entry_count; ++i) { 351 write_cert(KM_ALGORITHM_RSA, certchain.entries[i].data, 352 certchain.entries[i].data_length, i); 353 } 354 355 /* read ec algorithm */ 356 copy_uint32_from_buf(&key_buf, &algorithm); 357 debug("\n algorithm:%d\n", algorithm); 358 359 /* read ec private key */ 360 free_blob(key); 361 if (copy_blob_from_buf(&key_buf, &key) == false) { 362 printf("copy_blob_from_buf failed!\n"); 363 return ATAP_RESULT_ERROR_BUF_COPY; 364 } 365 366 /* write ec private key to security storage*/ 367 write_key(KM_ALGORITHM_EC, key_name, key.data, key.data_length); 368 369 /* read ec cert chain */ 370 free_cert_chain(certchain); 371 if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) { 372 printf("copy_cert_chain_from_buf failed!\n"); 373 return ATAP_RESULT_ERROR_BUF_COPY; 374 } 375 /* write ec cert chain size to security storage*/ 376 write_cert_chain_length(KM_ALGORITHM_EC, 377 (uint8_t) certchain.entry_count); 378 379 /* write ec cert chain to security storage*/ 380 for (i = 0; i < certchain.entry_count; ++i) { 381 write_cert(KM_ALGORITHM_EC, certchain.entries[i].data, 382 certchain.entries[i].data_length, i); 383 } 384 385 memset(keybuf, 0, sizeof(keybuf)); 386 387 /* wipe attestation data from misc*/ 388 if (blk_dwrite(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) { 389 printf("StorageWriteLba failed\n"); 390 return ATAP_RESULT_ERROR_BLOCK_WRITE; 391 } 392 393 return ATAP_RESULT_OK; 394 } 395 396 atap_result read_key_data(uint8_t **key_buf, uint8_t *key_data, 397 uint32_t *key_data_length) 398 { 399 atap_blob key; 400 atap_certchain certchain; 401 402 /* read private key */ 403 if (copy_blob_from_buf(key_buf, &key) == false) { 404 printf("copy_blob_from_buf failed!\n"); 405 return ATAP_RESULT_ERROR_BUF_COPY; 406 } 407 memcpy(key_data, &key.data_length, sizeof(uint32_t)); 408 memcpy(key_data + 4, key.data, key.data_length); 409 *key_data_length = 4 + key.data_length; 410 411 /* read certchain */ 412 if (copy_cert_chain_from_buf(key_buf, &certchain) == false) { 413 printf("copy_cert_chain_from_buf failed!\n"); 414 return ATAP_RESULT_ERROR_BUF_COPY; 415 } 416 memcpy(key_data + *key_data_length, 417 &certchain.entry_count, sizeof(uint32_t)); 418 *key_data_length += 4; 419 for (int i = 0; i < certchain.entry_count; ++i) { 420 memcpy(key_data + *key_data_length, 421 &certchain.entries[i].data_length, sizeof(uint32_t)); 422 *key_data_length += 4; 423 memcpy(key_data + *key_data_length, certchain.entries[i].data, 424 certchain.entries[i].data_length); 425 *key_data_length += certchain.entries[i].data_length; 426 } 427 428 free_blob(key); 429 free_cert_chain(certchain); 430 431 return 0; 432 } 433 434 atap_result write_attestation_key_to_secure_storage(uint8_t *received_data, 435 uint32_t len) 436 { 437 unsigned char keybuf[ATTESTATION_DATA_OFFSET] = {0}; 438 unsigned char key_name[STORAGE_ID_LENGTH_MAX] = {0}; 439 uint32_t device_id_size = 0; 440 uint8_t device_id[32] = {0}; 441 uint8_t *key_buf = NULL; 442 uint32_t algorithm; 443 uint8_t *key_data; 444 uint32_t key_data_length = 0; 445 446 /* skip the tag(4 byte) and the size of key(4 byte) */ 447 memcpy(keybuf, received_data + 8, ATTESTATION_DATA_OFFSET); 448 key_data = malloc(ATTESTATION_DATA_OFFSET); 449 /* read device id from keybuf */ 450 memcpy(&device_id_size, keybuf + CA_HEADER_LEN, sizeof(uint32_t)); 451 if (device_id_size < 0 || device_id_size > sizeof(device_id)) { 452 printf("invalidate device_id_size:%d\n", device_id_size); 453 return ATAP_RESULT_ERROR_INVALID_DEVICE_ID; 454 } 455 memcpy(device_id, keybuf + CA_HEADER_LEN + sizeof(uint32_t), 456 device_id_size); 457 printf("device_id:%s\n", device_id); 458 459 memcpy(key_name, ATTESTATION_KEY_FILE, sizeof(ATTESTATION_KEY_FILE)); 460 /* read algorithm(RSA) from keybuf */ 461 key_buf = keybuf + CA_HEADER_LEN + sizeof(uint32_t) + device_id_size; 462 copy_uint32_from_buf(&key_buf, &algorithm); 463 printf("\n algorithm: %d\n", algorithm); 464 /* read rsa key and certchain */ 465 read_key_data(&key_buf, key_data, &key_data_length); 466 TEEC_Result ret_rsa=write_key(KM_ALGORITHM_RSA, key_name, key_data, key_data_length); 467 printf("write attestation key: RSA ret_rsa=%d\n",ret_rsa); 468 469 /* read algorithm(EC) from keybuf */ 470 copy_uint32_from_buf(&key_buf, &algorithm); 471 printf("\n algorithm: %d\n", algorithm); 472 /* read ec key and certchain */ 473 read_key_data(&key_buf, key_data, &key_data_length); 474 TEEC_Result ret_ec=write_key(KM_ALGORITHM_EC, key_name, key_data, key_data_length); 475 printf("write attestation key: EC ret_ec=%d\n",ret_ec); 476 477 memset(keybuf, 0, sizeof(keybuf)); 478 free(key_data); 479 480 return ATAP_RESULT_OK; 481 } 482