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_hash.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_hash_ops hash_ops; 18 19 struct stm32_hash_ctx { 20 struct crypto_hash_ctx ch_ctx; 21 struct stm32_hash_context hash; 22 }; 23 24 static struct stm32_hash_ctx *to_stm32_hash_ctx(struct crypto_hash_ctx *ctx) 25 { 26 assert(ctx && ctx->ops == &hash_ops); 27 28 return container_of(ctx, struct stm32_hash_ctx, ch_ctx); 29 } 30 31 /* 32 * Initialization of the Hash operation 33 * 34 * @ctx Operation software context 35 */ 36 static TEE_Result do_hash_init(struct crypto_hash_ctx *ctx) 37 { 38 struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx); 39 40 return stm32_hash_init(&c->hash, NULL, 0); 41 } 42 43 /* 44 * Update the Hash operation 45 * 46 * @ctx Operation software context 47 * @data Data to hash 48 * @len Data length 49 */ 50 static TEE_Result do_hash_update(struct crypto_hash_ctx *ctx, 51 const uint8_t *data, size_t len) 52 { 53 struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx); 54 55 return stm32_hash_update(&c->hash, data, len); 56 } 57 58 /* 59 * Finalize the Hash operation 60 * 61 * @ctx Operation software context 62 * @digest [out] Hash digest buffer 63 * @len Digest buffer length 64 */ 65 static TEE_Result do_hash_final(struct crypto_hash_ctx *ctx, uint8_t *digest, 66 size_t len) 67 { 68 struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx); 69 TEE_Result res = TEE_ERROR_GENERIC; 70 uint8_t block_digest[STM32_HASH_MAX_DIGEST_SIZE] = { 0 }; 71 uint8_t *tmp_digest = digest; 72 73 if (len < stm32_hash_digest_size(&c->hash)) 74 tmp_digest = block_digest; 75 76 res = stm32_hash_final(&c->hash, tmp_digest, NULL, 0); 77 78 if (res == TEE_SUCCESS && len < stm32_hash_digest_size(&c->hash)) 79 memcpy(digest, tmp_digest, len); 80 81 return res; 82 } 83 84 /* 85 * Free the SW hashing data context 86 * 87 * @ctx [in/out] Caller context variable 88 */ 89 static void do_hash_free(struct crypto_hash_ctx *ctx) 90 { 91 struct stm32_hash_ctx *c = to_stm32_hash_ctx(ctx); 92 93 stm32_hash_free(&c->hash); 94 free(c); 95 } 96 97 /* 98 * Copy Software Hashing Context 99 * 100 * @dst_ctx [out] Reference the context destination 101 * @src_ctx Reference the context source 102 */ 103 static void do_hash_copy_state(struct crypto_hash_ctx *dst_ctx, 104 struct crypto_hash_ctx *src_ctx) 105 { 106 struct stm32_hash_ctx *src = to_stm32_hash_ctx(src_ctx); 107 struct stm32_hash_ctx *dst = to_stm32_hash_ctx(dst_ctx); 108 109 memcpy(&dst->ch_ctx, &src->ch_ctx, sizeof(dst->ch_ctx)); 110 stm32_hash_deep_copy(&dst->hash, &src->hash); 111 } 112 113 /* 114 * Registration of the hash Driver 115 */ 116 static const struct crypto_hash_ops hash_ops = { 117 .init = do_hash_init, 118 .update = do_hash_update, 119 .final = do_hash_final, 120 .free_ctx = do_hash_free, 121 .copy_state = do_hash_copy_state, 122 }; 123 124 /* 125 * Allocate the internal hashing data context 126 * 127 * @ctx [out] Caller context variable 128 * @algo OP_TEE Algorithm ID 129 */ 130 static TEE_Result stm32_hash_allocate(struct crypto_hash_ctx **ctx, 131 uint32_t algo) 132 { 133 TEE_Result res = TEE_ERROR_GENERIC; 134 struct stm32_hash_ctx *c = NULL; 135 enum stm32_hash_algo stm32_algo = STM32_HASH_SHA256; 136 137 /* Convert TEE Algo id to stm32 hash id */ 138 switch (TEE_ALG_GET_MAIN_ALG(algo)) { 139 case TEE_MAIN_ALGO_MD5: 140 stm32_algo = STM32_HASH_MD5; 141 break; 142 case TEE_MAIN_ALGO_SHA1: 143 stm32_algo = STM32_HASH_SHA1; 144 break; 145 case TEE_MAIN_ALGO_SHA224: 146 stm32_algo = STM32_HASH_SHA224; 147 break; 148 case TEE_MAIN_ALGO_SHA256: 149 stm32_algo = STM32_HASH_SHA256; 150 break; 151 case TEE_MAIN_ALGO_SHA384: 152 stm32_algo = STM32_HASH_SHA384; 153 break; 154 case TEE_MAIN_ALGO_SHA512: 155 stm32_algo = STM32_HASH_SHA512; 156 break; 157 default: 158 return TEE_ERROR_NOT_IMPLEMENTED; 159 } 160 161 c = calloc(1, sizeof(*c)); 162 if (!c) 163 return TEE_ERROR_OUT_OF_MEMORY; 164 165 res = stm32_hash_alloc(&c->hash, STM32_HASH_MODE, stm32_algo); 166 if (res) { 167 free(c); 168 return res; 169 } 170 171 FMSG("Using HASH %"PRIu32, stm32_algo); 172 c->ch_ctx.ops = &hash_ops; 173 *ctx = &c->ch_ctx; 174 175 return TEE_SUCCESS; 176 } 177 178 TEE_Result stm32_register_hash(void) 179 { 180 return drvcrypt_register_hash(&stm32_hash_allocate); 181 } 182