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