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 19 #define DES3_KEY_SIZE 24 20 21 struct stm32_cipher_ctx { 22 struct crypto_cipher_ctx c_ctx; 23 struct stm32_cryp_context cryp; 24 enum stm32_cryp_algo_mode algo; 25 }; 26 27 static struct stm32_cipher_ctx * 28 to_stm32_cipher_ctx(struct crypto_cipher_ctx *ctx) 29 { 30 assert(ctx); 31 32 return container_of(ctx, struct stm32_cipher_ctx, c_ctx); 33 } 34 35 static TEE_Result stm32_cipher_initialize(struct drvcrypt_cipher_init *dinit) 36 { 37 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dinit->ctx); 38 uint8_t temp_key[DES3_KEY_SIZE] = { 0 }; 39 uint8_t *key = NULL; 40 size_t key_size = 0; 41 42 if (dinit->key1.length == 16 && 43 (c->algo == STM32_CRYP_MODE_TDES_ECB || 44 c->algo == STM32_CRYP_MODE_TDES_CBC)) { 45 /* Manage DES2: ie K=K1.K2.K1 */ 46 memcpy(temp_key, dinit->key1.data, dinit->key1.length); 47 memcpy(temp_key + dinit->key1.length, dinit->key1.data, 48 dinit->key1.length / 2); 49 key_size = DES3_KEY_SIZE; 50 key = temp_key; 51 } else { 52 key_size = dinit->key1.length; 53 key = dinit->key1.data; 54 } 55 56 return stm32_cryp_init(&c->cryp, !dinit->encrypt, c->algo, 57 key, key_size, dinit->iv.data, 58 dinit->iv.length); 59 } 60 61 static TEE_Result stm32_cipher_update(struct drvcrypt_cipher_update *dupdate) 62 { 63 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dupdate->ctx); 64 size_t len = MIN(dupdate->src.length, dupdate->dst.length); 65 66 return stm32_cryp_update(&c->cryp, dupdate->last, 67 dupdate->src.data, dupdate->dst.data, 68 len); 69 } 70 71 static void stm32_cipher_final(void *ctx __unused) 72 { 73 } 74 75 static void stm32_cipher_free(void *ctx) 76 { 77 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx); 78 79 free(c); 80 } 81 82 static void stm32_cipher_copy_state(void *dst_ctx, void *src_ctx) 83 { 84 struct stm32_cipher_ctx *src = to_stm32_cipher_ctx(src_ctx); 85 struct stm32_cipher_ctx *dst = to_stm32_cipher_ctx(dst_ctx); 86 87 memcpy(dst, src, sizeof(*dst)); 88 } 89 90 static TEE_Result alloc_ctx(void **ctx, enum stm32_cryp_algo_mode algo) 91 { 92 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c)); 93 94 if (!c) 95 return TEE_ERROR_OUT_OF_MEMORY; 96 97 c->algo = algo; 98 *ctx = &c->c_ctx; 99 100 return TEE_SUCCESS; 101 } 102 103 /* 104 * Allocate the SW cipher data context. 105 * 106 * @ctx [out] Caller context variable 107 * @algo Algorithm ID of the context 108 */ 109 static TEE_Result stm32_cipher_allocate(void **ctx, uint32_t algo) 110 { 111 /* 112 * Convert TEE_ALGO id to internal id 113 */ 114 switch (algo) { 115 case TEE_ALG_DES_ECB_NOPAD: 116 return alloc_ctx(ctx, STM32_CRYP_MODE_DES_ECB); 117 case TEE_ALG_DES_CBC_NOPAD: 118 return alloc_ctx(ctx, STM32_CRYP_MODE_DES_CBC); 119 case TEE_ALG_DES3_ECB_NOPAD: 120 return alloc_ctx(ctx, STM32_CRYP_MODE_TDES_ECB); 121 case TEE_ALG_DES3_CBC_NOPAD: 122 return alloc_ctx(ctx, STM32_CRYP_MODE_TDES_CBC); 123 case TEE_ALG_AES_ECB_NOPAD: 124 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_ECB); 125 case TEE_ALG_AES_CBC_NOPAD: 126 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CBC); 127 case TEE_ALG_AES_CTR: 128 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CTR); 129 default: 130 return TEE_ERROR_NOT_IMPLEMENTED; 131 } 132 } 133 134 static struct drvcrypt_cipher driver_cipher = { 135 .alloc_ctx = &stm32_cipher_allocate, 136 .free_ctx = &stm32_cipher_free, 137 .init = &stm32_cipher_initialize, 138 .update = &stm32_cipher_update, 139 .final = &stm32_cipher_final, 140 .copy_state = &stm32_cipher_copy_state, 141 }; 142 143 TEE_Result stm32_register_cipher(void) 144 { 145 return drvcrypt_register_cipher(&driver_cipher); 146 } 147