Annotation of embedaddon/mpd/src/ecp_dese_bis.c, revision 1.1.1.2
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: {
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:
1.1.1.2 ! misho 206: DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
1.1 misho 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;
1.1.1.2 ! misho 273: DES_cblock next_ivec;
1.1 misho 274:
275: memcpy(next_ivec, block, 8);
1.1.1.2 ! misho 276: DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
1.1 misho 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>