aboutsummaryrefslogtreecommitdiff
path: root/core/crypto/aes-gcm-sw.c
blob: b651d5e0af9b71d8393a0e3999e891449b16b48c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2017, Linaro Limited
 */

#include <assert.h>
#include <crypto/crypto.h>
#include <crypto/internal_aes-gcm.h>
#include <string.h>
#include <tee_api_types.h>
#include <types_ext.h>

#include "aes-gcm-private.h"

void __weak internal_aes_gcm_set_key(struct internal_aes_gcm_state *state,
				     const struct internal_aes_gcm_key *ek)
{
#ifdef CFG_AES_GCM_TABLE_BASED
	internal_aes_gcm_ghash_gen_tbl(state, ek);
#else
	internal_aes_gcm_encrypt_block(ek, state->ctr, state->hash_subkey);
#endif
}

void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_state *state,
					  const void *head, const void *data,
					  size_t num_blocks)
{
	size_t n;

	if (head)
		internal_aes_gcm_ghash_update_block(state, head);

	for (n = 0; n < num_blocks; n++)
		internal_aes_gcm_ghash_update_block(state, (uint8_t *)data +
						    n * TEE_AES_BLOCK_SIZE);
}

void __weak
internal_aes_gcm_update_payload_block_aligned(
				struct internal_aes_gcm_state *state,
				const struct internal_aes_gcm_key *ek,
				TEE_OperationMode m, const void *src,
				size_t num_blocks, void *dst)
{
	size_t n;
	const uint8_t *s = src;
	uint8_t *d = dst;
	void *ctr = state->ctr;
	void *buf_cryp = state->buf_cryp;

	assert(!state->buf_pos && num_blocks &&
	       internal_aes_gcm_ptr_is_block_aligned(s) &&
	       internal_aes_gcm_ptr_is_block_aligned(d));

	for (n = 0; n < num_blocks; n++) {
		if (m == TEE_MODE_ENCRYPT) {
			internal_aes_gcm_xor_block(buf_cryp, s);
			internal_aes_gcm_ghash_update(state, buf_cryp, NULL, 0);
			memcpy(d, buf_cryp, sizeof(state->buf_cryp));

			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);
			internal_aes_gcm_inc_ctr(state);
		} else {
			internal_aes_gcm_encrypt_block(ek, ctr, buf_cryp);

			internal_aes_gcm_xor_block(buf_cryp, s);
			internal_aes_gcm_ghash_update(state, s, NULL, 0);
			memcpy(d, buf_cryp, sizeof(state->buf_cryp));

			internal_aes_gcm_inc_ctr(state);
		}
		s += TEE_AES_BLOCK_SIZE;
		d += TEE_AES_BLOCK_SIZE;
	}
}

void __weak
internal_aes_gcm_encrypt_block(const struct internal_aes_gcm_key *ek,
			       const void *src, void *dst)
{
	size_t ek_len = sizeof(ek->data);

	crypto_aes_enc_block(ek->data, ek_len, ek->rounds, src, dst);
}

TEE_Result __weak
internal_aes_gcm_expand_enc_key(const void *key, size_t key_len,
				struct internal_aes_gcm_key *ek)
{
	size_t ek_len = sizeof(ek->data);

	return crypto_aes_expand_enc_key(key, key_len, ek->data, ek_len,
					&ek->rounds);
}