Commit 28856a9e52c7cac712af6c143de04766617535dc
Committed by
Herbert Xu
1 parent
730d02e276
Exists in
smarc_imx_lf-5.15.y
and in
27 other branches
crypto: xts - consolidate sanity check for keys
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> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Showing 13 changed files with 71 additions and 53 deletions Side-by-side Diff
- arch/arm/crypto/aes-ce-glue.c
- arch/arm/crypto/aesbs-glue.c
- arch/arm64/crypto/aes-glue.c
- arch/powerpc/crypto/aes-spe-glue.c
- arch/s390/crypto/aes_s390.c
- arch/x86/crypto/aesni-intel_glue.c
- arch/x86/crypto/camellia_glue.c
- arch/x86/crypto/cast6_avx_glue.c
- arch/x86/crypto/serpent_avx_glue.c
- arch/x86/crypto/serpent_sse2_glue.c
- arch/x86/crypto/twofish_glue_3way.c
- crypto/xts.c
- include/crypto/xts.h
arch/arm/crypto/aes-ce-glue.c
... | ... | @@ -152,6 +152,10 @@ |
152 | 152 | struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
153 | 153 | int ret; |
154 | 154 | |
155 | + ret = xts_check_key(tfm, in_key, key_len); | |
156 | + if (ret) | |
157 | + return ret; | |
158 | + | |
155 | 159 | ret = ce_aes_expandkey(&ctx->key1, in_key, key_len / 2); |
156 | 160 | if (!ret) |
157 | 161 | ret = ce_aes_expandkey(&ctx->key2, &in_key[key_len / 2], |
arch/arm/crypto/aesbs-glue.c
... | ... | @@ -89,6 +89,11 @@ |
89 | 89 | { |
90 | 90 | struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
91 | 91 | int bits = key_len * 4; |
92 | + int err; | |
93 | + | |
94 | + err = xts_check_key(tfm, in_key, key_len); | |
95 | + if (err) | |
96 | + return err; | |
92 | 97 | |
93 | 98 | if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) { |
94 | 99 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
arch/arm64/crypto/aes-glue.c
... | ... | @@ -85,6 +85,10 @@ |
85 | 85 | struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
86 | 86 | int ret; |
87 | 87 | |
88 | + ret = xts_check_key(tfm, in_key, key_len); | |
89 | + if (ret) | |
90 | + return ret; | |
91 | + | |
88 | 92 | ret = aes_expandkey(&ctx->key1, in_key, key_len / 2); |
89 | 93 | if (!ret) |
90 | 94 | ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2], |
arch/powerpc/crypto/aes-spe-glue.c
arch/s390/crypto/aes_s390.c
arch/x86/crypto/aesni-intel_glue.c
... | ... | @@ -639,16 +639,11 @@ |
639 | 639 | unsigned int keylen) |
640 | 640 | { |
641 | 641 | struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
642 | - u32 *flags = &tfm->crt_flags; | |
643 | 642 | int err; |
644 | 643 | |
645 | - /* key consists of keys of equal size concatenated, therefore | |
646 | - * the length must be even | |
647 | - */ | |
648 | - if (keylen % 2) { | |
649 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
650 | - return -EINVAL; | |
651 | - } | |
644 | + err = xts_check_key(tfm, key, keylen); | |
645 | + if (err) | |
646 | + return err; | |
652 | 647 | |
653 | 648 | /* first half of xts-key is for crypt */ |
654 | 649 | err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen / 2); |
arch/x86/crypto/camellia_glue.c
... | ... | @@ -1503,13 +1503,9 @@ |
1503 | 1503 | u32 *flags = &tfm->crt_flags; |
1504 | 1504 | int err; |
1505 | 1505 | |
1506 | - /* key consists of keys of equal size concatenated, therefore | |
1507 | - * the length must be even | |
1508 | - */ | |
1509 | - if (keylen % 2) { | |
1510 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
1511 | - return -EINVAL; | |
1512 | - } | |
1506 | + err = xts_check_key(tfm, key, keylen); | |
1507 | + if (err) | |
1508 | + return err; | |
1513 | 1509 | |
1514 | 1510 | /* first half of xts-key is for crypt */ |
1515 | 1511 | err = __camellia_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); |
arch/x86/crypto/cast6_avx_glue.c
... | ... | @@ -329,13 +329,9 @@ |
329 | 329 | u32 *flags = &tfm->crt_flags; |
330 | 330 | int err; |
331 | 331 | |
332 | - /* key consists of keys of equal size concatenated, therefore | |
333 | - * the length must be even | |
334 | - */ | |
335 | - if (keylen % 2) { | |
336 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
337 | - return -EINVAL; | |
338 | - } | |
332 | + err = xts_check_key(tfm, key, keylen); | |
333 | + if (err) | |
334 | + return err; | |
339 | 335 | |
340 | 336 | /* first half of xts-key is for crypt */ |
341 | 337 | err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); |
arch/x86/crypto/serpent_avx_glue.c
... | ... | @@ -332,16 +332,11 @@ |
332 | 332 | unsigned int keylen) |
333 | 333 | { |
334 | 334 | struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
335 | - u32 *flags = &tfm->crt_flags; | |
336 | 335 | int err; |
337 | 336 | |
338 | - /* key consists of keys of equal size concatenated, therefore | |
339 | - * the length must be even | |
340 | - */ | |
341 | - if (keylen % 2) { | |
342 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
343 | - return -EINVAL; | |
344 | - } | |
337 | + err = xts_check_key(tfm, key, keylen); | |
338 | + if (err) | |
339 | + return err; | |
345 | 340 | |
346 | 341 | /* first half of xts-key is for crypt */ |
347 | 342 | err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2); |
arch/x86/crypto/serpent_sse2_glue.c
... | ... | @@ -309,16 +309,11 @@ |
309 | 309 | unsigned int keylen) |
310 | 310 | { |
311 | 311 | struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
312 | - u32 *flags = &tfm->crt_flags; | |
313 | 312 | int err; |
314 | 313 | |
315 | - /* key consists of keys of equal size concatenated, therefore | |
316 | - * the length must be even | |
317 | - */ | |
318 | - if (keylen % 2) { | |
319 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
320 | - return -EINVAL; | |
321 | - } | |
314 | + err = xts_check_key(tfm, key, keylen); | |
315 | + if (err) | |
316 | + return err; | |
322 | 317 | |
323 | 318 | /* first half of xts-key is for crypt */ |
324 | 319 | err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2); |
arch/x86/crypto/twofish_glue_3way.c
... | ... | @@ -277,13 +277,9 @@ |
277 | 277 | u32 *flags = &tfm->crt_flags; |
278 | 278 | int err; |
279 | 279 | |
280 | - /* key consists of keys of equal size concatenated, therefore | |
281 | - * the length must be even | |
282 | - */ | |
283 | - if (keylen % 2) { | |
284 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
285 | - return -EINVAL; | |
286 | - } | |
280 | + err = xts_check_key(tfm, key, keylen); | |
281 | + if (err) | |
282 | + return err; | |
287 | 283 | |
288 | 284 | /* first half of xts-key is for crypt */ |
289 | 285 | err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); |
crypto/xts.c
... | ... | @@ -35,16 +35,11 @@ |
35 | 35 | { |
36 | 36 | struct priv *ctx = crypto_tfm_ctx(parent); |
37 | 37 | struct crypto_cipher *child = ctx->tweak; |
38 | - u32 *flags = &parent->crt_flags; | |
39 | 38 | int err; |
40 | 39 | |
41 | - /* key consists of keys of equal size concatenated, therefore | |
42 | - * the length must be even */ | |
43 | - if (keylen % 2) { | |
44 | - /* tell the user why there was an error */ | |
45 | - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
46 | - return -EINVAL; | |
47 | - } | |
40 | + err = xts_check_key(parent, key, keylen); | |
41 | + if (err) | |
42 | + return err; | |
48 | 43 | |
49 | 44 | /* we need two cipher instances: one to compute the initial 'tweak' |
50 | 45 | * by encrypting the IV (usually the 'plain' iv) and the other |
include/crypto/xts.h
... | ... | @@ -2,6 +2,9 @@ |
2 | 2 | #define _CRYPTO_XTS_H |
3 | 3 | |
4 | 4 | #include <crypto/b128ops.h> |
5 | +#include <linux/crypto.h> | |
6 | +#include <crypto/algapi.h> | |
7 | +#include <linux/fips.h> | |
5 | 8 | |
6 | 9 | struct scatterlist; |
7 | 10 | struct blkcipher_desc; |
... | ... | @@ -23,6 +26,30 @@ |
23 | 26 | int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
24 | 27 | struct scatterlist *src, unsigned int nbytes, |
25 | 28 | struct xts_crypt_req *req); |
29 | + | |
30 | +static inline int xts_check_key(struct crypto_tfm *tfm, | |
31 | + const u8 *key, unsigned int keylen) | |
32 | +{ | |
33 | + u32 *flags = &tfm->crt_flags; | |
34 | + | |
35 | + /* | |
36 | + * key consists of keys of equal size concatenated, therefore | |
37 | + * the length must be even. | |
38 | + */ | |
39 | + if (keylen % 2) { | |
40 | + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
41 | + return -EINVAL; | |
42 | + } | |
43 | + | |
44 | + /* ensure that the AES and tweak key are not identical */ | |
45 | + if (fips_enabled && | |
46 | + !crypto_memneq(key, key + (keylen / 2), keylen / 2)) { | |
47 | + *flags |= CRYPTO_TFM_RES_WEAK_KEY; | |
48 | + return -EINVAL; | |
49 | + } | |
50 | + | |
51 | + return 0; | |
52 | +} | |
26 | 53 | |
27 | 54 | #endif /* _CRYPTO_XTS_H */ |