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 8*61b4cd9cSJens Wiklander #include <assert.h> 9*61b4cd9cSJens Wiklander #include <crypto/crypto.h> 101fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h> 111fca7e26SJens Wiklander #include <string.h> 121fca7e26SJens Wiklander #include <tee_api_types.h> 131fca7e26SJens Wiklander #include <types_ext.h> 141fca7e26SJens Wiklander 15b8c186b5SJens Wiklander #include "aes-gcm-private.h" 161fca7e26SJens Wiklander 171fca7e26SJens Wiklander TEE_Result __weak internal_aes_gcm_set_key(struct internal_aes_gcm_ctx *ctx, 181fca7e26SJens Wiklander const void *key, size_t key_len) 191fca7e26SJens Wiklander { 20*61b4cd9cSJens Wiklander TEE_Result res = internal_aes_gcm_expand_enc_key(key, key_len, 21*61b4cd9cSJens Wiklander ctx->enc_key, 22*61b4cd9cSJens Wiklander &ctx->rounds); 23*61b4cd9cSJens Wiklander 24*61b4cd9cSJens Wiklander if (res) 25*61b4cd9cSJens Wiklander return res; 261fca7e26SJens Wiklander 27b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED 28b8c186b5SJens Wiklander internal_aes_gcm_ghash_gen_tbl(ctx); 29b8c186b5SJens Wiklander #else 30b8c186b5SJens Wiklander internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->hash_subkey); 31b8c186b5SJens Wiklander #endif 321fca7e26SJens Wiklander 331fca7e26SJens Wiklander return TEE_SUCCESS; 341fca7e26SJens Wiklander } 351fca7e26SJens Wiklander 36b8c186b5SJens Wiklander void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_ctx *ctx, 37b8c186b5SJens Wiklander const void *head, const void *data, 38b8c186b5SJens Wiklander size_t num_blocks) 39b8c186b5SJens Wiklander { 40b8c186b5SJens Wiklander size_t n; 41b8c186b5SJens Wiklander 42b8c186b5SJens Wiklander if (head) 43b8c186b5SJens Wiklander internal_aes_gcm_ghash_update_block(ctx, head); 44b8c186b5SJens Wiklander 45b8c186b5SJens Wiklander for (n = 0; n < num_blocks; n++) 46b8c186b5SJens Wiklander internal_aes_gcm_ghash_update_block(ctx, (uint8_t *)data + 47b8c186b5SJens Wiklander n * TEE_AES_BLOCK_SIZE); 48b8c186b5SJens Wiklander } 49b8c186b5SJens Wiklander 501fca7e26SJens Wiklander void __weak 511fca7e26SJens Wiklander internal_aes_gcm_update_payload_block_aligned(struct internal_aes_gcm_ctx *ctx, 521fca7e26SJens Wiklander TEE_OperationMode m, 531fca7e26SJens Wiklander const void *src, 541fca7e26SJens Wiklander size_t num_blocks, void *dst) 551fca7e26SJens Wiklander { 561fca7e26SJens Wiklander size_t n; 571fca7e26SJens Wiklander const uint8_t *s = src; 581fca7e26SJens Wiklander uint8_t *d = dst; 591fca7e26SJens Wiklander 601fca7e26SJens Wiklander assert(!ctx->buf_pos && num_blocks && 61b8c186b5SJens Wiklander internal_aes_gcm_ptr_is_block_aligned(s) && 62b8c186b5SJens Wiklander internal_aes_gcm_ptr_is_block_aligned(d)); 631fca7e26SJens Wiklander 641fca7e26SJens Wiklander for (n = 0; n < num_blocks; n++) { 651fca7e26SJens Wiklander if (m == TEE_MODE_ENCRYPT) { 66b8c186b5SJens Wiklander internal_aes_gcm_xor_block(ctx->buf_cryp, s); 671fca7e26SJens Wiklander internal_aes_gcm_ghash_update(ctx, ctx->buf_cryp, 681fca7e26SJens Wiklander NULL, 0); 691fca7e26SJens Wiklander memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp)); 701fca7e26SJens Wiklander internal_aes_gcm_encrypt_block(ctx, ctx->ctr, 711fca7e26SJens Wiklander ctx->buf_cryp); 721fca7e26SJens Wiklander internal_aes_gcm_inc_ctr(ctx); 731fca7e26SJens Wiklander } else { 741fca7e26SJens Wiklander internal_aes_gcm_encrypt_block(ctx, ctx->ctr, 751fca7e26SJens Wiklander ctx->buf_cryp); 761fca7e26SJens Wiklander 77b8c186b5SJens Wiklander internal_aes_gcm_xor_block(ctx->buf_cryp, s); 781fca7e26SJens Wiklander internal_aes_gcm_ghash_update(ctx, s, NULL, 0); 791fca7e26SJens Wiklander memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp)); 801fca7e26SJens Wiklander 811fca7e26SJens Wiklander internal_aes_gcm_inc_ctr(ctx); 821fca7e26SJens Wiklander } 831fca7e26SJens Wiklander s += TEE_AES_BLOCK_SIZE; 841fca7e26SJens Wiklander d += TEE_AES_BLOCK_SIZE; 851fca7e26SJens Wiklander } 861fca7e26SJens Wiklander } 871fca7e26SJens Wiklander 881fca7e26SJens Wiklander void __weak internal_aes_gcm_encrypt_block(struct internal_aes_gcm_ctx *ctx, 891fca7e26SJens Wiklander const void *src, void *dst) 901fca7e26SJens Wiklander { 91*61b4cd9cSJens Wiklander crypto_aes_enc_block(ctx->enc_key, ctx->rounds, src, dst); 92*61b4cd9cSJens Wiklander } 93*61b4cd9cSJens Wiklander 94*61b4cd9cSJens Wiklander TEE_Result __weak internal_aes_gcm_expand_enc_key(const void *key, 95*61b4cd9cSJens Wiklander size_t key_len, 96*61b4cd9cSJens Wiklander uint64_t *enc_key, 97*61b4cd9cSJens Wiklander unsigned int *rounds) 98*61b4cd9cSJens Wiklander { 99*61b4cd9cSJens Wiklander return crypto_aes_expand_enc_key(key, key_len, enc_key, rounds); 1001fca7e26SJens Wiklander } 101