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));
270 pktipvers(Fs *f, Block **bpp)
272 if (*bpp == nil || BLEN(*bpp) == 0) {
273 /* get enough to identify the IP version */
274 *bpp = pullupblock(*bpp, IP4HDR);
276 netlog(f, Logesp, "esp: short packet\n");
280 return (((Esp4hdr*)(*bpp)->rp)->vihl & 0xf0) == IP_VER4? V4: V6;
284 getverslens(int version, Versdep *vp)
286 vp->version = version;
287 switch(vp->version) {
289 vp->iphdrlen = IP4HDR;
290 vp->hdrlen = Esp4hdrlen;
293 vp->iphdrlen = IP6HDR;
294 vp->hdrlen = Esp6hdrlen;
297 panic("esp: getverslens version %d wrong", version);
302 getpktspiaddrs(uchar *pkt, Versdep *vp)
307 switch(vp->version) {
310 v4tov6(vp->raddr, eh4->espsrc);
311 v4tov6(vp->laddr, eh4->espdst);
312 vp->spi = nhgetl(eh4->espspi);
316 ipmove(vp->raddr, eh6->src);
317 ipmove(vp->laddr, eh6->dst);
318 vp->spi = nhgetl(eh6->espspi);
321 panic("esp: getpktspiaddrs vp->version %ld wrong", vp->version);
326 * encapsulate next IP packet on x's write queue in IP/ESP packet
327 * and initiate output of the result.
332 int nexthdr, payload, pad, align;
343 getverslens(convipvers(c), &vers);
352 /* make sure the message has a User header */
353 bp = pullupblock(bp, Userhdrlen);
358 uh = (Userhdr*)bp->rp;
359 nexthdr = uh->nexthdr;
360 bp->rp += Userhdrlen;
362 nexthdr = 0; /* what should this be? */
365 payload = BLEN(bp) + ecb->espivlen;
367 /* Make space to fit ip header */
368 bp = padblock(bp, vers.hdrlen + ecb->espivlen);
369 getpktspiaddrs(bp->rp, &vers);
372 if(ecb->espblklen > align)
373 align = ecb->espblklen;
374 if(align % ecb->ahblklen != 0)
375 panic("espkick: ahblklen is important after all");
376 pad = (align-1) - (payload + Esptaillen-1)%align;
379 * Make space for tail
380 * this is done by calling padblock with a negative size
381 * Padblock does not change bp->wp!
383 bp = padblock(bp, -(pad+Esptaillen+ecb->ahlen));
384 bp->wp += pad+Esptaillen+ecb->ahlen;
386 et = (Esptail*)(bp->rp + vers.hdrlen + payload + pad);
390 et->nexthdr = nexthdr;
392 /* encrypt the payload */
393 ecb->cipher(ecb, bp->rp + vers.hdrlen, payload + pad + Esptaillen);
394 auth = bp->rp + vers.hdrlen + payload + pad + Esptaillen;
396 /* fill in head; construct a new IP header and an ESP header */
397 if (vers.version == V4) {
398 eh4 = (Esp4hdr *)bp->rp;
400 v6tov4(eh4->espsrc, c->laddr);
401 v6tov4(eh4->espdst, c->raddr);
402 eh4->espproto = IP_ESPPROTO;
406 hnputl(eh4->espspi, ecb->spi);
407 hnputl(eh4->espseq, ++ecb->seq);
409 eh6 = (Esp6hdr *)bp->rp;
410 eh6->vcf[0] = IP_VER6;
411 ipmove(eh6->src, c->laddr);
412 ipmove(eh6->dst, c->raddr);
413 eh6->proto = IP_ESPPROTO;
415 hnputl(eh6->espspi, ecb->spi);
416 hnputl(eh6->espseq, ++ecb->seq);
419 /* compute secure hash */
420 ecb->auth(ecb, bp->rp + vers.iphdrlen, (vers.hdrlen - vers.iphdrlen) +
421 payload + pad + Esptaillen, auth);
424 /* print("esp: pass down: %uld\n", BLEN(bp)); */
425 if (vers.version == V4)
426 ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c);
428 ipoput6(c->p->f, bp, 0, c->ttl, c->tos, c);
432 * decapsulate IP packet from IP/ESP packet in bp and
433 * pass the result up the spi's Conv's read queue.
436 espiput(Proto *esp, Ipifc*, Block *bp)
438 int payload, nexthdr;
439 uchar *auth, *espspi;
449 getverslens(pktipvers(f, &bp), &vers);
451 bp = pullupblock(bp, vers.hdrlen + Esptaillen);
453 netlog(f, Logesp, "esp: short packet\n");
456 getpktspiaddrs(bp->rp, &vers);
459 /* Look for a conversation structure for this port */
460 c = convlookup(esp, vers.spi);
463 netlog(f, Logesp, "esp: no conv %I -> %I!%lud\n", vers.raddr,
464 vers.laddr, vers.spi);
474 /* too hard to do decryption/authentication on block lists */
476 bp = concatblock(bp);
478 if(BLEN(bp) < vers.hdrlen + ecb->espivlen + Esptaillen + ecb->ahlen) {
480 netlog(f, Logesp, "esp: short block %I -> %I!%lud\n", vers.raddr,
481 vers.laddr, vers.spi);
486 auth = bp->wp - ecb->ahlen;
487 espspi = vers.version == V4? ((Esp4hdr*)bp->rp)->espspi:
488 ((Esp6hdr*)bp->rp)->espspi;
490 /* compute secure hash and authenticate */
491 if(!ecb->auth(ecb, espspi, auth - espspi, auth)) {
493 print("esp: bad auth %I -> %I!%ld\n", vers.raddr, vers.laddr, vers.spi);
494 netlog(f, Logesp, "esp: bad auth %I -> %I!%lud\n", vers.raddr,
495 vers.laddr, vers.spi);
500 payload = BLEN(bp) - vers.hdrlen - ecb->ahlen;
501 if(payload <= 0 || payload % 4 != 0 || payload % ecb->espblklen != 0) {
503 netlog(f, Logesp, "esp: bad length %I -> %I!%lud payload=%d BLEN=%zd\n",
504 vers.raddr, vers.laddr, vers.spi, payload, BLEN(bp));
509 /* decrypt payload */
510 if(!ecb->cipher(ecb, bp->rp + vers.hdrlen, payload)) {
512 print("esp: cipher failed %I -> %I!%ld: %s\n", vers.raddr, vers.laddr, vers.spi, up->errstr);
513 netlog(f, Logesp, "esp: cipher failed %I -> %I!%lud: %s\n",
514 vers.raddr, vers.laddr, vers.spi, up->errstr);
519 payload -= Esptaillen;
520 et = (Esptail*)(bp->rp + vers.hdrlen + payload);
521 payload -= et->pad + ecb->espivlen;
522 nexthdr = et->nexthdr;
525 netlog(f, Logesp, "esp: short packet after decrypt %I -> %I!%lud\n",
526 vers.raddr, vers.laddr, vers.spi);
532 bp->rp += vers.hdrlen + ecb->espivlen; /* toss original IP & ESP hdrs */
533 bp->wp = bp->rp + payload;
535 /* assume Userhdrlen < Esp4hdrlen < Esp6hdrlen */
536 bp->rp -= Userhdrlen;
537 uh = (Userhdr*)bp->rp;
538 memset(uh, 0, Userhdrlen);
539 uh->nexthdr = nexthdr;
542 /* ingress filtering here? */
545 netlog(f, Logesp, "esp: qfull %I -> %I.%uld\n", vers.raddr,
546 vers.laddr, vers.spi);
549 // print("esp: pass up: %uld\n", BLEN(bp));
550 qpass(c->rq, bp); /* pass packet up the read queue */
557 espctl(Conv *c, char **f, int n)
559 Espcb *ecb = c->ptcl;
562 if(strcmp(f[0], "esp") == 0)
563 e = setalg(ecb, f, n, espalg);
564 else if(strcmp(f[0], "ah") == 0)
565 e = setalg(ecb, f, n, ahalg);
566 else if(strcmp(f[0], "header") == 0)
568 else if(strcmp(f[0], "noheader") == 0)
571 e = "unknown control request";
575 /* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
577 espadvise(Proto *esp, Block *bp, char *msg)
582 getverslens(pktipvers(esp->f, &bp), &vers);
583 getpktspiaddrs(bp->rp, &vers);
586 c = convlookup(esp, vers.spi);
587 if(c != nil && !c->ignoreadvice) {
596 espstats(Proto *esp, char *buf, int len)
601 return snprint(buf, len, "%llud %lud\n",
607 esplocal(Conv *c, char *buf, int len)
609 Espcb *ecb = c->ptcl;
614 n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi);
616 n = snprint(buf, len, "%I\n", c->laddr);
622 espremote(Conv *c, char *buf, int len)
624 Espcb *ecb = c->ptcl;
629 n = snprint(buf, len, "%I\n", c->raddr);
631 n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi);
637 convlookup(Proto *esp, ulong spi)
642 for(p=esp->conv; *p; p++){
645 if(ecb->incoming && ecb->spi == spi)
652 setalg(Espcb *ecb, char **f, int n, Algorithm *alg)
660 for(; alg->name; alg++)
661 if(strcmp(f[1], alg->name) == 0)
664 return "unknown algorithm";
666 nbyte = (alg->keylen + 7) >> 3;
670 nchar = strlen(f[2]);
671 if(nchar != 2 * nbyte) /* TODO: maybe < is ok */
672 return "key not required length";
673 /* convert hex digits from ascii, in place */
674 for(i=0; i<nchar; i++) {
676 if(c >= '0' && c <= '9')
678 else if(c >= 'a' && c <= 'f')
680 else if(c >= 'A' && c <= 'F')
683 return "non-hex character in key";
685 /* collapse hex digits into complete bytes in reverse order in key */
686 key = secalloc(nbyte);
687 for(i = 0; i < nchar && i/2 < nbyte; i++) {
693 memset(f[2], 0, nchar);
694 alg->init(ecb, alg->name, key, alg->keylen);
705 nullcipher(Espcb*, uchar*, int)
711 nullespinit(Espcb *ecb, char *name, uchar*, unsigned)
716 ecb->cipher = nullcipher;
720 nullauth(Espcb*, uchar*, int, uchar*)
726 nullahinit(Espcb *ecb, char *name, uchar*, unsigned)
731 ecb->auth = nullauth;
740 seanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen)
743 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[SHA1dlen];
746 memset(ipad, 0x36, Hmacblksz);
747 memset(opad, 0x5c, Hmacblksz);
748 ipad[Hmacblksz] = opad[Hmacblksz] = 0;
749 for(i = 0; i < klen; i++){
753 digest = sha1(ipad, Hmacblksz, nil, nil);
754 sha1(t, tlen, innerhash, digest);
755 digest = sha1(opad, Hmacblksz, nil, nil);
756 sha1(innerhash, SHA1dlen, hash, digest);
760 shaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
763 uchar hash[SHA1dlen];
765 memset(hash, 0, SHA1dlen);
766 seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
767 r = memcmp(auth, hash, ecb->ahlen) == 0;
768 memmove(auth, hash, ecb->ahlen);
773 shaahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
776 panic("shaahinit: bad keylen");
781 ecb->ahlen = BITS2BYTES(96);
783 ecb->ahstate = secalloc(klen);
784 memmove(ecb->ahstate, key, klen);
792 aescbccipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */
794 uchar tmp[AESbsize], q[AESbsize];
795 uchar *pp, *tp, *ip, *eip, *ep;
796 AESstate *ds = ecb->espstate;
800 memmove(ds->ivec, p, AESbsize);
803 memmove(tmp, p, AESbsize);
804 aes_decrypt(ds->dkey, ds->rounds, p, q);
805 memmove(p, q, AESbsize);
808 for(eip = ip + AESbsize; ip < eip; ){
814 memmove(p, ds->ivec, AESbsize);
815 for(p += AESbsize; p < ep; p += AESbsize){
818 for(eip = ip + AESbsize; ip < eip; )
820 aes_encrypt(ds->ekey, ds->rounds, p, q);
821 memmove(ds->ivec, q, AESbsize);
822 memmove(p, q, AESbsize);
829 aescbcespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
831 uchar key[Aeskeysz], ivec[Aeskeysz];
836 memset(key, 0, sizeof(key));
838 prng(ivec, Aeskeysz);
840 ecb->espblklen = Aesblk;
841 ecb->espivlen = Aesblk;
842 ecb->cipher = aescbccipher;
843 ecb->espstate = secalloc(sizeof(AESstate));
844 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
845 memset(ivec, 0, sizeof(ivec));
846 memset(key, 0, sizeof(key));
850 aesctrcipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */
852 uchar tmp[AESbsize], q[AESbsize];
853 uchar *pp, *tp, *ip, *eip, *ep;
854 AESstate *ds = ecb->espstate;
858 memmove(ds->ivec, p, AESbsize);
861 memmove(tmp, p, AESbsize);
862 aes_decrypt(ds->dkey, ds->rounds, p, q);
863 memmove(p, q, AESbsize);
866 for(eip = ip + AESbsize; ip < eip; ){
872 memmove(p, ds->ivec, AESbsize);
873 for(p += AESbsize; p < ep; p += AESbsize){
876 for(eip = ip + AESbsize; ip < eip; )
878 aes_encrypt(ds->ekey, ds->rounds, p, q);
879 memmove(ds->ivec, q, AESbsize);
880 memmove(p, q, AESbsize);
887 aesctrespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
889 uchar key[Aesblk], ivec[Aesblk];
894 memset(key, 0, sizeof(key));
898 ecb->espblklen = Aesblk;
899 ecb->espivlen = Aesblk;
900 ecb->cipher = aesctrcipher;
901 ecb->espstate = secalloc(sizeof(AESstate));
902 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec);
903 memset(ivec, 0, sizeof(ivec));
904 memset(key, 0, sizeof(key));
913 seanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen)
916 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[MD5dlen];
919 memset(ipad, 0x36, Hmacblksz);
920 memset(opad, 0x5c, Hmacblksz);
921 ipad[Hmacblksz] = opad[Hmacblksz] = 0;
922 for(i = 0; i < klen; i++){
926 digest = md5(ipad, Hmacblksz, nil, nil);
927 md5(t, tlen, innerhash, digest);
928 digest = md5(opad, Hmacblksz, nil, nil);
929 md5(innerhash, MD5dlen, hash, digest);
933 md5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
938 memset(hash, 0, MD5dlen);
939 seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128));
940 r = memcmp(auth, hash, ecb->ahlen) == 0;
941 memmove(auth, hash, ecb->ahlen);
946 md5ahinit(Espcb *ecb, char *name, uchar *key, unsigned klen)
949 panic("md5ahinit: bad keylen");
950 klen = BITS2BYTES(klen);
953 ecb->ahlen = BITS2BYTES(96);
955 ecb->ahstate = secalloc(klen);
956 memmove(ecb->ahstate, key, klen);
961 * des, single and triple
965 descipher(Espcb *ecb, uchar *p, int n)
967 DESstate *ds = ecb->espstate;
970 memmove(ds->ivec, p, Desblk);
971 desCBCdecrypt(p + Desblk, n - Desblk, ds);
973 memmove(p, ds->ivec, Desblk);
974 desCBCencrypt(p + Desblk, n - Desblk, ds);
980 des3cipher(Espcb *ecb, uchar *p, int n)
982 DES3state *ds = ecb->espstate;
985 memmove(ds->ivec, p, Desblk);
986 des3CBCdecrypt(p + Desblk, n - Desblk, ds);
988 memmove(p, ds->ivec, Desblk);
989 des3CBCencrypt(p + Desblk, n - Desblk, ds);
995 desespinit(Espcb *ecb, char *name, uchar *k, unsigned n)
997 uchar key[Desblk], ivec[Desblk];
1002 memset(key, 0, sizeof(key));
1006 ecb->espblklen = Desblk;
1007 ecb->espivlen = Desblk;
1009 ecb->cipher = descipher;
1010 ecb->espstate = secalloc(sizeof(DESstate));
1011 setupDESstate(ecb->espstate, key, ivec);
1012 memset(ivec, 0, sizeof(ivec));
1013 memset(key, 0, sizeof(key));
1017 des3espinit(Espcb *ecb, char *name, uchar *k, unsigned n)
1019 uchar key[3][Desblk], ivec[Desblk];
1024 memset(key, 0, sizeof(key));
1028 ecb->espblklen = Desblk;
1029 ecb->espivlen = Desblk;
1031 ecb->cipher = des3cipher;
1032 ecb->espstate = secalloc(sizeof(DES3state));
1033 setupDES3state(ecb->espstate, key, ivec);
1034 memset(ivec, 0, sizeof(ivec));
1035 memset(key, 0, sizeof(key));
1040 * interfacing to devip
1047 esp = smalloc(sizeof(Proto));
1048 esp->priv = smalloc(sizeof(Esppriv));
1050 esp->connect = espconnect;
1051 esp->announce = nil;
1053 esp->state = espstate;
1054 esp->create = espcreate;
1055 esp->close = espclose;
1057 esp->advise = espadvise;
1058 esp->stats = espstats;
1059 esp->local = esplocal;
1060 esp->remote = espremote;
1061 esp->ipproto = IP_ESPPROTO;
1063 esp->ptclsize = sizeof(Espcb);