1fb7ef469SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 21fca7e26SJens Wiklander /* 3b314df1fSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 41fca7e26SJens Wiklander */ 51fca7e26SJens Wiklander 661b4cd9cSJens Wiklander #include <assert.h> 761b4cd9cSJens Wiklander #include <crypto/crypto.h> 81fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h> 91fca7e26SJens Wiklander #include <string.h> 101fca7e26SJens Wiklander #include <tee_api_types.h> 111fca7e26SJens Wiklander #include <types_ext.h> 121fca7e26SJens Wiklander 13b314df1fSJens Wiklander void internal_aes_gcm_set_key(struct internal_aes_gcm_state *state, 1454af8d67SJens Wiklander const struct internal_aes_gcm_key *ek) 151fca7e26SJens Wiklander { 16b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED 17b314df1fSJens Wiklander internal_aes_gcm_ghash_gen_tbl(&state->ghash_key, ek); 18b8c186b5SJens Wiklander #else 194f6d7160SJens Wiklander crypto_aes_enc_block(ek->data, sizeof(ek->data), ek->rounds, 204f6d7160SJens Wiklander state->ctr, state->ghash_key.hash_subkey); 21b8c186b5SJens Wiklander #endif 221fca7e26SJens Wiklander } 231fca7e26SJens Wiklander 24b314df1fSJens Wiklander static void ghash_update_block(struct internal_aes_gcm_state *state, 25b314df1fSJens Wiklander const void *data) 26b314df1fSJens Wiklander { 27b314df1fSJens Wiklander void *y = state->hash_state; 28b314df1fSJens Wiklander 29b314df1fSJens Wiklander internal_aes_gcm_xor_block(y, data); 30b314df1fSJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED 31b314df1fSJens Wiklander internal_aes_gcm_ghash_mult_tbl(&state->ghash_key, y, y); 32b314df1fSJens Wiklander #else 33b314df1fSJens Wiklander internal_aes_gcm_gfmul(state->ghash_key.hash_subkey, y, y); 34b314df1fSJens Wiklander #endif 35b314df1fSJens Wiklander } 36b314df1fSJens Wiklander 37b314df1fSJens Wiklander void internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state, 38b8c186b5SJens Wiklander const void *head, const void *data, 39b8c186b5SJens Wiklander size_t num_blocks) 40b8c186b5SJens Wiklander { 41b314df1fSJens Wiklander size_t n = 0; 42b8c186b5SJens Wiklander 43b8c186b5SJens Wiklander if (head) 44b314df1fSJens Wiklander ghash_update_block(state, head); 45b8c186b5SJens Wiklander 46b8c186b5SJens Wiklander for (n = 0; n < num_blocks; n++) 47b314df1fSJens Wiklander ghash_update_block(state, 48b314df1fSJens Wiklander (uint8_t *)data + n * TEE_AES_BLOCK_SIZE); 49b8c186b5SJens Wiklander } 50*80f47278SJens Wiklander 51*80f47278SJens Wiklander static void encrypt_block(struct internal_aes_gcm_state *state, 52*80f47278SJens Wiklander const struct internal_aes_gcm_key *enc_key, 53*80f47278SJens Wiklander const uint64_t src[2], uint64_t dst[2]) 54*80f47278SJens Wiklander { 55*80f47278SJens Wiklander void *buf_cryp = state->buf_cryp; 56*80f47278SJens Wiklander 57*80f47278SJens Wiklander internal_aes_gcm_xor_block(buf_cryp, src); 58*80f47278SJens Wiklander internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0); 59*80f47278SJens Wiklander memcpy(dst, buf_cryp, sizeof(state->buf_cryp)); 60*80f47278SJens Wiklander 61*80f47278SJens Wiklander crypto_aes_enc_block(enc_key->data, sizeof(enc_key->data), 62*80f47278SJens Wiklander enc_key->rounds, state->ctr, state->buf_cryp); 63*80f47278SJens Wiklander internal_aes_gcm_inc_ctr(state); 64*80f47278SJens Wiklander } 65*80f47278SJens Wiklander 66*80f47278SJens Wiklander static void encrypt_pl(struct internal_aes_gcm_state *state, 67*80f47278SJens Wiklander const struct internal_aes_gcm_key *ek, 68*80f47278SJens Wiklander const uint8_t *src, size_t num_blocks, uint8_t *dst) 69*80f47278SJens Wiklander { 70*80f47278SJens Wiklander size_t n = 0; 71*80f47278SJens Wiklander 72*80f47278SJens Wiklander if (ALIGNMENT_IS_OK(src, uint64_t)) { 73*80f47278SJens Wiklander for (n = 0; n < num_blocks; n++) { 74*80f47278SJens Wiklander const void *s = src + n * TEE_AES_BLOCK_SIZE; 75*80f47278SJens Wiklander void *d = dst + n * TEE_AES_BLOCK_SIZE; 76*80f47278SJens Wiklander 77*80f47278SJens Wiklander encrypt_block(state, ek, s, d); 78*80f47278SJens Wiklander } 79*80f47278SJens Wiklander } else { 80*80f47278SJens Wiklander for (n = 0; n < num_blocks; n++) { 81*80f47278SJens Wiklander uint64_t tmp[2] = { 0 }; 82*80f47278SJens Wiklander void *d = dst + n * TEE_AES_BLOCK_SIZE; 83*80f47278SJens Wiklander 84*80f47278SJens Wiklander memcpy(tmp, src + n * TEE_AES_BLOCK_SIZE, sizeof(tmp)); 85*80f47278SJens Wiklander encrypt_block(state, ek, tmp, d); 86*80f47278SJens Wiklander } 87*80f47278SJens Wiklander } 88*80f47278SJens Wiklander } 89*80f47278SJens Wiklander 90*80f47278SJens Wiklander static void decrypt_block(struct internal_aes_gcm_state *state, 91*80f47278SJens Wiklander const struct internal_aes_gcm_key *enc_key, 92*80f47278SJens Wiklander const uint64_t src[2], uint64_t dst[2]) 93*80f47278SJens Wiklander { 94*80f47278SJens Wiklander void *buf_cryp = state->buf_cryp; 95*80f47278SJens Wiklander 96*80f47278SJens Wiklander crypto_aes_enc_block(enc_key->data, sizeof(enc_key->data), 97*80f47278SJens Wiklander enc_key->rounds, state->ctr, buf_cryp); 98*80f47278SJens Wiklander internal_aes_gcm_inc_ctr(state); 99*80f47278SJens Wiklander 100*80f47278SJens Wiklander internal_aes_gcm_xor_block(buf_cryp, src); 101*80f47278SJens Wiklander internal_aes_gcm_ghash_update(state, src, NULL, 0); 102*80f47278SJens Wiklander memcpy(dst, buf_cryp, sizeof(state->buf_cryp)); 103*80f47278SJens Wiklander } 104*80f47278SJens Wiklander 105*80f47278SJens Wiklander static void decrypt_pl(struct internal_aes_gcm_state *state, 106*80f47278SJens Wiklander const struct internal_aes_gcm_key *ek, 107*80f47278SJens Wiklander const uint8_t *src, size_t num_blocks, uint8_t *dst) 108*80f47278SJens Wiklander { 109*80f47278SJens Wiklander size_t n = 0; 110*80f47278SJens Wiklander 111*80f47278SJens Wiklander if (ALIGNMENT_IS_OK(src, uint64_t)) { 112*80f47278SJens Wiklander for (n = 0; n < num_blocks; n++) { 113*80f47278SJens Wiklander const void *s = src + n * TEE_AES_BLOCK_SIZE; 114*80f47278SJens Wiklander void *d = dst + n * TEE_AES_BLOCK_SIZE; 115*80f47278SJens Wiklander 116*80f47278SJens Wiklander decrypt_block(state, ek, s, d); 117*80f47278SJens Wiklander } 118*80f47278SJens Wiklander } else { 119*80f47278SJens Wiklander for (n = 0; n < num_blocks; n++) { 120*80f47278SJens Wiklander uint64_t tmp[2] = { 0 }; 121*80f47278SJens Wiklander void *d = dst + n * TEE_AES_BLOCK_SIZE; 122*80f47278SJens Wiklander 123*80f47278SJens Wiklander memcpy(tmp, src + n * TEE_AES_BLOCK_SIZE, sizeof(tmp)); 124*80f47278SJens Wiklander decrypt_block(state, ek, tmp, d); 125*80f47278SJens Wiklander } 126*80f47278SJens Wiklander } 127*80f47278SJens Wiklander } 128*80f47278SJens Wiklander 129*80f47278SJens Wiklander void 130*80f47278SJens Wiklander internal_aes_gcm_update_payload_blocks(struct internal_aes_gcm_state *state, 131*80f47278SJens Wiklander const struct internal_aes_gcm_key *ek, 132*80f47278SJens Wiklander TEE_OperationMode m, const void *src, 133*80f47278SJens Wiklander size_t num_blocks, void *dst) 134*80f47278SJens Wiklander { 135*80f47278SJens Wiklander assert(!state->buf_pos && num_blocks); 136*80f47278SJens Wiklander 137*80f47278SJens Wiklander if (m == TEE_MODE_ENCRYPT) 138*80f47278SJens Wiklander encrypt_pl(state, ek, src, num_blocks, dst); 139*80f47278SJens Wiklander else 140*80f47278SJens Wiklander decrypt_pl(state, ek, src, num_blocks, dst); 141*80f47278SJens Wiklander } 142