1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
4 */
5
6 #include <assert.h>
7 #include <crypto/crypto.h>
8 #include <crypto/crypto_impl.h>
9 #include <crypto/internal_aes-gcm.h>
10 #include <drvcrypt.h>
11 #include <drvcrypt_authenc.h>
12 #include <initcall.h>
13 #include <kernel/dt.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <string_ext.h>
17 #include <tee_api_types.h>
18 #include <utee_defines.h>
19 #include <util.h>
20
21 #include "common.h"
22 #include "stm32_cryp.h"
23
24 #define TOBE32(x) TEE_U32_BSWAP(x)
25 #define FROMBE32(x) TEE_U32_BSWAP(x)
26
27 #define MAX_TAG_SIZE 16U
28
29 struct stm32_ae_ctx {
30 struct crypto_authenc_ctx a_ctx;
31 struct stm32_cryp_context cryp;
32 enum stm32_cryp_algo_mode algo;
33 uint8_t tag_mask[MAX_TAG_SIZE];
34 };
35
xor_vec(uint8_t * r,uint8_t * a,uint8_t * b,size_t len)36 static void xor_vec(uint8_t *r, uint8_t *a, uint8_t *b, size_t len)
37 {
38 size_t i = 0;
39
40 for (i = 0; i < len; i++)
41 r[i] = a[i] ^ b[i];
42 }
43
to_stm32_ae_ctx(struct crypto_authenc_ctx * ctx)44 static struct stm32_ae_ctx *to_stm32_ae_ctx(struct crypto_authenc_ctx *ctx)
45 {
46 assert(ctx);
47
48 return container_of(ctx, struct stm32_ae_ctx, a_ctx);
49 }
50
stm32_ae_gcm_generate_iv(struct stm32_ae_ctx * c,uint32_t * iv,struct drvcrypt_authenc_init * dinit)51 static TEE_Result stm32_ae_gcm_generate_iv(struct stm32_ae_ctx *c,
52 uint32_t *iv,
53 struct drvcrypt_authenc_init *dinit)
54 {
55 TEE_Result res = TEE_SUCCESS;
56 uint8_t tag1[MAX_TAG_SIZE] = { 0 };
57 uint8_t tag2[MAX_TAG_SIZE] = { 0 };
58 uint32_t j0[MAX_TAG_SIZE / sizeof(uint32_t)] = { 0 };
59 uint8_t dummy_iv[MAX_TAG_SIZE] = { 0 };
60 struct stm32_cryp_context ctx = { };
61 uint8_t *data_out = NULL;
62
63 if (dinit->nonce.length == 12) {
64 memcpy(iv, dinit->nonce.data, dinit->nonce.length);
65 iv[3] = TOBE32(2);
66 return TEE_SUCCESS;
67 }
68
69 /* Calculate GHASH(dinit->nonce.data) */
70 dummy_iv[15] = 2;
71
72 res = stm32_cryp_init(&ctx, true, STM32_CRYP_MODE_AES_GCM,
73 dinit->key.data, dinit->key.length,
74 dummy_iv, sizeof(dummy_iv));
75 if (res)
76 return res;
77
78 res = stm32_cryp_final(&ctx, tag1, sizeof(tag1));
79 if (res)
80 return res;
81
82 memset(&ctx, 0, sizeof(ctx));
83 res = stm32_cryp_init(&ctx, true, STM32_CRYP_MODE_AES_GCM,
84 dinit->key.data, dinit->key.length,
85 dummy_iv, sizeof(dummy_iv));
86 if (res)
87 return res;
88
89 data_out = malloc(dinit->nonce.length);
90 if (!data_out)
91 return TEE_ERROR_OUT_OF_MEMORY;
92
93 res = stm32_cryp_update_load(&ctx, dinit->nonce.data, data_out,
94 dinit->nonce.length);
95 free(data_out);
96
97 if (res)
98 return res;
99
100 res = stm32_cryp_final(&ctx, tag2, sizeof(tag2));
101 if (res)
102 return res;
103
104 xor_vec((uint8_t *)j0, tag1, tag2, sizeof(tag1));
105
106 memcpy(iv, j0, sizeof(j0));
107 iv[3] = TOBE32(FROMBE32(iv[3]) + 1);
108
109 /* Compute first mask=AES_ECB(J0_real) into tag1 */
110 memset(&ctx, 0, sizeof(ctx));
111 res = stm32_cryp_init(&ctx, false, STM32_CRYP_MODE_AES_ECB,
112 dinit->key.data, dinit->key.length,
113 NULL, 0);
114 if (res)
115 return res;
116
117 res = stm32_cryp_update(&ctx, true, (uint8_t *)j0, tag1,
118 sizeof(tag1));
119 if (res)
120 return res;
121
122 /* Compute second mask=AES_ECB(J0_used_by_HW) into tag2 */
123 memset(&ctx, 0, sizeof(ctx));
124 j0[3] = TOBE32(1);
125 res = stm32_cryp_init(&ctx, false, STM32_CRYP_MODE_AES_ECB,
126 dinit->key.data, dinit->key.length,
127 NULL, 0);
128 if (res)
129 return res;
130
131 res = stm32_cryp_update(&ctx, true, (uint8_t *)j0, tag2,
132 sizeof(tag2));
133 if (res)
134 return res;
135
136 /*
137 * Save the mask we will apply in {enc,dec}_final() to the
138 * (wrongly) computed tag to get the expected one.
139 */
140 xor_vec(c->tag_mask, tag1, tag2, sizeof(c->tag_mask));
141
142 return TEE_SUCCESS;
143 }
144
stm32_ae_ccm_generate_b0(uint8_t * b0,struct drvcrypt_authenc_init * dinit)145 static void stm32_ae_ccm_generate_b0(uint8_t *b0,
146 struct drvcrypt_authenc_init *dinit)
147 {
148 size_t m = dinit->tag_len;
149 size_t l = 15 - dinit->nonce.length;
150 size_t payload_len = dinit->payload_len;
151 size_t i = 15;
152
153 /* The tag_len should be 4, 6, 8, 10, 12, 14 or 16 */
154 assert(m >= 4 && m <= 16 && (m % 2) == 0);
155
156 memset(b0, 0, TEE_AES_BLOCK_SIZE);
157 /* Flags: (Adata << 6) | (M' << 3) | L' */
158 b0[0] = ((dinit->aad_len ? 1 : 0) << 6) |
159 (((m - 2) / 2) << 3) |
160 (l - 1);
161
162 /* Nonce */
163 memcpy(b0 + 1, dinit->nonce.data, dinit->nonce.length);
164
165 /* Payload length */
166 for (i = 15; i >= 15 - l + 1; i--, payload_len >>= 8)
167 b0[i] = payload_len & 0xFF;
168 }
169
stm32_ae_ccm_push_b1(struct stm32_ae_ctx * c,struct drvcrypt_authenc_init * dinit)170 static TEE_Result stm32_ae_ccm_push_b1(struct stm32_ae_ctx *c,
171 struct drvcrypt_authenc_init *dinit)
172 {
173 uint8_t b1[TEE_AES_BLOCK_SIZE] = { 0 };
174 size_t len = 0;
175
176 if (dinit->aad_len == 0)
177 return TEE_SUCCESS;
178
179 if (dinit->aad_len < 0x100) {
180 b1[1] = dinit->aad_len;
181 len = 2;
182 } else if (dinit->aad_len < 0xFF00) {
183 b1[0] = dinit->aad_len / 0x100;
184 b1[1] = dinit->aad_len % 0x100;
185 len = 2;
186 } else if (dinit->aad_len <= UINT32_MAX) {
187 b1[0] = 0xFF;
188 b1[1] = 0xFE;
189 b1[2] = dinit->aad_len & GENMASK_32(7, 0);
190 b1[3] = (dinit->aad_len & GENMASK_32(15, 8)) >> 8;
191 b1[4] = (dinit->aad_len & GENMASK_32(23, 16)) >> 16;
192 b1[5] = (dinit->aad_len & GENMASK_32(31, 24)) >> 24;
193 len = 6;
194 } else {
195 b1[0] = 0xFF;
196 b1[1] = 0xFF;
197 b1[2] = dinit->aad_len & GENMASK_64(7, 0);
198 b1[3] = (dinit->aad_len & GENMASK_64(15, 8)) >> 8;
199 b1[4] = (dinit->aad_len & GENMASK_64(23, 16)) >> 16;
200 b1[5] = (dinit->aad_len & GENMASK_64(31, 24)) >> 24;
201 b1[6] = (dinit->aad_len & GENMASK_64(39, 32)) >> 32;
202 b1[7] = (dinit->aad_len & GENMASK_64(47, 40)) >> 40;
203 b1[8] = (dinit->aad_len & GENMASK_64(55, 48)) >> 48;
204 b1[9] = (dinit->aad_len & GENMASK_64(63, 56)) >> 56;
205 len = 10;
206 }
207
208 return stm32_cryp_update_assodata(&c->cryp, b1, len);
209 }
210
stm32_ae_initialize(struct drvcrypt_authenc_init * dinit)211 static TEE_Result stm32_ae_initialize(struct drvcrypt_authenc_init *dinit)
212 {
213 TEE_Result res = TEE_SUCCESS;
214 uint32_t iv[4] = { 0 };
215 struct stm32_ae_ctx *c = to_stm32_ae_ctx(dinit->ctx);
216
217 if (c->algo == STM32_CRYP_MODE_AES_GCM) {
218 res = stm32_ae_gcm_generate_iv(c, iv, dinit);
219 if (res)
220 return res;
221 } else if (c->algo == STM32_CRYP_MODE_AES_CCM) {
222 stm32_ae_ccm_generate_b0((uint8_t *)iv, dinit);
223 }
224
225 res = stm32_cryp_init(&c->cryp, !dinit->encrypt, c->algo,
226 dinit->key.data, dinit->key.length, iv,
227 sizeof(iv));
228 if (res)
229 return res;
230
231 if (c->algo == STM32_CRYP_MODE_AES_CCM)
232 return stm32_ae_ccm_push_b1(c, dinit);
233
234 return TEE_SUCCESS;
235 }
236
237 static TEE_Result
stm32_ae_update_aad(struct drvcrypt_authenc_update_aad * dupdate)238 stm32_ae_update_aad(struct drvcrypt_authenc_update_aad *dupdate)
239 {
240 struct stm32_ae_ctx *c = to_stm32_ae_ctx(dupdate->ctx);
241
242 return stm32_cryp_update_assodata(&c->cryp, dupdate->aad.data,
243 dupdate->aad.length);
244 }
245
246 static TEE_Result
stm32_ae_update_payload(struct drvcrypt_authenc_update_payload * dupdate)247 stm32_ae_update_payload(struct drvcrypt_authenc_update_payload *dupdate)
248 {
249 struct stm32_ae_ctx *c = to_stm32_ae_ctx(dupdate->ctx);
250 size_t len = MIN(dupdate->src.length, dupdate->dst.length);
251
252 return stm32_cryp_update_load(&c->cryp, dupdate->src.data,
253 dupdate->dst.data, len);
254 }
255
stm32_ae_encdec_final(struct stm32_ae_ctx * c,uint8_t * tag,size_t tag_size)256 static TEE_Result stm32_ae_encdec_final(struct stm32_ae_ctx *c, uint8_t *tag,
257 size_t tag_size)
258 {
259 TEE_Result res = TEE_SUCCESS;
260 uint8_t t[MAX_TAG_SIZE] = { 0 };
261
262 res = stm32_cryp_final(&c->cryp, t, sizeof(t));
263 if (res)
264 return res;
265
266 xor_vec(tag, t, c->tag_mask, tag_size);
267
268 return TEE_SUCCESS;
269 }
270
stm32_ae_enc_final(struct drvcrypt_authenc_final * dfinal)271 static TEE_Result stm32_ae_enc_final(struct drvcrypt_authenc_final *dfinal)
272 {
273 TEE_Result res = TEE_SUCCESS;
274 struct stm32_ae_ctx *c = to_stm32_ae_ctx(dfinal->ctx);
275 size_t len = MIN(dfinal->src.length, dfinal->dst.length);
276
277 res = stm32_cryp_update_load(&c->cryp, dfinal->src.data,
278 dfinal->dst.data, len);
279 if (res)
280 return res;
281
282 return stm32_ae_encdec_final(c, dfinal->tag.data, dfinal->tag.length);
283 }
284
stm32_ae_dec_final(struct drvcrypt_authenc_final * dfinal)285 static TEE_Result stm32_ae_dec_final(struct drvcrypt_authenc_final *dfinal)
286 {
287 TEE_Result res = TEE_SUCCESS;
288 struct stm32_ae_ctx *c = to_stm32_ae_ctx(dfinal->ctx);
289 size_t len = MIN(dfinal->src.length, dfinal->dst.length);
290 unsigned char tag_buf[MAX_TAG_SIZE] = { 0 };
291
292 res = stm32_cryp_update_load(&c->cryp, dfinal->src.data,
293 dfinal->dst.data, len);
294 if (res)
295 return res;
296
297 res = stm32_ae_encdec_final(c, tag_buf, sizeof(tag_buf));
298 if (res)
299 return res;
300
301 if (consttime_memcmp(tag_buf, dfinal->tag.data, dfinal->tag.length))
302 return TEE_ERROR_MAC_INVALID;
303
304 return TEE_SUCCESS;
305 }
306
stm32_ae_final(void * ctx __unused)307 static void stm32_ae_final(void *ctx __unused)
308 {
309 }
310
stm32_ae_free(void * ctx)311 static void stm32_ae_free(void *ctx)
312 {
313 struct stm32_ae_ctx *c = to_stm32_ae_ctx(ctx);
314
315 free(c);
316 }
317
stm32_ae_copy_state(void * dst_ctx,void * src_ctx)318 static void stm32_ae_copy_state(void *dst_ctx, void *src_ctx)
319 {
320 struct stm32_ae_ctx *src = to_stm32_ae_ctx(src_ctx);
321 struct stm32_ae_ctx *dst = to_stm32_ae_ctx(dst_ctx);
322
323 memcpy(dst, src, sizeof(*dst));
324 }
325
alloc_ctx(void ** ctx,enum stm32_cryp_algo_mode algo)326 static TEE_Result alloc_ctx(void **ctx, enum stm32_cryp_algo_mode algo)
327 {
328 struct stm32_ae_ctx *c = calloc(1, sizeof(*c));
329
330 if (!c)
331 return TEE_ERROR_OUT_OF_MEMORY;
332
333 c->algo = algo;
334 *ctx = &c->a_ctx;
335
336 return TEE_SUCCESS;
337 }
338
339 /*
340 * Allocate the SW authenc data context
341 *
342 * @ctx [out] Caller context variable
343 * @algo Algorithm ID of the context
344 */
stm32_ae_allocate(void ** ctx,uint32_t algo)345 static TEE_Result stm32_ae_allocate(void **ctx, uint32_t algo)
346 {
347 /* Convert TEE_ALGO id to CRYP id */
348 switch (algo) {
349 case TEE_ALG_AES_CCM:
350 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CCM);
351 case TEE_ALG_AES_GCM:
352 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_GCM);
353 default:
354 return TEE_ERROR_NOT_IMPLEMENTED;
355 }
356 }
357
358 /*
359 * Registration of the Authenc Driver
360 */
361 static struct drvcrypt_authenc driver_authenc = {
362 .alloc_ctx = &stm32_ae_allocate,
363 .free_ctx = &stm32_ae_free,
364 .init = &stm32_ae_initialize,
365 .update_aad = &stm32_ae_update_aad,
366 .update_payload = &stm32_ae_update_payload,
367 .enc_final = &stm32_ae_enc_final,
368 .dec_final = &stm32_ae_dec_final,
369 .final = &stm32_ae_final,
370 .copy_state = &stm32_ae_copy_state,
371 };
372
stm32_register_authenc(void)373 TEE_Result stm32_register_authenc(void)
374 {
375 return drvcrypt_register_authenc(&driver_authenc);
376 }
377