1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright 2020 NXP
4 */
5 #ifndef __IMX_DCP_H__
6 #define __IMX_DCP_H__
7
8 #include <compiler.h>
9 #include <tee_api_types.h>
10 #include <types_ext.h>
11 #include <util.h>
12
13 #define DCP_SHA_BLOCK_SIZE U(64)
14 #define DCP_AES128_BLOCK_SIZE U(16)
15 #define DCP_AES128_KEY_SIZE DCP_AES128_BLOCK_SIZE
16 #define DCP_AES128_IV_SIZE DCP_AES128_BLOCK_SIZE
17
18 enum dcp_key_mode {
19 DCP_SRAM0 = 0,
20 DCP_SRAM1,
21 DCP_SRAM2,
22 DCP_SRAM3,
23 DCP_PAYLOAD,
24 DCP_OTP,
25 };
26
27 enum dcp_aes_mode {
28 DCP_ECB = 0,
29 DCP_CBC,
30 };
31
32 enum dcp_aes_op {
33 DCP_ENCRYPT = 0,
34 DCP_DECRYPT,
35 };
36
37 enum dcp_hash_config {
38 DCP_SHA1 = 0,
39 DCP_SHA256,
40 };
41
42 enum dcp_channel {
43 DCP_CHANN0 = 0,
44 DCP_CHANN1,
45 DCP_CHANN2,
46 DCP_CHANN3,
47 DCP_NB_CHANNELS,
48 };
49
50 /* DCP work packet descriptor is a hardware data structure */
51 struct dcp_descriptor {
52 uint32_t next;
53 uint32_t ctrl0;
54 uint32_t ctrl1;
55 /* Source buffer physical address */
56 uint32_t src_buffer;
57 /* Destination buffer physical address */
58 uint32_t dest_buffer;
59 uint32_t buff_size;
60 /* Payload buffer physical address */
61 uint32_t payload;
62 uint32_t status;
63 };
64
65 struct dcp_align_buf {
66 uint8_t *data;
67 paddr_t paddr;
68 size_t size;
69 };
70
71 struct dcp_data {
72 struct dcp_descriptor desc;
73 enum dcp_channel channel;
74 };
75
76 struct dcp_hash_data {
77 struct dcp_data dcp_data;
78 bool initialized;
79 enum dcp_hash_config alg;
80 struct dcp_align_buf ctx;
81 size_t ctx_size;
82 };
83
84 struct dcp_hashalg {
85 unsigned int type;
86 unsigned int size;
87 };
88
89 struct dcp_cipher_data {
90 struct dcp_data dcp_data;
91 bool initialized;
92 uint8_t iv[DCP_AES128_IV_SIZE];
93 uint8_t key[DCP_AES128_KEY_SIZE];
94 /* payload buffer holds the key and the iv */
95 struct dcp_align_buf payload;
96 size_t payload_size;
97 };
98
99 struct dcp_cipher_init {
100 enum dcp_aes_op op;
101 enum dcp_aes_mode mode;
102 enum dcp_key_mode key_mode;
103 uint8_t *key;
104 uint8_t *iv;
105 };
106
107 /*
108 * Perform AES-CMAC operation
109 *
110 * @init Cipher operation context
111 * @input Input message
112 * @input_size Input message size
113 * @output Output MAC
114 */
115 TEE_Result dcp_cmac(struct dcp_cipher_init *init, uint8_t *input,
116 size_t input_size, uint8_t *output);
117
118 /*
119 * Store key in the SRAM
120 *
121 * @key Buffer containing the key to store (128 bit)
122 * @index Index of the key (0, 1, 2 or 3)
123 */
124 TEE_Result dcp_store_key(uint32_t *key, unsigned int index);
125
126 /*
127 * Initialize AES-128 operation
128 *
129 * @data Cipher operation context
130 * @init Data for aesdata initialization
131 */
132 TEE_Result dcp_cipher_do_init(struct dcp_cipher_data *data,
133 struct dcp_cipher_init *init);
134
135 /*
136 * Update AES-128 operation
137 *
138 * @data Cipher operation context
139 * @src Source data to encrypt/decrypt
140 * @dst [out] Destination buffer
141 * @size Size of source data in bytes, must be 16 bytes multiple
142 */
143 TEE_Result dcp_cipher_do_update(struct dcp_cipher_data *data,
144 const uint8_t *src, uint8_t *dst, size_t size);
145
146 /*
147 * Finalize AES-128 operation
148 *
149 * @data Cipher operation context
150 */
151 void dcp_cipher_do_final(struct dcp_cipher_data *data);
152
153 /*
154 * Initialize hash operation
155 *
156 * @hashdata Hash operation context
157 */
158 TEE_Result dcp_sha_do_init(struct dcp_hash_data *hashdata);
159
160 /*
161 * Update hash operation
162 *
163 * @hashdata Hash operation context
164 * @data Buffer to hash
165 * @len Size of the input buffer in bytes
166 */
167 TEE_Result dcp_sha_do_update(struct dcp_hash_data *hashdata,
168 const uint8_t *data, size_t len);
169
170 /*
171 * Finalize the hash operation
172 *
173 * @hashdata Hash operation context
174 * @digest [out] Result of the hash operation
175 * @digest_size Digest buffer size in bytes
176 */
177 TEE_Result dcp_sha_do_final(struct dcp_hash_data *hashdata, uint8_t *digest,
178 size_t digest_size);
179
180 /* Initialize DCP */
181 TEE_Result dcp_init(void);
182
183 #ifndef CFG_DT
dcp_vbase(vaddr_t * base __unused)184 static inline TEE_Result dcp_vbase(vaddr_t *base __unused)
185 {
186 return TEE_ERROR_NOT_SUPPORTED;
187 }
188 #endif /* CFG_DT */
189
190 #endif /* __IMX_DCP_H__ */
191