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_copy_state(void *dst_ctx, void *src_ctx) 153 { 154 struct stm32_cipher_ctx *src = to_stm32_cipher_ctx(src_ctx); 155 struct stm32_cipher_ctx *dst = to_stm32_cipher_ctx(dst_ctx); 156 157 memcpy(dst, src, sizeof(*dst)); 158 } 159 160 static TEE_Result alloc_cryp_ctx(void **ctx, enum stm32_cryp_algo_mode algo) 161 { 162 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 163 164 if (!c) 165 return TEE_ERROR_OUT_OF_MEMORY; 166 167 FMSG("Using CRYP %d", algo); 168 c->ip_ctx.cryp.algo = algo; 169 c->ops = &cryp_ops; 170 *ctx = &c->c_ctx; 171 172 return TEE_SUCCESS; 173 } 174 175 static TEE_Result stm32_cryp_cipher_allocate(void **ctx, uint32_t algo) 176 { 177 /* 178 * Convert TEE_ALGO id to internal id 179 */ 180 switch (algo) { 181 case TEE_ALG_DES_ECB_NOPAD: 182 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_ECB); 183 case TEE_ALG_DES_CBC_NOPAD: 184 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_CBC); 185 case TEE_ALG_DES3_ECB_NOPAD: 186 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_ECB); 187 case TEE_ALG_DES3_CBC_NOPAD: 188 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_CBC); 189 case TEE_ALG_AES_ECB_NOPAD: 190 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_ECB); 191 case TEE_ALG_AES_CBC_NOPAD: 192 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CBC); 193 case TEE_ALG_AES_CTR: 194 return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CTR); 195 default: 196 return TEE_ERROR_NOT_IMPLEMENTED; 197 } 198 } 199 200 static TEE_Result alloc_saes_ctx(void **ctx, enum stm32_saes_chaining_mode algo) 201 { 202 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 203 204 if (!c) 205 return TEE_ERROR_OUT_OF_MEMORY; 206 207 FMSG("Using SAES %d", algo); 208 c->ip_ctx.saes.algo = algo; 209 c->ops = &saes_ops; 210 *ctx = &c->c_ctx; 211 212 return TEE_SUCCESS; 213 } 214 215 static TEE_Result stm32_saes_cipher_allocate(void **ctx, uint32_t algo) 216 { 217 /* 218 * Convert TEE_ALGO id to internal id 219 */ 220 switch (algo) { 221 case TEE_ALG_AES_ECB_NOPAD: 222 return alloc_saes_ctx(ctx, STM32_SAES_MODE_ECB); 223 case TEE_ALG_AES_CBC_NOPAD: 224 return alloc_saes_ctx(ctx, STM32_SAES_MODE_CBC); 225 case TEE_ALG_AES_CTR: 226 return alloc_saes_ctx(ctx, STM32_SAES_MODE_CTR); 227 default: 228 return TEE_ERROR_NOT_IMPLEMENTED; 229 } 230 } 231 232 static void stm32_cipher_free(void *ctx) 233 { 234 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 235 236 free(c); 237 } 238 239 static struct drvcrypt_cipher driver_cipher_cryp = { 240 .alloc_ctx = stm32_cryp_cipher_allocate, 241 .free_ctx = stm32_cipher_free, 242 .init = stm32_cipher_initialize, 243 .update = stm32_cipher_update, 244 .final = stm32_cipher_final, 245 .copy_state = stm32_cipher_copy_state, 246 }; 247 248 static struct drvcrypt_cipher driver_cipher_saes = { 249 .alloc_ctx = stm32_saes_cipher_allocate, 250 .free_ctx = stm32_cipher_free, 251 .init = stm32_cipher_initialize, 252 .update = stm32_cipher_update, 253 .final = stm32_cipher_final, 254 .copy_state = stm32_cipher_copy_state, 255 }; 256 257 TEE_Result stm32_register_cipher(enum stm32_cipher_ip_id cipher_ip) 258 { 259 if (cipher_ip == SAES_IP) 260 return drvcrypt_register_cipher(&driver_cipher_saes); 261 else if (cipher_ip == CRYP_IP) 262 return drvcrypt_register_cipher(&driver_cipher_cryp); 263 else 264 return TEE_ERROR_BAD_PARAMETERS; 265 } 266