xref: /optee_os/core/crypto/aes-gcm-sw.c (revision 54af8d679d9af478930edd5a8caef1b778dfe74d)
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 
861b4cd9cSJens Wiklander #include <assert.h>
961b4cd9cSJens 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 
17*54af8d67SJens Wiklander void __weak internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
18*54af8d67SJens Wiklander 				     const struct internal_aes_gcm_key *ek)
191fca7e26SJens Wiklander {
20b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
21*54af8d67SJens Wiklander 	internal_aes_gcm_ghash_gen_tbl(state, ek);
22b8c186b5SJens Wiklander #else
23*54af8d67SJens Wiklander 	internal_aes_gcm_encrypt_block(ek, state->ctr, state->hash_subkey);
24b8c186b5SJens Wiklander #endif
251fca7e26SJens Wiklander }
261fca7e26SJens Wiklander 
27*54af8d67SJens Wiklander void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
28b8c186b5SJens Wiklander 					  const void *head, const void *data,
29b8c186b5SJens Wiklander 					  size_t num_blocks)
30b8c186b5SJens Wiklander {
31b8c186b5SJens Wiklander 	size_t n;
32b8c186b5SJens Wiklander 
33b8c186b5SJens Wiklander 	if (head)
34*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update_block(state, head);
35b8c186b5SJens Wiklander 
36b8c186b5SJens Wiklander 	for (n = 0; n < num_blocks; n++)
37*54af8d67SJens Wiklander 		internal_aes_gcm_ghash_update_block(state, (uint8_t *)data +
38b8c186b5SJens Wiklander 						    n * TEE_AES_BLOCK_SIZE);
39b8c186b5SJens Wiklander }
40b8c186b5SJens Wiklander 
411fca7e26SJens Wiklander void __weak
42*54af8d67SJens Wiklander internal_aes_gcm_update_payload_block_aligned(
43*54af8d67SJens Wiklander 				struct internal_aes_gcm_state *state,
44*54af8d67SJens Wiklander 				const struct internal_aes_gcm_key *ek,
45*54af8d67SJens Wiklander 				TEE_OperationMode m, const void *src,
461fca7e26SJens Wiklander 				size_t num_blocks, void *dst)
471fca7e26SJens Wiklander {
481fca7e26SJens Wiklander 	size_t n;
491fca7e26SJens Wiklander 	const uint8_t *s = src;
501fca7e26SJens Wiklander 	uint8_t *d = dst;
51*54af8d67SJens Wiklander 	void *ctr = state->ctr;
52*54af8d67SJens Wiklander 	void *buf_cryp = state->buf_cryp;
531fca7e26SJens Wiklander 
54*54af8d67SJens Wiklander 	assert(!state->buf_pos && num_blocks &&
55b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
56b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(d));
571fca7e26SJens Wiklander 
581fca7e26SJens Wiklander 	for (n = 0; n < num_blocks; n++) {
591fca7e26SJens Wiklander 		if (m == TEE_MODE_ENCRYPT) {
60*54af8d67SJens Wiklander 			internal_aes_gcm_xor_block(buf_cryp, s);
61*54af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0);
62*54af8d67SJens Wiklander 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
63*54af8d67SJens Wiklander 
64*54af8d67SJens Wiklander 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
65*54af8d67SJens Wiklander 			internal_aes_gcm_inc_ctr(state);
661fca7e26SJens Wiklander 		} else {
67*54af8d67SJens Wiklander 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
681fca7e26SJens Wiklander 
69*54af8d67SJens Wiklander 			internal_aes_gcm_xor_block(buf_cryp, s);
70*54af8d67SJens Wiklander 			internal_aes_gcm_ghash_update(state, s, NULL, 0);
71*54af8d67SJens Wiklander 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
721fca7e26SJens Wiklander 
73*54af8d67SJens Wiklander 			internal_aes_gcm_inc_ctr(state);
741fca7e26SJens Wiklander 		}
751fca7e26SJens Wiklander 		s += TEE_AES_BLOCK_SIZE;
761fca7e26SJens Wiklander 		d += TEE_AES_BLOCK_SIZE;
771fca7e26SJens Wiklander 	}
781fca7e26SJens Wiklander }
791fca7e26SJens Wiklander 
80*54af8d67SJens Wiklander void __weak
81*54af8d67SJens Wiklander internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *ek,
821fca7e26SJens Wiklander 			       const void *src, void *dst)
831fca7e26SJens Wiklander {
84*54af8d67SJens Wiklander 	crypto_aes_enc_block(ek->data, ek->rounds, src, dst);
8561b4cd9cSJens Wiklander }
8661b4cd9cSJens Wiklander 
87*54af8d67SJens Wiklander TEE_Result __weak
88*54af8d67SJens Wiklander internal_aes_gcm_expand_enc_key(const void *key, size_t key_len,
89*54af8d67SJens Wiklander 				struct internal_aes_gcm_key *ek)
9061b4cd9cSJens Wiklander {
91*54af8d67SJens Wiklander 	return crypto_aes_expand_enc_key(key, key_len, ek->data, &ek->rounds);
921fca7e26SJens Wiklander }
93