xref: /optee_os/lib/libmbedtls/core/aes_cbc.c (revision b99a4a1850c2ce661156ebc25f48d47efa8a41c1)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2019, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <compiler.h>
8 #include <crypto/crypto.h>
9 #include <crypto/crypto_impl.h>
10 #include <mbedtls/aes.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <tee_api_types.h>
14 #include <utee_defines.h>
15 #include <util.h>
16 
17 struct mbed_aes_cbc_ctx {
18 	struct crypto_cipher_ctx ctx;
19 	int mbed_mode;
20 	mbedtls_aes_context aes_ctx;
21 	unsigned char iv[TEE_AES_BLOCK_SIZE];
22 };
23 
24 static const struct crypto_cipher_ops mbed_aes_cbc_ops;
25 
26 static struct mbed_aes_cbc_ctx *to_aes_cbc_ctx(struct crypto_cipher_ctx *ctx)
27 {
28 	assert(ctx && ctx->ops == &mbed_aes_cbc_ops);
29 
30 	return container_of(ctx, struct mbed_aes_cbc_ctx, ctx);
31 }
32 
33 static TEE_Result mbed_aes_cbc_init(struct crypto_cipher_ctx *ctx,
34 				    TEE_OperationMode mode, const uint8_t *key1,
35 				    size_t key1_len,
36 				    const uint8_t *key2 __unused,
37 				    size_t key2_len __unused,
38 				    const uint8_t *iv, size_t iv_len)
39 {
40 	struct mbed_aes_cbc_ctx *c = to_aes_cbc_ctx(ctx);
41 	int mbed_res = 0;
42 
43 	if (iv_len != sizeof(c->iv))
44 		return TEE_ERROR_BAD_PARAMETERS;
45 	memcpy(c->iv, iv, sizeof(c->iv));
46 
47 	mbedtls_aes_init(&c->aes_ctx);
48 
49 	if (mode == TEE_MODE_ENCRYPT) {
50 		c->mbed_mode = MBEDTLS_AES_ENCRYPT;
51 		mbed_res = mbedtls_aes_setkey_enc(&c->aes_ctx, key1,
52 						  key1_len * 8);
53 	} else {
54 		c->mbed_mode = MBEDTLS_AES_DECRYPT;
55 		mbed_res = mbedtls_aes_setkey_dec(&c->aes_ctx, key1,
56 						  key1_len * 8);
57 	}
58 
59 	if (mbed_res)
60 		return TEE_ERROR_BAD_STATE;
61 
62 	return TEE_SUCCESS;
63 }
64 
65 static TEE_Result mbed_aes_cbc_update(struct crypto_cipher_ctx *ctx,
66 				      bool last_block __unused,
67 				      const uint8_t *data, size_t len,
68 				      uint8_t *dst)
69 {
70 	struct mbed_aes_cbc_ctx *c = to_aes_cbc_ctx(ctx);
71 
72 	if (mbedtls_aes_crypt_cbc(&c->aes_ctx, c->mbed_mode, len, c->iv,
73 				  data, dst))
74 		return TEE_ERROR_BAD_STATE;
75 
76 	return TEE_SUCCESS;
77 }
78 
79 static void mbed_aes_cbc_final(struct crypto_cipher_ctx *ctx)
80 {
81 	mbedtls_aes_free(&to_aes_cbc_ctx(ctx)->aes_ctx);
82 }
83 
84 static void mbed_aes_cbc_free_ctx(struct crypto_cipher_ctx *ctx)
85 {
86 	free(to_aes_cbc_ctx(ctx));
87 }
88 
89 static void mbed_aes_cbc_copy_state(struct crypto_cipher_ctx *dst_ctx,
90 				    struct crypto_cipher_ctx *src_ctx)
91 {
92 	struct mbed_aes_cbc_ctx *src = to_aes_cbc_ctx(src_ctx);
93 	struct mbed_aes_cbc_ctx *dst = to_aes_cbc_ctx(dst_ctx);
94 
95 	memcpy(dst->iv, src->iv, sizeof(dst->iv));
96 	dst->mbed_mode = src->mbed_mode;
97 	dst->aes_ctx = src->aes_ctx;
98 }
99 
100 static const struct crypto_cipher_ops mbed_aes_cbc_ops = {
101 	.init = mbed_aes_cbc_init,
102 	.update = mbed_aes_cbc_update,
103 	.final = mbed_aes_cbc_final,
104 	.free_ctx = mbed_aes_cbc_free_ctx,
105 	.copy_state = mbed_aes_cbc_copy_state,
106 };
107 
108 TEE_Result crypto_aes_cbc_alloc_ctx(struct crypto_cipher_ctx **ctx_ret)
109 {
110 	struct mbed_aes_cbc_ctx *c = NULL;
111 
112 	c = calloc(1, sizeof(*c));
113 	if (!c)
114 		return TEE_ERROR_OUT_OF_MEMORY;
115 
116 	c->ctx.ops = &mbed_aes_cbc_ops;
117 	*ctx_ret = &c->ctx;
118 
119 	return TEE_SUCCESS;
120 }
121