xref: /optee_os/core/crypto/aes-gcm-sw.c (revision 424cb3863ab707e652dc5c2f54c1d78686c45fa2)
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 TEE_Result __weak internal_aes_gcm_set_key(struct internal_aes_gcm_ctx *ctx,
18 					   const void *key, size_t key_len)
19 {
20 	TEE_Result res = internal_aes_gcm_expand_enc_key(key, key_len,
21 							 ctx->enc_key,
22 							 &ctx->rounds);
23 
24 	if (res)
25 		return res;
26 
27 #ifdef CFG_AES_GCM_TABLE_BASED
28 	internal_aes_gcm_ghash_gen_tbl(ctx);
29 #else
30 	internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->hash_subkey);
31 #endif
32 
33 	return TEE_SUCCESS;
34 }
35 
36 void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_ctx *ctx,
37 					  const void *head, const void *data,
38 					  size_t num_blocks)
39 {
40 	size_t n;
41 
42 	if (head)
43 		internal_aes_gcm_ghash_update_block(ctx, head);
44 
45 	for (n = 0; n < num_blocks; n++)
46 		internal_aes_gcm_ghash_update_block(ctx, (uint8_t *)data +
47 						    n * TEE_AES_BLOCK_SIZE);
48 }
49 
50 void __weak
51 internal_aes_gcm_update_payload_block_aligned(struct internal_aes_gcm_ctx *ctx,
52 					      TEE_OperationMode m,
53 					      const void *src,
54 					      size_t num_blocks, void *dst)
55 {
56 	size_t n;
57 	const uint8_t *s = src;
58 	uint8_t *d = dst;
59 
60 	assert(!ctx->buf_pos && num_blocks &&
61 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
62 	       internal_aes_gcm_ptr_is_block_aligned(d));
63 
64 	for (n = 0; n < num_blocks; n++) {
65 		if (m == TEE_MODE_ENCRYPT) {
66 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
67 			internal_aes_gcm_ghash_update(ctx, ctx->buf_cryp,
68 						      NULL, 0);
69 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
70 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
71 						       ctx->buf_cryp);
72 			internal_aes_gcm_inc_ctr(ctx);
73 		} else {
74 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
75 						       ctx->buf_cryp);
76 
77 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
78 			internal_aes_gcm_ghash_update(ctx, s, NULL, 0);
79 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
80 
81 			internal_aes_gcm_inc_ctr(ctx);
82 		}
83 		s += TEE_AES_BLOCK_SIZE;
84 		d += TEE_AES_BLOCK_SIZE;
85 	}
86 }
87 
88 void __weak internal_aes_gcm_encrypt_block(struct internal_aes_gcm_ctx *ctx,
89 					   const void *src, void *dst)
90 {
91 	crypto_aes_enc_block(ctx->enc_key, ctx->rounds, src, dst);
92 }
93 
94 TEE_Result __weak internal_aes_gcm_expand_enc_key(const void *key,
95 						  size_t key_len,
96 						  uint64_t *enc_key,
97 						  unsigned int *rounds)
98 {
99 	return crypto_aes_expand_enc_key(key, key_len, enc_key, rounds);
100 }
101