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