crypto: streebog - Use API partial block handling
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 29 Apr 2025 08:43:22 +0000 (16:43 +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/streebog_generic.c
include/crypto/streebog.h

index dc625ffc54ad7f57db883bf330588cd33888f902..99c07e0c10baa6f4dc29b7da224eb08b7df05500 100644 (file)
  */
 
 #include <crypto/internal/hash.h>
-#include <linux/module.h>
-#include <linux/crypto.h>
 #include <crypto/streebog.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
 
 static const struct streebog_uint512 buffer0 = { {
        0, 0, 0, 0, 0, 0, 0, 0
@@ -919,17 +920,6 @@ static int streebog_init(struct shash_desc *desc)
        return 0;
 }
 
-static void streebog_pad(struct streebog_state *ctx)
-{
-       if (ctx->fillsize >= STREEBOG_BLOCK_SIZE)
-               return;
-
-       memset(ctx->buffer + ctx->fillsize, 0,
-              sizeof(ctx->buffer) - ctx->fillsize);
-
-       ctx->buffer[ctx->fillsize] = 1;
-}
-
 static void streebog_add512(const struct streebog_uint512 *x,
                            const struct streebog_uint512 *y,
                            struct streebog_uint512 *r)
@@ -984,16 +974,23 @@ static void streebog_stage2(struct streebog_state *ctx, const u8 *data)
        streebog_add512(&ctx->Sigma, &m, &ctx->Sigma);
 }
 
-static void streebog_stage3(struct streebog_state *ctx)
+static void streebog_stage3(struct streebog_state *ctx, const u8 *src,
+                           unsigned int len)
 {
        struct streebog_uint512 buf = { { 0 } };
+       union {
+               u8 buffer[STREEBOG_BLOCK_SIZE];
+               struct streebog_uint512 m;
+       } u = {};
 
-       buf.qword[0] = cpu_to_le64(ctx->fillsize << 3);
-       streebog_pad(ctx);
+       buf.qword[0] = cpu_to_le64(len << 3);
+       memcpy(u.buffer, src, len);
+       u.buffer[len] = 1;
 
-       streebog_g(&ctx->h, &ctx->N, &ctx->m);
+       streebog_g(&ctx->h, &ctx->N, &u.m);
        streebog_add512(&ctx->N, &buf, &ctx->N);
-       streebog_add512(&ctx->Sigma, &ctx->m, &ctx->Sigma);
+       streebog_add512(&ctx->Sigma, &u.m, &ctx->Sigma);
+       memzero_explicit(&u, sizeof(u));
        streebog_g(&ctx->h, &buffer0, &ctx->N);
        streebog_g(&ctx->h, &buffer0, &ctx->Sigma);
        memcpy(&ctx->hash, &ctx->h, sizeof(struct streebog_uint512));
@@ -1003,42 +1000,22 @@ static int streebog_update(struct shash_desc *desc, const u8 *data,
                           unsigned int len)
 {
        struct streebog_state *ctx = shash_desc_ctx(desc);
-       size_t chunksize;
 
-       if (ctx->fillsize) {
-               chunksize = STREEBOG_BLOCK_SIZE - ctx->fillsize;
-               if (chunksize > len)
-                       chunksize = len;
-               memcpy(&ctx->buffer[ctx->fillsize], data, chunksize);
-               ctx->fillsize += chunksize;
-               len  -= chunksize;
-               data += chunksize;
-
-               if (ctx->fillsize == STREEBOG_BLOCK_SIZE) {
-                       streebog_stage2(ctx, ctx->buffer);
-                       ctx->fillsize = 0;
-               }
-       }
-
-       while (len >= STREEBOG_BLOCK_SIZE) {
+       do {
                streebog_stage2(ctx, data);
                data += STREEBOG_BLOCK_SIZE;
                len  -= STREEBOG_BLOCK_SIZE;
-       }
+       } while (len >= STREEBOG_BLOCK_SIZE);
 
-       if (len) {
-               memcpy(&ctx->buffer, data, len);
-               ctx->fillsize = len;
-       }
-       return 0;
+       return len;
 }
 
-static int streebog_final(struct shash_desc *desc, u8 *digest)
+static int streebog_finup(struct shash_desc *desc, const u8 *src,
+                         unsigned int len, u8 *digest)
 {
        struct streebog_state *ctx = shash_desc_ctx(desc);
 
-       streebog_stage3(ctx);
-       ctx->fillsize = 0;
+       streebog_stage3(ctx, src, len);
        if (crypto_shash_digestsize(desc->tfm) == STREEBOG256_DIGEST_SIZE)
                memcpy(digest, &ctx->hash.qword[4], STREEBOG256_DIGEST_SIZE);
        else
@@ -1050,11 +1027,12 @@ static struct shash_alg algs[2] = { {
        .digestsize     =       STREEBOG256_DIGEST_SIZE,
        .init           =       streebog_init,
        .update         =       streebog_update,
-       .final          =       streebog_final,
+       .finup          =       streebog_finup,
        .descsize       =       sizeof(struct streebog_state),
        .base           =       {
                .cra_name        =      "streebog256",
                .cra_driver_name =      "streebog256-generic",
+               .cra_flags       =      CRYPTO_AHASH_ALG_BLOCK_ONLY,
                .cra_blocksize   =      STREEBOG_BLOCK_SIZE,
                .cra_module      =      THIS_MODULE,
        },
@@ -1062,11 +1040,12 @@ static struct shash_alg algs[2] = { {
        .digestsize     =       STREEBOG512_DIGEST_SIZE,
        .init           =       streebog_init,
        .update         =       streebog_update,
-       .final          =       streebog_final,
+       .finup          =       streebog_finup,
        .descsize       =       sizeof(struct streebog_state),
        .base           =       {
                .cra_name        =      "streebog512",
                .cra_driver_name =      "streebog512-generic",
+               .cra_flags       =      CRYPTO_AHASH_ALG_BLOCK_ONLY,
                .cra_blocksize   =      STREEBOG_BLOCK_SIZE,
                .cra_module      =      THIS_MODULE,
        }
index cae1b4a0197137e1f28227cc18e7e40754e8c79f..570f720a113bdc0127b0ee088d3801f3c4194307 100644 (file)
@@ -23,15 +23,10 @@ struct streebog_uint512 {
 };
 
 struct streebog_state {
-       union {
-               u8 buffer[STREEBOG_BLOCK_SIZE];
-               struct streebog_uint512 m;
-       };
        struct streebog_uint512 hash;
        struct streebog_uint512 h;
        struct streebog_uint512 N;
        struct streebog_uint512 Sigma;
-       size_t fillsize;
 };
 
 #endif /* !_CRYPTO_STREEBOG_H_ */