1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2018, ARM Limited
4 * Copyright (C) 2019, Linaro Limited
5 * Copyright (C) 2021, SumUp Services GmbH
6 */
7
8 #include <assert.h>
9 #include <crypto/crypto.h>
10 #include <crypto/crypto_impl.h>
11 #include <kernel/panic.h>
12 #include <mbedtls/cipher.h>
13 #include <mbedtls/cmac.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <tee_api_types.h>
17 #include <utee_defines.h>
18 #include <util.h>
19
20 struct mbed_cmac_ctx {
21 struct crypto_mac_ctx mac_ctx;
22 mbedtls_cipher_context_t cipher_ctx;
23 mbedtls_cipher_id_t cipher_id;
24 };
25
26 static const struct crypto_mac_ops mbed_cmac_ops;
27
to_cmac_ctx(struct crypto_mac_ctx * ctx)28 static struct mbed_cmac_ctx *to_cmac_ctx(struct crypto_mac_ctx *ctx)
29 {
30 assert(ctx);
31 assert(ctx->ops == &mbed_cmac_ops);
32
33 return container_of(ctx, struct mbed_cmac_ctx, mac_ctx);
34 }
35
mbed_cmac_init(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)36 static TEE_Result mbed_cmac_init(struct crypto_mac_ctx *ctx,
37 const uint8_t *key, size_t len)
38 {
39 struct mbed_cmac_ctx *c = to_cmac_ctx(ctx);
40 const mbedtls_cipher_info_t *cipher_info = NULL;
41
42 cipher_info = mbedtls_cipher_info_from_values(c->cipher_id,
43 len * 8,
44 MBEDTLS_MODE_ECB);
45 if (!cipher_info)
46 return TEE_ERROR_NOT_SUPPORTED;
47
48 if (mbedtls_cipher_setup_info(&c->cipher_ctx, cipher_info))
49 return TEE_ERROR_BAD_STATE;
50
51 if (mbedtls_cipher_cmac_reset(&c->cipher_ctx))
52 return TEE_ERROR_BAD_STATE;
53
54 if (mbedtls_cipher_cmac_starts(&c->cipher_ctx, key, len * 8))
55 return TEE_ERROR_BAD_STATE;
56
57 return TEE_SUCCESS;
58 }
59
mbed_cmac_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)60 static TEE_Result mbed_cmac_update(struct crypto_mac_ctx *ctx,
61 const uint8_t *data, size_t len)
62 {
63 struct mbed_cmac_ctx *c = to_cmac_ctx(ctx);
64
65 if (mbedtls_cipher_cmac_update(&c->cipher_ctx, data, len))
66 return TEE_ERROR_BAD_STATE;
67
68 return TEE_SUCCESS;
69 }
70
mbed_cmac_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)71 static TEE_Result mbed_cmac_final(struct crypto_mac_ctx *ctx,
72 uint8_t *digest, size_t len)
73 {
74 struct mbed_cmac_ctx *c = to_cmac_ctx(ctx);
75 size_t block_size = TEE_AES_BLOCK_SIZE;
76 uint8_t block_digest[TEE_AES_BLOCK_SIZE] = { };
77 uint8_t *tmp_digest = NULL;
78
79 COMPILE_TIME_ASSERT(TEE_AES_BLOCK_SIZE >= TEE_DES_BLOCK_SIZE);
80
81 if (len == 0)
82 return TEE_ERROR_BAD_PARAMETERS;
83
84 if (c->cipher_id == MBEDTLS_CIPHER_ID_3DES)
85 block_size = TEE_DES_BLOCK_SIZE;
86
87 if (len < block_size)
88 tmp_digest = block_digest; /* use a tempory buffer */
89 else
90 tmp_digest = digest;
91
92 if (mbedtls_cipher_cmac_finish(&c->cipher_ctx, tmp_digest))
93 return TEE_ERROR_BAD_STATE;
94
95 if (len < block_size)
96 memcpy(digest, tmp_digest, len);
97
98 return TEE_SUCCESS;
99 }
100
mbed_cmac_free_ctx(struct crypto_mac_ctx * ctx)101 static void mbed_cmac_free_ctx(struct crypto_mac_ctx *ctx)
102 {
103 struct mbed_cmac_ctx *c = to_cmac_ctx(ctx);
104
105 mbedtls_cipher_free(&c->cipher_ctx);
106 free(c);
107 }
108
mbed_cmac_copy_state(struct crypto_mac_ctx * dst_ctx,struct crypto_mac_ctx * src_ctx)109 static void mbed_cmac_copy_state(struct crypto_mac_ctx *dst_ctx,
110 struct crypto_mac_ctx *src_ctx)
111 {
112 struct mbed_cmac_ctx *src = to_cmac_ctx(src_ctx);
113 struct mbed_cmac_ctx *dst = to_cmac_ctx(dst_ctx);
114
115 if (mbedtls_cipher_clone(&dst->cipher_ctx, &src->cipher_ctx))
116 panic();
117 }
118
119 static const struct crypto_mac_ops mbed_cmac_ops = {
120 .init = mbed_cmac_init,
121 .update = mbed_cmac_update,
122 .final = mbed_cmac_final,
123 .free_ctx = mbed_cmac_free_ctx,
124 .copy_state = mbed_cmac_copy_state,
125 };
126
crypto_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret,const mbedtls_cipher_id_t cipher_id,int key_bitlen)127 static TEE_Result crypto_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret,
128 const mbedtls_cipher_id_t cipher_id,
129 int key_bitlen)
130 {
131 int mbed_res = 0;
132 struct mbed_cmac_ctx *c = NULL;
133 const mbedtls_cipher_info_t *cipher_info = NULL;
134
135 /*
136 * Use a default key length for getting 'cipher_info' to do the
137 * setup. The 'cipher_info' will need to be re-assigned with final
138 * key length obtained in mbed_cmac_init() above.
139 *
140 * This is safe since 'mbedtls_cipher_base_t' (used for cipher
141 * context) uses the same fixed allocation all key lengths.
142 */
143 cipher_info = mbedtls_cipher_info_from_values(cipher_id, key_bitlen,
144 MBEDTLS_MODE_ECB);
145 if (!cipher_info)
146 return TEE_ERROR_NOT_SUPPORTED;
147
148 c = calloc(1, sizeof(*c));
149 if (!c)
150 return TEE_ERROR_OUT_OF_MEMORY;
151
152 c->cipher_id = cipher_id;
153 c->mac_ctx.ops = &mbed_cmac_ops;
154
155 mbedtls_cipher_init(&c->cipher_ctx);
156 mbed_res = mbedtls_cipher_setup(&c->cipher_ctx, cipher_info);
157 if (mbed_res) {
158 free(c);
159 if (mbed_res == MBEDTLS_ERR_CIPHER_ALLOC_FAILED)
160 return TEE_ERROR_OUT_OF_MEMORY;
161 return TEE_ERROR_NOT_SUPPORTED;
162 }
163 mbed_res = mbedtls_cipher_cmac_setup(&c->cipher_ctx);
164 if (mbed_res) {
165 free(c);
166 return TEE_ERROR_NOT_SUPPORTED;
167 }
168
169 *ctx_ret = &c->mac_ctx;
170
171 return TEE_SUCCESS;
172 }
173
crypto_des3_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret)174 TEE_Result crypto_des3_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret)
175 {
176 return crypto_cmac_alloc_ctx(ctx_ret, MBEDTLS_CIPHER_ID_3DES, 192);
177 }
178
crypto_aes_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret)179 TEE_Result crypto_aes_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret)
180 {
181 return crypto_cmac_alloc_ctx(ctx_ret, MBEDTLS_CIPHER_ID_AES, 128);
182 }
183