2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-09-13 23:00:49 +00:00
/*
* Cryptographic API .
*
* powerpc implementation of the SHA1 Secure Hash Algorithm .
*
* Derived from cryptoapi implementation , adapted for in - place
* scatterlist interface .
*
* Derived from " crypto/sha1.c "
* Copyright ( c ) Alan Smithee .
* Copyright ( c ) Andrew McDonald < andrew @ mcdonald . org . uk >
* Copyright ( c ) Jean - Francois Dive < jef @ linuxbe . org >
*/
# include <crypto/internal/hash.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/mm.h>
# include <linux/types.h>
2020-11-12 21:20:21 -08:00
# include <crypto/sha1.h>
2012-09-13 23:00:49 +00:00
# include <asm/byteorder.h>
2020-05-02 11:24:22 -07:00
void powerpc_sha_transform ( u32 * state , const u8 * src ) ;
2012-09-13 23:00:49 +00:00
2020-05-02 11:24:23 -07:00
static int powerpc_sha1_init ( struct shash_desc * desc )
2012-09-13 23:00:49 +00:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
* sctx = ( struct sha1_state ) {
. state = { SHA1_H0 , SHA1_H1 , SHA1_H2 , SHA1_H3 , SHA1_H4 } ,
} ;
return 0 ;
}
2020-05-02 11:24:23 -07:00
static int powerpc_sha1_update ( struct shash_desc * desc , const u8 * data ,
unsigned int len )
2012-09-13 23:00:49 +00:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
unsigned int partial , done ;
const u8 * src ;
partial = sctx - > count & 0x3f ;
sctx - > count + = len ;
done = 0 ;
src = data ;
if ( ( partial + len ) > 63 ) {
if ( partial ) {
done = - partial ;
memcpy ( sctx - > buffer + partial , data , done + 64 ) ;
src = sctx - > buffer ;
}
do {
2020-05-02 11:24:22 -07:00
powerpc_sha_transform ( sctx - > state , src ) ;
2012-09-13 23:00:49 +00:00
done + = 64 ;
src = data + done ;
} while ( done + 63 < len ) ;
partial = 0 ;
}
memcpy ( sctx - > buffer + partial , src , len - done ) ;
return 0 ;
}
/* Add padding and return the message digest. */
2020-05-02 11:24:23 -07:00
static int powerpc_sha1_final ( struct shash_desc * desc , u8 * out )
2012-09-13 23:00:49 +00:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
__be32 * dst = ( __be32 * ) out ;
u32 i , index , padlen ;
__be64 bits ;
static const u8 padding [ 64 ] = { 0x80 , } ;
bits = cpu_to_be64 ( sctx - > count < < 3 ) ;
/* Pad out to 56 mod 64 */
index = sctx - > count & 0x3f ;
padlen = ( index < 56 ) ? ( 56 - index ) : ( ( 64 + 56 ) - index ) ;
2020-05-02 11:24:23 -07:00
powerpc_sha1_update ( desc , padding , padlen ) ;
2012-09-13 23:00:49 +00:00
/* Append length */
2020-05-02 11:24:23 -07:00
powerpc_sha1_update ( desc , ( const u8 * ) & bits , sizeof ( bits ) ) ;
2012-09-13 23:00:49 +00:00
/* Store state in digest */
for ( i = 0 ; i < 5 ; i + + )
dst [ i ] = cpu_to_be32 ( sctx - > state [ i ] ) ;
/* Wipe context */
memset ( sctx , 0 , sizeof * sctx ) ;
return 0 ;
}
2020-05-02 11:24:23 -07:00
static int powerpc_sha1_export ( struct shash_desc * desc , void * out )
2012-09-13 23:00:49 +00:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
memcpy ( out , sctx , sizeof ( * sctx ) ) ;
return 0 ;
}
2020-05-02 11:24:23 -07:00
static int powerpc_sha1_import ( struct shash_desc * desc , const void * in )
2012-09-13 23:00:49 +00:00
{
struct sha1_state * sctx = shash_desc_ctx ( desc ) ;
memcpy ( sctx , in , sizeof ( * sctx ) ) ;
return 0 ;
}
static struct shash_alg alg = {
. digestsize = SHA1_DIGEST_SIZE ,
2020-05-02 11:24:23 -07:00
. init = powerpc_sha1_init ,
. update = powerpc_sha1_update ,
. final = powerpc_sha1_final ,
. export = powerpc_sha1_export ,
. import = powerpc_sha1_import ,
2012-09-13 23:00:49 +00:00
. descsize = sizeof ( struct sha1_state ) ,
. statesize = sizeof ( struct sha1_state ) ,
. base = {
. cra_name = " sha1 " ,
. cra_driver_name = " sha1-powerpc " ,
. cra_blocksize = SHA1_BLOCK_SIZE ,
. cra_module = THIS_MODULE ,
}
} ;
static int __init sha1_powerpc_mod_init ( void )
{
return crypto_register_shash ( & alg ) ;
}
static void __exit sha1_powerpc_mod_fini ( void )
{
crypto_unregister_shash ( & alg ) ;
}
module_init ( sha1_powerpc_mod_init ) ;
module_exit ( sha1_powerpc_mod_fini ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " SHA1 Secure Hash Algorithm " ) ;
2015-01-11 18:17:42 +01:00
MODULE_ALIAS_CRYPTO ( " sha1 " ) ;
2014-11-20 17:05:53 -08:00
MODULE_ALIAS_CRYPTO ( " sha1-powerpc " ) ;