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