File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ecp_dese.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_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_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:  * 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: 
  193:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
  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;
  260:     DES_cblock	next_ivec;
  261: 
  262:     memcpy(next_ivec, block, 8);
  263:     DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
  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>