1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2019-2021, 2023 NXP
4 */
5 #include <caam_common.h>
6 #include <caam_sm.h>
7 #include <caam_utils_mem.h>
8 #include <caam_utils_status.h>
9 #include <drivers/caam_extension.h>
10 #include <mm/core_memprot.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <tee/cache.h>
14
15 #ifdef CFG_PHYS_64BIT
16 #define BLOB_OPERATE_DESC_ENTRIES 12
17 #else
18 #define BLOB_OPERATE_DESC_ENTRIES 10
19 #endif
20
21 /* Secure Memory Access Permission allowed */
22 #define SM_GRP_BLOB BIT32(3) /* Export/Import Secure Memory blobs allowed */
23
24 /* Secure Memory Page(s)/Partition definition for DEK Blob generation */
25 static const struct caam_sm_page_desc dek_sm_page = {
26 .partition = 1,
27 .page = 3,
28 .page_count = 1,
29 };
30
caam_dek_generate(const uint8_t * payload,size_t payload_size,uint8_t * dek,size_t dek_size)31 TEE_Result caam_dek_generate(const uint8_t *payload, size_t payload_size,
32 uint8_t *dek, size_t dek_size)
33 {
34 TEE_Result ret = TEE_ERROR_GENERIC;
35 enum caam_status retstatus = CAAM_FAILURE;
36 struct caam_sm_page_addr dek_sm_addr = { };
37 struct caamdmaobj resblob = { };
38 struct caam_jobctx jobctx = { };
39 uint32_t key_modifier[2] = { };
40 uint32_t *desc = NULL;
41 unsigned int opflags = 0;
42
43 assert(payload && dek);
44 assert(payload_size && dek_size);
45
46 /* Re-allocate output buffer if alignment needed */
47 ret = caam_dmaobj_output_sgtbuf(&resblob, dek, dek_size, dek_size);
48 if (ret)
49 return ret;
50
51 /* Allocate page(s) in one Secure Memory partition */
52 ret = caam_sm_alloc(&dek_sm_page, &dek_sm_addr);
53 if (ret != CAAM_NO_ERROR) {
54 BLOB_TRACE("Secure memory allocation error 0x%" PRIx32, ret);
55 goto out;
56 }
57
58 /* Copy input data to encapsulate in Secure Memory allocated */
59 memcpy((void *)dek_sm_addr.vaddr, payload, payload_size);
60
61 /*
62 * Set the partition access rights for the group #1 to be
63 * a blob export/import
64 */
65 caam_sm_set_access_perm(&dek_sm_page, SM_GRP_BLOB, 0);
66
67 /*
68 * Create the key modifier:
69 * 31 16 8 0
70 * ---------------------------------------------------
71 * | Length of the payload | AES - 0x55 | CCM - 0x66 |
72 * ---------------------------------------------------
73 */
74 key_modifier[0] = SHIFT_U32(payload_size, 16) | SHIFT_U32(0x55, 8) |
75 SHIFT_U32(0x66, 0);
76 key_modifier[1] = 0;
77
78 /* Allocate the descriptor */
79 desc = caam_calloc_desc(BLOB_OPERATE_DESC_ENTRIES);
80 if (!desc) {
81 BLOB_TRACE("CAAM Context Descriptor Allocation error");
82 ret = TEE_ERROR_OUT_OF_MEMORY;
83 goto out;
84 }
85
86 caam_desc_init(desc);
87 caam_desc_add_word(desc, DESC_HEADER(0));
88 caam_desc_add_word(desc, LD_IMM_OFF(CLASS_2, REG_KEY, 8, 12));
89 caam_desc_add_word(desc, key_modifier[0]);
90 caam_desc_add_word(desc, key_modifier[1]);
91 caam_desc_add_word(desc, SEQ_IN_PTR(payload_size));
92 caam_desc_add_ptr(desc, dek_sm_addr.paddr);
93 caam_desc_seq_out(desc, &resblob);
94 caam_desc_add_word(desc, BLOB_ENCAPS | PROT_BLOB_SEC_MEM | opflags);
95
96 BLOB_DUMPDESC(desc);
97
98 cache_operation(TEE_CACHECLEAN, (void *)payload, payload_size);
99 caam_dmaobj_cache_push(&resblob);
100
101 jobctx.desc = desc;
102 retstatus = caam_jr_enqueue(&jobctx, NULL);
103
104 if (retstatus) {
105 BLOB_TRACE("CAAM Status 0x%08" PRIx32 "", jobctx.status);
106 goto out;
107 }
108
109 caam_dmaobj_copy_to_orig(&resblob);
110
111 BLOB_TRACE("Done CAAM BLOB from Secure Memory encaps");
112 BLOB_DUMPBUF("Blob Output", resblob.orig.data, resblob.orig.length);
113 out:
114 caam_sm_free(&dek_sm_page);
115 caam_free_desc(&desc);
116 caam_dmaobj_free(&resblob);
117
118 return caam_status_to_tee_result(retstatus);
119 }
120