21
21
*/
22
22
#include <crypto/internal/hash.h>
23
23
#include <linux/init.h>
24
+ #include <linux/kernel.h>
24
25
#include <linux/module.h>
25
- #include <linux/mm.h>
26
- #include <asm/byteorder.h>
27
- #include <linux/types.h>
26
+ #include <linux/string.h>
27
+ #include <linux/unaligned.h>
28
28
29
29
#define WP512_DIGEST_SIZE 64
30
30
#define WP384_DIGEST_SIZE 48
37
37
38
38
struct wp512_ctx {
39
39
u8 bitLength [WP512_LENGTHBYTES ];
40
- u8 buffer [WP512_BLOCK_SIZE ];
41
- int bufferBits ;
42
- int bufferPos ;
43
40
u64 hash [WP512_DIGEST_SIZE /8 ];
44
41
};
45
42
@@ -779,16 +776,16 @@ static const u64 rc[WHIRLPOOL_ROUNDS] = {
779
776
* The core Whirlpool transform.
780
777
*/
781
778
782
- static __no_kmsan_checks void wp512_process_buffer (struct wp512_ctx * wctx ) {
779
+ static __no_kmsan_checks void wp512_process_buffer (struct wp512_ctx * wctx ,
780
+ const u8 * buffer ) {
783
781
int i , r ;
784
782
u64 K [8 ]; /* the round key */
785
783
u64 block [8 ]; /* mu(buffer) */
786
784
u64 state [8 ]; /* the cipher state */
787
785
u64 L [8 ];
788
- const __be64 * buffer = (const __be64 * )wctx -> buffer ;
789
786
790
787
for (i = 0 ; i < 8 ; i ++ )
791
- block [i ] = be64_to_cpu (buffer [ i ] );
788
+ block [i ] = get_unaligned_be64 (buffer + i * 8 );
792
789
793
790
state [0 ] = block [0 ] ^ (K [0 ] = wctx -> hash [0 ]);
794
791
state [1 ] = block [1 ] ^ (K [1 ] = wctx -> hash [1 ]);
@@ -991,93 +988,61 @@ static int wp512_init(struct shash_desc *desc) {
991
988
int i ;
992
989
993
990
memset (wctx -> bitLength , 0 , 32 );
994
- wctx -> bufferBits = wctx -> bufferPos = 0 ;
995
- wctx -> buffer [0 ] = 0 ;
996
991
for (i = 0 ; i < 8 ; i ++ ) {
997
992
wctx -> hash [i ] = 0L ;
998
993
}
999
994
1000
995
return 0 ;
1001
996
}
1002
997
1003
- static int wp512_update (struct shash_desc * desc , const u8 * source ,
1004
- unsigned int len )
998
+ static void wp512_add_length (u8 * bitLength , u64 value )
1005
999
{
1006
- struct wp512_ctx * wctx = shash_desc_ctx (desc );
1007
- int sourcePos = 0 ;
1008
- unsigned int bits_len = len * 8 ; // convert to number of bits
1009
- int sourceGap = (8 - ((int )bits_len & 7 )) & 7 ;
1010
- int bufferRem = wctx -> bufferBits & 7 ;
1000
+ u32 carry ;
1011
1001
int i ;
1012
- u32 b , carry ;
1013
- u8 * buffer = wctx -> buffer ;
1014
- u8 * bitLength = wctx -> bitLength ;
1015
- int bufferBits = wctx -> bufferBits ;
1016
- int bufferPos = wctx -> bufferPos ;
1017
1002
1018
- u64 value = bits_len ;
1019
1003
for (i = 31 , carry = 0 ; i >= 0 && (carry != 0 || value != 0ULL ); i -- ) {
1020
1004
carry += bitLength [i ] + ((u32 )value & 0xff );
1021
1005
bitLength [i ] = (u8 )carry ;
1022
1006
carry >>= 8 ;
1023
1007
value >>= 8 ;
1024
1008
}
1025
- while (bits_len > 8 ) {
1026
- b = ((source [sourcePos ] << sourceGap ) & 0xff ) |
1027
- ((source [sourcePos + 1 ] & 0xff ) >> (8 - sourceGap ));
1028
- buffer [bufferPos ++ ] |= (u8 )(b >> bufferRem );
1029
- bufferBits += 8 - bufferRem ;
1030
- if (bufferBits == WP512_BLOCK_SIZE * 8 ) {
1031
- wp512_process_buffer (wctx );
1032
- bufferBits = bufferPos = 0 ;
1033
- }
1034
- buffer [bufferPos ] = b << (8 - bufferRem );
1035
- bufferBits += bufferRem ;
1036
- bits_len -= 8 ;
1037
- sourcePos ++ ;
1038
- }
1039
- if (bits_len > 0 ) {
1040
- b = (source [sourcePos ] << sourceGap ) & 0xff ;
1041
- buffer [bufferPos ] |= b >> bufferRem ;
1042
- } else {
1043
- b = 0 ;
1044
- }
1045
- if (bufferRem + bits_len < 8 ) {
1046
- bufferBits += bits_len ;
1047
- } else {
1048
- bufferPos ++ ;
1049
- bufferBits += 8 - bufferRem ;
1050
- bits_len -= 8 - bufferRem ;
1051
- if (bufferBits == WP512_BLOCK_SIZE * 8 ) {
1052
- wp512_process_buffer (wctx );
1053
- bufferBits = bufferPos = 0 ;
1054
- }
1055
- buffer [bufferPos ] = b << (8 - bufferRem );
1056
- bufferBits += (int )bits_len ;
1057
- }
1009
+ }
1058
1010
1059
- wctx -> bufferBits = bufferBits ;
1060
- wctx -> bufferPos = bufferPos ;
1011
+ static int wp512_update (struct shash_desc * desc , const u8 * source ,
1012
+ unsigned int len )
1013
+ {
1014
+ struct wp512_ctx * wctx = shash_desc_ctx (desc );
1015
+ unsigned int remain = len % WP512_BLOCK_SIZE ;
1016
+ u64 bits_len = (len - remain ) * 8ull ;
1017
+ u8 * bitLength = wctx -> bitLength ;
1061
1018
1062
- return 0 ;
1019
+ wp512_add_length (bitLength , bits_len );
1020
+ do {
1021
+ wp512_process_buffer (wctx , source );
1022
+ source += WP512_BLOCK_SIZE ;
1023
+ bits_len -= WP512_BLOCK_SIZE * 8 ;
1024
+ } while (bits_len );
1025
+
1026
+ return remain ;
1063
1027
}
1064
1028
1065
- static int wp512_final (struct shash_desc * desc , u8 * out )
1029
+ static int wp512_finup (struct shash_desc * desc , const u8 * src ,
1030
+ unsigned int bufferPos , u8 * out )
1066
1031
{
1067
1032
struct wp512_ctx * wctx = shash_desc_ctx (desc );
1068
1033
int i ;
1069
- u8 * buffer = wctx -> buffer ;
1070
1034
u8 * bitLength = wctx -> bitLength ;
1071
- int bufferBits = wctx -> bufferBits ;
1072
- int bufferPos = wctx -> bufferPos ;
1073
1035
__be64 * digest = (__be64 * )out ;
1036
+ u8 buffer [WP512_BLOCK_SIZE ];
1074
1037
1075
- buffer [bufferPos ] |= 0x80U >> (bufferBits & 7 );
1038
+ wp512_add_length (bitLength , bufferPos * 8 );
1039
+ memcpy (buffer , src , bufferPos );
1040
+ buffer [bufferPos ] = 0x80U ;
1076
1041
bufferPos ++ ;
1077
1042
if (bufferPos > WP512_BLOCK_SIZE - WP512_LENGTHBYTES ) {
1078
1043
if (bufferPos < WP512_BLOCK_SIZE )
1079
1044
memset (& buffer [bufferPos ], 0 , WP512_BLOCK_SIZE - bufferPos );
1080
- wp512_process_buffer (wctx );
1045
+ wp512_process_buffer (wctx , buffer );
1081
1046
bufferPos = 0 ;
1082
1047
}
1083
1048
if (bufferPos < WP512_BLOCK_SIZE - WP512_LENGTHBYTES )
@@ -1086,31 +1051,32 @@ static int wp512_final(struct shash_desc *desc, u8 *out)
1086
1051
bufferPos = WP512_BLOCK_SIZE - WP512_LENGTHBYTES ;
1087
1052
memcpy (& buffer [WP512_BLOCK_SIZE - WP512_LENGTHBYTES ],
1088
1053
bitLength , WP512_LENGTHBYTES );
1089
- wp512_process_buffer (wctx );
1054
+ wp512_process_buffer (wctx , buffer );
1055
+ memzero_explicit (buffer , sizeof (buffer ));
1090
1056
for (i = 0 ; i < WP512_DIGEST_SIZE /8 ; i ++ )
1091
1057
digest [i ] = cpu_to_be64 (wctx -> hash [i ]);
1092
- wctx -> bufferBits = bufferBits ;
1093
- wctx -> bufferPos = bufferPos ;
1094
1058
1095
1059
return 0 ;
1096
1060
}
1097
1061
1098
- static int wp384_final (struct shash_desc * desc , u8 * out )
1062
+ static int wp384_finup (struct shash_desc * desc , const u8 * src ,
1063
+ unsigned int len , u8 * out )
1099
1064
{
1100
1065
u8 D [64 ];
1101
1066
1102
- wp512_final (desc , D );
1067
+ wp512_finup (desc , src , len , D );
1103
1068
memcpy (out , D , WP384_DIGEST_SIZE );
1104
1069
memzero_explicit (D , WP512_DIGEST_SIZE );
1105
1070
1106
1071
return 0 ;
1107
1072
}
1108
1073
1109
- static int wp256_final (struct shash_desc * desc , u8 * out )
1074
+ static int wp256_finup (struct shash_desc * desc , const u8 * src ,
1075
+ unsigned int len , u8 * out )
1110
1076
{
1111
1077
u8 D [64 ];
1112
1078
1113
- wp512_final (desc , D );
1079
+ wp512_finup (desc , src , len , D );
1114
1080
memcpy (out , D , WP256_DIGEST_SIZE );
1115
1081
memzero_explicit (D , WP512_DIGEST_SIZE );
1116
1082
@@ -1121,35 +1087,38 @@ static struct shash_alg wp_algs[3] = { {
1121
1087
.digestsize = WP512_DIGEST_SIZE ,
1122
1088
.init = wp512_init ,
1123
1089
.update = wp512_update ,
1124
- .final = wp512_final ,
1090
+ .finup = wp512_finup ,
1125
1091
.descsize = sizeof (struct wp512_ctx ),
1126
1092
.base = {
1127
1093
.cra_name = "wp512" ,
1128
1094
.cra_driver_name = "wp512-generic" ,
1095
+ .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY ,
1129
1096
.cra_blocksize = WP512_BLOCK_SIZE ,
1130
1097
.cra_module = THIS_MODULE ,
1131
1098
}
1132
1099
}, {
1133
1100
.digestsize = WP384_DIGEST_SIZE ,
1134
1101
.init = wp512_init ,
1135
1102
.update = wp512_update ,
1136
- .final = wp384_final ,
1103
+ .finup = wp384_finup ,
1137
1104
.descsize = sizeof (struct wp512_ctx ),
1138
1105
.base = {
1139
1106
.cra_name = "wp384" ,
1140
1107
.cra_driver_name = "wp384-generic" ,
1108
+ .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY ,
1141
1109
.cra_blocksize = WP512_BLOCK_SIZE ,
1142
1110
.cra_module = THIS_MODULE ,
1143
1111
}
1144
1112
}, {
1145
1113
.digestsize = WP256_DIGEST_SIZE ,
1146
1114
.init = wp512_init ,
1147
1115
.update = wp512_update ,
1148
- .final = wp256_final ,
1116
+ .finup = wp256_finup ,
1149
1117
.descsize = sizeof (struct wp512_ctx ),
1150
1118
.base = {
1151
1119
.cra_name = "wp256" ,
1152
1120
.cra_driver_name = "wp256-generic" ,
1121
+ .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY ,
1153
1122
.cra_blocksize = WP512_BLOCK_SIZE ,
1154
1123
.cra_module = THIS_MODULE ,
1155
1124
}
0 commit comments