1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * DES & Triple DES EDE key verification helpers 4 */ 5 6 #ifndef __CRYPTO_INTERNAL_DES_H 7 #define __CRYPTO_INTERNAL_DES_H 8 9 #include <linux/crypto.h> 10 #include <linux/fips.h> 11 #include <crypto/des.h> 12 #include <crypto/aead.h> 13 #include <crypto/skcipher.h> 14 15 /** 16 * crypto_des_verify_key - Check whether a DES key is weak 17 * @tfm: the crypto algo 18 * @key: the key buffer 19 * 20 * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak 21 * keys. Otherwise, 0 is returned. 22 * 23 * It is the job of the caller to ensure that the size of the key equals 24 * DES_KEY_SIZE. 25 */ 26 static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key) 27 { 28 struct des_ctx tmp; 29 int err; 30 31 err = des_expand_key(&tmp, key, DES_KEY_SIZE); 32 if (err == -ENOKEY) { 33 if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 34 err = -EINVAL; 35 else 36 err = 0; 37 } 38 memzero_explicit(&tmp, sizeof(tmp)); 39 return err; 40 } 41 42 /* 43 * RFC2451: 44 * 45 * For DES-EDE3, there is no known need to reject weak or 46 * complementation keys. Any weakness is obviated by the use of 47 * multiple keys. 48 * 49 * However, if the first two or last two independent 64-bit keys are 50 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the 51 * same as DES. Implementers MUST reject keys that exhibit this 52 * property. 53 * 54 */ 55 static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len, 56 bool check_weak) 57 { 58 int ret = fips_enabled ? -EINVAL : -ENOKEY; 59 u32 K[6]; 60 61 memcpy(K, key, DES3_EDE_KEY_SIZE); 62 63 if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 64 !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && 65 (fips_enabled || check_weak)) 66 goto bad; 67 68 if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) 69 goto bad; 70 71 ret = 0; 72 bad: 73 memzero_explicit(K, DES3_EDE_KEY_SIZE); 74 75 return ret; 76 } 77 78 /** 79 * crypto_des3_ede_verify_key - Check whether a DES3-EDE key is weak 80 * @tfm: the crypto algo 81 * @key: the key buffer 82 * 83 * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak 84 * keys or when running in FIPS mode. Otherwise, 0 is returned. Note that some 85 * keys are rejected in FIPS mode even if weak keys are permitted by the TFM 86 * flags. 87 * 88 * It is the job of the caller to ensure that the size of the key equals 89 * DES3_EDE_KEY_SIZE. 90 */ 91 static inline int crypto_des3_ede_verify_key(struct crypto_tfm *tfm, 92 const u8 *key) 93 { 94 return des3_ede_verify_key(key, DES3_EDE_KEY_SIZE, 95 crypto_tfm_get_flags(tfm) & 96 CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 97 } 98 99 static inline int verify_skcipher_des_key(struct crypto_skcipher *tfm, 100 const u8 *key) 101 { 102 return crypto_des_verify_key(crypto_skcipher_tfm(tfm), key); 103 } 104 105 static inline int verify_skcipher_des3_key(struct crypto_skcipher *tfm, 106 const u8 *key) 107 { 108 return crypto_des3_ede_verify_key(crypto_skcipher_tfm(tfm), key); 109 } 110 111 static inline int verify_aead_des_key(struct crypto_aead *tfm, const u8 *key, 112 int keylen) 113 { 114 if (keylen != DES_KEY_SIZE) 115 return -EINVAL; 116 return crypto_des_verify_key(crypto_aead_tfm(tfm), key); 117 } 118 119 static inline int verify_aead_des3_key(struct crypto_aead *tfm, const u8 *key, 120 int keylen) 121 { 122 if (keylen != DES3_EDE_KEY_SIZE) 123 return -EINVAL; 124 return crypto_des3_ede_verify_key(crypto_aead_tfm(tfm), key); 125 } 126 127 #endif /* __CRYPTO_INTERNAL_DES_H */ 128
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.