xref: /optee_os/core/crypto/aes-gcm.c (revision b8c186b57350152c3e67500d540920ca40309d5b)
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 
81fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h>
91fca7e26SJens Wiklander #include <io.h>
101fca7e26SJens Wiklander #include <string_ext.h>
111fca7e26SJens Wiklander #include <string.h>
121fca7e26SJens Wiklander #include <tee_api_types.h>
131fca7e26SJens Wiklander #include <types_ext.h>
141fca7e26SJens Wiklander #include <utee_defines.h>
151fca7e26SJens Wiklander #include <util.h>
161fca7e26SJens Wiklander 
17*b8c186b5SJens Wiklander #include "aes-gcm-private.h"
18*b8c186b5SJens Wiklander 
191fca7e26SJens Wiklander static void xor_buf(uint8_t *dst, const uint8_t *src, size_t len)
201fca7e26SJens Wiklander {
211fca7e26SJens Wiklander 	size_t n;
221fca7e26SJens Wiklander 
231fca7e26SJens Wiklander 	for (n = 0; n < len; n++)
241fca7e26SJens Wiklander 		dst[n] ^= src[n];
251fca7e26SJens Wiklander }
261fca7e26SJens Wiklander 
271fca7e26SJens Wiklander 
281fca7e26SJens Wiklander static void ghash_update_pad_zero(struct internal_aes_gcm_ctx *ctx,
291fca7e26SJens Wiklander 				  const uint8_t *data, size_t len)
301fca7e26SJens Wiklander {
311fca7e26SJens Wiklander 	size_t n = len / TEE_AES_BLOCK_SIZE;
321fca7e26SJens Wiklander 	uint64_t block[2];
331fca7e26SJens Wiklander 
341fca7e26SJens Wiklander 	if (n) {
35*b8c186b5SJens Wiklander 		if (internal_aes_gcm_ptr_is_block_aligned(data)) {
361fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, NULL, data, n);
371fca7e26SJens Wiklander 		} else {
381fca7e26SJens Wiklander 			size_t m;
391fca7e26SJens Wiklander 
401fca7e26SJens Wiklander 			for (m = 0; m < n; m++) {
411fca7e26SJens Wiklander 
421fca7e26SJens Wiklander 				memcpy(block, data + m * sizeof(block),
431fca7e26SJens Wiklander 				       sizeof(block));
441fca7e26SJens Wiklander 				internal_aes_gcm_ghash_update(ctx, NULL,
451fca7e26SJens Wiklander 							      (void *)block, 1);
461fca7e26SJens Wiklander 			}
471fca7e26SJens Wiklander 		}
481fca7e26SJens Wiklander 	}
491fca7e26SJens Wiklander 
501fca7e26SJens Wiklander 	if (len - n * TEE_AES_BLOCK_SIZE) {
511fca7e26SJens Wiklander 		memset(block, 0, sizeof(block));
521fca7e26SJens Wiklander 		memcpy(block, data + n * TEE_AES_BLOCK_SIZE,
531fca7e26SJens Wiklander 		       len - n * TEE_AES_BLOCK_SIZE);
541fca7e26SJens Wiklander 		internal_aes_gcm_ghash_update(ctx, block, NULL, 0);
551fca7e26SJens Wiklander 	}
561fca7e26SJens Wiklander }
571fca7e26SJens Wiklander 
581fca7e26SJens Wiklander static void ghash_update_lengths(struct internal_aes_gcm_ctx *ctx, uint32_t l1,
591fca7e26SJens Wiklander 				 uint32_t l2)
601fca7e26SJens Wiklander {
611fca7e26SJens Wiklander 	uint64_t len_fields[2] = {
621fca7e26SJens Wiklander 		TEE_U64_TO_BIG_ENDIAN(l1 * 8),
631fca7e26SJens Wiklander 		TEE_U64_TO_BIG_ENDIAN(l2 * 8)
641fca7e26SJens Wiklander 	};
651fca7e26SJens Wiklander 
661fca7e26SJens Wiklander 	COMPILE_TIME_ASSERT(sizeof(len_fields) == TEE_AES_BLOCK_SIZE);
671fca7e26SJens Wiklander 	internal_aes_gcm_ghash_update(ctx, (uint8_t *)len_fields, NULL, 0);
681fca7e26SJens Wiklander }
691fca7e26SJens Wiklander 
701fca7e26SJens Wiklander TEE_Result internal_aes_gcm_init(struct internal_aes_gcm_ctx *ctx,
711fca7e26SJens Wiklander 				 TEE_OperationMode mode, const void *key,
721fca7e26SJens Wiklander 				 size_t key_len, const void *nonce,
731fca7e26SJens Wiklander 				 size_t nonce_len, size_t tag_len)
741fca7e26SJens Wiklander {
751fca7e26SJens Wiklander 	TEE_Result res;
761fca7e26SJens Wiklander 
771fca7e26SJens Wiklander 	COMPILE_TIME_ASSERT(sizeof(ctx->ctr) == TEE_AES_BLOCK_SIZE);
781fca7e26SJens Wiklander 
791fca7e26SJens Wiklander 	if (tag_len > sizeof(ctx->buf_tag))
801fca7e26SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
811fca7e26SJens Wiklander 
821fca7e26SJens Wiklander 	memset(ctx, 0, sizeof(*ctx));
831fca7e26SJens Wiklander 
841fca7e26SJens Wiklander 	ctx->tag_len = tag_len;
851fca7e26SJens Wiklander 	res = internal_aes_gcm_set_key(ctx, key, key_len);
861fca7e26SJens Wiklander 	if (res)
871fca7e26SJens Wiklander 		return res;
881fca7e26SJens Wiklander 
891fca7e26SJens Wiklander 	if (nonce_len == (96 / 8)) {
901fca7e26SJens Wiklander 		memcpy(ctx->ctr, nonce, nonce_len);
911fca7e26SJens Wiklander 		internal_aes_gcm_inc_ctr(ctx);
921fca7e26SJens Wiklander 	} else {
931fca7e26SJens Wiklander 		ghash_update_pad_zero(ctx, nonce, nonce_len);
941fca7e26SJens Wiklander 		ghash_update_lengths(ctx, 0, nonce_len);
951fca7e26SJens Wiklander 
961fca7e26SJens Wiklander 		memcpy(ctx->ctr, ctx->hash_state, sizeof(ctx->ctr));
971fca7e26SJens Wiklander 		memset(ctx->hash_state, 0, sizeof(ctx->hash_state));
981fca7e26SJens Wiklander 	}
991fca7e26SJens Wiklander 
1001fca7e26SJens Wiklander 	internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->buf_tag);
1011fca7e26SJens Wiklander 	internal_aes_gcm_inc_ctr(ctx);
1021fca7e26SJens Wiklander 	if (mode == TEE_MODE_ENCRYPT) {
1031fca7e26SJens Wiklander 		/*
1041fca7e26SJens Wiklander 		 * Encryption uses the pre-encrypted xor-buffer to encrypt
1051fca7e26SJens Wiklander 		 * while decryption encrypts the xor-buffer when needed
1061fca7e26SJens Wiklander 		 * instead.
1071fca7e26SJens Wiklander 		 *
1081fca7e26SJens Wiklander 		 * The reason for this is that the combined encryption and
1091fca7e26SJens Wiklander 		 * ghash implementation does both operations intertwined.
1101fca7e26SJens Wiklander 		 * In the decrypt case the xor-buffer is needed at the end
1111fca7e26SJens Wiklander 		 * of processing each block, while the encryption case
1121fca7e26SJens Wiklander 		 * needs xor-buffer before processing each block.
1131fca7e26SJens Wiklander 		 *
1141fca7e26SJens Wiklander 		 * In a pure software implementation we wouldn't have any
1151fca7e26SJens Wiklander 		 * use for this kind of optimization, but since this
1161fca7e26SJens Wiklander 		 * AES-GCM implementation is aimed at being combined with
1171fca7e26SJens Wiklander 		 * accelerated routines it's more convenient to always have
1181fca7e26SJens Wiklander 		 * this optimization activated.
1191fca7e26SJens Wiklander 		 */
1201fca7e26SJens Wiklander 		internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->buf_cryp);
1211fca7e26SJens Wiklander 		internal_aes_gcm_inc_ctr(ctx);
1221fca7e26SJens Wiklander 	}
1231fca7e26SJens Wiklander 
1241fca7e26SJens Wiklander 	return TEE_SUCCESS;
1251fca7e26SJens Wiklander }
1261fca7e26SJens Wiklander 
1271fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_aad(struct internal_aes_gcm_ctx *ctx,
1281fca7e26SJens Wiklander 				       const void *data, size_t len)
1291fca7e26SJens Wiklander {
1301fca7e26SJens Wiklander 	const uint8_t *d = data;
1311fca7e26SJens Wiklander 	size_t l = len;
1321fca7e26SJens Wiklander 	const uint8_t *head = NULL;
1331fca7e26SJens Wiklander 	size_t n;
1341fca7e26SJens Wiklander 
1351fca7e26SJens Wiklander 	if (ctx->payload_bytes)
1361fca7e26SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
1371fca7e26SJens Wiklander 
1381fca7e26SJens Wiklander 	ctx->aad_bytes += len;
1391fca7e26SJens Wiklander 
1401fca7e26SJens Wiklander 	while (l) {
141*b8c186b5SJens Wiklander 		if (ctx->buf_pos || !internal_aes_gcm_ptr_is_block_aligned(d) ||
1421fca7e26SJens Wiklander 		    l < TEE_AES_BLOCK_SIZE) {
1431fca7e26SJens Wiklander 			n = MIN(TEE_AES_BLOCK_SIZE - ctx->buf_pos, l);
1441fca7e26SJens Wiklander 			memcpy(ctx->buf_hash + ctx->buf_pos, d, n);
1451fca7e26SJens Wiklander 			ctx->buf_pos += n;
1461fca7e26SJens Wiklander 
1471fca7e26SJens Wiklander 			if (ctx->buf_pos != TEE_AES_BLOCK_SIZE)
1481fca7e26SJens Wiklander 				return TEE_SUCCESS;
1491fca7e26SJens Wiklander 
1501fca7e26SJens Wiklander 			ctx->buf_pos = 0;
1511fca7e26SJens Wiklander 			head = ctx->buf_hash;
1521fca7e26SJens Wiklander 			d += n;
1531fca7e26SJens Wiklander 			l -= n;
1541fca7e26SJens Wiklander 		}
1551fca7e26SJens Wiklander 
156*b8c186b5SJens Wiklander 		if (internal_aes_gcm_ptr_is_block_aligned(d))
1571fca7e26SJens Wiklander 			n = l / TEE_AES_BLOCK_SIZE;
1581fca7e26SJens Wiklander 		else
1591fca7e26SJens Wiklander 			n = 0;
1601fca7e26SJens Wiklander 
1611fca7e26SJens Wiklander 		internal_aes_gcm_ghash_update(ctx, head, d, n);
1621fca7e26SJens Wiklander 		l -= n * TEE_AES_BLOCK_SIZE;
1631fca7e26SJens Wiklander 		d += n * TEE_AES_BLOCK_SIZE;
1641fca7e26SJens Wiklander 	}
1651fca7e26SJens Wiklander 
1661fca7e26SJens Wiklander 	return TEE_SUCCESS;
1671fca7e26SJens Wiklander }
1681fca7e26SJens Wiklander 
1691fca7e26SJens Wiklander TEE_Result internal_aes_gcm_update_payload(struct internal_aes_gcm_ctx *ctx,
1701fca7e26SJens Wiklander 					   TEE_OperationMode mode,
1711fca7e26SJens Wiklander 					   const void *src, size_t len,
1721fca7e26SJens Wiklander 					   void *dst)
1731fca7e26SJens Wiklander {
1741fca7e26SJens Wiklander 	size_t n;
1751fca7e26SJens Wiklander 	const uint8_t *s = src;
1761fca7e26SJens Wiklander 	uint8_t *d = dst;
1771fca7e26SJens Wiklander 	size_t l = len;
1781fca7e26SJens Wiklander 
1791fca7e26SJens Wiklander 	if (!ctx->payload_bytes && ctx->buf_pos) {
1801fca7e26SJens Wiklander 		/* AAD part done, finish up the last bits. */
1811fca7e26SJens Wiklander 		memset(ctx->buf_hash + ctx->buf_pos, 0,
1821fca7e26SJens Wiklander 		       TEE_AES_BLOCK_SIZE - ctx->buf_pos);
1831fca7e26SJens Wiklander 		internal_aes_gcm_ghash_update(ctx, ctx->buf_hash, NULL, 0);
1841fca7e26SJens Wiklander 		ctx->buf_pos = 0;
1851fca7e26SJens Wiklander 	}
1861fca7e26SJens Wiklander 
1871fca7e26SJens Wiklander 	ctx->payload_bytes += len;
1881fca7e26SJens Wiklander 
1891fca7e26SJens Wiklander 	while (l) {
190*b8c186b5SJens Wiklander 		if (ctx->buf_pos || !internal_aes_gcm_ptr_is_block_aligned(s) ||
191*b8c186b5SJens Wiklander 		    !internal_aes_gcm_ptr_is_block_aligned(d) ||
192*b8c186b5SJens Wiklander 		    l < TEE_AES_BLOCK_SIZE) {
1931fca7e26SJens Wiklander 			n = MIN(TEE_AES_BLOCK_SIZE - ctx->buf_pos, l);
1941fca7e26SJens Wiklander 
1951fca7e26SJens Wiklander 			if (!ctx->buf_pos && mode == TEE_MODE_DECRYPT) {
1961fca7e26SJens Wiklander 				internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
1971fca7e26SJens Wiklander 							       ctx->buf_cryp);
1981fca7e26SJens Wiklander 			}
1991fca7e26SJens Wiklander 
2001fca7e26SJens Wiklander 			xor_buf(ctx->buf_cryp + ctx->buf_pos, s, n);
2011fca7e26SJens Wiklander 			memcpy(d, ctx->buf_cryp + ctx->buf_pos, n);
2021fca7e26SJens Wiklander 			if (mode == TEE_MODE_ENCRYPT)
2031fca7e26SJens Wiklander 				memcpy(ctx->buf_hash + ctx->buf_pos,
2041fca7e26SJens Wiklander 				       ctx->buf_cryp + ctx->buf_pos, n);
2051fca7e26SJens Wiklander 			else
2061fca7e26SJens Wiklander 				memcpy(ctx->buf_hash + ctx->buf_pos, s, n);
2071fca7e26SJens Wiklander 
2081fca7e26SJens Wiklander 			ctx->buf_pos += n;
2091fca7e26SJens Wiklander 
2101fca7e26SJens Wiklander 			if (ctx->buf_pos != TEE_AES_BLOCK_SIZE)
2111fca7e26SJens Wiklander 				return TEE_SUCCESS;
2121fca7e26SJens Wiklander 
2131fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, ctx->buf_hash,
2141fca7e26SJens Wiklander 						      NULL, 0);
2151fca7e26SJens Wiklander 			ctx->buf_pos = 0;
2161fca7e26SJens Wiklander 			d += n;
2171fca7e26SJens Wiklander 			s += n;
2181fca7e26SJens Wiklander 			l -= n;
2191fca7e26SJens Wiklander 
2201fca7e26SJens Wiklander 			if (mode == TEE_MODE_ENCRYPT)
2211fca7e26SJens Wiklander 				internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
2221fca7e26SJens Wiklander 							       ctx->buf_cryp);
2231fca7e26SJens Wiklander 			internal_aes_gcm_inc_ctr(ctx);
2241fca7e26SJens Wiklander 		} else {
2251fca7e26SJens Wiklander 			n = l / TEE_AES_BLOCK_SIZE;
2261fca7e26SJens Wiklander 			internal_aes_gcm_update_payload_block_aligned(ctx, mode,
2271fca7e26SJens Wiklander 								      s, n, d);
2281fca7e26SJens Wiklander 			s += n * TEE_AES_BLOCK_SIZE;
2291fca7e26SJens Wiklander 			d += n * TEE_AES_BLOCK_SIZE;
2301fca7e26SJens Wiklander 			l -= n * TEE_AES_BLOCK_SIZE;
2311fca7e26SJens Wiklander 		}
2321fca7e26SJens Wiklander 	}
2331fca7e26SJens Wiklander 
2341fca7e26SJens Wiklander 	return TEE_SUCCESS;
2351fca7e26SJens Wiklander }
2361fca7e26SJens Wiklander 
2371fca7e26SJens Wiklander static TEE_Result operation_final(struct internal_aes_gcm_ctx *ctx,
2381fca7e26SJens Wiklander 				  TEE_OperationMode m, const uint8_t *src,
2391fca7e26SJens Wiklander 				  size_t len, uint8_t *dst)
2401fca7e26SJens Wiklander {
2411fca7e26SJens Wiklander 	TEE_Result res;
2421fca7e26SJens Wiklander 
2431fca7e26SJens Wiklander 	res = internal_aes_gcm_update_payload(ctx, m, src, len, dst);
2441fca7e26SJens Wiklander 	if (res)
2451fca7e26SJens Wiklander 		return res;
2461fca7e26SJens Wiklander 
2471fca7e26SJens Wiklander 	if (ctx->buf_pos) {
2481fca7e26SJens Wiklander 		memset(ctx->buf_hash + ctx->buf_pos, 0,
2491fca7e26SJens Wiklander 		       sizeof(ctx->buf_hash) - ctx->buf_pos);
2501fca7e26SJens Wiklander 		internal_aes_gcm_ghash_update(ctx, ctx->buf_hash, NULL, 0);
2511fca7e26SJens Wiklander 	}
2521fca7e26SJens Wiklander 
2531fca7e26SJens Wiklander 	ghash_update_lengths(ctx, ctx->aad_bytes, ctx->payload_bytes);
2541fca7e26SJens Wiklander 	/* buf_tag was filled in with the first counter block aes_gcm_init() */
2551fca7e26SJens Wiklander 	xor_buf(ctx->buf_tag, ctx->hash_state, ctx->tag_len);
2561fca7e26SJens Wiklander 
2571fca7e26SJens Wiklander 	return TEE_SUCCESS;
2581fca7e26SJens Wiklander }
2591fca7e26SJens Wiklander 
2601fca7e26SJens Wiklander TEE_Result internal_aes_gcm_enc_final(struct internal_aes_gcm_ctx *ctx,
2611fca7e26SJens Wiklander 				      const void *src, size_t len, void *dst,
2621fca7e26SJens Wiklander 				      void *tag, size_t *tag_len)
2631fca7e26SJens Wiklander {
2641fca7e26SJens Wiklander 	TEE_Result res;
2651fca7e26SJens Wiklander 
2661fca7e26SJens Wiklander 	if (*tag_len < ctx->tag_len)
2671fca7e26SJens Wiklander 		return TEE_ERROR_SHORT_BUFFER;
2681fca7e26SJens Wiklander 
2691fca7e26SJens Wiklander 	res = operation_final(ctx, TEE_MODE_ENCRYPT, src, len, dst);
2701fca7e26SJens Wiklander 	if (res)
2711fca7e26SJens Wiklander 		return res;
2721fca7e26SJens Wiklander 
2731fca7e26SJens Wiklander 	memcpy(tag, ctx->buf_tag, ctx->tag_len);
2741fca7e26SJens Wiklander 	*tag_len = ctx->tag_len;
2751fca7e26SJens Wiklander 
2761fca7e26SJens Wiklander 	return TEE_SUCCESS;
2771fca7e26SJens Wiklander }
2781fca7e26SJens Wiklander 
2791fca7e26SJens Wiklander TEE_Result internal_aes_gcm_dec_final(struct internal_aes_gcm_ctx *ctx,
2801fca7e26SJens Wiklander 				      const void *src, size_t len, void *dst,
2811fca7e26SJens Wiklander 				      const void *tag, size_t tag_len)
2821fca7e26SJens Wiklander {
2831fca7e26SJens Wiklander 	TEE_Result res;
2841fca7e26SJens Wiklander 
2851fca7e26SJens Wiklander 	if (tag_len != ctx->tag_len)
2861fca7e26SJens Wiklander 		return TEE_ERROR_MAC_INVALID;
2871fca7e26SJens Wiklander 
2881fca7e26SJens Wiklander 	res = operation_final(ctx, TEE_MODE_DECRYPT, src, len, dst);
2891fca7e26SJens Wiklander 	if (res)
2901fca7e26SJens Wiklander 		return res;
2911fca7e26SJens Wiklander 
2921fca7e26SJens Wiklander 	if (buf_compare_ct(ctx->buf_tag, tag, tag_len))
2931fca7e26SJens Wiklander 		return TEE_ERROR_MAC_INVALID;
2941fca7e26SJens Wiklander 
2951fca7e26SJens Wiklander 	return TEE_SUCCESS;
2961fca7e26SJens Wiklander }
2971fca7e26SJens Wiklander 
2981fca7e26SJens Wiklander void internal_aes_gcm_inc_ctr(struct internal_aes_gcm_ctx *ctx)
2991fca7e26SJens Wiklander {
3001fca7e26SJens Wiklander 	uint64_t c;
3011fca7e26SJens Wiklander 
3021fca7e26SJens Wiklander 	c = TEE_U64_FROM_BIG_ENDIAN(ctx->ctr[1]) + 1;
3031fca7e26SJens Wiklander 	ctx->ctr[1] = TEE_U64_TO_BIG_ENDIAN(c);
3041fca7e26SJens Wiklander 	if (!c) {
3051fca7e26SJens Wiklander 		c = TEE_U64_FROM_BIG_ENDIAN(ctx->ctr[0]) + 1;
3061fca7e26SJens Wiklander 		ctx->ctr[0] = TEE_U64_TO_BIG_ENDIAN(c);
3071fca7e26SJens Wiklander 	}
3081fca7e26SJens Wiklander }
3091fca7e26SJens Wiklander 
3101fca7e26SJens Wiklander #ifndef CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB
3111fca7e26SJens Wiklander #include <crypto/aes-gcm.h>
3121fca7e26SJens Wiklander 
3131fca7e26SJens Wiklander size_t crypto_aes_gcm_get_ctx_size(void)
3141fca7e26SJens Wiklander {
3151fca7e26SJens Wiklander 	return sizeof(struct internal_aes_gcm_ctx);
3161fca7e26SJens Wiklander }
3171fca7e26SJens Wiklander 
3181fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_init(void *c, TEE_OperationMode mode,
3191fca7e26SJens Wiklander 			       const uint8_t *key, size_t key_len,
3201fca7e26SJens Wiklander 			       const uint8_t *nonce, size_t nonce_len,
3211fca7e26SJens Wiklander 			       size_t tag_len)
3221fca7e26SJens Wiklander {
3231fca7e26SJens Wiklander 	return internal_aes_gcm_init(c, mode, key, key_len, nonce, nonce_len,
3241fca7e26SJens Wiklander 				     tag_len);
3251fca7e26SJens Wiklander }
3261fca7e26SJens Wiklander 
3271fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_update_aad(void *c, const uint8_t *data, size_t len)
3281fca7e26SJens Wiklander {
3291fca7e26SJens Wiklander 	return internal_aes_gcm_update_aad(c, data, len);
3301fca7e26SJens Wiklander }
3311fca7e26SJens Wiklander 
3321fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_update_payload(void *c, TEE_OperationMode m,
3331fca7e26SJens Wiklander 					 const uint8_t *src, size_t len,
3341fca7e26SJens Wiklander 					 uint8_t *dst)
3351fca7e26SJens Wiklander {
3361fca7e26SJens Wiklander 	return internal_aes_gcm_update_payload(c, m, src, len, dst);
3371fca7e26SJens Wiklander }
3381fca7e26SJens Wiklander 
3391fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_enc_final(void *c, const uint8_t *src, size_t len,
3401fca7e26SJens Wiklander 				    uint8_t *dst, uint8_t *tag, size_t *tag_len)
3411fca7e26SJens Wiklander {
3421fca7e26SJens Wiklander 	return internal_aes_gcm_enc_final(c, src, len, dst, tag, tag_len);
3431fca7e26SJens Wiklander }
3441fca7e26SJens Wiklander 
3451fca7e26SJens Wiklander TEE_Result crypto_aes_gcm_dec_final(void *c, const uint8_t *src, size_t len,
3461fca7e26SJens Wiklander 				    uint8_t *dst, const uint8_t *tag,
3471fca7e26SJens Wiklander 				    size_t tag_len)
3481fca7e26SJens Wiklander {
3491fca7e26SJens Wiklander 	return internal_aes_gcm_dec_final(c, src, len, dst, tag, tag_len);
3501fca7e26SJens Wiklander }
3511fca7e26SJens Wiklander 
3521fca7e26SJens Wiklander void crypto_aes_gcm_final(void *c __unused)
3531fca7e26SJens Wiklander {
3541fca7e26SJens Wiklander }
3551fca7e26SJens Wiklander #endif /*!CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB*/
356