Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
On Fri, Dec 04, 2009 at 05:31:43PM +0100, Tobias Brunner wrote: 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 tob...@strongswan.org Applied to cryptodev. Thanks Tobias! -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- 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
Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
+u8 auth_tag[16]; 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). 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 tob...@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) +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 crypto_authenc_chain */ +static void crypto_rfc4543_chain(struct scatterlist *head, +struct scatterlist *sg, int chain) +{ + if (chain) { + head-length += sg-length; + sg = scatterwalk_sg_next(sg); + } + + if (sg) + scatterwalk_sg_chain(head, 2, sg); + else + sg_mark_end(head); +} + +static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, +int enc) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); + struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); + struct aead_request *subreq = rctx-subreq; + struct scatterlist *dst = req-dst; + struct scatterlist *cipher = rctx-cipher; + struct scatterlist *payload = rctx-payload; + struct scatterlist *assoc = rctx-assoc; + unsigned int authsize = crypto_aead_authsize(aead); + unsigned int assoclen = req-assoclen; + struct page *dstp; + u8 *vdst; + u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx-child), + crypto_aead_alignmask(ctx-child) + 1); + + memcpy(iv, ctx-nonce, 4); + memcpy(iv + 4, req-iv, 8); + + /* construct cipher/plaintext */ + if (enc) + memset(rctx-auth_tag, 0, authsize); + else + scatterwalk_map_and_copy(rctx-auth_tag, dst, +req-cryptlen - authsize, +authsize, 0); + + sg_init_one(cipher, rctx-auth_tag, authsize); + + /* construct the aad */ + dstp = sg_page(dst); + vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst-offset; + + sg_init_table(payload, 2); + sg_set_buf(payload, req-iv, 8); + crypto_rfc4543_chain(payload, dst, vdst == req-iv + 8); + assoclen += 8 + req-cryptlen - (enc ? 0 : authsize); + + sg_init_table(assoc, 2); +
Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
On Tue, Dec 01, 2009 at 05:49:28PM +0100, Tobias Brunner wrote: 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 tob...@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]; 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 ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- 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
[PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
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 tob...@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 crypto_authenc_chain */ +static void crypto_rfc4543_chain(struct scatterlist *head, +struct scatterlist *sg, int chain) +{ + if (chain) { + head-length += sg-length; + sg = scatterwalk_sg_next(sg); + } + + if (sg) + scatterwalk_sg_chain(head, 2, sg); + else + sg_mark_end(head); +} + +static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, +int enc) +{ + struct aead_request *subreq = aead_request_ctx(req); + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); + struct crypto_aead *child = ctx-child; + struct scatterlist *dst = req-dst; + struct scatterlist *cipher = ctx-cipher; + struct scatterlist *payload = ctx-payload; + struct scatterlist *assoc = ctx-assoc; + unsigned int authsize = crypto_aead_authsize(aead); + unsigned int assoclen = req-assoclen; + struct page *dstp; + u8 *vdst; + u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child), + crypto_aead_alignmask(child) + 1); + + memcpy(iv, ctx-nonce, 4); + memcpy(iv + 4, req-iv, 8); + + /* construct cipher/plaintext */ + if (enc) + memset(ctx-auth_tag, 0, authsize); + else + scatterwalk_map_and_copy(ctx-auth_tag, dst, +req-cryptlen - authsize, +authsize, 0); + + sg_init_one(cipher, ctx-auth_tag, authsize); + + /* construct the aad */ + dstp = sg_page(dst); + vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst-offset; + + sg_init_table(payload, 2); + sg_set_buf(payload, req-iv, 8); + crypto_rfc4543_chain(payload, dst, vdst == req-iv + 8); + assoclen += 8 + req-cryptlen - (enc ? 0 : authsize); + + sg_init_table(assoc, 2); + sg_set_page(assoc, sg_page(req-assoc), req-assoc-length, + req-assoc-offset); + crypto_rfc4543_chain(assoc, payload, 0); + + aead_request_set_tfm(subreq, child); + aead_request_set_callback(subreq, req-base.flags, req-base.complete, + req-base.data); + aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv); + aead_request_set_assoc(subreq, assoc, assoclen); + + return subreq; +} + +static int crypto_rfc4543_encrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); + struct aead_request
Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
From: Tobias Brunner tob...@strongswan.org Date: Tue, 01 Dec 2009 17:49:28 +0100 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 tob...@strongswan.org Herbert, you got this one? Thanks. -- 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
Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
On Tue, Dec 01, 2009 at 03:51:41PM -0800, David Miller wrote: From: Tobias Brunner tob...@strongswan.org Date: Tue, 01 Dec 2009 17:49:28 +0100 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 tob...@strongswan.org Herbert, you got this one? Sure I'll pick it up. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- 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