2005-04-16 15:20:36 -07:00
/*
2011-08-05 18:46:27 -07:00
* SHA1 routine optimized to do word accesses rather than byte accesses ,
* and to avoid unnecessary copies into the context array .
*
* This was based on the git SHA1 implementation .
2005-04-16 15:20:36 -07:00
*/
# include <linux/kernel.h>
2011-11-16 21:29:17 -05:00
# include <linux/export.h>
2011-08-05 18:46:27 -07:00
# include <linux/bitops.h>
2011-09-09 11:30:27 -07:00
# include <linux/cryptohash.h>
2022-01-11 18:58:43 +01:00
# include <linux/string.h>
2011-08-05 18:46:27 -07:00
# include <asm/unaligned.h>
2005-04-16 15:20:36 -07:00
2011-08-05 18:46:27 -07:00
/*
* If you have 32 registers or more , the compiler can ( and should )
* try to change the array [ ] accesses into registers . However , on
* machines with less than ~ 25 registers , that won ' t really work ,
* and at least gcc will make an unholy mess of it .
*
* So to avoid that mess which just slows things down , we force
* the stores to memory to actually happen ( we might be better off
* with a ' W ( t ) = ( val ) ; asm ( " " : " +m " ( W ( t ) ) ' there instead , as
* suggested by Artur Skawina - that will also make gcc unable to
* try to do the silly " optimize away loads " part because it won ' t
* see what the value will be ) .
*
* Ben Herrenschmidt reports that on PPC , the C version comes close
* to the optimized asm with this ( ie on PPC you don ' t want that
* ' volatile ' , since there are lots of registers ) .
*
* On ARM we get the best code generation by forcing a full memory barrier
* between each SHA_ROUND , otherwise gcc happily get wild with spilling and
* the stack frame size simply explode and performance goes down the drain .
*/
2005-04-16 15:20:36 -07:00
2011-08-05 18:46:27 -07:00
# ifdef CONFIG_X86
# define setW(x, val) (*(volatile __u32 *)&W(x) = (val))
# elif defined(CONFIG_ARM)
# define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
# else
# define setW(x, val) (W(x) = (val))
# endif
2005-04-16 15:20:36 -07:00
2011-08-05 18:46:27 -07:00
/* This "rolls" over the 512-bit array */
# define W(x) (array[(x)&15])
2005-04-16 15:20:36 -07:00
2011-08-05 18:46:27 -07:00
/*
* Where do we get the source from ? The first 16 iterations get it from
* the input data , the next mix it from the 512 - bit array .
*/
# define SHA_SRC(t) get_unaligned_be32((__u32 *)data + t)
# define SHA_MIX(t) rol32(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
# define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
__u32 TEMP = input ( t ) ; setW ( t , TEMP ) ; \
E + = TEMP + rol32 ( A , 5 ) + ( fn ) + ( constant ) ; \
2022-01-11 18:58:43 +01:00
B = ror32 ( B , 2 ) ; \
TEMP = E ; E = D ; D = C ; C = B ; B = A ; A = TEMP ; } while ( 0 )
2011-08-05 18:46:27 -07:00
# define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
# define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
# define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
# define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
# define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
2005-04-16 15:20:36 -07:00
2007-02-10 01:45:59 -08:00
/**
* sha_transform - single block SHA1 transform
2005-04-16 15:20:36 -07:00
*
* @ digest : 160 bit digest to update
* @ data : 512 bits of data to hash
2011-08-05 18:46:27 -07:00
* @ array : 16 words of workspace ( see note )
2005-04-16 15:20:36 -07:00
*
* This function generates a SHA1 digest for a single 512 - bit block .
* Be warned , it does not handle padding and message digest , do not
* confuse it with the full FIPS 180 - 1 digest algorithm for variable
* length messages .
*
* Note : If the hash is security sensitive , the caller should be sure
* to clear the workspace . This is left to the caller to avoid
* unnecessary clears between chained hashing operations .
*/
2011-08-05 18:46:27 -07:00
void sha_transform ( __u32 * digest , const char * data , __u32 * array )
2005-04-16 15:20:36 -07:00
{
2011-08-05 18:46:27 -07:00
__u32 A , B , C , D , E ;
2022-01-11 18:58:43 +01:00
unsigned int i = 0 ;
2011-08-05 18:46:27 -07:00
A = digest [ 0 ] ;
B = digest [ 1 ] ;
C = digest [ 2 ] ;
D = digest [ 3 ] ;
E = digest [ 4 ] ;
/* Round 1 - iterations 0-16 take their input from 'data' */
2022-01-11 18:58:43 +01:00
for ( ; i < 16 ; + + i )
T_0_15 ( i , A , B , C , D , E ) ;
2011-08-05 18:46:27 -07:00
/* Round 1 - tail. Input from 512-bit mixing array */
2022-01-11 18:58:43 +01:00
for ( ; i < 20 ; + + i )
T_16_19 ( i , A , B , C , D , E ) ;
2011-08-05 18:46:27 -07:00
/* Round 2 */
2022-01-11 18:58:43 +01:00
for ( ; i < 40 ; + + i )
T_20_39 ( i , A , B , C , D , E ) ;
2011-08-05 18:46:27 -07:00
/* Round 3 */
2022-01-11 18:58:43 +01:00
for ( ; i < 60 ; + + i )
T_40_59 ( i , A , B , C , D , E ) ;
2011-08-05 18:46:27 -07:00
/* Round 4 */
2022-01-11 18:58:43 +01:00
for ( ; i < 80 ; + + i )
T_60_79 ( i , A , B , C , D , E ) ;
2011-08-05 18:46:27 -07:00
digest [ 0 ] + = A ;
digest [ 1 ] + = B ;
digest [ 2 ] + = C ;
digest [ 3 ] + = D ;
digest [ 4 ] + = E ;
2005-04-16 15:20:36 -07:00
}
EXPORT_SYMBOL ( sha_transform ) ;
2007-02-10 01:45:59 -08:00
/**
* sha_init - initialize the vectors for a SHA1 digest
2005-04-16 15:20:36 -07:00
* @ buf : vector to initialize
*/
void sha_init ( __u32 * buf )
{
buf [ 0 ] = 0x67452301 ;
buf [ 1 ] = 0xefcdab89 ;
buf [ 2 ] = 0x98badcfe ;
buf [ 3 ] = 0x10325476 ;
buf [ 4 ] = 0xc3d2e1f0 ;
}
2015-03-23 23:35:59 +01:00
EXPORT_SYMBOL ( sha_init ) ;