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