xref: /optee_os/core/crypto/aes-gcm-sw.c (revision b97e9666f646ca681890b1f5c61b8d62f0160d34)
1 /*
2  * Copyright (c) 2017, Linaro Limited
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-2-Clause
6  */
7 
8 #include <assert.h>
9 #include <crypto/crypto.h>
10 #include <crypto/internal_aes-gcm.h>
11 #include <string.h>
12 #include <tee_api_types.h>
13 #include <types_ext.h>
14 
15 #include "aes-gcm-private.h"
16 
17 void __weak internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
18 				     const struct internal_aes_gcm_key *ek)
19 {
20 #ifdef CFG_AES_GCM_TABLE_BASED
21 	internal_aes_gcm_ghash_gen_tbl(state, ek);
22 #else
23 	internal_aes_gcm_encrypt_block(ek, state->ctr, state->hash_subkey);
24 #endif
25 }
26 
27 void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
28 					  const void *head, const void *data,
29 					  size_t num_blocks)
30 {
31 	size_t n;
32 
33 	if (head)
34 		internal_aes_gcm_ghash_update_block(state, head);
35 
36 	for (n = 0; n < num_blocks; n++)
37 		internal_aes_gcm_ghash_update_block(state, (uint8_t *)data +
38 						    n * TEE_AES_BLOCK_SIZE);
39 }
40 
41 void __weak
42 internal_aes_gcm_update_payload_block_aligned(
43 				struct internal_aes_gcm_state *state,
44 				const struct internal_aes_gcm_key *ek,
45 				TEE_OperationMode m, const void *src,
46 				size_t num_blocks, void *dst)
47 {
48 	size_t n;
49 	const uint8_t *s = src;
50 	uint8_t *d = dst;
51 	void *ctr = state->ctr;
52 	void *buf_cryp = state->buf_cryp;
53 
54 	assert(!state->buf_pos && num_blocks &&
55 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
56 	       internal_aes_gcm_ptr_is_block_aligned(d));
57 
58 	for (n = 0; n < num_blocks; n++) {
59 		if (m == TEE_MODE_ENCRYPT) {
60 			internal_aes_gcm_xor_block(buf_cryp, s);
61 			internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0);
62 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
63 
64 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
65 			internal_aes_gcm_inc_ctr(state);
66 		} else {
67 			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
68 
69 			internal_aes_gcm_xor_block(buf_cryp, s);
70 			internal_aes_gcm_ghash_update(state, s, NULL, 0);
71 			memcpy(d, buf_cryp, sizeof(state->buf_cryp));
72 
73 			internal_aes_gcm_inc_ctr(state);
74 		}
75 		s += TEE_AES_BLOCK_SIZE;
76 		d += TEE_AES_BLOCK_SIZE;
77 	}
78 }
79 
80 void __weak
81 internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *ek,
82 			       const void *src, void *dst)
83 {
84 	crypto_aes_enc_block(ek->data, ek->rounds, src, dst);
85 }
86 
87 TEE_Result __weak
88 internal_aes_gcm_expand_enc_key(const void *key, size_t key_len,
89 				struct internal_aes_gcm_key *ek)
90 {
91 	return crypto_aes_expand_enc_key(key, key_len, ek->data, &ek->rounds);
92 }
93