X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=crypto%2Fhmac.c;h=0ad39c3749639e227bef876664ce3ff7ed147c2c;hb=745417e20684e4951afcabfe74583a3884e54980;hp=0f05be769c346c71d6ed3a70228d947c4699e50f;hpb=a6767721a563acb172c73f693fcf719b3b3d6716;p=safe%2Fjmp%2Flinux-2.6 diff --git a/crypto/hmac.c b/crypto/hmac.c index 0f05be7..0ad39c3 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -16,7 +16,8 @@ * */ -#include +#include +#include #include #include #include @@ -56,14 +57,35 @@ static int hmac_setkey(struct crypto_hash *parent, if (keylen > bs) { struct hash_desc desc; struct scatterlist tmp; + int tmplen; int err; desc.tfm = tfm; desc.flags = crypto_hash_get_flags(parent); desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; - sg_init_one(&tmp, inkey, keylen); - err = crypto_hash_digest(&desc, &tmp, keylen, digest); + err = crypto_hash_init(&desc); + if (err) + return err; + + tmplen = bs * 2 + ds; + sg_init_one(&tmp, ipad, tmplen); + + for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) { + memcpy(ipad, inkey, tmplen); + err = crypto_hash_update(&desc, &tmp, tmplen); + if (err) + return err; + } + + if (keylen) { + memcpy(ipad, inkey, keylen); + err = crypto_hash_update(&desc, &tmp, keylen); + if (err) + return err; + } + + err = crypto_hash_final(&desc, digest); if (err) return err; @@ -160,7 +182,7 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, sg_init_table(sg1, 2); sg_set_buf(sg1, ipad, bs); - sg_set_page(&sg1[1], (void *) sg, 0, 0); + scatterwalk_sg_chain(sg1, 2, sg); sg_init_table(sg2, 1); sg_set_buf(sg2, opad, bs + ds); @@ -204,6 +226,7 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) struct crypto_instance *inst; struct crypto_alg *alg; int err; + int ds; err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH); if (err) @@ -212,7 +235,16 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK); if (IS_ERR(alg)) - return ERR_PTR(PTR_ERR(alg)); + return ERR_CAST(alg); + + inst = ERR_PTR(-EINVAL); + ds = alg->cra_type == &crypto_hash_type ? + alg->cra_hash.digestsize : + alg->cra_type ? + __crypto_shash_alg(alg)->digestsize : + alg->cra_digest.dia_digestsize; + if (ds > alg->cra_blocksize) + goto out_put_alg; inst = crypto_alloc_instance("hmac", alg); if (IS_ERR(inst)) @@ -224,14 +256,10 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) 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_digest.dia_digestsize; + inst->alg.cra_hash.digestsize = ds; inst->alg.cra_ctxsize = sizeof(struct hmac_ctx) + - ALIGN(inst->alg.cra_blocksize * 2 + - inst->alg.cra_hash.digestsize, + ALIGN(inst->alg.cra_blocksize * 2 + ds, sizeof(void *)); inst->alg.cra_init = hmac_init_tfm;