2018-12-05 09:20:01 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* NHPoly1305 - ε - almost - ∆ - universal hash function for Adiantum
* ( AVX2 accelerated version )
*
* Copyright 2018 Google LLC
*/
# include <crypto/internal/hash.h>
2019-03-13 08:12:48 +03:00
# include <crypto/internal/simd.h>
2018-12-05 09:20:01 +03:00
# include <crypto/nhpoly1305.h>
# include <linux/module.h>
2020-08-19 14:58:20 +03:00
# include <linux/sizes.h>
2019-03-13 08:12:48 +03:00
# include <asm/simd.h>
2018-12-05 09:20:01 +03:00
asmlinkage void nh_avx2 ( const u32 * key , const u8 * message , size_t message_len ,
u8 hash [ NH_HASH_BYTES ] ) ;
/* wrapper to avoid indirect call to assembly, which doesn't work with CFI */
static void _nh_avx2 ( const u32 * key , const u8 * message , size_t message_len ,
__le64 hash [ NH_NUM_PASSES ] )
{
nh_avx2 ( key , message , message_len , ( u8 * ) hash ) ;
}
static int nhpoly1305_avx2_update ( struct shash_desc * desc ,
const u8 * src , unsigned int srclen )
{
2019-03-13 08:12:48 +03:00
if ( srclen < 64 | | ! crypto_simd_usable ( ) )
2018-12-05 09:20:01 +03:00
return crypto_nhpoly1305_update ( desc , src , srclen ) ;
do {
2020-04-23 02:18:54 +03:00
unsigned int n = min_t ( unsigned int , srclen , SZ_4K ) ;
2018-12-05 09:20:01 +03:00
kernel_fpu_begin ( ) ;
crypto_nhpoly1305_update_helper ( desc , src , n , _nh_avx2 ) ;
kernel_fpu_end ( ) ;
src + = n ;
srclen - = n ;
} while ( srclen ) ;
return 0 ;
}
static struct shash_alg nhpoly1305_alg = {
. base . cra_name = " nhpoly1305 " ,
. base . cra_driver_name = " nhpoly1305-avx2 " ,
. base . cra_priority = 300 ,
. base . cra_ctxsize = sizeof ( struct nhpoly1305_key ) ,
. base . cra_module = THIS_MODULE ,
. digestsize = POLY1305_DIGEST_SIZE ,
. init = crypto_nhpoly1305_init ,
. update = nhpoly1305_avx2_update ,
. final = crypto_nhpoly1305_final ,
. setkey = crypto_nhpoly1305_setkey ,
. descsize = sizeof ( struct nhpoly1305_state ) ,
} ;
static int __init nhpoly1305_mod_init ( void )
{
if ( ! boot_cpu_has ( X86_FEATURE_AVX2 ) | |
! boot_cpu_has ( X86_FEATURE_OSXSAVE ) )
return - ENODEV ;
return crypto_register_shash ( & nhpoly1305_alg ) ;
}
static void __exit nhpoly1305_mod_exit ( void )
{
crypto_unregister_shash ( & nhpoly1305_alg ) ;
}
module_init ( nhpoly1305_mod_init ) ;
module_exit ( nhpoly1305_mod_exit ) ;
MODULE_DESCRIPTION ( " NHPoly1305 ε-almost-∆-universal hash function (AVX2-accelerated) " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Eric Biggers <ebiggers@google.com> " ) ;
MODULE_ALIAS_CRYPTO ( " nhpoly1305 " ) ;
MODULE_ALIAS_CRYPTO ( " nhpoly1305-avx2 " ) ;