mppe
pipex_mppe_setkey(struct pipex_mppe *mppe)
rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen);
pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt)
KASSERT(mppe->old_session_keys != NULL);
rc4_keysetup(&mppe->rc4ctx,
mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK],
mppe->keylen);
pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata,
rc4_crypt(&mppe->rc4ctx, indata, outdata, len);
pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits,
memset(mppe, 0, sizeof(struct pipex_mppe));
mtx_init(&mppe->pxm_mtx, IPL_SOFTNET);
mppe->flags |= PIPEX_MPPE_STATELESS;
mppe->old_session_keys =
mppe->old_session_keys = NULL;
memcpy(mppe->master_key, master_key, sizeof(mppe->master_key));
mppe->keylenbits = keylenbits;
mppe->keylen = 8;
mppe->keylen = 16;
GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen,
mppe->session_key);
pipex_mppe_reduce_key(mppe);
pipex_mppe_setkey(mppe);
pipex_mppe_reduce_key(struct pipex_mppe *mppe)
switch (mppe->keylenbits) {
mppe->session_key[0] = 0xd1;
mppe->session_key[1] = 0x26;
mppe->session_key[2] = 0x9e;
mppe->session_key[0] = 0xd1;
mppe_key_change(struct pipex_mppe *mppe)
GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen,
rc4_keysetup(&keychg, interim, mppe->keylen);
rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen);
pipex_mppe_reduce_key(mppe);
if (mppe->old_session_keys) {
int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK;
memcpy(mppe->old_session_keys[idx],
mppe->session_key, PIPEX_MPPE_KEYLEN);
struct pipex_mppe *mppe;
mppe = &session->mppe_recv;
mtx_enter(&mppe->pxm_mtx);
mppe->coher_cnt, (flushed) ? "[flushed]" : "",
mtx_leave(&mppe->pxm_mtx);
if (coher_cnt < mppe->coher_cnt)
if (coher_cnt0 - mppe->coher_cnt > 0x0f00) {
if ((mppe->flags & PIPEX_MPPE_STATELESS) == 0 ||
coher_cnt0 - mppe->coher_cnt
"%d => %d", mppe->coher_cnt, coher_cnt);
mtx_leave(&mppe->pxm_mtx);
if ((mppe->flags & PIPEX_MPPE_STATELESS) != 0) {
mppe_key_change(mppe);
while (mppe->coher_cnt != coher_cnt) {
mppe->coher_cnt++;
mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
mppe_key_change(mppe);
pipex_mppe_setoldkey(mppe, coher_cnt);
if (coher_cnt < mppe->coher_cnt) {
pktloss += coher_cnt - mppe->coher_cnt;
m = mppe->coher_cnt / 256;
mppe_key_change(mppe);
mppe->coher_cnt = coher_cnt;
} else if (mppe->coher_cnt != coher_cnt) {
mtx_leave(&mppe->pxm_mtx);
mppe_key_change(mppe);
pipex_mppe_setkey(mppe);
pipex_mppe_crypt(mppe, len, cp, cp);
mppe->coher_cnt++;
mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
mtx_leave(&mppe->pxm_mtx);
struct pipex_mppe *mppe;
mppe = &session->mppe_send;
mtx_enter(&mppe->pxm_mtx);
if ((mppe->flags & PIPEX_MPPE_STATELESS) != 0) {
mppe_key_change(mppe);
if ((mppe->coher_cnt % 0x100) == 0xff) {
mppe_key_change(mppe);
} else if ((mppe->flags & PIPEX_MPPE_RESETREQ) != 0) {
mppe->flags &= ~PIPEX_MPPE_RESETREQ;
pipex_mppe_setkey(mppe);
mppe->coher_cnt, (flushed) ? "[flushed]" : "",
hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK;
pipex_mppe_crypt(mppe, len, cp, cp);
mtx_leave(&mppe->pxm_mtx);
if (ppp->mppe.enabled == 0)
our_bits = mppe_create_our_bits(&ppp->mppe, peer_bits);
mppe_create_our_bits(&f->ppp->mppe, 0);
our_bits = mppe_create_our_bits(&ppp->mppe, peer_bits);
mppe_recv_ccp_reset(&f->ppp->mppe);
if (_this->ppp->mppe.enabled != 0) {
_this->ppp->mppe.master_key);
mschap_asymetric_startkey(_this->ppp->mppe.master_key,
_this->ppp->mppe.recv.master_key, MPPE_KEYLEN, 0, 1);
mschap_asymetric_startkey(_this->ppp->mppe.master_key,
_this->ppp->mppe.send.master_key, MPPE_KEYLEN, 1, 1);
if (_this->ppp->mppe.enabled != 0) {
mschap_radiuskey(_this->ppp->mppe.send.master_key,
mschap_radiuskey(_this->ppp->mppe.recv.master_key,
mppe_init(mppe *_this, npppd_ppp *ppp)
memset(_this, 0, sizeof(mppe));
mppe_fini(mppe *_this)
mppe_key_change(mppe *_mppe, mppe_rc4_t *_this)
mppe_start(mppe *_this)
mppe_create_our_bits(mppe *_this, uint32_t peer_bits)
mppe_input(mppe *_this, u_char *pktp, int len)
mppe_recv_ccp_reset(mppe *_this)
mppe_pkt_output(mppe *_this, uint16_t proto, u_char *pktp, int len)
mppe_log(mppe *_this, uint32_t prio, const char *fmt, ...)
mppe_rc4_init(mppe *_mppe, mppe_rc4_t *_this, int has_oldkey)
mppe_rc4_setkey(mppe *_mppe, mppe_rc4_t *_this)
mppe_rc4_setoldkey(mppe *_mppe, mppe_rc4_t *_this, uint16_t coher_cnt)
mppe_rc4_encrypt(mppe *_mppe, mppe_rc4_t *_this, int len, u_char *indata, u_char *outdata)
mppe_rc4_destroy(mppe *_mppe, mppe_rc4_t *_this)
static void mppe_log(mppe *, uint32_t, const char *, ...) __printflike(3,4);
static int mppe_rc4_init(mppe *, mppe_rc4_t *, int);
static int mppe_rc4_setkey(mppe *, mppe_rc4_t *);
static int mppe_rc4_setoldkey(mppe *, mppe_rc4_t *, uint16_t);
static void mppe_rc4_destroy(mppe *, mppe_rc4_t *);
static void mppe_rc4_encrypt(mppe *, mppe_rc4_t *, int, u_char *, u_char *);
if (ppp->mppe.send.keybits > 0) {
ppp->mppe.send.master_key,
req->pr_mppe_send.stateless = ppp->mppe.send.stateless;
req->pr_mppe_send.keylenbits = ppp->mppe.send.keybits;
if (ppp->mppe.recv.keybits > 0) {
ppp->mppe.recv.master_key,
req->pr_mppe_recv.stateless = ppp->mppe.recv.stateless;
req->pr_mppe_recv.keylenbits = ppp->mppe.recv.keybits;
if (ppp->mppe.required)
mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, args->pktp,
mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, pktp, lpktp);
mppe_init(&_this->mppe, _this);
_this->mppe.recv.keybits,
(_this->mppe.recv.stateless)? "stateless" : "stateful",
_this->mppe.send.keybits,
(_this->mppe.send.stateless)? "stateless" : "stateful");
mppe_fini(&_this->mppe);
mppe_start(&_this->mppe);
if (_this->mppe.required)
if (_this->mppe.required) {
mppe_input(&_this->mppe, inp, lpkt - (inp - pkt));
mppe mppe;
(((ppp)->mppe.enabled != 0) && \
(((ppp)->mppe.enabled != 0) && ((ppp)->mppe.required != 0))
((ppp)->mppe_started != 0 && (ppp)->mppe.send.keybits > 0)
((ppp)->mppe_started != 0 && (ppp)->mppe.recv.keybits > 0)
void mppe_init (mppe *, npppd_ppp *);
void mppe_fini (mppe *);
void mppe_start (mppe *);
uint32_t mppe_create_our_bits (mppe *, uint32_t);
void mppe_input (mppe *, u_char *, int);
void mppe_recv_ccp_reset (mppe *);
void mppe_pkt_output (mppe *, uint16_t, u_char *, int);