esp.c 17 KB

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