crypto: powerpc/md5 - Use API partial block handling
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 18 Apr 2025 02:59:08 +0000 (10:59 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 23 Apr 2025 03:33:47 +0000 (11:33 +0800)
Use the Crypto API partial block handling.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
arch/powerpc/crypto/md5-glue.c

index c24f605033bdb336e9350d3149f8ea33daf700cb..204440a90cd84c6d5e3954b261317393fa554ba9 100644 (file)
@@ -8,25 +8,13 @@
  */
 
 #include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
 #include <crypto/md5.h>
-#include <asm/byteorder.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
 
 extern void ppc_md5_transform(u32 *state, const u8 *src, u32 blocks);
 
-static inline void ppc_md5_clear_context(struct md5_state *sctx)
-{
-       int count = sizeof(struct md5_state) >> 2;
-       u32 *ptr = (u32 *)sctx;
-
-       /* make sure we can clear the fast way */
-       BUILD_BUG_ON(sizeof(struct md5_state) % 4);
-       do { *ptr++ = 0; } while (--count);
-}
-
 static int ppc_md5_init(struct shash_desc *desc)
 {
        struct md5_state *sctx = shash_desc_ctx(desc);
@@ -44,79 +32,34 @@ static int ppc_md5_update(struct shash_desc *desc, const u8 *data,
                        unsigned int len)
 {
        struct md5_state *sctx = shash_desc_ctx(desc);
-       const unsigned int offset = sctx->byte_count & 0x3f;
-       unsigned int avail = 64 - offset;
-       const u8 *src = data;
 
-       sctx->byte_count += len;
-
-       if (avail > len) {
-               memcpy((char *)sctx->block + offset, src, len);
-               return 0;
-       }
-
-       if (offset) {
-               memcpy((char *)sctx->block + offset, src, avail);
-               ppc_md5_transform(sctx->hash, (const u8 *)sctx->block, 1);
-               len -= avail;
-               src += avail;
-       }
-
-       if (len > 63) {
-               ppc_md5_transform(sctx->hash, src, len >> 6);
-               src += len & ~0x3f;
-               len &= 0x3f;
-       }
-
-       memcpy((char *)sctx->block, src, len);
-       return 0;
+       sctx->byte_count += round_down(len, MD5_HMAC_BLOCK_SIZE);
+       ppc_md5_transform(sctx->hash, data, len >> 6);
+       return len - round_down(len, MD5_HMAC_BLOCK_SIZE);
 }
 
-static int ppc_md5_final(struct shash_desc *desc, u8 *out)
+static int ppc_md5_finup(struct shash_desc *desc, const u8 *src,
+                        unsigned int offset, u8 *out)
 {
        struct md5_state *sctx = shash_desc_ctx(desc);
-       const unsigned int offset = sctx->byte_count & 0x3f;
-       const u8 *src = (const u8 *)sctx->block;
-       u8 *p = (u8 *)src + offset;
-       int padlen = 55 - offset;
-       __le64 *pbits = (__le64 *)((char *)sctx->block + 56);
+       __le64 block[MD5_BLOCK_WORDS] = {};
+       u8 *p = memcpy(block, src, offset);
        __le32 *dst = (__le32 *)out;
+       __le64 *pbits;
 
+       src = p;
+       p += offset;
        *p++ = 0x80;
-
-       if (padlen < 0) {
-               memset(p, 0x00, padlen + sizeof (u64));
-               ppc_md5_transform(sctx->hash, src, 1);
-               p = (char *)sctx->block;
-               padlen = 56;
-       }
-
-       memset(p, 0, padlen);
+       sctx->byte_count += offset;
+       pbits = &block[(MD5_BLOCK_WORDS / (offset > 55 ? 1 : 2)) - 1];
        *pbits = cpu_to_le64(sctx->byte_count << 3);
-       ppc_md5_transform(sctx->hash, src, 1);
+       ppc_md5_transform(sctx->hash, src, (pbits - block + 1) / 8);
+       memzero_explicit(block, sizeof(block));
 
        dst[0] = cpu_to_le32(sctx->hash[0]);
        dst[1] = cpu_to_le32(sctx->hash[1]);
        dst[2] = cpu_to_le32(sctx->hash[2]);
        dst[3] = cpu_to_le32(sctx->hash[3]);
-
-       ppc_md5_clear_context(sctx);
-       return 0;
-}
-
-static int ppc_md5_export(struct shash_desc *desc, void *out)
-{
-       struct md5_state *sctx = shash_desc_ctx(desc);
-
-       memcpy(out, sctx, sizeof(*sctx));
-       return 0;
-}
-
-static int ppc_md5_import(struct shash_desc *desc, const void *in)
-{
-       struct md5_state *sctx = shash_desc_ctx(desc);
-
-       memcpy(sctx, in, sizeof(*sctx));
        return 0;
 }
 
@@ -124,15 +67,13 @@ static struct shash_alg alg = {
        .digestsize     =       MD5_DIGEST_SIZE,
        .init           =       ppc_md5_init,
        .update         =       ppc_md5_update,
-       .final          =       ppc_md5_final,
-       .export         =       ppc_md5_export,
-       .import         =       ppc_md5_import,
-       .descsize       =       sizeof(struct md5_state),
-       .statesize      =       sizeof(struct md5_state),
+       .finup          =       ppc_md5_finup,
+       .descsize       =       MD5_STATE_SIZE,
        .base           =       {
                .cra_name       =       "md5",
                .cra_driver_name=       "md5-ppc",
                .cra_priority   =       200,
+               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY,
                .cra_blocksize  =       MD5_HMAC_BLOCK_SIZE,
                .cra_module     =       THIS_MODULE,
        }