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_GCM_TAG_MAX_LENGTH		16
16 
17 struct tee_gcm_state {
18 	struct crypto_authenc_ctx aectx;
19 	gcm_state ctx;			/* the gcm state as defined by LTC */
20 	size_t tag_len;			/* tag length */
21 };
22 
23 static const struct crypto_authenc_ops aes_gcm_ops;
24 
to_tee_gcm_state(struct crypto_authenc_ctx * aectx)25 static struct tee_gcm_state *to_tee_gcm_state(struct crypto_authenc_ctx *aectx)
26 {
27 	assert(aectx && aectx->ops == &aes_gcm_ops);
28 
29 	return container_of(aectx, struct tee_gcm_state, aectx);
30 }
31 
crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx ** ctx_ret)32 TEE_Result crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx **ctx_ret)
33 {
34 	struct tee_gcm_state *ctx = calloc(1, sizeof(*ctx));
35 
36 	if (!ctx)
37 		return TEE_ERROR_OUT_OF_MEMORY;
38 	ctx->aectx.ops = &aes_gcm_ops;
39 
40 	*ctx_ret = &ctx->aectx;
41 
42 	return TEE_SUCCESS;
43 }
44 
crypto_aes_gcm_free_ctx(struct crypto_authenc_ctx * aectx)45 static void crypto_aes_gcm_free_ctx(struct crypto_authenc_ctx *aectx)
46 {
47 	free(to_tee_gcm_state(aectx));
48 }
49 
crypto_aes_gcm_copy_state(struct crypto_authenc_ctx * dst_aectx,struct crypto_authenc_ctx * src_aectx)50 static void crypto_aes_gcm_copy_state(struct crypto_authenc_ctx *dst_aectx,
51 				      struct crypto_authenc_ctx *src_aectx)
52 {
53 	struct tee_gcm_state *dst_ctx = to_tee_gcm_state(dst_aectx);
54 	struct tee_gcm_state *src_ctx = to_tee_gcm_state(src_aectx);
55 
56 	dst_ctx->ctx = src_ctx->ctx;
57 	dst_ctx->tag_len = src_ctx->tag_len;
58 }
59 
crypto_aes_gcm_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 __unused,size_t payload_len __unused)60 static TEE_Result crypto_aes_gcm_init(struct crypto_authenc_ctx *aectx,
61 				      TEE_OperationMode mode __unused,
62 				      const uint8_t *key, size_t key_len,
63 				      const uint8_t *nonce, size_t nonce_len,
64 				      size_t tag_len, size_t aad_len __unused,
65 				      size_t payload_len __unused)
66 {
67 	int ltc_res = 0;
68 	int ltc_cipherindex = find_cipher("aes");
69 	struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
70 
71 	if (ltc_cipherindex < 0)
72 		return TEE_ERROR_NOT_SUPPORTED;
73 
74 	/* reset the state */
75 	memset(&gcm->ctx, 0, sizeof(gcm->ctx));
76 	gcm->tag_len = tag_len;
77 
78 	ltc_res = gcm_init(&gcm->ctx, ltc_cipherindex, key, key_len);
79 	if (ltc_res != CRYPT_OK)
80 		return TEE_ERROR_BAD_STATE;
81 
82 	/* Add the IV */
83 	ltc_res = gcm_add_iv(&gcm->ctx, nonce, nonce_len);
84 	if (ltc_res != CRYPT_OK)
85 		return TEE_ERROR_BAD_STATE;
86 
87 	return TEE_SUCCESS;
88 }
89 
crypto_aes_gcm_update_aad(struct crypto_authenc_ctx * aectx,const uint8_t * data,size_t len)90 static TEE_Result crypto_aes_gcm_update_aad(struct crypto_authenc_ctx *aectx,
91 					    const uint8_t *data, size_t len)
92 {
93 	struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
94 	int ltc_res = 0;
95 
96 	/* Add the AAD (note: aad can be NULL if aadlen == 0) */
97 	ltc_res = gcm_add_aad(&gcm->ctx, data, len);
98 	if (ltc_res != CRYPT_OK)
99 		return TEE_ERROR_BAD_STATE;
100 
101 	return TEE_SUCCESS;
102 }
103 
104 static TEE_Result
crypto_aes_gcm_update_payload(struct crypto_authenc_ctx * aectx,TEE_OperationMode mode,const uint8_t * src_data,size_t len,uint8_t * dst_data)105 crypto_aes_gcm_update_payload(struct crypto_authenc_ctx *aectx,
106 			      TEE_OperationMode mode, const uint8_t *src_data,
107 			      size_t len, uint8_t *dst_data)
108 {
109 	TEE_Result res = TEE_SUCCESS;
110 	int ltc_res = 0;
111 	int dir = 0;
112 	struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
113 	unsigned char *pt = NULL;
114 	unsigned char *ct = NULL;
115 
116 	if (mode == TEE_MODE_ENCRYPT) {
117 		pt = (unsigned char *)src_data;
118 		ct = dst_data;
119 		dir = GCM_ENCRYPT;
120 	} else {
121 		pt = dst_data;
122 		ct = (unsigned char *)src_data;
123 		dir = GCM_DECRYPT;
124 	}
125 
126 	/* aad is optional ==> add one without length */
127 	if (gcm->ctx.mode == LTC_GCM_MODE_IV) {
128 		res = crypto_aes_gcm_update_aad(aectx, NULL, 0);
129 		if (res != TEE_SUCCESS)
130 			return res;
131 	}
132 
133 	/* process the data */
134 	ltc_res = gcm_process(&gcm->ctx, pt, len, ct, dir);
135 	if (ltc_res != CRYPT_OK)
136 		return TEE_ERROR_BAD_STATE;
137 
138 	return TEE_SUCCESS;
139 }
140 
crypto_aes_gcm_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)141 static TEE_Result crypto_aes_gcm_enc_final(struct crypto_authenc_ctx *aectx,
142 					   const uint8_t *src_data, size_t len,
143 					   uint8_t *dst_data, uint8_t *dst_tag,
144 					   size_t *dst_tag_len)
145 {
146 	TEE_Result res = TEE_SUCCESS;
147 	struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
148 	int ltc_res = 0;
149 
150 	/* Finalize the remaining buffer */
151 	res = crypto_aes_gcm_update_payload(aectx, TEE_MODE_ENCRYPT, src_data,
152 					    len, dst_data);
153 	if (res != TEE_SUCCESS)
154 		return res;
155 
156 	/* Check the tag length */
157 	if (*dst_tag_len < gcm->tag_len) {
158 		*dst_tag_len = gcm->tag_len;
159 		return TEE_ERROR_SHORT_BUFFER;
160 	}
161 	*dst_tag_len = gcm->tag_len;
162 
163 	/* Compute the tag */
164 	ltc_res = gcm_done(&gcm->ctx, dst_tag, (unsigned long *)dst_tag_len);
165 	if (ltc_res != CRYPT_OK)
166 		return TEE_ERROR_BAD_STATE;
167 
168 	return TEE_SUCCESS;
169 }
170 
crypto_aes_gcm_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)171 static TEE_Result crypto_aes_gcm_dec_final(struct crypto_authenc_ctx *aectx,
172 					   const uint8_t *src_data, size_t len,
173 					   uint8_t *dst_data,
174 					   const uint8_t *tag, size_t tag_len)
175 {
176 	TEE_Result res = TEE_ERROR_BAD_STATE;
177 	struct tee_gcm_state *gcm = to_tee_gcm_state(aectx);
178 	int ltc_res = 0;
179 	uint8_t dst_tag[TEE_GCM_TAG_MAX_LENGTH] = { 0 };
180 	unsigned long ltc_tag_len = tag_len;
181 
182 	if (tag_len == 0)
183 		return TEE_ERROR_SHORT_BUFFER;
184 	if (tag_len > TEE_GCM_TAG_MAX_LENGTH)
185 		return TEE_ERROR_BAD_STATE;
186 
187 	/* Process the last buffer, if any */
188 	res = crypto_aes_gcm_update_payload(aectx, TEE_MODE_DECRYPT, src_data,
189 					    len, dst_data);
190 	if (res != TEE_SUCCESS)
191 		return res;
192 
193 	/* Finalize the authentication */
194 	ltc_res = gcm_done(&gcm->ctx, dst_tag, &ltc_tag_len);
195 	if (ltc_res != CRYPT_OK)
196 		return TEE_ERROR_BAD_STATE;
197 
198 	if (consttime_memcmp(dst_tag, tag, tag_len) != 0)
199 		res = TEE_ERROR_MAC_INVALID;
200 	else
201 		res = TEE_SUCCESS;
202 	return res;
203 }
204 
crypto_aes_gcm_final(struct crypto_authenc_ctx * aectx)205 static void crypto_aes_gcm_final(struct crypto_authenc_ctx *aectx)
206 {
207 	gcm_reset(&to_tee_gcm_state(aectx)->ctx);
208 }
209 
210 static const struct crypto_authenc_ops aes_gcm_ops = {
211 	.init = crypto_aes_gcm_init,
212 	.update_aad = crypto_aes_gcm_update_aad,
213 	.update_payload = crypto_aes_gcm_update_payload,
214 	.enc_final = crypto_aes_gcm_enc_final,
215 	.dec_final = crypto_aes_gcm_dec_final,
216 	.final = crypto_aes_gcm_final,
217 	.free_ctx = crypto_aes_gcm_free_ctx,
218 	.copy_state = crypto_aes_gcm_copy_state,
219 };
220