Skip to content

Commit 20d7175

Browse files
committed
crypto: wp512 - Use API partial block handling
Use the Crypto API partial block handling. Signed-off-by: Herbert Xu <[email protected]> Tested-by: Milan Broz <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent df29f60 commit 20d7175

File tree

1 file changed

+45
-76
lines changed

1 file changed

+45
-76
lines changed

crypto/wp512.c

Lines changed: 45 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
*/
2222
#include <crypto/internal/hash.h>
2323
#include <linux/init.h>
24+
#include <linux/kernel.h>
2425
#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>
2828

2929
#define WP512_DIGEST_SIZE 64
3030
#define WP384_DIGEST_SIZE 48
@@ -37,9 +37,6 @@
3737

3838
struct wp512_ctx {
3939
u8 bitLength[WP512_LENGTHBYTES];
40-
u8 buffer[WP512_BLOCK_SIZE];
41-
int bufferBits;
42-
int bufferPos;
4340
u64 hash[WP512_DIGEST_SIZE/8];
4441
};
4542

@@ -779,16 +776,16 @@ static const u64 rc[WHIRLPOOL_ROUNDS] = {
779776
* The core Whirlpool transform.
780777
*/
781778

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) {
783781
int i, r;
784782
u64 K[8]; /* the round key */
785783
u64 block[8]; /* mu(buffer) */
786784
u64 state[8]; /* the cipher state */
787785
u64 L[8];
788-
const __be64 *buffer = (const __be64 *)wctx->buffer;
789786

790787
for (i = 0; i < 8; i++)
791-
block[i] = be64_to_cpu(buffer[i]);
788+
block[i] = get_unaligned_be64(buffer + i * 8);
792789

793790
state[0] = block[0] ^ (K[0] = wctx->hash[0]);
794791
state[1] = block[1] ^ (K[1] = wctx->hash[1]);
@@ -991,93 +988,61 @@ static int wp512_init(struct shash_desc *desc) {
991988
int i;
992989

993990
memset(wctx->bitLength, 0, 32);
994-
wctx->bufferBits = wctx->bufferPos = 0;
995-
wctx->buffer[0] = 0;
996991
for (i = 0; i < 8; i++) {
997992
wctx->hash[i] = 0L;
998993
}
999994

1000995
return 0;
1001996
}
1002997

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)
1005999
{
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;
10111001
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;
10171002

1018-
u64 value = bits_len;
10191003
for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != 0ULL); i--) {
10201004
carry += bitLength[i] + ((u32)value & 0xff);
10211005
bitLength[i] = (u8)carry;
10221006
carry >>= 8;
10231007
value >>= 8;
10241008
}
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+
}
10581010

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;
10611018

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;
10631027
}
10641028

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)
10661031
{
10671032
struct wp512_ctx *wctx = shash_desc_ctx(desc);
10681033
int i;
1069-
u8 *buffer = wctx->buffer;
10701034
u8 *bitLength = wctx->bitLength;
1071-
int bufferBits = wctx->bufferBits;
1072-
int bufferPos = wctx->bufferPos;
10731035
__be64 *digest = (__be64 *)out;
1036+
u8 buffer[WP512_BLOCK_SIZE];
10741037

1075-
buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
1038+
wp512_add_length(bitLength, bufferPos * 8);
1039+
memcpy(buffer, src, bufferPos);
1040+
buffer[bufferPos] = 0x80U;
10761041
bufferPos++;
10771042
if (bufferPos > WP512_BLOCK_SIZE - WP512_LENGTHBYTES) {
10781043
if (bufferPos < WP512_BLOCK_SIZE)
10791044
memset(&buffer[bufferPos], 0, WP512_BLOCK_SIZE - bufferPos);
1080-
wp512_process_buffer(wctx);
1045+
wp512_process_buffer(wctx, buffer);
10811046
bufferPos = 0;
10821047
}
10831048
if (bufferPos < WP512_BLOCK_SIZE - WP512_LENGTHBYTES)
@@ -1086,31 +1051,32 @@ static int wp512_final(struct shash_desc *desc, u8 *out)
10861051
bufferPos = WP512_BLOCK_SIZE - WP512_LENGTHBYTES;
10871052
memcpy(&buffer[WP512_BLOCK_SIZE - WP512_LENGTHBYTES],
10881053
bitLength, WP512_LENGTHBYTES);
1089-
wp512_process_buffer(wctx);
1054+
wp512_process_buffer(wctx, buffer);
1055+
memzero_explicit(buffer, sizeof(buffer));
10901056
for (i = 0; i < WP512_DIGEST_SIZE/8; i++)
10911057
digest[i] = cpu_to_be64(wctx->hash[i]);
1092-
wctx->bufferBits = bufferBits;
1093-
wctx->bufferPos = bufferPos;
10941058

10951059
return 0;
10961060
}
10971061

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)
10991064
{
11001065
u8 D[64];
11011066

1102-
wp512_final(desc, D);
1067+
wp512_finup(desc, src, len, D);
11031068
memcpy(out, D, WP384_DIGEST_SIZE);
11041069
memzero_explicit(D, WP512_DIGEST_SIZE);
11051070

11061071
return 0;
11071072
}
11081073

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)
11101076
{
11111077
u8 D[64];
11121078

1113-
wp512_final(desc, D);
1079+
wp512_finup(desc, src, len, D);
11141080
memcpy(out, D, WP256_DIGEST_SIZE);
11151081
memzero_explicit(D, WP512_DIGEST_SIZE);
11161082

@@ -1121,35 +1087,38 @@ static struct shash_alg wp_algs[3] = { {
11211087
.digestsize = WP512_DIGEST_SIZE,
11221088
.init = wp512_init,
11231089
.update = wp512_update,
1124-
.final = wp512_final,
1090+
.finup = wp512_finup,
11251091
.descsize = sizeof(struct wp512_ctx),
11261092
.base = {
11271093
.cra_name = "wp512",
11281094
.cra_driver_name = "wp512-generic",
1095+
.cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY,
11291096
.cra_blocksize = WP512_BLOCK_SIZE,
11301097
.cra_module = THIS_MODULE,
11311098
}
11321099
}, {
11331100
.digestsize = WP384_DIGEST_SIZE,
11341101
.init = wp512_init,
11351102
.update = wp512_update,
1136-
.final = wp384_final,
1103+
.finup = wp384_finup,
11371104
.descsize = sizeof(struct wp512_ctx),
11381105
.base = {
11391106
.cra_name = "wp384",
11401107
.cra_driver_name = "wp384-generic",
1108+
.cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY,
11411109
.cra_blocksize = WP512_BLOCK_SIZE,
11421110
.cra_module = THIS_MODULE,
11431111
}
11441112
}, {
11451113
.digestsize = WP256_DIGEST_SIZE,
11461114
.init = wp512_init,
11471115
.update = wp512_update,
1148-
.final = wp256_final,
1116+
.finup = wp256_finup,
11491117
.descsize = sizeof(struct wp512_ctx),
11501118
.base = {
11511119
.cra_name = "wp256",
11521120
.cra_driver_name = "wp256-generic",
1121+
.cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY,
11531122
.cra_blocksize = WP512_BLOCK_SIZE,
11541123
.cra_module = THIS_MODULE,
11551124
}

0 commit comments

Comments
 (0)