162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#define MPPE_PAD 4 /* MPPE growth per frame */ 362306a36Sopenharmony_ci#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* option bits for ccp_options.mppe */ 662306a36Sopenharmony_ci#define MPPE_OPT_40 0x01 /* 40 bit */ 762306a36Sopenharmony_ci#define MPPE_OPT_128 0x02 /* 128 bit */ 862306a36Sopenharmony_ci#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ 962306a36Sopenharmony_ci/* unsupported opts */ 1062306a36Sopenharmony_ci#define MPPE_OPT_56 0x08 /* 56 bit */ 1162306a36Sopenharmony_ci#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ 1262306a36Sopenharmony_ci#define MPPE_OPT_D 0x20 /* Unknown */ 1362306a36Sopenharmony_ci#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) 1462306a36Sopenharmony_ci#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * This is not nice ... the alternative is a bitfield struct though. 1862306a36Sopenharmony_ci * And unfortunately, we cannot share the same bits for the option 1962306a36Sopenharmony_ci * names above since C and H are the same bit. We could do a u_int32 2062306a36Sopenharmony_ci * but then we have to do a htonl() all the time and/or we still need 2162306a36Sopenharmony_ci * to know which octet is which. 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define MPPE_C_BIT 0x01 /* MPPC */ 2462306a36Sopenharmony_ci#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ 2562306a36Sopenharmony_ci#define MPPE_L_BIT 0x20 /* 40-bit */ 2662306a36Sopenharmony_ci#define MPPE_S_BIT 0x40 /* 128-bit */ 2762306a36Sopenharmony_ci#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ 2862306a36Sopenharmony_ci#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* Does not include H bit; used for least significant octet only. */ 3162306a36Sopenharmony_ci#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* Build a CI from mppe opts (see RFC 3078) */ 3462306a36Sopenharmony_ci#define MPPE_OPTS_TO_CI(opts, ci) \ 3562306a36Sopenharmony_ci do { \ 3662306a36Sopenharmony_ci u_char *ptr = ci; /* u_char[4] */ \ 3762306a36Sopenharmony_ci \ 3862306a36Sopenharmony_ci /* H bit */ \ 3962306a36Sopenharmony_ci if (opts & MPPE_OPT_STATEFUL) \ 4062306a36Sopenharmony_ci *ptr++ = 0x0; \ 4162306a36Sopenharmony_ci else \ 4262306a36Sopenharmony_ci *ptr++ = MPPE_H_BIT; \ 4362306a36Sopenharmony_ci *ptr++ = 0; \ 4462306a36Sopenharmony_ci *ptr++ = 0; \ 4562306a36Sopenharmony_ci \ 4662306a36Sopenharmony_ci /* S,L bits */ \ 4762306a36Sopenharmony_ci *ptr = 0; \ 4862306a36Sopenharmony_ci if (opts & MPPE_OPT_128) \ 4962306a36Sopenharmony_ci *ptr |= MPPE_S_BIT; \ 5062306a36Sopenharmony_ci if (opts & MPPE_OPT_40) \ 5162306a36Sopenharmony_ci *ptr |= MPPE_L_BIT; \ 5262306a36Sopenharmony_ci /* M,D,C bits not supported */ \ 5362306a36Sopenharmony_ci } while (/* CONSTCOND */ 0) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/* The reverse of the above */ 5662306a36Sopenharmony_ci#define MPPE_CI_TO_OPTS(ci, opts) \ 5762306a36Sopenharmony_ci do { \ 5862306a36Sopenharmony_ci u_char *ptr = ci; /* u_char[4] */ \ 5962306a36Sopenharmony_ci \ 6062306a36Sopenharmony_ci opts = 0; \ 6162306a36Sopenharmony_ci \ 6262306a36Sopenharmony_ci /* H bit */ \ 6362306a36Sopenharmony_ci if (!(ptr[0] & MPPE_H_BIT)) \ 6462306a36Sopenharmony_ci opts |= MPPE_OPT_STATEFUL; \ 6562306a36Sopenharmony_ci \ 6662306a36Sopenharmony_ci /* S,L bits */ \ 6762306a36Sopenharmony_ci if (ptr[3] & MPPE_S_BIT) \ 6862306a36Sopenharmony_ci opts |= MPPE_OPT_128; \ 6962306a36Sopenharmony_ci if (ptr[3] & MPPE_L_BIT) \ 7062306a36Sopenharmony_ci opts |= MPPE_OPT_40; \ 7162306a36Sopenharmony_ci \ 7262306a36Sopenharmony_ci /* M,D,C bits */ \ 7362306a36Sopenharmony_ci if (ptr[3] & MPPE_M_BIT) \ 7462306a36Sopenharmony_ci opts |= MPPE_OPT_56; \ 7562306a36Sopenharmony_ci if (ptr[3] & MPPE_D_BIT) \ 7662306a36Sopenharmony_ci opts |= MPPE_OPT_D; \ 7762306a36Sopenharmony_ci if (ptr[3] & MPPE_C_BIT) \ 7862306a36Sopenharmony_ci opts |= MPPE_OPT_MPPC; \ 7962306a36Sopenharmony_ci \ 8062306a36Sopenharmony_ci /* Other bits */ \ 8162306a36Sopenharmony_ci if (ptr[0] & ~MPPE_H_BIT) \ 8262306a36Sopenharmony_ci opts |= MPPE_OPT_UNKNOWN; \ 8362306a36Sopenharmony_ci if (ptr[1] || ptr[2]) \ 8462306a36Sopenharmony_ci opts |= MPPE_OPT_UNKNOWN; \ 8562306a36Sopenharmony_ci if (ptr[3] & ~MPPE_ALL_BITS) \ 8662306a36Sopenharmony_ci opts |= MPPE_OPT_UNKNOWN; \ 8762306a36Sopenharmony_ci } while (/* CONSTCOND */ 0) 88