1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2023-2024 NXP 4 */ 5 #include <assert.h> 6 #include <caam_desc_helper.h> 7 #include <caam_key.h> 8 #include <caam_status.h> 9 #include <caam_trace.h> 10 #include <caam_utils_mem.h> 11 #include <crypto/crypto.h> 12 #include <kernel/panic.h> 13 #include <mm/core_memprot.h> 14 #include <stdint.h> 15 #include <string.h> 16 #include <tee/cache.h> 17 #include <tee_api_defines.h> 18 #include <trace.h> 19 #include <utee_types.h> 20 21 /* 22 * CAAM Key magic number. 23 * When the first 32 bits of a key buffer are equal to this value, the buffer 24 * is a serialized CAAM key structure. 25 */ 26 #define MAGIC_NUMBER 0xCAAFBFFB 27 28 /* 29 * Because the CAAM driver relies on this magic number to determine if the key 30 * is plain text or black, collision can happen. A randomly generated plain text 31 * key could feature the magic number. That's unlikely but still possible. 32 * 33 * Regarding the possibility of collision or forging attack, there are no 34 * security concerns. Forging and trying to make a plain text key look like a 35 * black key, won't do much. If the key is forged to look like an ECB Black 36 * key, the singing operation will output a corrupted result. If the key is 37 * forged to look like a CCM Black key, the import key will fail (because the 38 * MAC verification) and no signing operation will be done. 39 */ 40 41 #define BLOB_BKEK_SIZE 32 /* Blob key encryption key size */ 42 #define BLOB_MAC_SIZE 16 /* Blob MAC size */ 43 #define BLOB_PAD_SIZE (BLOB_BKEK_SIZE + BLOB_MAC_SIZE) 44 45 /* 46 * CAAM Blob key modifier 47 * Key modifier used to derive Blob-key encryption key (BKEK) from the CAAM 48 * master key. 49 * 50 * A CAAM black key is encrypted using a volatile Job Descriptor key encryption 51 * key or JDKEK. Black keys are not intended for storage of keys across SoC 52 * power cycles. The JDKEK is re-generated upon every power cycle (reset, 53 * suspend/resume ...) or CAAM RNG re-seed. 54 * 55 * To retain key across power cycles, the black key must be encapsulated as a 56 * blob. The blob key encryption key is derived from the CAAM master key which 57 * makes it non-volatile and can be re-created when the chip powers up again. 58 */ 59 #define KEY_BLOB_MODIFIER_SIZE 16 60 #define KEY_BLOB_MODIFIER "NXP_KEY_MODIFIER" 61 static_assert(sizeof(KEY_BLOB_MODIFIER) >= KEY_BLOB_MODIFIER_SIZE); 62 static uint8_t *key_blob_modifier; 63 64 /* 65 * Serialized CAAM key structure format. 66 * 67 * If the incoming key buffer is the following: 68 * | Magic number | key type | key size | key blob buffer | 69 * The CAAM Key structure will be populated as following: 70 * struct caamkey { 71 * .key_type = key type, 72 * .key_size = key size, 73 * .is_blob = true, 74 * .buf = key blob buffer 75 * } 76 * 77 * If the incoming key buffer is the following: 78 * | Key buffer | 79 * The CAAM Key structure will be populated as following: 80 * struct caamkey { 81 * .key_type = CAAM_KEY_PLAIN_TEXT, 82 * .key_size = sizeof(Key buffer), 83 * .is_blob = false, 84 * .buf = key buffer 85 * } 86 */ 87 struct caam_key_serialized { 88 uint32_t magic_number; /* Magic number */ 89 uint32_t key_type; /* Black key type */ 90 uint32_t sec_size; /* The original plain text key size */ 91 uint8_t key[]; 92 }; 93 94 /* 95 * CAAM key type enumeration to string 96 */ 97 static const char *const caam_key_type_to_str[] __maybe_unused = { 98 [CAAM_KEY_PLAIN_TEXT] = "Plain Text", 99 [CAAM_KEY_BLACK_ECB] = "Black ECB", 100 [CAAM_KEY_BLACK_CCM] = "Black CCM", 101 }; 102 103 static struct caam_key_serialized *data_to_serialized_key(const uint8_t *data, 104 size_t size) 105 { 106 assert(data && size); 107 assert(size > sizeof(struct caam_key_serialized)); 108 109 /* 110 * It's important to make sure uint8_t and caam_key_serialized{} are 111 * actually aligned for performance purpose. 112 * 113 * A __packed attribute to caam_key_serialized{} could solve the 114 * alignment issue but at the cost of un-optimize memory access. 115 * To avoid using the __packed attribute, caam_key_serialized{} is 116 * defined to be aligned on uint8_t. The following assert checks 117 * for this alignment. 118 */ 119 assert(IS_ALIGNED_WITH_TYPE(data, struct caam_key_serialized)); 120 121 /* 122 * The cast to void* instead of struct caam_key_serialized* is needed 123 * to avoid the cast alignment compilation warning. 124 */ 125 return (void *)data; 126 } 127 128 /* 129 * Return the CAAM key type of the given key buffer 130 * 131 * @data Input buffer 132 * @size Input buffer size 133 */ 134 static enum caam_key_type get_key_type(const uint8_t *data, size_t size) 135 { 136 struct caam_key_serialized *key = data_to_serialized_key(data, size); 137 138 if (key->magic_number != MAGIC_NUMBER) 139 return CAAM_KEY_PLAIN_TEXT; 140 141 return key->key_type; 142 } 143 144 /* 145 * Return the CAAM key size of the given key buffer 146 * 147 * @data Input buffer 148 * @size Input buffer size 149 */ 150 static size_t get_key_sec_size(const uint8_t *data, size_t size) 151 { 152 struct caam_key_serialized *key = data_to_serialized_key(data, size); 153 154 if (key->magic_number != MAGIC_NUMBER) 155 return size; 156 157 return key->sec_size; 158 } 159 160 /* 161 * Return the CAAM key buffer pointer of the given key buffer 162 * 163 * @data Input buffer 164 * @size Input buffer size 165 */ 166 static unsigned long get_key_buf_offset(const uint8_t *data, size_t size) 167 { 168 struct caam_key_serialized *key = data_to_serialized_key(data, size); 169 170 if (key->magic_number != MAGIC_NUMBER) 171 return 0; 172 else 173 return offsetof(struct caam_key_serialized, key); 174 } 175 176 /* 177 * Return the CAAM key buffer size of the given key buffer 178 * 179 * @data Input buffer 180 * @size Input buffer size 181 */ 182 static size_t get_key_buf_size(const uint8_t *data, size_t size) 183 { 184 struct caam_key_serialized *key = data_to_serialized_key(data, size); 185 186 /* 187 * In the caam_key_serialized{}, the last element of the structure is 188 * a variable-sized buffer. 189 */ 190 return size - sizeof(*key); 191 } 192 193 size_t caam_key_get_alloc_size(const struct caamkey *key) 194 { 195 if (!key) 196 return 0; 197 198 /* A blob size is independent from the key encryption algorithm */ 199 if (key->is_blob) 200 return key->sec_size + BLOB_PAD_SIZE; 201 202 switch (key->key_type) { 203 case CAAM_KEY_PLAIN_TEXT: 204 /* 205 * If the key is plain text, the allocation size is equal to the 206 * key size and no blob operation on this key is possible. 207 */ 208 return key->sec_size; 209 case CAAM_KEY_BLACK_ECB: 210 /* ECB-black key must be a multiple of 16 bytes */ 211 return ROUNDUP(key->sec_size, 16); 212 case CAAM_KEY_BLACK_CCM: 213 /* 214 * CCM-black key must be a multiple of 8 bytes. The nonce and 215 * ICV add another 12 bytes to the allocation size 216 */ 217 return ROUNDUP(key->sec_size, 8) + BLACK_KEY_NONCE_SIZE + 218 BLACK_KEY_ICV_SIZE; 219 default: 220 return 0; 221 } 222 } 223 224 void caam_key_dump(const char *trace, const struct caamkey *key) 225 { 226 if (!key || !trace) 227 return; 228 229 if (key->key_type >= CAAM_KEY_MAX_VALUE) 230 return; 231 232 KEY_TRACE("%s key_type:%s key_size:%zu is_blob:%s addr:%p", 233 caam_key_type_to_str[key->key_type], trace, key->sec_size, 234 key->is_blob ? "yes" : "no", key->buf.data); 235 236 if (key->buf.data) 237 KEY_DUMPBUF("Key data", key->buf.data, key->buf.length); 238 } 239 240 enum caam_status caam_key_alloc(struct caamkey *key) 241 { 242 size_t alloc_size = 0; 243 244 if (!key) 245 return CAAM_BAD_PARAM; 246 247 if (key->buf.data) { 248 KEY_TRACE("Key already allocated"); 249 return CAAM_BAD_PARAM; 250 } 251 252 alloc_size = caam_key_get_alloc_size(key); 253 if (!alloc_size) 254 return CAAM_FAILURE; 255 256 return caam_calloc_align_buf(&key->buf, alloc_size); 257 } 258 259 void caam_key_free(struct caamkey *key) 260 { 261 if (!key) 262 return; 263 264 caam_free_buf(&key->buf); 265 } 266 267 void caam_key_cache_op(enum utee_cache_operation op, const struct caamkey *key) 268 { 269 if (!key) 270 return; 271 272 if (!key->buf.nocache) 273 cache_operation(op, key->buf.data, key->buf.length); 274 } 275 276 #define BLOB_OP_DESC_ENTRIES 12 277 enum caam_status caam_key_operation_blob(const struct caamkey *in_key, 278 struct caamkey *out_key) 279 { 280 enum caam_status status = CAAM_FAILURE; 281 struct caam_jobctx jobctx = { }; 282 uint32_t opflag = PROT_BLOB_TYPE(BLACK_KEY); 283 uint32_t *desc = NULL; 284 size_t output_buffer_size = 0; 285 size_t input_buffer_size = 0; 286 287 assert(in_key && out_key); 288 289 KEY_TRACE("Blob %scapsulation of the following key", 290 in_key->is_blob ? "de" : "en"); 291 292 caam_key_dump("Blob input key", in_key); 293 294 /* This function blobs or un-blobs */ 295 if (in_key->is_blob == out_key->is_blob) { 296 KEY_TRACE("Only one key must be defined as a blob"); 297 return CAAM_BAD_PARAM; 298 } 299 300 /* A black blob cannot take a plain test key as input */ 301 if (out_key->key_type == CAAM_KEY_PLAIN_TEXT || 302 in_key->key_type == CAAM_KEY_PLAIN_TEXT) { 303 KEY_TRACE("A blob in/out operation cannot be plain text"); 304 return CAAM_BAD_PARAM; 305 } 306 307 /* The key type must remain the same */ 308 if (out_key->key_type != in_key->key_type) { 309 KEY_TRACE("The in/out keys must have the same key type"); 310 return CAAM_BAD_PARAM; 311 } 312 313 /* Define blob operation direction */ 314 if (out_key->is_blob) 315 opflag |= BLOB_ENCAPS; 316 else 317 opflag |= BLOB_DECAPS; 318 319 /* Build OP flags depending on the blob type */ 320 switch (out_key->key_type) { 321 case CAAM_KEY_BLACK_ECB: 322 opflag |= PROT_BLOB_INFO(ECB); 323 break; 324 case CAAM_KEY_BLACK_CCM: 325 opflag |= PROT_BLOB_INFO(CCM); 326 break; 327 default: 328 return CAAM_BAD_PARAM; 329 } 330 331 /* Allocate the descriptor */ 332 desc = caam_calloc_desc(BLOB_OP_DESC_ENTRIES); 333 if (!desc) { 334 KEY_TRACE("CAAM Context Descriptor Allocation error"); 335 return CAAM_OUT_MEMORY; 336 } 337 338 status = caam_key_alloc(out_key); 339 if (status) { 340 KEY_TRACE("Key output allocation error"); 341 goto err; 342 } 343 344 /* Define input and output buffer size */ 345 if (out_key->is_blob) { 346 /* 347 * For a blob operation, the input key size is the original key 348 * size of the black key. 349 * The output key size is the final blob size. 350 */ 351 input_buffer_size = in_key->sec_size; 352 output_buffer_size = out_key->buf.length; 353 } else { 354 /* 355 * For an non-blob operation, the input key size is the original 356 * key size of the black key. 357 * The output key size is the key security size. 358 */ 359 input_buffer_size = in_key->buf.length; 360 output_buffer_size = out_key->sec_size; 361 } 362 363 /* Create the blob encapsulation/decapsulation descriptor */ 364 caam_desc_init(desc); 365 caam_desc_add_word(desc, DESC_HEADER(0)); 366 367 /* Load the key modifier */ 368 caam_desc_add_word(desc, 369 LD_NOIMM(CLASS_2, REG_KEY, KEY_BLOB_MODIFIER_SIZE)); 370 caam_desc_add_ptr(desc, virt_to_phys((void *)key_blob_modifier)); 371 372 /* Define the Input data sequence */ 373 caam_desc_add_word(desc, SEQ_IN_PTR(input_buffer_size)); 374 caam_desc_add_ptr(desc, in_key->buf.paddr); 375 376 /* Define the Output data sequence */ 377 caam_desc_add_word(desc, SEQ_OUT_PTR(output_buffer_size)); 378 caam_desc_add_ptr(desc, out_key->buf.paddr); 379 caam_desc_add_word(desc, opflag); 380 381 KEY_DUMPDESC(desc); 382 383 cache_operation(TEE_CACHECLEAN, key_blob_modifier, 384 KEY_BLOB_MODIFIER_SIZE); 385 caam_key_cache_op(TEE_CACHECLEAN, in_key); 386 caam_key_cache_op(TEE_CACHECLEAN, out_key); 387 388 jobctx.desc = desc; 389 status = caam_jr_enqueue(&jobctx, NULL); 390 391 if (status == CAAM_NO_ERROR) { 392 KEY_TRACE("CAAM Blob %scapsulation Done", 393 out_key->is_blob ? "En" : "De"); 394 395 caam_key_cache_op(TEE_CACHEINVALIDATE, out_key); 396 caam_key_dump("Blob output key", out_key); 397 398 goto out; 399 } else { 400 KEY_TRACE("CAAM Blob Status 0x%08" PRIx32 "", jobctx.status); 401 } 402 403 err: 404 caam_key_free(out_key); 405 out: 406 caam_free_desc(&desc); 407 return status; 408 } 409 410 enum caam_status caam_key_deserialize_from_bin(uint8_t *data, size_t size, 411 struct caamkey *key, 412 size_t sec_size) 413 { 414 enum caam_status status = CAAM_FAILURE; 415 struct caamkey blob = { }; 416 417 assert(data && size && key); 418 419 KEY_TRACE("Deserialization binary buffer"); 420 KEY_DUMPBUF("Deserialize key buffer input", data, size); 421 422 /* 423 * If a security key size is given, use it. Otherwise, rely on 424 * the buffer size. 425 * In some case, like ECC keys, the bignum size is less than the 426 * security size and it requires the key to be padded with 0's. 427 */ 428 if (sec_size == 0) 429 sec_size = get_key_sec_size(data, size); 430 431 blob.key_type = get_key_type(data, size); 432 blob.sec_size = sec_size; 433 blob.is_blob = true; 434 435 if (blob.key_type == CAAM_KEY_PLAIN_TEXT) { 436 key->sec_size = blob.sec_size; 437 key->key_type = blob.key_type; 438 key->is_blob = false; 439 440 status = caam_key_alloc(key); 441 if (status) { 442 KEY_TRACE("Key allocation error"); 443 return status; 444 } 445 446 /* Some asymmetric keys have leading zeros we must preserve */ 447 memcpy(key->buf.data + key->buf.length - size, data, size); 448 449 return CAAM_NO_ERROR; 450 } 451 452 status = caam_key_alloc(&blob); 453 if (status) { 454 KEY_TRACE("Key allocation error"); 455 return status; 456 } 457 458 memcpy(blob.buf.data, data + get_key_buf_offset(data, size), 459 get_key_buf_size(data, size)); 460 461 /* Set destination key */ 462 key->key_type = blob.key_type; 463 key->sec_size = blob.sec_size; 464 key->is_blob = false; 465 466 /* De-blob operation */ 467 status = caam_key_operation_blob(&blob, key); 468 if (status) { 469 KEY_TRACE("De-blob operation fail"); 470 goto out; 471 } 472 473 KEY_TRACE("Deserialization binary buffer done"); 474 caam_key_dump("Deserialization output key", key); 475 out: 476 caam_key_free(&blob); 477 return status; 478 } 479 480 enum caam_status caam_key_serialize_to_bin(uint8_t *data, size_t size, 481 const struct caamkey *key) 482 { 483 struct caam_key_serialized key_ser = { }; 484 struct caamkey blob = { }; 485 enum caam_status status = CAAM_FAILURE; 486 size_t serialized_size = 0; 487 488 assert(data && size && key); 489 490 caam_key_dump("Serialization input key", key); 491 492 /* If the key is plain text, just copy key to buffer */ 493 if (key->key_type == CAAM_KEY_PLAIN_TEXT) { 494 if (size < key->buf.length) { 495 KEY_TRACE("Buffer is too short"); 496 return CAAM_SHORT_BUFFER; 497 } 498 499 memcpy(data, key->buf.data, key->buf.length); 500 501 return CAAM_NO_ERROR; 502 } 503 504 /* The input key must not be a blob */ 505 assert(!key->is_blob); 506 507 /* Blob the given key for serialization and export */ 508 blob.is_blob = true; 509 blob.sec_size = key->sec_size; 510 blob.key_type = key->key_type; 511 512 /* 513 * Check if the destination is big enough for the black blob buffer and 514 * header. 515 */ 516 status = caam_key_serialized_size(&blob, &serialized_size); 517 if (status) 518 return status; 519 520 if (size < serialized_size) { 521 KEY_TRACE("Destination buffer is too short %zu < %zu", size, 522 serialized_size); 523 return CAAM_OUT_MEMORY; 524 } 525 526 /* Blob the given key */ 527 status = caam_key_operation_blob(key, &blob); 528 if (status) { 529 KEY_TRACE("Blob operation fail"); 530 return status; 531 } 532 533 /* Copy the header to destination */ 534 key_ser.magic_number = MAGIC_NUMBER; 535 key_ser.key_type = blob.key_type; 536 key_ser.sec_size = blob.sec_size; 537 memcpy(data, &key_ser, sizeof(key_ser)); 538 539 /* Copy the key buffer */ 540 memcpy(data + sizeof(key_ser), blob.buf.data, blob.buf.length); 541 542 KEY_DUMPBUF("Key data", data, size); 543 544 caam_key_free(&blob); 545 546 return status; 547 } 548 549 enum caam_status caam_key_serialized_size(const struct caamkey *key, 550 size_t *size) 551 { 552 assert(key && size); 553 554 /* For a plain text key, the serialized key is identical to the key */ 555 *size = key->buf.length; 556 557 /* 558 * For black keys, the serialized key includes the header and must be 559 * in a blob format 560 */ 561 if (key->key_type != CAAM_KEY_PLAIN_TEXT) { 562 size_t alloc = 0; 563 const struct caamkey tmp = { 564 .key_type = key->key_type, 565 .sec_size = key->sec_size, 566 .is_blob = true, 567 }; 568 569 alloc = caam_key_get_alloc_size(&tmp); 570 if (!alloc) 571 return CAAM_FAILURE; 572 573 *size = alloc + sizeof(struct caam_key_serialized); 574 } 575 576 return CAAM_NO_ERROR; 577 } 578 579 enum caam_status caam_key_deserialize_from_bn(const struct bignum *inkey, 580 struct caamkey *outkey, 581 size_t size_sec) 582 { 583 enum caam_status status = CAAM_FAILURE; 584 uint8_t *buf = NULL; 585 size_t size = 0; 586 587 assert(inkey && outkey); 588 589 KEY_TRACE("Deserialization bignum"); 590 591 /* Get bignum size */ 592 size = crypto_bignum_num_bytes((struct bignum *)inkey); 593 594 /* Allocate temporary buffer */ 595 buf = caam_calloc(size); 596 if (!buf) 597 return CAAM_OUT_MEMORY; 598 599 /* Convert bignum to binary */ 600 crypto_bignum_bn2bin(inkey, buf); 601 602 status = caam_key_deserialize_from_bin(buf, size, outkey, size_sec); 603 604 caam_key_dump("Output key", outkey); 605 606 caam_free(buf); 607 608 return status; 609 } 610 611 enum caam_status caam_key_serialize_to_bn(struct bignum *outkey, 612 const struct caamkey *inkey) 613 { 614 enum caam_status status = CAAM_FAILURE; 615 TEE_Result res = TEE_ERROR_GENERIC; 616 uint8_t *buf = NULL; 617 size_t size = 0; 618 619 assert(inkey && outkey); 620 621 KEY_TRACE("Serialization bignum"); 622 caam_key_dump("Input key", inkey); 623 624 status = caam_key_serialized_size(inkey, &size); 625 if (status) 626 return status; 627 628 buf = caam_calloc(size); 629 if (!buf) 630 return CAAM_OUT_MEMORY; 631 632 status = caam_key_serialize_to_bin(buf, size, inkey); 633 if (status) 634 goto out; 635 636 res = crypto_bignum_bin2bn(buf, size, outkey); 637 if (res) 638 status = CAAM_FAILURE; 639 out: 640 caam_free(buf); 641 642 return status; 643 } 644 645 #define MAX_DESC_ENTRIES 22 646 enum caam_status caam_key_black_encapsulation(struct caamkey *key, 647 enum caam_key_type key_type) 648 { 649 enum caam_status status = CAAM_FAILURE; 650 struct caambuf input_buf = { }; 651 struct caam_jobctx jobctx = { }; 652 uint32_t *desc = NULL; 653 654 assert(key); 655 assert(!key->is_blob && key->key_type == CAAM_KEY_PLAIN_TEXT); 656 assert(key_type != CAAM_KEY_PLAIN_TEXT); 657 658 KEY_TRACE("Black key encapsulation"); 659 660 /* Copy input plain text key to temp buffer */ 661 status = caam_calloc_align_buf(&input_buf, key->buf.length); 662 if (status) 663 return status; 664 665 memcpy(input_buf.data, key->buf.data, key->buf.length); 666 cache_operation(TEE_CACHEFLUSH, input_buf.data, input_buf.length); 667 668 /* Re-allocate the output key for black format */ 669 caam_key_free(key); 670 key->key_type = key_type; 671 672 status = caam_key_alloc(key); 673 if (status) 674 goto out; 675 676 /* Allocate the descriptor */ 677 desc = caam_calloc_desc(MAX_DESC_ENTRIES); 678 if (!desc) { 679 KEY_TRACE("Allocation descriptor error"); 680 status = CAAM_OUT_MEMORY; 681 goto out; 682 } 683 684 caam_key_dump("Input key", key); 685 686 caam_desc_init(desc); 687 caam_desc_add_word(desc, DESC_HEADER(0)); 688 caam_desc_add_word(desc, LD_KEY(CLASS_1, PKHA_E, key->sec_size)); 689 caam_desc_add_ptr(desc, input_buf.paddr); 690 691 switch (key->key_type) { 692 case CAAM_KEY_BLACK_ECB: 693 caam_desc_add_word(desc, FIFO_ST(CLASS_NO, PKHA_E_AES_ECB_JKEK, 694 key->sec_size)); 695 break; 696 case CAAM_KEY_BLACK_CCM: 697 caam_desc_add_word(desc, FIFO_ST(CLASS_NO, PKHA_E_AES_CCM_JKEK, 698 key->sec_size)); 699 break; 700 default: 701 status = CAAM_FAILURE; 702 goto out; 703 } 704 705 caam_desc_add_ptr(desc, key->buf.paddr); 706 707 KEY_DUMPDESC(desc); 708 709 caam_key_cache_op(TEE_CACHEFLUSH, key); 710 711 jobctx.desc = desc; 712 status = caam_jr_enqueue(&jobctx, NULL); 713 if (status != CAAM_NO_ERROR) { 714 KEY_TRACE("CAAM return 0x%08x Status 0x%08" PRIx32, status, 715 jobctx.status); 716 status = CAAM_FAILURE; 717 goto out; 718 } 719 720 caam_key_cache_op(TEE_CACHEINVALIDATE, key); 721 722 caam_key_dump("Output Key", key); 723 724 out: 725 caam_free_buf(&input_buf); 726 caam_free_desc(&desc); 727 728 return status; 729 } 730 731 enum caam_status caam_key_init(void) 732 { 733 size_t alloc_size = 0; 734 const struct caamkey key = { 735 .key_type = caam_key_default_key_gen_type(), 736 .sec_size = 4096, /* Max RSA key size */ 737 .is_blob = true, 738 }; 739 740 /* 741 * Ensure bignum format maximum size is enough to store a black key 742 * blob. The largest key is a 4096 bits RSA key pair. 743 */ 744 if (caam_key_serialized_size(&key, &alloc_size)) 745 return CAAM_FAILURE; 746 747 assert(alloc_size <= CFG_CORE_BIGNUM_MAX_BITS); 748 749 key_blob_modifier = caam_calloc_align(KEY_BLOB_MODIFIER_SIZE); 750 if (!key_blob_modifier) 751 return CAAM_FAILURE; 752 753 memcpy(key_blob_modifier, KEY_BLOB_MODIFIER, KEY_BLOB_MODIFIER_SIZE); 754 755 KEY_TRACE("Max serialized key size %zu", alloc_size); 756 757 KEY_TRACE("Default CAAM key generation type %s", 758 caam_key_type_to_str[caam_key_default_key_gen_type()]); 759 760 return CAAM_NO_ERROR; 761 } 762