.. | .. |
---|
42 | 42 | * deprecated in 2.6 |
---|
43 | 43 | */ |
---|
44 | 44 | |
---|
| 45 | +#include <crypto/arc4.h> |
---|
45 | 46 | #include <crypto/hash.h> |
---|
46 | | -#include <crypto/skcipher.h> |
---|
47 | 47 | #include <linux/err.h> |
---|
| 48 | +#include <linux/fips.h> |
---|
48 | 49 | #include <linux/module.h> |
---|
49 | 50 | #include <linux/kernel.h> |
---|
50 | 51 | #include <linux/init.h> |
---|
.. | .. |
---|
63 | 64 | MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support"); |
---|
64 | 65 | MODULE_LICENSE("Dual BSD/GPL"); |
---|
65 | 66 | MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE)); |
---|
66 | | -MODULE_SOFTDEP("pre: arc4"); |
---|
67 | 67 | MODULE_VERSION("1.0.2"); |
---|
68 | | - |
---|
69 | | -static unsigned int |
---|
70 | | -setup_sg(struct scatterlist *sg, const void *address, unsigned int length) |
---|
71 | | -{ |
---|
72 | | - sg_set_buf(sg, address, length); |
---|
73 | | - return length; |
---|
74 | | -} |
---|
75 | 68 | |
---|
76 | 69 | #define SHA1_PAD_SIZE 40 |
---|
77 | 70 | |
---|
.. | .. |
---|
96 | 89 | * State for an MPPE (de)compressor. |
---|
97 | 90 | */ |
---|
98 | 91 | struct ppp_mppe_state { |
---|
99 | | - struct crypto_skcipher *arc4; |
---|
| 92 | + struct arc4_ctx arc4; |
---|
100 | 93 | struct shash_desc *sha1; |
---|
101 | 94 | unsigned char *sha1_digest; |
---|
102 | 95 | unsigned char master_key[MPPE_MAX_KEY_LEN]; |
---|
.. | .. |
---|
155 | 148 | */ |
---|
156 | 149 | static void mppe_rekey(struct ppp_mppe_state * state, int initial_key) |
---|
157 | 150 | { |
---|
158 | | - struct scatterlist sg_in[1], sg_out[1]; |
---|
159 | | - SKCIPHER_REQUEST_ON_STACK(req, state->arc4); |
---|
160 | | - |
---|
161 | | - skcipher_request_set_tfm(req, state->arc4); |
---|
162 | | - skcipher_request_set_callback(req, 0, NULL, NULL); |
---|
163 | | - |
---|
164 | 151 | get_new_key_from_sha(state); |
---|
165 | 152 | if (!initial_key) { |
---|
166 | | - crypto_skcipher_setkey(state->arc4, state->sha1_digest, |
---|
167 | | - state->keylen); |
---|
168 | | - sg_init_table(sg_in, 1); |
---|
169 | | - sg_init_table(sg_out, 1); |
---|
170 | | - setup_sg(sg_in, state->sha1_digest, state->keylen); |
---|
171 | | - setup_sg(sg_out, state->session_key, state->keylen); |
---|
172 | | - skcipher_request_set_crypt(req, sg_in, sg_out, state->keylen, |
---|
173 | | - NULL); |
---|
174 | | - if (crypto_skcipher_encrypt(req)) |
---|
175 | | - printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n"); |
---|
| 153 | + arc4_setkey(&state->arc4, state->sha1_digest, state->keylen); |
---|
| 154 | + arc4_crypt(&state->arc4, state->session_key, state->sha1_digest, |
---|
| 155 | + state->keylen); |
---|
176 | 156 | } else { |
---|
177 | 157 | memcpy(state->session_key, state->sha1_digest, state->keylen); |
---|
178 | 158 | } |
---|
.. | .. |
---|
182 | 162 | state->session_key[1] = 0x26; |
---|
183 | 163 | state->session_key[2] = 0x9e; |
---|
184 | 164 | } |
---|
185 | | - crypto_skcipher_setkey(state->arc4, state->session_key, state->keylen); |
---|
186 | | - skcipher_request_zero(req); |
---|
| 165 | + arc4_setkey(&state->arc4, state->session_key, state->keylen); |
---|
187 | 166 | } |
---|
188 | 167 | |
---|
189 | 168 | /* |
---|
.. | .. |
---|
196 | 175 | unsigned int digestsize; |
---|
197 | 176 | |
---|
198 | 177 | if (optlen != CILEN_MPPE + sizeof(state->master_key) || |
---|
199 | | - options[0] != CI_MPPE || options[1] != CILEN_MPPE) |
---|
| 178 | + options[0] != CI_MPPE || options[1] != CILEN_MPPE || |
---|
| 179 | + fips_enabled) |
---|
200 | 180 | goto out; |
---|
201 | 181 | |
---|
202 | 182 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
---|
203 | 183 | if (state == NULL) |
---|
204 | 184 | goto out; |
---|
205 | 185 | |
---|
206 | | - |
---|
207 | | - state->arc4 = crypto_alloc_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
---|
208 | | - if (IS_ERR(state->arc4)) { |
---|
209 | | - state->arc4 = NULL; |
---|
210 | | - goto out_free; |
---|
211 | | - } |
---|
212 | 186 | |
---|
213 | 187 | shash = crypto_alloc_shash("sha1", 0, 0); |
---|
214 | 188 | if (IS_ERR(shash)) |
---|
.. | .. |
---|
222 | 196 | goto out_free; |
---|
223 | 197 | } |
---|
224 | 198 | state->sha1->tfm = shash; |
---|
225 | | - state->sha1->flags = 0; |
---|
226 | 199 | |
---|
227 | 200 | digestsize = crypto_shash_digestsize(shash); |
---|
228 | 201 | if (digestsize < MPPE_MAX_KEY_LEN) |
---|
.. | .. |
---|
249 | 222 | kfree(state->sha1_digest); |
---|
250 | 223 | if (state->sha1) { |
---|
251 | 224 | crypto_free_shash(state->sha1->tfm); |
---|
252 | | - kzfree(state->sha1); |
---|
| 225 | + kfree_sensitive(state->sha1); |
---|
253 | 226 | } |
---|
254 | | - crypto_free_skcipher(state->arc4); |
---|
255 | 227 | kfree(state); |
---|
256 | 228 | out: |
---|
257 | 229 | return NULL; |
---|
.. | .. |
---|
266 | 238 | if (state) { |
---|
267 | 239 | kfree(state->sha1_digest); |
---|
268 | 240 | crypto_free_shash(state->sha1->tfm); |
---|
269 | | - kzfree(state->sha1); |
---|
270 | | - crypto_free_skcipher(state->arc4); |
---|
271 | | - kfree(state); |
---|
| 241 | + kfree_sensitive(state->sha1); |
---|
| 242 | + kfree_sensitive(state); |
---|
272 | 243 | } |
---|
273 | 244 | } |
---|
274 | 245 | |
---|
.. | .. |
---|
367 | 338 | int isize, int osize) |
---|
368 | 339 | { |
---|
369 | 340 | struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; |
---|
370 | | - SKCIPHER_REQUEST_ON_STACK(req, state->arc4); |
---|
371 | 341 | int proto; |
---|
372 | | - int err; |
---|
373 | | - struct scatterlist sg_in[1], sg_out[1]; |
---|
374 | 342 | |
---|
375 | 343 | /* |
---|
376 | 344 | * Check that the protocol is in the range we handle. |
---|
.. | .. |
---|
421 | 389 | ibuf += 2; /* skip to proto field */ |
---|
422 | 390 | isize -= 2; |
---|
423 | 391 | |
---|
424 | | - /* Encrypt packet */ |
---|
425 | | - sg_init_table(sg_in, 1); |
---|
426 | | - sg_init_table(sg_out, 1); |
---|
427 | | - setup_sg(sg_in, ibuf, isize); |
---|
428 | | - setup_sg(sg_out, obuf, osize); |
---|
429 | | - |
---|
430 | | - skcipher_request_set_tfm(req, state->arc4); |
---|
431 | | - skcipher_request_set_callback(req, 0, NULL, NULL); |
---|
432 | | - skcipher_request_set_crypt(req, sg_in, sg_out, isize, NULL); |
---|
433 | | - err = crypto_skcipher_encrypt(req); |
---|
434 | | - skcipher_request_zero(req); |
---|
435 | | - if (err) { |
---|
436 | | - printk(KERN_DEBUG "crypto_cypher_encrypt failed\n"); |
---|
437 | | - return -1; |
---|
438 | | - } |
---|
| 392 | + arc4_crypt(&state->arc4, obuf, ibuf, isize); |
---|
439 | 393 | |
---|
440 | 394 | state->stats.unc_bytes += isize; |
---|
441 | 395 | state->stats.unc_packets++; |
---|
.. | .. |
---|
481 | 435 | int osize) |
---|
482 | 436 | { |
---|
483 | 437 | struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; |
---|
484 | | - SKCIPHER_REQUEST_ON_STACK(req, state->arc4); |
---|
485 | 438 | unsigned ccount; |
---|
486 | 439 | int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED; |
---|
487 | | - struct scatterlist sg_in[1], sg_out[1]; |
---|
488 | 440 | |
---|
489 | 441 | if (isize <= PPP_HDRLEN + MPPE_OVHD) { |
---|
490 | 442 | if (state->debug) |
---|
.. | .. |
---|
611 | 563 | * Decrypt the first byte in order to check if it is |
---|
612 | 564 | * a compressed or uncompressed protocol field. |
---|
613 | 565 | */ |
---|
614 | | - sg_init_table(sg_in, 1); |
---|
615 | | - sg_init_table(sg_out, 1); |
---|
616 | | - setup_sg(sg_in, ibuf, 1); |
---|
617 | | - setup_sg(sg_out, obuf, 1); |
---|
618 | | - |
---|
619 | | - skcipher_request_set_tfm(req, state->arc4); |
---|
620 | | - skcipher_request_set_callback(req, 0, NULL, NULL); |
---|
621 | | - skcipher_request_set_crypt(req, sg_in, sg_out, 1, NULL); |
---|
622 | | - if (crypto_skcipher_decrypt(req)) { |
---|
623 | | - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); |
---|
624 | | - osize = DECOMP_ERROR; |
---|
625 | | - goto out_zap_req; |
---|
626 | | - } |
---|
| 566 | + arc4_crypt(&state->arc4, obuf, ibuf, 1); |
---|
627 | 567 | |
---|
628 | 568 | /* |
---|
629 | 569 | * Do PFC decompression. |
---|
.. | .. |
---|
638 | 578 | } |
---|
639 | 579 | |
---|
640 | 580 | /* And finally, decrypt the rest of the packet. */ |
---|
641 | | - setup_sg(sg_in, ibuf + 1, isize - 1); |
---|
642 | | - setup_sg(sg_out, obuf + 1, osize - 1); |
---|
643 | | - skcipher_request_set_crypt(req, sg_in, sg_out, isize - 1, NULL); |
---|
644 | | - if (crypto_skcipher_decrypt(req)) { |
---|
645 | | - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); |
---|
646 | | - osize = DECOMP_ERROR; |
---|
647 | | - goto out_zap_req; |
---|
648 | | - } |
---|
| 581 | + arc4_crypt(&state->arc4, obuf + 1, ibuf + 1, isize - 1); |
---|
649 | 582 | |
---|
650 | 583 | state->stats.unc_bytes += osize; |
---|
651 | 584 | state->stats.unc_packets++; |
---|
.. | .. |
---|
655 | 588 | /* good packet credit */ |
---|
656 | 589 | state->sanity_errors >>= 1; |
---|
657 | 590 | |
---|
658 | | -out_zap_req: |
---|
659 | | - skcipher_request_zero(req); |
---|
660 | 591 | return osize; |
---|
661 | 592 | |
---|
662 | 593 | sanity_error: |
---|
.. | .. |
---|
729 | 660 | static int __init ppp_mppe_init(void) |
---|
730 | 661 | { |
---|
731 | 662 | int answer; |
---|
732 | | - if (!(crypto_has_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC) && |
---|
733 | | - crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC))) |
---|
| 663 | + if (fips_enabled || !crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC)) |
---|
734 | 664 | return -ENODEV; |
---|
735 | 665 | |
---|
736 | 666 | sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL); |
---|