esp.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. /*
  2. * Encapsulating Security Payload for IPsec for IPv4, rfc1827.
  3. * TODO: update to match rfc4303 and thus IPv6.
  4. */
  5. #include "u.h"
  6. #include "../port/lib.h"
  7. #include "mem.h"
  8. #include "dat.h"
  9. #include "fns.h"
  10. #include "../port/error.h"
  11. #include "ip.h"
  12. #include "libsec.h"
  13. typedef struct Esphdr Esphdr;
  14. typedef struct Esptail Esptail;
  15. typedef struct Userhdr Userhdr;
  16. typedef struct Esppriv Esppriv;
  17. typedef struct Espcb Espcb;
  18. typedef struct Algorithm Algorithm;
  19. // typedef struct Esprc4 Esprc4;
  20. #define DPRINT if(0)print
  21. enum
  22. {
  23. IP_ESPPROTO = 50, /* IP v4 and v6 protocol number */
  24. EsphdrSize = IP4HDR + 8,
  25. EsptailSize = 2, /* does not include pad or auth data */
  26. UserhdrSize = 4, /* user-visible header size - if enabled */
  27. };
  28. struct Esphdr
  29. {
  30. /* ipv4 header */
  31. uchar vihl; /* Version and header length */
  32. uchar tos; /* Type of service */
  33. uchar length[2]; /* packet length */
  34. uchar id[2]; /* Identification */
  35. uchar frag[2]; /* Fragment information */
  36. uchar Unused;
  37. uchar espproto; /* Protocol */
  38. uchar espplen[2]; /* Header plus data length */
  39. uchar espsrc[4]; /* Ip source */
  40. uchar espdst[4]; /* Ip destination */
  41. /* esp header */
  42. uchar espspi[4]; /* Security parameter index */
  43. uchar espseq[4]; /* Sequence number */
  44. };
  45. struct Esptail
  46. {
  47. uchar pad;
  48. uchar nexthdr;
  49. };
  50. /* header as seen by the user */
  51. struct Userhdr
  52. {
  53. uchar nexthdr; /* next protocol */
  54. uchar unused[3];
  55. };
  56. struct Esppriv
  57. {
  58. ulong in;
  59. ulong inerrors;
  60. };
  61. /*
  62. * protocol specific part of Conv
  63. */
  64. struct Espcb
  65. {
  66. int incoming;
  67. int header; /* user user level header */
  68. ulong spi;
  69. ulong seq; /* last seq sent */
  70. ulong window; /* for replay attacks */
  71. char *espalg;
  72. void *espstate; /* other state for esp */
  73. int espivlen; /* in bytes */
  74. int espblklen;
  75. int (*cipher)(Espcb*, uchar *buf, int len);
  76. char *ahalg;
  77. void *ahstate; /* other state for esp */
  78. int ahlen; /* auth data length in bytes */
  79. int ahblklen;
  80. int (*auth)(Espcb*, uchar *buf, int len, uchar *hash);
  81. };
  82. struct Algorithm
  83. {
  84. char *name;
  85. int keylen; /* in bits */
  86. void (*init)(Espcb*, char* name, uchar *key, int keylen);
  87. };
  88. enum {
  89. RC4forward= 10*1024*1024, /* maximum skip forward */
  90. RC4back = 100*1024, /* maximum look back */
  91. };
  92. #ifdef notdef
  93. struct Esprc4
  94. {
  95. ulong cseq; /* current byte sequence number */
  96. RC4state current;
  97. int ovalid; /* old is valid */
  98. ulong lgseq; /* last good sequence */
  99. ulong oseq; /* old byte sequence number */
  100. RC4state old;
  101. };
  102. #endif
  103. static Conv* convlookup(Proto *esp, ulong spi);
  104. static char *setalg(Espcb *ecb, char **f, int n, Algorithm *alg);
  105. static void espkick(void *x);
  106. static void nullespinit(Espcb*, char*, uchar *key, int keylen);
  107. static void desespinit(Espcb *ecb, char *name, uchar *k, int n);
  108. // static void rc4espinit(Espcb *ecb, char *name, uchar *k, int n);
  109. static void nullahinit(Espcb*, char*, uchar *key, int keylen);
  110. static void shaahinit(Espcb*, char*, uchar *key, int keylen);
  111. static void md5ahinit(Espcb*, char*, uchar *key, int keylen);
  112. static Algorithm espalg[] =
  113. {
  114. "null", 0, nullespinit,
  115. // "des3_cbc", 192, des3espinit, /* rfc2451 */
  116. // "aes_128_cbc", 128, aescbcespinit, /* rfc3602 */
  117. // "aes_ctr", 128, aesctrespinit, /* rfc3686 */
  118. "des_56_cbc", 64, desespinit, /* rfc2405, deprecated */
  119. // "rc4_128", 128, rc4espinit, /* gone in rfc4305 */
  120. nil, 0, nil,
  121. };
  122. static Algorithm ahalg[] =
  123. {
  124. "null", 0, nullahinit,
  125. "hmac_sha1_96", 128, shaahinit, /* rfc2404 */
  126. // "aes_xcbc_mac_96", 128, aesahinit, /* rfc3566 */
  127. "hmac_md5_96", 128, md5ahinit, /* rfc2403 */
  128. nil, 0, nil,
  129. };
  130. static char*
  131. espconnect(Conv *c, char **argv, int argc)
  132. {
  133. char *p, *pp;
  134. char *e = nil;
  135. ulong spi;
  136. Espcb *ecb = (Espcb*)c->ptcl;
  137. switch(argc) {
  138. default:
  139. e = "bad args to connect";
  140. break;
  141. case 2:
  142. p = strchr(argv[1], '!');
  143. if(p == nil){
  144. e = "malformed address";
  145. break;
  146. }
  147. *p++ = 0;
  148. parseip(c->raddr, argv[1]);
  149. findlocalip(c->p->f, c->laddr, c->raddr);
  150. ecb->incoming = 0;
  151. ecb->seq = 0;
  152. if(strcmp(p, "*") == 0) {
  153. qlock(c->p);
  154. for(;;) {
  155. spi = nrand(1<<16) + 256;
  156. if(convlookup(c->p, spi) == nil)
  157. break;
  158. }
  159. qunlock(c->p);
  160. ecb->spi = spi;
  161. ecb->incoming = 1;
  162. qhangup(c->wq, nil);
  163. } else {
  164. spi = strtoul(p, &pp, 10);
  165. if(pp == p) {
  166. e = "malformed address";
  167. break;
  168. }
  169. ecb->spi = spi;
  170. qhangup(c->rq, nil);
  171. }
  172. nullespinit(ecb, "null", nil, 0);
  173. nullahinit(ecb, "null", nil, 0);
  174. }
  175. Fsconnected(c, e);
  176. return e;
  177. }
  178. static int
  179. espstate(Conv *c, char *state, int n)
  180. {
  181. return snprint(state, n, "%s", c->inuse?"Open\n":"Closed\n");
  182. }
  183. static void
  184. espcreate(Conv *c)
  185. {
  186. c->rq = qopen(64*1024, Qmsg, 0, 0);
  187. c->wq = qopen(64*1024, Qkick, espkick, c);
  188. }
  189. static void
  190. espclose(Conv *c)
  191. {
  192. Espcb *ecb;
  193. qclose(c->rq);
  194. qclose(c->wq);
  195. qclose(c->eq);
  196. ipmove(c->laddr, IPnoaddr);
  197. ipmove(c->raddr, IPnoaddr);
  198. ecb = (Espcb*)c->ptcl;
  199. free(ecb->espstate);
  200. free(ecb->ahstate);
  201. memset(ecb, 0, sizeof(Espcb));
  202. }
  203. static void
  204. espkick(void *x)
  205. {
  206. Conv *c = x;
  207. Esphdr *eh;
  208. Esptail *et;
  209. Userhdr *uh;
  210. Espcb *ecb;
  211. Block *bp;
  212. int nexthdr, payload, pad, align;
  213. uchar *auth;
  214. bp = qget(c->wq);
  215. if(bp == nil)
  216. return;
  217. qlock(c);
  218. ecb = c->ptcl;
  219. if(ecb->header) {
  220. /* make sure the message has a User header */
  221. bp = pullupblock(bp, UserhdrSize);
  222. if(bp == nil) {
  223. qunlock(c);
  224. return;
  225. }
  226. uh = (Userhdr*)bp->rp;
  227. nexthdr = uh->nexthdr;
  228. bp->rp += UserhdrSize;
  229. } else {
  230. nexthdr = 0; /* what should this be? */
  231. }
  232. payload = BLEN(bp) + ecb->espivlen;
  233. /* adapt to v6 */
  234. /* Make space to fit ip header */
  235. bp = padblock(bp, EsphdrSize + ecb->espivlen);
  236. align = 4;
  237. if(ecb->espblklen > align)
  238. align = ecb->espblklen;
  239. if(align % ecb->ahblklen != 0)
  240. panic("espkick: ahblklen is important after all");
  241. pad = (align-1) - (payload + EsptailSize-1)%align;
  242. /*
  243. * Make space for tail
  244. * this is done by calling padblock with a negative size
  245. * Padblock does not change bp->wp!
  246. */
  247. bp = padblock(bp, -(pad+EsptailSize+ecb->ahlen));
  248. bp->wp += pad+EsptailSize+ecb->ahlen;
  249. eh = (Esphdr *)(bp->rp);
  250. et = (Esptail*)(bp->rp + EsphdrSize + payload + pad);
  251. /* fill in tail */
  252. et->pad = pad;
  253. et->nexthdr = nexthdr;
  254. ecb->cipher(ecb, bp->rp+EsphdrSize, payload+pad+EsptailSize);
  255. auth = bp->rp + EsphdrSize + payload + pad + EsptailSize;
  256. /* fill in head */
  257. eh->vihl = IP_VER4;
  258. hnputl(eh->espspi, ecb->spi);
  259. hnputl(eh->espseq, ++ecb->seq);
  260. v6tov4(eh->espsrc, c->laddr);
  261. v6tov4(eh->espdst, c->raddr);
  262. eh->espproto = IP_ESPPROTO;
  263. eh->frag[0] = 0;
  264. eh->frag[1] = 0;
  265. ecb->auth(ecb, bp->rp + IP4HDR, (EsphdrSize - IP4HDR) +
  266. payload + pad + EsptailSize, auth);
  267. qunlock(c);
  268. /* print("esp: pass down: %uld\n", BLEN(bp)); */
  269. ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c);
  270. /* end adapt to v6 */
  271. }
  272. void
  273. espiput(Proto *esp, Ipifc*, Block *bp)
  274. {
  275. Esphdr *eh;
  276. Esptail *et;
  277. Userhdr *uh;
  278. Conv *c;
  279. Espcb *ecb;
  280. uchar raddr[IPaddrlen], laddr[IPaddrlen];
  281. Fs *f;
  282. uchar *auth;
  283. ulong spi;
  284. int payload, nexthdr;
  285. f = esp->f;
  286. bp = pullupblock(bp, EsphdrSize+EsptailSize);
  287. if(bp == nil) {
  288. netlog(f, Logesp, "esp: short packet\n");
  289. return;
  290. }
  291. /* adapt to v6 */
  292. eh = (Esphdr*)(bp->rp);
  293. spi = nhgetl(eh->espspi);
  294. v4tov6(raddr, eh->espsrc);
  295. v4tov6(laddr, eh->espdst);
  296. /* end adapt to v6 */
  297. qlock(esp);
  298. /* Look for a conversation structure for this port */
  299. c = convlookup(esp, spi);
  300. if(c == nil) {
  301. qunlock(esp);
  302. netlog(f, Logesp, "esp: no conv %I -> %I!%d\n", raddr,
  303. laddr, spi);
  304. icmpnoconv(f, bp);
  305. freeblist(bp);
  306. return;
  307. }
  308. qlock(c);
  309. qunlock(esp);
  310. ecb = c->ptcl;
  311. /* too hard to do decryption/authentication on block lists */
  312. if(bp->next)
  313. bp = concatblock(bp);
  314. /* adapt to v6 */
  315. if(BLEN(bp) < EsphdrSize + ecb->espivlen + EsptailSize + ecb->ahlen) {
  316. qunlock(c);
  317. netlog(f, Logesp, "esp: short block %I -> %I!%d\n", raddr,
  318. laddr, spi);
  319. freeb(bp);
  320. return;
  321. }
  322. eh = (Esphdr*)(bp->rp);
  323. auth = bp->wp - ecb->ahlen;
  324. if(!ecb->auth(ecb, eh->espspi, auth-eh->espspi, auth)) {
  325. qunlock(c);
  326. print("esp: bad auth %I -> %I!%ld\n", raddr, laddr, spi);
  327. netlog(f, Logesp, "esp: bad auth %I -> %I!%d\n", raddr,
  328. laddr, spi);
  329. freeb(bp);
  330. return;
  331. }
  332. payload = BLEN(bp)-EsphdrSize-ecb->ahlen;
  333. if(payload<=0 || payload%4 != 0 || payload%ecb->espblklen!=0) {
  334. qunlock(c);
  335. netlog(f, Logesp, "esp: bad length %I -> %I!%d payload=%d BLEN=%d\n",
  336. raddr, laddr, spi, payload, BLEN(bp));
  337. freeb(bp);
  338. return;
  339. }
  340. if(!ecb->cipher(ecb, bp->rp+EsphdrSize, payload)) {
  341. qunlock(c);
  342. print("esp: cipher failed %I -> %I!%ld: %s\n", raddr, laddr, spi, up->errstr);
  343. netlog(f, Logesp, "esp: cipher failed %I -> %I!%d: %s\n", raddr,
  344. laddr, spi, up->errstr);
  345. freeb(bp);
  346. return;
  347. }
  348. payload -= EsptailSize;
  349. et = (Esptail*)(bp->rp + EsphdrSize + payload);
  350. payload -= et->pad + ecb->espivlen;
  351. nexthdr = et->nexthdr;
  352. if(payload <= 0) {
  353. qunlock(c);
  354. netlog(f, Logesp, "esp: short packet after decrypt %I -> %I!%d\n",
  355. raddr, laddr, spi);
  356. freeb(bp);
  357. return;
  358. }
  359. /* trim packet */
  360. bp->rp += EsphdrSize + ecb->espivlen;
  361. bp->wp = bp->rp + payload;
  362. if(ecb->header) {
  363. /* assume UserhdrSize < EsphdrSize */
  364. bp->rp -= UserhdrSize;
  365. uh = (Userhdr*)bp->rp;
  366. memset(uh, 0, UserhdrSize);
  367. uh->nexthdr = nexthdr;
  368. }
  369. /* end adapt to v6 */
  370. if(qfull(c->rq)){
  371. netlog(f, Logesp, "esp: qfull %I -> %I.%uld\n", raddr,
  372. laddr, spi);
  373. freeblist(bp);
  374. }else {
  375. // print("esp: pass up: %uld\n", BLEN(bp));
  376. qpass(c->rq, bp);
  377. }
  378. qunlock(c);
  379. }
  380. char*
  381. espctl(Conv *c, char **f, int n)
  382. {
  383. Espcb *ecb = c->ptcl;
  384. char *e = nil;
  385. if(strcmp(f[0], "esp") == 0)
  386. e = setalg(ecb, f, n, espalg);
  387. else if(strcmp(f[0], "ah") == 0)
  388. e = setalg(ecb, f, n, ahalg);
  389. else if(strcmp(f[0], "header") == 0)
  390. ecb->header = 1;
  391. else if(strcmp(f[0], "noheader") == 0)
  392. ecb->header = 0;
  393. else
  394. e = "unknown control request";
  395. return e;
  396. }
  397. void
  398. espadvise(Proto *esp, Block *bp, char *msg)
  399. {
  400. Esphdr *h;
  401. Conv *c;
  402. ulong spi;
  403. h = (Esphdr*)(bp->rp);
  404. spi = nhgets(h->espspi);
  405. qlock(esp);
  406. c = convlookup(esp, spi);
  407. if(c != nil) {
  408. qhangup(c->rq, msg);
  409. qhangup(c->wq, msg);
  410. }
  411. qunlock(esp);
  412. freeblist(bp);
  413. }
  414. int
  415. espstats(Proto *esp, char *buf, int len)
  416. {
  417. Esppriv *upriv;
  418. upriv = esp->priv;
  419. return snprint(buf, len, "%lud %lud\n",
  420. upriv->in,
  421. upriv->inerrors);
  422. }
  423. static int
  424. esplocal(Conv *c, char *buf, int len)
  425. {
  426. Espcb *ecb = c->ptcl;
  427. int n;
  428. qlock(c);
  429. if(ecb->incoming)
  430. n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi);
  431. else
  432. n = snprint(buf, len, "%I\n", c->laddr);
  433. qunlock(c);
  434. return n;
  435. }
  436. static int
  437. espremote(Conv *c, char *buf, int len)
  438. {
  439. Espcb *ecb = c->ptcl;
  440. int n;
  441. qlock(c);
  442. if(ecb->incoming)
  443. n = snprint(buf, len, "%I\n", c->raddr);
  444. else
  445. n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi);
  446. qunlock(c);
  447. return n;
  448. }
  449. static Conv*
  450. convlookup(Proto *esp, ulong spi)
  451. {
  452. Conv *c, **p;
  453. Espcb *ecb;
  454. for(p=esp->conv; *p; p++){
  455. c = *p;
  456. ecb = c->ptcl;
  457. if(ecb->incoming && ecb->spi == spi)
  458. return c;
  459. }
  460. return nil;
  461. }
  462. static char *
  463. setalg(Espcb *ecb, char **f, int n, Algorithm *alg)
  464. {
  465. uchar *key;
  466. int c, i, nbyte, nchar;
  467. if(n < 2)
  468. return "bad format";
  469. for(; alg->name; alg++)
  470. if(strcmp(f[1], alg->name) == 0)
  471. break;
  472. if(alg->name == nil)
  473. return "unknown algorithm";
  474. if(n != 3)
  475. return "bad format";
  476. nbyte = (alg->keylen + 7) >> 3;
  477. nchar = strlen(f[2]);
  478. for(i=0; i<nchar; i++) {
  479. c = f[2][i];
  480. if(c >= '0' && c <= '9')
  481. f[2][i] -= '0';
  482. else if(c >= 'a' && c <= 'f')
  483. f[2][i] -= 'a'-10;
  484. else if(c >= 'A' && c <= 'F')
  485. f[2][i] -= 'A'-10;
  486. else
  487. return "bad character in key";
  488. }
  489. key = smalloc(nbyte);
  490. for(i=0; i<nchar && i*2<nbyte; i++) {
  491. c = f[2][nchar-i-1];
  492. if(i&1)
  493. c <<= 4;
  494. key[i>>1] |= c;
  495. }
  496. alg->init(ecb, alg->name, key, alg->keylen);
  497. free(key);
  498. return nil;
  499. }
  500. static int
  501. nullcipher(Espcb*, uchar*, int)
  502. {
  503. return 1;
  504. }
  505. static void
  506. nullespinit(Espcb *ecb, char *name, uchar*, int)
  507. {
  508. ecb->espalg = name;
  509. ecb->espblklen = 1;
  510. ecb->espivlen = 0;
  511. ecb->cipher = nullcipher;
  512. }
  513. static int
  514. nullauth(Espcb*, uchar*, int, uchar*)
  515. {
  516. return 1;
  517. }
  518. static void
  519. nullahinit(Espcb *ecb, char *name, uchar*, int)
  520. {
  521. ecb->ahalg = name;
  522. ecb->ahblklen = 1;
  523. ecb->ahlen = 0;
  524. ecb->auth = nullauth;
  525. }
  526. void
  527. seanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen)
  528. {
  529. uchar ipad[65], opad[65];
  530. int i;
  531. DigestState *digest;
  532. uchar innerhash[SHA1dlen];
  533. for(i=0; i<64; i++){
  534. ipad[i] = 0x36;
  535. opad[i] = 0x5c;
  536. }
  537. ipad[64] = opad[64] = 0;
  538. for(i=0; i<klen; i++){
  539. ipad[i] ^= key[i];
  540. opad[i] ^= key[i];
  541. }
  542. digest = sha1(ipad, 64, nil, nil);
  543. sha1(t, tlen, innerhash, digest);
  544. digest = sha1(opad, 64, nil, nil);
  545. sha1(innerhash, SHA1dlen, hash, digest);
  546. }
  547. static int
  548. shaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
  549. {
  550. uchar hash[SHA1dlen];
  551. int r;
  552. memset(hash, 0, SHA1dlen);
  553. seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, 16);
  554. r = memcmp(auth, hash, ecb->ahlen) == 0;
  555. memmove(auth, hash, ecb->ahlen);
  556. return r;
  557. }
  558. static void
  559. shaahinit(Espcb *ecb, char *name, uchar *key, int klen)
  560. {
  561. if(klen != 128)
  562. panic("shaahinit: bad keylen");
  563. klen >>= 8; /* convert to bytes */
  564. ecb->ahalg = name;
  565. ecb->ahblklen = 1;
  566. ecb->ahlen = 12;
  567. ecb->auth = shaauth;
  568. ecb->ahstate = smalloc(klen);
  569. memmove(ecb->ahstate, key, klen);
  570. }
  571. void
  572. seanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen)
  573. {
  574. uchar ipad[65], opad[65];
  575. int i;
  576. DigestState *digest;
  577. uchar innerhash[MD5dlen];
  578. for(i=0; i<64; i++){
  579. ipad[i] = 0x36;
  580. opad[i] = 0x5c;
  581. }
  582. ipad[64] = opad[64] = 0;
  583. for(i=0; i<klen; i++){
  584. ipad[i] ^= key[i];
  585. opad[i] ^= key[i];
  586. }
  587. digest = md5(ipad, 64, nil, nil);
  588. md5(t, tlen, innerhash, digest);
  589. digest = md5(opad, 64, nil, nil);
  590. md5(innerhash, MD5dlen, hash, digest);
  591. }
  592. static int
  593. md5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth)
  594. {
  595. uchar hash[MD5dlen];
  596. int r;
  597. memset(hash, 0, MD5dlen);
  598. seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, 16);
  599. r = memcmp(auth, hash, ecb->ahlen) == 0;
  600. memmove(auth, hash, ecb->ahlen);
  601. return r;
  602. }
  603. static void
  604. md5ahinit(Espcb *ecb, char *name, uchar *key, int klen)
  605. {
  606. if(klen != 128)
  607. panic("md5ahinit: bad keylen");
  608. klen >>= 3; /* convert to bytes */
  609. ecb->ahalg = name;
  610. ecb->ahblklen = 1;
  611. ecb->ahlen = 12;
  612. ecb->auth = md5auth;
  613. ecb->ahstate = smalloc(klen);
  614. memmove(ecb->ahstate, key, klen);
  615. }
  616. static int
  617. descipher(Espcb *ecb, uchar *p, int n)
  618. {
  619. uchar tmp[8];
  620. uchar *pp, *tp, *ip, *eip, *ep;
  621. DESstate *ds = ecb->espstate;
  622. ep = p + n;
  623. if(ecb->incoming) {
  624. memmove(ds->ivec, p, 8);
  625. p += 8;
  626. while(p < ep){
  627. memmove(tmp, p, 8);
  628. block_cipher(ds->expanded, p, 1);
  629. tp = tmp;
  630. ip = ds->ivec;
  631. for(eip = ip+8; ip < eip; ){
  632. *p++ ^= *ip;
  633. *ip++ = *tp++;
  634. }
  635. }
  636. } else {
  637. memmove(p, ds->ivec, 8);
  638. for(p += 8; p < ep; p += 8){
  639. pp = p;
  640. ip = ds->ivec;
  641. for(eip = ip+8; ip < eip; )
  642. *pp++ ^= *ip++;
  643. block_cipher(ds->expanded, p, 0);
  644. memmove(ds->ivec, p, 8);
  645. }
  646. }
  647. return 1;
  648. }
  649. static void
  650. desespinit(Espcb *ecb, char *name, uchar *k, int n)
  651. {
  652. uchar key[8], ivec[8];
  653. int i;
  654. /* bits to bytes */
  655. n = (n+7)>>3;
  656. if(n > 8)
  657. n = 8;
  658. memset(key, 0, sizeof(key));
  659. memmove(key, k, n);
  660. for(i=0; i<8; i++)
  661. ivec[i] = nrand(256);
  662. ecb->espalg = name;
  663. ecb->espblklen = 8;
  664. ecb->espivlen = 8;
  665. ecb->cipher = descipher;
  666. ecb->espstate = smalloc(sizeof(DESstate));
  667. setupDESstate(ecb->espstate, key, ivec);
  668. }
  669. #ifdef notdef
  670. static int
  671. rc4cipher(Espcb *ecb, uchar *p, int n)
  672. {
  673. Esprc4 *esprc4;
  674. RC4state tmpstate;
  675. ulong seq;
  676. long d, dd;
  677. if(n < 4)
  678. return 0;
  679. esprc4 = ecb->espstate;
  680. if(ecb->incoming) {
  681. seq = nhgetl(p);
  682. p += 4;
  683. n -= 4;
  684. d = seq-esprc4->cseq;
  685. if(d == 0) {
  686. rc4(&esprc4->current, p, n);
  687. esprc4->cseq += n;
  688. if(esprc4->ovalid) {
  689. dd = esprc4->cseq - esprc4->lgseq;
  690. if(dd > RC4back)
  691. esprc4->ovalid = 0;
  692. }
  693. } else if(d > 0) {
  694. print("esp rc4cipher: missing packet: %uld %ld\n", seq, d); /* this link is hosed */
  695. if(d > RC4forward) {
  696. strcpy(up->errstr, "rc4cipher: skipped too much");
  697. return 0;
  698. }
  699. esprc4->lgseq = seq;
  700. if(!esprc4->ovalid) {
  701. esprc4->ovalid = 1;
  702. esprc4->oseq = esprc4->cseq;
  703. memmove(&esprc4->old, &esprc4->current,
  704. sizeof(RC4state));
  705. }
  706. rc4skip(&esprc4->current, d);
  707. rc4(&esprc4->current, p, n);
  708. esprc4->cseq = seq+n;
  709. } else {
  710. print("esp rc4cipher: reordered packet: %uld %ld\n", seq, d);
  711. dd = seq - esprc4->oseq;
  712. if(!esprc4->ovalid || -d > RC4back || dd < 0) {
  713. strcpy(up->errstr, "rc4cipher: too far back");
  714. return 0;
  715. }
  716. memmove(&tmpstate, &esprc4->old, sizeof(RC4state));
  717. rc4skip(&tmpstate, dd);
  718. rc4(&tmpstate, p, n);
  719. return 1;
  720. }
  721. /* move old state up */
  722. if(esprc4->ovalid) {
  723. dd = esprc4->cseq - RC4back - esprc4->oseq;
  724. if(dd > 0) {
  725. rc4skip(&esprc4->old, dd);
  726. esprc4->oseq += dd;
  727. }
  728. }
  729. } else {
  730. hnputl(p, esprc4->cseq);
  731. p += 4;
  732. n -= 4;
  733. rc4(&esprc4->current, p, n);
  734. esprc4->cseq += n;
  735. }
  736. return 1;
  737. }
  738. static void
  739. rc4espinit(Espcb *ecb, char *name, uchar *k, int n)
  740. {
  741. Esprc4 *esprc4;
  742. /* bits to bytes */
  743. n = (n+7)>>3;
  744. esprc4 = smalloc(sizeof(Esprc4));
  745. memset(esprc4, 0, sizeof(Esprc4));
  746. setupRC4state(&esprc4->current, k, n);
  747. ecb->espalg = name;
  748. ecb->espblklen = 4;
  749. ecb->espivlen = 4;
  750. ecb->cipher = rc4cipher;
  751. ecb->espstate = esprc4;
  752. }
  753. #endif
  754. void
  755. espinit(Fs *fs)
  756. {
  757. Proto *esp;
  758. esp = smalloc(sizeof(Proto));
  759. esp->priv = smalloc(sizeof(Esppriv));
  760. esp->name = "esp";
  761. esp->connect = espconnect;
  762. esp->announce = nil;
  763. esp->ctl = espctl;
  764. esp->state = espstate;
  765. esp->create = espcreate;
  766. esp->close = espclose;
  767. esp->rcv = espiput;
  768. esp->advise = espadvise;
  769. esp->stats = espstats;
  770. esp->local = esplocal;
  771. esp->remote = espremote;
  772. esp->ipproto = IP_ESPPROTO;
  773. esp->nc = Nchans;
  774. esp->ptclsize = sizeof(Espcb);
  775. Fsproto(fs, esp);
  776. }