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 : : 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 : 0 : static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len, 56 : : bool check_weak) 57 : : { 58 : 0 : int ret = fips_enabled ? -EINVAL : -ENOKEY; 59 : 0 : u32 K[6]; 60 : : 61 : 0 : memcpy(K, key, DES3_EDE_KEY_SIZE); 62 : : 63 [ # # ]: 0 : if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 64 [ # # # # ]: 0 : !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && 65 : : (fips_enabled || check_weak)) 66 : 0 : goto bad; 67 : : 68 : : if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) 69 : : goto bad; 70 : : 71 : : ret = 0; 72 : 0 : bad: 73 : 0 : memzero_explicit(K, DES3_EDE_KEY_SIZE); 74 : : 75 : 0 : 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 */