|
| 1 | +#if defined(__aarch64__) || defined(_M_ARM64) |
| 2 | + |
| 3 | +# include <stddef.h> |
| 4 | +# include <stdint.h> |
| 5 | + |
| 6 | +# include "../common/common.h" |
| 7 | +# include "aegis128l.h" |
| 8 | +# include "aegis128l_neon_sha3.h" |
| 9 | + |
| 10 | +# ifndef __ARM_FEATURE_CRYPTO |
| 11 | +# define __ARM_FEATURE_CRYPTO 1 |
| 12 | +# endif |
| 13 | +# ifndef __ARM_FEATURE_AES |
| 14 | +# define __ARM_FEATURE_AES 1 |
| 15 | +# endif |
| 16 | +# ifndef __ARM_FEATURE_SHA3 |
| 17 | +# define __ARM_FEATURE_SHA3 1 |
| 18 | +# endif |
| 19 | + |
| 20 | +# include <arm_neon.h> |
| 21 | + |
| 22 | +# ifdef __clang__ |
| 23 | +# pragma clang attribute push(__attribute__((target("neon,crypto,aes,sha3"))), \ |
| 24 | + apply_to = function) |
| 25 | +# elif defined(__GNUC__) |
| 26 | +# pragma GCC target("+simd+crypto+sha3") |
| 27 | +# endif |
| 28 | + |
| 29 | +# define AES_BLOCK_LENGTH 16 |
| 30 | + |
| 31 | +typedef uint8x16_t aes_block_t; |
| 32 | + |
| 33 | +# define AES_BLOCK_XOR(A, B) veorq_u8((A), (B)) |
| 34 | +# define AES_BLOCK_XOR3(A, B, C) veor3q_u8((A), (B), (C)) |
| 35 | +# define AES_BLOCK_AND(A, B) vandq_u8((A), (B)) |
| 36 | +# define AES_BLOCK_LOAD(A) vld1q_u8(A) |
| 37 | +# define AES_BLOCK_LOAD_64x2(A, B) vreinterpretq_u8_u64(vsetq_lane_u64((A), vmovq_n_u64(B), 1)) |
| 38 | +# define AES_BLOCK_STORE(A, B) vst1q_u8((A), (B)) |
| 39 | +# define AES_ENC0(A) vaesmcq_u8(vaeseq_u8(vmovq_n_u8(0), (A))) |
| 40 | +# define AES_ENC(A, B) AES_BLOCK_XOR(AES_ENC0(A), (B)) |
| 41 | + |
| 42 | +static inline void |
| 43 | +aegis128l_update(aes_block_t *const state, const aes_block_t d1, const aes_block_t d2) |
| 44 | +{ |
| 45 | + aes_block_t tmp; |
| 46 | + |
| 47 | + tmp = state[7]; |
| 48 | + state[7] = AES_ENC(state[6], state[7]); |
| 49 | + state[6] = AES_ENC(state[5], state[6]); |
| 50 | + state[5] = AES_ENC(state[4], state[5]); |
| 51 | + state[4] = AES_BLOCK_XOR3(state[4], AES_ENC0(state[3]), d2); |
| 52 | + state[3] = AES_ENC(state[2], state[3]); |
| 53 | + state[2] = AES_ENC(state[1], state[2]); |
| 54 | + state[1] = AES_ENC(state[0], state[1]); |
| 55 | + state[0] = AES_BLOCK_XOR3(state[0], AES_ENC0(tmp), d1); |
| 56 | +} |
| 57 | + |
| 58 | +# include "aegis128l_common.h" |
| 59 | + |
| 60 | +struct aegis128l_implementation aegis128l_neon_sha3_implementation = { |
| 61 | + .encrypt_detached = encrypt_detached, |
| 62 | + .decrypt_detached = decrypt_detached, |
| 63 | + .encrypt_unauthenticated = encrypt_unauthenticated, |
| 64 | + .decrypt_unauthenticated = decrypt_unauthenticated, |
| 65 | + .stream = stream, |
| 66 | + .state_init = state_init, |
| 67 | + .state_encrypt_update = state_encrypt_update, |
| 68 | + .state_encrypt_detached_final = state_encrypt_detached_final, |
| 69 | + .state_encrypt_final = state_encrypt_final, |
| 70 | + .state_decrypt_detached_update = state_decrypt_detached_update, |
| 71 | + .state_decrypt_detached_final = state_decrypt_detached_final, |
| 72 | + .state_mac_init = state_mac_init, |
| 73 | + .state_mac_update = state_mac_update, |
| 74 | + .state_mac_final = state_mac_final, |
| 75 | + .state_mac_reset = state_mac_reset, |
| 76 | + .state_mac_clone = state_mac_clone, |
| 77 | +}; |
| 78 | + |
| 79 | +# ifdef __clang__ |
| 80 | +# pragma clang attribute pop |
| 81 | +# endif |
| 82 | + |
| 83 | +#endif |
0 commit comments