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