Annotation of embedaddon/mpd/src/ecp_dese.c, revision 1.1.1.2
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;
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: * 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:
1.1.1.2 ! misho 193: DES_cbc_encrypt(block, block, 8, &des->ks, &des->xmit_ivec, TRUE);
1.1 misho 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;
1.1.1.2 ! misho 260: DES_cblock next_ivec;
1.1 misho 261:
262: memcpy(next_ivec, block, 8);
1.1.1.2 ! misho 263: DES_cbc_encrypt(block, block, 8, &des->ks, &des->recv_ivec, FALSE);
1.1 misho 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>