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

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