Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM

Previous thread: seeing strange values for tcp sk_rmem_alloc by Chris Friesen on Tuesday, December 1, 2009 - 9:16 am. (8 messages)

Next thread: Re: [linux-pm] intermittent suspend problem again by Ferenc Wagner on Tuesday, December 1, 2009 - 10:46 am. (3 messages)
From: Tobias Brunner
Date: Tuesday, December 1, 2009 - 9:49 am

This patch adds the RFC4543 (GMAC) wrapper for GCM similar to the
existing RFC4106 wrapper. The main differences between GCM and GMAC are
the contents of the AAD and that the plaintext is empty for the latter.

Signed-off-by: Tobias Brunner <tobias@strongswan.org>
---
 crypto/gcm.c            |  275 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pfkeyv2.h |    1 +
 net/xfrm/xfrm_algo.c    |   16 +++
 3 files changed, 292 insertions(+), 0 deletions(-)

diff --git a/crypto/gcm.c b/crypto/gcm.c
index 5fc3292..b097eb4 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -37,6 +37,15 @@ struct crypto_rfc4106_ctx {
 	u8 nonce[4];
 };
 
+struct crypto_rfc4543_ctx {
+	struct crypto_aead *child;
+	u8 nonce[4];
+	u8 auth_tag[16];
+	struct scatterlist cipher[1];
+	struct scatterlist payload[2];
+	struct scatterlist assoc[2];
+};
+
 struct crypto_gcm_ghash_ctx {
 	unsigned int cryptlen;
 	struct scatterlist *src;
@@ -1008,6 +1017,264 @@ static struct crypto_template crypto_rfc4106_tmpl = {
 	.module = THIS_MODULE,
 };
 
+static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key,
+				 unsigned int keylen)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
+	struct crypto_aead *child = ctx->child;
+	int err;
+
+	if (keylen < 4)
+		return -EINVAL;
+
+	keylen -= 4;
+	memcpy(ctx->nonce, key + keylen, 4);
+
+	crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
+				     CRYPTO_TFM_REQ_MASK);
+	err = crypto_aead_setkey(child, key, keylen);
+	crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
+				      CRYPTO_TFM_RES_MASK);
+
+	return err;
+}
+
+static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
+				      unsigned int authsize)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
+
+	if (authsize != 16)
+		return -EINVAL;
+
+	return crypto_aead_setauthsize(ctx->child, authsize);
+}
+
+/* this is the same as ...
From: David Miller
Date: Tuesday, December 1, 2009 - 4:51 pm

From: Tobias Brunner <tobias@strongswan.org>

Herbert, you got this one?

Thanks.
--

From: Herbert Xu
Date: Tuesday, December 1, 2009 - 5:53 pm

Sure I'll pick it up.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--

From: Herbert Xu
Date: Wednesday, December 2, 2009 - 8:50 pm

This field needs to be aligned to whatever alignment needed by
the underlying cipher algorithm (currently the biggest is padlock
which needs 16-byte alignment).

See for example how rfc4543/gcm handles it.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--

From: Tobias Brunner
Date: Friday, December 4, 2009 - 9:31 am

Didn't realize that, thanks. I fixed the aligning according to
how it's done in GCM.

Regards,
Tobias

-------------8<-------------8<-------------

This patch adds the RFC4543 (GMAC) wrapper for GCM similar to the
existing RFC4106 wrapper. The main differences between GCM and GMAC are
the contents of the AAD and that the plaintext is empty for the latter.

Signed-off-by: Tobias Brunner <tobias@strongswan.org>

---
 crypto/gcm.c            |  287 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pfkeyv2.h |    1 +
 net/xfrm/xfrm_algo.c    |   16 +++
 3 files changed, 304 insertions(+), 0 deletions(-)

diff --git a/crypto/gcm.c b/crypto/gcm.c
index 5fc3292..7d3fba8 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -37,6 +37,19 @@ struct crypto_rfc4106_ctx {
 	u8 nonce[4];
 };
 
+struct crypto_rfc4543_ctx {
+	struct crypto_aead *child;
+	u8 nonce[4];
+};
+
+struct crypto_rfc4543_req_ctx {
+	u8 auth_tag[16];
+	struct scatterlist cipher[1];
+	struct scatterlist payload[2];
+	struct scatterlist assoc[2];
+	struct aead_request subreq;
+};
+
 struct crypto_gcm_ghash_ctx {
 	unsigned int cryptlen;
 	struct scatterlist *src;
@@ -1008,6 +1021,272 @@ static struct crypto_template crypto_rfc4106_tmpl = {
 	.module = THIS_MODULE,
 };
 
+static inline struct crypto_rfc4543_req_ctx *crypto_rfc4543_reqctx(
+	struct aead_request *req)
+{
+	unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
+
+	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
+}
+
+static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key,
+				 unsigned int keylen)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
+	struct crypto_aead *child = ctx->child;
+	int err;
+
+	if (keylen < 4)
+		return -EINVAL;
+
+	keylen -= 4;
+	memcpy(ctx->nonce, key + keylen, 4);
+
+	crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
+				     ...
From: Herbert Xu
Date: Sunday, January 17, 2010 - 3:52 am

Applied to cryptodev.  Thanks Tobias!
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--

Previous thread: seeing strange values for tcp sk_rmem_alloc by Chris Friesen on Tuesday, December 1, 2009 - 9:16 am. (8 messages)

Next thread: Re: [linux-pm] intermittent suspend problem again by Ferenc Wagner on Tuesday, December 1, 2009 - 10:46 am. (3 messages)