Annotation of embedaddon/mpd/src/ecp_dese.c, revision 1.1.1.1
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;
92: des_cblock key;
93:
94: des_check_key = FALSE;
95: des_string_to_key(ecp->key, &key);
96: des_set_key(&key, des->ks);
97: des->xmit_seq = 0;
98: des->recv_seq = 0;
99: }
100:
101: /*
102: * DesSubtractBloat()
103: */
104:
105: static int
106: DesSubtractBloat(Bund b, int size)
107: {
108: size -= DES_OVERHEAD; /* reserve space for header */
109: size &= ~0x7;
110: return(size);
111: }
112:
113: static int
114: DesStat(Context ctx, int dir)
115: {
116: EcpState const ecp = &ctx->bund->ecp;
117: DesInfo const des = &ecp->des;
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: * DesEncrypt()
156: */
157:
158: Mbuf
159: DesEncrypt(Bund b, Mbuf plain)
160: {
161: EcpState const ecp = &b->ecp;
162: DesInfo const des = &ecp->des;
163: const int plen = MBLEN(plain);
164: int padlen = roundup2(plen, 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: cypher->cnt = DES_OVERHEAD + clen;
187:
188: /* Copy in plaintext and encrypt it */
189:
190: for (k = 0; k < clen; k += 8)
191: {
192: u_char *const block = MBDATA(cypher) + DES_OVERHEAD + k;
193:
194: des_cbc_encrypt(block, block, 8, des->ks, &des->xmit_ivec, TRUE);
195: memcpy(des->xmit_ivec, block, 8);
196: }
197:
198: des->xmit_stats.FramesOut++;
199: des->xmit_stats.OctetsOut += DES_OVERHEAD + clen;
200:
201: /* Return cyphertext */
202:
203: mbfree(plain);
204: return(cypher);
205: }
206:
207: /*
208: * DesDecrypt()
209: */
210:
211: Mbuf
212: DesDecrypt(Bund b, Mbuf cypher)
213: {
214: EcpState const ecp = &b->ecp;
215: DesInfo des = &ecp->des;
216: const int clen = MBLEN(cypher) - DES_OVERHEAD;
217: u_int16_t seq;
218: Mbuf plain;
219: int k;
220:
221: des->recv_stats.FramesIn++;
222: des->recv_stats.OctetsIn += clen + DES_OVERHEAD;
223:
224: /* Get mbuf for plaintext */
225:
226: if (clen < 8 || (clen & 0x7))
227: {
228: Log(LG_ECP, ("[%s] DESE: rec'd bogus DES cypher: len=%d",
229: b->name, clen + DES_OVERHEAD));
230: des->recv_stats.Errors++;
231: return(NULL);
232: }
233:
234: /* Check sequence number */
235:
236: cypher = mbread(cypher, &seq, DES_OVERHEAD);
237: seq = ntohs(seq);
238: if (seq != des->recv_seq)
239: {
240: Mbuf tail;
241:
242: /* Recover from dropped packet */
243:
244: Log(LG_ECP, ("[%s] DESE: rec'd wrong seq=%u, expected %u",
245: b->name, seq, des->recv_seq));
246: tail = mbadj(cypher, clen - 8);
247: tail = mbread(tail, &des->recv_ivec, 8);
248: assert(!tail);
249: des->recv_seq = seq + 1;
250: des->recv_stats.Errors++;
251: return(NULL);
252: }
253: des->recv_seq++;
254:
255: /* Decrypt frame */
256:
257: plain = cypher;
258: for (k = 0; k < clen; k += 8)
259: {
260: u_char *const block = MBDATA(plain) + k;
261: des_cblock next_ivec;
262:
263: memcpy(next_ivec, block, 8);
264: des_cbc_encrypt(block, block, 8, des->ks, &des->recv_ivec, FALSE);
265: memcpy(des->recv_ivec, next_ivec, 8);
266: }
267:
268: des->recv_stats.FramesOut++;
269: des->recv_stats.OctetsOut += clen;
270:
271: /* Done */
272:
273: return(plain);
274: }
275:
276: /*
277: * DesCleanup()
278: */
279:
280: static void
281: DesCleanup(Bund b, int dir)
282: {
283: EcpState const ecp = &b->ecp;
284: DesInfo const des = &ecp->des;
285:
286: if (dir == ECP_DIR_RECV)
287: {
288: memset(&des->recv_stats, 0, sizeof(des->recv_stats));
289: }
290: if (dir == ECP_DIR_XMIT)
291: {
292: memset(&des->xmit_stats, 0, sizeof(des->xmit_stats));
293: }
294: }
295:
296: /*
297: * DesBuildConfigReq()
298: */
299:
300: static u_char *
301: DesBuildConfigReq(Bund b, u_char *cp)
302: {
303: EcpState const ecp = &b->ecp;
304: DesInfo const des = &ecp->des;
305:
306: ((u_int32_t *) des->xmit_ivec)[0] = random();
307: ((u_int32_t *) des->xmit_ivec)[1] = random();
308: return(FsmConfValue(cp, ECP_TY_DESE, 8, des->xmit_ivec));
309: }
310:
311: /*
312: * DesDecodeConfigReq()
313: */
314:
315: static void
316: DesDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
317: {
318: Bund b = (Bund)fp->arg;
319: DesInfo const des = &b->ecp.des;
320:
321: if (opt->len != 10)
322: {
323: Log(LG_ECP, ("[%s] bogus length %d", b->name, opt->len));
324: if (mode == MODE_REQ)
325: FsmRej(fp, opt);
326: return;
327: }
328: Log(LG_ECP, ("[%s] nonce 0x%02x%02x%02x%02x%02x%02x%02x%02x", b->name,
329: opt->data[0], opt->data[1],opt->data[2],opt->data[3],
330: opt->data[4], opt->data[5],opt->data[6],opt->data[7]));
331: switch (mode)
332: {
333: case MODE_REQ:
334: memcpy(des->recv_ivec, opt->data, 8);
335: FsmAck(fp, opt);
336: break;
337: case MODE_NAK:
338: break;
339: }
340: }
341:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>