ppp_mppe.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. * ppp_mppe.c - interface MPPE to the PPP code.
  3. * This version is for use with Linux kernel 2.6.14+
  4. *
  5. * By Frank Cusack <fcusack@fcusack.com>.
  6. * Copyright (c) 2002,2003,2004 Google, Inc.
  7. * All rights reserved.
  8. *
  9. * License:
  10. * Permission to use, copy, modify, and distribute this software and its
  11. * documentation is hereby granted, provided that the above copyright
  12. * notice appears in all copies. This software is provided without any
  13. * warranty, express or implied.
  14. *
  15. * ALTERNATIVELY, provided that this notice is retained in full, this product
  16. * may be distributed under the terms of the GNU General Public License (GPL),
  17. * in which case the provisions of the GPL apply INSTEAD OF those given above.
  18. *
  19. * This program is free software; you can redistribute it and/or modify
  20. * it under the terms of the GNU General Public License as published by
  21. * the Free Software Foundation; either version 2 of the License, or
  22. * (at your option) any later version.
  23. *
  24. * This program is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. * GNU General Public License for more details.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  31. *
  32. *
  33. * Changelog:
  34. * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
  35. * Only need extra skb padding on transmit, not receive.
  36. * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
  37. * Use Linux kernel 2.6 arc4 and sha1 routines rather than
  38. * providing our own.
  39. * 2/15/04 - TS: added #include <version.h> and testing for Kernel
  40. * version before using
  41. * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
  42. * deprecated in 2.6
  43. */
  44. #include <crypto/arc4.h>
  45. #include <crypto/sha1.h>
  46. #include <linux/err.h>
  47. #include <linux/fips.h>
  48. #include <linux/module.h>
  49. #include <linux/kernel.h>
  50. #include <linux/init.h>
  51. #include <linux/types.h>
  52. #include <linux/slab.h>
  53. #include <linux/string.h>
  54. #include <linux/mm.h>
  55. #include <linux/ppp_defs.h>
  56. #include <linux/ppp-comp.h>
  57. #include <linux/unaligned.h>
  58. #include "ppp_mppe.h"
  59. MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
  60. MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
  61. MODULE_LICENSE("Dual BSD/GPL");
  62. MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
  63. MODULE_VERSION("1.0.2");
  64. #define SHA1_PAD_SIZE 40
  65. static const u8 sha_pad1[SHA1_PAD_SIZE] = { 0 };
  66. static const u8 sha_pad2[SHA1_PAD_SIZE] = { [0 ... SHA1_PAD_SIZE - 1] = 0xF2 };
  67. /*
  68. * State for an MPPE (de)compressor.
  69. */
  70. struct ppp_mppe_state {
  71. struct arc4_ctx arc4;
  72. unsigned char sha1_digest[SHA1_DIGEST_SIZE];
  73. unsigned char master_key[MPPE_MAX_KEY_LEN];
  74. unsigned char session_key[MPPE_MAX_KEY_LEN];
  75. unsigned keylen; /* key length in bytes */
  76. /* NB: 128-bit == 16, 40-bit == 8! */
  77. /* If we want to support 56-bit, */
  78. /* the unit has to change to bits */
  79. unsigned char bits; /* MPPE control bits */
  80. unsigned ccount; /* 12-bit coherency count (seqno) */
  81. unsigned stateful; /* stateful mode flag */
  82. int discard; /* stateful mode packet loss flag */
  83. int sanity_errors; /* take down LCP if too many */
  84. int unit;
  85. int debug;
  86. struct compstat stats;
  87. };
  88. /* struct ppp_mppe_state.bits definitions */
  89. #define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
  90. #define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
  91. #define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
  92. #define MPPE_BIT_D 0x10 /* This is an encrypted frame */
  93. #define MPPE_BIT_FLUSHED MPPE_BIT_A
  94. #define MPPE_BIT_ENCRYPTED MPPE_BIT_D
  95. #define MPPE_BITS(p) ((p)[4] & 0xf0)
  96. #define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
  97. #define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
  98. #define MPPE_OVHD 2 /* MPPE overhead/packet */
  99. #define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
  100. /*
  101. * Key Derivation, from RFC 3078, RFC 3079.
  102. * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
  103. */
  104. static void get_new_key_from_sha(struct ppp_mppe_state * state)
  105. {
  106. struct sha1_ctx ctx;
  107. sha1_init(&ctx);
  108. sha1_update(&ctx, state->master_key, state->keylen);
  109. sha1_update(&ctx, sha_pad1, sizeof(sha_pad1));
  110. sha1_update(&ctx, state->session_key, state->keylen);
  111. sha1_update(&ctx, sha_pad2, sizeof(sha_pad2));
  112. sha1_final(&ctx, state->sha1_digest);
  113. }
  114. /*
  115. * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
  116. * Well, not what's written there, but rather what they meant.
  117. */
  118. static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
  119. {
  120. get_new_key_from_sha(state);
  121. if (!initial_key) {
  122. arc4_setkey(&state->arc4, state->sha1_digest, state->keylen);
  123. arc4_crypt(&state->arc4, state->session_key, state->sha1_digest,
  124. state->keylen);
  125. } else {
  126. memcpy(state->session_key, state->sha1_digest, state->keylen);
  127. }
  128. if (state->keylen == 8) {
  129. /* See RFC 3078 */
  130. state->session_key[0] = 0xd1;
  131. state->session_key[1] = 0x26;
  132. state->session_key[2] = 0x9e;
  133. }
  134. arc4_setkey(&state->arc4, state->session_key, state->keylen);
  135. }
  136. /*
  137. * Allocate space for a (de)compressor.
  138. */
  139. static void *mppe_alloc(unsigned char *options, int optlen)
  140. {
  141. struct ppp_mppe_state *state;
  142. if (optlen != CILEN_MPPE + sizeof(state->master_key) ||
  143. options[0] != CI_MPPE || options[1] != CILEN_MPPE ||
  144. fips_enabled)
  145. return NULL;
  146. state = kzalloc_obj(*state);
  147. if (state == NULL)
  148. return NULL;
  149. /* Save keys. */
  150. memcpy(state->master_key, &options[CILEN_MPPE],
  151. sizeof(state->master_key));
  152. memcpy(state->session_key, state->master_key,
  153. sizeof(state->master_key));
  154. /*
  155. * We defer initial key generation until mppe_init(), as mppe_alloc()
  156. * is called frequently during negotiation.
  157. */
  158. return (void *)state;
  159. }
  160. /*
  161. * Deallocate space for a (de)compressor.
  162. */
  163. static void mppe_free(void *arg)
  164. {
  165. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  166. kfree_sensitive(state);
  167. }
  168. /*
  169. * Initialize (de)compressor state.
  170. */
  171. static int
  172. mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
  173. const char *debugstr)
  174. {
  175. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  176. unsigned char mppe_opts;
  177. if (optlen != CILEN_MPPE ||
  178. options[0] != CI_MPPE || options[1] != CILEN_MPPE)
  179. return 0;
  180. MPPE_CI_TO_OPTS(&options[2], mppe_opts);
  181. if (mppe_opts & MPPE_OPT_128)
  182. state->keylen = 16;
  183. else if (mppe_opts & MPPE_OPT_40)
  184. state->keylen = 8;
  185. else {
  186. printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
  187. unit);
  188. return 0;
  189. }
  190. if (mppe_opts & MPPE_OPT_STATEFUL)
  191. state->stateful = 1;
  192. /* Generate the initial session key. */
  193. mppe_rekey(state, 1);
  194. if (debug) {
  195. printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
  196. debugstr, unit, (state->keylen == 16) ? 128 : 40,
  197. (state->stateful) ? "stateful" : "stateless");
  198. printk(KERN_DEBUG
  199. "%s[%d]: keys: master: %*phN initial session: %*phN\n",
  200. debugstr, unit,
  201. (int)sizeof(state->master_key), state->master_key,
  202. (int)sizeof(state->session_key), state->session_key);
  203. }
  204. /*
  205. * Initialize the coherency count. The initial value is not specified
  206. * in RFC 3078, but we can make a reasonable assumption that it will
  207. * start at 0. Setting it to the max here makes the comp/decomp code
  208. * do the right thing (determined through experiment).
  209. */
  210. state->ccount = MPPE_CCOUNT_SPACE - 1;
  211. /*
  212. * Note that even though we have initialized the key table, we don't
  213. * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
  214. */
  215. state->bits = MPPE_BIT_ENCRYPTED;
  216. state->unit = unit;
  217. state->debug = debug;
  218. return 1;
  219. }
  220. static int
  221. mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
  222. int hdrlen, int debug)
  223. {
  224. /* ARGSUSED */
  225. return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
  226. }
  227. /*
  228. * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
  229. * tell the compressor to rekey. Note that we MUST NOT rekey for
  230. * every CCP Reset-Request; we only rekey on the next xmit packet.
  231. * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
  232. * So, rekeying for every CCP Reset-Request is broken as the peer will not
  233. * know how many times we've rekeyed. (If we rekey and THEN get another
  234. * CCP Reset-Request, we must rekey again.)
  235. */
  236. static void mppe_comp_reset(void *arg)
  237. {
  238. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  239. state->bits |= MPPE_BIT_FLUSHED;
  240. }
  241. /*
  242. * Compress (encrypt) a packet.
  243. * It's strange to call this a compressor, since the output is always
  244. * MPPE_OVHD + 2 bytes larger than the input.
  245. */
  246. static int
  247. mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
  248. int isize, int osize)
  249. {
  250. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  251. int proto;
  252. /*
  253. * Check that the protocol is in the range we handle.
  254. */
  255. proto = PPP_PROTOCOL(ibuf);
  256. if (proto < 0x0021 || proto > 0x00fa)
  257. return 0;
  258. /* Make sure we have enough room to generate an encrypted packet. */
  259. if (osize < isize + MPPE_OVHD + 2) {
  260. /* Drop the packet if we should encrypt it, but can't. */
  261. printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
  262. "(have: %d need: %d)\n", state->unit,
  263. osize, osize + MPPE_OVHD + 2);
  264. return -1;
  265. }
  266. osize = isize + MPPE_OVHD + 2;
  267. /*
  268. * Copy over the PPP header and set control bits.
  269. */
  270. obuf[0] = PPP_ADDRESS(ibuf);
  271. obuf[1] = PPP_CONTROL(ibuf);
  272. put_unaligned_be16(PPP_COMP, obuf + 2);
  273. obuf += PPP_HDRLEN;
  274. state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
  275. if (state->debug >= 7)
  276. printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
  277. state->ccount);
  278. put_unaligned_be16(state->ccount, obuf);
  279. if (!state->stateful || /* stateless mode */
  280. ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
  281. (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
  282. /* We must rekey */
  283. if (state->debug && state->stateful)
  284. printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
  285. state->unit);
  286. mppe_rekey(state, 0);
  287. state->bits |= MPPE_BIT_FLUSHED;
  288. }
  289. obuf[0] |= state->bits;
  290. state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
  291. obuf += MPPE_OVHD;
  292. ibuf += 2; /* skip to proto field */
  293. isize -= 2;
  294. arc4_crypt(&state->arc4, obuf, ibuf, isize);
  295. state->stats.unc_bytes += isize;
  296. state->stats.unc_packets++;
  297. state->stats.comp_bytes += osize;
  298. state->stats.comp_packets++;
  299. return osize;
  300. }
  301. /*
  302. * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
  303. * to look bad ... and the longer the link is up the worse it will get.
  304. */
  305. static void mppe_comp_stats(void *arg, struct compstat *stats)
  306. {
  307. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  308. *stats = state->stats;
  309. }
  310. static int
  311. mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
  312. int hdrlen, int mru, int debug)
  313. {
  314. /* ARGSUSED */
  315. return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
  316. }
  317. /*
  318. * We received a CCP Reset-Ack. Just ignore it.
  319. */
  320. static void mppe_decomp_reset(void *arg)
  321. {
  322. /* ARGSUSED */
  323. return;
  324. }
  325. /*
  326. * Decompress (decrypt) an MPPE packet.
  327. */
  328. static int
  329. mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
  330. int osize)
  331. {
  332. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  333. unsigned ccount;
  334. int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
  335. if (isize <= PPP_HDRLEN + MPPE_OVHD) {
  336. if (state->debug)
  337. printk(KERN_DEBUG
  338. "mppe_decompress[%d]: short pkt (%d)\n",
  339. state->unit, isize);
  340. return DECOMP_ERROR;
  341. }
  342. /*
  343. * Make sure we have enough room to decrypt the packet.
  344. * Note that for our test we only subtract 1 byte whereas in
  345. * mppe_compress() we added 2 bytes (+MPPE_OVHD);
  346. * this is to account for possible PFC.
  347. */
  348. if (osize < isize - MPPE_OVHD - 1) {
  349. printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
  350. "(have: %d need: %d)\n", state->unit,
  351. osize, isize - MPPE_OVHD - 1);
  352. return DECOMP_ERROR;
  353. }
  354. osize = isize - MPPE_OVHD - 2; /* assume no PFC */
  355. ccount = MPPE_CCOUNT(ibuf);
  356. if (state->debug >= 7)
  357. printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
  358. state->unit, ccount);
  359. /* sanity checks -- terminate with extreme prejudice */
  360. if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
  361. printk(KERN_DEBUG
  362. "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
  363. state->unit);
  364. state->sanity_errors += 100;
  365. goto sanity_error;
  366. }
  367. if (!state->stateful && !flushed) {
  368. printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
  369. "stateless mode!\n", state->unit);
  370. state->sanity_errors += 100;
  371. goto sanity_error;
  372. }
  373. if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
  374. printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
  375. "flag packet!\n", state->unit);
  376. state->sanity_errors += 100;
  377. goto sanity_error;
  378. }
  379. /*
  380. * Check the coherency count.
  381. */
  382. if (!state->stateful) {
  383. /* Discard late packet */
  384. if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE
  385. > MPPE_CCOUNT_SPACE / 2) {
  386. state->sanity_errors++;
  387. goto sanity_error;
  388. }
  389. /* RFC 3078, sec 8.1. Rekey for every packet. */
  390. while (state->ccount != ccount) {
  391. mppe_rekey(state, 0);
  392. state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
  393. }
  394. } else {
  395. /* RFC 3078, sec 8.2. */
  396. if (!state->discard) {
  397. /* normal state */
  398. state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
  399. if (ccount != state->ccount) {
  400. /*
  401. * (ccount > state->ccount)
  402. * Packet loss detected, enter the discard state.
  403. * Signal the peer to rekey (by sending a CCP Reset-Request).
  404. */
  405. state->discard = 1;
  406. return DECOMP_ERROR;
  407. }
  408. } else {
  409. /* discard state */
  410. if (!flushed) {
  411. /* ccp.c will be silent (no additional CCP Reset-Requests). */
  412. return DECOMP_ERROR;
  413. } else {
  414. /* Rekey for every missed "flag" packet. */
  415. while ((ccount & ~0xff) !=
  416. (state->ccount & ~0xff)) {
  417. mppe_rekey(state, 0);
  418. state->ccount =
  419. (state->ccount +
  420. 256) % MPPE_CCOUNT_SPACE;
  421. }
  422. /* reset */
  423. state->discard = 0;
  424. state->ccount = ccount;
  425. /*
  426. * Another problem with RFC 3078 here. It implies that the
  427. * peer need not send a Reset-Ack packet. But RFC 1962
  428. * requires it. Hopefully, M$ does send a Reset-Ack; even
  429. * though it isn't required for MPPE synchronization, it is
  430. * required to reset CCP state.
  431. */
  432. }
  433. }
  434. if (flushed)
  435. mppe_rekey(state, 0);
  436. }
  437. /*
  438. * Fill in the first part of the PPP header. The protocol field
  439. * comes from the decrypted data.
  440. */
  441. obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
  442. obuf[1] = PPP_CONTROL(ibuf); /* +1 */
  443. obuf += 2;
  444. ibuf += PPP_HDRLEN + MPPE_OVHD;
  445. isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
  446. /* net osize: isize-4 */
  447. /*
  448. * Decrypt the first byte in order to check if it is
  449. * a compressed or uncompressed protocol field.
  450. */
  451. arc4_crypt(&state->arc4, obuf, ibuf, 1);
  452. /*
  453. * Do PFC decompression.
  454. * This would be nicer if we were given the actual sk_buff
  455. * instead of a char *.
  456. */
  457. if ((obuf[0] & 0x01) != 0) {
  458. obuf[1] = obuf[0];
  459. obuf[0] = 0;
  460. obuf++;
  461. osize++;
  462. }
  463. /* And finally, decrypt the rest of the packet. */
  464. arc4_crypt(&state->arc4, obuf + 1, ibuf + 1, isize - 1);
  465. state->stats.unc_bytes += osize;
  466. state->stats.unc_packets++;
  467. state->stats.comp_bytes += isize;
  468. state->stats.comp_packets++;
  469. /* good packet credit */
  470. state->sanity_errors >>= 1;
  471. return osize;
  472. sanity_error:
  473. if (state->sanity_errors < SANITY_MAX)
  474. return DECOMP_ERROR;
  475. else
  476. /* Take LCP down if the peer is sending too many bogons.
  477. * We don't want to do this for a single or just a few
  478. * instances since it could just be due to packet corruption.
  479. */
  480. return DECOMP_FATALERROR;
  481. }
  482. /*
  483. * Incompressible data has arrived (this should never happen!).
  484. * We should probably drop the link if the protocol is in the range
  485. * of what should be encrypted. At the least, we should drop this
  486. * packet. (How to do this?)
  487. */
  488. static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
  489. {
  490. struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
  491. if (state->debug &&
  492. (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
  493. printk(KERN_DEBUG
  494. "mppe_incomp[%d]: incompressible (unencrypted) data! "
  495. "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
  496. state->stats.inc_bytes += icnt;
  497. state->stats.inc_packets++;
  498. state->stats.unc_bytes += icnt;
  499. state->stats.unc_packets++;
  500. }
  501. /*************************************************************
  502. * Module interface table
  503. *************************************************************/
  504. /*
  505. * Procedures exported to if_ppp.c.
  506. */
  507. static struct compressor ppp_mppe = {
  508. .compress_proto = CI_MPPE,
  509. .comp_alloc = mppe_alloc,
  510. .comp_free = mppe_free,
  511. .comp_init = mppe_comp_init,
  512. .comp_reset = mppe_comp_reset,
  513. .compress = mppe_compress,
  514. .comp_stat = mppe_comp_stats,
  515. .decomp_alloc = mppe_alloc,
  516. .decomp_free = mppe_free,
  517. .decomp_init = mppe_decomp_init,
  518. .decomp_reset = mppe_decomp_reset,
  519. .decompress = mppe_decompress,
  520. .incomp = mppe_incomp,
  521. .decomp_stat = mppe_comp_stats,
  522. .owner = THIS_MODULE,
  523. .comp_extra = MPPE_PAD,
  524. };
  525. static int __init ppp_mppe_init(void)
  526. {
  527. int answer;
  528. if (fips_enabled)
  529. return -ENODEV;
  530. answer = ppp_register_compressor(&ppp_mppe);
  531. if (answer == 0)
  532. printk(KERN_INFO "PPP MPPE Compression module registered\n");
  533. return answer;
  534. }
  535. static void __exit ppp_mppe_cleanup(void)
  536. {
  537. ppp_unregister_compressor(&ppp_mppe);
  538. }
  539. module_init(ppp_mppe_init);
  540. module_exit(ppp_mppe_cleanup);