Annotation of embedaddon/mpd/src/ecp_dese.c, revision 1.1.1.3

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;
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:  * DesSubtractBloat()
                    102:  */
                    103: 
                    104: static int
                    105: DesSubtractBloat(Bund b, int size)
                    106: {
1.1.1.3 ! misho     107:   (void)b;
1.1       misho     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: 
1.1.1.2   misho     194:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
1.1       misho     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;
1.1.1.2   misho     261:     DES_cblock next_ivec;
1.1       misho     262: 
                    263:     memcpy(next_ivec, block, 8);
1.1.1.2   misho     264:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
1.1       misho     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: 
1.1.1.3 ! misho     306:   ((u_int32_t *)(void *) des->xmit_ivec)[0] = random();
        !           307:   ((u_int32_t *)(void *) des->xmit_ivec)[1] = random();
1.1       misho     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>