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 <drvcrypt.h> 10 #include <drvcrypt_cipher.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <tee_api_types.h> 14 #include <util.h> 15 16 #include "common.h" 17 #include "stm32_cryp.h" 18 #include "stm32_saes.h" 19 20 #define DES3_KEY_SIZE 24 21 22 struct cryp_ctx { 23 struct stm32_cryp_context ctx; 24 enum stm32_cryp_algo_mode algo; 25 }; 26 27 struct saes_ctx { 28 struct stm32_saes_context ctx; 29 enum stm32_saes_chaining_mode algo; 30 /* Fallback to software implementation on 192bit AES key */ 31 bool use_fallback; 32 struct crypto_cipher_ctx *fallback_ctx; 33 }; 34 35 /* 36 * Internal peripheral context 37 * SAES and CRYP are registered under the same ID in the crypto framework. 38 * Therefore, only one of them can be registered. 39 */ 40 41 union ip_ctx { 42 struct saes_ctx saes; 43 struct cryp_ctx cryp; 44 }; 45 46 /* Internal Peripheral cipher ops*/ 47 struct ip_cipher_ops { 48 TEE_Result (*init)(union ip_ctx *ctx, bool is_decrypt, 49 const uint8_t *key, size_t key_len, 50 const uint8_t *iv, size_t iv_len); 51 TEE_Result (*update)(union ip_ctx *ctx, bool last_block, uint8_t *src, 52 uint8_t *dst, size_t len); 53 void (*final)(union ip_ctx *ctx); 54 void (*copy_state)(union ip_ctx *dst_ctx, union ip_ctx *src_ctx); 55 }; 56 57 struct stm32_cipher_ctx { 58 struct crypto_cipher_ctx c_ctx; 59 union ip_ctx ip_ctx; 60 const struct ip_cipher_ops *ops; 61 }; 62 63 static TEE_Result cryp_init(union ip_ctx *ip_ctx, bool is_decrypt, 64 const uint8_t *key, size_t key_len, 65 const uint8_t *iv, size_t iv_len) 66 { 67 uint8_t temp_key[DES3_KEY_SIZE] = { }; 68 69 if (!IS_ENABLED(CFG_STM32_CRYP)) 70 return TEE_ERROR_NOT_IMPLEMENTED; 71 72 if (key_len == 16 && 73 (ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_ECB || 74 ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_CBC)) { 75 /* Manage DES2: i.e. K=K1.K2.K1 */ 76 memcpy(temp_key, key, key_len); 77 memcpy(temp_key + key_len, key, key_len / 2); 78 key_len = DES3_KEY_SIZE; 79 key = temp_key; 80 } 81 82 return stm32_cryp_init(&ip_ctx->cryp.ctx, is_decrypt, ip_ctx->cryp.algo, 83 key, key_len, iv, iv_len); 84 } 85 86 static TEE_Result cryp_update(union ip_ctx *ip_ctx, bool last_block, 87 uint8_t *src, uint8_t *dst, size_t len) 88 { 89 if (!IS_ENABLED(CFG_STM32_CRYP)) 90 return TEE_ERROR_NOT_IMPLEMENTED; 91 92 return stm32_cryp_update(&ip_ctx->cryp.ctx, last_block, src, dst, len); 93 } 94 95 static void cryp_copy_state(union ip_ctx *dst_ip_ctx, union ip_ctx *src_ip_ctx) 96 { 97 assert(IS_ENABLED(CFG_STM32_CRYP)); 98 99 memcpy(&dst_ip_ctx->cryp, &src_ip_ctx->cryp, sizeof(dst_ip_ctx->cryp)); 100 } 101 102 static const struct ip_cipher_ops cryp_ops = { 103 .init = cryp_init, 104 .update = cryp_update, 105 .copy_state = cryp_copy_state, 106 }; 107 108 static TEE_Result saes_init(union ip_ctx *ip_ctx, bool is_decrypt, 109 const uint8_t *key, size_t key_len, 110 const uint8_t *iv, size_t iv_len) 111 { 112 enum stm32_saes_key_selection key_sel = STM32_SAES_KEY_SOFT; 113 114 if (!IS_ENABLED(CFG_STM32_SAES)) 115 return TEE_ERROR_NOT_IMPLEMENTED; 116 117 if (key_len == AES_KEYSIZE_192) { 118 struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx; 119 TEE_OperationMode mode = TEE_MODE_ILLEGAL_VALUE; 120 TEE_Result res = TEE_ERROR_GENERIC; 121 122 if (!IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) { 123 EMSG("STM32 SAES does not support 192bit keys"); 124 125 return TEE_ERROR_NOT_IMPLEMENTED; 126 } 127 128 if (is_decrypt) 129 mode = TEE_MODE_DECRYPT; 130 else 131 mode = TEE_MODE_ENCRYPT; 132 133 res = ctx->ops->init(ctx, mode, key, key_len, NULL, 0, iv, 134 iv_len); 135 if (res) 136 return res; 137 138 ip_ctx->saes.use_fallback = true; 139 140 return TEE_SUCCESS; 141 } 142 143 ip_ctx->saes.use_fallback = false; 144 145 return stm32_saes_init(&ip_ctx->saes.ctx, is_decrypt, ip_ctx->saes.algo, 146 key_sel, key, key_len, iv, iv_len); 147 } 148 149 static TEE_Result saes_update(union ip_ctx *ip_ctx, bool last_block, 150 uint8_t *src, uint8_t *dst, size_t len) 151 { 152 if (!IS_ENABLED(CFG_STM32_SAES)) 153 return TEE_ERROR_NOT_IMPLEMENTED; 154 155 if (ip_ctx->saes.use_fallback) { 156 struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx; 157 158 assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)); 159 160 return ctx->ops->update(ctx, last_block, src, len, dst); 161 } 162 163 return stm32_saes_update(&ip_ctx->saes.ctx, last_block, src, dst, len); 164 } 165 166 static void saes_final(union ip_ctx *ip_ctx) 167 { 168 struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx; 169 170 assert(IS_ENABLED(CFG_STM32_SAES)); 171 172 if (ip_ctx->saes.use_fallback) { 173 assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)); 174 ctx->ops->final(ctx); 175 } 176 } 177 178 static void saes_copy_state(union ip_ctx *dst_ip_ctx, union ip_ctx *src_ip_ctx) 179 { 180 struct saes_ctx *src_ctx = &src_ip_ctx->saes; 181 struct crypto_cipher_ctx *fb_ctx = src_ctx->fallback_ctx; 182 183 assert(IS_ENABLED(CFG_STM32_SAES)); 184 185 memcpy(&dst_ip_ctx->saes.ctx, &src_ctx->ctx, sizeof(src_ctx->ctx)); 186 187 dst_ip_ctx->saes.algo = src_ctx->algo; 188 dst_ip_ctx->saes.use_fallback = src_ctx->use_fallback; 189 190 if (src_ctx->use_fallback) { 191 assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)); 192 fb_ctx->ops->copy_state(dst_ip_ctx->saes.fallback_ctx, fb_ctx); 193 } 194 } 195 196 static const struct ip_cipher_ops saes_ops = { 197 .init = saes_init, 198 .update = saes_update, 199 .final = saes_final, 200 .copy_state = saes_copy_state, 201 }; 202 203 static struct stm32_cipher_ctx * 204 to_stm32_cipher_ctx(struct crypto_cipher_ctx *ctx) 205 { 206 assert(ctx); 207 208 return container_of(ctx, struct stm32_cipher_ctx, c_ctx); 209 } 210 211 static TEE_Result stm32_cipher_initialize(struct drvcrypt_cipher_init *dinit) 212 { 213 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dinit->ctx); 214 215 return c->ops->init(&c->ip_ctx, !dinit->encrypt, dinit->key1.data, 216 dinit->key1.length, dinit->iv.data, 217 dinit->iv.length); 218 } 219 220 static TEE_Result stm32_cipher_update(struct drvcrypt_cipher_update *dupdate) 221 { 222 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dupdate->ctx); 223 size_t len = MIN(dupdate->src.length, dupdate->dst.length); 224 225 return c->ops->update(&c->ip_ctx, dupdate->last, dupdate->src.data, 226 dupdate->dst.data, len); 227 } 228 229 static void stm32_cipher_final(void *ctx __unused) 230 { 231 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 232 233 if (c->ops->final) 234 c->ops->final(&c->ip_ctx); 235 } 236 237 static void stm32_cipher_copy_state(void *dst_ctx, void *src_ctx) 238 { 239 struct stm32_cipher_ctx *src_c = to_stm32_cipher_ctx(src_ctx); 240 struct stm32_cipher_ctx *dst_c = to_stm32_cipher_ctx(dst_ctx); 241 242 src_c->ops->copy_state(&dst_c->ip_ctx, &src_c->ip_ctx); 243 } 244 245 static TEE_Result alloc_cryp_ctx(void **ctx, enum stm32_cryp_algo_mode algo) 246 { 247 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 248 249 if (!c) 250 return TEE_ERROR_OUT_OF_MEMORY; 251 252 FMSG("Using CRYP %d", algo); 253 c->ip_ctx.cryp.algo = algo; 254 c->ops = &cryp_ops; 255 *ctx = &c->c_ctx; 256 257 return TEE_SUCCESS; 258 } 259 260 static TEE_Result stm32_cryp_cipher_allocate(void **ctx, uint32_t algo) 261 { 262 /* 263 * Convert TEE_ALGO id to internal id 264 */ 265 switch (algo) { 266 case TEE_ALG_DES_ECB_NOPAD: 267 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_ECB); 268 case TEE_ALG_DES_CBC_NOPAD: 269 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_CBC); 270 case TEE_ALG_DES3_ECB_NOPAD: 271 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_ECB); 272 case TEE_ALG_DES3_CBC_NOPAD: 273 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_CBC); 274 case TEE_ALG_AES_ECB_NOPAD: 275 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_ECB); 276 case TEE_ALG_AES_CBC_NOPAD: 277 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CBC); 278 case TEE_ALG_AES_CTR: 279 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CTR); 280 default: 281 return TEE_ERROR_NOT_IMPLEMENTED; 282 } 283 } 284 285 static void stm32_cryp_cipher_free(void *ctx) 286 { 287 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 288 289 free(c); 290 } 291 292 static TEE_Result stm32_saes_cipher_allocate(void **ctx, uint32_t algo) 293 { 294 enum stm32_saes_chaining_mode saes_algo = STM32_SAES_MODE_ECB; 295 struct crypto_cipher_ctx *fallback_ctx = NULL; 296 struct stm32_cipher_ctx *saes_ctx = NULL; 297 TEE_Result res = TEE_SUCCESS; 298 299 switch (algo) { 300 case TEE_ALG_AES_ECB_NOPAD: 301 saes_algo = STM32_SAES_MODE_ECB; 302 if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) 303 res = crypto_aes_ecb_alloc_ctx(&fallback_ctx); 304 break; 305 case TEE_ALG_AES_CBC_NOPAD: 306 saes_algo = STM32_SAES_MODE_CBC; 307 if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) 308 res = crypto_aes_cbc_alloc_ctx(&fallback_ctx); 309 break; 310 case TEE_ALG_AES_CTR: 311 saes_algo = STM32_SAES_MODE_CTR; 312 if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) 313 res = crypto_aes_ctr_alloc_ctx(&fallback_ctx); 314 break; 315 default: 316 return TEE_ERROR_NOT_IMPLEMENTED; 317 } 318 if (res) 319 return res; 320 321 saes_ctx = calloc(1, sizeof(*saes_ctx)); 322 if (!saes_ctx) { 323 if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) 324 fallback_ctx->ops->free_ctx(fallback_ctx); 325 326 return TEE_ERROR_OUT_OF_MEMORY; 327 } 328 329 FMSG("Using SAES %d", saes_algo); 330 saes_ctx->ip_ctx.saes.algo = saes_algo; 331 saes_ctx->ops = &saes_ops; 332 saes_ctx->ip_ctx.saes.fallback_ctx = fallback_ctx; 333 *ctx = &saes_ctx->c_ctx; 334 335 return TEE_SUCCESS; 336 } 337 338 static void stm32_saes_cipher_free(void *ctx) 339 { 340 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 341 342 if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) { 343 struct crypto_cipher_ctx *fb_ctx = c->ip_ctx.saes.fallback_ctx; 344 345 fb_ctx->ops->free_ctx(fb_ctx); 346 } 347 348 free(c); 349 } 350 351 static struct drvcrypt_cipher driver_cipher_cryp = { 352 .alloc_ctx = stm32_cryp_cipher_allocate, 353 .free_ctx = stm32_cryp_cipher_free, 354 .init = stm32_cipher_initialize, 355 .update = stm32_cipher_update, 356 .final = stm32_cipher_final, 357 .copy_state = stm32_cipher_copy_state, 358 }; 359 360 static struct drvcrypt_cipher driver_cipher_saes = { 361 .alloc_ctx = stm32_saes_cipher_allocate, 362 .free_ctx = stm32_saes_cipher_free, 363 .init = stm32_cipher_initialize, 364 .update = stm32_cipher_update, 365 .final = stm32_cipher_final, 366 .copy_state = stm32_cipher_copy_state, 367 }; 368 369 TEE_Result stm32_register_cipher(enum stm32_cipher_ip_id cipher_ip) 370 { 371 if (cipher_ip == SAES_IP) 372 return drvcrypt_register_cipher(&driver_cipher_saes); 373 else if (cipher_ip == CRYP_IP) 374 return drvcrypt_register_cipher(&driver_cipher_cryp); 375 else 376 return TEE_ERROR_BAD_PARAMETERS; 377 } 378