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