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>