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.h> 11 #include <string_ext.h> 12 #include <tee_api_types.h> 13 #include <util.h> 14 15 #include "sm4.h" 16 17 struct sm4_ctr_ctx { 18 struct crypto_cipher_ctx ctx; 19 struct sm4_context state; 20 uint8_t ctr[16]; 21 }; 22 23 static const struct crypto_cipher_ops sm4_ctr_ops; 24 25 static struct sm4_ctr_ctx *to_sm4_ctr_ctx(struct crypto_cipher_ctx *ctx) 26 { 27 assert(ctx && ctx->ops == &sm4_ctr_ops); 28 29 return container_of(ctx, struct sm4_ctr_ctx, ctx); 30 } 31 32 static TEE_Result sm4_ctr_init(struct crypto_cipher_ctx *ctx, 33 TEE_OperationMode mode __unused, 34 const uint8_t *key1, size_t key1_len, 35 const uint8_t *key2 __unused, 36 size_t key2_len __unused, 37 const uint8_t *iv, size_t iv_len) 38 { 39 struct sm4_ctr_ctx *c = to_sm4_ctr_ctx(ctx); 40 41 if (key1_len != 16 || iv_len != sizeof(c->ctr)) 42 return TEE_ERROR_BAD_PARAMETERS; 43 44 sm4_setkey_enc(&c->state, key1); 45 memcpy(c->ctr, iv, sizeof(c->ctr)); 46 47 return TEE_SUCCESS; 48 } 49 50 static TEE_Result sm4_ctr_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_ctr_ctx *c = to_sm4_ctr_ctx(ctx); 55 56 sm4_crypt_ctr(&c->state, len, c->ctr, data, dst); 57 58 return TEE_SUCCESS; 59 } 60 61 static void sm4_ctr_final(struct crypto_cipher_ctx *ctx) 62 { 63 struct sm4_ctr_ctx *c = to_sm4_ctr_ctx(ctx); 64 65 memzero_explicit(&c->state, sizeof(c->state)); 66 memzero_explicit(&c->ctr, sizeof(c->ctr)); 67 } 68 69 static void sm4_ctr_free_ctx(struct crypto_cipher_ctx *ctx) 70 { 71 free(to_sm4_ctr_ctx(ctx)); 72 } 73 74 static void sm4_ctr_copy_state(struct crypto_cipher_ctx *dst_ctx, 75 struct crypto_cipher_ctx *src_ctx) 76 { 77 struct sm4_ctr_ctx *src = to_sm4_ctr_ctx(src_ctx); 78 struct sm4_ctr_ctx *dst = to_sm4_ctr_ctx(dst_ctx); 79 80 dst->state = src->state; 81 memcpy(dst->ctr, src->ctr, sizeof(src->ctr)); 82 } 83 84 static const struct crypto_cipher_ops sm4_ctr_ops = { 85 .init = sm4_ctr_init, 86 .update = sm4_ctr_update, 87 .final = sm4_ctr_final, 88 .free_ctx = sm4_ctr_free_ctx, 89 .copy_state = sm4_ctr_copy_state, 90 }; 91 92 TEE_Result crypto_sm4_ctr_alloc_ctx(struct crypto_cipher_ctx **ctx_ret) 93 { 94 struct sm4_ctr_ctx *c = NULL; 95 96 c = calloc(1, sizeof(*c)); 97 if (!c) 98 return TEE_ERROR_OUT_OF_MEMORY; 99 100 c->ctx.ops = &sm4_ctr_ops; 101 *ctx_ret = &c->ctx; 102 103 return TEE_SUCCESS; 104 } 105