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