1 /* 2 * Copyright (c) 2017, Linaro Limited 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8 /* 9 * gfmul() is based on ghash_gfmul from 10 * https://github.com/openbsd/src/blob/master/sys/crypto/gmac.c 11 * Which is: 12 * Copyright (c) 2010 Mike Belopuhov 13 * 14 * Permission to use, copy, modify, and distribute this software for any 15 * purpose with or without fee is hereby granted, provided that the above 16 * copyright notice and this permission notice appear in all copies. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 19 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 21 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 23 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 24 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 */ 26 27 #include <crypto/internal_aes-gcm.h> 28 #include <kernel/panic.h> 29 #include <string.h> 30 #include <tee_api_types.h> 31 #include <tomcrypt.h> 32 #include <types_ext.h> 33 34 static bool __maybe_unused ptr_is_block_aligned(const void *p) 35 { 36 return !((vaddr_t)p & (TEE_AES_BLOCK_SIZE - 1)); 37 } 38 39 static void xor_block(void *dst, const void *src) 40 { 41 uint64_t *d = dst; 42 const uint64_t *s = src; 43 44 d[0] ^= s[0]; 45 d[1] ^= s[1]; 46 } 47 48 TEE_Result __weak internal_aes_gcm_set_key(struct internal_aes_gcm_ctx *ctx, 49 const void *key, size_t key_len) 50 { 51 if (aes_setup(key, key_len, 0, &ctx->skey)) 52 return TEE_ERROR_BAD_PARAMETERS; 53 54 if (aes_ecb_encrypt((void *)ctx->ctr, ctx->hash_subkey, &ctx->skey)) 55 panic(); 56 57 return TEE_SUCCESS; 58 } 59 60 void __weak 61 internal_aes_gcm_update_payload_block_aligned(struct internal_aes_gcm_ctx *ctx, 62 TEE_OperationMode m, 63 const void *src, 64 size_t num_blocks, void *dst) 65 { 66 size_t n; 67 const uint8_t *s = src; 68 uint8_t *d = dst; 69 70 assert(!ctx->buf_pos && num_blocks && 71 ptr_is_block_aligned(s) && ptr_is_block_aligned(d)); 72 73 for (n = 0; n < num_blocks; n++) { 74 if (m == TEE_MODE_ENCRYPT) { 75 xor_block(ctx->buf_cryp, s); 76 internal_aes_gcm_ghash_update(ctx, ctx->buf_cryp, 77 NULL, 0); 78 memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp)); 79 internal_aes_gcm_encrypt_block(ctx, ctx->ctr, 80 ctx->buf_cryp); 81 internal_aes_gcm_inc_ctr(ctx); 82 } else { 83 internal_aes_gcm_encrypt_block(ctx, ctx->ctr, 84 ctx->buf_cryp); 85 86 xor_block(ctx->buf_cryp, s); 87 internal_aes_gcm_ghash_update(ctx, s, NULL, 0); 88 memcpy(d, ctx->buf_cryp, sizeof(ctx->buf_cryp)); 89 90 internal_aes_gcm_inc_ctr(ctx); 91 } 92 s += TEE_AES_BLOCK_SIZE; 93 d += TEE_AES_BLOCK_SIZE; 94 } 95 } 96 97 void __weak internal_aes_gcm_encrypt_block(struct internal_aes_gcm_ctx *ctx, 98 const void *src, void *dst) 99 { 100 if (aes_ecb_encrypt(src, dst, &ctx->skey)) 101 panic(); 102 } 103