From: Stephan Mueller <smueller@chronox.de>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
"linux-crypto@vger.kernel.org" <linux-crypto@vger.kernel.org>,
Markus Stockhausen <stockhausen@collogia.de>,
jang@de.ibm.com, "Huang, Ying" <ying.huang@intel.com>,
jussi.kivilinna@mbnet.fi,
Johannes.Goetzfried@informatik.stud.uni-erlangen.de,
rsnel@cube.dyndns.org
Subject: Re: [PATCH] crypto: xts - consolidate sanity check for keys
Date: Sun, 07 Feb 2016 15:40:43 +0100 [thread overview]
Message-ID: <4148489.8sXpslkmzC@positron.chronox.de> (raw)
In-Reply-To: <CAKv+Gu9e4Dgd25VFuSfRUB=Di7aSfocjwgLo1k96W2MN=G0RZA@mail.gmail.com>
Am Sonntag, 7. Februar 2016, 14:41:22 schrieb Ard Biesheuvel:
Hi Ard,
> Hi Stephan,
>
> On 7 February 2016 at 14:05, Stephan Mueller <smueller@chronox.de> wrote:
> > Hi,
> >
> > I only have an x86 system for testing. May I ask the owners for the other
> > architectures to review and test?
> >
> > ---8<---
> >
> > The patch centralizes the XTS key check logic into the service function
> > xts_check_key which is invoked from the different XTS implementations.
> > With this, the XTS implementations in ARM, ARM64, PPC and S390 have now
> > a sanity check for the XTS keys similar to the other arches.
> >
> > In addition, this service function received a check to ensure that the
> > key != the tweak key which is mandated by FIPS 140-2 IG A.9. As the
> > check is not present in the standards defining XTS, it is only enforced
> > in FIPS mode of the kernel.
> >
> > Signed-off-by: Stephan Mueller <smueller@chronox.de>
>
> One remark below (and a nit). With that fixed:
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Thank you.
>
> > ---
> >
> > arch/arm/crypto/aes-ce-glue.c | 4 ++++
> > arch/arm/crypto/aesbs-glue.c | 5 +++++
> > arch/arm64/crypto/aes-glue.c | 4 ++++
> > arch/powerpc/crypto/aes-spe-glue.c | 5 +++++
> > arch/s390/crypto/aes_s390.c | 5 +++++
> > arch/x86/crypto/aesni-intel_glue.c | 11 +++--------
> > arch/x86/crypto/camellia_glue.c | 10 +++-------
> > arch/x86/crypto/cast6_avx_glue.c | 10 +++-------
> > arch/x86/crypto/serpent_avx_glue.c | 11 +++--------
> > arch/x86/crypto/serpent_sse2_glue.c | 11 +++--------
> > arch/x86/crypto/twofish_glue_3way.c | 10 +++-------
> > crypto/xts.c | 11 +++--------
> > include/crypto/xts.h | 29 +++++++++++++++++++++++++++++
> > 13 files changed, 73 insertions(+), 53 deletions(-)
> >
> > diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c
> > index b445a5d..85ff69b 100644
> > --- a/arch/arm/crypto/aes-ce-glue.c
> > +++ b/arch/arm/crypto/aes-ce-glue.c
> > @@ -152,6 +152,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const
> > u8 *in_key,>
> > struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> > int ret;
> >
> > + ret = xts_check_key(tfm, in_key, key_len);
> > + if (ret)
> > + return ret;
> > +
> >
> > ret = ce_aes_expandkey(&ctx->key1, in_key, key_len / 2);
> > if (!ret)
> >
> > ret = ce_aes_expandkey(&ctx->key2, &in_key[key_len / 2],
> >
> > diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
> > index 6d68529..d004bd1 100644
> > --- a/arch/arm/crypto/aesbs-glue.c
> > +++ b/arch/arm/crypto/aesbs-glue.c
> > @@ -89,6 +89,11 @@ static int aesbs_xts_set_key(struct crypto_tfm *tfm,
> > const u8 *in_key,>
> > {
> >
> > struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> > int bits = key_len * 4;
> >
> > + int err;
> > +
> > + err = xts_check_key(tfm, in_key, key_len);
> > + if (err)
> > + return err;
> >
> > if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
> >
> > tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> >
> > diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
> > index 05d9e16..c963d75 100644
> > --- a/arch/arm64/crypto/aes-glue.c
> > +++ b/arch/arm64/crypto/aes-glue.c
> > @@ -85,6 +85,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const u8
> > *in_key,>
> > struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> > int ret;
> >
> > + ret = xts_check_key(tfm, in_key, key_len);
> > + if (ret)
> > + return ret;
> > +
> >
> > ret = aes_expandkey(&ctx->key1, in_key, key_len / 2);
> > if (!ret)
> >
> > ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2],
> >
> > diff --git a/arch/powerpc/crypto/aes-spe-glue.c
> > b/arch/powerpc/crypto/aes-spe-glue.c index 93ee046..1608079 100644
> > --- a/arch/powerpc/crypto/aes-spe-glue.c
> > +++ b/arch/powerpc/crypto/aes-spe-glue.c
> > @@ -126,6 +126,11 @@ static int ppc_xts_setkey(struct crypto_tfm *tfm,
> > const u8 *in_key,>
> > unsigned int key_len)
> >
> > {
> >
> > struct ppc_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> >
> > + int err;
> > +
> > + err = xts_check_key(tfm, in_key, key_len);
> > + if (err)
> > + return err;
> >
> > key_len >>= 1;
> >
> > diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
> > index 0b9b95f..3f1a1a4 100644
> > --- a/arch/s390/crypto/aes_s390.c
> > +++ b/arch/s390/crypto/aes_s390.c
> > @@ -587,6 +587,11 @@ static int xts_aes_set_key(struct crypto_tfm *tfm,
> > const u8 *in_key,>
> > {
> >
> > struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
> > u32 *flags = &tfm->crt_flags;
> >
> > + int err;
> > +
> > + err = xts_check_key(tfm, in_key, key_len);
> > + if (err)
> > + return err;
> >
> > switch (key_len) {
> >
> > case 32:
> > diff --git a/arch/x86/crypto/aesni-intel_glue.c
> > b/arch/x86/crypto/aesni-intel_glue.c index 3633ad6..064c7e2 100644
> > --- a/arch/x86/crypto/aesni-intel_glue.c
> > +++ b/arch/x86/crypto/aesni-intel_glue.c
> > @@ -639,16 +639,11 @@ static int xts_aesni_setkey(struct crypto_tfm *tfm,
> > const u8 *key,>
> > unsigned int keylen)
> >
> > {
> >
> > struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> >
> > - u32 *flags = &tfm->crt_flags;
> >
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen /
> > 2);
> >
> > diff --git a/arch/x86/crypto/camellia_glue.c
> > b/arch/x86/crypto/camellia_glue.c index 5c8b626..aa76cad 100644
> > --- a/arch/x86/crypto/camellia_glue.c
> > +++ b/arch/x86/crypto/camellia_glue.c
> > @@ -1503,13 +1503,9 @@ int xts_camellia_setkey(struct crypto_tfm *tfm,
> > const u8 *key,>
> > u32 *flags = &tfm->crt_flags;
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = __camellia_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
> >
> > diff --git a/arch/x86/crypto/cast6_avx_glue.c
> > b/arch/x86/crypto/cast6_avx_glue.c index fca4595..50e6847 100644
> > --- a/arch/x86/crypto/cast6_avx_glue.c
> > +++ b/arch/x86/crypto/cast6_avx_glue.c
> > @@ -329,13 +329,9 @@ static int xts_cast6_setkey(struct crypto_tfm *tfm,
> > const u8 *key,>
> > u32 *flags = &tfm->crt_flags;
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
> >
> > diff --git a/arch/x86/crypto/serpent_avx_glue.c
> > b/arch/x86/crypto/serpent_avx_glue.c index 5dc3702..6f778d3 100644
> > --- a/arch/x86/crypto/serpent_avx_glue.c
> > +++ b/arch/x86/crypto/serpent_avx_glue.c
> > @@ -332,16 +332,11 @@ int xts_serpent_setkey(struct crypto_tfm *tfm, const
> > u8 *key,>
> > unsigned int keylen)
> >
> > {
> >
> > struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> >
> > - u32 *flags = &tfm->crt_flags;
> >
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
> >
> > diff --git a/arch/x86/crypto/serpent_sse2_glue.c
> > b/arch/x86/crypto/serpent_sse2_glue.c index 3643dd5..8943407 100644
> > --- a/arch/x86/crypto/serpent_sse2_glue.c
> > +++ b/arch/x86/crypto/serpent_sse2_glue.c
> > @@ -309,16 +309,11 @@ static int xts_serpent_setkey(struct crypto_tfm
> > *tfm, const u8 *key,>
> > unsigned int keylen)
> >
> > {
> >
> > struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> >
> > - u32 *flags = &tfm->crt_flags;
> >
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
> >
> > diff --git a/arch/x86/crypto/twofish_glue_3way.c
> > b/arch/x86/crypto/twofish_glue_3way.c index 56d8a08..2ebb5e9 100644
> > --- a/arch/x86/crypto/twofish_glue_3way.c
> > +++ b/arch/x86/crypto/twofish_glue_3way.c
> > @@ -277,13 +277,9 @@ int xts_twofish_setkey(struct crypto_tfm *tfm, const
> > u8 *key,>
> > u32 *flags = &tfm->crt_flags;
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even
> > - */
> > - if (keylen % 2) {
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(tfm, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* first half of xts-key is for crypt */
> > err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
> >
> > diff --git a/crypto/xts.c b/crypto/xts.c
> > index f6fd43f..26ba583 100644
> > --- a/crypto/xts.c
> > +++ b/crypto/xts.c
> > @@ -35,16 +35,11 @@ static int setkey(struct crypto_tfm *parent, const u8
> > *key,>
> > {
> >
> > struct priv *ctx = crypto_tfm_ctx(parent);
> > struct crypto_cipher *child = ctx->tweak;
> >
> > - u32 *flags = &parent->crt_flags;
> >
> > int err;
> >
> > - /* key consists of keys of equal size concatenated, therefore
> > - * the length must be even */
> > - if (keylen % 2) {
> > - /* tell the user why there was an error */
> > - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > - return -EINVAL;
> > - }
> > + err = xts_check_key(parent, key, keylen);
> > + if (err)
> > + return err;
> >
> > /* we need two cipher instances: one to compute the initial
> > 'tweak'
> >
> > * by encrypting the IV (usually the 'plain' iv) and the other
> >
> > diff --git a/include/crypto/xts.h b/include/crypto/xts.h
> > index 72c09eb..41d936e 100644
> > --- a/include/crypto/xts.h
> > +++ b/include/crypto/xts.h
> > @@ -2,6 +2,9 @@
> >
> > #define _CRYPTO_XTS_H
> >
> > #include <crypto/b128ops.h>
> >
> > +#include <linux/crypto.h>
> > +#include <crypto/algapi.h>
> > +#include <linux/fips.h>
> >
> > struct scatterlist;
> > struct blkcipher_desc;
> >
> > @@ -24,4 +27,30 @@ int xts_crypt(struct blkcipher_desc *desc, struct
> > scatterlist *dst,>
> > struct scatterlist *src, unsigned int nbytes,
> > struct xts_crypt_req *req);
> >
> > +static inline int xts_check_key(struct crypto_tfm *tfm,
> > + const u8 *key, unsigned int keylen)
> > +{
> > + u32 *flags = &tfm->crt_flags;
> > +
> > + /*
> > + * key consists of keys of equal size concatenated, therefore
> > + * the length must be even.
> > + */
> > + if (keylen % 2) {
> > + /* tell the user why there was an error */
>
> Nit: I don't think this comment adds anything useful tbh
I just copied it from the x86 code -- I will remove it.
>
> > + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> > + return -EINVAL;
> > + }
> > +
> > +#ifdef CONFIG_CRYPTO_FIPS
> > + /* ensure that the AES and tweak key are not identical */
> > + if (fips_enabled &&
>
> This is redundant. 'fips_enabled' is #defined to 0 if CRYPTO_FIPS=n so
> you can lose the #ifdef entirely.
I would concur. But then we have an additional check which is not really
required in the "normal" use case.
As I have seen that all FIPS related stuff is encapsulated with the FIPS
ifdef, I thought this is warranted here too.
I am fine either way though.
Herbert, what do you think?
>
> > + !crypto_memneq(key, key + (keylen / 2), keylen / 2)) {
> > + *flags |= CRYPTO_TFM_RES_WEAK_KEY;
> > + return -EINVAL;
> > + }
> > +#endif
> > + return 0;
> > +}
> > +
> >
> > #endif /* _CRYPTO_XTS_H */
> >
> > --
> > 2.5.0
Ciao
Stephan
prev parent reply other threads:[~2016-02-07 14:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-07 13:05 [PATCH] crypto: xts - consolidate sanity check for keys Stephan Mueller
2016-02-07 13:41 ` Ard Biesheuvel
2016-02-07 14:40 ` Stephan Mueller [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4148489.8sXpslkmzC@positron.chronox.de \
--to=smueller@chronox.de \
--cc=Johannes.Goetzfried@informatik.stud.uni-erlangen.de \
--cc=ard.biesheuvel@linaro.org \
--cc=herbert@gondor.apana.org.au \
--cc=jang@de.ibm.com \
--cc=jussi.kivilinna@mbnet.fi \
--cc=linux-crypto@vger.kernel.org \
--cc=rsnel@cube.dyndns.org \
--cc=stockhausen@collogia.de \
--cc=ying.huang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.