2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2015-04-03 18:03:40 +08:00
/*
* Glue code for the SHA256 Secure Hash Algorithm assembly implementation
* using optimized ARM assembler and NEON instructions .
*
2018-08-23 17:01:26 -07:00
* Copyright © 2015 Google Inc .
2015-04-03 18:03:40 +08:00
*
* This file is based on sha256_ssse3_glue . c :
* Copyright ( C ) 2013 Intel Corporation
* Author : Tim Chen < tim . c . chen @ linux . intel . com >
*/
# include <crypto/internal/hash.h>
# include <linux/crypto.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/mm.h>
# include <linux/cryptohash.h>
# include <linux/types.h>
# include <linux/string.h>
# include <crypto/sha.h>
2015-04-09 12:55:42 +02:00
# include <crypto/sha256_base.h>
2015-04-03 18:03:40 +08:00
# include <asm/simd.h>
# include <asm/neon.h>
2015-04-09 12:55:42 +02:00
2015-04-03 18:03:40 +08:00
# include "sha256_glue.h"
asmlinkage void sha256_block_data_order ( u32 * digest , const void * data ,
2015-04-09 12:55:42 +02:00
unsigned int num_blks ) ;
2015-04-03 18:03:40 +08:00
2015-04-09 12:55:42 +02:00
int crypto_sha256_arm_update ( struct shash_desc * desc , const u8 * data ,
unsigned int len )
2015-04-03 18:03:40 +08:00
{
2015-04-09 12:55:42 +02:00
/* make sure casting to sha256_block_fn() is safe */
BUILD_BUG_ON ( offsetof ( struct sha256_state , state ) ! = 0 ) ;
2015-04-03 18:03:40 +08:00
2015-04-09 12:55:42 +02:00
return sha256_base_do_update ( desc , data , len ,
( sha256_block_fn * ) sha256_block_data_order ) ;
2015-04-03 18:03:40 +08:00
}
2015-04-09 12:55:42 +02:00
EXPORT_SYMBOL ( crypto_sha256_arm_update ) ;
2015-04-03 18:03:40 +08:00
2019-09-01 22:35:24 +02:00
static int crypto_sha256_arm_final ( struct shash_desc * desc , u8 * out )
2015-04-03 18:03:40 +08:00
{
2015-04-09 12:55:42 +02:00
sha256_base_do_finalize ( desc ,
( sha256_block_fn * ) sha256_block_data_order ) ;
return sha256_base_finish ( desc , out ) ;
2015-04-03 18:03:40 +08:00
}
2015-04-09 12:55:42 +02:00
int crypto_sha256_arm_finup ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
2015-04-03 18:03:40 +08:00
{
2015-04-09 12:55:42 +02:00
sha256_base_do_update ( desc , data , len ,
( sha256_block_fn * ) sha256_block_data_order ) ;
2019-09-01 22:35:24 +02:00
return crypto_sha256_arm_final ( desc , out ) ;
2015-04-03 18:03:40 +08:00
}
2015-04-09 12:55:42 +02:00
EXPORT_SYMBOL ( crypto_sha256_arm_finup ) ;
2015-04-03 18:03:40 +08:00
static struct shash_alg algs [ ] = { {
. digestsize = SHA256_DIGEST_SIZE ,
2015-04-09 12:55:42 +02:00
. init = sha256_base_init ,
. update = crypto_sha256_arm_update ,
2019-09-01 22:35:24 +02:00
. final = crypto_sha256_arm_final ,
2015-04-09 12:55:42 +02:00
. finup = crypto_sha256_arm_finup ,
2015-04-03 18:03:40 +08:00
. descsize = sizeof ( struct sha256_state ) ,
. base = {
. cra_name = " sha256 " ,
. cra_driver_name = " sha256-asm " ,
. cra_priority = 150 ,
. cra_blocksize = SHA256_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} , {
. digestsize = SHA224_DIGEST_SIZE ,
2015-04-09 12:55:42 +02:00
. init = sha224_base_init ,
. update = crypto_sha256_arm_update ,
2019-09-01 22:35:24 +02:00
. final = crypto_sha256_arm_final ,
2015-04-09 12:55:42 +02:00
. finup = crypto_sha256_arm_finup ,
2015-04-03 18:03:40 +08:00
. descsize = sizeof ( struct sha256_state ) ,
. base = {
. cra_name = " sha224 " ,
. cra_driver_name = " sha224-asm " ,
. cra_priority = 150 ,
. cra_blocksize = SHA224_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} } ;
static int __init sha256_mod_init ( void )
{
int res = crypto_register_shashes ( algs , ARRAY_SIZE ( algs ) ) ;
if ( res < 0 )
return res ;
if ( IS_ENABLED ( CONFIG_KERNEL_MODE_NEON ) & & cpu_has_neon ( ) ) {
res = crypto_register_shashes ( sha256_neon_algs ,
ARRAY_SIZE ( sha256_neon_algs ) ) ;
if ( res < 0 )
crypto_unregister_shashes ( algs , ARRAY_SIZE ( algs ) ) ;
}
return res ;
}
static void __exit sha256_mod_fini ( void )
{
crypto_unregister_shashes ( algs , ARRAY_SIZE ( algs ) ) ;
if ( IS_ENABLED ( CONFIG_KERNEL_MODE_NEON ) & & cpu_has_neon ( ) )
crypto_unregister_shashes ( sha256_neon_algs ,
ARRAY_SIZE ( sha256_neon_algs ) ) ;
}
module_init ( sha256_mod_init ) ;
module_exit ( sha256_mod_fini ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " SHA256 Secure Hash Algorithm (ARM), including NEON " ) ;
MODULE_ALIAS_CRYPTO ( " sha256 " ) ;