xref: /optee_os/core/crypto/aes-gcm-sw.c (revision 61b4cd9c4374b872e59d84b3d6b564264716c485)
11fca7e26SJens Wiklander /*
21fca7e26SJens Wiklander  * Copyright (c) 2017, Linaro Limited
31fca7e26SJens Wiklander  * All rights reserved.
41fca7e26SJens Wiklander  *
51fca7e26SJens Wiklander  * SPDX-License-Identifier: BSD-2-Clause
61fca7e26SJens Wiklander  */
71fca7e26SJens Wiklander 
8*61b4cd9cSJens Wiklander #include <assert.h>
9*61b4cd9cSJens Wiklander #include <crypto/crypto.h>
101fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h>
111fca7e26SJens Wiklander #include <string.h>
121fca7e26SJens Wiklander #include <tee_api_types.h>
131fca7e26SJens Wiklander #include <types_ext.h>
141fca7e26SJens Wiklander 
15b8c186b5SJens Wiklander #include "aes-gcm-private.h"
161fca7e26SJens Wiklander 
171fca7e26SJens Wiklander TEE_Result __weak internal_aes_gcm_set_key(struct internal_aes_gcm_ctx *ctx,
181fca7e26SJens Wiklander 					   const void *key, size_t key_len)
191fca7e26SJens Wiklander {
20*61b4cd9cSJens Wiklander 	TEE_Result res = internal_aes_gcm_expand_enc_key(key, key_len,
21*61b4cd9cSJens Wiklander 							 ctx->enc_key,
22*61b4cd9cSJens Wiklander 							 &ctx->rounds);
23*61b4cd9cSJens Wiklander 
24*61b4cd9cSJens Wiklander 	if (res)
25*61b4cd9cSJens Wiklander 		return res;
261fca7e26SJens Wiklander 
27b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
28b8c186b5SJens Wiklander 	internal_aes_gcm_ghash_gen_tbl(ctx);
29b8c186b5SJens Wiklander #else
30b8c186b5SJens Wiklander 	internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->hash_subkey);
31b8c186b5SJens Wiklander #endif
321fca7e26SJens Wiklander 
331fca7e26SJens Wiklander 	return TEE_SUCCESS;
341fca7e26SJens Wiklander }
351fca7e26SJens Wiklander 
36b8c186b5SJens Wiklander void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_ctx *ctx,
37b8c186b5SJens Wiklander 					  const void *head, const void *data,
38b8c186b5SJens Wiklander 					  size_t num_blocks)
39b8c186b5SJens Wiklander {
40b8c186b5SJens Wiklander 	size_t n;
41b8c186b5SJens Wiklander 
42b8c186b5SJens Wiklander 	if (head)
43b8c186b5SJens Wiklander 		internal_aes_gcm_ghash_update_block(ctx, head);
44b8c186b5SJens Wiklander 
45b8c186b5SJens Wiklander 	for (n = 0; n < num_blocks; n++)
46b8c186b5SJens Wiklander 		internal_aes_gcm_ghash_update_block(ctx, (uint8_t *)data +
47b8c186b5SJens Wiklander 						    n * TEE_AES_BLOCK_SIZE);
48b8c186b5SJens Wiklander }
49b8c186b5SJens Wiklander 
501fca7e26SJens Wiklander void __weak
511fca7e26SJens Wiklander internal_aes_gcm_update_payload_block_aligned(struct internal_aes_gcm_ctx *ctx,
521fca7e26SJens Wiklander 					      TEE_OperationMode m,
531fca7e26SJens Wiklander 					      const void *src,
541fca7e26SJens Wiklander 					      size_t num_blocks, void *dst)
551fca7e26SJens Wiklander {
561fca7e26SJens Wiklander 	size_t n;
571fca7e26SJens Wiklander 	const uint8_t *s = src;
581fca7e26SJens Wiklander 	uint8_t *d = dst;
591fca7e26SJens Wiklander 
601fca7e26SJens Wiklander 	assert(!ctx->buf_pos && num_blocks &&
61b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
62b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(d));
631fca7e26SJens Wiklander 
641fca7e26SJens Wiklander 	for (n = 0; n < num_blocks; n++) {
651fca7e26SJens Wiklander 		if (m == TEE_MODE_ENCRYPT) {
66b8c186b5SJens Wiklander 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
671fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, ctx->buf_cryp,
681fca7e26SJens Wiklander 						      NULL, 0);
691fca7e26SJens Wiklander 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
701fca7e26SJens Wiklander 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
711fca7e26SJens Wiklander 						       ctx->buf_cryp);
721fca7e26SJens Wiklander 			internal_aes_gcm_inc_ctr(ctx);
731fca7e26SJens Wiklander 		} else {
741fca7e26SJens Wiklander 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
751fca7e26SJens Wiklander 						       ctx->buf_cryp);
761fca7e26SJens Wiklander 
77b8c186b5SJens Wiklander 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
781fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, s, NULL, 0);
791fca7e26SJens Wiklander 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
801fca7e26SJens Wiklander 
811fca7e26SJens Wiklander 			internal_aes_gcm_inc_ctr(ctx);
821fca7e26SJens Wiklander 		}
831fca7e26SJens Wiklander 		s += TEE_AES_BLOCK_SIZE;
841fca7e26SJens Wiklander 		d += TEE_AES_BLOCK_SIZE;
851fca7e26SJens Wiklander 	}
861fca7e26SJens Wiklander }
871fca7e26SJens Wiklander 
881fca7e26SJens Wiklander void __weak internal_aes_gcm_encrypt_block(struct internal_aes_gcm_ctx *ctx,
891fca7e26SJens Wiklander 					   const void *src, void *dst)
901fca7e26SJens Wiklander {
91*61b4cd9cSJens Wiklander 	crypto_aes_enc_block(ctx->enc_key, ctx->rounds, src, dst);
92*61b4cd9cSJens Wiklander }
93*61b4cd9cSJens Wiklander 
94*61b4cd9cSJens Wiklander TEE_Result __weak internal_aes_gcm_expand_enc_key(const void *key,
95*61b4cd9cSJens Wiklander 						  size_t key_len,
96*61b4cd9cSJens Wiklander 						  uint64_t *enc_key,
97*61b4cd9cSJens Wiklander 						  unsigned int *rounds)
98*61b4cd9cSJens Wiklander {
99*61b4cd9cSJens Wiklander 	return crypto_aes_expand_enc_key(key, key_len, enc_key, rounds);
1001fca7e26SJens Wiklander }
101