1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <crypto/crypto_impl.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <tomcrypt_private.h> 11 #include <utee_defines.h> 12 13 struct shake_ctx { 14 struct crypto_hash_ctx ctx; 15 struct sha3_state sha3; 16 }; 17 18 static struct shake_ctx *to_shake_ctx(struct crypto_hash_ctx *ctx) 19 { 20 return container_of(ctx, struct shake_ctx, ctx); 21 } 22 23 static TEE_Result do_shake_init(struct crypto_hash_ctx *ctx, unsigned int num) 24 { 25 struct shake_ctx *c = to_shake_ctx(ctx); 26 27 if (sha3_shake_init((void *)&c->sha3, num) == CRYPT_OK) 28 return TEE_SUCCESS; 29 else 30 return TEE_ERROR_BAD_STATE; 31 } 32 33 static TEE_Result do_sha3_update(struct crypto_hash_ctx *ctx, 34 const uint8_t *data, size_t len) 35 { 36 struct shake_ctx *c = to_shake_ctx(ctx); 37 38 if (sha3_process((void *)&c->sha3, data, len) == CRYPT_OK) 39 return TEE_SUCCESS; 40 else 41 return TEE_ERROR_BAD_STATE; 42 } 43 44 static TEE_Result do_shake_final(struct crypto_hash_ctx *ctx, 45 uint8_t *digest, size_t len) 46 { 47 struct shake_ctx *c = to_shake_ctx(ctx); 48 49 if (sha3_shake_done((void *)&c->sha3, digest, len) == CRYPT_OK) 50 return TEE_SUCCESS; 51 else 52 return TEE_ERROR_BAD_STATE; 53 } 54 55 static TEE_Result do_shake_alloc_ctx(struct crypto_hash_ctx **ctx_ret, 56 const struct crypto_hash_ops *ops) 57 { 58 struct shake_ctx *ctx = calloc(1, sizeof(*ctx)); 59 60 if (!ctx) 61 return TEE_ERROR_OUT_OF_MEMORY; 62 63 ctx->ctx.ops = ops; 64 *ctx_ret = &ctx->ctx; 65 66 return TEE_SUCCESS; 67 } 68 69 static void do_sha3_free_ctx(struct crypto_hash_ctx *ctx) 70 { 71 struct shake_ctx *c = to_shake_ctx(ctx); 72 73 free(c); 74 } 75 static void do_sha3_copy_state(struct crypto_hash_ctx *dst_ctx, 76 struct crypto_hash_ctx *src_ctx) 77 { 78 struct shake_ctx *dc = to_shake_ctx(dst_ctx); 79 struct shake_ctx *sc = to_shake_ctx(src_ctx); 80 81 assert(sc->ctx.ops == dc->ctx.ops); 82 dc->sha3 = sc->sha3; 83 } 84 85 #if defined(_CFG_CORE_LTC_SHAKE128) 86 static TEE_Result do_shake128_init(struct crypto_hash_ctx *ctx) 87 { 88 return do_shake_init(ctx, 128); 89 } 90 91 static const struct crypto_hash_ops shake128_ops = { 92 .init = do_shake128_init, 93 .update = do_sha3_update, 94 .final = do_shake_final, 95 .free_ctx = do_sha3_free_ctx, 96 .copy_state = do_sha3_copy_state, 97 }; 98 99 TEE_Result crypto_shake128_alloc_ctx(struct crypto_hash_ctx **ctx) 100 { 101 return do_shake_alloc_ctx(ctx, &shake128_ops); 102 } 103 #endif 104 105 #if defined(_CFG_CORE_LTC_SHAKE256) 106 static TEE_Result do_shake256_init(struct crypto_hash_ctx *ctx) 107 { 108 return do_shake_init(ctx, 256); 109 } 110 111 static const struct crypto_hash_ops shake256_ops = { 112 .init = do_shake256_init, 113 .update = do_sha3_update, 114 .final = do_shake_final, 115 .free_ctx = do_sha3_free_ctx, 116 .copy_state = do_sha3_copy_state, 117 }; 118 119 TEE_Result crypto_shake256_alloc_ctx(struct crypto_hash_ctx **ctx) 120 { 121 return do_shake_alloc_ctx(ctx, &shake256_ops); 122 } 123 #endif 124