Annotation of embedaddon/mpd/src/ecp_dese_bis.c, revision 1.1.1.2

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;
1.1.1.2 ! misho      92:   DES_cblock   key;
1.1       misho      93: 
1.1.1.2 ! misho      94:   DES_string_to_key(ecp->key, &key);
        !            95:   DES_set_key(&key, &des->ks);
1.1       misho      96:   des->xmit_seq = 0;
                     97:   des->recv_seq = 0;
                     98: }
                     99: 
                    100: /*
                    101:  * DeseBisSubtractBloat()
                    102:  */
                    103: 
                    104: static int
                    105: DeseBisSubtractBloat(Bund b, int size)
                    106: {
                    107:   size -= DES_OVERHEAD;        /* reserve space for header */
                    108:   size &= ~0x7;
                    109:   size--;              /* reserve space for possible padding */
                    110:   return(size);
                    111: }
                    112: 
                    113: static int
                    114: DeseBisStat(Context ctx, int dir) 
                    115: {
                    116:     EcpState   const ecp = &ctx->bund->ecp;
                    117:     DeseBisInfo        const des = &ecp->desebis;
                    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:  * DeseBisEncrypt()
                    156:  */
                    157: 
                    158: Mbuf
                    159: DeseBisEncrypt(Bund b, Mbuf plain)
                    160: {
                    161:   EcpState     const ecp = &b->ecp;
                    162:   DeseBisInfo  const des = &ecp->desebis;
                    163:   const int    plen = MBLEN(plain);
                    164:   int          padlen = roundup2(plen + 1, 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: /* Correct and add padding */
                    187: 
                    188:   if ((padlen>7) &&
                    189:     ((MBDATA(cypher)[DES_OVERHEAD + plen - 1]==0) ||
                    190:      (MBDATA(cypher)[DES_OVERHEAD + plen - 1]>8))) {
                    191:         padlen -=8;
                    192:        clen = plen + padlen;
                    193:   }
                    194:   for (k = 0; k < padlen; k++) {
                    195:     MBDATA(cypher)[DES_OVERHEAD + plen + k] = k + 1;
                    196:   }
                    197:   
                    198:   cypher->cnt = DES_OVERHEAD + clen;
                    199:   
                    200: /* Copy in plaintext and encrypt it */
                    201:   
                    202:   for (k = 0; k < clen; k += 8)
                    203:   {
                    204:     u_char     *const block = MBDATA(cypher) + DES_OVERHEAD + k;
                    205: 
1.1.1.2 ! misho     206:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
1.1       misho     207:     memcpy(des->xmit_ivec, block, 8);
                    208:   }
                    209: 
                    210:   des->xmit_stats.FramesOut++;
                    211:   des->xmit_stats.OctetsOut += DES_OVERHEAD + clen;
                    212: 
                    213: /* Return cyphertext */
                    214: 
                    215:   mbfree(plain);
                    216:   return(cypher);
                    217: }
                    218: 
                    219: /*
                    220:  * DeseBisDecrypt()
                    221:  */
                    222: 
                    223: Mbuf
                    224: DeseBisDecrypt(Bund b, Mbuf cypher)
                    225: {
                    226:   EcpState     const ecp = &b->ecp;
                    227:   DeseBisInfo  des = &ecp->desebis;
                    228:   int          clen = MBLEN(cypher) - DES_OVERHEAD;
                    229:   u_int16_t    seq;
                    230:   Mbuf         plain;
                    231:   int          k;
                    232: 
                    233:   des->recv_stats.FramesIn++;
                    234:   des->recv_stats.OctetsIn += clen + DES_OVERHEAD;
                    235: 
                    236: /* Get mbuf for plaintext */
                    237: 
                    238:   if (clen < 8 || (clen & 0x7))
                    239:   {
                    240:     Log(LG_ECP, ("[%s] DESE-bis: rec'd bogus DES cypher: len=%d",
                    241:       b->name, clen + DES_OVERHEAD));
                    242:     des->recv_stats.Errors++;
                    243:     return(NULL);
                    244:   }
                    245: 
                    246: /* Check sequence number */
                    247: 
                    248:   cypher = mbread(cypher, &seq, DES_OVERHEAD);
                    249:   seq = ntohs(seq);
                    250:   if (seq != des->recv_seq)
                    251:   {
                    252:     Mbuf       tail;
                    253: 
                    254:   /* Recover from dropped packet */
                    255: 
                    256:     Log(LG_ECP, ("[%s] DESE-bis: rec'd wrong seq=%u, expected %u",
                    257:       b->name, seq, des->recv_seq));
                    258:     tail = mbadj(cypher, clen - 8);
                    259:     tail = mbread(tail, &des->recv_ivec, 8);
                    260:     assert(!tail);
                    261:     des->recv_seq = seq + 1;
                    262:     des->recv_stats.Errors++;
                    263:     return(NULL);
                    264:   }
                    265:   des->recv_seq++;
                    266: 
                    267: /* Decrypt frame */
                    268: 
                    269:   plain = cypher;
                    270:   for (k = 0; k < clen; k += 8)
                    271:   {
                    272:     u_char     *const block = MBDATA(plain) + k;
1.1.1.2 ! misho     273:     DES_cblock next_ivec;
1.1       misho     274: 
                    275:     memcpy(next_ivec, block, 8);
1.1.1.2 ! misho     276:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
1.1       misho     277:     memcpy(des->recv_ivec, next_ivec, 8);
                    278:   }
                    279: 
                    280: /* Strip padding */
                    281:   if (MBDATAU(plain)[clen-1]>0 &&
                    282:     MBDATAU(plain)[clen-1]<=8) {
                    283:       clen -= MBDATAU(plain)[clen-1];
                    284:       mbtrunc(plain, clen);
                    285:   }
                    286: 
                    287:   des->recv_stats.FramesOut++;
                    288:   des->recv_stats.OctetsOut += clen;
                    289: 
                    290: /* Done */
                    291: 
                    292:   return(plain);
                    293: }
                    294: 
                    295: /*
                    296:  * DeseBisCleanup()
                    297:  */
                    298: 
                    299: static void
                    300: DeseBisCleanup(Bund b, int dir)
                    301: {
                    302:   EcpState     const ecp = &b->ecp;
                    303:   DeseBisInfo  const des = &ecp->desebis;
                    304:   
                    305:   if (dir == ECP_DIR_RECV)
                    306:   {
                    307:     memset(&des->recv_stats, 0, sizeof(des->recv_stats));
                    308:   }
                    309:   if (dir == ECP_DIR_XMIT)
                    310:   {
                    311:     memset(&des->xmit_stats, 0, sizeof(des->xmit_stats));
                    312:   }
                    313: }
                    314: 
                    315: /*
                    316:  * DeseBisBuildConfigReq()
                    317:  */
                    318: 
                    319: static u_char *
                    320: DeseBisBuildConfigReq(Bund b, u_char *cp)
                    321: {
                    322:   EcpState     const ecp = &b->ecp;
                    323:   DeseBisInfo  const des = &ecp->desebis;
                    324: 
                    325:   ((u_int32_t *) des->xmit_ivec)[0] = random();
                    326:   ((u_int32_t *) des->xmit_ivec)[1] = random();
                    327:   return(FsmConfValue(cp, ECP_TY_DESE_bis, 8, des->xmit_ivec));
                    328: }
                    329: 
                    330: /*
                    331:  * DeseBisDecodeConfigReq()
                    332:  */
                    333: 
                    334: static void
                    335: DeseBisDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
                    336: {
                    337:     Bund       b = (Bund)fp->arg;
                    338:   DeseBisInfo  const des = &b->ecp.desebis;
                    339: 
                    340:   if (opt->len != 10)
                    341:   {
                    342:     Log(LG_ECP, ("[%s]   bogus length %d", b->name, opt->len));
                    343:     if (mode == MODE_REQ)
                    344:       FsmRej(fp, opt);
                    345:     return;
                    346:   }
                    347:   Log(LG_ECP, ("[%s]   nonce 0x%02x%02x%02x%02x%02x%02x%02x%02x", b->name,
                    348:     opt->data[0], opt->data[1],opt->data[2],opt->data[3],
                    349:     opt->data[4], opt->data[5],opt->data[6],opt->data[7]));
                    350:   switch (mode)
                    351:   {
                    352:     case MODE_REQ:
                    353:       memcpy(des->recv_ivec, opt->data, 8);
                    354:       FsmAck(fp, opt);
                    355:       break;
                    356:     case MODE_NAK:
                    357:       break;
                    358:   }
                    359: }
                    360: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>