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
data_to_serialized_key(const uint8_t * data,size_t size)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 */
get_key_type(const uint8_t * data,size_t size)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 */
get_key_sec_size(const uint8_t * data,size_t size)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 */
get_key_buf_offset(const uint8_t * data,size_t size)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 */
get_key_buf_size(const uint8_t * data,size_t size)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
caam_key_get_alloc_size(const struct caamkey * key)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
caam_key_dump(const char * trace,const struct caamkey * key)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
caam_key_alloc(struct caamkey * key)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
caam_key_free(struct caamkey * key)259 void caam_key_free(struct caamkey *key)
260 {
261 if (!key)
262 return;
263
264 caam_free_buf(&key->buf);
265 }
266
caam_key_cache_op(enum utee_cache_operation op,const struct caamkey * key)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
caam_key_operation_blob(const struct caamkey * in_key,struct caamkey * out_key)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
caam_key_deserialize_from_bin(uint8_t * data,size_t size,struct caamkey * key,size_t sec_size)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
caam_key_serialize_to_bin(uint8_t * data,size_t size,const struct caamkey * key)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
caam_key_serialized_size(const struct caamkey * key,size_t * size)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
caam_key_deserialize_from_bn(const struct bignum * inkey,struct caamkey * outkey,size_t size_sec)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
caam_key_serialize_to_bn(struct bignum * outkey,const struct caamkey * inkey)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
caam_key_black_encapsulation(struct caamkey * key,enum caam_key_type key_type)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
caam_key_init(void)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