1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2021-2025, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto_impl.h> 8 #include <crypto/crypto.h> 9 #include <drvcrypt_mac.h> 10 #include <drvcrypt.h> 11 #include <kernel/dt.h> 12 #include <string.h> 13 14 #include "common.h" 15 #include "stm32_hash.h" 16 17 static const struct crypto_mac_ops hmac_ops; 18 19 struct stm32_hmac_ctx { 20 struct crypto_mac_ctx mac_ctx; 21 struct stm32_hash_context hash; 22 uint8_t *key; 23 size_t key_len; 24 }; 25 26 static struct stm32_hmac_ctx *to_stm32_hmac_ctx(struct crypto_mac_ctx *ctx) 27 { 28 assert(ctx && ctx->ops == &hmac_ops); 29 30 return container_of(ctx, struct stm32_hmac_ctx, mac_ctx); 31 } 32 33 /* 34 * Initialization of the hmac operation 35 * 36 * @ctx Operation software context 37 * @key Key used for hmac operation 38 * @len Length of @key in bytes 39 */ 40 static TEE_Result do_hmac_init(struct crypto_mac_ctx *ctx, const uint8_t *key, 41 size_t len) 42 { 43 struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx); 44 45 /* 46 * If hmac_init() is called again, 47 * we won't need the previously saved key. 48 */ 49 if (c->key) 50 free(c->key); 51 52 c->key = malloc(len); 53 if (!c->key) { 54 c->key_len = 0; 55 return TEE_ERROR_OUT_OF_MEMORY; 56 } 57 memcpy(c->key, key, len); 58 c->key_len = len; 59 60 return stm32_hash_init(&c->hash, c->key, c->key_len); 61 } 62 63 /* 64 * Update the hmac operation 65 * 66 * @ctx Operation software context 67 * @data Data to hmac 68 * @len Data length 69 */ 70 static TEE_Result do_hmac_update(struct crypto_mac_ctx *ctx, 71 const uint8_t *data, size_t len) 72 { 73 struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx); 74 75 if (!c->key) { 76 EMSG("NULL key pointer"); 77 return TEE_ERROR_OUT_OF_MEMORY; 78 } 79 80 return stm32_hash_update(&c->hash, data, len); 81 } 82 83 /* 84 * Finalize the hmac operation 85 * 86 * @ctx Operation software context 87 * @digest [out] hmac digest buffer 88 * @len Digest buffer length 89 */ 90 static TEE_Result do_hmac_final(struct crypto_mac_ctx *ctx, uint8_t *digest, 91 size_t len) 92 { 93 struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx); 94 TEE_Result res = TEE_ERROR_GENERIC; 95 uint8_t block_digest[STM32_HASH_MAX_DIGEST_SIZE] = { 0 }; 96 uint8_t *tmp_digest = digest; 97 98 if (!c->key) { 99 EMSG("NULL key pointer"); 100 return TEE_ERROR_OUT_OF_MEMORY; 101 } 102 103 if (len < stm32_hash_digest_size(&c->hash)) 104 tmp_digest = block_digest; 105 106 res = stm32_hash_final(&c->hash, tmp_digest, c->key, c->key_len); 107 108 if (res == TEE_SUCCESS && len < stm32_hash_digest_size(&c->hash)) 109 memcpy(digest, tmp_digest, len); 110 111 return res; 112 } 113 114 /* 115 * Free the SW hmac context 116 * 117 * @ctx [in/out] Caller context variable 118 */ 119 static void do_hmac_free(struct crypto_mac_ctx *ctx) 120 { 121 struct stm32_hmac_ctx *c = to_stm32_hmac_ctx(ctx); 122 123 free(c->key); 124 stm32_hash_free(&c->hash); 125 free(c); 126 } 127 128 /* 129 * Copy Software HMAC Context 130 * 131 * @dst_ctx [out] Reference the context destination 132 * @src_ctx Reference the context source 133 */ 134 static void do_hmac_copy_state(struct crypto_mac_ctx *dst_ctx, 135 struct crypto_mac_ctx *src_ctx) 136 { 137 struct stm32_hmac_ctx *src = to_stm32_hmac_ctx(src_ctx); 138 struct stm32_hmac_ctx *dst = to_stm32_hmac_ctx(dst_ctx); 139 140 memcpy(&dst->mac_ctx, &src->mac_ctx, sizeof(dst->mac_ctx)); 141 stm32_hash_deep_copy(&dst->hash, &src->hash); 142 143 dst->key_len = src->key_len; 144 145 if (src->key) 146 dst->key = malloc(dst->key_len); 147 148 if (dst->key && src->key) 149 memcpy(dst->key, src->key, dst->key_len); 150 else 151 dst->key_len = 0; 152 } 153 154 /* 155 * Registration of the hmac Driver 156 */ 157 static const struct crypto_mac_ops hmac_ops = { 158 .init = do_hmac_init, 159 .update = do_hmac_update, 160 .final = do_hmac_final, 161 .free_ctx = do_hmac_free, 162 .copy_state = do_hmac_copy_state, 163 }; 164 165 /* 166 * Allocate the internal HMAC data context 167 * 168 * @ctx [out] Caller context variable 169 * @algo OP_TEE Algorithm ID 170 */ 171 static TEE_Result stm32_hmac_allocate(struct crypto_mac_ctx **ctx, 172 uint32_t algo) 173 { 174 TEE_Result res = TEE_ERROR_GENERIC; 175 enum stm32_hash_algo stm32_algo = STM32_HASH_MD5; 176 struct stm32_hmac_ctx *c = NULL; 177 178 switch (TEE_ALG_GET_MAIN_ALG(algo)) { 179 case TEE_MAIN_ALGO_MD5: 180 stm32_algo = STM32_HASH_MD5; 181 break; 182 case TEE_MAIN_ALGO_SHA1: 183 stm32_algo = STM32_HASH_SHA1; 184 break; 185 case TEE_MAIN_ALGO_SHA224: 186 stm32_algo = STM32_HASH_SHA224; 187 break; 188 case TEE_MAIN_ALGO_SHA256: 189 stm32_algo = STM32_HASH_SHA256; 190 break; 191 case TEE_MAIN_ALGO_SHA384: 192 stm32_algo = STM32_HASH_SHA384; 193 break; 194 case TEE_MAIN_ALGO_SHA512: 195 stm32_algo = STM32_HASH_SHA512; 196 break; 197 default: 198 return TEE_ERROR_NOT_IMPLEMENTED; 199 } 200 201 c = calloc(1, sizeof(*c)); 202 if (!c) 203 return TEE_ERROR_OUT_OF_MEMORY; 204 205 res = stm32_hash_alloc(&c->hash, STM32_HMAC_MODE, stm32_algo); 206 if (res) { 207 free(c); 208 return res; 209 } 210 211 FMSG("Using HMAC %d", stm32_algo); 212 c->mac_ctx.ops = &hmac_ops; 213 *ctx = &c->mac_ctx; 214 215 return TEE_SUCCESS; 216 } 217 218 TEE_Result stm32_register_hmac(void) 219 { 220 return drvcrypt_register_hmac(&stm32_hmac_allocate); 221 } 222