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
