1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022 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 #include "sm4.h" 15 16 struct sm4_xts_ctx { 17 struct crypto_cipher_ctx ctx; 18 struct sm4_context state; 19 struct sm4_context state_ek; 20 struct sm4_context state_dk; 21 uint8_t iv[16]; 22 }; 23 24 static const struct crypto_cipher_ops sm4_xts_ops; 25 26 static struct sm4_xts_ctx *to_sm4_xts_ctx(struct crypto_cipher_ctx *ctx) 27 { 28 assert(ctx && ctx->ops == &sm4_xts_ops); 29 30 return container_of(ctx, struct sm4_xts_ctx, ctx); 31 } 32 33 static TEE_Result sm4_xts_init(struct crypto_cipher_ctx *ctx, 34 TEE_OperationMode mode, const uint8_t *key1, 35 size_t key1_len, const uint8_t *key2, 36 size_t key2_len, const uint8_t *iv, 37 size_t iv_len) 38 { 39 struct sm4_xts_ctx *c = to_sm4_xts_ctx(ctx); 40 41 if (key1_len != 16 || key2_len != 16 || iv_len != sizeof(c->iv)) 42 return TEE_ERROR_BAD_STATE; 43 44 if (iv) 45 memcpy(c->iv, iv, sizeof(c->iv)); 46 47 if (mode == TEE_MODE_ENCRYPT) 48 sm4_setkey_enc(&c->state, key1); 49 else 50 sm4_setkey_dec(&c->state, key1); 51 52 sm4_setkey_enc(&c->state_ek, key2); 53 sm4_setkey_dec(&c->state_dk, key2); 54 55 return TEE_SUCCESS; 56 } 57 58 static TEE_Result sm4_xts_update(struct crypto_cipher_ctx *ctx, 59 bool last_block __unused, const uint8_t *data, 60 size_t len, uint8_t *dst) 61 { 62 struct sm4_xts_ctx *c = to_sm4_xts_ctx(ctx); 63 64 sm4_crypt_xts(&c->state, &c->state_ek, &c->state_dk, 65 len, c->iv, data, dst); 66 67 return TEE_SUCCESS; 68 } 69 70 static void sm4_xts_final(struct crypto_cipher_ctx *ctx) 71 { 72 struct sm4_xts_ctx *c = to_sm4_xts_ctx(ctx); 73 74 memzero_explicit(&c->state, sizeof(c->state)); 75 memzero_explicit(&c->state_ek, sizeof(c->state_ek)); 76 memzero_explicit(&c->state_dk, sizeof(c->state_dk)); 77 memzero_explicit(&c->iv, sizeof(c->iv)); 78 } 79 80 static void sm4_xts_free_ctx(struct crypto_cipher_ctx *ctx) 81 { 82 free(to_sm4_xts_ctx(ctx)); 83 } 84 85 static void sm4_xts_copy_state(struct crypto_cipher_ctx *dst_ctx, 86 struct crypto_cipher_ctx *src_ctx) 87 { 88 struct sm4_xts_ctx *src = to_sm4_xts_ctx(src_ctx); 89 struct sm4_xts_ctx *dst = to_sm4_xts_ctx(dst_ctx); 90 91 dst->state = src->state; 92 dst->state_ek = src->state_ek; 93 dst->state_dk = src->state_dk; 94 memcpy(dst->iv, src->iv, sizeof(src->iv)); 95 } 96 97 static const struct crypto_cipher_ops sm4_xts_ops = { 98 .init = sm4_xts_init, 99 .update = sm4_xts_update, 100 .final = sm4_xts_final, 101 .free_ctx = sm4_xts_free_ctx, 102 .copy_state = sm4_xts_copy_state, 103 }; 104 105 TEE_Result crypto_sm4_xts_alloc_ctx(struct crypto_cipher_ctx **ctx_ret) 106 { 107 struct sm4_xts_ctx *c = NULL; 108 109 c = calloc(1, sizeof(*c)); 110 if (!c) 111 return TEE_ERROR_OUT_OF_MEMORY; 112 113 c->ctx.ops = &sm4_xts_ops; 114 *ctx_ret = &c->ctx; 115 116 return TEE_SUCCESS; 117 } 118