diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2019-08-15 12:01:09 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-08-22 14:57:33 +1000 |
commit | 04007b0e6cbbab5836ac891626e91edf10d46341 (patch) | |
tree | 6ab34c77d53b585d844c628893c2eebf4c249751 /include | |
parent | 6b5c4818621fb0d3eda1d4059634b38e09bd7243 (diff) |
crypto: des - split off DES library from generic DES cipher driver
Another one for the cipher museum: split off DES core processing into
a separate module so other drivers (mostly for crypto accelerators)
can reuse the code without pulling in the generic DES cipher itself.
This will also permit the cipher interface to be made private to the
crypto API itself once we move the only user in the kernel (CIFS) to
this library interface.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include')
-rw-r--r-- | include/crypto/des.h | 43 | ||||
-rw-r--r-- | include/crypto/internal/des.h | 69 |
2 files changed, 79 insertions, 33 deletions
diff --git a/include/crypto/des.h b/include/crypto/des.h index 31b04ba835b1..2c864a4e6707 100644 --- a/include/crypto/des.h +++ b/include/crypto/des.h @@ -6,10 +6,7 @@ #ifndef __CRYPTO_DES_H #define __CRYPTO_DES_H -#include <crypto/skcipher.h> -#include <linux/compiler.h> -#include <linux/fips.h> -#include <linux/string.h> +#include <linux/types.h> #define DES_KEY_SIZE 8 #define DES_EXPKEY_WORDS 32 @@ -19,6 +16,44 @@ #define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS) #define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE +struct des_ctx { + u32 expkey[DES_EXPKEY_WORDS]; +}; + +struct des3_ede_ctx { + u32 expkey[DES3_EDE_EXPKEY_WORDS]; +}; + +void des_encrypt(const struct des_ctx *ctx, u8 *dst, const u8 *src); +void des_decrypt(const struct des_ctx *ctx, u8 *dst, const u8 *src); + +void des3_ede_encrypt(const struct des3_ede_ctx *dctx, u8 *dst, const u8 *src); +void des3_ede_decrypt(const struct des3_ede_ctx *dctx, u8 *dst, const u8 *src); + +/** + * des_expand_key - Expand a DES input key into a key schedule + * @ctx: the key schedule + * @key: buffer containing the input key + * @len: size of the buffer contents + * + * Returns 0 on success, -EINVAL if the input key is rejected and -ENOKEY if + * the key is accepted but has been found to be weak. + */ +int des_expand_key(struct des_ctx *ctx, const u8 *key, unsigned int keylen); + +/** + * des3_ede_expand_key - Expand a triple DES input key into a key schedule + * @ctx: the key schedule + * @key: buffer containing the input key + * @len: size of the buffer contents + * + * Returns 0 on success, -EINVAL if the input key is rejected and -ENOKEY if + * the key is accepted but has been found to be weak. Note that weak keys will + * be rejected (and -EINVAL will be returned) when running in FIPS mode. + */ +int des3_ede_expand_key(struct des3_ede_ctx *ctx, const u8 *key, + unsigned int keylen); + extern int __des3_ede_setkey(u32 *expkey, u32 *flags, const u8 *key, unsigned int keylen); diff --git a/include/crypto/internal/des.h b/include/crypto/internal/des.h index f5d2e696522e..81ea1a425e9c 100644 --- a/include/crypto/internal/des.h +++ b/include/crypto/internal/des.h @@ -25,18 +25,21 @@ */ static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key) { - u32 tmp[DES_EXPKEY_WORDS]; - int err = 0; - - if (!(crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)) - return 0; + struct des_ctx tmp; + int err; + + err = des_expand_key(&tmp, key, DES_KEY_SIZE); + if (err == -ENOKEY) { + if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) + err = -EINVAL; + else + err = 0; + } - if (!des_ekey(tmp, key)) { + if (err) crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); - err = -EINVAL; - } - memzero_explicit(tmp, sizeof(tmp)); + memzero_explicit(&tmp, sizeof(tmp)); return err; } @@ -53,6 +56,28 @@ static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key) * property. * */ +static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len, + bool check_weak) +{ + int ret = fips_enabled ? -EINVAL : -ENOKEY; + u32 K[6]; + + memcpy(K, key, DES3_EDE_KEY_SIZE); + + if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || + !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && + (fips_enabled || check_weak)) + goto bad; + + if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) + goto bad; + + ret = 0; +bad: + memzero_explicit(K, DES3_EDE_KEY_SIZE); + + return ret; +} /** * crypto_des3_ede_verify_key - Check whether a DES3-EDE key is weak @@ -70,28 +95,14 @@ static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key) static inline int crypto_des3_ede_verify_key(struct crypto_tfm *tfm, const u8 *key) { - int err = -EINVAL; - u32 K[6]; - - memcpy(K, key, DES3_EDE_KEY_SIZE); - - if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || - !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && - (fips_enabled || (crypto_tfm_get_flags(tfm) & - CRYPTO_TFM_REQ_FORBID_WEAK_KEYS))) - goto bad; - - if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) - goto bad; + int err; - err = 0; -out: - memzero_explicit(K, DES3_EDE_KEY_SIZE); + err = des3_ede_verify_key(key, DES3_EDE_KEY_SIZE, + crypto_tfm_get_flags(tfm) & + CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); + if (err) + crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); return err; - -bad: - crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); - goto out; } static inline int verify_skcipher_des_key(struct crypto_skcipher *tfm, |