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

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: {
                    107:   size -= DES_OVERHEAD;        /* reserve space for header */
                    108:   size &= ~0x7;
                    109:   return(size);
                    110: }
                    111: 
                    112: static int
                    113: DesStat(Context ctx, int dir) 
                    114: {
                    115:     EcpState   const ecp = &ctx->bund->ecp;
                    116:     DesInfo    const des = &ecp->des;
                    117:     
                    118:     switch (dir) {
                    119:        case ECP_DIR_XMIT:
                    120:            Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
                    121:                (unsigned long long)des->xmit_stats.OctetsIn,
                    122:                (unsigned long long)des->xmit_stats.OctetsOut,
                    123:                ((des->xmit_stats.OctetsIn!=0)?
                    124:                    ((long long)(des->xmit_stats.OctetsOut - des->xmit_stats.OctetsIn)
                    125:                        *100/(long long)des->xmit_stats.OctetsIn):
                    126:                    0));
                    127:            Printf("\tFrames\t: %llu -> %llu\r\n",
                    128:                (unsigned long long)des->xmit_stats.FramesIn,
                    129:                (unsigned long long)des->xmit_stats.FramesOut);
                    130:            Printf("\tErrors\t: %llu\r\n",
                    131:                (unsigned long long)des->xmit_stats.Errors);
                    132:            break;
                    133:        case ECP_DIR_RECV:
                    134:            Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
                    135:                (unsigned long long)des->recv_stats.OctetsOut,
                    136:                (unsigned long long)des->recv_stats.OctetsIn,
                    137:                ((des->recv_stats.OctetsOut!=0)?
                    138:                    ((long long)(des->recv_stats.OctetsIn - des->recv_stats.OctetsOut)
                    139:                        *100/(long long)des->recv_stats.OctetsOut):
                    140:                    0));
                    141:            Printf("\tFrames\t: %llu <- %llu\r\n",
                    142:                (unsigned long long)des->xmit_stats.FramesOut,
                    143:                (unsigned long long)des->xmit_stats.FramesIn);
                    144:            Printf("\tErrors\t: %llu\r\n",
                    145:                (unsigned long long)des->recv_stats.Errors);
                    146:            break;
                    147:        default:
                    148:            assert(0);
                    149:     }
                    150:     return (0);
                    151: }
                    152: 
                    153: /*
                    154:  * DesEncrypt()
                    155:  */
                    156: 
                    157: Mbuf
                    158: DesEncrypt(Bund b, Mbuf plain)
                    159: {
                    160:   EcpState     const ecp = &b->ecp;
                    161:   DesInfo      const des = &ecp->des;
                    162:   const int    plen = MBLEN(plain);
                    163:   int          padlen = roundup2(plen, 8) - plen;
                    164:   int          clen = plen + padlen;
                    165:   Mbuf         cypher;
                    166:   int          k;
                    167: 
                    168:   des->xmit_stats.FramesIn++;
                    169:   des->xmit_stats.OctetsIn += plen;
                    170: 
                    171: /* Get mbuf for encrypted frame */
                    172: 
                    173:   cypher = mballoc(DES_OVERHEAD + clen);
                    174: 
                    175: /* Copy in sequence number */
                    176: 
                    177:   MBDATAU(cypher)[0] = des->xmit_seq >> 8;
                    178:   MBDATAU(cypher)[1] = des->xmit_seq & 0xff;
                    179:   des->xmit_seq++;
                    180: 
                    181: /* Copy in plaintext */
                    182: 
                    183:   mbcopy(plain, 0, MBDATA(cypher) + DES_OVERHEAD, plen);
                    184:   
                    185:   cypher->cnt = DES_OVERHEAD + clen;
                    186:   
                    187: /* Copy in plaintext and encrypt it */
                    188:   
                    189:   for (k = 0; k < clen; k += 8)
                    190:   {
                    191:     u_char     *const block = MBDATA(cypher) + DES_OVERHEAD + k;
                    192: 
1.1.1.2 ! misho     193:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
1.1       misho     194:     memcpy(des->xmit_ivec, block, 8);
                    195:   }
                    196: 
                    197:   des->xmit_stats.FramesOut++;
                    198:   des->xmit_stats.OctetsOut += DES_OVERHEAD + clen;
                    199: 
                    200: /* Return cyphertext */
                    201: 
                    202:   mbfree(plain);
                    203:   return(cypher);
                    204: }
                    205: 
                    206: /*
                    207:  * DesDecrypt()
                    208:  */
                    209: 
                    210: Mbuf
                    211: DesDecrypt(Bund b, Mbuf cypher)
                    212: {
                    213:   EcpState     const ecp = &b->ecp;
                    214:   DesInfo      des = &ecp->des;
                    215:   const int    clen = MBLEN(cypher) - DES_OVERHEAD;
                    216:   u_int16_t    seq;
                    217:   Mbuf         plain;
                    218:   int          k;
                    219: 
                    220:   des->recv_stats.FramesIn++;
                    221:   des->recv_stats.OctetsIn += clen + DES_OVERHEAD;
                    222: 
                    223: /* Get mbuf for plaintext */
                    224: 
                    225:   if (clen < 8 || (clen & 0x7))
                    226:   {
                    227:     Log(LG_ECP, ("[%s] DESE: rec'd bogus DES cypher: len=%d",
                    228:       b->name, clen + DES_OVERHEAD));
                    229:     des->recv_stats.Errors++;
                    230:     return(NULL);
                    231:   }
                    232: 
                    233: /* Check sequence number */
                    234: 
                    235:   cypher = mbread(cypher, &seq, DES_OVERHEAD);
                    236:   seq = ntohs(seq);
                    237:   if (seq != des->recv_seq)
                    238:   {
                    239:     Mbuf       tail;
                    240: 
                    241:   /* Recover from dropped packet */
                    242: 
                    243:     Log(LG_ECP, ("[%s] DESE: rec'd wrong seq=%u, expected %u",
                    244:       b->name, seq, des->recv_seq));
                    245:     tail = mbadj(cypher, clen - 8);
                    246:     tail = mbread(tail, &des->recv_ivec, 8);
                    247:     assert(!tail);
                    248:     des->recv_seq = seq + 1;
                    249:     des->recv_stats.Errors++;
                    250:     return(NULL);
                    251:   }
                    252:   des->recv_seq++;
                    253: 
                    254: /* Decrypt frame */
                    255: 
                    256:   plain = cypher;
                    257:   for (k = 0; k < clen; k += 8)
                    258:   {
                    259:     u_char     *const block = MBDATA(plain) + k;
1.1.1.2 ! misho     260:     DES_cblock next_ivec;
1.1       misho     261: 
                    262:     memcpy(next_ivec, block, 8);
1.1.1.2 ! misho     263:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
1.1       misho     264:     memcpy(des->recv_ivec, next_ivec, 8);
                    265:   }
                    266: 
                    267:   des->recv_stats.FramesOut++;
                    268:   des->recv_stats.OctetsOut += clen;
                    269: 
                    270: /* Done */
                    271: 
                    272:   return(plain);
                    273: }
                    274: 
                    275: /*
                    276:  * DesCleanup()
                    277:  */
                    278: 
                    279: static void
                    280: DesCleanup(Bund b, int dir)
                    281: {
                    282:   EcpState     const ecp = &b->ecp;
                    283:   DesInfo      const des = &ecp->des;
                    284:   
                    285:   if (dir == ECP_DIR_RECV)
                    286:   {
                    287:     memset(&des->recv_stats, 0, sizeof(des->recv_stats));
                    288:   }
                    289:   if (dir == ECP_DIR_XMIT)
                    290:   {
                    291:     memset(&des->xmit_stats, 0, sizeof(des->xmit_stats));
                    292:   }
                    293: }
                    294: 
                    295: /*
                    296:  * DesBuildConfigReq()
                    297:  */
                    298: 
                    299: static u_char *
                    300: DesBuildConfigReq(Bund b, u_char *cp)
                    301: {
                    302:   EcpState     const ecp = &b->ecp;
                    303:   DesInfo      const des = &ecp->des;
                    304: 
                    305:   ((u_int32_t *) des->xmit_ivec)[0] = random();
                    306:   ((u_int32_t *) des->xmit_ivec)[1] = random();
                    307:   return(FsmConfValue(cp, ECP_TY_DESE, 8, des->xmit_ivec));
                    308: }
                    309: 
                    310: /*
                    311:  * DesDecodeConfigReq()
                    312:  */
                    313: 
                    314: static void
                    315: DesDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
                    316: {
                    317:     Bund       b = (Bund)fp->arg;
                    318:   DesInfo      const des = &b->ecp.des;
                    319: 
                    320:   if (opt->len != 10)
                    321:   {
                    322:     Log(LG_ECP, ("[%s]   bogus length %d", b->name, opt->len));
                    323:     if (mode == MODE_REQ)
                    324:       FsmRej(fp, opt);
                    325:     return;
                    326:   }
                    327:   Log(LG_ECP, ("[%s]   nonce 0x%02x%02x%02x%02x%02x%02x%02x%02x", b->name,
                    328:     opt->data[0], opt->data[1],opt->data[2],opt->data[3],
                    329:     opt->data[4], opt->data[5],opt->data[6],opt->data[7]));
                    330:   switch (mode)
                    331:   {
                    332:     case MODE_REQ:
                    333:       memcpy(des->recv_ivec, opt->data, 8);
                    334:       FsmAck(fp, opt);
                    335:       break;
                    336:     case MODE_NAK:
                    337:       break;
                    338:   }
                    339: }
                    340: 

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