xref: /optee_os/core/crypto/aes-gcm.c (revision 54af8d679d9af478930edd5a8caef1b778dfe74d)
11fca7e26SJens Wiklander /*
21fca7e26SJens Wiklander  * Copyright (c) 2017, Linaro Limited
31fca7e26SJens Wiklander  * All rights reserved.
41fca7e26SJens Wiklander  *
51fca7e26SJens Wiklander  * SPDX-License-Identifier: BSD-2-Clause
61fca7e26SJens Wiklander  */
71fca7e26SJens Wiklander 
861b4cd9cSJens Wiklander #include <assert.h>
91fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h>
101fca7e26SJens Wiklander #include <io.h>
111fca7e26SJens Wiklander #include <string_ext.h>
121fca7e26SJens Wiklander #include <string.h>
131fca7e26SJens Wiklander #include <tee_api_types.h>
141fca7e26SJens Wiklander #include <types_ext.h>
151fca7e26SJens Wiklander #include <utee_defines.h>
161fca7e26SJens Wiklander #include <util.h>
171fca7e26SJens Wiklander 
18b8c186b5SJens Wiklander #include "aes-gcm-private.h"
19b8c186b5SJens Wiklander 
201fca7e26SJens Wiklander static void xor_buf(uint8_t *dst, const uint8_t *src, size_t len)
211fca7e26SJens Wiklander {
221fca7e26SJens Wiklander 	size_t n;
231fca7e26SJens Wiklander 
241fca7e26SJens Wiklander 	for (n = 0; n < len; n++)
251fca7e26SJens Wiklander 		dst[n] ^= src[n];
261fca7e26SJens Wiklander }
271fca7e26SJens Wiklander 
281fca7e26SJens Wiklander 
29*54af8d67SJens Wiklander static void ghash_update_pad_zero(struct internal_aes_gcm_state *state,
301fca7e26SJens Wiklander 				  const uint8_t *data, size_t len)
311fca7e26SJens Wiklander {
321fca7e26SJens Wiklander 	size_t n = len / TEE_AES_BLOCK_SIZE;
331fca7e26SJens Wiklander 	uint64_t block[2];
341fca7e26SJens Wiklander 
351fca7e26SJens Wiklander 	if (n) {
36b8c186b5SJens Wiklander 		if (internal_aes_gcm_ptr_is_block_aligned(data)) {
37*54af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, NULL, data, n);
381fca7e26SJens Wiklander 		} else {
391fca7e26SJens Wiklander 			size_t m;
401fca7e26SJens Wiklander 
411fca7e26SJens Wiklander 			for (m = 0; m < n; m++) {
421fca7e26SJens Wiklander 
431fca7e26SJens Wiklander 				memcpy(block, data + m * sizeof(block),
441fca7e26SJens Wiklander 				       sizeof(block));
45*54af8d67SJens Wiklander 				internal_aes_gcm_ghash_update(state, NULL,
461fca7e26SJens Wiklander 							      (void *)block, 1);
471fca7e26SJens Wiklander 			}
481fca7e26SJens Wiklander 		}
491fca7e26SJens Wiklander 	}
501fca7e26SJens Wiklander 
511fca7e26SJens Wiklander 	if (len - n * TEE_AES_BLOCK_SIZE) {
521fca7e26SJens Wiklander 		memset(block, 0, sizeof(block));
531fca7e26SJens Wiklander 		memcpy(block, data + n * TEE_AES_BLOCK_SIZE,
541fca7e26SJens Wiklander 		       len - n * TEE_AES_BLOCK_SIZE);
55*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update(state, block, NULL, 0);
561fca7e26SJens Wiklander 	}
571fca7e26SJens Wiklander }
581fca7e26SJens Wiklander 
59*54af8d67SJens Wiklander static void ghash_update_lengths(struct internal_aes_gcm_state *state,
60*54af8d67SJens Wiklander 				 uint32_t l1, uint32_t l2)
611fca7e26SJens Wiklander {
621fca7e26SJens Wiklander 	uint64_t len_fields[2] = {
631fca7e26SJens Wiklander 		TEE_U64_TO_BIG_ENDIAN(l1 * 8),
641fca7e26SJens Wiklander 		TEE_U64_TO_BIG_ENDIAN(l2 * 8)
651fca7e26SJens Wiklander 	};
661fca7e26SJens Wiklander 
671fca7e26SJens Wiklander 	COMPILE_TIME_ASSERT(sizeof(len_fields) == TEE_AES_BLOCK_SIZE);
68*54af8d67SJens Wiklander 	internal_aes_gcm_ghash_update(state, (uint8_t *)len_fields, NULL, 0);
691fca7e26SJens Wiklander }
701fca7e26SJens Wiklander 
71*54af8d67SJens Wiklander static TEE_Result __gcm_init(struct internal_aes_gcm_state *state,
72*54af8d67SJens Wiklander 			     const struct internal_aes_gcm_key *ek,
73*54af8d67SJens Wiklander 			     TEE_OperationMode mode, const void *nonce,
741fca7e26SJens Wiklander 			     size_t nonce_len, size_t tag_len)
751fca7e26SJens Wiklander {
76*54af8d67SJens Wiklander 	COMPILE_TIME_ASSERT(sizeof(state->ctr) == TEE_AES_BLOCK_SIZE);
771fca7e26SJens Wiklander 
78*54af8d67SJens Wiklander 	if (tag_len > sizeof(state->buf_tag))
791fca7e26SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
801fca7e26SJens Wiklander 
81*54af8d67SJens Wiklander 	memset(state, 0, sizeof(*state));
821fca7e26SJens Wiklander 
83*54af8d67SJens Wiklander 	state->tag_len = tag_len;
84*54af8d67SJens Wiklander 	internal_aes_gcm_set_key(state, ek);
851fca7e26SJens Wiklander 
861fca7e26SJens Wiklander 	if (nonce_len == (96 / 8)) {
87*54af8d67SJens Wiklander 		memcpy(state->ctr, nonce, nonce_len);
88*54af8d67SJens Wiklander 		internal_aes_gcm_inc_ctr(state);
891fca7e26SJens Wiklander 	} else {
90*54af8d67SJens Wiklander 		ghash_update_pad_zero(state, nonce, nonce_len);
91*54af8d67SJens Wiklander 		ghash_update_lengths(state, 0, nonce_len);
921fca7e26SJens Wiklander 
93*54af8d67SJens Wiklander 		memcpy(state->ctr, state->hash_state, sizeof(state->ctr));
94*54af8d67SJens Wiklander 		memset(state->hash_state, 0, sizeof(state->hash_state));
951fca7e26SJens Wiklander 	}
961fca7e26SJens Wiklander 
97*54af8d67SJens Wiklander 	internal_aes_gcm_encrypt_block(ek, state->ctr, state->buf_tag);
98*54af8d67SJens Wiklander 	internal_aes_gcm_inc_ctr(state);
991fca7e26SJens Wiklander 	if (mode == TEE_MODE_ENCRYPT) {
1001fca7e26SJens Wiklander 		/*
1011fca7e26SJens Wiklander 		 * Encryption uses the pre-encrypted xor-buffer to encrypt
1021fca7e26SJens Wiklander 		 * while decryption encrypts the xor-buffer when needed
1031fca7e26SJens Wiklander 		 * instead.
1041fca7e26SJens Wiklander 		 *
1051fca7e26SJens Wiklander 		 * The reason for this is that the combined encryption and
1061fca7e26SJens Wiklander 		 * ghash implementation does both operations intertwined.
1071fca7e26SJens Wiklander 		 * In the decrypt case the xor-buffer is needed at the end
1081fca7e26SJens Wiklander 		 * of processing each block, while the encryption case
1091fca7e26SJens Wiklander 		 * needs xor-buffer before processing each block.
1101fca7e26SJens Wiklander 		 *
1111fca7e26SJens Wiklander 		 * In a pure software implementation we wouldn't have any
1121fca7e26SJens Wiklander 		 * use for this kind of optimization, but since this
1131fca7e26SJens Wiklander 		 * AES-GCM implementation is aimed at being combined with
1141fca7e26SJens Wiklander 		 * accelerated routines it's more convenient to always have
1151fca7e26SJens Wiklander 		 * this optimization activated.
1161fca7e26SJens Wiklander 		 */
117*54af8d67SJens Wiklander 		internal_aes_gcm_encrypt_block(ek, state->ctr, state->buf_cryp);
118*54af8d67SJens Wiklander 		internal_aes_gcm_inc_ctr(state);
1191fca7e26SJens Wiklander 	}
1201fca7e26SJens Wiklander 
1211fca7e26SJens Wiklander 	return TEE_SUCCESS;
1221fca7e26SJens Wiklander }
1231fca7e26SJens Wiklander 
124*54af8d67SJens Wiklander TEE_Result internal_aes_gcm_init(struct internal_aes_gcm_ctx *ctx,
125*54af8d67SJens Wiklander 				 TEE_OperationMode mode, const void *key,
126*54af8d67SJens Wiklander 				 size_t key_len, const void *nonce,
127*54af8d67SJens Wiklander 				 size_t nonce_len, size_t tag_len)
128*54af8d67SJens Wiklander {
129*54af8d67SJens Wiklander 	TEE_Result res = internal_aes_gcm_expand_enc_key(key, key_len,
130*54af8d67SJens Wiklander 							 &ctx->key);
131*54af8d67SJens Wiklander 	if (res)
132*54af8d67SJens Wiklander 		return res;
133*54af8d67SJens Wiklander 
134*54af8d67SJens Wiklander 	return __gcm_init(&ctx->state, &ctx->key, mode, nonce, nonce_len,
135*54af8d67SJens Wiklander 			  tag_len);
136*54af8d67SJens Wiklander }
137*54af8d67SJens Wiklander 
1381fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_aad(struct internal_aes_gcm_ctx *ctx,
1391fca7e26SJens Wiklander 				       const void *data, size_t len)
1401fca7e26SJens Wiklander {
141*54af8d67SJens Wiklander 	struct internal_aes_gcm_state *state = &ctx->state;
1421fca7e26SJens Wiklander 	const uint8_t *d = data;
1431fca7e26SJens Wiklander 	size_t l = len;
1441fca7e26SJens Wiklander 	const uint8_t *head = NULL;
1451fca7e26SJens Wiklander 	size_t n;
1461fca7e26SJens Wiklander 
147*54af8d67SJens Wiklander 	if (state->payload_bytes)
1481fca7e26SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
1491fca7e26SJens Wiklander 
150*54af8d67SJens Wiklander 	state->aad_bytes += len;
1511fca7e26SJens Wiklander 
1521fca7e26SJens Wiklander 	while (l) {
153*54af8d67SJens Wiklander 		if (state->buf_pos ||
154*54af8d67SJens Wiklander 		    !internal_aes_gcm_ptr_is_block_aligned(d) ||
1551fca7e26SJens Wiklander 		    l < TEE_AES_BLOCK_SIZE) {
156*54af8d67SJens Wiklander 			n = MIN(TEE_AES_BLOCK_SIZE - state->buf_pos, l);
157*54af8d67SJens Wiklander 			memcpy(state->buf_hash + state->buf_pos, d, n);
158*54af8d67SJens Wiklander 			state->buf_pos += n;
1591fca7e26SJens Wiklander 
160*54af8d67SJens Wiklander 			if (state->buf_pos != TEE_AES_BLOCK_SIZE)
1611fca7e26SJens Wiklander 				return TEE_SUCCESS;
1621fca7e26SJens Wiklander 
163*54af8d67SJens Wiklander 			state->buf_pos = 0;
164*54af8d67SJens Wiklander 			head = state->buf_hash;
1651fca7e26SJens Wiklander 			d += n;
1661fca7e26SJens Wiklander 			l -= n;
1671fca7e26SJens Wiklander 		}
1681fca7e26SJens Wiklander 
169b8c186b5SJens Wiklander 		if (internal_aes_gcm_ptr_is_block_aligned(d))
1701fca7e26SJens Wiklander 			n = l / TEE_AES_BLOCK_SIZE;
1711fca7e26SJens Wiklander 		else
1721fca7e26SJens Wiklander 			n = 0;
1731fca7e26SJens Wiklander 
174*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update(state, head, d, n);
1751fca7e26SJens Wiklander 		l -= n * TEE_AES_BLOCK_SIZE;
1761fca7e26SJens Wiklander 		d += n * TEE_AES_BLOCK_SIZE;
1771fca7e26SJens Wiklander 	}
1781fca7e26SJens Wiklander 
1791fca7e26SJens Wiklander 	return TEE_SUCCESS;
1801fca7e26SJens Wiklander }
1811fca7e26SJens Wiklander 
1821fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_payload(struct internal_aes_gcm_ctx *ctx,
1831fca7e26SJens Wiklander 					   TEE_OperationMode mode,
1841fca7e26SJens Wiklander 					   const void *src, size_t len,
1851fca7e26SJens Wiklander 					   void *dst)
1861fca7e26SJens Wiklander {
187*54af8d67SJens Wiklander 	struct internal_aes_gcm_state *state = &ctx->state;
188*54af8d67SJens Wiklander 	struct internal_aes_gcm_key *ek = &ctx->key;
1891fca7e26SJens Wiklander 	size_t n;
1901fca7e26SJens Wiklander 	const uint8_t *s = src;
1911fca7e26SJens Wiklander 	uint8_t *d = dst;
1921fca7e26SJens Wiklander 	size_t l = len;
1931fca7e26SJens Wiklander 
194*54af8d67SJens Wiklander 	if (!state->payload_bytes && state->buf_pos) {
1951fca7e26SJens Wiklander 		/* AAD part done, finish up the last bits. */
196*54af8d67SJens Wiklander 		memset(state->buf_hash + state->buf_pos, 0,
197*54af8d67SJens Wiklander 		       TEE_AES_BLOCK_SIZE - state->buf_pos);
198*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update(state, state->buf_hash, NULL, 0);
199*54af8d67SJens Wiklander 		state->buf_pos = 0;
2001fca7e26SJens Wiklander 	}
2011fca7e26SJens Wiklander 
202*54af8d67SJens Wiklander 	state->payload_bytes += len;
2031fca7e26SJens Wiklander 
2041fca7e26SJens Wiklander 	while (l) {
205*54af8d67SJens Wiklander 		if (state->buf_pos ||
206*54af8d67SJens Wiklander 		    !internal_aes_gcm_ptr_is_block_aligned(s) ||
207b8c186b5SJens Wiklander 		    !internal_aes_gcm_ptr_is_block_aligned(d) ||
208b8c186b5SJens Wiklander 		    l < TEE_AES_BLOCK_SIZE) {
209*54af8d67SJens Wiklander 			n = MIN(TEE_AES_BLOCK_SIZE - state->buf_pos, l);
2101fca7e26SJens Wiklander 
211*54af8d67SJens Wiklander 			if (!state->buf_pos && mode == TEE_MODE_DECRYPT) {
212*54af8d67SJens Wiklander 				internal_aes_gcm_encrypt_block(ek, state->ctr,
213*54af8d67SJens Wiklander 							       state->buf_cryp);
2141fca7e26SJens Wiklander 			}
2151fca7e26SJens Wiklander 
216*54af8d67SJens Wiklander 			xor_buf(state->buf_cryp + state->buf_pos, s, n);
217*54af8d67SJens Wiklander 			memcpy(d, state->buf_cryp + state->buf_pos, n);
2181fca7e26SJens Wiklander 			if (mode == TEE_MODE_ENCRYPT)
219*54af8d67SJens Wiklander 				memcpy(state->buf_hash + state->buf_pos,
220*54af8d67SJens Wiklander 				       state->buf_cryp + state->buf_pos, n);
2211fca7e26SJens Wiklander 			else
222*54af8d67SJens Wiklander 				memcpy(state->buf_hash + state->buf_pos, s, n);
2231fca7e26SJens Wiklander 
224*54af8d67SJens Wiklander 			state->buf_pos += n;
2251fca7e26SJens Wiklander 
226*54af8d67SJens Wiklander 			if (state->buf_pos != TEE_AES_BLOCK_SIZE)
2271fca7e26SJens Wiklander 				return TEE_SUCCESS;
2281fca7e26SJens Wiklander 
229*54af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, state->buf_hash,
2301fca7e26SJens Wiklander 						      NULL, 0);
231*54af8d67SJens Wiklander 			state->buf_pos = 0;
2321fca7e26SJens Wiklander 			d += n;
2331fca7e26SJens Wiklander 			s += n;
2341fca7e26SJens Wiklander 			l -= n;
2351fca7e26SJens Wiklander 
2361fca7e26SJens Wiklander 			if (mode == TEE_MODE_ENCRYPT)
237*54af8d67SJens Wiklander 				internal_aes_gcm_encrypt_block(ek, state->ctr,
238*54af8d67SJens Wiklander 							       state->buf_cryp);
239*54af8d67SJens Wiklander 			internal_aes_gcm_inc_ctr(state);
2401fca7e26SJens Wiklander 		} else {
2411fca7e26SJens Wiklander 			n = l / TEE_AES_BLOCK_SIZE;
242*54af8d67SJens Wiklander 			internal_aes_gcm_update_payload_block_aligned(state, ek,
243*54af8d67SJens Wiklander 								      mode,
2441fca7e26SJens Wiklander 								      s, n, d);
2451fca7e26SJens Wiklander 			s += n * TEE_AES_BLOCK_SIZE;
2461fca7e26SJens Wiklander 			d += n * TEE_AES_BLOCK_SIZE;
2471fca7e26SJens Wiklander 			l -= n * TEE_AES_BLOCK_SIZE;
2481fca7e26SJens Wiklander 		}
2491fca7e26SJens Wiklander 	}
2501fca7e26SJens Wiklander 
2511fca7e26SJens Wiklander 	return TEE_SUCCESS;
2521fca7e26SJens Wiklander }
2531fca7e26SJens Wiklander 
2541fca7e26SJens Wiklander static TEE_Result operation_final(struct internal_aes_gcm_ctx *ctx,
2551fca7e26SJens Wiklander 				  TEE_OperationMode m, const uint8_t *src,
2561fca7e26SJens Wiklander 				  size_t len, uint8_t *dst)
2571fca7e26SJens Wiklander {
258*54af8d67SJens Wiklander 	struct internal_aes_gcm_state *state = &ctx->state;
2591fca7e26SJens Wiklander 	TEE_Result res;
2601fca7e26SJens Wiklander 
2611fca7e26SJens Wiklander 	res = internal_aes_gcm_update_payload(ctx, m, src, len, dst);
2621fca7e26SJens Wiklander 	if (res)
2631fca7e26SJens Wiklander 		return res;
2641fca7e26SJens Wiklander 
265*54af8d67SJens Wiklander 	if (state->buf_pos) {
266*54af8d67SJens Wiklander 		memset(state->buf_hash + state->buf_pos, 0,
267*54af8d67SJens Wiklander 		       sizeof(state->buf_hash) - state->buf_pos);
268*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update(state, state->buf_hash, NULL, 0);
2691fca7e26SJens Wiklander 	}
2701fca7e26SJens Wiklander 
271*54af8d67SJens Wiklander 	ghash_update_lengths(state, state->aad_bytes, state->payload_bytes);
2721fca7e26SJens Wiklander 	/* buf_tag was filled in with the first counter block aes_gcm_init() */
273*54af8d67SJens Wiklander 	xor_buf(state->buf_tag, state->hash_state, state->tag_len);
2741fca7e26SJens Wiklander 
2751fca7e26SJens Wiklander 	return TEE_SUCCESS;
2761fca7e26SJens Wiklander }
2771fca7e26SJens Wiklander 
2781fca7e26SJens Wiklander TEE_Result internal_aes_gcm_enc_final(struct internal_aes_gcm_ctx *ctx,
2791fca7e26SJens Wiklander 				      const void *src, size_t len, void *dst,
2801fca7e26SJens Wiklander 				      void *tag, size_t *tag_len)
2811fca7e26SJens Wiklander {
282*54af8d67SJens Wiklander 	struct internal_aes_gcm_state *state = &ctx->state;
2831fca7e26SJens Wiklander 	TEE_Result res;
2841fca7e26SJens Wiklander 
285*54af8d67SJens Wiklander 	if (*tag_len < state->tag_len)
2861fca7e26SJens Wiklander 		return TEE_ERROR_SHORT_BUFFER;
2871fca7e26SJens Wiklander 
2881fca7e26SJens Wiklander 	res = operation_final(ctx, TEE_MODE_ENCRYPT, src, len, dst);
2891fca7e26SJens Wiklander 	if (res)
2901fca7e26SJens Wiklander 		return res;
2911fca7e26SJens Wiklander 
292*54af8d67SJens Wiklander 	memcpy(tag, state->buf_tag, state->tag_len);
293*54af8d67SJens Wiklander 	*tag_len = state->tag_len;
2941fca7e26SJens Wiklander 
2951fca7e26SJens Wiklander 	return TEE_SUCCESS;
2961fca7e26SJens Wiklander }
2971fca7e26SJens Wiklander 
2981fca7e26SJens Wiklander TEE_Result internal_aes_gcm_dec_final(struct internal_aes_gcm_ctx *ctx,
2991fca7e26SJens Wiklander 				      const void *src, size_t len, void *dst,
3001fca7e26SJens Wiklander 				      const void *tag, size_t tag_len)
3011fca7e26SJens Wiklander {
302*54af8d67SJens Wiklander 	struct internal_aes_gcm_state *state = &ctx->state;
3031fca7e26SJens Wiklander 	TEE_Result res;
3041fca7e26SJens Wiklander 
305*54af8d67SJens Wiklander 	if (tag_len != state->tag_len)
3061fca7e26SJens Wiklander 		return TEE_ERROR_MAC_INVALID;
3071fca7e26SJens Wiklander 
3081fca7e26SJens Wiklander 	res = operation_final(ctx, TEE_MODE_DECRYPT, src, len, dst);
3091fca7e26SJens Wiklander 	if (res)
3101fca7e26SJens Wiklander 		return res;
3111fca7e26SJens Wiklander 
312*54af8d67SJens Wiklander 	if (buf_compare_ct(state->buf_tag, tag, tag_len))
3131fca7e26SJens Wiklander 		return TEE_ERROR_MAC_INVALID;
3141fca7e26SJens Wiklander 
3151fca7e26SJens Wiklander 	return TEE_SUCCESS;
3161fca7e26SJens Wiklander }
3171fca7e26SJens Wiklander 
318*54af8d67SJens Wiklander void internal_aes_gcm_inc_ctr(struct internal_aes_gcm_state *state)
3191fca7e26SJens Wiklander {
3201fca7e26SJens Wiklander 	uint64_t c;
3211fca7e26SJens Wiklander 
322*54af8d67SJens Wiklander 	c = TEE_U64_FROM_BIG_ENDIAN(state->ctr[1]) + 1;
323*54af8d67SJens Wiklander 	state->ctr[1] = TEE_U64_TO_BIG_ENDIAN(c);
3241fca7e26SJens Wiklander 	if (!c) {
325*54af8d67SJens Wiklander 		c = TEE_U64_FROM_BIG_ENDIAN(state->ctr[0]) + 1;
326*54af8d67SJens Wiklander 		state->ctr[0] = TEE_U64_TO_BIG_ENDIAN(c);
3271fca7e26SJens Wiklander 	}
3281fca7e26SJens Wiklander }
3291fca7e26SJens Wiklander 
3301fca7e26SJens Wiklander #ifndef CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB
3311fca7e26SJens Wiklander #include <crypto/aes-gcm.h>
3321fca7e26SJens Wiklander 
3331fca7e26SJens Wiklander size_t crypto_aes_gcm_get_ctx_size(void)
3341fca7e26SJens Wiklander {
3351fca7e26SJens Wiklander 	return sizeof(struct internal_aes_gcm_ctx);
3361fca7e26SJens Wiklander }
3371fca7e26SJens Wiklander 
3381fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_init(void *c, TEE_OperationMode mode,
3391fca7e26SJens Wiklander 			       const uint8_t *key, size_t key_len,
3401fca7e26SJens Wiklander 			       const uint8_t *nonce, size_t nonce_len,
3411fca7e26SJens Wiklander 			       size_t tag_len)
3421fca7e26SJens Wiklander {
3431fca7e26SJens Wiklander 	return internal_aes_gcm_init(c, mode, key, key_len, nonce, nonce_len,
3441fca7e26SJens Wiklander 				     tag_len);
3451fca7e26SJens Wiklander }
3461fca7e26SJens Wiklander 
3471fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_update_aad(void *c, const uint8_t *data, size_t len)
3481fca7e26SJens Wiklander {
3491fca7e26SJens Wiklander 	return internal_aes_gcm_update_aad(c, data, len);
3501fca7e26SJens Wiklander }
3511fca7e26SJens Wiklander 
3521fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_update_payload(void *c, TEE_OperationMode m,
3531fca7e26SJens Wiklander 					 const uint8_t *src, size_t len,
3541fca7e26SJens Wiklander 					 uint8_t *dst)
3551fca7e26SJens Wiklander {
3561fca7e26SJens Wiklander 	return internal_aes_gcm_update_payload(c, m, src, len, dst);
3571fca7e26SJens Wiklander }
3581fca7e26SJens Wiklander 
3591fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_enc_final(void *c, const uint8_t *src, size_t len,
3601fca7e26SJens Wiklander 				    uint8_t *dst, uint8_t *tag, size_t *tag_len)
3611fca7e26SJens Wiklander {
3621fca7e26SJens Wiklander 	return internal_aes_gcm_enc_final(c, src, len, dst, tag, tag_len);
3631fca7e26SJens Wiklander }
3641fca7e26SJens Wiklander 
3651fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_dec_final(void *c, const uint8_t *src, size_t len,
3661fca7e26SJens Wiklander 				    uint8_t *dst, const uint8_t *tag,
3671fca7e26SJens Wiklander 				    size_t tag_len)
3681fca7e26SJens Wiklander {
3691fca7e26SJens Wiklander 	return internal_aes_gcm_dec_final(c, src, len, dst, tag, tag_len);
3701fca7e26SJens Wiklander }
3711fca7e26SJens Wiklander 
3721fca7e26SJens Wiklander void crypto_aes_gcm_final(void *c __unused)
3731fca7e26SJens Wiklander {
3741fca7e26SJens Wiklander }
3751fca7e26SJens Wiklander #endif /*!CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB*/
376