2017-11-24 15:00:34 +01:00
// SPDX-License-Identifier: GPL-2.0+
2008-03-06 19:50:20 +08:00
/*
* Cryptographic API .
*
* s390 generic implementation of the SHA Secure Hash Algorithms .
*
* Copyright IBM Corp . 2007
* Author ( s ) : Jan Glauber ( jang @ de . ibm . com )
*/
2009-01-18 20:33:33 +11:00
# include <crypto/internal/hash.h>
2011-07-30 09:25:15 +02:00
# include <linux/module.h>
2016-03-17 15:22:12 +01:00
# include <asm/cpacf.h>
2008-03-06 19:50:20 +08:00
# include "sha.h"
2009-01-18 20:33:33 +11:00
int s390_sha_update ( struct shash_desc * desc , const u8 * data , unsigned int len )
2008-03-06 19:50:20 +08:00
{
2009-01-18 20:33:33 +11:00
struct s390_sha_ctx * ctx = shash_desc_ctx ( desc ) ;
unsigned int bsize = crypto_shash_blocksize ( desc - > tfm ) ;
2016-08-15 10:41:52 +02:00
unsigned int index , n ;
2008-03-06 19:50:20 +08:00
/* how much is already in the buffer? */
index = ctx - > count & ( bsize - 1 ) ;
ctx - > count + = len ;
if ( ( index + len ) < bsize )
goto store ;
/* process one stored block */
if ( index ) {
memcpy ( ctx - > buf + index , data , bsize - index ) ;
2016-08-15 10:41:52 +02:00
cpacf_kimd ( ctx - > func , ctx - > state , ctx - > buf , bsize ) ;
2008-03-06 19:50:20 +08:00
data + = bsize - index ;
len - = bsize - index ;
2011-02-07 20:26:06 +11:00
index = 0 ;
2008-03-06 19:50:20 +08:00
}
/* process as many blocks as possible */
if ( len > = bsize ) {
2016-08-15 10:41:52 +02:00
n = len & ~ ( bsize - 1 ) ;
cpacf_kimd ( ctx - > func , ctx - > state , data , n ) ;
data + = n ;
len - = n ;
2008-03-06 19:50:20 +08:00
}
store :
if ( len )
memcpy ( ctx - > buf + index , data , len ) ;
2009-01-18 20:33:33 +11:00
return 0 ;
2008-03-06 19:50:20 +08:00
}
EXPORT_SYMBOL_GPL ( s390_sha_update ) ;
2009-01-18 20:33:33 +11:00
int s390_sha_final ( struct shash_desc * desc , u8 * out )
2008-03-06 19:50:20 +08:00
{
2009-01-18 20:33:33 +11:00
struct s390_sha_ctx * ctx = shash_desc_ctx ( desc ) ;
unsigned int bsize = crypto_shash_blocksize ( desc - > tfm ) ;
2008-03-06 19:50:20 +08:00
u64 bits ;
2008-03-06 19:52:00 +08:00
unsigned int index , end , plen ;
2008-03-06 19:50:20 +08:00
2008-03-06 19:52:00 +08:00
/* SHA-512 uses 128 bit padding length */
plen = ( bsize > SHA256_BLOCK_SIZE ) ? 16 : 8 ;
2008-03-06 19:50:20 +08:00
/* must perform manual padding */
index = ctx - > count & ( bsize - 1 ) ;
2008-03-06 19:52:00 +08:00
end = ( index < bsize - plen ) ? bsize : ( 2 * bsize ) ;
2008-03-06 19:50:20 +08:00
/* start pad with 1 */
ctx - > buf [ index ] = 0x80 ;
index + + ;
/* pad with zeros */
memset ( ctx - > buf + index , 0x00 , end - index - 8 ) ;
2008-03-06 19:52:00 +08:00
/*
2010-01-29 15:57:49 +08:00
* Append message length . Well , SHA - 512 wants a 128 bit length value ,
2008-03-06 19:52:00 +08:00
* nevertheless we use u64 , should be enough for now . . .
*/
2008-03-06 19:50:20 +08:00
bits = ctx - > count * 8 ;
memcpy ( ctx - > buf + end - 8 , & bits , sizeof ( bits ) ) ;
2016-08-15 10:41:52 +02:00
cpacf_kimd ( ctx - > func , ctx - > state , ctx - > buf , end ) ;
2008-03-06 19:50:20 +08:00
/* copy digest to out */
2009-01-18 20:33:33 +11:00
memcpy ( out , ctx - > state , crypto_shash_digestsize ( desc - > tfm ) ) ;
2008-03-06 19:50:20 +08:00
/* wipe context */
memset ( ctx , 0 , sizeof * ctx ) ;
2009-01-18 20:33:33 +11:00
return 0 ;
2008-03-06 19:50:20 +08:00
}
EXPORT_SYMBOL_GPL ( s390_sha_final ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " s390 SHA cipher common functions " ) ;