xref: /optee_os/core/drivers/crypto/caam/blob/caam_dek.c (revision 280dd8827f4c728d6927ca1314839a9799d43ac9)
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