Annotation of embedaddon/mpd/src/ecp_dese.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * ecp_des.c
! 4: *
! 5: * Rewritten by Alexander Motin <mav@FreeBSD.org>
! 6: * Written by Archie Cobbs <archie@freebsd.org>
! 7: * Copyright (c) 1998-1999 Whistle Communications, Inc. All rights reserved.
! 8: * See ``COPYRIGHT.whistle''
! 9: */
! 10:
! 11: #include "ppp.h"
! 12: #include "ecp.h"
! 13: #include "log.h"
! 14:
! 15: /*
! 16: * DEFINITIONS
! 17: */
! 18:
! 19: #define DES_OVERHEAD 2
! 20:
! 21: /*
! 22: * INTERNAL FUNCTIONS
! 23: */
! 24:
! 25: static int DesInit(Bund b, int dir);
! 26: static void DesConfigure(Bund b);
! 27: static int DesSubtractBloat(Bund b, int size);
! 28: static Mbuf DesEncrypt(Bund b, Mbuf plain);
! 29: static Mbuf DesDecrypt(Bund b, Mbuf cypher);
! 30: static void DesCleanup(Bund b, int dir);
! 31: static int DesStat(Context ctx, int dir);
! 32:
! 33: static u_char *DesBuildConfigReq(Bund b, u_char *cp);
! 34: static void DesDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
! 35:
! 36: /*
! 37: * GLOBAL VARIABLES
! 38: */
! 39:
! 40: const struct enctype gDeseEncType =
! 41: {
! 42: "dese-old",
! 43: ECP_TY_DESE,
! 44: DesInit,
! 45: DesConfigure,
! 46: NULL,
! 47: DesSubtractBloat,
! 48: DesCleanup,
! 49: DesBuildConfigReq,
! 50: DesDecodeConfigReq,
! 51: NULL,
! 52: NULL,
! 53: NULL,
! 54: DesStat,
! 55: DesEncrypt,
! 56: DesDecrypt,
! 57: };
! 58:
! 59: /*
! 60: * DesInit()
! 61: */
! 62:
! 63: static int
! 64: DesInit(Bund b, int dir)
! 65: {
! 66: EcpState const ecp = &b->ecp;
! 67: DesInfo const des = &ecp->des;
! 68:
! 69: switch (dir) {
! 70: case ECP_DIR_XMIT:
! 71: des->xmit_seq = 0;
! 72: break;
! 73: case ECP_DIR_RECV:
! 74: des->recv_seq = 0;
! 75: break;
! 76: default:
! 77: assert(0);
! 78: return(-1);
! 79: }
! 80: return(0);
! 81: }
! 82:
! 83: /*
! 84: * DesConfigure()
! 85: */
! 86:
! 87: static void
! 88: DesConfigure(Bund b)
! 89: {
! 90: EcpState const ecp = &b->ecp;
! 91: DesInfo const des = &ecp->des;
! 92: des_cblock key;
! 93:
! 94: des_check_key = FALSE;
! 95: des_string_to_key(ecp->key, &key);
! 96: des_set_key(&key, des->ks);
! 97: des->xmit_seq = 0;
! 98: des->recv_seq = 0;
! 99: }
! 100:
! 101: /*
! 102: * DesSubtractBloat()
! 103: */
! 104:
! 105: static int
! 106: DesSubtractBloat(Bund b, int size)
! 107: {
! 108: size -= DES_OVERHEAD; /* reserve space for header */
! 109: size &= ~0x7;
! 110: return(size);
! 111: }
! 112:
! 113: static int
! 114: DesStat(Context ctx, int dir)
! 115: {
! 116: EcpState const ecp = &ctx->bund->ecp;
! 117: DesInfo const des = &ecp->des;
! 118:
! 119: switch (dir) {
! 120: case ECP_DIR_XMIT:
! 121: Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
! 122: (unsigned long long)des->xmit_stats.OctetsIn,
! 123: (unsigned long long)des->xmit_stats.OctetsOut,
! 124: ((des->xmit_stats.OctetsIn!=0)?
! 125: ((long long)(des->xmit_stats.OctetsOut - des->xmit_stats.OctetsIn)
! 126: *100/(long long)des->xmit_stats.OctetsIn):
! 127: 0));
! 128: Printf("\tFrames\t: %llu -> %llu\r\n",
! 129: (unsigned long long)des->xmit_stats.FramesIn,
! 130: (unsigned long long)des->xmit_stats.FramesOut);
! 131: Printf("\tErrors\t: %llu\r\n",
! 132: (unsigned long long)des->xmit_stats.Errors);
! 133: break;
! 134: case ECP_DIR_RECV:
! 135: Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
! 136: (unsigned long long)des->recv_stats.OctetsOut,
! 137: (unsigned long long)des->recv_stats.OctetsIn,
! 138: ((des->recv_stats.OctetsOut!=0)?
! 139: ((long long)(des->recv_stats.OctetsIn - des->recv_stats.OctetsOut)
! 140: *100/(long long)des->recv_stats.OctetsOut):
! 141: 0));
! 142: Printf("\tFrames\t: %llu <- %llu\r\n",
! 143: (unsigned long long)des->xmit_stats.FramesOut,
! 144: (unsigned long long)des->xmit_stats.FramesIn);
! 145: Printf("\tErrors\t: %llu\r\n",
! 146: (unsigned long long)des->recv_stats.Errors);
! 147: break;
! 148: default:
! 149: assert(0);
! 150: }
! 151: return (0);
! 152: }
! 153:
! 154: /*
! 155: * DesEncrypt()
! 156: */
! 157:
! 158: Mbuf
! 159: DesEncrypt(Bund b, Mbuf plain)
! 160: {
! 161: EcpState const ecp = &b->ecp;
! 162: DesInfo const des = &ecp->des;
! 163: const int plen = MBLEN(plain);
! 164: int padlen = roundup2(plen, 8) - plen;
! 165: int clen = plen + padlen;
! 166: Mbuf cypher;
! 167: int k;
! 168:
! 169: des->xmit_stats.FramesIn++;
! 170: des->xmit_stats.OctetsIn += plen;
! 171:
! 172: /* Get mbuf for encrypted frame */
! 173:
! 174: cypher = mballoc(DES_OVERHEAD + clen);
! 175:
! 176: /* Copy in sequence number */
! 177:
! 178: MBDATAU(cypher)[0] = des->xmit_seq >> 8;
! 179: MBDATAU(cypher)[1] = des->xmit_seq & 0xff;
! 180: des->xmit_seq++;
! 181:
! 182: /* Copy in plaintext */
! 183:
! 184: mbcopy(plain, 0, MBDATA(cypher) + DES_OVERHEAD, plen);
! 185:
! 186: cypher->cnt = DES_OVERHEAD + clen;
! 187:
! 188: /* Copy in plaintext and encrypt it */
! 189:
! 190: for (k = 0; k < clen; k += 8)
! 191: {
! 192: u_char *const block = MBDATA(cypher) + DES_OVERHEAD + k;
! 193:
! 194: des_cbc_encrypt(block, block, 8, des->ks, &des->xmit_ivec, TRUE);
! 195: memcpy(des->xmit_ivec, block, 8);
! 196: }
! 197:
! 198: des->xmit_stats.FramesOut++;
! 199: des->xmit_stats.OctetsOut += DES_OVERHEAD + clen;
! 200:
! 201: /* Return cyphertext */
! 202:
! 203: mbfree(plain);
! 204: return(cypher);
! 205: }
! 206:
! 207: /*
! 208: * DesDecrypt()
! 209: */
! 210:
! 211: Mbuf
! 212: DesDecrypt(Bund b, Mbuf cypher)
! 213: {
! 214: EcpState const ecp = &b->ecp;
! 215: DesInfo des = &ecp->des;
! 216: const int clen = MBLEN(cypher) - DES_OVERHEAD;
! 217: u_int16_t seq;
! 218: Mbuf plain;
! 219: int k;
! 220:
! 221: des->recv_stats.FramesIn++;
! 222: des->recv_stats.OctetsIn += clen + DES_OVERHEAD;
! 223:
! 224: /* Get mbuf for plaintext */
! 225:
! 226: if (clen < 8 || (clen & 0x7))
! 227: {
! 228: Log(LG_ECP, ("[%s] DESE: rec'd bogus DES cypher: len=%d",
! 229: b->name, clen + DES_OVERHEAD));
! 230: des->recv_stats.Errors++;
! 231: return(NULL);
! 232: }
! 233:
! 234: /* Check sequence number */
! 235:
! 236: cypher = mbread(cypher, &seq, DES_OVERHEAD);
! 237: seq = ntohs(seq);
! 238: if (seq != des->recv_seq)
! 239: {
! 240: Mbuf tail;
! 241:
! 242: /* Recover from dropped packet */
! 243:
! 244: Log(LG_ECP, ("[%s] DESE: rec'd wrong seq=%u, expected %u",
! 245: b->name, seq, des->recv_seq));
! 246: tail = mbadj(cypher, clen - 8);
! 247: tail = mbread(tail, &des->recv_ivec, 8);
! 248: assert(!tail);
! 249: des->recv_seq = seq + 1;
! 250: des->recv_stats.Errors++;
! 251: return(NULL);
! 252: }
! 253: des->recv_seq++;
! 254:
! 255: /* Decrypt frame */
! 256:
! 257: plain = cypher;
! 258: for (k = 0; k < clen; k += 8)
! 259: {
! 260: u_char *const block = MBDATA(plain) + k;
! 261: des_cblock next_ivec;
! 262:
! 263: memcpy(next_ivec, block, 8);
! 264: des_cbc_encrypt(block, block, 8, des->ks, &des->recv_ivec, FALSE);
! 265: memcpy(des->recv_ivec, next_ivec, 8);
! 266: }
! 267:
! 268: des->recv_stats.FramesOut++;
! 269: des->recv_stats.OctetsOut += clen;
! 270:
! 271: /* Done */
! 272:
! 273: return(plain);
! 274: }
! 275:
! 276: /*
! 277: * DesCleanup()
! 278: */
! 279:
! 280: static void
! 281: DesCleanup(Bund b, int dir)
! 282: {
! 283: EcpState const ecp = &b->ecp;
! 284: DesInfo const des = &ecp->des;
! 285:
! 286: if (dir == ECP_DIR_RECV)
! 287: {
! 288: memset(&des->recv_stats, 0, sizeof(des->recv_stats));
! 289: }
! 290: if (dir == ECP_DIR_XMIT)
! 291: {
! 292: memset(&des->xmit_stats, 0, sizeof(des->xmit_stats));
! 293: }
! 294: }
! 295:
! 296: /*
! 297: * DesBuildConfigReq()
! 298: */
! 299:
! 300: static u_char *
! 301: DesBuildConfigReq(Bund b, u_char *cp)
! 302: {
! 303: EcpState const ecp = &b->ecp;
! 304: DesInfo const des = &ecp->des;
! 305:
! 306: ((u_int32_t *) des->xmit_ivec)[0] = random();
! 307: ((u_int32_t *) des->xmit_ivec)[1] = random();
! 308: return(FsmConfValue(cp, ECP_TY_DESE, 8, des->xmit_ivec));
! 309: }
! 310:
! 311: /*
! 312: * DesDecodeConfigReq()
! 313: */
! 314:
! 315: static void
! 316: DesDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
! 317: {
! 318: Bund b = (Bund)fp->arg;
! 319: DesInfo const des = &b->ecp.des;
! 320:
! 321: if (opt->len != 10)
! 322: {
! 323: Log(LG_ECP, ("[%s] bogus length %d", b->name, opt->len));
! 324: if (mode == MODE_REQ)
! 325: FsmRej(fp, opt);
! 326: return;
! 327: }
! 328: Log(LG_ECP, ("[%s] nonce 0x%02x%02x%02x%02x%02x%02x%02x%02x", b->name,
! 329: opt->data[0], opt->data[1],opt->data[2],opt->data[3],
! 330: opt->data[4], opt->data[5],opt->data[6],opt->data[7]));
! 331: switch (mode)
! 332: {
! 333: case MODE_REQ:
! 334: memcpy(des->recv_ivec, opt->data, 8);
! 335: FsmAck(fp, opt);
! 336: break;
! 337: case MODE_NAK:
! 338: break;
! 339: }
! 340: }
! 341:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>