1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * Host functions for keys. 6 */ 7 8 #include <stdio.h> 9 10 #include <openssl/pem.h> 11 12 #include "2sysincludes.h" 13 #include "2common.h" 14 #include "2rsa.h" 15 #include "2sha.h" 16 #include "vb2_common.h" 17 #include "host_common.h" 18 #include "host_key2.h" 19 #include "host_misc.h" 20 21 struct vb2_text_vs_enum vb2_text_vs_algorithm[] = { 22 {"RSA1024 SHA1", VB2_ALG_RSA1024_SHA1}, 23 {"RSA1024 SHA256", VB2_ALG_RSA1024_SHA256}, 24 {"RSA1024 SHA512", VB2_ALG_RSA1024_SHA512}, 25 {"RSA2048 SHA1", VB2_ALG_RSA2048_SHA1}, 26 {"RSA2048 SHA256", VB2_ALG_RSA2048_SHA256}, 27 {"RSA2048 SHA512", VB2_ALG_RSA2048_SHA512}, 28 {"RSA4096 SHA1", VB2_ALG_RSA4096_SHA1}, 29 {"RSA4096 SHA256", VB2_ALG_RSA4096_SHA256}, 30 {"RSA4096 SHA512", VB2_ALG_RSA4096_SHA512}, 31 {"RSA8192 SHA1", VB2_ALG_RSA8192_SHA1}, 32 {"RSA8192 SHA256", VB2_ALG_RSA8192_SHA256}, 33 {"RSA8192 SHA512", VB2_ALG_RSA8192_SHA512}, 34 {0, 0} 35 }; 36 37 struct vb2_text_vs_enum vb2_text_vs_sig[] = { 38 {"RSA1024", VB2_SIG_RSA1024}, 39 {"RSA2048", VB2_SIG_RSA2048}, 40 {"RSA4096", VB2_SIG_RSA4096}, 41 {"RSA8192", VB2_SIG_RSA8192}, 42 {0, 0} 43 }; 44 45 struct vb2_text_vs_enum vb2_text_vs_hash[] = { 46 {"SHA1", VB2_HASH_SHA1}, 47 {"SHA256", VB2_HASH_SHA256}, 48 {"SHA512", VB2_HASH_SHA512}, 49 {0, 0} 50 }; 51 52 const struct vb2_text_vs_enum *vb2_lookup_by_num( 53 const struct vb2_text_vs_enum *table, 54 const unsigned int num) 55 { 56 for (; table->name; table++) 57 if (table->num == num) 58 return table; 59 return 0; 60 } 61 62 const struct vb2_text_vs_enum *vb2_lookup_by_name( 63 const struct vb2_text_vs_enum *table, 64 const char *name) 65 { 66 for (; table->name; table++) 67 if (!strcasecmp(table->name, name)) 68 return table; 69 return 0; 70 } 71 72 void vb2_private_key_free(struct vb2_private_key *key) 73 { 74 if (!key) 75 return; 76 77 if (key->rsa_private_key) 78 RSA_free(key->rsa_private_key); 79 80 if (key->desc) 81 free(key->desc); 82 83 free(key); 84 } 85 86 int vb2_private_key_unpack(struct vb2_private_key **key_ptr, 87 const uint8_t *buf, 88 uint32_t size) 89 { 90 const struct vb2_packed_private_key *pkey = 91 (const struct vb2_packed_private_key *)buf; 92 struct vb2_private_key *key; 93 const unsigned char *start; 94 uint32_t min_offset = 0; 95 96 *key_ptr = NULL; 97 98 /* 99 * Check magic number. 100 * 101 * TODO: If it doesn't match, pass through to the old packed key format. 102 */ 103 if (pkey->c.magic != VB2_MAGIC_PACKED_PRIVATE_KEY) 104 return VB2_ERROR_UNPACK_PRIVATE_KEY_MAGIC; 105 106 if (vb2_verify_common_header(buf, size)) 107 return VB2_ERROR_UNPACK_PRIVATE_KEY_HEADER; 108 109 /* Make sure key data is inside */ 110 if (vb2_verify_common_member(pkey, &min_offset, 111 pkey->key_offset, pkey->key_size)) 112 return VB2_ERROR_UNPACK_PRIVATE_KEY_DATA; 113 114 /* 115 * Check for compatible version. No need to check minor version, since 116 * that's compatible across readers matching the major version, and we 117 * haven't added any new fields. 118 */ 119 if (pkey->c.struct_version_major != 120 VB2_PACKED_PRIVATE_KEY_VERSION_MAJOR) 121 return VB2_ERROR_UNPACK_PRIVATE_KEY_STRUCT_VERSION; 122 123 /* Allocate the new key */ 124 key = calloc(1, sizeof(*key)); 125 if (!key) 126 return VB2_ERROR_UNPACK_PRIVATE_KEY_ALLOC; 127 128 /* Copy key algorithms and guid */ 129 key->sig_alg = pkey->sig_alg; 130 key->hash_alg = pkey->hash_alg; 131 key->guid = pkey->guid; 132 133 /* Unpack RSA key */ 134 if (pkey->sig_alg == VB2_SIG_NONE) { 135 if (pkey->key_size != 0) { 136 free(key); 137 return VB2_ERROR_UNPACK_PRIVATE_KEY_HASH; 138 } 139 } else { 140 start = (const unsigned char *)(buf + pkey->key_offset); 141 key->rsa_private_key = d2i_RSAPrivateKey(0, &start, 142 pkey->key_size); 143 if (!key->rsa_private_key) { 144 free(key); 145 return VB2_ERROR_UNPACK_PRIVATE_KEY_RSA; 146 } 147 } 148 149 /* Key description */ 150 if (pkey->c.desc_size) { 151 if (vb2_private_key_set_desc( 152 key, (const char *)(buf + pkey->c.fixed_size))) { 153 vb2_private_key_free(key); 154 return VB2_ERROR_UNPACK_PRIVATE_KEY_DESC; 155 } 156 } 157 158 *key_ptr = key; 159 return VB2_SUCCESS; 160 } 161 162 int vb2_private_key_read(struct vb2_private_key **key_ptr, 163 const char *filename) 164 { 165 uint32_t size = 0; 166 uint8_t *buf; 167 int rv; 168 169 *key_ptr = NULL; 170 171 rv = vb2_read_file(filename, &buf, &size); 172 if (rv) 173 return rv; 174 175 rv = vb2_private_key_unpack(key_ptr, buf, size); 176 177 free(buf); 178 179 return rv; 180 } 181 182 int vb2_private_key_read_pem(struct vb2_private_key **key_ptr, 183 const char *filename) 184 { 185 struct vb2_private_key *key; 186 FILE *f; 187 188 *key_ptr = NULL; 189 190 /* Allocate the new key */ 191 key = calloc(1, sizeof(*key)); 192 if (!key) 193 return VB2_ERROR_READ_PEM_ALLOC; 194 195 /* Read private key */ 196 f = fopen(filename, "rb"); 197 if (!f) { 198 free(key); 199 return VB2_ERROR_READ_PEM_FILE_OPEN; 200 } 201 202 key->rsa_private_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); 203 fclose(f); 204 205 if (!key->rsa_private_key) { 206 free(key); 207 return VB2_ERROR_READ_PEM_RSA; 208 } 209 210 *key_ptr = key; 211 return VB2_SUCCESS; 212 } 213 214 int vb2_private_key_set_desc(struct vb2_private_key *key, const char *desc) 215 { 216 if (key->desc) 217 free(key->desc); 218 219 if (desc) { 220 key->desc = strdup(desc); 221 if (!key->desc) 222 return VB2_ERROR_PRIVATE_KEY_SET_DESC; 223 } else { 224 key->desc = NULL; 225 } 226 227 return VB2_SUCCESS; 228 } 229 230 int vb2_private_key_write(const struct vb2_private_key *key, 231 const char *filename) 232 { 233 struct vb2_packed_private_key pkey = { 234 .c.magic = VB2_MAGIC_PACKED_PRIVATE_KEY, 235 .c.struct_version_major = VB2_PACKED_PRIVATE_KEY_VERSION_MAJOR, 236 .c.struct_version_minor = VB2_PACKED_PRIVATE_KEY_VERSION_MINOR, 237 .c.fixed_size = sizeof(pkey), 238 .sig_alg = key->sig_alg, 239 .hash_alg = key->hash_alg, 240 .guid = key->guid, 241 }; 242 uint8_t *buf; 243 uint8_t *rsabuf = NULL; 244 int rsalen = 0; 245 int rv; 246 247 memcpy(&pkey.guid, &key->guid, sizeof(pkey.guid)); 248 249 pkey.c.desc_size = vb2_desc_size(key->desc); 250 251 if (key->sig_alg != VB2_SIG_NONE) { 252 /* Pack RSA key */ 253 rsalen = i2d_RSAPrivateKey(key->rsa_private_key, &rsabuf); 254 if (rsalen <= 0 || !rsabuf) 255 return VB2_ERROR_PRIVATE_KEY_WRITE_RSA; 256 } 257 258 pkey.key_offset = pkey.c.fixed_size + pkey.c.desc_size; 259 pkey.key_size = roundup32(rsalen); 260 pkey.c.total_size = pkey.key_offset + pkey.key_size; 261 262 /* Pack private key */ 263 buf = calloc(1, pkey.c.total_size); 264 if (!buf) { 265 free(rsabuf); 266 return VB2_ERROR_PRIVATE_KEY_WRITE_ALLOC; 267 } 268 269 memcpy(buf, &pkey, sizeof(pkey)); 270 271 /* strcpy() is ok here because we checked the length above */ 272 if (key->desc) 273 strcpy((char *)buf + pkey.c.fixed_size, key->desc); 274 275 if (rsabuf) { 276 memcpy(buf + pkey.key_offset, rsabuf, rsalen); 277 free(rsabuf); 278 } 279 280 rv = vb2_write_object(filename, buf); 281 free(buf); 282 283 return rv ? VB2_ERROR_PRIVATE_KEY_WRITE_FILE : VB2_SUCCESS; 284 } 285 286 int vb2_private_key_hash(const struct vb2_private_key **key_ptr, 287 enum vb2_hash_algorithm hash_alg) 288 { 289 *key_ptr = NULL; 290 291 switch (hash_alg) { 292 #if VB2_SUPPORT_SHA1 293 case VB2_HASH_SHA1: 294 { 295 static const struct vb2_private_key key = { 296 .hash_alg = VB2_HASH_SHA1, 297 .sig_alg = VB2_SIG_NONE, 298 .desc = "Unsigned SHA1", 299 .guid = VB2_GUID_NONE_SHA1, 300 }; 301 *key_ptr = &key; 302 return VB2_SUCCESS; 303 } 304 #endif 305 #if VB2_SUPPORT_SHA256 306 case VB2_HASH_SHA256: 307 { 308 static const struct vb2_private_key key = { 309 .hash_alg = VB2_HASH_SHA256, 310 .sig_alg = VB2_SIG_NONE, 311 .desc = "Unsigned SHA-256", 312 .guid = VB2_GUID_NONE_SHA256, 313 }; 314 *key_ptr = &key; 315 return VB2_SUCCESS; 316 } 317 #endif 318 #if VB2_SUPPORT_SHA512 319 case VB2_HASH_SHA512: 320 { 321 static const struct vb2_private_key key = { 322 .hash_alg = VB2_HASH_SHA512, 323 .sig_alg = VB2_SIG_NONE, 324 .desc = "Unsigned SHA-512", 325 .guid = VB2_GUID_NONE_SHA512, 326 }; 327 *key_ptr = &key; 328 return VB2_SUCCESS; 329 } 330 #endif 331 default: 332 return VB2_ERROR_PRIVATE_KEY_HASH; 333 } 334 } 335 336 int vb2_public_key_alloc(struct vb2_public_key **key_ptr, 337 enum vb2_signature_algorithm sig_alg) 338 { 339 struct vb2_public_key *key; 340 uint32_t key_data_size = vb2_packed_key_size(sig_alg); 341 342 /* The buffer contains the key, its GUID, and its packed data */ 343 uint32_t buf_size = sizeof(*key) + sizeof(struct vb2_guid) + 344 key_data_size; 345 346 if (!key_data_size) 347 return VB2_ERROR_PUBLIC_KEY_ALLOC_SIZE; 348 349 key = calloc(1, buf_size); 350 if (!key) 351 return VB2_ERROR_PUBLIC_KEY_ALLOC; 352 353 key->guid = (struct vb2_guid *)(key + 1); 354 key->sig_alg = sig_alg; 355 356 *key_ptr = key; 357 358 return VB2_SUCCESS; 359 } 360 361 void vb2_public_key_free(struct vb2_public_key *key) 362 { 363 if (!key) 364 return; 365 366 if (key->desc) 367 free((void *)key->desc); 368 369 free(key); 370 } 371 372 uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key) 373 { 374 return (uint8_t *)(key->guid + 1); 375 } 376 377 int vb2_public_key_read_keyb(struct vb2_public_key **key_ptr, 378 const char *filename) 379 { 380 struct vb2_public_key *key = NULL; 381 uint8_t *key_data, *key_buf; 382 uint32_t key_size; 383 enum vb2_signature_algorithm sig_alg; 384 385 *key_ptr = NULL; 386 387 if (vb2_read_file(filename, &key_data, &key_size)) 388 return VB2_ERROR_READ_KEYB_DATA; 389 390 /* Guess the signature algorithm from the key size */ 391 for (sig_alg = VB2_SIG_RSA1024; sig_alg <= VB2_SIG_RSA8192; sig_alg++) { 392 if (key_size == vb2_packed_key_size(sig_alg)) 393 break; 394 } 395 if (sig_alg > VB2_SIG_RSA8192) { 396 free(key_data); 397 return VB2_ERROR_READ_KEYB_SIZE; 398 } 399 400 if (vb2_public_key_alloc(&key, sig_alg)) { 401 free(key_data); 402 return VB2_ERROR_READ_KEYB_ALLOC; 403 } 404 405 /* Copy data from the file buffer to the public key buffer */ 406 key_buf = vb2_public_key_packed_data(key); 407 memcpy(key_buf, key_data, key_size); 408 free(key_data); 409 410 if (vb2_unpack_key_data(key, key_buf, key_size)) { 411 vb2_public_key_free(key); 412 return VB2_ERROR_READ_KEYB_UNPACK; 413 } 414 415 *key_ptr = key; 416 417 return VB2_SUCCESS; 418 } 419 420 int vb2_public_key_set_desc(struct vb2_public_key *key, const char *desc) 421 { 422 if (key->desc) 423 free((void *)key->desc); 424 425 if (desc) { 426 key->desc = strdup(desc); 427 if (!key->desc) 428 return VB2_ERROR_PUBLIC_KEY_SET_DESC; 429 } else { 430 key->desc = NULL; 431 } 432 433 return VB2_SUCCESS; 434 } 435 436 int vb2_packed_key_read(struct vb2_packed_key **key_ptr, 437 const char *filename) 438 { 439 struct vb2_public_key key; 440 uint8_t *buf; 441 uint32_t size; 442 443 *key_ptr = NULL; 444 445 if (vb2_read_file(filename, &buf, &size)) 446 return VB2_ERROR_READ_PACKED_KEY_DATA; 447 448 /* Sanity check: make sure key unpacks properly */ 449 if (vb2_unpack_key(&key, buf, size)) 450 return VB2_ERROR_READ_PACKED_KEY; 451 452 *key_ptr = (struct vb2_packed_key *)buf; 453 454 return VB2_SUCCESS; 455 } 456 457 int vb2_public_key_pack(struct vb2_packed_key **key_ptr, 458 const struct vb2_public_key *pubk) 459 { 460 struct vb2_packed_key key = { 461 .c.magic = VB2_MAGIC_PACKED_KEY, 462 .c.struct_version_major = VB2_PACKED_KEY_VERSION_MAJOR, 463 .c.struct_version_minor = VB2_PACKED_KEY_VERSION_MINOR, 464 }; 465 uint8_t *buf; 466 uint32_t *buf32; 467 468 *key_ptr = NULL; 469 470 /* Calculate sizes and offsets */ 471 key.c.fixed_size = sizeof(key); 472 key.c.desc_size = vb2_desc_size(pubk->desc); 473 key.key_offset = key.c.fixed_size + key.c.desc_size; 474 475 if (pubk->sig_alg != VB2_SIG_NONE) { 476 key.key_size = vb2_packed_key_size(pubk->sig_alg); 477 if (!key.key_size) 478 return VB2_ERROR_PUBLIC_KEY_PACK_SIZE; 479 } 480 481 key.c.total_size = key.key_offset + key.key_size; 482 483 /* Copy/initialize fields */ 484 key.key_version = pubk->version; 485 key.sig_alg = pubk->sig_alg; 486 key.hash_alg = pubk->hash_alg; 487 key.guid = *pubk->guid; 488 489 /* Allocate the new buffer */ 490 buf = calloc(1, key.c.total_size); 491 492 /* Copy data into the buffer */ 493 memcpy(buf, &key, sizeof(key)); 494 495 /* strcpy() is safe because we allocated above based on strlen() */ 496 if (pubk->desc && *pubk->desc) { 497 strcpy((char *)(buf + key.c.fixed_size), pubk->desc); 498 buf[key.c.fixed_size + key.c.desc_size - 1] = 0; 499 } 500 501 if (pubk->sig_alg != VB2_SIG_NONE) { 502 /* Re-pack the key arrays */ 503 buf32 = (uint32_t *)(buf + key.key_offset); 504 buf32[0] = pubk->arrsize; 505 buf32[1] = pubk->n0inv; 506 memcpy(buf32 + 2, pubk->n, pubk->arrsize * sizeof(uint32_t)); 507 memcpy(buf32 + 2 + pubk->arrsize, pubk->rr, 508 pubk->arrsize * sizeof(uint32_t)); 509 } 510 511 *key_ptr = (struct vb2_packed_key *)buf; 512 513 return VB2_SUCCESS; 514 } 515 516 int vb2_public_key_hash(struct vb2_public_key *key, 517 enum vb2_hash_algorithm hash_alg) 518 { 519 switch (hash_alg) { 520 #if VB2_SUPPORT_SHA1 521 case VB2_HASH_SHA1: 522 key->desc = "Unsigned SHA1"; 523 break; 524 #endif 525 #if VB2_SUPPORT_SHA256 526 case VB2_HASH_SHA256: 527 key->desc = "Unsigned SHA-256"; 528 break; 529 #endif 530 #if VB2_SUPPORT_SHA512 531 case VB2_HASH_SHA512: 532 key->desc = "Unsigned SHA-512"; 533 break; 534 #endif 535 default: 536 return VB2_ERROR_PUBLIC_KEY_HASH; 537 } 538 539 key->sig_alg = VB2_SIG_NONE; 540 key->hash_alg = hash_alg; 541 key->guid = vb2_hash_guid(hash_alg); 542 return VB2_SUCCESS; 543 } 544 545 enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa) 546 { 547 int bits = BN_num_bits(rsa->n); 548 549 switch (bits) { 550 case 1024: 551 return VB2_SIG_RSA1024; 552 case 2048: 553 return VB2_SIG_RSA2048; 554 case 4096: 555 return VB2_SIG_RSA4096; 556 case 8192: 557 return VB2_SIG_RSA8192; 558 } 559 560 /* no clue */ 561 return VB2_SIG_INVALID; 562 } 563 564 int vb2_public_key_write(const struct vb2_public_key *key, 565 const char *filename) 566 { 567 struct vb2_packed_key *pkey; 568 int ret; 569 570 ret = vb2_public_key_pack(&pkey, key); 571 if (ret) 572 return ret; 573 574 ret = vb2_write_object(filename, pkey); 575 576 free(pkey); 577 return ret; 578 } 579