xref: /plan9/sys/src/9/ip/esp.c (revision 3468a4915d661daa200976acc4f80f51aae144b2)
1 /*
2  * Encapsulating Security Payload for IPsec for IPv4, rfc1827.
3  * extended to IPv6.
4  * rfc2104 defines hmac computation.
5  *	currently only implements tunnel mode.
6  * TODO: verify aes algorithms;
7  *	transport mode (host-to-host)
8  */
9 #include	"u.h"
10 #include	"../port/lib.h"
11 #include	"mem.h"
12 #include	"dat.h"
13 #include	"fns.h"
14 #include	"../port/error.h"
15 
16 #include	"ip.h"
17 #include	"ipv6.h"
18 #include	"libsec.h"
19 
20 #define BITS2BYTES(bi) (((bi) + BI2BY - 1) / BI2BY)
21 #define BYTES2BITS(by)  ((by) * BI2BY)
22 
23 typedef struct Algorithm Algorithm;
24 typedef struct Esp4hdr Esp4hdr;
25 typedef struct Esp6hdr Esp6hdr;
26 typedef struct Espcb Espcb;
27 typedef struct Esphdr Esphdr;
28 typedef struct Esppriv Esppriv;
29 typedef struct Esptail Esptail;
30 typedef struct Userhdr Userhdr;
31 
32 enum {
33 	Encrypt,
34 	Decrypt,
35 
36 	IP_ESPPROTO	= 50,	/* IP v4 and v6 protocol number */
37 	Esp4hdrlen	= IP4HDR + 8,
38 	Esp6hdrlen	= IP6HDR + 8,
39 
40 	Esptaillen	= 2,	/* does not include pad or auth data */
41 	Userhdrlen	= 4,	/* user-visible header size - if enabled */
42 
43 	Desblk	 = BITS2BYTES(64),
44 	Des3keysz = BITS2BYTES(192),
45 
46 	Aesblk	 = BITS2BYTES(128),
47 	Aeskeysz = BITS2BYTES(128),
48 };
49 
50 struct Esphdr
51 {
52 	uchar	espspi[4];	/* Security parameter index */
53 	uchar	espseq[4];	/* Sequence number */
54 	uchar	payload[];
55 };
56 
57 /*
58  * tunnel-mode (network-to-network, etc.) layout is:
59  * new IP hdrs | ESP hdr |
60  *	 enc { orig IP hdrs | TCP/UDP hdr | user data | ESP trailer } | ESP ICV
61  *
62  * transport-mode (host-to-host) layout would be:
63  *	orig IP hdrs | ESP hdr |
64  *			enc { TCP/UDP hdr | user data | ESP trailer } | ESP ICV
65  */
66 struct Esp4hdr
67 {
68 	/* ipv4 header */
69 	uchar	vihl;		/* Version and header length */
70 	uchar	tos;		/* Type of service */
71 	uchar	length[2];	/* packet length */
72 	uchar	id[2];		/* Identification */
73 	uchar	frag[2];	/* Fragment information */
74 	uchar	Unused;
75 	uchar	espproto;	/* Protocol */
76 	uchar	espplen[2];	/* Header plus data length */
77 	uchar	espsrc[4];	/* Ip source */
78 	uchar	espdst[4];	/* Ip destination */
79 
80 	Esphdr;
81 };
82 
83 /* tunnel-mode layout */
84 struct Esp6hdr
85 {
86 	IPV6HDR;
87 	Esphdr;
88 };
89 
90 struct Esptail
91 {
92 	uchar	pad;
93 	uchar	nexthdr;
94 };
95 
96 /* IP-version-dependent data */
97 typedef struct Versdep Versdep;
98 struct Versdep
99 {
100 	ulong	version;
101 	ulong	iphdrlen;
102 	ulong	hdrlen;		/* iphdrlen + esp hdr len */
103 	ulong	spi;
104 	uchar	laddr[IPaddrlen];
105 	uchar	raddr[IPaddrlen];
106 };
107 
108 /* header as seen by the user */
109 struct Userhdr
110 {
111 	uchar	nexthdr;	/* next protocol */
112 	uchar	unused[3];
113 };
114 
115 struct Esppriv
116 {
117 	uvlong	in;
118 	ulong	inerrors;
119 };
120 
121 /*
122  *  protocol specific part of Conv
123  */
124 struct Espcb
125 {
126 	int	incoming;
127 	int	header;		/* user-level header */
128 	ulong	spi;
129 	ulong	seq;		/* last seq sent */
130 	ulong	window;		/* for replay attacks */
131 
132 	char	*espalg;
133 	void	*espstate;	/* other state for esp */
134 	int	espivlen;	/* in bytes */
135 	int	espblklen;
136 	int	(*cipher)(Espcb*, uchar *buf, int len);
137 
138 	char	*ahalg;
139 	void	*ahstate;	/* other state for esp */
140 	int	ahlen;		/* auth data length in bytes */
141 	int	ahblklen;
142 	int	(*auth)(Espcb*, uchar *buf, int len, uchar *hash);
143 	DigestState *ds;
144 };
145 
146 struct Algorithm
147 {
148 	char 	*name;
149 	int	keylen;		/* in bits */
150 	void	(*init)(Espcb*, char* name, uchar *key, unsigned keylen);
151 };
152 
153 static	Conv* convlookup(Proto *esp, ulong spi);
154 static	char *setalg(Espcb *ecb, char **f, int n, Algorithm *alg);
155 static	void espkick(void *x);
156 
157 static	void nullespinit(Espcb*, char*, uchar *key, unsigned keylen);
158 static	void des3espinit(Espcb*, char*, uchar *key, unsigned keylen);
159 static	void aescbcespinit(Espcb*, char*, uchar *key, unsigned keylen);
160 static	void aesctrespinit(Espcb*, char*, uchar *key, unsigned keylen);
161 static	void desespinit(Espcb *ecb, char *name, uchar *k, unsigned n);
162 
163 static	void nullahinit(Espcb*, char*, uchar *key, unsigned keylen);
164 static	void shaahinit(Espcb*, char*, uchar *key, unsigned keylen);
165 static	void aesahinit(Espcb*, char*, uchar *key, unsigned keylen);
166 static	void md5ahinit(Espcb*, char*, uchar *key, unsigned keylen);
167 
168 static Algorithm espalg[] =
169 {
170 	"null",		0,	nullespinit,
171 	"des3_cbc",	192,	des3espinit,	/* new rfc2451, des-ede3 */
172 	"aes_128_cbc",	128,	aescbcespinit,	/* new rfc3602 */
173 	"aes_ctr",	128,	aesctrespinit,	/* new rfc3686 */
174 	"des_56_cbc",	64,	desespinit,	/* rfc2405, deprecated */
175 	/* rc4 was never required, was used in original bandt */
176 //	"rc4_128",	128,	rc4espinit,
177 	nil,		0,	nil,
178 };
179 
180 static Algorithm ahalg[] =
181 {
182 	"null",		0,	nullahinit,
183 	"hmac_sha1_96",	128,	shaahinit,	/* rfc2404 */
184 	"aes_xcbc_mac_96", 128,	aesahinit,	/* new rfc3566 */
185 	"hmac_md5_96",	128,	md5ahinit,	/* rfc2403 */
186 	nil,		0,	nil,
187 };
188 
189 static char*
espconnect(Conv * c,char ** argv,int argc)190 espconnect(Conv *c, char **argv, int argc)
191 {
192 	char *p, *pp, *e = nil;
193 	ulong spi;
194 	Espcb *ecb = (Espcb*)c->ptcl;
195 
196 	switch(argc) {
197 	default:
198 		e = "bad args to connect";
199 		break;
200 	case 2:
201 		p = strchr(argv[1], '!');
202 		if(p == nil){
203 			e = "malformed address";
204 			break;
205 		}
206 		*p++ = 0;
207 		if (parseip(c->raddr, argv[1]) == -1) {
208 			e = Ebadip;
209 			break;
210 		}
211 		findlocalip(c->p->f, c->laddr, c->raddr);
212 		ecb->incoming = 0;
213 		ecb->seq = 0;
214 		if(strcmp(p, "*") == 0) {
215 			qlock(c->p);
216 			for(;;) {
217 				spi = nrand(1<<16) + 256;
218 				if(convlookup(c->p, spi) == nil)
219 					break;
220 			}
221 			qunlock(c->p);
222 			ecb->spi = spi;
223 			ecb->incoming = 1;
224 			qhangup(c->wq, nil);
225 		} else {
226 			spi = strtoul(p, &pp, 10);
227 			if(pp == p) {
228 				e = "malformed address";
229 				break;
230 			}
231 			ecb->spi = spi;
232 			qhangup(c->rq, nil);
233 		}
234 		nullespinit(ecb, "null", nil, 0);
235 		nullahinit(ecb, "null", nil, 0);
236 	}
237 	Fsconnected(c, e);
238 
239 	return e;
240 }
241 
242 
243 static int
espstate(Conv * c,char * state,int n)244 espstate(Conv *c, char *state, int n)
245 {
246 	return snprint(state, n, "%s", c->inuse?"Open\n":"Closed\n");
247 }
248 
249 static void
espcreate(Conv * c)250 espcreate(Conv *c)
251 {
252 	c->rq = qopen(64*1024, Qmsg, 0, 0);
253 	c->wq = qopen(64*1024, Qkick, espkick, c);
254 }
255 
256 static void
espclose(Conv * c)257 espclose(Conv *c)
258 {
259 	Espcb *ecb;
260 
261 	qclose(c->rq);
262 	qclose(c->wq);
263 	qclose(c->eq);
264 	ipmove(c->laddr, IPnoaddr);
265 	ipmove(c->raddr, IPnoaddr);
266 
267 	ecb = (Espcb*)c->ptcl;
268 	free(ecb->espstate);
269 	free(ecb->ahstate);
270 	memset(ecb, 0, sizeof(Espcb));
271 }
272 
273 static int
convipvers(Conv * c)274 convipvers(Conv *c)
275 {
276 	if((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
277 	    memcmp(c->laddr, v4prefix, IPv4off) == 0) ||
278 	    ipcmp(c->raddr, IPnoaddr) == 0)
279 		return V4;
280 	else
281 		return V6;
282 }
283 
284 static int
pktipvers(Fs * f,Block ** bpp)285 pktipvers(Fs *f, Block **bpp)
286 {
287 	if (*bpp == nil || BLEN(*bpp) == 0) {
288 		/* get enough to identify the IP version */
289 		*bpp = pullupblock(*bpp, IP4HDR);
290 		if(*bpp == nil) {
291 			netlog(f, Logesp, "esp: short packet\n");
292 			return 0;
293 		}
294 	}
295 	return (((Esp4hdr*)(*bpp)->rp)->vihl & 0xf0) == IP_VER4? V4: V6;
296 }
297 
298 static void
getverslens(int version,Versdep * vp)299 getverslens(int version, Versdep *vp)
300 {
301 	vp->version = version;
302 	switch(vp->version) {
303 	case V4:
304 		vp->iphdrlen = IP4HDR;
305 		vp->hdrlen   = Esp4hdrlen;
306 		break;
307 	case V6:
308 		vp->iphdrlen = IP6HDR;
309 		vp->hdrlen   = Esp6hdrlen;
310 		break;
311 	default:
312 		panic("esp: getverslens version %d wrong", version);
313 	}
314 }
315 
316 static void
getpktspiaddrs(uchar * pkt,Versdep * vp)317 getpktspiaddrs(uchar *pkt, Versdep *vp)
318 {
319 	Esp4hdr *eh4;
320 	Esp6hdr *eh6;
321 
322 	switch(vp->version) {
323 	case V4:
324 		eh4 = (Esp4hdr*)pkt;
325 		v4tov6(vp->raddr, eh4->espsrc);
326 		v4tov6(vp->laddr, eh4->espdst);
327 		vp->spi = nhgetl(eh4->espspi);
328 		break;
329 	case V6:
330 		eh6 = (Esp6hdr*)pkt;
331 		ipmove(vp->raddr, eh6->src);
332 		ipmove(vp->laddr, eh6->dst);
333 		vp->spi = nhgetl(eh6->espspi);
334 		break;
335 	default:
336 		panic("esp: getpktspiaddrs vp->version %ld wrong", vp->version);
337 	}
338 }
339 
340 /*
341  * encapsulate next IP packet on x's write queue in IP/ESP packet
342  * and initiate output of the result.
343  */
344 static void
espkick(void * x)345 espkick(void *x)
346 {
347 	int nexthdr, payload, pad, align;
348 	uchar *auth;
349 	Block *bp;
350 	Conv *c = x;
351 	Esp4hdr *eh4;
352 	Esp6hdr *eh6;
353 	Espcb *ecb;
354 	Esptail *et;
355 	Userhdr *uh;
356 	Versdep vers;
357 
358 	getverslens(convipvers(c), &vers);
359 	bp = qget(c->wq);
360 	if(bp == nil)
361 		return;
362 
363 	qlock(c);
364 	ecb = c->ptcl;
365 
366 	if(ecb->header) {
367 		/* make sure the message has a User header */
368 		bp = pullupblock(bp, Userhdrlen);
369 		if(bp == nil) {
370 			qunlock(c);
371 			return;
372 		}
373 		uh = (Userhdr*)bp->rp;
374 		nexthdr = uh->nexthdr;
375 		bp->rp += Userhdrlen;
376 	} else {
377 		nexthdr = 0;	/* what should this be? */
378 	}
379 
380 	payload = BLEN(bp) + ecb->espivlen;
381 
382 	/* Make space to fit ip header */
383 	bp = padblock(bp, vers.hdrlen + ecb->espivlen);
384 	getpktspiaddrs(bp->rp, &vers);
385 
386 	align = 4;
387 	if(ecb->espblklen > align)
388 		align = ecb->espblklen;
389 	if(align % ecb->ahblklen != 0)
390 		panic("espkick: ahblklen is important after all");
391 	pad = (align-1) - (payload + Esptaillen-1)%align;
392 
393 	/*
394 	 * Make space for tail
395 	 * this is done by calling padblock with a negative size
396 	 * Padblock does not change bp->wp!
397 	 */
398 	bp = padblock(bp, -(pad+Esptaillen+ecb->ahlen));
399 	bp->wp += pad+Esptaillen+ecb->ahlen;
400 
401 	et = (Esptail*)(bp->rp + vers.hdrlen + payload + pad);
402 
403 	/* fill in tail */
404 	et->pad = pad;
405 	et->nexthdr = nexthdr;
406 
407 	/* encrypt the payload */
408 	ecb->cipher(ecb, bp->rp + vers.hdrlen, payload + pad + Esptaillen);
409 	auth = bp->rp + vers.hdrlen + payload + pad + Esptaillen;
410 
411 	/* fill in head; construct a new IP header and an ESP header */
412 	if (vers.version == V4) {
413 		eh4 = (Esp4hdr *)bp->rp;
414 		eh4->vihl = IP_VER4;
415 		v6tov4(eh4->espsrc, c->laddr);
416 		v6tov4(eh4->espdst, c->raddr);
417 		eh4->espproto = IP_ESPPROTO;
418 		eh4->frag[0] = 0;
419 		eh4->frag[1] = 0;
420 
421 		hnputl(eh4->espspi, ecb->spi);
422 		hnputl(eh4->espseq, ++ecb->seq);
423 	} else {
424 		eh6 = (Esp6hdr *)bp->rp;
425 		eh6->vcf[0] = IP_VER6;
426 		ipmove(eh6->src, c->laddr);
427 		ipmove(eh6->dst, c->raddr);
428 		eh6->proto = IP_ESPPROTO;
429 
430 		hnputl(eh6->espspi, ecb->spi);
431 		hnputl(eh6->espseq, ++ecb->seq);
432 	}
433 
434 	/* compute secure hash */
435 	ecb->auth(ecb, bp->rp + vers.iphdrlen, (vers.hdrlen - vers.iphdrlen) +
436 		payload + pad + Esptaillen, auth);
437 
438 	qunlock(c);
439 	/* print("esp: pass down: %uld\n", BLEN(bp)); */
440 	if (vers.version == V4)
441 		ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c);
442 	else
443 		ipoput6(c->p->f, bp, 0, c->ttl, c->tos, c);
444 }
445 
446 /*
447  * decapsulate IP packet from IP/ESP packet in bp and
448  * pass the result up the spi's Conv's read queue.
449  */
450 void
espiput(Proto * esp,Ipifc *,Block * bp)451 espiput(Proto *esp, Ipifc*, Block *bp)
452 {
453 	int payload, nexthdr;
454 	uchar *auth, *espspi;
455 	Conv *c;
456 	Espcb *ecb;
457 	Esptail *et;
458 	Fs *f;
459 	Userhdr *uh;
460 	Versdep vers;
461 
462 	f = esp->f;
463 
464 	getverslens(pktipvers(f, &bp), &vers);
465 
466 	bp = pullupblock(bp, vers.hdrlen + Esptaillen);
467 	if(bp == nil) {
468 		netlog(f, Logesp, "esp: short packet\n");
469 		return;
470 	}
471 	getpktspiaddrs(bp->rp, &vers);
472 
473 	qlock(esp);
474 	/* Look for a conversation structure for this port */
475 	c = convlookup(esp, vers.spi);
476 	if(c == nil) {
477 		qunlock(esp);
478 		netlog(f, Logesp, "esp: no conv %I -> %I!%lud\n", vers.raddr,
479 			vers.laddr, vers.spi);
480 		icmpnoconv(f, bp);
481 		freeblist(bp);
482 		return;
483 	}
484 
485 	qlock(c);
486 	qunlock(esp);
487 
488 	ecb = c->ptcl;
489 	/* too hard to do decryption/authentication on block lists */
490 	if(bp->next)
491 		bp = concatblock(bp);
492 
493 	if(BLEN(bp) < vers.hdrlen + ecb->espivlen + Esptaillen + ecb->ahlen) {
494 		qunlock(c);
495 		netlog(f, Logesp, "esp: short block %I -> %I!%lud\n", vers.raddr,
496 			vers.laddr, vers.spi);
497 		freeb(bp);
498 		return;
499 	}
500 
501 	auth = bp->wp - ecb->ahlen;
502 	espspi = vers.version == V4?	((Esp4hdr*)bp->rp)->espspi:
503 					((Esp6hdr*)bp->rp)->espspi;
504 
505 	/* compute secure hash and authenticate */
506 	if(!ecb->auth(ecb, espspi, auth - espspi, auth)) {
507 		qunlock(c);
508 print("esp: bad auth %I -> %I!%ld\n", vers.raddr, vers.laddr, vers.spi);
509 		netlog(f, Logesp, "esp: bad auth %I -> %I!%lud\n", vers.raddr,
510 			vers.laddr, vers.spi);
511 		freeb(bp);
512 		return;
513 	}
514 
515 	payload = BLEN(bp) - vers.hdrlen - ecb->ahlen;
516 	if(payload <= 0 || payload % 4 != 0 || payload % ecb->espblklen != 0) {
517 		qunlock(c);
518 		netlog(f, Logesp, "esp: bad length %I -> %I!%lud payload=%d BLEN=%lud\n",
519 			vers.raddr, vers.laddr, vers.spi, payload, BLEN(bp));
520 		freeb(bp);
521 		return;
522 	}
523 
524 	/* decrypt payload */
525 	if(!ecb->cipher(ecb, bp->rp + vers.hdrlen, payload)) {
526 		qunlock(c);
527 print("esp: cipher failed %I -> %I!%ld: %s\n", vers.raddr, vers.laddr, vers.spi, up->errstr);
528 		netlog(f, Logesp, "esp: cipher failed %I -> %I!%lud: %s\n",
529 			vers.raddr, vers.laddr, vers.spi, up->errstr);
530 		freeb(bp);
531 		return;
532 	}
533 
534 	payload -= Esptaillen;
535 	et = (Esptail*)(bp->rp + vers.hdrlen + payload);
536 	payload -= et->pad + ecb->espivlen;
537 	nexthdr = et->nexthdr;
538 	if(payload <= 0) {
539 		qunlock(c);
540 		netlog(f, Logesp, "esp: short packet after decrypt %I -> %I!%lud\n",
541 			vers.raddr, vers.laddr, vers.spi);
542 		freeb(bp);
543 		return;
544 	}
545 
546 	/* trim packet */
547 	bp->rp += vers.hdrlen + ecb->espivlen; /* toss original IP & ESP hdrs */
548 	bp->wp = bp->rp + payload;
549 	if(ecb->header) {
550 		/* assume Userhdrlen < Esp4hdrlen < Esp6hdrlen */
551 		bp->rp -= Userhdrlen;
552 		uh = (Userhdr*)bp->rp;
553 		memset(uh, 0, Userhdrlen);
554 		uh->nexthdr = nexthdr;
555 	}
556 
557 	/* ingress filtering here? */
558 
559 	if(qfull(c->rq)){
560 		netlog(f, Logesp, "esp: qfull %I -> %I.%uld\n", vers.raddr,
561 			vers.laddr, vers.spi);
562 		freeblist(bp);
563 	}else {
564 //		print("esp: pass up: %uld\n", BLEN(bp));
565 		qpass(c->rq, bp);	/* pass packet up the read queue */
566 	}
567 
568 	qunlock(c);
569 }
570 
571 char*
espctl(Conv * c,char ** f,int n)572 espctl(Conv *c, char **f, int n)
573 {
574 	Espcb *ecb = c->ptcl;
575 	char *e = nil;
576 
577 	if(strcmp(f[0], "esp") == 0)
578 		e = setalg(ecb, f, n, espalg);
579 	else if(strcmp(f[0], "ah") == 0)
580 		e = setalg(ecb, f, n, ahalg);
581 	else if(strcmp(f[0], "header") == 0)
582 		ecb->header = 1;
583 	else if(strcmp(f[0], "noheader") == 0)
584 		ecb->header = 0;
585 	else
586 		e = "unknown control request";
587 	return e;
588 }
589 
590 /* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
591 void
espadvise(Proto * esp,Block * bp,char * msg)592 espadvise(Proto *esp, Block *bp, char *msg)
593 {
594 	Conv *c;
595 	Versdep vers;
596 
597 	getverslens(pktipvers(esp->f, &bp), &vers);
598 	getpktspiaddrs(bp->rp, &vers);
599 
600 	qlock(esp);
601 	c = convlookup(esp, vers.spi);
602 	if(c != nil) {
603 		qhangup(c->rq, msg);
604 		qhangup(c->wq, msg);
605 	}
606 	qunlock(esp);
607 	freeblist(bp);
608 }
609 
610 int
espstats(Proto * esp,char * buf,int len)611 espstats(Proto *esp, char *buf, int len)
612 {
613 	Esppriv *upriv;
614 
615 	upriv = esp->priv;
616 	return snprint(buf, len, "%llud %lud\n",
617 		upriv->in,
618 		upriv->inerrors);
619 }
620 
621 static int
esplocal(Conv * c,char * buf,int len)622 esplocal(Conv *c, char *buf, int len)
623 {
624 	Espcb *ecb = c->ptcl;
625 	int n;
626 
627 	qlock(c);
628 	if(ecb->incoming)
629 		n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi);
630 	else
631 		n = snprint(buf, len, "%I\n", c->laddr);
632 	qunlock(c);
633 	return n;
634 }
635 
636 static int
espremote(Conv * c,char * buf,int len)637 espremote(Conv *c, char *buf, int len)
638 {
639 	Espcb *ecb = c->ptcl;
640 	int n;
641 
642 	qlock(c);
643 	if(ecb->incoming)
644 		n = snprint(buf, len, "%I\n", c->raddr);
645 	else
646 		n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi);
647 	qunlock(c);
648 	return n;
649 }
650 
651 static	Conv*
convlookup(Proto * esp,ulong spi)652 convlookup(Proto *esp, ulong spi)
653 {
654 	Conv *c, **p;
655 	Espcb *ecb;
656 
657 	for(p=esp->conv; *p; p++){
658 		c = *p;
659 		ecb = c->ptcl;
660 		if(ecb->incoming && ecb->spi == spi)
661 			return c;
662 	}
663 	return nil;
664 }
665 
666 static char *
setalg(Espcb * ecb,char ** f,int n,Algorithm * alg)667 setalg(Espcb *ecb, char **f, int n, Algorithm *alg)
668 {
669 	uchar *key;
670 	int c, nbyte, nchar;
671 	uint i;
672 
673 	if(n < 2 || n > 3)
674 		return "bad format";
675 	for(; alg->name; alg++)
676 		if(strcmp(f[1], alg->name) == 0)
677 			break;
678 	if(alg->name == nil)
679 		return "unknown algorithm";
680 
681 	nbyte = (alg->keylen + 7) >> 3;
682 	if (n == 2)
683 		nchar = 0;
684 	else
685 		nchar = strlen(f[2]);
686 	if(nchar != 2 * nbyte)			/* TODO: maybe < is ok */
687 		return "key not required length";
688 	/* convert hex digits from ascii, in place */
689 	for(i=0; i<nchar; i++) {
690 		c = f[2][i];
691 		if(c >= '0' && c <= '9')
692 			f[2][i] -= '0';
693 		else if(c >= 'a' && c <= 'f')
694 			f[2][i] -= 'a'-10;
695 		else if(c >= 'A' && c <= 'F')
696 			f[2][i] -= 'A'-10;
697 		else
698 			return "non-hex character in key";
699 	}
700 	/* collapse hex digits into complete bytes in reverse order in key */
701 	key = smalloc(nbyte);
702 	for(i = 0; i < nchar && i/2 < nbyte; i++) {
703 		c = f[2][nchar-i-1];
704 		if(i&1)
705 			c <<= 4;
706 		key[i/2] |= c;
707 	}
708 
709 	alg->init(ecb, alg->name, key, alg->keylen);
710 	free(key);
711 	return nil;
712 }
713 
714 
715 /*
716  * null encryption
717  */
718 
719 static int
nullcipher(Espcb *,uchar *,int)720 nullcipher(Espcb*, uchar*, int)
721 {
722 	return 1;
723 }
724 
725 static void
nullespinit(Espcb * ecb,char * name,uchar *,unsigned)726 nullespinit(Espcb *ecb, char *name, uchar*, unsigned)
727 {
728 	ecb->espalg = name;
729 	ecb->espblklen = 1;
730 	ecb->espivlen = 0;
731 	ecb->cipher = nullcipher;
732 }
733 
734 static int
nullauth(Espcb *,uchar *,int,uchar *)735 nullauth(Espcb*, uchar*, int, uchar*)
736 {
737 	return 1;
738 }
739 
740 static void
nullahinit(Espcb * ecb,char * name,uchar *,unsigned)741 nullahinit(Espcb *ecb, char *name, uchar*, unsigned)
742 {
743 	ecb->ahalg = name;
744 	ecb->ahblklen = 1;
745 	ecb->ahlen = 0;
746 	ecb->auth = nullauth;
747 }
748 
749 
750 /*
751  * sha1
752  */
753 
754 static void
seanq_hmac_sha1(uchar hash[SHA1dlen],uchar * t,long tlen,uchar * key,long klen)755 seanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen)
756 {
757 	int i;
758 	uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[SHA1dlen];
759 	DigestState *digest;
760 
761 	memset(ipad, 0x36, Hmacblksz);
762 	memset(opad, 0x5c, Hmacblksz);
763 	ipad[Hmacblksz] = opad[Hmacblksz] = 0;
764 	for(i = 0; i < klen; i++){
765 		ipad[i] ^= key[i];
766 		opad[i] ^= key[i];
767 	}
768 	digest = sha1(ipad, Hmacblksz, nil, nil);
769 	sha1(t, tlen, innerhash, digest);
770 	digest = sha1(opad, Hmacblksz, nil, nil);
771 	sha1(innerhash, SHA1dlen, hash, digest);
772 }
773 
774 static int
shaauth(Espcb * ecb,uchar * t,int tlen,uchar * auth)775 shaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
776 {
777 	int r;
778 	uchar hash[SHA1dlen];
779 
780 	memset(hash, 0, SHA1dlen);
781 	seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
782 	r = memcmp(auth, hash, ecb->ahlen) == 0;
783 	memmove(auth, hash, ecb->ahlen);
784 	return r;
785 }
786 
787 static void
shaahinit(Espcb * ecb,char * name,uchar * key,unsigned klen)788 shaahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
789 {
790 	if(klen != 128)
791 		panic("shaahinit: bad keylen");
792 	klen /= BI2BY;
793 
794 	ecb->ahalg = name;
795 	ecb->ahblklen = 1;
796 	ecb->ahlen = BITS2BYTES(96);
797 	ecb->auth = shaauth;
798 	ecb->ahstate = smalloc(klen);
799 	memmove(ecb->ahstate, key, klen);
800 }
801 
802 
803 /*
804  * aes
805  */
806 
807 /* ah_aes_xcbc_mac_96, rfc3566 */
808 static int
aesahauth(Espcb * ecb,uchar * t,int tlen,uchar * auth)809 aesahauth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
810 {
811 	int r;
812 	uchar hash[AESdlen];
813 
814 	memset(hash, 0, AESdlen);
815 	ecb->ds = hmac_aes(t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(96), hash,
816 		ecb->ds);
817 	r = memcmp(auth, hash, ecb->ahlen) == 0;
818 	memmove(auth, hash, ecb->ahlen);
819 	return r;
820 }
821 
822 static void
aesahinit(Espcb * ecb,char * name,uchar * key,unsigned klen)823 aesahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
824 {
825 	if(klen != 128)
826 		panic("aesahinit: keylen not 128");
827 	klen /= BI2BY;
828 
829 	ecb->ahalg = name;
830 	ecb->ahblklen = 1;
831 	ecb->ahlen = BITS2BYTES(96);
832 	ecb->auth = aesahauth;
833 	ecb->ahstate = smalloc(klen);
834 	memmove(ecb->ahstate, key, klen);
835 }
836 
837 static int
aescbccipher(Espcb * ecb,uchar * p,int n)838 aescbccipher(Espcb *ecb, uchar *p, int n)	/* 128-bit blocks */
839 {
840 	uchar tmp[AESbsize], q[AESbsize];
841 	uchar *pp, *tp, *ip, *eip, *ep;
842 	AESstate *ds = ecb->espstate;
843 
844 	ep = p + n;
845 	if(ecb->incoming) {
846 		memmove(ds->ivec, p, AESbsize);
847 		p += AESbsize;
848 		while(p < ep){
849 			memmove(tmp, p, AESbsize);
850 			aes_decrypt(ds->dkey, ds->rounds, p, q);
851 			memmove(p, q, AESbsize);
852 			tp = tmp;
853 			ip = ds->ivec;
854 			for(eip = ip + AESbsize; ip < eip; ){
855 				*p++ ^= *ip;
856 				*ip++ = *tp++;
857 			}
858 		}
859 	} else {
860 		memmove(p, ds->ivec, AESbsize);
861 		for(p += AESbsize; p < ep; p += AESbsize){
862 			pp = p;
863 			ip = ds->ivec;
864 			for(eip = ip + AESbsize; ip < eip; )
865 				*pp++ ^= *ip++;
866 			aes_encrypt(ds->ekey, ds->rounds, p, q);
867 			memmove(ds->ivec, q, AESbsize);
868 			memmove(p, q, AESbsize);
869 		}
870 	}
871 	return 1;
872 }
873 
874 static void
aescbcespinit(Espcb * ecb,char * name,uchar * k,unsigned n)875 aescbcespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
876 {
877 	uchar key[Aeskeysz], ivec[Aeskeysz];
878 	int i;
879 
880 	n = BITS2BYTES(n);
881 	if(n > Aeskeysz)
882 		n = Aeskeysz;
883 	memset(key, 0, sizeof(key));
884 	memmove(key, k, n);
885 	for(i = 0; i < Aeskeysz; i++)
886 		ivec[i] = nrand(256);
887 	ecb->espalg = name;
888 	ecb->espblklen = Aesblk;
889 	ecb->espivlen = Aesblk;
890 	ecb->cipher = aescbccipher;
891 	ecb->espstate = smalloc(sizeof(AESstate));
892 	setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
893 }
894 
895 static int
aesctrcipher(Espcb * ecb,uchar * p,int n)896 aesctrcipher(Espcb *ecb, uchar *p, int n)	/* 128-bit blocks */
897 {
898 	uchar tmp[AESbsize], q[AESbsize];
899 	uchar *pp, *tp, *ip, *eip, *ep;
900 	AESstate *ds = ecb->espstate;
901 
902 	ep = p + n;
903 	if(ecb->incoming) {
904 		memmove(ds->ivec, p, AESbsize);
905 		p += AESbsize;
906 		while(p < ep){
907 			memmove(tmp, p, AESbsize);
908 			aes_decrypt(ds->dkey, ds->rounds, p, q);
909 			memmove(p, q, AESbsize);
910 			tp = tmp;
911 			ip = ds->ivec;
912 			for(eip = ip + AESbsize; ip < eip; ){
913 				*p++ ^= *ip;
914 				*ip++ = *tp++;
915 			}
916 		}
917 	} else {
918 		memmove(p, ds->ivec, AESbsize);
919 		for(p += AESbsize; p < ep; p += AESbsize){
920 			pp = p;
921 			ip = ds->ivec;
922 			for(eip = ip + AESbsize; ip < eip; )
923 				*pp++ ^= *ip++;
924 			aes_encrypt(ds->ekey, ds->rounds, p, q);
925 			memmove(ds->ivec, q, AESbsize);
926 			memmove(p, q, AESbsize);
927 		}
928 	}
929 	return 1;
930 }
931 
932 static void
aesctrespinit(Espcb * ecb,char * name,uchar * k,unsigned n)933 aesctrespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
934 {
935 	uchar key[Aesblk], ivec[Aesblk];
936 	int i;
937 
938 	n = BITS2BYTES(n);
939 	if(n > Aeskeysz)
940 		n = Aeskeysz;
941 	memset(key, 0, sizeof(key));
942 	memmove(key, k, n);
943 	for(i = 0; i < Aesblk; i++)
944 		ivec[i] = nrand(256);
945 	ecb->espalg = name;
946 	ecb->espblklen = Aesblk;
947 	ecb->espivlen = Aesblk;
948 	ecb->cipher = aesctrcipher;
949 	ecb->espstate = smalloc(sizeof(AESstate));
950 	setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
951 }
952 
953 
954 /*
955  * md5
956  */
957 
958 static void
seanq_hmac_md5(uchar hash[MD5dlen],uchar * t,long tlen,uchar * key,long klen)959 seanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen)
960 {
961 	int i;
962 	uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[MD5dlen];
963 	DigestState *digest;
964 
965 	memset(ipad, 0x36, Hmacblksz);
966 	memset(opad, 0x5c, Hmacblksz);
967 	ipad[Hmacblksz] = opad[Hmacblksz] = 0;
968 	for(i = 0; i < klen; i++){
969 		ipad[i] ^= key[i];
970 		opad[i] ^= key[i];
971 	}
972 	digest = md5(ipad, Hmacblksz, nil, nil);
973 	md5(t, tlen, innerhash, digest);
974 	digest = md5(opad, Hmacblksz, nil, nil);
975 	md5(innerhash, MD5dlen, hash, digest);
976 }
977 
978 static int
md5auth(Espcb * ecb,uchar * t,int tlen,uchar * auth)979 md5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
980 {
981 	uchar hash[MD5dlen];
982 	int r;
983 
984 	memset(hash, 0, MD5dlen);
985 	seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
986 	r = memcmp(auth, hash, ecb->ahlen) == 0;
987 	memmove(auth, hash, ecb->ahlen);
988 	return r;
989 }
990 
991 static void
md5ahinit(Espcb * ecb,char * name,uchar * key,unsigned klen)992 md5ahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
993 {
994 	if(klen != 128)
995 		panic("md5ahinit: bad keylen");
996 	klen = BITS2BYTES(klen);
997 	ecb->ahalg = name;
998 	ecb->ahblklen = 1;
999 	ecb->ahlen = BITS2BYTES(96);
1000 	ecb->auth = md5auth;
1001 	ecb->ahstate = smalloc(klen);
1002 	memmove(ecb->ahstate, key, klen);
1003 }
1004 
1005 
1006 /*
1007  * des, single and triple
1008  */
1009 
1010 static int
descipher(Espcb * ecb,uchar * p,int n)1011 descipher(Espcb *ecb, uchar *p, int n)
1012 {
1013 	DESstate *ds = ecb->espstate;
1014 
1015 	if(ecb->incoming) {
1016 		memmove(ds->ivec, p, Desblk);
1017 		desCBCdecrypt(p + Desblk, n - Desblk, ds);
1018 	} else {
1019 		memmove(p, ds->ivec, Desblk);
1020 		desCBCencrypt(p + Desblk, n - Desblk, ds);
1021 	}
1022 	return 1;
1023 }
1024 
1025 static int
des3cipher(Espcb * ecb,uchar * p,int n)1026 des3cipher(Espcb *ecb, uchar *p, int n)
1027 {
1028 	DES3state *ds = ecb->espstate;
1029 
1030 	if(ecb->incoming) {
1031 		memmove(ds->ivec, p, Desblk);
1032 		des3CBCdecrypt(p + Desblk, n - Desblk, ds);
1033 	} else {
1034 		memmove(p, ds->ivec, Desblk);
1035 		des3CBCencrypt(p + Desblk, n - Desblk, ds);
1036 	}
1037 	return 1;
1038 }
1039 
1040 static void
desespinit(Espcb * ecb,char * name,uchar * k,unsigned n)1041 desespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
1042 {
1043 	uchar key[Desblk], ivec[Desblk];
1044 	int i;
1045 
1046 	n = BITS2BYTES(n);
1047 	if(n > Desblk)
1048 		n = Desblk;
1049 	memset(key, 0, sizeof(key));
1050 	memmove(key, k, n);
1051 	for(i = 0; i < Desblk; i++)
1052 		ivec[i] = nrand(256);
1053 	ecb->espalg = name;
1054 	ecb->espblklen = Desblk;
1055 	ecb->espivlen = Desblk;
1056 
1057 	ecb->cipher = descipher;
1058 	ecb->espstate = smalloc(sizeof(DESstate));
1059 	setupDESstate(ecb->espstate, key, ivec);
1060 }
1061 
1062 static void
des3espinit(Espcb * ecb,char * name,uchar * k,unsigned n)1063 des3espinit(Espcb *ecb, char *name, uchar *k, unsigned n)
1064 {
1065 	uchar key[3][Desblk], ivec[Desblk];
1066 	int i;
1067 
1068 	n = BITS2BYTES(n);
1069 	if(n > Des3keysz)
1070 		n = Des3keysz;
1071 	memset(key, 0, sizeof(key));
1072 	memmove(key, k, n);
1073 	for(i = 0; i < Desblk; i++)
1074 		ivec[i] = nrand(256);
1075 	ecb->espalg = name;
1076 	ecb->espblklen = Desblk;
1077 	ecb->espivlen = Desblk;
1078 
1079 	ecb->cipher = des3cipher;
1080 	ecb->espstate = smalloc(sizeof(DES3state));
1081 	setupDES3state(ecb->espstate, key, ivec);
1082 }
1083 
1084 
1085 /*
1086  * interfacing to devip
1087  */
1088 void
espinit(Fs * fs)1089 espinit(Fs *fs)
1090 {
1091 	Proto *esp;
1092 
1093 	esp = smalloc(sizeof(Proto));
1094 	esp->priv = smalloc(sizeof(Esppriv));
1095 	esp->name = "esp";
1096 	esp->connect = espconnect;
1097 	esp->announce = nil;
1098 	esp->ctl = espctl;
1099 	esp->state = espstate;
1100 	esp->create = espcreate;
1101 	esp->close = espclose;
1102 	esp->rcv = espiput;
1103 	esp->advise = espadvise;
1104 	esp->stats = espstats;
1105 	esp->local = esplocal;
1106 	esp->remote = espremote;
1107 	esp->ipproto = IP_ESPPROTO;
1108 	esp->nc = Nchans;
1109 	esp->ptclsize = sizeof(Espcb);
1110 
1111 	Fsproto(fs, esp);
1112 }
1113