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 }; 31 32 /* 33 * Internal peripheral context 34 * SAES and CRYP are registered under the same ID in the crypto framework. 35 * Therefore, only one of them can be registered. 36 */ 37 38 union ip_ctx { 39 struct saes_ctx saes; 40 struct cryp_ctx cryp; 41 }; 42 43 /* Internal Peripheral cipher ops*/ 44 struct ip_cipher_ops { 45 TEE_Result (*init)(union ip_ctx *ctx, bool is_decrypt, 46 const uint8_t *key, size_t key_len, 47 const uint8_t *iv, size_t iv_len); 48 TEE_Result (*update)(union ip_ctx *ctx, bool last_block, uint8_t *src, 49 uint8_t *dst, size_t len); 50 }; 51 52 struct stm32_cipher_ctx { 53 struct crypto_cipher_ctx c_ctx; 54 union ip_ctx ip_ctx; 55 const struct ip_cipher_ops *ops; 56 }; 57 58 static TEE_Result cryp_init(union ip_ctx *ip_ctx, bool is_decrypt, 59 const uint8_t *key, size_t key_len, 60 const uint8_t *iv, size_t iv_len) 61 { 62 uint8_t temp_key[DES3_KEY_SIZE] = { }; 63 64 if (!IS_ENABLED(CFG_STM32_CRYP)) 65 return TEE_ERROR_NOT_IMPLEMENTED; 66 67 if (key_len == 16 && 68 (ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_ECB || 69 ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_CBC)) { 70 /* Manage DES2: i.e. K=K1.K2.K1 */ 71 memcpy(temp_key, key, key_len); 72 memcpy(temp_key + key_len, key, key_len / 2); 73 key_len = DES3_KEY_SIZE; 74 key = temp_key; 75 } 76 77 return stm32_cryp_init(&ip_ctx->cryp.ctx, is_decrypt, ip_ctx->cryp.algo, 78 key, key_len, iv, iv_len); 79 } 80 81 static TEE_Result cryp_update(union ip_ctx *ip_ctx, bool last_block, 82 uint8_t *src, uint8_t *dst, size_t len) 83 { 84 if (!IS_ENABLED(CFG_STM32_CRYP)) 85 return TEE_ERROR_NOT_IMPLEMENTED; 86 87 return stm32_cryp_update(&ip_ctx->cryp.ctx, last_block, src, dst, len); 88 } 89 90 static TEE_Result saes_init(union ip_ctx *ip_ctx, bool is_decrypt, 91 const uint8_t *key, size_t key_len, 92 const uint8_t *iv, size_t iv_len) 93 { 94 enum stm32_saes_key_selection key_sel = STM32_SAES_KEY_SOFT; 95 96 if (!IS_ENABLED(CFG_STM32_SAES)) 97 return TEE_ERROR_NOT_IMPLEMENTED; 98 99 return stm32_saes_init(&ip_ctx->saes.ctx, is_decrypt, ip_ctx->saes.algo, 100 key_sel, key, key_len, iv, iv_len); 101 } 102 103 static TEE_Result saes_update(union ip_ctx *ip_ctx, bool last_block, 104 uint8_t *src, uint8_t *dst, size_t len) 105 { 106 if (!IS_ENABLED(CFG_STM32_SAES)) 107 return TEE_ERROR_NOT_IMPLEMENTED; 108 109 return stm32_saes_update(&ip_ctx->saes.ctx, last_block, src, dst, len); 110 } 111 112 const struct ip_cipher_ops cryp_ops = { 113 .init = cryp_init, 114 .update = cryp_update, 115 }; 116 117 const struct ip_cipher_ops saes_ops = { 118 .init = saes_init, 119 .update = saes_update, 120 }; 121 122 static struct stm32_cipher_ctx * 123 to_stm32_cipher_ctx(struct crypto_cipher_ctx *ctx) 124 { 125 assert(ctx); 126 127 return container_of(ctx, struct stm32_cipher_ctx, c_ctx); 128 } 129 130 static TEE_Result stm32_cipher_initialize(struct drvcrypt_cipher_init *dinit) 131 { 132 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dinit->ctx); 133 134 return c->ops->init(&c->ip_ctx, !dinit->encrypt, dinit->key1.data, 135 dinit->key1.length, dinit->iv.data, 136 dinit->iv.length); 137 } 138 139 static TEE_Result stm32_cipher_update(struct drvcrypt_cipher_update *dupdate) 140 { 141 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dupdate->ctx); 142 size_t len = MIN(dupdate->src.length, dupdate->dst.length); 143 144 return c->ops->update(&c->ip_ctx, dupdate->last, dupdate->src.data, 145 dupdate->dst.data, len); 146 } 147 148 static void stm32_cipher_final(void *ctx __unused) 149 { 150 } 151 152 static void stm32_cipher_free(void *ctx) 153 { 154 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 155 156 free(c); 157 } 158 159 static void stm32_cipher_copy_state(void *dst_ctx, void *src_ctx) 160 { 161 struct stm32_cipher_ctx *src = to_stm32_cipher_ctx(src_ctx); 162 struct stm32_cipher_ctx *dst = to_stm32_cipher_ctx(dst_ctx); 163 164 memcpy(dst, src, sizeof(*dst)); 165 } 166 167 static TEE_Result alloc_cryp_ctx(void **ctx, enum stm32_cryp_algo_mode algo) 168 { 169 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 170 171 if (!c) 172 return TEE_ERROR_OUT_OF_MEMORY; 173 174 FMSG("Using CRYP %d", algo); 175 c->ip_ctx.cryp.algo = algo; 176 c->ops = &cryp_ops; 177 *ctx = &c->c_ctx; 178 179 return TEE_SUCCESS; 180 } 181 182 static TEE_Result alloc_saes_ctx(void **ctx, enum stm32_saes_chaining_mode algo) 183 { 184 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 185 186 if (!c) 187 return TEE_ERROR_OUT_OF_MEMORY; 188 189 FMSG("Using SAES %d", algo); 190 c->ip_ctx.saes.algo = algo; 191 c->ops = &saes_ops; 192 *ctx = &c->c_ctx; 193 194 return TEE_SUCCESS; 195 } 196 197 /* 198 * Allocate the SW cipher data context for CRYP peripheral. 199 * 200 * @ctx [out] Caller context variable 201 * @algo Algorithm ID of the context 202 */ 203 static TEE_Result stm32_cryp_cipher_allocate(void **ctx, uint32_t algo) 204 { 205 /* 206 * Convert TEE_ALGO id to internal id 207 */ 208 switch (algo) { 209 case TEE_ALG_DES_ECB_NOPAD: 210 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_ECB); 211 case TEE_ALG_DES_CBC_NOPAD: 212 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_CBC); 213 case TEE_ALG_DES3_ECB_NOPAD: 214 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_ECB); 215 case TEE_ALG_DES3_CBC_NOPAD: 216 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_CBC); 217 case TEE_ALG_AES_ECB_NOPAD: 218 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_ECB); 219 case TEE_ALG_AES_CBC_NOPAD: 220 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CBC); 221 case TEE_ALG_AES_CTR: 222 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CTR); 223 default: 224 return TEE_ERROR_NOT_IMPLEMENTED; 225 } 226 } 227 228 /* 229 * Allocate the SW cipher data context for SAES peripheral. 230 * 231 * @ctx [out] Caller context variable 232 * @algo Algorithm ID of the context 233 */ 234 static TEE_Result stm32_saes_cipher_allocate(void **ctx, uint32_t algo) 235 { 236 /* 237 * Convert TEE_ALGO id to internal id 238 */ 239 switch (algo) { 240 case TEE_ALG_AES_ECB_NOPAD: 241 return alloc_saes_ctx(ctx, STM32_SAES_MODE_ECB); 242 case TEE_ALG_AES_CBC_NOPAD: 243 return alloc_saes_ctx(ctx, STM32_SAES_MODE_CBC); 244 case TEE_ALG_AES_CTR: 245 return alloc_saes_ctx(ctx, STM32_SAES_MODE_CTR); 246 default: 247 return TEE_ERROR_NOT_IMPLEMENTED; 248 } 249 } 250 251 static struct drvcrypt_cipher driver_cipher_cryp = { 252 .alloc_ctx = stm32_cryp_cipher_allocate, 253 .free_ctx = stm32_cipher_free, 254 .init = stm32_cipher_initialize, 255 .update = stm32_cipher_update, 256 .final = stm32_cipher_final, 257 .copy_state = stm32_cipher_copy_state, 258 }; 259 260 static struct drvcrypt_cipher driver_cipher_saes = { 261 .alloc_ctx = stm32_saes_cipher_allocate, 262 .free_ctx = stm32_cipher_free, 263 .init = stm32_cipher_initialize, 264 .update = stm32_cipher_update, 265 .final = stm32_cipher_final, 266 .copy_state = stm32_cipher_copy_state, 267 }; 268 269 TEE_Result stm32_register_cipher(enum stm32_cipher_ip_id cipher_ip) 270 { 271 if (cipher_ip == SAES_IP) 272 return drvcrypt_register_cipher(&driver_cipher_saes); 273 else if (cipher_ip == CRYP_IP) 274 return drvcrypt_register_cipher(&driver_cipher_cryp); 275 else 276 return TEE_ERROR_BAD_PARAMETERS; 277 } 278