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 39 if (err) 40 crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); 41 42 memzero_explicit(&tmp, sizeof(tmp)); 43 return err; 44 } 45 46 /* 47 * RFC2451: 48 * 49 * For DES-EDE3, there is no known need to reject weak or 50 * complementation keys. Any weakness is obviated by the use of 51 * multiple keys. 52 * 53 * However, if the first two or last two independent 64-bit keys are 54 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the 55 * same as DES. Implementers MUST reject keys that exhibit this 56 * property. 57 * 58 */ 59 static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len, 60 bool check_weak) 61 { 62 int ret = fips_enabled ? -EINVAL : -ENOKEY; 63 u32 K[6]; 64 65 memcpy(K, key, DES3_EDE_KEY_SIZE); 66 67 if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 68 !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && 69 (fips_enabled || check_weak)) 70 goto bad; 71 72 if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) 73 goto bad; 74 75 ret = 0; 76 bad: 77 memzero_explicit(K, DES3_EDE_KEY_SIZE); 78 79 return ret; 80 } 81 82 /** 83 * crypto_des3_ede_verify_key - Check whether a DES3-EDE key is weak 84 * @tfm: the crypto algo 85 * @key: the key buffer 86 * 87 * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak 88 * keys or when running in FIPS mode. Otherwise, 0 is returned. Note that some 89 * keys are rejected in FIPS mode even if weak keys are permitted by the TFM 90 * flags. 91 * 92 * It is the job of the caller to ensure that the size of the key equals 93 * DES3_EDE_KEY_SIZE. 94 */ 95 static inline int crypto_des3_ede_verify_key(struct crypto_tfm *tfm, 96 const u8 *key) 97 { 98 int err; 99 100 err = des3_ede_verify_key(key, DES3_EDE_KEY_SIZE, 101 crypto_tfm_get_flags(tfm) & 102 CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 103 if (err) 104 crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); 105 return err; 106 } 107 108 static inline int verify_skcipher_des_key(struct crypto_skcipher *tfm, 109 const u8 *key) 110 { 111 return crypto_des_verify_key(crypto_skcipher_tfm(tfm), key); 112 } 113 114 static inline int verify_skcipher_des3_key(struct crypto_skcipher *tfm, 115 const u8 *key) 116 { 117 return crypto_des3_ede_verify_key(crypto_skcipher_tfm(tfm), key); 118 } 119 120 static inline int verify_ablkcipher_des_key(struct crypto_ablkcipher *tfm, 121 const u8 *key) 122 { 123 return crypto_des_verify_key(crypto_ablkcipher_tfm(tfm), key); 124 } 125 126 static inline int verify_ablkcipher_des3_key(struct crypto_ablkcipher *tfm, 127 const u8 *key) 128 { 129 return crypto_des3_ede_verify_key(crypto_ablkcipher_tfm(tfm), key); 130 } 131 132 static inline int verify_aead_des_key(struct crypto_aead *tfm, const u8 *key, 133 int keylen) 134 { 135 if (keylen != DES_KEY_SIZE) { 136 crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 137 return -EINVAL; 138 } 139 return crypto_des_verify_key(crypto_aead_tfm(tfm), key); 140 } 141 142 static inline int verify_aead_des3_key(struct crypto_aead *tfm, const u8 *key, 143 int keylen) 144 { 145 if (keylen != DES3_EDE_KEY_SIZE) { 146 crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 147 return -EINVAL; 148 } 149 return crypto_des3_ede_verify_key(crypto_aead_tfm(tfm), key); 150 } 151 152 #endif /* __CRYPTO_INTERNAL_DES_H */ 153