async_tx: ensure the xor destination buffer remains dma-mapped
[sfrench/cifs-2.6.git] / crypto / hmac.c
index 0f05be769c346c71d6ed3a70228d947c4699e50f..14c6351e639d9484aa093fac191c7919a99127b4 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -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);
@@ -212,7 +234,7 @@ 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 = crypto_alloc_instance("hmac", alg);
        if (IS_ERR(inst))