Hi:

[CRYPTO] digest: Added direct SG update and digest interface

This patch allows digest algorithms to provide an SG update function
as well as a direct digest function.  If the SG update function is
present, it will be used instead of the normal update interface.  That
is, the algorithm will be directly responsible for walking the SG list.

If the digest function is present, it will take precedence over the
generic digest function.  This can be used by hardware that is able
(and/or only able) to digest in one operation.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/crypto/digest.c b/crypto/digest.c
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -18,11 +18,6 @@
 #include <asm/scatterlist.h>
 #include "internal.h"
 
-static void init(struct crypto_tfm *tfm)
-{
-       tfm->__crt_alg->cra_digest.dia_init(tfm);
-}
-
 static void update(struct crypto_tfm *tfm,
                    struct scatterlist *sg, unsigned int nsg)
 {
@@ -87,9 +82,11 @@ static int setkey(struct crypto_tfm *tfm
 static void digest(struct crypto_tfm *tfm,
                    struct scatterlist *sg, unsigned int nsg, u8 *out)
 {
-       init(tfm);
-       update(tfm, sg, nsg);
-       final(tfm, out);
+       struct digest_tfm *ops = &tfm->crt_digest;
+
+       ops->dit_init(tfm);
+       ops->dit_update(tfm, sg, nsg);
+       ops->dit_final(tfm, out);
 }
 
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
@@ -100,11 +97,13 @@ int crypto_init_digest_flags(struct cryp
 int crypto_init_digest_ops(struct crypto_tfm *tfm)
 {
        struct digest_tfm *ops = &tfm->crt_digest;
+       struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
        
-       ops->dit_init   = init;
-       ops->dit_update = update;
-       ops->dit_final  = final;
-       ops->dit_digest = digest;
+       ops->dit_init   = dalg->dia_init;
+       ops->dit_update = dalg->dia_update_sg ?: update;
+       ops->dit_final  = crypto_tfm_alg_alignmask(tfm) ? dalg->dia_final :
+                                                         final;
+       ops->dit_digest = dalg->dia_digest ?: digest;
        ops->dit_setkey = setkey;
        
        return crypto_alloc_hmac_block(tfm);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -107,7 +107,11 @@ struct digest_alg {
        void (*dia_init)(struct crypto_tfm *tfm);
        void (*dia_update)(struct crypto_tfm *tfm, const u8 *data,
                           unsigned int len);
+       void (*dia_update_sg)(struct crypto_tfm *tfm, struct scatterlist *sg,
+                             unsigned int nsg);
        void (*dia_final)(struct crypto_tfm *tfm, u8 *out);
+       void (*dia_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
+                          unsigned int nsg, u8 *out);
        int (*dia_setkey)(struct crypto_tfm *tfm, const u8 *key,
                          unsigned int keylen, u32 *flags);
 };
-
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to