blob: b651d5e0af9b71d8393a0e3999e891449b16b48c [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2017, Linaro Limited
*/
#include <assert.h>
#include <crypto/crypto.h>
#include <crypto/internal_aes-gcm.h>
#include <string.h>
#include <tee_api_types.h>
#include <types_ext.h>
#include "aes-gcm-private.h"
void __weak internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
const struct internal_aes_gcm_key *ek)
{
#ifdef CFG_AES_GCM_TABLE_BASED
internal_aes_gcm_ghash_gen_tbl(state, ek);
#else
internal_aes_gcm_encrypt_block(ek, state->ctr, state->hash_subkey);
#endif
}
void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
const void *head, const void *data,
size_t num_blocks)
{
size_t n;
if (head)
internal_aes_gcm_ghash_update_block(state, head);
for (n = 0; n < num_blocks; n++)
internal_aes_gcm_ghash_update_block(state, (uint8_t *)data +
n * TEE_AES_BLOCK_SIZE);
}
void __weak
internal_aes_gcm_update_payload_block_aligned(
struct internal_aes_gcm_state *state,
const struct internal_aes_gcm_key *ek,
TEE_OperationMode m, const void *src,
size_t num_blocks, void *dst)
{
size_t n;
const uint8_t *s = src;
uint8_t *d = dst;
void *ctr = state->ctr;
void *buf_cryp = state->buf_cryp;
assert(!state->buf_pos && num_blocks &&
internal_aes_gcm_ptr_is_block_aligned(s) &&
internal_aes_gcm_ptr_is_block_aligned(d));
for (n = 0; n < num_blocks; n++) {
if (m == TEE_MODE_ENCRYPT) {
internal_aes_gcm_xor_block(buf_cryp, s);
internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0);
memcpy(d, buf_cryp, sizeof(state->buf_cryp));
internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
internal_aes_gcm_inc_ctr(state);
} else {
internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
internal_aes_gcm_xor_block(buf_cryp, s);
internal_aes_gcm_ghash_update(state, s, NULL, 0);
memcpy(d, buf_cryp, sizeof(state->buf_cryp));
internal_aes_gcm_inc_ctr(state);
}
s += TEE_AES_BLOCK_SIZE;
d += TEE_AES_BLOCK_SIZE;
}
}
void __weak
internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *ek,
const void *src, void *dst)
{
size_t ek_len = sizeof(ek->data);
crypto_aes_enc_block(ek->data, ek_len, ek->rounds, src, dst);
}
TEE_Result __weak
internal_aes_gcm_expand_enc_key(const void *key, size_t key_len,
struct internal_aes_gcm_key *ek)
{
size_t ek_len = sizeof(ek->data);
return crypto_aes_expand_enc_key(key, key_len, ek->data, ek_len,
&ek->rounds);
}