Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ppp: mppe: switch to RC4 library interface

The MPPE code uses the sync skcipher to invoke the ecb(arc4) skcipher,
of which only a single generic C code implementation exists. This means
that going through all the trouble of using scatterlists etc buys us
very little, and we're better off just invoking the arc4 library directly.

Note that the SHA1 shash used by this driver has several accelerated
implementations for various architectures, so retaining that part does
make sense.

Cc: linux-ppp@vger.kernel.org
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Ard Biesheuvel and committed by
Herbert Xu
0e5a610b 611a23c2

+15 -85
+1 -2
drivers/net/ppp/Kconfig
··· 86 86 depends on PPP 87 87 select CRYPTO 88 88 select CRYPTO_SHA1 89 - select CRYPTO_ARC4 90 - select CRYPTO_ECB 89 + select CRYPTO_LIB_ARC4 91 90 ---help--- 92 91 Support for the MPPE Encryption protocol, as employed by the 93 92 Microsoft Point-to-Point Tunneling Protocol.
+14 -83
drivers/net/ppp/ppp_mppe.c
··· 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> ··· 65 64 MODULE_LICENSE("Dual BSD/GPL"); 66 65 MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE)); 67 66 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 67 76 68 #define SHA1_PAD_SIZE 40 77 69 ··· 89 95 * State for an MPPE (de)compressor. 90 96 */ 91 97 struct ppp_mppe_state { 92 - struct crypto_sync_skcipher *arc4; 98 + struct arc4_ctx arc4; 93 99 struct shash_desc *sha1; 94 100 unsigned char *sha1_digest; 95 101 unsigned char master_key[MPPE_MAX_KEY_LEN]; ··· 148 154 */ 149 155 static void mppe_rekey(struct ppp_mppe_state * state, int initial_key) 150 156 { 151 - struct scatterlist sg_in[1], sg_out[1]; 152 - SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4); 153 - 154 - skcipher_request_set_sync_tfm(req, state->arc4); 155 - skcipher_request_set_callback(req, 0, NULL, NULL); 156 - 157 157 get_new_key_from_sha(state); 158 158 if (!initial_key) { 159 - crypto_sync_skcipher_setkey(state->arc4, state->sha1_digest, 160 - state->keylen); 161 - sg_init_table(sg_in, 1); 162 - sg_init_table(sg_out, 1); 163 - setup_sg(sg_in, state->sha1_digest, state->keylen); 164 - setup_sg(sg_out, state->session_key, state->keylen); 165 - skcipher_request_set_crypt(req, sg_in, sg_out, state->keylen, 166 - NULL); 167 - if (crypto_skcipher_encrypt(req)) 168 - printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n"); 159 + arc4_setkey(&state->arc4, state->sha1_digest, state->keylen); 160 + arc4_crypt(&state->arc4, state->session_key, state->sha1_digest, 161 + state->keylen); 169 162 } else { 170 163 memcpy(state->session_key, state->sha1_digest, state->keylen); 171 164 } ··· 162 181 state->session_key[1] = 0x26; 163 182 state->session_key[2] = 0x9e; 164 183 } 165 - crypto_sync_skcipher_setkey(state->arc4, state->session_key, 166 - state->keylen); 167 - skcipher_request_zero(req); 184 + arc4_setkey(&state->arc4, state->session_key, state->keylen); 168 185 } 169 186 170 187 /* ··· 175 196 unsigned int digestsize; 176 197 177 198 if (optlen != CILEN_MPPE + sizeof(state->master_key) || 178 - options[0] != CI_MPPE || options[1] != CILEN_MPPE) 199 + options[0] != CI_MPPE || options[1] != CILEN_MPPE || 200 + fips_enabled) 179 201 goto out; 180 202 181 203 state = kzalloc(sizeof(*state), GFP_KERNEL); 182 204 if (state == NULL) 183 205 goto out; 184 206 185 - 186 - state->arc4 = crypto_alloc_sync_skcipher("ecb(arc4)", 0, 0); 187 - if (IS_ERR(state->arc4)) { 188 - state->arc4 = NULL; 189 - goto out_free; 190 - } 191 207 192 208 shash = crypto_alloc_shash("sha1", 0, 0); 193 209 if (IS_ERR(shash)) ··· 224 250 crypto_free_shash(state->sha1->tfm); 225 251 kzfree(state->sha1); 226 252 } 227 - crypto_free_sync_skcipher(state->arc4); 228 253 kfree(state); 229 254 out: 230 255 return NULL; ··· 239 266 kfree(state->sha1_digest); 240 267 crypto_free_shash(state->sha1->tfm); 241 268 kzfree(state->sha1); 242 - crypto_free_sync_skcipher(state->arc4); 243 - kfree(state); 269 + kzfree(state); 244 270 } 245 271 } 246 272 ··· 338 366 int isize, int osize) 339 367 { 340 368 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; 341 - SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4); 342 369 int proto; 343 - int err; 344 - struct scatterlist sg_in[1], sg_out[1]; 345 370 346 371 /* 347 372 * Check that the protocol is in the range we handle. ··· 389 420 ibuf += 2; /* skip to proto field */ 390 421 isize -= 2; 391 422 392 - /* Encrypt packet */ 393 - sg_init_table(sg_in, 1); 394 - sg_init_table(sg_out, 1); 395 - setup_sg(sg_in, ibuf, isize); 396 - setup_sg(sg_out, obuf, osize); 397 - 398 - skcipher_request_set_sync_tfm(req, state->arc4); 399 - skcipher_request_set_callback(req, 0, NULL, NULL); 400 - skcipher_request_set_crypt(req, sg_in, sg_out, isize, NULL); 401 - err = crypto_skcipher_encrypt(req); 402 - skcipher_request_zero(req); 403 - if (err) { 404 - printk(KERN_DEBUG "crypto_cypher_encrypt failed\n"); 405 - return -1; 406 - } 423 + arc4_crypt(&state->arc4, obuf, ibuf, isize); 407 424 408 425 state->stats.unc_bytes += isize; 409 426 state->stats.unc_packets++; ··· 435 480 int osize) 436 481 { 437 482 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; 438 - SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4); 439 483 unsigned ccount; 440 484 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED; 441 - struct scatterlist sg_in[1], sg_out[1]; 442 485 443 486 if (isize <= PPP_HDRLEN + MPPE_OVHD) { 444 487 if (state->debug) ··· 563 610 * Decrypt the first byte in order to check if it is 564 611 * a compressed or uncompressed protocol field. 565 612 */ 566 - sg_init_table(sg_in, 1); 567 - sg_init_table(sg_out, 1); 568 - setup_sg(sg_in, ibuf, 1); 569 - setup_sg(sg_out, obuf, 1); 570 - 571 - skcipher_request_set_sync_tfm(req, state->arc4); 572 - skcipher_request_set_callback(req, 0, NULL, NULL); 573 - skcipher_request_set_crypt(req, sg_in, sg_out, 1, NULL); 574 - if (crypto_skcipher_decrypt(req)) { 575 - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); 576 - osize = DECOMP_ERROR; 577 - goto out_zap_req; 578 - } 613 + arc4_crypt(&state->arc4, obuf, ibuf, 1); 579 614 580 615 /* 581 616 * Do PFC decompression. ··· 578 637 } 579 638 580 639 /* And finally, decrypt the rest of the packet. */ 581 - setup_sg(sg_in, ibuf + 1, isize - 1); 582 - setup_sg(sg_out, obuf + 1, osize - 1); 583 - skcipher_request_set_crypt(req, sg_in, sg_out, isize - 1, NULL); 584 - if (crypto_skcipher_decrypt(req)) { 585 - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); 586 - osize = DECOMP_ERROR; 587 - goto out_zap_req; 588 - } 640 + arc4_crypt(&state->arc4, obuf + 1, ibuf + 1, isize - 1); 589 641 590 642 state->stats.unc_bytes += osize; 591 643 state->stats.unc_packets++; ··· 588 654 /* good packet credit */ 589 655 state->sanity_errors >>= 1; 590 656 591 - out_zap_req: 592 - skcipher_request_zero(req); 593 657 return osize; 594 658 595 659 sanity_error: ··· 660 728 static int __init ppp_mppe_init(void) 661 729 { 662 730 int answer; 663 - if (!(crypto_has_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC) && 664 - crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC))) 731 + if (fips_enabled || !crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC)) 665 732 return -ENODEV; 666 733 667 734 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);