File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ecp_dese_bis.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Nov 1 09:56:12 2016 UTC (7 years, 8 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, HEAD
mpd 5.8

    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_string_to_key(ecp->key, &key);
   95:   DES_set_key(&key, &des->ks);
   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: 
  206:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
  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;
  273:     DES_cblock	next_ivec;
  274: 
  275:     memcpy(next_ivec, block, 8);
  276:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
  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>