2 * Encapsulating Security Payload for IPsec for IPv4, rfc1827.
4 * rfc2104 defines hmac computation.
5 * currently only implements tunnel mode.
6 * TODO: verify aes algorithms;
7 * transport mode (host-to-host)
10 #include "../port/lib.h"
14 #include "../port/error.h"
20 #define BITS2BYTES(bi) (((bi) + BI2BY - 1) / BI2BY)
21 #define BYTES2BITS(by) ((by) * BI2BY)
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;
36 IP_ESPPROTO = 50, /* IP v4 and v6 protocol number */
37 Esp4hdrlen = IP4HDR + 8,
38 Esp6hdrlen = IP6HDR + 8,
40 Esptaillen = 2, /* does not include pad or auth data */
41 Userhdrlen = 4, /* user-visible header size - if enabled */
43 Desblk = BITS2BYTES(64),
44 Des3keysz = BITS2BYTES(192),
46 Aesblk = BITS2BYTES(128),
47 Aeskeysz = BITS2BYTES(128),
52 uchar espspi[4]; /* Security parameter index */
53 uchar espseq[4]; /* Sequence number */
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
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
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 */
75 uchar espproto; /* Protocol */
76 uchar espplen[2]; /* Header plus data length */
77 uchar espsrc[4]; /* Ip source */
78 uchar espdst[4]; /* Ip destination */
83 /* tunnel-mode layout */
96 /* IP-version-dependent data */
97 typedef struct Versdep Versdep;
102 ulong hdrlen; /* iphdrlen + esp hdr len */
104 uchar laddr[IPaddrlen];
105 uchar raddr[IPaddrlen];
108 /* header as seen by the user */
111 uchar nexthdr; /* next protocol */
122 * protocol specific part of Conv
127 int header; /* user-level header */
129 ulong seq; /* last seq sent */
130 ulong window; /* for replay attacks */
133 void *espstate; /* other state for esp */
134 int espivlen; /* in bytes */
136 int (*cipher)(Espcb*, uchar *buf, int len);
139 void *ahstate; /* other state for esp */
140 int ahlen; /* auth data length in bytes */
142 int (*auth)(Espcb*, uchar *buf, int len, uchar *hash);
149 int keylen; /* in bits */
150 void (*init)(Espcb*, char* name, uchar *key, unsigned keylen);
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);
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);
163 static void nullahinit(Espcb*, char*, uchar *key, unsigned keylen);
164 static void shaahinit(Espcb*, char*, uchar *key, unsigned keylen);
165 static void md5ahinit(Espcb*, char*, uchar *key, unsigned keylen);
167 static Algorithm espalg[] =
169 "null", 0, nullespinit,
170 "des3_cbc", 192, des3espinit, /* new rfc2451, des-ede3 */
171 "aes_128_cbc", 128, aescbcespinit, /* new rfc3602 */
172 "aes_ctr", 128, aesctrespinit, /* new rfc3686 */
173 "des_56_cbc", 64, desespinit, /* rfc2405, deprecated */
177 static Algorithm ahalg[] =
179 "null", 0, nullahinit,
180 "hmac_sha1_96", 128, shaahinit, /* rfc2404 */
181 "hmac_md5_96", 128, md5ahinit, /* rfc2403 */
186 espconnect(Conv *c, char **argv, int argc)
188 char *p, *pp, *e = nil;
190 Espcb *ecb = (Espcb*)c->ptcl;
194 e = "bad args to connect";
197 p = strchr(argv[1], '!');
199 e = "malformed address";
203 if (parseip(c->raddr, argv[1]) == -1) {
207 findlocalip(c->p->f, c->laddr, c->raddr);
210 if(strcmp(p, "*") == 0) {
213 spi = nrand(1<<16) + 256;
214 if(convlookup(c->p, spi) == nil)
222 spi = strtoul(p, &pp, 10);
224 e = "malformed address";
230 nullespinit(ecb, "null", nil, 0);
231 nullahinit(ecb, "null", nil, 0);
240 espstate(Conv *c, char *state, int n)
242 return snprint(state, n, "%s", c->inuse?"Open\n":"Closed\n");
248 c->rq = qopen(64*1024, Qmsg, 0, 0);
249 c->wq = qopen(64*1024, Qkick, espkick, c);
260 ipmove(c->laddr, IPnoaddr);
261 ipmove(c->raddr, IPnoaddr);
263 ecb = (Espcb*)c->ptcl;
264 secfree(ecb->espstate);
265 secfree(ecb->ahstate);
266 memset(ecb, 0, sizeof(Espcb));
272 if((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
273 memcmp(c->laddr, v4prefix, IPv4off) == 0) ||
274 ipcmp(c->raddr, IPnoaddr) == 0)
281 pktipvers(Fs *f, Block **bpp)
283 if (*bpp == nil || BLEN(*bpp) == 0) {
284 /* get enough to identify the IP version */
285 *bpp = pullupblock(*bpp, IP4HDR);
287 netlog(f, Logesp, "esp: short packet\n");
291 return (((Esp4hdr*)(*bpp)->rp)->vihl & 0xf0) == IP_VER4? V4: V6;
295 getverslens(int version, Versdep *vp)
297 vp->version = version;
298 switch(vp->version) {
300 vp->iphdrlen = IP4HDR;
301 vp->hdrlen = Esp4hdrlen;
304 vp->iphdrlen = IP6HDR;
305 vp->hdrlen = Esp6hdrlen;
308 panic("esp: getverslens version %d wrong", version);
313 getpktspiaddrs(uchar *pkt, Versdep *vp)
318 switch(vp->version) {
321 v4tov6(vp->raddr, eh4->espsrc);
322 v4tov6(vp->laddr, eh4->espdst);
323 vp->spi = nhgetl(eh4->espspi);
327 ipmove(vp->raddr, eh6->src);
328 ipmove(vp->laddr, eh6->dst);
329 vp->spi = nhgetl(eh6->espspi);
332 panic("esp: getpktspiaddrs vp->version %ld wrong", vp->version);
337 * encapsulate next IP packet on x's write queue in IP/ESP packet
338 * and initiate output of the result.
343 int nexthdr, payload, pad, align;
354 getverslens(convipvers(c), &vers);
363 /* make sure the message has a User header */
364 bp = pullupblock(bp, Userhdrlen);
369 uh = (Userhdr*)bp->rp;
370 nexthdr = uh->nexthdr;
371 bp->rp += Userhdrlen;
373 nexthdr = 0; /* what should this be? */
376 payload = BLEN(bp) + ecb->espivlen;
378 /* Make space to fit ip header */
379 bp = padblock(bp, vers.hdrlen + ecb->espivlen);
380 getpktspiaddrs(bp->rp, &vers);
383 if(ecb->espblklen > align)
384 align = ecb->espblklen;
385 if(align % ecb->ahblklen != 0)
386 panic("espkick: ahblklen is important after all");
387 pad = (align-1) - (payload + Esptaillen-1)%align;
390 * Make space for tail
391 * this is done by calling padblock with a negative size
392 * Padblock does not change bp->wp!
394 bp = padblock(bp, -(pad+Esptaillen+ecb->ahlen));
395 bp->wp += pad+Esptaillen+ecb->ahlen;
397 et = (Esptail*)(bp->rp + vers.hdrlen + payload + pad);
401 et->nexthdr = nexthdr;
403 /* encrypt the payload */
404 ecb->cipher(ecb, bp->rp + vers.hdrlen, payload + pad + Esptaillen);
405 auth = bp->rp + vers.hdrlen + payload + pad + Esptaillen;
407 /* fill in head; construct a new IP header and an ESP header */
408 if (vers.version == V4) {
409 eh4 = (Esp4hdr *)bp->rp;
411 v6tov4(eh4->espsrc, c->laddr);
412 v6tov4(eh4->espdst, c->raddr);
413 eh4->espproto = IP_ESPPROTO;
417 hnputl(eh4->espspi, ecb->spi);
418 hnputl(eh4->espseq, ++ecb->seq);
420 eh6 = (Esp6hdr *)bp->rp;
421 eh6->vcf[0] = IP_VER6;
422 ipmove(eh6->src, c->laddr);
423 ipmove(eh6->dst, c->raddr);
424 eh6->proto = IP_ESPPROTO;
426 hnputl(eh6->espspi, ecb->spi);
427 hnputl(eh6->espseq, ++ecb->seq);
430 /* compute secure hash */
431 ecb->auth(ecb, bp->rp + vers.iphdrlen, (vers.hdrlen - vers.iphdrlen) +
432 payload + pad + Esptaillen, auth);
435 /* print("esp: pass down: %uld\n", BLEN(bp)); */
436 if (vers.version == V4)
437 ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c);
439 ipoput6(c->p->f, bp, 0, c->ttl, c->tos, c);
443 * decapsulate IP packet from IP/ESP packet in bp and
444 * pass the result up the spi's Conv's read queue.
447 espiput(Proto *esp, Ipifc*, Block *bp)
449 int payload, nexthdr;
450 uchar *auth, *espspi;
460 getverslens(pktipvers(f, &bp), &vers);
462 bp = pullupblock(bp, vers.hdrlen + Esptaillen);
464 netlog(f, Logesp, "esp: short packet\n");
467 getpktspiaddrs(bp->rp, &vers);
470 /* Look for a conversation structure for this port */
471 c = convlookup(esp, vers.spi);
474 netlog(f, Logesp, "esp: no conv %I -> %I!%lud\n", vers.raddr,
475 vers.laddr, vers.spi);
485 /* too hard to do decryption/authentication on block lists */
487 bp = concatblock(bp);
489 if(BLEN(bp) < vers.hdrlen + ecb->espivlen + Esptaillen + ecb->ahlen) {
491 netlog(f, Logesp, "esp: short block %I -> %I!%lud\n", vers.raddr,
492 vers.laddr, vers.spi);
497 auth = bp->wp - ecb->ahlen;
498 espspi = vers.version == V4? ((Esp4hdr*)bp->rp)->espspi:
499 ((Esp6hdr*)bp->rp)->espspi;
501 /* compute secure hash and authenticate */
502 if(!ecb->auth(ecb, espspi, auth - espspi, auth)) {
504 print("esp: bad auth %I -> %I!%ld\n", vers.raddr, vers.laddr, vers.spi);
505 netlog(f, Logesp, "esp: bad auth %I -> %I!%lud\n", vers.raddr,
506 vers.laddr, vers.spi);
511 payload = BLEN(bp) - vers.hdrlen - ecb->ahlen;
512 if(payload <= 0 || payload % 4 != 0 || payload % ecb->espblklen != 0) {
514 netlog(f, Logesp, "esp: bad length %I -> %I!%lud payload=%d BLEN=%zd\n",
515 vers.raddr, vers.laddr, vers.spi, payload, BLEN(bp));
520 /* decrypt payload */
521 if(!ecb->cipher(ecb, bp->rp + vers.hdrlen, payload)) {
523 print("esp: cipher failed %I -> %I!%ld: %s\n", vers.raddr, vers.laddr, vers.spi, up->errstr);
524 netlog(f, Logesp, "esp: cipher failed %I -> %I!%lud: %s\n",
525 vers.raddr, vers.laddr, vers.spi, up->errstr);
530 payload -= Esptaillen;
531 et = (Esptail*)(bp->rp + vers.hdrlen + payload);
532 payload -= et->pad + ecb->espivlen;
533 nexthdr = et->nexthdr;
536 netlog(f, Logesp, "esp: short packet after decrypt %I -> %I!%lud\n",
537 vers.raddr, vers.laddr, vers.spi);
543 bp->rp += vers.hdrlen + ecb->espivlen; /* toss original IP & ESP hdrs */
544 bp->wp = bp->rp + payload;
546 /* assume Userhdrlen < Esp4hdrlen < Esp6hdrlen */
547 bp->rp -= Userhdrlen;
548 uh = (Userhdr*)bp->rp;
549 memset(uh, 0, Userhdrlen);
550 uh->nexthdr = nexthdr;
553 /* ingress filtering here? */
556 netlog(f, Logesp, "esp: qfull %I -> %I.%uld\n", vers.raddr,
557 vers.laddr, vers.spi);
560 // print("esp: pass up: %uld\n", BLEN(bp));
561 qpass(c->rq, bp); /* pass packet up the read queue */
568 espctl(Conv *c, char **f, int n)
570 Espcb *ecb = c->ptcl;
573 if(strcmp(f[0], "esp") == 0)
574 e = setalg(ecb, f, n, espalg);
575 else if(strcmp(f[0], "ah") == 0)
576 e = setalg(ecb, f, n, ahalg);
577 else if(strcmp(f[0], "header") == 0)
579 else if(strcmp(f[0], "noheader") == 0)
582 e = "unknown control request";
586 /* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
588 espadvise(Proto *esp, Block *bp, char *msg)
593 getverslens(pktipvers(esp->f, &bp), &vers);
594 getpktspiaddrs(bp->rp, &vers);
597 c = convlookup(esp, vers.spi);
598 if(c != nil && !c->ignoreadvice) {
607 espstats(Proto *esp, char *buf, int len)
612 return snprint(buf, len, "%llud %lud\n",
618 esplocal(Conv *c, char *buf, int len)
620 Espcb *ecb = c->ptcl;
625 n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi);
627 n = snprint(buf, len, "%I\n", c->laddr);
633 espremote(Conv *c, char *buf, int len)
635 Espcb *ecb = c->ptcl;
640 n = snprint(buf, len, "%I\n", c->raddr);
642 n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi);
648 convlookup(Proto *esp, ulong spi)
653 for(p=esp->conv; *p; p++){
656 if(ecb->incoming && ecb->spi == spi)
663 setalg(Espcb *ecb, char **f, int n, Algorithm *alg)
671 for(; alg->name; alg++)
672 if(strcmp(f[1], alg->name) == 0)
675 return "unknown algorithm";
677 nbyte = (alg->keylen + 7) >> 3;
681 nchar = strlen(f[2]);
682 if(nchar != 2 * nbyte) /* TODO: maybe < is ok */
683 return "key not required length";
684 /* convert hex digits from ascii, in place */
685 for(i=0; i<nchar; i++) {
687 if(c >= '0' && c <= '9')
689 else if(c >= 'a' && c <= 'f')
691 else if(c >= 'A' && c <= 'F')
694 return "non-hex character in key";
696 /* collapse hex digits into complete bytes in reverse order in key */
697 key = secalloc(nbyte);
698 for(i = 0; i < nchar && i/2 < nbyte; i++) {
704 memset(f[2], 0, nchar);
705 alg->init(ecb, alg->name, key, alg->keylen);
716 nullcipher(Espcb*, uchar*, int)
722 nullespinit(Espcb *ecb, char *name, uchar*, unsigned)
727 ecb->cipher = nullcipher;
731 nullauth(Espcb*, uchar*, int, uchar*)
737 nullahinit(Espcb *ecb, char *name, uchar*, unsigned)
742 ecb->auth = nullauth;
751 seanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen)
754 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[SHA1dlen];
757 memset(ipad, 0x36, Hmacblksz);
758 memset(opad, 0x5c, Hmacblksz);
759 ipad[Hmacblksz] = opad[Hmacblksz] = 0;
760 for(i = 0; i < klen; i++){
764 digest = sha1(ipad, Hmacblksz, nil, nil);
765 sha1(t, tlen, innerhash, digest);
766 digest = sha1(opad, Hmacblksz, nil, nil);
767 sha1(innerhash, SHA1dlen, hash, digest);
771 shaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
774 uchar hash[SHA1dlen];
776 memset(hash, 0, SHA1dlen);
777 seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
778 r = memcmp(auth, hash, ecb->ahlen) == 0;
779 memmove(auth, hash, ecb->ahlen);
784 shaahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
787 panic("shaahinit: bad keylen");
792 ecb->ahlen = BITS2BYTES(96);
794 ecb->ahstate = secalloc(klen);
795 memmove(ecb->ahstate, key, klen);
803 aescbccipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */
805 uchar tmp[AESbsize], q[AESbsize];
806 uchar *pp, *tp, *ip, *eip, *ep;
807 AESstate *ds = ecb->espstate;
811 memmove(ds->ivec, p, AESbsize);
814 memmove(tmp, p, AESbsize);
815 aes_decrypt(ds->dkey, ds->rounds, p, q);
816 memmove(p, q, AESbsize);
819 for(eip = ip + AESbsize; ip < eip; ){
825 memmove(p, ds->ivec, AESbsize);
826 for(p += AESbsize; p < ep; p += AESbsize){
829 for(eip = ip + AESbsize; ip < eip; )
831 aes_encrypt(ds->ekey, ds->rounds, p, q);
832 memmove(ds->ivec, q, AESbsize);
833 memmove(p, q, AESbsize);
840 aescbcespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
842 uchar key[Aeskeysz], ivec[Aeskeysz];
847 memset(key, 0, sizeof(key));
849 prng(ivec, Aeskeysz);
851 ecb->espblklen = Aesblk;
852 ecb->espivlen = Aesblk;
853 ecb->cipher = aescbccipher;
854 ecb->espstate = secalloc(sizeof(AESstate));
855 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
856 memset(ivec, 0, sizeof(ivec));
857 memset(key, 0, sizeof(key));
861 aesctrcipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */
863 uchar tmp[AESbsize], q[AESbsize];
864 uchar *pp, *tp, *ip, *eip, *ep;
865 AESstate *ds = ecb->espstate;
869 memmove(ds->ivec, p, AESbsize);
872 memmove(tmp, p, AESbsize);
873 aes_decrypt(ds->dkey, ds->rounds, p, q);
874 memmove(p, q, AESbsize);
877 for(eip = ip + AESbsize; ip < eip; ){
883 memmove(p, ds->ivec, AESbsize);
884 for(p += AESbsize; p < ep; p += AESbsize){
887 for(eip = ip + AESbsize; ip < eip; )
889 aes_encrypt(ds->ekey, ds->rounds, p, q);
890 memmove(ds->ivec, q, AESbsize);
891 memmove(p, q, AESbsize);
898 aesctrespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
900 uchar key[Aesblk], ivec[Aesblk];
905 memset(key, 0, sizeof(key));
909 ecb->espblklen = Aesblk;
910 ecb->espivlen = Aesblk;
911 ecb->cipher = aesctrcipher;
912 ecb->espstate = secalloc(sizeof(AESstate));
913 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
914 memset(ivec, 0, sizeof(ivec));
915 memset(key, 0, sizeof(key));
924 seanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen)
927 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[MD5dlen];
930 memset(ipad, 0x36, Hmacblksz);
931 memset(opad, 0x5c, Hmacblksz);
932 ipad[Hmacblksz] = opad[Hmacblksz] = 0;
933 for(i = 0; i < klen; i++){
937 digest = md5(ipad, Hmacblksz, nil, nil);
938 md5(t, tlen, innerhash, digest);
939 digest = md5(opad, Hmacblksz, nil, nil);
940 md5(innerhash, MD5dlen, hash, digest);
944 md5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
949 memset(hash, 0, MD5dlen);
950 seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
951 r = memcmp(auth, hash, ecb->ahlen) == 0;
952 memmove(auth, hash, ecb->ahlen);
957 md5ahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
960 panic("md5ahinit: bad keylen");
961 klen = BITS2BYTES(klen);
964 ecb->ahlen = BITS2BYTES(96);
966 ecb->ahstate = secalloc(klen);
967 memmove(ecb->ahstate, key, klen);
972 * des, single and triple
976 descipher(Espcb *ecb, uchar *p, int n)
978 DESstate *ds = ecb->espstate;
981 memmove(ds->ivec, p, Desblk);
982 desCBCdecrypt(p + Desblk, n - Desblk, ds);
984 memmove(p, ds->ivec, Desblk);
985 desCBCencrypt(p + Desblk, n - Desblk, ds);
991 des3cipher(Espcb *ecb, uchar *p, int n)
993 DES3state *ds = ecb->espstate;
996 memmove(ds->ivec, p, Desblk);
997 des3CBCdecrypt(p + Desblk, n - Desblk, ds);
999 memmove(p, ds->ivec, Desblk);
1000 des3CBCencrypt(p + Desblk, n - Desblk, ds);
1006 desespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
1008 uchar key[Desblk], ivec[Desblk];
1013 memset(key, 0, sizeof(key));
1017 ecb->espblklen = Desblk;
1018 ecb->espivlen = Desblk;
1020 ecb->cipher = descipher;
1021 ecb->espstate = secalloc(sizeof(DESstate));
1022 setupDESstate(ecb->espstate, key, ivec);
1023 memset(ivec, 0, sizeof(ivec));
1024 memset(key, 0, sizeof(key));
1028 des3espinit(Espcb *ecb, char *name, uchar *k, unsigned n)
1030 uchar key[3][Desblk], ivec[Desblk];
1035 memset(key, 0, sizeof(key));
1039 ecb->espblklen = Desblk;
1040 ecb->espivlen = Desblk;
1042 ecb->cipher = des3cipher;
1043 ecb->espstate = secalloc(sizeof(DES3state));
1044 setupDES3state(ecb->espstate, key, ivec);
1045 memset(ivec, 0, sizeof(ivec));
1046 memset(key, 0, sizeof(key));
1051 * interfacing to devip
1058 esp = smalloc(sizeof(Proto));
1059 esp->priv = smalloc(sizeof(Esppriv));
1061 esp->connect = espconnect;
1062 esp->announce = nil;
1064 esp->state = espstate;
1065 esp->create = espcreate;
1066 esp->close = espclose;
1068 esp->advise = espadvise;
1069 esp->stats = espstats;
1070 esp->local = esplocal;
1071 esp->remote = espremote;
1072 esp->ipproto = IP_ESPPROTO;
1074 esp->ptclsize = sizeof(Espcb);