1 /* 2 * mppe.h - Definitions for MPPE 3 * 4 * Copyright (c) 2008 Paul Mackerras. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * 3. The name(s) of the authors of this software must not be used to 19 * endorse or promote products derived from this software without 20 * prior written permission. 21 * 22 * 4. Redistributions of any form whatsoever must retain the following 23 * acknowledgment: 24 * "This product includes software developed by Paul Mackerras 25 * <paulus@samba.org>". 26 * 27 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 28 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 29 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 30 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 31 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 32 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 33 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 34 */ 35 36 #include "netif/ppp/ppp_opts.h" 37 #if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ 38 39 #ifndef MPPE_H 40 #define MPPE_H 41 42 #include "netif/ppp/pppcrypt.h" 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 #define MPPE_PAD 4 /* MPPE growth per frame */ 49 #define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ 50 51 /* option bits for ccp_options.mppe */ 52 #define MPPE_OPT_40 0x01 /* 40 bit */ 53 #define MPPE_OPT_128 0x02 /* 128 bit */ 54 #define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ 55 /* unsupported opts */ 56 #define MPPE_OPT_56 0x08 /* 56 bit */ 57 #define MPPE_OPT_MPPC 0x10 /* MPPC compression */ 58 #define MPPE_OPT_D 0x20 /* Unknown */ 59 #define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) 60 #define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ 61 62 /* 63 * This is not nice ... the alternative is a bitfield struct though. 64 * And unfortunately, we cannot share the same bits for the option 65 * names above since C and H are the same bit. We could do a u_int32 66 * but then we have to do a lwip_htonl() all the time and/or we still need 67 * to know which octet is which. 68 */ 69 #define MPPE_C_BIT 0x01 /* MPPC */ 70 #define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ 71 #define MPPE_L_BIT 0x20 /* 40-bit */ 72 #define MPPE_S_BIT 0x40 /* 128-bit */ 73 #define MPPE_M_BIT 0x80 /* 56-bit, not supported */ 74 #define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ 75 76 /* Does not include H bit; used for least significant octet only. */ 77 #define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) 78 79 /* Build a CI from mppe opts (see RFC 3078) */ 80 #define MPPE_OPTS_TO_CI(opts, ci) \ 81 do { \ 82 u_char *ptr = ci; /* u_char[4] */ \ 83 \ 84 /* H bit */ \ 85 if (opts & MPPE_OPT_STATEFUL) \ 86 *ptr++ = 0x0; \ 87 else \ 88 *ptr++ = MPPE_H_BIT; \ 89 *ptr++ = 0; \ 90 *ptr++ = 0; \ 91 \ 92 /* S,L bits */ \ 93 *ptr = 0; \ 94 if (opts & MPPE_OPT_128) \ 95 *ptr |= MPPE_S_BIT; \ 96 if (opts & MPPE_OPT_40) \ 97 *ptr |= MPPE_L_BIT; \ 98 /* M,D,C bits not supported */ \ 99 } while (/* CONSTCOND */ 0) 100 101 /* The reverse of the above */ 102 #define MPPE_CI_TO_OPTS(ci, opts) \ 103 do { \ 104 const u_char *ptr = ci; /* u_char[4] */ \ 105 \ 106 opts = 0; \ 107 \ 108 /* H bit */ \ 109 if (!(ptr[0] & MPPE_H_BIT)) \ 110 opts |= MPPE_OPT_STATEFUL; \ 111 \ 112 /* S,L bits */ \ 113 if (ptr[3] & MPPE_S_BIT) \ 114 opts |= MPPE_OPT_128; \ 115 if (ptr[3] & MPPE_L_BIT) \ 116 opts |= MPPE_OPT_40; \ 117 \ 118 /* M,D,C bits */ \ 119 if (ptr[3] & MPPE_M_BIT) \ 120 opts |= MPPE_OPT_56; \ 121 if (ptr[3] & MPPE_D_BIT) \ 122 opts |= MPPE_OPT_D; \ 123 if (ptr[3] & MPPE_C_BIT) \ 124 opts |= MPPE_OPT_MPPC; \ 125 \ 126 /* Other bits */ \ 127 if (ptr[0] & ~MPPE_H_BIT) \ 128 opts |= MPPE_OPT_UNKNOWN; \ 129 if (ptr[1] || ptr[2]) \ 130 opts |= MPPE_OPT_UNKNOWN; \ 131 if (ptr[3] & ~MPPE_ALL_BITS) \ 132 opts |= MPPE_OPT_UNKNOWN; \ 133 } while (/* CONSTCOND */ 0) 134 135 /* Shared MPPE padding between MSCHAP and MPPE */ 136 #define SHA1_PAD_SIZE 40 137 138 static const u8_t mppe_sha1_pad1[SHA1_PAD_SIZE] = { 139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 143 }; 144 static const u8_t mppe_sha1_pad2[SHA1_PAD_SIZE] = { 145 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 146 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 147 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 148 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 149 }; 150 151 /* 152 * State for an MPPE (de)compressor. 153 */ 154 typedef struct ppp_mppe_state { 155 lwip_arc4_context arc4; 156 u8_t master_key[MPPE_MAX_KEY_LEN]; 157 u8_t session_key[MPPE_MAX_KEY_LEN]; 158 u8_t keylen; /* key length in bytes */ 159 /* NB: 128-bit == 16, 40-bit == 8! 160 * If we want to support 56-bit, the unit has to change to bits 161 */ 162 u8_t bits; /* MPPE control bits */ 163 u16_t ccount; /* 12-bit coherency count (seqno) */ 164 u16_t sanity_errors; /* take down LCP if too many */ 165 unsigned int stateful :1; /* stateful mode flag */ 166 unsigned int discard :1; /* stateful mode packet loss flag */ 167 } ppp_mppe_state; 168 169 void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key); 170 void mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options); 171 void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state); 172 err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol); 173 void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state); 174 err_t mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb); 175 176 #ifdef __cplusplus 177 } 178 #endif 179 180 #endif /* MPPE_H */ 181 #endif /* PPP_SUPPORT && MPPE_SUPPORT */ 182