1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
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 <tee_api_types.h>
12 #include <tomcrypt_private.h>
13 #include <util.h>
14 
15 #define TEE_CCM_KEY_MAX_LENGTH		32
16 #define TEE_CCM_NONCE_MAX_LENGTH	13
17 #define TEE_CCM_TAG_MAX_LENGTH		16
18 
19 struct tee_ccm_state {
20 	struct crypto_authenc_ctx aectx;
21 	ccm_state ctx;			/* the ccm state as defined by LTC */
22 	size_t tag_len;			/* tag length */
23 };
24 
25 static const struct crypto_authenc_ops aes_ccm_ops;
26 
crypto_aes_ccm_alloc_ctx(struct crypto_authenc_ctx ** ctx_ret)27 TEE_Result crypto_aes_ccm_alloc_ctx(struct crypto_authenc_ctx **ctx_ret)
28 {
29 	struct tee_ccm_state *ctx = calloc(1, sizeof(*ctx));
30 
31 	if (!ctx)
32 		return TEE_ERROR_OUT_OF_MEMORY;
33 	ctx->aectx.ops = &aes_ccm_ops;
34 
35 	*ctx_ret = &ctx->aectx;
36 	return TEE_SUCCESS;
37 }
38 
to_tee_ccm_state(struct crypto_authenc_ctx * aectx)39 static struct tee_ccm_state *to_tee_ccm_state(struct crypto_authenc_ctx *aectx)
40 {
41 	assert(aectx && aectx->ops == &aes_ccm_ops);
42 
43 	return container_of(aectx, struct tee_ccm_state, aectx);
44 }
45 
crypto_aes_ccm_free_ctx(struct crypto_authenc_ctx * aectx)46 static void crypto_aes_ccm_free_ctx(struct crypto_authenc_ctx *aectx)
47 {
48 	free(to_tee_ccm_state(aectx));
49 }
50 
crypto_aes_ccm_copy_state(struct crypto_authenc_ctx * dst_aectx,struct crypto_authenc_ctx * src_aectx)51 static void crypto_aes_ccm_copy_state(struct crypto_authenc_ctx *dst_aectx,
52 				      struct crypto_authenc_ctx *src_aectx)
53 {
54 	struct tee_ccm_state *dst_ctx = to_tee_ccm_state(dst_aectx);
55 	struct tee_ccm_state *src_ctx = to_tee_ccm_state(src_aectx);
56 
57 	dst_ctx->ctx = src_ctx->ctx;
58 	dst_ctx->tag_len = src_ctx->tag_len;
59 }
60 
crypto_aes_ccm_init(struct crypto_authenc_ctx * aectx,TEE_OperationMode mode __unused,const uint8_t * key,size_t key_len,const uint8_t * nonce,size_t nonce_len,size_t tag_len,size_t aad_len,size_t payload_len)61 static TEE_Result crypto_aes_ccm_init(struct crypto_authenc_ctx *aectx,
62 				      TEE_OperationMode mode __unused,
63 				      const uint8_t *key, size_t key_len,
64 				      const uint8_t *nonce, size_t nonce_len,
65 				      size_t tag_len, size_t aad_len,
66 				      size_t payload_len)
67 {
68 	int ltc_res = 0;
69 	int ltc_cipherindex = find_cipher("aes");
70 	struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
71 
72 	if (ltc_cipherindex < 0)
73 		return TEE_ERROR_NOT_SUPPORTED;
74 
75 	/* reset the state */
76 	memset(&ccm->ctx, 0, sizeof(ccm->ctx));
77 	ccm->tag_len = tag_len;
78 
79 	/* Check the key length */
80 	if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH))
81 		return TEE_ERROR_BAD_PARAMETERS;
82 
83 	/* check the nonce */
84 	if (nonce_len > TEE_CCM_NONCE_MAX_LENGTH)
85 		return TEE_ERROR_BAD_PARAMETERS;
86 
87 	/* check the tag len */
88 	if ((tag_len < 4) || (tag_len > TEE_CCM_TAG_MAX_LENGTH) ||
89 	    (tag_len % 2 != 0))
90 		return TEE_ERROR_NOT_SUPPORTED;
91 
92 	ltc_res = ccm_init(&ccm->ctx, ltc_cipherindex, key, key_len,
93 			   payload_len, tag_len, aad_len);
94 	if (ltc_res != CRYPT_OK)
95 		return TEE_ERROR_BAD_STATE;
96 
97 	/* Add the IV */
98 	ltc_res = ccm_add_nonce(&ccm->ctx, nonce, nonce_len);
99 	if (ltc_res != CRYPT_OK)
100 		return TEE_ERROR_BAD_STATE;
101 
102 	return TEE_SUCCESS;
103 }
104 
crypto_aes_ccm_update_aad(struct crypto_authenc_ctx * aectx,const uint8_t * data,size_t len)105 static TEE_Result crypto_aes_ccm_update_aad(struct crypto_authenc_ctx *aectx,
106 					    const uint8_t *data, size_t len)
107 {
108 	struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
109 	int ltc_res = 0;
110 
111 	/* Add the AAD (note: aad can be NULL if aadlen == 0) */
112 	ltc_res = ccm_add_aad(&ccm->ctx, data, len);
113 	if (ltc_res != CRYPT_OK)
114 		return TEE_ERROR_BAD_STATE;
115 
116 	return TEE_SUCCESS;
117 }
118 
119 static TEE_Result
crypto_aes_ccm_update_payload(struct crypto_authenc_ctx * aectx,TEE_OperationMode mode,const uint8_t * src_data,size_t len,uint8_t * dst_data)120 crypto_aes_ccm_update_payload(struct crypto_authenc_ctx *aectx,
121 			      TEE_OperationMode mode, const uint8_t *src_data,
122 			      size_t len, uint8_t *dst_data)
123 {
124 	int ltc_res = 0;
125 	int dir = 0;
126 	struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
127 	unsigned char *pt = NULL;
128 	unsigned char *ct = NULL;
129 
130 	if (mode == TEE_MODE_ENCRYPT) {
131 		pt = (unsigned char *)src_data;
132 		ct = dst_data;
133 		dir = CCM_ENCRYPT;
134 	} else {
135 		pt = dst_data;
136 		ct = (unsigned char *)src_data;
137 		dir = CCM_DECRYPT;
138 	}
139 	ltc_res = ccm_process(&ccm->ctx, pt, len, ct, dir);
140 	if (ltc_res != CRYPT_OK)
141 		return TEE_ERROR_BAD_STATE;
142 
143 	return TEE_SUCCESS;
144 }
145 
crypto_aes_ccm_enc_final(struct crypto_authenc_ctx * aectx,const uint8_t * src_data,size_t len,uint8_t * dst_data,uint8_t * dst_tag,size_t * dst_tag_len)146 static TEE_Result crypto_aes_ccm_enc_final(struct crypto_authenc_ctx *aectx,
147 					   const uint8_t *src_data,
148 					   size_t len, uint8_t *dst_data,
149 					   uint8_t *dst_tag,
150 					   size_t *dst_tag_len)
151 {
152 	TEE_Result res = TEE_SUCCESS;
153 	struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
154 	int ltc_res = 0;
155 
156 	/* Finalize the remaining buffer */
157 	res = crypto_aes_ccm_update_payload(aectx, TEE_MODE_ENCRYPT, src_data,
158 					    len, dst_data);
159 	if (res != TEE_SUCCESS)
160 		return res;
161 
162 	/* Check the tag length */
163 	if (*dst_tag_len < ccm->tag_len) {
164 		*dst_tag_len = ccm->tag_len;
165 		return TEE_ERROR_SHORT_BUFFER;
166 	}
167 	*dst_tag_len = ccm->tag_len;
168 
169 	/* Compute the tag */
170 	ltc_res = ccm_done(&ccm->ctx, dst_tag,
171 			   (unsigned long *)dst_tag_len);
172 	if (ltc_res != CRYPT_OK)
173 		return TEE_ERROR_BAD_STATE;
174 
175 	return TEE_SUCCESS;
176 }
177 
crypto_aes_ccm_dec_final(struct crypto_authenc_ctx * aectx,const uint8_t * src_data,size_t len,uint8_t * dst_data,const uint8_t * tag,size_t tag_len)178 static TEE_Result crypto_aes_ccm_dec_final(struct crypto_authenc_ctx *aectx,
179 					   const uint8_t *src_data, size_t len,
180 					   uint8_t *dst_data,
181 					   const uint8_t *tag, size_t tag_len)
182 {
183 	TEE_Result res = TEE_ERROR_BAD_STATE;
184 	struct tee_ccm_state *ccm = to_tee_ccm_state(aectx);
185 	int ltc_res = 0;
186 	uint8_t dst_tag[TEE_CCM_TAG_MAX_LENGTH] = { 0 };
187 	unsigned long ltc_tag_len = tag_len;
188 
189 	if (tag_len == 0)
190 		return TEE_ERROR_SHORT_BUFFER;
191 	if (tag_len > TEE_CCM_TAG_MAX_LENGTH)
192 		return TEE_ERROR_BAD_STATE;
193 
194 	/* Process the last buffer, if any */
195 	res = crypto_aes_ccm_update_payload(aectx, TEE_MODE_DECRYPT, src_data,
196 					    len, dst_data);
197 	if (res != TEE_SUCCESS)
198 		return res;
199 
200 	/* Finalize the authentication */
201 	ltc_res = ccm_done(&ccm->ctx, dst_tag, &ltc_tag_len);
202 	if (ltc_res != CRYPT_OK)
203 		return TEE_ERROR_BAD_STATE;
204 
205 	if (consttime_memcmp(dst_tag, tag, tag_len) != 0)
206 		res = TEE_ERROR_MAC_INVALID;
207 	else
208 		res = TEE_SUCCESS;
209 	return res;
210 }
211 
crypto_aes_ccm_final(struct crypto_authenc_ctx * aectx)212 static void crypto_aes_ccm_final(struct crypto_authenc_ctx *aectx)
213 {
214 	ccm_reset(&to_tee_ccm_state(aectx)->ctx);
215 }
216 
217 static const struct crypto_authenc_ops aes_ccm_ops = {
218 	.init = crypto_aes_ccm_init,
219 	.update_aad = crypto_aes_ccm_update_aad,
220 	.update_payload = crypto_aes_ccm_update_payload,
221 	.enc_final = crypto_aes_ccm_enc_final,
222 	.dec_final = crypto_aes_ccm_dec_final,
223 	.final = crypto_aes_ccm_final,
224 	.free_ctx = crypto_aes_ccm_free_ctx,
225 	.copy_state = crypto_aes_ccm_copy_state,
226 };
227