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