Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * AEGIS common definitions
0004  *
0005  * Copyright (c) 2018 Ondrej Mosnacek <omosnacek@gmail.com>
0006  * Copyright (c) 2018 Red Hat, Inc. All rights reserved.
0007  */
0008 
0009 #ifndef _CRYPTO_AEGIS_H
0010 #define _CRYPTO_AEGIS_H
0011 
0012 #include <crypto/aes.h>
0013 #include <linux/bitops.h>
0014 #include <linux/types.h>
0015 
0016 #define AEGIS_BLOCK_SIZE 16
0017 
0018 union aegis_block {
0019     __le64 words64[AEGIS_BLOCK_SIZE / sizeof(__le64)];
0020     __le32 words32[AEGIS_BLOCK_SIZE / sizeof(__le32)];
0021     u8 bytes[AEGIS_BLOCK_SIZE];
0022 };
0023 
0024 struct aegis_state;
0025 
0026 extern int aegis128_have_aes_insn;
0027 
0028 #define AEGIS_BLOCK_ALIGN (__alignof__(union aegis_block))
0029 #define AEGIS_ALIGNED(p) IS_ALIGNED((uintptr_t)p, AEGIS_BLOCK_ALIGN)
0030 
0031 bool crypto_aegis128_have_simd(void);
0032 void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg);
0033 void crypto_aegis128_init_simd(struct aegis_state *state,
0034                    const union aegis_block *key,
0035                    const u8 *iv);
0036 void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
0037                     const u8 *src, unsigned int size);
0038 void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
0039                     const u8 *src, unsigned int size);
0040 int crypto_aegis128_final_simd(struct aegis_state *state,
0041                    union aegis_block *tag_xor,
0042                    unsigned int assoclen,
0043                    unsigned int cryptlen,
0044                    unsigned int authsize);
0045 
0046 static __always_inline void crypto_aegis_block_xor(union aegis_block *dst,
0047                            const union aegis_block *src)
0048 {
0049     dst->words64[0] ^= src->words64[0];
0050     dst->words64[1] ^= src->words64[1];
0051 }
0052 
0053 static __always_inline void crypto_aegis_block_and(union aegis_block *dst,
0054                            const union aegis_block *src)
0055 {
0056     dst->words64[0] &= src->words64[0];
0057     dst->words64[1] &= src->words64[1];
0058 }
0059 
0060 static __always_inline void crypto_aegis_aesenc(union aegis_block *dst,
0061                         const union aegis_block *src,
0062                         const union aegis_block *key)
0063 {
0064     const u8  *s  = src->bytes;
0065     const u32 *t = crypto_ft_tab[0];
0066     u32 d0, d1, d2, d3;
0067 
0068     d0 = t[s[ 0]] ^ rol32(t[s[ 5]], 8) ^ rol32(t[s[10]], 16) ^ rol32(t[s[15]], 24);
0069     d1 = t[s[ 4]] ^ rol32(t[s[ 9]], 8) ^ rol32(t[s[14]], 16) ^ rol32(t[s[ 3]], 24);
0070     d2 = t[s[ 8]] ^ rol32(t[s[13]], 8) ^ rol32(t[s[ 2]], 16) ^ rol32(t[s[ 7]], 24);
0071     d3 = t[s[12]] ^ rol32(t[s[ 1]], 8) ^ rol32(t[s[ 6]], 16) ^ rol32(t[s[11]], 24);
0072 
0073     dst->words32[0] = cpu_to_le32(d0) ^ key->words32[0];
0074     dst->words32[1] = cpu_to_le32(d1) ^ key->words32[1];
0075     dst->words32[2] = cpu_to_le32(d2) ^ key->words32[2];
0076     dst->words32[3] = cpu_to_le32(d3) ^ key->words32[3];
0077 }
0078 
0079 #endif /* _CRYPTO_AEGIS_H */