Annotation of embedaddon/mpd/src/ecp_dese_bis.c, revision 1.1.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>