]>
Commit | Line | Data |
---|---|---|
6ee41e54 AB |
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 | { | |
04007b0e AB |
28 | struct des_ctx tmp; |
29 | int err; | |
6ee41e54 | 30 | |
04007b0e AB |
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 | } | |
6ee41e54 | 38 | |
04007b0e | 39 | if (err) |
6ee41e54 | 40 | crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); |
6ee41e54 | 41 | |
04007b0e | 42 | memzero_explicit(&tmp, sizeof(tmp)); |
6ee41e54 AB |
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 | */ | |
04007b0e AB |
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 | } | |
6ee41e54 AB |
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 | { | |
04007b0e | 98 | int err; |
6ee41e54 | 99 | |
04007b0e AB |
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); | |
6ee41e54 | 105 | return err; |
6ee41e54 AB |
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 */ |