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
to_sm4_xts_ctx(struct crypto_cipher_ctx * ctx)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
sm4_xts_init(struct crypto_cipher_ctx * ctx,TEE_OperationMode mode,const uint8_t * key1,size_t key1_len,const uint8_t * key2,size_t key2_len,const uint8_t * iv,size_t iv_len)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
sm4_xts_update(struct crypto_cipher_ctx * ctx,bool last_block __unused,const uint8_t * data,size_t len,uint8_t * dst)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
sm4_xts_final(struct crypto_cipher_ctx * ctx)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
sm4_xts_free_ctx(struct crypto_cipher_ctx * ctx)80 static void sm4_xts_free_ctx(struct crypto_cipher_ctx *ctx)
81 {
82 free(to_sm4_xts_ctx(ctx));
83 }
84
sm4_xts_copy_state(struct crypto_cipher_ctx * dst_ctx,struct crypto_cipher_ctx * src_ctx)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
crypto_sm4_xts_alloc_ctx(struct crypto_cipher_ctx ** ctx_ret)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