Re: crypto: chacha20poly1305 - Convert to new AEAD interface

2015-07-16 Thread Martin Willi
Herbert,

 This patch converts rfc7539 and rfc7539esp to the new AEAD interface.
 The test vectors for rfc7539esp have also been updated to include
 the IV.

Thanks for taking care of it, I haven't found the time yet to do it
myself. I can confirm that it works fine under IPsec load, so you may
add my:

Tested-by: Martin Willi mar...@strongswan.org

Regards
Martin

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


crypto: chacha20poly1305 - Convert to new AEAD interface

2015-07-15 Thread Herbert Xu
This patch converts rfc7539 and rfc7539esp to the new AEAD interface.
The test vectors for rfc7539esp have also been updated to include
the IV.

Signed-off-by: Herbert Xu herb...@gondor.apana.org.au
---

 crypto/chacha20poly1305.c |  213 +++---
 crypto/testmgr.h  |   10 +-
 2 files changed, 133 insertions(+), 90 deletions(-)

diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index 7b46ed7..8626093 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -60,12 +60,16 @@ struct chacha_req {
 };
 
 struct chachapoly_req_ctx {
+   struct scatterlist src[2];
+   struct scatterlist dst[2];
/* the key we generate for Poly1305 using Chacha20 */
u8 key[POLY1305_KEY_SIZE];
/* calculated Poly1305 tag */
u8 tag[POLY1305_DIGEST_SIZE];
/* length of data to en/decrypt, without ICV */
unsigned int cryptlen;
+   /* Actual AD, excluding IV */
+   unsigned int assoclen;
union {
struct poly_req poly;
struct chacha_req chacha;
@@ -98,7 +102,9 @@ static int poly_verify_tag(struct aead_request *req)
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
u8 tag[sizeof(rctx-tag)];
 
-   scatterwalk_map_and_copy(tag, req-src, rctx-cryptlen, sizeof(tag), 0);
+   scatterwalk_map_and_copy(tag, req-src,
+req-assoclen + rctx-cryptlen,
+sizeof(tag), 0);
if (crypto_memneq(tag, rctx-tag, sizeof(tag)))
return -EBADMSG;
return 0;
@@ -108,7 +114,8 @@ static int poly_copy_tag(struct aead_request *req)
 {
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
 
-   scatterwalk_map_and_copy(rctx-tag, req-dst, rctx-cryptlen,
+   scatterwalk_map_and_copy(rctx-tag, req-dst,
+req-assoclen + rctx-cryptlen,
 sizeof(rctx-tag), 1);
return 0;
 }
@@ -123,14 +130,24 @@ static int chacha_decrypt(struct aead_request *req)
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
struct chacha_req *creq = rctx-u.chacha;
+   struct scatterlist *src, *dst;
int err;
 
chacha_iv(creq-iv, req, 1);
 
+   sg_init_table(rctx-src, 2);
+   src = scatterwalk_ffwd(rctx-src, req-src, req-assoclen);
+   dst = src;
+
+   if (req-src != req-dst) {
+   sg_init_table(rctx-dst, 2);
+   dst = scatterwalk_ffwd(rctx-dst, req-dst, req-assoclen);
+   }
+
ablkcipher_request_set_callback(creq-req, aead_request_flags(req),
chacha_decrypt_done, req);
ablkcipher_request_set_tfm(creq-req, ctx-chacha);
-   ablkcipher_request_set_crypt(creq-req, req-src, req-dst,
+   ablkcipher_request_set_crypt(creq-req, src, dst,
 rctx-cryptlen, creq-iv);
err = crypto_ablkcipher_decrypt(creq-req);
if (err)
@@ -156,14 +173,15 @@ static void poly_tail_done(struct crypto_async_request 
*areq, int err)
 
 static int poly_tail(struct aead_request *req)
 {
-   struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+   struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+   struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
struct poly_req *preq = rctx-u.poly;
__le64 len;
int err;
 
sg_init_table(preq-src, 1);
-   len = cpu_to_le64(req-assoclen);
+   len = cpu_to_le64(rctx-assoclen);
memcpy(preq-tail.assoclen, len, sizeof(len));
len = cpu_to_le64(rctx-cryptlen);
memcpy(preq-tail.cryptlen, len, sizeof(len));
@@ -228,6 +246,9 @@ static int poly_cipher(struct aead_request *req)
if (rctx-cryptlen == req-cryptlen) /* encrypting */
crypt = req-dst;
 
+   sg_init_table(rctx-src, 2);
+   crypt = scatterwalk_ffwd(rctx-src, crypt, req-assoclen);
+
ahash_request_set_callback(preq-req, aead_request_flags(req),
   poly_cipher_done, req);
ahash_request_set_tfm(preq-req, ctx-poly);
@@ -253,7 +274,7 @@ static int poly_adpad(struct aead_request *req)
unsigned int padlen, bs = POLY1305_BLOCK_SIZE;
int err;
 
-   padlen = (bs - (req-assoclen % bs)) % bs;
+   padlen = (bs - (rctx-assoclen % bs)) % bs;
memset(preq-pad, 0, sizeof(preq-pad));
sg_init_table(preq-src, 1);
sg_set_buf(preq-src, preq-pad, padlen);
@@ -285,7 +306,7 @@ static int poly_ad(struct aead_request *req)
ahash_request_set_callback(preq-req, aead_request_flags(req),
   poly_ad_done, req);
ahash_request_set_tfm(preq-req, ctx-poly);
-   ahash_request_set_crypt(preq-req,