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