Branch data Line data Source code
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 : 0 : 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 : 0 : memcpy(K, key, DES3_EDE_KEY_SIZE); 66 : : 67 : 0 : if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 68 : 0 : !((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 : 0 : 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 */