]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: rmd160 - Use API partial block handling
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 29 Apr 2025 08:42:20 +0000 (16:42 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Mon, 5 May 2025 10:20:44 +0000 (18:20 +0800)
Use the Crypto API partial block handling.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/rmd160.c

index c5fe4034b153cb4c84a97a0356fee314ab926728..890d29e46a76c6d9b66c77ee94554f93af399a4f 100644 (file)
@@ -9,18 +9,14 @@
  * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
  */
 #include <crypto/internal/hash.h>
-#include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
+#include <linux/string.h>
 #include "ripemd.h"
 
 struct rmd160_ctx {
        u64 byte_count;
        u32 state[5];
-       __le32 buffer[16];
 };
 
 #define K1  RMD_K1
@@ -265,72 +261,59 @@ static int rmd160_init(struct shash_desc *desc)
        rctx->state[3] = RMD_H3;
        rctx->state[4] = RMD_H4;
 
-       memset(rctx->buffer, 0, sizeof(rctx->buffer));
-
        return 0;
 }
 
 static int rmd160_update(struct shash_desc *desc, const u8 *data,
                         unsigned int len)
 {
+       int remain = len - round_down(len, RMD160_BLOCK_SIZE);
        struct rmd160_ctx *rctx = shash_desc_ctx(desc);
-       const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
-
-       rctx->byte_count += len;
+       __le32 buffer[RMD160_BLOCK_SIZE / 4];
 
-       /* Enough space in buffer? If so copy and we're done */
-       if (avail > len) {
-               memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
-                      data, len);
-               goto out;
-       }
-
-       memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
-              data, avail);
+       rctx->byte_count += len - remain;
 
-       rmd160_transform(rctx->state, rctx->buffer);
-       data += avail;
-       len -= avail;
-
-       while (len >= sizeof(rctx->buffer)) {
-               memcpy(rctx->buffer, data, sizeof(rctx->buffer));
-               rmd160_transform(rctx->state, rctx->buffer);
-               data += sizeof(rctx->buffer);
-               len -= sizeof(rctx->buffer);
-       }
+       do {
+               memcpy(buffer, data, sizeof(buffer));
+               rmd160_transform(rctx->state, buffer);
+               data += sizeof(buffer);
+               len -= sizeof(buffer);
+       } while (len >= sizeof(buffer));
 
-       memcpy(rctx->buffer, data, len);
-
-out:
-       return 0;
+       memzero_explicit(buffer, sizeof(buffer));
+       return remain;
 }
 
 /* Add padding and return the message digest. */
-static int rmd160_final(struct shash_desc *desc, u8 *out)
+static int rmd160_finup(struct shash_desc *desc, const u8 *src,
+                       unsigned int len, u8 *out)
 {
+       unsigned int bit_offset = RMD160_BLOCK_SIZE / 8 - 1;
        struct rmd160_ctx *rctx = shash_desc_ctx(desc);
-       u32 i, index, padlen;
-       __le64 bits;
+       union {
+               __le64 l64[RMD160_BLOCK_SIZE / 4];
+               __le32 l32[RMD160_BLOCK_SIZE / 2];
+               u8 u8[RMD160_BLOCK_SIZE * 2];
+       } block = {};
        __le32 *dst = (__le32 *)out;
-       static const u8 padding[64] = { 0x80, };
-
-       bits = cpu_to_le64(rctx->byte_count << 3);
-
-       /* Pad out to 56 mod 64 */
-       index = rctx->byte_count & 0x3f;
-       padlen = (index < 56) ? (56 - index) : ((64+56) - index);
-       rmd160_update(desc, padding, padlen);
+       u32 i;
 
-       /* Append length */
-       rmd160_update(desc, (const u8 *)&bits, sizeof(bits));
+       rctx->byte_count += len;
+       if (len >= bit_offset * 8)
+               bit_offset += RMD160_BLOCK_SIZE / 8;
+       memcpy(&block, src, len);
+       block.u8[len] = 0x80;
+       block.l64[bit_offset] = cpu_to_le64(rctx->byte_count << 3);
+
+       rmd160_transform(rctx->state, block.l32);
+       if (bit_offset > RMD160_BLOCK_SIZE / 8)
+               rmd160_transform(rctx->state,
+                                block.l32 + RMD160_BLOCK_SIZE / 4);
+       memzero_explicit(&block, sizeof(block));
 
        /* Store state in digest */
        for (i = 0; i < 5; i++)
                dst[i] = cpu_to_le32p(&rctx->state[i]);
-
-       /* Wipe context */
-       memset(rctx, 0, sizeof(*rctx));
-
        return 0;
 }
 
@@ -338,11 +321,12 @@ static struct shash_alg alg = {
        .digestsize     =       RMD160_DIGEST_SIZE,
        .init           =       rmd160_init,
        .update         =       rmd160_update,
-       .final          =       rmd160_final,
+       .finup          =       rmd160_finup,
        .descsize       =       sizeof(struct rmd160_ctx),
        .base           =       {
                .cra_name        =      "rmd160",
                .cra_driver_name =      "rmd160-generic",
+               .cra_flags       =      CRYPTO_AHASH_ALG_BLOCK_ONLY,
                .cra_blocksize   =      RMD160_BLOCK_SIZE,
                .cra_module      =      THIS_MODULE,
        }