1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014-2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <crypto/crypto_impl.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <string_ext.h> 12 #include <tee_api_types.h> 13 #include <tomcrypt_private.h> 14 #include <utee_defines.h> 15 #include <util.h> 16 17 /****************************************************************************** 18 * Message digest functions 19 ******************************************************************************/ 20 21 struct ltc_hash_ctx { 22 struct crypto_hash_ctx ctx; 23 const struct ltc_hash_descriptor *descr; 24 hash_state state; 25 }; 26 27 static const struct crypto_hash_ops ltc_hash_ops; 28 29 static struct ltc_hash_ctx *to_hash_ctx(struct crypto_hash_ctx *ctx) 30 { 31 assert(ctx && ctx->ops == <c_hash_ops); 32 33 return container_of(ctx, struct ltc_hash_ctx, ctx); 34 } 35 36 static TEE_Result ltc_hash_init(struct crypto_hash_ctx *ctx) 37 { 38 struct ltc_hash_ctx *hc = to_hash_ctx(ctx); 39 40 if (hc->descr->init(&hc->state) == CRYPT_OK) 41 return TEE_SUCCESS; 42 else 43 return TEE_ERROR_BAD_STATE; 44 } 45 46 static TEE_Result ltc_hash_update(struct crypto_hash_ctx *ctx, 47 const uint8_t *data, size_t len) 48 { 49 struct ltc_hash_ctx *hc = to_hash_ctx(ctx); 50 51 if (hc->descr->process(&hc->state, data, len) == CRYPT_OK) 52 return TEE_SUCCESS; 53 else 54 return TEE_ERROR_BAD_STATE; 55 } 56 57 static TEE_Result ltc_hash_final(struct crypto_hash_ctx *ctx, uint8_t *digest, 58 size_t len) 59 { 60 struct ltc_hash_ctx *hc = to_hash_ctx(ctx); 61 size_t hash_size = hc->descr->hashsize; 62 uint8_t block_digest[TEE_MAX_HASH_SIZE] = { 0 }; 63 uint8_t *tmp_digest = NULL; 64 65 if (len == 0) 66 return TEE_ERROR_BAD_PARAMETERS; 67 68 if (hash_size > len) { 69 if (hash_size > sizeof(block_digest)) 70 return TEE_ERROR_BAD_STATE; 71 tmp_digest = block_digest; /* use a tempory buffer */ 72 } else { 73 tmp_digest = digest; 74 } 75 76 if (hc->descr->done(&hc->state, tmp_digest) == CRYPT_OK) { 77 if (hash_size > len) 78 memcpy(digest, tmp_digest, len); 79 } else { 80 return TEE_ERROR_BAD_STATE; 81 } 82 83 return TEE_SUCCESS; 84 } 85 86 static void ltc_hash_free_ctx(struct crypto_hash_ctx *ctx) 87 { 88 free(to_hash_ctx(ctx)); 89 } 90 91 static void ltc_hash_copy_state(struct crypto_hash_ctx *dst_ctx, 92 struct crypto_hash_ctx *src_ctx) 93 { 94 struct ltc_hash_ctx *src = to_hash_ctx(src_ctx); 95 struct ltc_hash_ctx *dst = to_hash_ctx(dst_ctx); 96 97 assert(src->descr == dst->descr); 98 dst->state = src->state; 99 } 100 101 static const struct crypto_hash_ops ltc_hash_ops = { 102 .init = ltc_hash_init, 103 .update = ltc_hash_update, 104 .final = ltc_hash_final, 105 .free_ctx = ltc_hash_free_ctx, 106 .copy_state = ltc_hash_copy_state, 107 }; 108 109 static TEE_Result ltc_hash_alloc_ctx(struct crypto_hash_ctx **ctx_ret, 110 int ltc_hash_idx) 111 { 112 struct ltc_hash_ctx *ctx = NULL; 113 114 if (ltc_hash_idx < 0) 115 return TEE_ERROR_NOT_SUPPORTED; 116 117 ctx = calloc(1, sizeof(*ctx)); 118 if (!ctx) 119 return TEE_ERROR_OUT_OF_MEMORY; 120 121 ctx->ctx.ops = <c_hash_ops; 122 ctx->descr = hash_descriptor[ltc_hash_idx]; 123 124 *ctx_ret = &ctx->ctx; 125 126 return TEE_SUCCESS; 127 } 128 129 #if defined(_CFG_CORE_LTC_MD5) 130 TEE_Result crypto_md5_alloc_ctx(struct crypto_hash_ctx **ctx) 131 { 132 return ltc_hash_alloc_ctx(ctx, find_hash("md5")); 133 } 134 #endif 135 136 #if defined(_CFG_CORE_LTC_SHA1) 137 TEE_Result crypto_sha1_alloc_ctx(struct crypto_hash_ctx **ctx) 138 { 139 return ltc_hash_alloc_ctx(ctx, find_hash("sha1")); 140 } 141 #endif 142 143 #if defined(_CFG_CORE_LTC_SHA224) 144 TEE_Result crypto_sha224_alloc_ctx(struct crypto_hash_ctx **ctx) 145 { 146 return ltc_hash_alloc_ctx(ctx, find_hash("sha224")); 147 } 148 #endif 149 150 #if defined(_CFG_CORE_LTC_SHA256) 151 TEE_Result crypto_sha256_alloc_ctx(struct crypto_hash_ctx **ctx) 152 { 153 return ltc_hash_alloc_ctx(ctx, find_hash("sha256")); 154 } 155 #endif 156 157 #if defined(_CFG_CORE_LTC_SHA384) 158 TEE_Result crypto_sha384_alloc_ctx(struct crypto_hash_ctx **ctx) 159 { 160 return ltc_hash_alloc_ctx(ctx, find_hash("sha384")); 161 } 162 #endif 163 164 #if defined(_CFG_CORE_LTC_SHA512) 165 TEE_Result crypto_sha512_alloc_ctx(struct crypto_hash_ctx **ctx) 166 { 167 return ltc_hash_alloc_ctx(ctx, find_hash("sha512")); 168 } 169 #endif 170 171 #if defined(_CFG_CORE_LTC_SHA256) 172 TEE_Result hash_sha256_check(const uint8_t *hash, const uint8_t *data, 173 size_t data_size) 174 { 175 hash_state hs; 176 uint8_t digest[TEE_SHA256_HASH_SIZE]; 177 178 if (sha256_init(&hs) != CRYPT_OK) 179 return TEE_ERROR_GENERIC; 180 if (sha256_process(&hs, data, data_size) != CRYPT_OK) 181 return TEE_ERROR_GENERIC; 182 if (sha256_done(&hs, digest) != CRYPT_OK) 183 return TEE_ERROR_GENERIC; 184 if (consttime_memcmp(digest, hash, sizeof(digest)) != 0) 185 return TEE_ERROR_SECURITY; 186 return TEE_SUCCESS; 187 } 188 #endif 189 190 #if defined(_CFG_CORE_LTC_SHA512_256) 191 TEE_Result hash_sha512_256_compute(uint8_t *digest, const uint8_t *data, 192 size_t data_size) 193 { 194 hash_state hs; 195 196 if (sha512_256_init(&hs) != CRYPT_OK) 197 return TEE_ERROR_GENERIC; 198 if (sha512_256_process(&hs, data, data_size) != CRYPT_OK) 199 return TEE_ERROR_GENERIC; 200 if (sha512_256_done(&hs, digest) != CRYPT_OK) 201 return TEE_ERROR_GENERIC; 202 203 return TEE_SUCCESS; 204 } 205 #endif 206 207 #if defined(_CFG_CORE_LTC_SHA3_224) 208 TEE_Result crypto_sha3_224_alloc_ctx(struct crypto_hash_ctx **ctx) 209 { 210 return ltc_hash_alloc_ctx(ctx, find_hash("sha3-224")); 211 } 212 #endif 213 214 #if defined(_CFG_CORE_LTC_SHA3_256) 215 TEE_Result crypto_sha3_256_alloc_ctx(struct crypto_hash_ctx **ctx) 216 { 217 return ltc_hash_alloc_ctx(ctx, find_hash("sha3-256")); 218 } 219 #endif 220 221 #if defined(_CFG_CORE_LTC_SHA3_384) 222 TEE_Result crypto_sha3_384_alloc_ctx(struct crypto_hash_ctx **ctx) 223 { 224 return ltc_hash_alloc_ctx(ctx, find_hash("sha3-384")); 225 } 226 #endif 227 228 #if defined(_CFG_CORE_LTC_SHA3_512) 229 TEE_Result crypto_sha3_512_alloc_ctx(struct crypto_hash_ctx **ctx) 230 { 231 return ltc_hash_alloc_ctx(ctx, find_hash("sha3-512")); 232 } 233 #endif 234