Annotation of embedaddon/mpd/src/ecp_dese_bis.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * ecp_dese.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 DeseBisInit(Bund b, int dir);
! 26: static void DeseBisConfigure(Bund b);
! 27: static int DeseBisSubtractBloat(Bund b, int size);
! 28: static Mbuf DeseBisEncrypt(Bund b, Mbuf plain);
! 29: static Mbuf DeseBisDecrypt(Bund b, Mbuf cypher);
! 30: static void DeseBisCleanup(Bund b, int dir);
! 31: static int DeseBisStat(Context ctx, int dir);
! 32:
! 33: static u_char *DeseBisBuildConfigReq(Bund b, u_char *cp);
! 34: static void DeseBisDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
! 35:
! 36: /*
! 37: * GLOBAL VARIABLES
! 38: */
! 39:
! 40: const struct enctype gDeseBisEncType =
! 41: {
! 42: "dese-bis",
! 43: ECP_TY_DESE_bis,
! 44: DeseBisInit,
! 45: DeseBisConfigure,
! 46: NULL,
! 47: DeseBisSubtractBloat,
! 48: DeseBisCleanup,
! 49: DeseBisBuildConfigReq,
! 50: DeseBisDecodeConfigReq,
! 51: NULL,
! 52: NULL,
! 53: NULL,
! 54: DeseBisStat,
! 55: DeseBisEncrypt,
! 56: DeseBisDecrypt,
! 57: };
! 58:
! 59: /*
! 60: * DeseBisInit()
! 61: */
! 62:
! 63: static int
! 64: DeseBisInit(Bund b, int dir)
! 65: {
! 66: EcpState const ecp = &b->ecp;
! 67: DeseBisInfo const des = &ecp->desebis;
! 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: * DeseBisConfigure()
! 85: */
! 86:
! 87: static void
! 88: DeseBisConfigure(Bund b)
! 89: {
! 90: EcpState const ecp = &b->ecp;
! 91: DeseBisInfo const des = &ecp->desebis;
! 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: * DeseBisSubtractBloat()
! 103: */
! 104:
! 105: static int
! 106: DeseBisSubtractBloat(Bund b, int size)
! 107: {
! 108: size -= DES_OVERHEAD; /* reserve space for header */
! 109: size &= ~0x7;
! 110: size--; /* reserve space for possible padding */
! 111: return(size);
! 112: }
! 113:
! 114: static int
! 115: DeseBisStat(Context ctx, int dir)
! 116: {
! 117: EcpState const ecp = &ctx->bund->ecp;
! 118: DeseBisInfo const des = &ecp->desebis;
! 119:
! 120: switch (dir) {
! 121: case ECP_DIR_XMIT:
! 122: Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
! 123: (unsigned long long)des->xmit_stats.OctetsIn,
! 124: (unsigned long long)des->xmit_stats.OctetsOut,
! 125: ((des->xmit_stats.OctetsIn!=0)?
! 126: ((long long)(des->xmit_stats.OctetsOut - des->xmit_stats.OctetsIn)
! 127: *100/(long long)des->xmit_stats.OctetsIn):
! 128: 0));
! 129: Printf("\tFrames\t: %llu -> %llu\r\n",
! 130: (unsigned long long)des->xmit_stats.FramesIn,
! 131: (unsigned long long)des->xmit_stats.FramesOut);
! 132: Printf("\tErrors\t: %llu\r\n",
! 133: (unsigned long long)des->xmit_stats.Errors);
! 134: break;
! 135: case ECP_DIR_RECV:
! 136: Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
! 137: (unsigned long long)des->recv_stats.OctetsOut,
! 138: (unsigned long long)des->recv_stats.OctetsIn,
! 139: ((des->recv_stats.OctetsOut!=0)?
! 140: ((long long)(des->recv_stats.OctetsIn - des->recv_stats.OctetsOut)
! 141: *100/(long long)des->recv_stats.OctetsOut):
! 142: 0));
! 143: Printf("\tFrames\t: %llu <- %llu\r\n",
! 144: (unsigned long long)des->xmit_stats.FramesOut,
! 145: (unsigned long long)des->xmit_stats.FramesIn);
! 146: Printf("\tErrors\t: %llu\r\n",
! 147: (unsigned long long)des->recv_stats.Errors);
! 148: break;
! 149: default:
! 150: assert(0);
! 151: }
! 152: return (0);
! 153: }
! 154:
! 155: /*
! 156: * DeseBisEncrypt()
! 157: */
! 158:
! 159: Mbuf
! 160: DeseBisEncrypt(Bund b, Mbuf plain)
! 161: {
! 162: EcpState const ecp = &b->ecp;
! 163: DeseBisInfo const des = &ecp->desebis;
! 164: const int plen = MBLEN(plain);
! 165: int padlen = roundup2(plen + 1, 8) - plen;
! 166: int clen = plen + padlen;
! 167: Mbuf cypher;
! 168: int k;
! 169:
! 170: des->xmit_stats.FramesIn++;
! 171: des->xmit_stats.OctetsIn += plen;
! 172:
! 173: /* Get mbuf for encrypted frame */
! 174:
! 175: cypher = mballoc(DES_OVERHEAD + clen);
! 176:
! 177: /* Copy in sequence number */
! 178:
! 179: MBDATAU(cypher)[0] = des->xmit_seq >> 8;
! 180: MBDATAU(cypher)[1] = des->xmit_seq & 0xff;
! 181: des->xmit_seq++;
! 182:
! 183: /* Copy in plaintext */
! 184:
! 185: mbcopy(plain, 0, MBDATA(cypher) + DES_OVERHEAD, plen);
! 186:
! 187: /* Correct and add padding */
! 188:
! 189: if ((padlen>7) &&
! 190: ((MBDATA(cypher)[DES_OVERHEAD + plen - 1]==0) ||
! 191: (MBDATA(cypher)[DES_OVERHEAD + plen - 1]>8))) {
! 192: padlen -=8;
! 193: clen = plen + padlen;
! 194: }
! 195: for (k = 0; k < padlen; k++) {
! 196: MBDATA(cypher)[DES_OVERHEAD + plen + k] = k + 1;
! 197: }
! 198:
! 199: cypher->cnt = DES_OVERHEAD + clen;
! 200:
! 201: /* Copy in plaintext and encrypt it */
! 202:
! 203: for (k = 0; k < clen; k += 8)
! 204: {
! 205: u_char *const block = MBDATA(cypher) + DES_OVERHEAD + k;
! 206:
! 207: des_cbc_encrypt(block, block, 8, des->ks, &des->xmit_ivec, TRUE);
! 208: memcpy(des->xmit_ivec, block, 8);
! 209: }
! 210:
! 211: des->xmit_stats.FramesOut++;
! 212: des->xmit_stats.OctetsOut += DES_OVERHEAD + clen;
! 213:
! 214: /* Return cyphertext */
! 215:
! 216: mbfree(plain);
! 217: return(cypher);
! 218: }
! 219:
! 220: /*
! 221: * DeseBisDecrypt()
! 222: */
! 223:
! 224: Mbuf
! 225: DeseBisDecrypt(Bund b, Mbuf cypher)
! 226: {
! 227: EcpState const ecp = &b->ecp;
! 228: DeseBisInfo des = &ecp->desebis;
! 229: int clen = MBLEN(cypher) - DES_OVERHEAD;
! 230: u_int16_t seq;
! 231: Mbuf plain;
! 232: int k;
! 233:
! 234: des->recv_stats.FramesIn++;
! 235: des->recv_stats.OctetsIn += clen + DES_OVERHEAD;
! 236:
! 237: /* Get mbuf for plaintext */
! 238:
! 239: if (clen < 8 || (clen & 0x7))
! 240: {
! 241: Log(LG_ECP, ("[%s] DESE-bis: rec'd bogus DES cypher: len=%d",
! 242: b->name, clen + DES_OVERHEAD));
! 243: des->recv_stats.Errors++;
! 244: return(NULL);
! 245: }
! 246:
! 247: /* Check sequence number */
! 248:
! 249: cypher = mbread(cypher, &seq, DES_OVERHEAD);
! 250: seq = ntohs(seq);
! 251: if (seq != des->recv_seq)
! 252: {
! 253: Mbuf tail;
! 254:
! 255: /* Recover from dropped packet */
! 256:
! 257: Log(LG_ECP, ("[%s] DESE-bis: rec'd wrong seq=%u, expected %u",
! 258: b->name, seq, des->recv_seq));
! 259: tail = mbadj(cypher, clen - 8);
! 260: tail = mbread(tail, &des->recv_ivec, 8);
! 261: assert(!tail);
! 262: des->recv_seq = seq + 1;
! 263: des->recv_stats.Errors++;
! 264: return(NULL);
! 265: }
! 266: des->recv_seq++;
! 267:
! 268: /* Decrypt frame */
! 269:
! 270: plain = cypher;
! 271: for (k = 0; k < clen; k += 8)
! 272: {
! 273: u_char *const block = MBDATA(plain) + k;
! 274: des_cblock next_ivec;
! 275:
! 276: memcpy(next_ivec, block, 8);
! 277: des_cbc_encrypt(block, block, 8, des->ks, &des->recv_ivec, FALSE);
! 278: memcpy(des->recv_ivec, next_ivec, 8);
! 279: }
! 280:
! 281: /* Strip padding */
! 282: if (MBDATAU(plain)[clen-1]>0 &&
! 283: MBDATAU(plain)[clen-1]<=8) {
! 284: clen -= MBDATAU(plain)[clen-1];
! 285: mbtrunc(plain, clen);
! 286: }
! 287:
! 288: des->recv_stats.FramesOut++;
! 289: des->recv_stats.OctetsOut += clen;
! 290:
! 291: /* Done */
! 292:
! 293: return(plain);
! 294: }
! 295:
! 296: /*
! 297: * DeseBisCleanup()
! 298: */
! 299:
! 300: static void
! 301: DeseBisCleanup(Bund b, int dir)
! 302: {
! 303: EcpState const ecp = &b->ecp;
! 304: DeseBisInfo const des = &ecp->desebis;
! 305:
! 306: if (dir == ECP_DIR_RECV)
! 307: {
! 308: memset(&des->recv_stats, 0, sizeof(des->recv_stats));
! 309: }
! 310: if (dir == ECP_DIR_XMIT)
! 311: {
! 312: memset(&des->xmit_stats, 0, sizeof(des->xmit_stats));
! 313: }
! 314: }
! 315:
! 316: /*
! 317: * DeseBisBuildConfigReq()
! 318: */
! 319:
! 320: static u_char *
! 321: DeseBisBuildConfigReq(Bund b, u_char *cp)
! 322: {
! 323: EcpState const ecp = &b->ecp;
! 324: DeseBisInfo const des = &ecp->desebis;
! 325:
! 326: ((u_int32_t *) des->xmit_ivec)[0] = random();
! 327: ((u_int32_t *) des->xmit_ivec)[1] = random();
! 328: return(FsmConfValue(cp, ECP_TY_DESE_bis, 8, des->xmit_ivec));
! 329: }
! 330:
! 331: /*
! 332: * DeseBisDecodeConfigReq()
! 333: */
! 334:
! 335: static void
! 336: DeseBisDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
! 337: {
! 338: Bund b = (Bund)fp->arg;
! 339: DeseBisInfo const des = &b->ecp.desebis;
! 340:
! 341: if (opt->len != 10)
! 342: {
! 343: Log(LG_ECP, ("[%s] bogus length %d", b->name, opt->len));
! 344: if (mode == MODE_REQ)
! 345: FsmRej(fp, opt);
! 346: return;
! 347: }
! 348: Log(LG_ECP, ("[%s] nonce 0x%02x%02x%02x%02x%02x%02x%02x%02x", b->name,
! 349: opt->data[0], opt->data[1],opt->data[2],opt->data[3],
! 350: opt->data[4], opt->data[5],opt->data[6],opt->data[7]));
! 351: switch (mode)
! 352: {
! 353: case MODE_REQ:
! 354: memcpy(des->recv_ivec, opt->data, 8);
! 355: FsmAck(fp, opt);
! 356: break;
! 357: case MODE_NAK:
! 358: break;
! 359: }
! 360: }
! 361:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>