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 <optee_include/OpteeClientApiLib.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 28 /* 29 * Name of the attestation key file is 30 * ATTESTATION_KEY_PREFIX.%algorithm, 31 * where algorithm is either "EC" or "RSA" 32 */ 33 #define ATTESTATION_KEY_PREFIX "PrivateKey" 34 35 /* 36 * Name of the attestation certificate file is 37 * ATTESTATION_CERT_PREFIX.%algorithm.%index, 38 * where index is the index within the certificate chain. 39 */ 40 #define ATTESTATION_CERT_PREFIX "CertificateChain" 41 42 /* Maximum file name size.*/ 43 #define STORAGE_ID_LENGTH_MAX 64 44 45 typedef enum{ 46 KM_ALGORITHM_RSA = 1, 47 KM_ALGORITHM_EC = 3, 48 } keymaster_algorithm_t; 49 50 typedef struct { 51 uint8_t *data; 52 uint32_t data_length; 53 } atap_blob; 54 55 typedef struct { 56 atap_blob entries[ATAP_CERT_CHAIN_ENTRIES_MAX]; 57 uint32_t entry_count; 58 } atap_certchain; 59 60 uint32_t write_to_keymaster(uint8_t *filename, uint32_t filename_size, 61 uint8_t *data, uint32_t data_size); 62 63 static const char *get_keyslot_str(keymaster_algorithm_t key_type) 64 { 65 switch (key_type) { 66 case KM_ALGORITHM_RSA: 67 return "RSA"; 68 case KM_ALGORITHM_EC: 69 return "EC"; 70 default: 71 return ""; 72 } 73 } 74 75 static void free_blob(atap_blob blob) 76 { 77 if (blob.data) 78 free(blob.data); 79 80 blob.data_length = 0; 81 } 82 83 static void free_cert_chain(atap_certchain cert_chain) 84 { 85 unsigned int i = 0; 86 87 for (i = 0; i < cert_chain.entry_count; ++i) { 88 if (cert_chain.entries[i].data) 89 free(cert_chain.entries[i].data); 90 91 cert_chain.entries[i].data_length = 0; 92 } 93 memset(&cert_chain, 0, sizeof(atap_certchain)); 94 } 95 96 static void copy_from_buf(uint8_t **buf_ptr, void *data, uint32_t data_size) 97 { 98 memcpy(data, *buf_ptr, data_size); 99 *buf_ptr += data_size; 100 } 101 102 static void copy_uint32_from_buf(uint8_t **buf_ptr, uint32_t *x) 103 { 104 copy_from_buf(buf_ptr, x, sizeof(uint32_t)); 105 } 106 107 static bool copy_blob_from_buf(uint8_t **buf_ptr, atap_blob *blob) 108 { 109 memset(blob, 0, sizeof(atap_blob)); 110 copy_uint32_from_buf(buf_ptr, &blob->data_length); 111 112 if (blob->data_length > ATAP_BLOB_LEN_MAX) 113 return false; 114 115 if (blob->data_length) { 116 blob->data = (uint8_t *) malloc(blob->data_length); 117 if (blob->data == NULL) 118 return false; 119 120 copy_from_buf(buf_ptr, blob->data, blob->data_length); 121 } 122 return true; 123 } 124 125 static bool copy_cert_chain_from_buf(uint8_t **buf_ptr, 126 atap_certchain *cert_chain) 127 { 128 uint32_t cert_chain_size = 0; 129 int32_t bytes_remaining = 0; 130 size_t i = 0; 131 bool retval = true; 132 133 memset(cert_chain, 0, sizeof(atap_certchain)); 134 135 /* Copy size of cert chain, as it is a Variable field. */ 136 copy_from_buf(buf_ptr, &cert_chain_size, sizeof(cert_chain_size)); 137 138 if (cert_chain_size > ATAP_CERT_CHAIN_LEN_MAX) 139 return false; 140 141 if (cert_chain_size == 0) 142 return true; 143 144 bytes_remaining = cert_chain_size; 145 for (i = 0; i < ATAP_CERT_CHAIN_ENTRIES_MAX; ++i) { 146 if (!copy_blob_from_buf(buf_ptr, &cert_chain->entries[i])) { 147 retval = false; 148 break; 149 } 150 151 ++cert_chain->entry_count; 152 bytes_remaining -= (sizeof(uint32_t) + 153 cert_chain->entries[i].data_length); 154 155 if (bytes_remaining <= 0) { 156 retval = (bytes_remaining == 0); 157 break; 158 } 159 } 160 if (retval == false) 161 free_cert_chain(*cert_chain); 162 163 return retval; 164 } 165 166 /* validate attestation data head. */ 167 static bool validate_ca_header(const uint8_t *buf, uint32_t buf_size) 168 { 169 170 if (buf[0] != 'C' || buf[1] != 'A' || buf[2] != 0) 171 return false; 172 173 uint32_t data_size; 174 175 memcpy(&data_size, buf + 3, sizeof(uint32_t)); 176 177 if (data_size <= 0 || data_size > ATTESTATION_DATA_OFFSET) { 178 printf("invalide data_size:%d\n", data_size); 179 return false; 180 } 181 182 uint32_t real_size; 183 184 memcpy(&real_size, buf + 3 + sizeof(uint32_t), sizeof(uint32_t)); 185 if (real_size <= 0 || real_size > data_size) { 186 printf("invalide real_size:%d\n", real_size); 187 return false; 188 } 189 return true; 190 } 191 192 /* write key to security storage. */ 193 static uint32_t write_key(keymaster_algorithm_t key_type, 194 const uint8_t *key, uint32_t key_size) 195 { 196 char key_file[STORAGE_ID_LENGTH_MAX] = {0}; 197 198 snprintf(key_file, STORAGE_ID_LENGTH_MAX, "%s.%s", ATTESTATION_KEY_PREFIX, 199 get_keyslot_str(key_type)); 200 write_to_keymaster((uint8_t *)key_file, strlen(key_file), 201 (uint8_t *)key, key_size); 202 return 0; 203 } 204 205 /* write cert to security storage. */ 206 static uint32_t write_cert(keymaster_algorithm_t key_type, const uint8_t *cert, 207 uint32_t cert_size, uint32_t index) 208 { 209 char cert_file[STORAGE_ID_LENGTH_MAX] = {0}; 210 211 snprintf(cert_file, STORAGE_ID_LENGTH_MAX, "%s.%s.%d", ATTESTATION_CERT_PREFIX, 212 get_keyslot_str(key_type), index); 213 write_to_keymaster((uint8_t *)cert_file, strlen(cert_file), 214 (uint8_t *)cert, cert_size); 215 return 0; 216 } 217 218 /* write cert chain length to security storage. */ 219 static uint32_t write_cert_chain_length(keymaster_algorithm_t key_type, 220 uint8_t chain_len) 221 { 222 char cert_chain_length_file[STORAGE_ID_LENGTH_MAX] = {0}; 223 uint8_t data = chain_len; 224 uint32_t len = 1; 225 226 snprintf(cert_chain_length_file, STORAGE_ID_LENGTH_MAX, "%s.%s.length", 227 ATTESTATION_CERT_PREFIX, get_keyslot_str(key_type)); 228 write_to_keymaster((uint8_t *)cert_chain_length_file, 229 strlen(cert_chain_length_file), &data, len); 230 231 return 0; 232 } 233 234 atap_result load_attestation_key(struct blk_desc *dev_desc, 235 disk_partition_t *misc_partition) 236 { 237 int ret; 238 239 if (!dev_desc) { 240 printf("%s: Could not find device\n", __func__); 241 return ATAP_RESULT_ERROR_DEVICE_NOT_FOUND; 242 } 243 244 if (misc_partition == NULL) { 245 printf("misc partition not found!\n"); 246 return ATAP_RESULT_ERROR_PARTITION_NOT_FOUND; 247 } 248 249 /* get attestation data offset from misc partition */ 250 lbaint_t key_offset = misc_partition->start + 251 misc_partition->size - ATTESTATION_DATA_BLOCK_OFFSET; 252 253 /* read ca head from attestation data offset */ 254 uint8_t ca_headr[ATTESTATION_DATA_BLOCK_SIZE]; 255 256 ret = blk_dread(dev_desc, key_offset, 1, ca_headr); 257 if (ret != 1) { 258 printf("failed to read ca head from misc\n"); 259 return ATAP_RESULT_ERROR_BLOCK_READ; 260 } 261 262 if (!validate_ca_header(ca_headr, sizeof(ca_headr))) { 263 printf("ca head not found\n"); 264 return ATAP_RESULT_ERROR_INVALID_HEAD; 265 } 266 267 /* get attestation data size from ca head */ 268 uint32_t real_size; 269 270 memcpy(&real_size, ca_headr + 3 + sizeof(uint32_t), sizeof(uint32_t)); 271 272 /* calculate real block size of attestation data */ 273 int real_block_num = real_size / ATTESTATION_DATA_BLOCK_SIZE; 274 275 if (real_size % ATTESTATION_DATA_BLOCK_SIZE != 0) 276 real_block_num++; 277 278 unsigned char keybuf[ATTESTATION_DATA_OFFSET] = {0}; 279 280 /* check block size */ 281 if (real_block_num <= 0 || real_block_num > ATTESTATION_DATA_BLOCK_OFFSET) { 282 printf("invalidate real_block_num:%d\n", real_block_num); 283 return ATAP_RESULT_ERROR_INVALID_BLOCK_NUM; 284 } 285 286 /* read all attestation data from misc */ 287 if (blk_dread(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) { 288 printf("failed to read misc key\n"); 289 return ATAP_RESULT_ERROR_BLOCK_READ; 290 } 291 292 /* read device id from buf*/ 293 uint32_t device_id_size = 0; 294 uint8_t device_id[32] = {0}; 295 296 memcpy(&device_id_size, keybuf + 16, sizeof(uint32_t)); 297 if (device_id_size < 0 || device_id_size > sizeof(device_id)) { 298 printf("invalidate device_id_size:%d\n", device_id_size); 299 return ATAP_RESULT_ERROR_INVALID_DEVICE_ID; 300 } 301 302 memcpy(device_id, keybuf + 16 + sizeof(uint32_t), device_id_size); 303 debug("device_id:%s\n", device_id); 304 305 /* read algorithm from buf */ 306 uint8_t *key_buf = keybuf + 16 + sizeof(uint32_t) + device_id_size; 307 uint32_t algorithm; 308 309 copy_uint32_from_buf(&key_buf, &algorithm); 310 debug("\n algorithm:%d\n", algorithm); 311 312 /* read rsa private key */ 313 atap_blob key; 314 315 if (copy_blob_from_buf(&key_buf, &key) == false) { 316 printf("copy_blob_from_buf failed!\n"); 317 return ATAP_RESULT_ERROR_BUF_COPY; 318 } 319 /* write rsa private key to security storage*/ 320 write_key(KM_ALGORITHM_RSA, key.data, key.data_length); 321 322 /* read rsa cert chain */ 323 atap_certchain certchain; 324 325 if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) { 326 printf("copy_cert_chain_from_buf failed!\n"); 327 return ATAP_RESULT_ERROR_BUF_COPY; 328 } 329 330 /* write rsa cert chain size to security storage*/ 331 write_cert_chain_length(KM_ALGORITHM_RSA, 332 (uint8_t) certchain.entry_count); 333 334 /* write rsa cert chain data to security storage*/ 335 int i = 0; 336 337 for (i = 0; i < certchain.entry_count; ++i) { 338 write_cert(KM_ALGORITHM_RSA, certchain.entries[i].data, 339 certchain.entries[i].data_length, i); 340 } 341 342 /* read ec algorithm */ 343 copy_uint32_from_buf(&key_buf, &algorithm); 344 debug("\n algorithm:%d\n", algorithm); 345 346 /* read ec private key */ 347 free_blob(key); 348 if (copy_blob_from_buf(&key_buf, &key) == false) { 349 printf("copy_blob_from_buf failed!\n"); 350 return ATAP_RESULT_ERROR_BUF_COPY; 351 } 352 353 /* write ec private key to security storage*/ 354 write_key(KM_ALGORITHM_EC, key.data, key.data_length); 355 356 /* read ec cert chain */ 357 free_cert_chain(certchain); 358 if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) { 359 printf("copy_cert_chain_from_buf failed!\n"); 360 return ATAP_RESULT_ERROR_BUF_COPY; 361 } 362 /* write ec cert chain size to security storage*/ 363 write_cert_chain_length(KM_ALGORITHM_EC, 364 (uint8_t) certchain.entry_count); 365 366 /* write ec cert chain to security storage*/ 367 for (i = 0; i < certchain.entry_count; ++i) { 368 write_cert(KM_ALGORITHM_EC, certchain.entries[i].data, 369 certchain.entries[i].data_length, i); 370 } 371 372 memset(keybuf, 0, sizeof(keybuf)); 373 374 /* wipe attestation data from misc*/ 375 if (blk_dwrite(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) { 376 printf("StorageWriteLba failed\n"); 377 return ATAP_RESULT_ERROR_BLOCK_WRITE; 378 } 379 380 return ATAP_RESULT_OK; 381 } 382