2015-04-03 13:03:40 +03:00
/*
* Glue code for the SHA256 Secure Hash Algorithm assembly implementation
* using NEON instructions .
*
* Copyright <EFBFBD> 2015 Google Inc .
*
* This file is based on sha512_neon_glue . c :
* Copyright <EFBFBD> 2014 Jussi Kivilinna < jussi . kivilinna @ iki . fi >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 2 of the License , or ( at your option )
* any later version .
*
*/
# include <crypto/internal/hash.h>
# include <linux/cryptohash.h>
# include <linux/types.h>
# include <linux/string.h>
# include <crypto/sha.h>
2015-04-09 13:55:42 +03:00
# include <crypto/sha256_base.h>
2015-04-03 13:03:40 +03:00
# include <asm/byteorder.h>
# include <asm/simd.h>
# include <asm/neon.h>
2015-04-09 13:55:42 +03:00
2015-04-03 13:03:40 +03:00
# include "sha256_glue.h"
asmlinkage void sha256_block_data_order_neon ( u32 * digest , const void * data ,
2015-04-09 13:55:42 +03:00
unsigned int num_blks ) ;
2015-04-03 13:03:40 +03:00
2015-04-09 13:55:42 +03:00
static int sha256_update ( struct shash_desc * desc , const u8 * data ,
unsigned int len )
2015-04-03 13:03:40 +03:00
{
struct sha256_state * sctx = shash_desc_ctx ( desc ) ;
2015-04-09 13:55:42 +03:00
if ( ! may_use_simd ( ) | |
( sctx - > count % SHA256_BLOCK_SIZE ) + len < SHA256_BLOCK_SIZE )
return crypto_sha256_arm_update ( desc , data , len ) ;
2015-04-03 13:03:40 +03:00
2015-04-09 13:55:42 +03:00
kernel_neon_begin ( ) ;
sha256_base_do_update ( desc , data , len ,
( sha256_block_fn * ) sha256_block_data_order_neon ) ;
kernel_neon_end ( ) ;
2015-04-03 13:03:40 +03:00
return 0 ;
}
2015-04-09 13:55:42 +03:00
static int sha256_finup ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
2015-04-03 13:03:40 +03:00
{
2015-04-09 13:55:42 +03:00
if ( ! may_use_simd ( ) )
return crypto_sha256_arm_finup ( desc , data , len , out ) ;
kernel_neon_begin ( ) ;
if ( len )
sha256_base_do_update ( desc , data , len ,
( sha256_block_fn * ) sha256_block_data_order_neon ) ;
sha256_base_do_finalize ( desc ,
( sha256_block_fn * ) sha256_block_data_order_neon ) ;
kernel_neon_end ( ) ;
return sha256_base_finish ( desc , out ) ;
2015-04-03 13:03:40 +03:00
}
2015-04-09 13:55:42 +03:00
static int sha256_final ( struct shash_desc * desc , u8 * out )
2015-04-03 13:03:40 +03:00
{
2015-04-09 13:55:42 +03:00
return sha256_finup ( desc , NULL , 0 , out ) ;
2015-04-03 13:03:40 +03:00
}
struct shash_alg sha256_neon_algs [ ] = { {
. digestsize = SHA256_DIGEST_SIZE ,
2015-04-09 13:55:42 +03:00
. init = sha256_base_init ,
. update = sha256_update ,
. final = sha256_final ,
. finup = sha256_finup ,
2015-04-03 13:03:40 +03:00
. descsize = sizeof ( struct sha256_state ) ,
. base = {
. cra_name = " sha256 " ,
. cra_driver_name = " sha256-neon " ,
. cra_priority = 250 ,
. cra_flags = CRYPTO_ALG_TYPE_SHASH ,
. cra_blocksize = SHA256_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} , {
. digestsize = SHA224_DIGEST_SIZE ,
2015-04-09 13:55:42 +03:00
. init = sha224_base_init ,
. update = sha256_update ,
. final = sha256_final ,
. finup = sha256_finup ,
2015-04-03 13:03:40 +03:00
. descsize = sizeof ( struct sha256_state ) ,
. base = {
. cra_name = " sha224 " ,
. cra_driver_name = " sha224-neon " ,
. cra_priority = 250 ,
. cra_flags = CRYPTO_ALG_TYPE_SHASH ,
. cra_blocksize = SHA224_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} } ;