X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=crypto%2Fxcbc.c;h=b63b633e549ce7d42370c7747cdc1fbad1f8fcb8;hb=3ba7f18cd9d974a5b1e75a68a4f0a50f1df8585e;hp=53e8ccbf0f5f514d9023431d9e15a47e53ed705e;hpb=4935361766cc73949fe032cd157d314f288922ba;p=linux-2.6-omap-h63xx.git diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 53e8ccbf0f5..b63b633e549 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -19,6 +19,7 @@ * Kazunori Miyazawa */ +#include #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include "internal.h" static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202, 0x02020202, 0x02020202, 0x02020202, @@ -116,13 +116,16 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); struct crypto_cipher *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); - unsigned int i = 0; - do { + for (;;) { + struct page *pg = sg_page(sg); + unsigned int offset = sg->offset; + unsigned int slen = sg->length; - struct page *pg = sg[i].page; - unsigned int offset = sg[i].offset; - unsigned int slen = sg[i].length; + if (unlikely(slen > nbytes)) + slen = nbytes; + + nbytes -= slen; while (slen > 0) { unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset); @@ -177,9 +180,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, offset = 0; pg++; } - nbytes-=sg[i].length; - i++; - } while (nbytes>0); + + if (!nbytes) + break; + sg = scatterwalk_sg_next(sg); + } return 0; } @@ -288,20 +293,27 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm) crypto_free_cipher(ctx->child); } -static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) +static struct crypto_instance *xcbc_alloc(struct rtattr **tb) { struct crypto_instance *inst; struct crypto_alg *alg; - alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, - CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC); + int err; + + err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH); + if (err) + return ERR_PTR(err); + + alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, + CRYPTO_ALG_TYPE_MASK); if (IS_ERR(alg)) - return ERR_PTR(PTR_ERR(alg)); + return ERR_CAST(alg); switch(alg->cra_blocksize) { case 16: break; default: - return ERR_PTR(PTR_ERR(alg)); + inst = ERR_PTR(-EINVAL); + goto out_put_alg; } inst = crypto_alloc_instance("xcbc", alg); @@ -314,10 +326,7 @@ static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) inst->alg.cra_alignmask = alg->cra_alignmask; inst->alg.cra_type = &crypto_hash_type; - inst->alg.cra_hash.digestsize = - (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == - CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize : - alg->cra_blocksize; + inst->alg.cra_hash.digestsize = alg->cra_blocksize; inst->alg.cra_ctxsize = sizeof(struct crypto_xcbc_ctx) + ALIGN(inst->alg.cra_blocksize * 3, sizeof(void *)); inst->alg.cra_init = xcbc_init_tfm;