xref: /optee_os/core/crypto/aes-gcm-sw.c (revision b8c186b57350152c3e67500d540920ca40309d5b)
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 
81fca7e26SJens Wiklander #include <crypto/internal_aes-gcm.h>
91fca7e26SJens Wiklander #include <kernel/panic.h>
101fca7e26SJens Wiklander #include <string.h>
111fca7e26SJens Wiklander #include <tee_api_types.h>
121fca7e26SJens Wiklander #include <tomcrypt.h>
131fca7e26SJens Wiklander #include <types_ext.h>
141fca7e26SJens Wiklander 
15*b8c186b5SJens 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 {
201fca7e26SJens Wiklander 	if (aes_setup(key, key_len, 0, &ctx->skey))
211fca7e26SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
221fca7e26SJens Wiklander 
23*b8c186b5SJens Wiklander #ifdef CFG_AES_GCM_TABLE_BASED
24*b8c186b5SJens Wiklander 	internal_aes_gcm_ghash_gen_tbl(ctx);
25*b8c186b5SJens Wiklander #else
26*b8c186b5SJens Wiklander 	internal_aes_gcm_encrypt_block(ctx, ctx->ctr, ctx->hash_subkey);
27*b8c186b5SJens Wiklander #endif
281fca7e26SJens Wiklander 
291fca7e26SJens Wiklander 	return TEE_SUCCESS;
301fca7e26SJens Wiklander }
311fca7e26SJens Wiklander 
32*b8c186b5SJens Wiklander void __weak internal_aes_gcm_ghash_update(struct internal_aes_gcm_ctx *ctx,
33*b8c186b5SJens Wiklander 					  const void *head, const void *data,
34*b8c186b5SJens Wiklander 					  size_t num_blocks)
35*b8c186b5SJens Wiklander {
36*b8c186b5SJens Wiklander 	size_t n;
37*b8c186b5SJens Wiklander 
38*b8c186b5SJens Wiklander 	if (head)
39*b8c186b5SJens Wiklander 		internal_aes_gcm_ghash_update_block(ctx, head);
40*b8c186b5SJens Wiklander 
41*b8c186b5SJens Wiklander 	for (n = 0; n < num_blocks; n++)
42*b8c186b5SJens Wiklander 		internal_aes_gcm_ghash_update_block(ctx, (uint8_t *)data +
43*b8c186b5SJens Wiklander 						    n * TEE_AES_BLOCK_SIZE);
44*b8c186b5SJens Wiklander }
45*b8c186b5SJens Wiklander 
461fca7e26SJens Wiklander void __weak
471fca7e26SJens Wiklander internal_aes_gcm_update_payload_block_aligned(struct internal_aes_gcm_ctx *ctx,
481fca7e26SJens Wiklander 					      TEE_OperationMode m,
491fca7e26SJens Wiklander 					      const void *src,
501fca7e26SJens Wiklander 					      size_t num_blocks, void *dst)
511fca7e26SJens Wiklander {
521fca7e26SJens Wiklander 	size_t n;
531fca7e26SJens Wiklander 	const uint8_t *s = src;
541fca7e26SJens Wiklander 	uint8_t *d = dst;
551fca7e26SJens Wiklander 
561fca7e26SJens Wiklander 	assert(!ctx->buf_pos && num_blocks &&
57*b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(s) &&
58*b8c186b5SJens Wiklander 	       internal_aes_gcm_ptr_is_block_aligned(d));
591fca7e26SJens Wiklander 
601fca7e26SJens Wiklander 	for (n = 0; n < num_blocks; n++) {
611fca7e26SJens Wiklander 		if (m == TEE_MODE_ENCRYPT) {
62*b8c186b5SJens Wiklander 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
631fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, ctx->buf_cryp,
641fca7e26SJens Wiklander 						      NULL, 0);
651fca7e26SJens Wiklander 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
661fca7e26SJens Wiklander 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
671fca7e26SJens Wiklander 						       ctx->buf_cryp);
681fca7e26SJens Wiklander 			internal_aes_gcm_inc_ctr(ctx);
691fca7e26SJens Wiklander 		} else {
701fca7e26SJens Wiklander 			internal_aes_gcm_encrypt_block(ctx, ctx->ctr,
711fca7e26SJens Wiklander 						       ctx->buf_cryp);
721fca7e26SJens Wiklander 
73*b8c186b5SJens Wiklander 			internal_aes_gcm_xor_block(ctx->buf_cryp, s);
741fca7e26SJens Wiklander 			internal_aes_gcm_ghash_update(ctx, s, NULL, 0);
751fca7e26SJens Wiklander 			memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp));
761fca7e26SJens Wiklander 
771fca7e26SJens Wiklander 			internal_aes_gcm_inc_ctr(ctx);
781fca7e26SJens Wiklander 		}
791fca7e26SJens Wiklander 		s += TEE_AES_BLOCK_SIZE;
801fca7e26SJens Wiklander 		d += TEE_AES_BLOCK_SIZE;
811fca7e26SJens Wiklander 	}
821fca7e26SJens Wiklander }
831fca7e26SJens Wiklander 
841fca7e26SJens Wiklander void __weak internal_aes_gcm_encrypt_block(struct internal_aes_gcm_ctx *ctx,
851fca7e26SJens Wiklander 					   const void *src, void *dst)
861fca7e26SJens Wiklander {
871fca7e26SJens Wiklander 	if (aes_ecb_encrypt(src, dst, &ctx->skey))
881fca7e26SJens Wiklander 		panic();
891fca7e26SJens Wiklander }
90