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