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