1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019 Huawei Technologies Co., Ltd 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <crypto/crypto_impl.h> 9 #include <stdlib.h> 10 #include <string_ext.h> 11 #include <tee_api_types.h> 12 #include <util.h> 13 14 #include "sm4.h" 15 16 struct sm4_ecb_ctx { 17 struct crypto_cipher_ctx ctx; 18 struct sm4_context state; 19 }; 20 21 static const struct crypto_cipher_ops sm4_ecb_ops; 22 23 static struct sm4_ecb_ctx *to_sm4_ecb_ctx(struct crypto_cipher_ctx *ctx) 24 { 25 assert(ctx && ctx->ops == &sm4_ecb_ops); 26 27 return container_of(ctx, struct sm4_ecb_ctx, ctx); 28 } 29 30 static TEE_Result sm4_ecb_init(struct crypto_cipher_ctx *ctx, 31 TEE_OperationMode mode, const uint8_t *key1, 32 size_t key1_len, const uint8_t *key2 __unused, 33 size_t key2_len __unused, 34 const uint8_t *iv __unused, 35 size_t iv_len __unused) 36 { 37 struct sm4_ecb_ctx *c = to_sm4_ecb_ctx(ctx); 38 39 if (key1_len != 16) 40 return TEE_ERROR_BAD_STATE; 41 42 if (mode == TEE_MODE_ENCRYPT) 43 sm4_setkey_enc(&c->state, key1); 44 else 45 sm4_setkey_dec(&c->state, key1); 46 47 return TEE_SUCCESS; 48 } 49 50 static TEE_Result sm4_ecb_update(struct crypto_cipher_ctx *ctx, 51 bool last_block __unused, 52 const uint8_t *data, size_t len, uint8_t *dst) 53 { 54 struct sm4_ecb_ctx *c = to_sm4_ecb_ctx(ctx); 55 56 sm4_crypt_ecb(&c->state, len, data, dst); 57 58 return TEE_SUCCESS; 59 } 60 61 static void sm4_ecb_final(struct crypto_cipher_ctx *ctx) 62 { 63 struct sm4_ecb_ctx *c = to_sm4_ecb_ctx(ctx); 64 65 memzero_explicit(&c->state, sizeof(c->state)); 66 } 67 68 static void sm4_ecb_free_ctx(struct crypto_cipher_ctx *ctx) 69 { 70 free(to_sm4_ecb_ctx(ctx)); 71 } 72 73 static void sm4_ecb_copy_state(struct crypto_cipher_ctx *dst_ctx, 74 struct crypto_cipher_ctx *src_ctx) 75 { 76 struct sm4_ecb_ctx *src = to_sm4_ecb_ctx(src_ctx); 77 struct sm4_ecb_ctx *dst = to_sm4_ecb_ctx(dst_ctx); 78 79 dst->state = src->state; 80 } 81 82 static const struct crypto_cipher_ops sm4_ecb_ops = { 83 .init = sm4_ecb_init, 84 .update = sm4_ecb_update, 85 .final = sm4_ecb_final, 86 .free_ctx = sm4_ecb_free_ctx, 87 .copy_state = sm4_ecb_copy_state, 88 }; 89 90 TEE_Result crypto_sm4_ecb_alloc_ctx(struct crypto_cipher_ctx **ctx_ret) 91 { 92 struct sm4_ecb_ctx *c = NULL; 93 94 c = calloc(1, sizeof(*c)); 95 if (!c) 96 return TEE_ERROR_OUT_OF_MEMORY; 97 98 c->ctx.ops = &sm4_ecb_ops; 99 *ctx_ret = &c->ctx; 100 101 return TEE_SUCCESS; 102 } 103