16ee41e54SArd Biesheuvel /* SPDX-License-Identifier: GPL-2.0 */ 26ee41e54SArd Biesheuvel /* 36ee41e54SArd Biesheuvel * DES & Triple DES EDE key verification helpers 46ee41e54SArd Biesheuvel */ 56ee41e54SArd Biesheuvel 66ee41e54SArd Biesheuvel #ifndef __CRYPTO_INTERNAL_DES_H 76ee41e54SArd Biesheuvel #define __CRYPTO_INTERNAL_DES_H 86ee41e54SArd Biesheuvel 96ee41e54SArd Biesheuvel #include <linux/crypto.h> 106ee41e54SArd Biesheuvel #include <linux/fips.h> 116ee41e54SArd Biesheuvel #include <crypto/des.h> 126ee41e54SArd Biesheuvel #include <crypto/aead.h> 136ee41e54SArd Biesheuvel #include <crypto/skcipher.h> 146ee41e54SArd Biesheuvel 156ee41e54SArd Biesheuvel /** 166ee41e54SArd Biesheuvel * crypto_des_verify_key - Check whether a DES key is weak 176ee41e54SArd Biesheuvel * @tfm: the crypto algo 186ee41e54SArd Biesheuvel * @key: the key buffer 196ee41e54SArd Biesheuvel * 206ee41e54SArd Biesheuvel * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak 216ee41e54SArd Biesheuvel * keys. Otherwise, 0 is returned. 226ee41e54SArd Biesheuvel * 236ee41e54SArd Biesheuvel * It is the job of the caller to ensure that the size of the key equals 246ee41e54SArd Biesheuvel * DES_KEY_SIZE. 256ee41e54SArd Biesheuvel */ 266ee41e54SArd Biesheuvel static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key) 276ee41e54SArd Biesheuvel { 2804007b0eSArd Biesheuvel struct des_ctx tmp; 2904007b0eSArd Biesheuvel int err; 306ee41e54SArd Biesheuvel 3104007b0eSArd Biesheuvel err = des_expand_key(&tmp, key, DES_KEY_SIZE); 3204007b0eSArd Biesheuvel if (err == -ENOKEY) { 3304007b0eSArd Biesheuvel if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 346ee41e54SArd Biesheuvel err = -EINVAL; 3504007b0eSArd Biesheuvel else 3604007b0eSArd Biesheuvel err = 0; 376ee41e54SArd Biesheuvel } 386ee41e54SArd Biesheuvel 3904007b0eSArd Biesheuvel if (err) 4004007b0eSArd Biesheuvel crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); 4104007b0eSArd Biesheuvel 4204007b0eSArd Biesheuvel memzero_explicit(&tmp, sizeof(tmp)); 436ee41e54SArd Biesheuvel return err; 446ee41e54SArd Biesheuvel } 456ee41e54SArd Biesheuvel 466ee41e54SArd Biesheuvel /* 476ee41e54SArd Biesheuvel * RFC2451: 486ee41e54SArd Biesheuvel * 496ee41e54SArd Biesheuvel * For DES-EDE3, there is no known need to reject weak or 506ee41e54SArd Biesheuvel * complementation keys. Any weakness is obviated by the use of 516ee41e54SArd Biesheuvel * multiple keys. 526ee41e54SArd Biesheuvel * 536ee41e54SArd Biesheuvel * However, if the first two or last two independent 64-bit keys are 546ee41e54SArd Biesheuvel * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the 556ee41e54SArd Biesheuvel * same as DES. Implementers MUST reject keys that exhibit this 566ee41e54SArd Biesheuvel * property. 576ee41e54SArd Biesheuvel * 586ee41e54SArd Biesheuvel */ 5904007b0eSArd Biesheuvel static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len, 6004007b0eSArd Biesheuvel bool check_weak) 6104007b0eSArd Biesheuvel { 6204007b0eSArd Biesheuvel int ret = fips_enabled ? -EINVAL : -ENOKEY; 6304007b0eSArd Biesheuvel u32 K[6]; 6404007b0eSArd Biesheuvel 6504007b0eSArd Biesheuvel memcpy(K, key, DES3_EDE_KEY_SIZE); 6604007b0eSArd Biesheuvel 6704007b0eSArd Biesheuvel if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) || 6804007b0eSArd Biesheuvel !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && 6904007b0eSArd Biesheuvel (fips_enabled || check_weak)) 7004007b0eSArd Biesheuvel goto bad; 7104007b0eSArd Biesheuvel 7204007b0eSArd Biesheuvel if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled) 7304007b0eSArd Biesheuvel goto bad; 7404007b0eSArd Biesheuvel 7504007b0eSArd Biesheuvel ret = 0; 7604007b0eSArd Biesheuvel bad: 7704007b0eSArd Biesheuvel memzero_explicit(K, DES3_EDE_KEY_SIZE); 7804007b0eSArd Biesheuvel 7904007b0eSArd Biesheuvel return ret; 8004007b0eSArd Biesheuvel } 816ee41e54SArd Biesheuvel 826ee41e54SArd Biesheuvel /** 836ee41e54SArd Biesheuvel * crypto_des3_ede_verify_key - Check whether a DES3-EDE key is weak 846ee41e54SArd Biesheuvel * @tfm: the crypto algo 856ee41e54SArd Biesheuvel * @key: the key buffer 866ee41e54SArd Biesheuvel * 876ee41e54SArd Biesheuvel * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak 886ee41e54SArd Biesheuvel * keys or when running in FIPS mode. Otherwise, 0 is returned. Note that some 896ee41e54SArd Biesheuvel * keys are rejected in FIPS mode even if weak keys are permitted by the TFM 906ee41e54SArd Biesheuvel * flags. 916ee41e54SArd Biesheuvel * 926ee41e54SArd Biesheuvel * It is the job of the caller to ensure that the size of the key equals 936ee41e54SArd Biesheuvel * DES3_EDE_KEY_SIZE. 946ee41e54SArd Biesheuvel */ 956ee41e54SArd Biesheuvel static inline int crypto_des3_ede_verify_key(struct crypto_tfm *tfm, 966ee41e54SArd Biesheuvel const u8 *key) 976ee41e54SArd Biesheuvel { 9804007b0eSArd Biesheuvel int err; 996ee41e54SArd Biesheuvel 10004007b0eSArd Biesheuvel err = des3_ede_verify_key(key, DES3_EDE_KEY_SIZE, 10104007b0eSArd Biesheuvel crypto_tfm_get_flags(tfm) & 10204007b0eSArd Biesheuvel CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 10304007b0eSArd Biesheuvel if (err) 1046ee41e54SArd Biesheuvel crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); 10504007b0eSArd Biesheuvel return err; 1066ee41e54SArd Biesheuvel } 1076ee41e54SArd Biesheuvel 1086ee41e54SArd Biesheuvel static inline int verify_skcipher_des_key(struct crypto_skcipher *tfm, 1096ee41e54SArd Biesheuvel const u8 *key) 1106ee41e54SArd Biesheuvel { 1116ee41e54SArd Biesheuvel return crypto_des_verify_key(crypto_skcipher_tfm(tfm), key); 1126ee41e54SArd Biesheuvel } 1136ee41e54SArd Biesheuvel 1146ee41e54SArd Biesheuvel static inline int verify_skcipher_des3_key(struct crypto_skcipher *tfm, 1156ee41e54SArd Biesheuvel const u8 *key) 1166ee41e54SArd Biesheuvel { 1176ee41e54SArd Biesheuvel return crypto_des3_ede_verify_key(crypto_skcipher_tfm(tfm), key); 1186ee41e54SArd Biesheuvel } 1196ee41e54SArd Biesheuvel 1206ee41e54SArd Biesheuvel static inline int verify_aead_des_key(struct crypto_aead *tfm, const u8 *key, 1216ee41e54SArd Biesheuvel int keylen) 1226ee41e54SArd Biesheuvel { 123*674f368aSEric Biggers if (keylen != DES_KEY_SIZE) 1246ee41e54SArd Biesheuvel return -EINVAL; 1256ee41e54SArd Biesheuvel return crypto_des_verify_key(crypto_aead_tfm(tfm), key); 1266ee41e54SArd Biesheuvel } 1276ee41e54SArd Biesheuvel 1286ee41e54SArd Biesheuvel static inline int verify_aead_des3_key(struct crypto_aead *tfm, const u8 *key, 1296ee41e54SArd Biesheuvel int keylen) 1306ee41e54SArd Biesheuvel { 131*674f368aSEric Biggers if (keylen != DES3_EDE_KEY_SIZE) 1326ee41e54SArd Biesheuvel return -EINVAL; 1336ee41e54SArd Biesheuvel return crypto_des3_ede_verify_key(crypto_aead_tfm(tfm), key); 1346ee41e54SArd Biesheuvel } 1356ee41e54SArd Biesheuvel 1366ee41e54SArd Biesheuvel #endif /* __CRYPTO_INTERNAL_DES_H */ 137