xref: /optee_os/core/crypto/aes-gcm-sw.c (revision e7dbc357e4f927150836fae68da133dd7de4da2f)
1fb7ef469SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
21fca7e26SJens Wiklander /*
31fca7e26SJens Wiklander  * Copyright (c) 2017, 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 
13b8c186b5SJens Wiklander #include "aes-gcm-private.h"
141fca7e26SJens Wiklander 
1554af8d67SJens Wiklander void __weak internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
1654af8d67SJens Wiklander 				     const struct internal_aes_gcm_key *ek)
171fca7e26SJens Wiklander {
18b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
1954af8d67SJens Wiklander 	internal_aes_gcm_ghash_gen_tbl(state, ek);
20b8c186b5SJens Wiklander #else
2154af8d67SJens Wiklander 	internal_aes_gcm_encrypt_block(ek, state->ctr, state->hash_subkey);
22b8c186b5SJens Wiklander #endif
231fca7e26SJens Wiklander }
241fca7e26SJens Wiklander 
2554af8d67SJens Wiklander void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
26b8c186b5SJens Wiklander 					  const void *head, const void *data,
27b8c186b5SJens Wiklander 					  size_t num_blocks)
28b8c186b5SJens Wiklander {
29b8c186b5SJens Wiklander 	size_t n;
30b8c186b5SJens Wiklander 
31b8c186b5SJens Wiklander 	if (head)
3254af8d67SJens Wiklander 		internal_aes_gcm_ghash_update_block(state, head);
33b8c186b5SJens Wiklander 
34b8c186b5SJens Wiklander 	for (n = 0; n < num_blocks; n++)
3554af8d67SJens Wiklander 		internal_aes_gcm_ghash_update_block(state, (uint8_t *)data +
36b8c186b5SJens Wiklander 						    n * TEE_AES_BLOCK_SIZE);
37b8c186b5SJens Wiklander }
38b8c186b5SJens Wiklander 
391fca7e26SJens Wiklander void __weak
4054af8d67SJens Wiklander internal_aes_gcm_update_payload_block_aligned(
4154af8d67SJens Wiklander 				struct internal_aes_gcm_state *state,
4254af8d67SJens Wiklander 				const struct internal_aes_gcm_key *ek,
4354af8d67SJens Wiklander 				TEE_OperationMode m, const void *src,
441fca7e26SJens Wiklander 				size_t num_blocks, void *dst)
451fca7e26SJens Wiklander {
461fca7e26SJens Wiklander 	size_t n;
471fca7e26SJens Wiklander 	const uint8_t *s = src;
481fca7e26SJens Wiklander 	uint8_t *d = dst;
4954af8d67SJens Wiklander 	void *ctr = state->ctr;
5054af8d67SJens Wiklander 	void *buf_cryp = state->buf_cryp;
511fca7e26SJens Wiklander 
5254af8d67SJens Wiklander 	assert(!state->buf_pos && num_blocks &&
53b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
54b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(d));
551fca7e26SJens Wiklander 
561fca7e26SJens Wiklander 	for (n = 0; n < num_blocks; n++) {
571fca7e26SJens Wiklander 		if (m == TEE_MODE_ENCRYPT) {
5854af8d67SJens Wiklander 			internal_aes_gcm_xor_block(buf_cryp, s);
5954af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0);
6054af8d67SJens Wiklander 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
6154af8d67SJens Wiklander 
6254af8d67SJens Wiklander 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
6354af8d67SJens Wiklander 			internal_aes_gcm_inc_ctr(state);
641fca7e26SJens Wiklander 		} else {
6554af8d67SJens Wiklander 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
661fca7e26SJens Wiklander 
6754af8d67SJens Wiklander 			internal_aes_gcm_xor_block(buf_cryp, s);
6854af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, s, NULL, 0);
6954af8d67SJens Wiklander 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
701fca7e26SJens Wiklander 
7154af8d67SJens Wiklander 			internal_aes_gcm_inc_ctr(state);
721fca7e26SJens Wiklander 		}
731fca7e26SJens Wiklander 		s += TEE_AES_BLOCK_SIZE;
741fca7e26SJens Wiklander 		d += TEE_AES_BLOCK_SIZE;
751fca7e26SJens Wiklander 	}
761fca7e26SJens Wiklander }
771fca7e26SJens Wiklander 
7854af8d67SJens Wiklander void __weak
7954af8d67SJens Wiklander internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *ek,
801fca7e26SJens Wiklander 			       const void *src, void *dst)
811fca7e26SJens Wiklander {
82*e7dbc357SSummer Qin 	size_t ek_len = sizeof(ek->data);
83*e7dbc357SSummer Qin 
84*e7dbc357SSummer Qin 	crypto_aes_enc_block(ek->data, ek_len, ek->rounds, src, dst);
8561b4cd9cSJens Wiklander }
8661b4cd9cSJens Wiklander 
8754af8d67SJens Wiklander TEE_Result __weak
8854af8d67SJens Wiklander internal_aes_gcm_expand_enc_key(const void *key, size_t key_len,
8954af8d67SJens Wiklander 				struct internal_aes_gcm_key *ek)
9061b4cd9cSJens Wiklander {
91*e7dbc357SSummer Qin 	size_t ek_len = sizeof(ek->data);
92*e7dbc357SSummer Qin 
93*e7dbc357SSummer Qin 	return crypto_aes_expand_enc_key(key, key_len, ek->data, ek_len,
94*e7dbc357SSummer Qin 					&ek->rounds);
951fca7e26SJens Wiklander }
96