xref: /optee_os/core/crypto/aes-gcm-sw.c (revision 80f47278d9577d02e60540a2426b5cd28fb4d637)
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