2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2014-07-29 17:14:14 +01:00
/*
* Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
* ARM NEON instructions .
*
* Copyright © 2014 Jussi Kivilinna < jussi . kivilinna @ iki . fi >
*
* This file is based on sha1_generic . c and sha1_ssse3_glue . c :
* Copyright ( c ) Alan Smithee .
* Copyright ( c ) Andrew McDonald < andrew @ mcdonald . org . uk >
* Copyright ( c ) Jean - Francois Dive < jef @ linuxbe . org >
* Copyright ( c ) Mathias Krause < minipli @ googlemail . com >
* Copyright ( c ) Chandramouli Narayanan < mouli @ linux . intel . com >
*/
# include <crypto/internal/hash.h>
2019-03-12 22:12:49 -07:00
# include <crypto/internal/simd.h>
2014-07-29 17:14:14 +01:00
# include <linux/init.h>
# include <linux/module.h>
# include <linux/mm.h>
# include <linux/types.h>
# include <crypto/sha.h>
2015-04-09 12:55:40 +02:00
# include <crypto/sha1_base.h>
2014-07-29 17:14:14 +01:00
# include <asm/neon.h>
# include <asm/simd.h>
2015-04-09 12:55:39 +02:00
# include "sha1.h"
2014-07-29 17:14:14 +01:00
asmlinkage void sha1_transform_neon ( void * state_h , const char * data ,
unsigned int rounds ) ;
static int sha1_neon_update ( struct shash_desc * desc , const u8 * data ,
2015-04-09 12:55:40 +02:00
unsigned int len )
2014-07-29 17:14:14 +01:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
2019-03-12 22:12:49 -07:00
if ( ! crypto_simd_usable ( ) | |
2015-04-09 12:55:40 +02:00
( sctx - > count % SHA1_BLOCK_SIZE ) + len < SHA1_BLOCK_SIZE )
return sha1_update_arm ( desc , data , len ) ;
2014-07-29 17:14:14 +01:00
2015-04-09 12:55:40 +02:00
kernel_neon_begin ( ) ;
sha1_base_do_update ( desc , data , len ,
( sha1_block_fn * ) sha1_transform_neon ) ;
kernel_neon_end ( ) ;
2014-07-29 17:14:14 +01:00
return 0 ;
}
2015-04-09 12:55:40 +02:00
static int sha1_neon_finup ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
2014-07-29 17:14:14 +01:00
{
2019-03-12 22:12:49 -07:00
if ( ! crypto_simd_usable ( ) )
2015-04-09 12:55:40 +02:00
return sha1_finup_arm ( desc , data , len , out ) ;
2014-07-29 17:14:14 +01:00
2015-04-09 12:55:40 +02:00
kernel_neon_begin ( ) ;
if ( len )
sha1_base_do_update ( desc , data , len ,
( sha1_block_fn * ) sha1_transform_neon ) ;
sha1_base_do_finalize ( desc , ( sha1_block_fn * ) sha1_transform_neon ) ;
kernel_neon_end ( ) ;
2014-07-29 17:14:14 +01:00
2015-04-09 12:55:40 +02:00
return sha1_base_finish ( desc , out ) ;
2014-07-29 17:14:14 +01:00
}
2015-04-09 12:55:40 +02:00
static int sha1_neon_final ( struct shash_desc * desc , u8 * out )
2014-07-29 17:14:14 +01:00
{
2015-04-09 12:55:40 +02:00
return sha1_neon_finup ( desc , NULL , 0 , out ) ;
2014-07-29 17:14:14 +01:00
}
static struct shash_alg alg = {
. digestsize = SHA1_DIGEST_SIZE ,
2015-04-09 12:55:40 +02:00
. init = sha1_base_init ,
2014-07-29 17:14:14 +01:00
. update = sha1_neon_update ,
. final = sha1_neon_final ,
2015-04-09 12:55:40 +02:00
. finup = sha1_neon_finup ,
2014-07-29 17:14:14 +01:00
. descsize = sizeof ( struct sha1_state ) ,
. base = {
. cra_name = " sha1 " ,
. cra_driver_name = " sha1-neon " ,
. cra_priority = 250 ,
. cra_blocksize = SHA1_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} ;
static int __init sha1_neon_mod_init ( void )
{
if ( ! cpu_has_neon ( ) )
return - ENODEV ;
return crypto_register_shash ( & alg ) ;
}
static void __exit sha1_neon_mod_fini ( void )
{
crypto_unregister_shash ( & alg ) ;
}
module_init ( sha1_neon_mod_init ) ;
module_exit ( sha1_neon_mod_fini ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " SHA1 Secure Hash Algorithm, NEON accelerated " ) ;
2014-11-20 17:05:53 -08:00
MODULE_ALIAS_CRYPTO ( " sha1 " ) ;