Skip to content

Commit 0e5a610

Browse files
Ard Biesheuvelherbertx
authored andcommitted
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>
1 parent 611a23c commit 0e5a610

File tree

2 files changed

+15
-85
lines changed

2 files changed

+15
-85
lines changed

drivers/net/ppp/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ config PPP_MPPE
8686
depends on PPP
8787
select CRYPTO
8888
select CRYPTO_SHA1
89-
select CRYPTO_ARC4
90-
select CRYPTO_ECB
89+
select CRYPTO_LIB_ARC4
9190
---help---
9291
Support for the MPPE Encryption protocol, as employed by the
9392
Microsoft Point-to-Point Tunneling Protocol.

drivers/net/ppp/ppp_mppe.c

Lines changed: 14 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@
4242
* deprecated in 2.6
4343
*/
4444

45+
#include <crypto/arc4.h>
4546
#include <crypto/hash.h>
46-
#include <crypto/skcipher.h>
4747
#include <linux/err.h>
48+
#include <linux/fips.h>
4849
#include <linux/module.h>
4950
#include <linux/kernel.h>
5051
#include <linux/init.h>
@@ -65,13 +66,6 @@ MODULE_LICENSE("Dual BSD/GPL");
6566
MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
6667
MODULE_VERSION("1.0.2");
6768

68-
static unsigned int
69-
setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
70-
{
71-
sg_set_buf(sg, address, length);
72-
return length;
73-
}
74-
7569
#define SHA1_PAD_SIZE 40
7670

7771
/*
@@ -95,7 +89,7 @@ static inline void sha_pad_init(struct sha_pad *shapad)
9589
* State for an MPPE (de)compressor.
9690
*/
9791
struct ppp_mppe_state {
98-
struct crypto_sync_skcipher *arc4;
92+
struct arc4_ctx arc4;
9993
struct shash_desc *sha1;
10094
unsigned char *sha1_digest;
10195
unsigned char master_key[MPPE_MAX_KEY_LEN];
@@ -154,24 +148,11 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state)
154148
*/
155149
static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
156150
{
157-
struct scatterlist sg_in[1], sg_out[1];
158-
SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4);
159-
160-
skcipher_request_set_sync_tfm(req, state->arc4);
161-
skcipher_request_set_callback(req, 0, NULL, NULL);
162-
163151
get_new_key_from_sha(state);
164152
if (!initial_key) {
165-
crypto_sync_skcipher_setkey(state->arc4, state->sha1_digest,
166-
state->keylen);
167-
sg_init_table(sg_in, 1);
168-
sg_init_table(sg_out, 1);
169-
setup_sg(sg_in, state->sha1_digest, state->keylen);
170-
setup_sg(sg_out, state->session_key, state->keylen);
171-
skcipher_request_set_crypt(req, sg_in, sg_out, state->keylen,
172-
NULL);
173-
if (crypto_skcipher_encrypt(req))
174-
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);
175156
} else {
176157
memcpy(state->session_key, state->sha1_digest, state->keylen);
177158
}
@@ -181,9 +162,7 @@ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
181162
state->session_key[1] = 0x26;
182163
state->session_key[2] = 0x9e;
183164
}
184-
crypto_sync_skcipher_setkey(state->arc4, state->session_key,
185-
state->keylen);
186-
skcipher_request_zero(req);
165+
arc4_setkey(&state->arc4, state->session_key, state->keylen);
187166
}
188167

189168
/*
@@ -196,20 +175,15 @@ static void *mppe_alloc(unsigned char *options, int optlen)
196175
unsigned int digestsize;
197176

198177
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)
200180
goto out;
201181

202182
state = kzalloc(sizeof(*state), GFP_KERNEL);
203183
if (state == NULL)
204184
goto out;
205185

206186

207-
state->arc4 = crypto_alloc_sync_skcipher("ecb(arc4)", 0, 0);
208-
if (IS_ERR(state->arc4)) {
209-
state->arc4 = NULL;
210-
goto out_free;
211-
}
212-
213187
shash = crypto_alloc_shash("sha1", 0, 0);
214188
if (IS_ERR(shash))
215189
goto out_free;
@@ -250,7 +224,6 @@ static void *mppe_alloc(unsigned char *options, int optlen)
250224
crypto_free_shash(state->sha1->tfm);
251225
kzfree(state->sha1);
252226
}
253-
crypto_free_sync_skcipher(state->arc4);
254227
kfree(state);
255228
out:
256229
return NULL;
@@ -266,8 +239,7 @@ static void mppe_free(void *arg)
266239
kfree(state->sha1_digest);
267240
crypto_free_shash(state->sha1->tfm);
268241
kzfree(state->sha1);
269-
crypto_free_sync_skcipher(state->arc4);
270-
kfree(state);
242+
kzfree(state);
271243
}
272244
}
273245

@@ -366,10 +338,7 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
366338
int isize, int osize)
367339
{
368340
struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
369-
SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4);
370341
int proto;
371-
int err;
372-
struct scatterlist sg_in[1], sg_out[1];
373342

374343
/*
375344
* Check that the protocol is in the range we handle.
@@ -420,21 +389,7 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
420389
ibuf += 2; /* skip to proto field */
421390
isize -= 2;
422391

423-
/* Encrypt packet */
424-
sg_init_table(sg_in, 1);
425-
sg_init_table(sg_out, 1);
426-
setup_sg(sg_in, ibuf, isize);
427-
setup_sg(sg_out, obuf, osize);
428-
429-
skcipher_request_set_sync_tfm(req, state->arc4);
430-
skcipher_request_set_callback(req, 0, NULL, NULL);
431-
skcipher_request_set_crypt(req, sg_in, sg_out, isize, NULL);
432-
err = crypto_skcipher_encrypt(req);
433-
skcipher_request_zero(req);
434-
if (err) {
435-
printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
436-
return -1;
437-
}
392+
arc4_crypt(&state->arc4, obuf, ibuf, isize);
438393

439394
state->stats.unc_bytes += isize;
440395
state->stats.unc_packets++;
@@ -480,10 +435,8 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
480435
int osize)
481436
{
482437
struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
483-
SYNC_SKCIPHER_REQUEST_ON_STACK(req, state->arc4);
484438
unsigned ccount;
485439
int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
486-
struct scatterlist sg_in[1], sg_out[1];
487440

488441
if (isize <= PPP_HDRLEN + MPPE_OVHD) {
489442
if (state->debug)
@@ -610,19 +563,7 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
610563
* Decrypt the first byte in order to check if it is
611564
* a compressed or uncompressed protocol field.
612565
*/
613-
sg_init_table(sg_in, 1);
614-
sg_init_table(sg_out, 1);
615-
setup_sg(sg_in, ibuf, 1);
616-
setup_sg(sg_out, obuf, 1);
617-
618-
skcipher_request_set_sync_tfm(req, state->arc4);
619-
skcipher_request_set_callback(req, 0, NULL, NULL);
620-
skcipher_request_set_crypt(req, sg_in, sg_out, 1, NULL);
621-
if (crypto_skcipher_decrypt(req)) {
622-
printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
623-
osize = DECOMP_ERROR;
624-
goto out_zap_req;
625-
}
566+
arc4_crypt(&state->arc4, obuf, ibuf, 1);
626567

627568
/*
628569
* Do PFC decompression.
@@ -637,14 +578,7 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
637578
}
638579

639580
/* And finally, decrypt the rest of the packet. */
640-
setup_sg(sg_in, ibuf + 1, isize - 1);
641-
setup_sg(sg_out, obuf + 1, osize - 1);
642-
skcipher_request_set_crypt(req, sg_in, sg_out, isize - 1, NULL);
643-
if (crypto_skcipher_decrypt(req)) {
644-
printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
645-
osize = DECOMP_ERROR;
646-
goto out_zap_req;
647-
}
581+
arc4_crypt(&state->arc4, obuf + 1, ibuf + 1, isize - 1);
648582

649583
state->stats.unc_bytes += osize;
650584
state->stats.unc_packets++;
@@ -654,8 +588,6 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
654588
/* good packet credit */
655589
state->sanity_errors >>= 1;
656590

657-
out_zap_req:
658-
skcipher_request_zero(req);
659591
return osize;
660592

661593
sanity_error:
@@ -728,8 +660,7 @@ static struct compressor ppp_mppe = {
728660
static int __init ppp_mppe_init(void)
729661
{
730662
int answer;
731-
if (!(crypto_has_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC) &&
732-
crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC)))
663+
if (fips_enabled || !crypto_has_ahash("sha1", 0, CRYPTO_ALG_ASYNC))
733664
return -ENODEV;
734665

735666
sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);

0 commit comments

Comments
 (0)