ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/connection.C
(Generate patch)

Comparing gvpe/src/connection.C (file contents):
Revision 1.112 by root, Fri Sep 12 10:40:43 2014 UTC vs.
Revision 1.113 by root, Thu Jan 29 00:21:39 2015 UTC

405 srcdst = ((src >> 8) << 4) | (dst >> 8); 405 srcdst = ((src >> 8) << 4) | (dst >> 8);
406 dst1 = dst; 406 dst1 = dst;
407} 407}
408 408
409#define MAXVPNDATA (MAX_MTU - 6 - 6) 409#define MAXVPNDATA (MAX_MTU - 6 - 6)
410#define DATAHDR (sizeof (u32) + RAND_SIZE)
411 410
412struct vpndata_packet : vpn_packet 411struct vpndata_packet : vpn_packet
413{ 412{
414 u8 data[MAXVPNDATA + DATAHDR]; // seqno 413 u32 ctr; // seqno
414 u8 data[MAXVPNDATA];
415 415
416 void setup (connection *conn, int dst, u8 *d, u32 len, u32 seqno); 416 void setup (connection *conn, int dst, u8 *d, u32 len, u32 seqno);
417 tap_packet *unpack (connection *conn, u32 &seqno); 417 tap_packet *unpack (connection *conn, u32 &seqno);
418 418
419private: 419private:
420 const u32 data_hdr_size () const 420 const u32 data_hdr_size () const
421 { 421 {
422 return sizeof (vpndata_packet) - sizeof (net_packet) - MAXVPNDATA - DATAHDR; 422 // the distance from beginning of packet to data member
423 return data - at (0);
423 } 424 }
424}; 425};
426
427// expands packet counter (unlike seqno, in network byte order) to counter mode IV
428static unsigned char *
429expand_iv (u32 ctr)
430{
431 static u32 iv[IV_SIZE (CIPHER) / 4];
432
433 require (sizeof (iv) == 4 * 4);
434 require (IV_SIZE (CIPHER) % 4 == 0);
435
436 iv[0] =
437 iv[1] =
438 iv[2] = ctr;
439
440 // I would reuse ctr here to to avoid potential endianness issues,
441 // but it seems openssl wraps around. While this would be still ok,
442 // and I don't even know if its true, let's play safe and initialise
443 // to 0.
444 iv[3] = 0;
445
446 return (unsigned char *)iv;
447}
425 448
426void 449void
427vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno) 450vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno)
428{ 451{
429 EVP_CIPHER_CTX *cctx = &conn->octx->cctx; 452 EVP_CIPHER_CTX *cctx = &conn->octx->cctx;
447 d[1] = cl; 470 d[1] = cl;
448 } 471 }
449 } 472 }
450#endif 473#endif
451 474
452 require (EVP_CipherInit_ex (cctx, 0, 0, 0, 0, 1)); 475 ctr = htonl (seqno);
453 476
454 struct { 477 require (EVP_EncryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr)));
455#if RAND_SIZE
456 u8 rnd[RAND_SIZE];
457#endif
458 u32 seqno;
459 } datahdr;
460
461 datahdr.seqno = ntohl (seqno);
462#if RAND_SIZE
463 // NB: a constant (per session) random prefix
464 // is likely enough, but we don't take any chances.
465 conn->oiv.get (datahdr.rnd, RAND_SIZE);
466#endif
467 478
468 require (EVP_EncryptUpdate (cctx, 479 require (EVP_EncryptUpdate (cctx,
469 (unsigned char *) data + outl, &outl2, 480 (unsigned char *)data + outl, &outl2,
470 (unsigned char *) &datahdr, DATAHDR)); 481 (unsigned char *)d, l));
471 outl += outl2; 482 outl += outl2;
472 483
473 require (EVP_EncryptUpdate (cctx, 484 // it seems this is a nop for us, but we do it anyways
474 (unsigned char *) data + outl, &outl2, 485 require (EVP_EncryptFinal_ex (cctx, (unsigned char *)data + outl, &outl2));
475 (unsigned char *) d, l));
476 outl += outl2; 486 outl += outl2;
477 487
478 require (EVP_EncryptFinal_ex (cctx, (unsigned char *) data + outl, &outl2));
479 outl += outl2;
480
481 len = outl + data_hdr_size (); 488 len = data_hdr_size () + outl;
482 489
483 set_hdr (type, dst); 490 set_hdr (type, dst);
484 491
485 hmac_set (conn->octx); 492 hmac_set (conn->octx);
486} 493}
490{ 497{
491 EVP_CIPHER_CTX *cctx = &conn->ictx->cctx; 498 EVP_CIPHER_CTX *cctx = &conn->ictx->cctx;
492 int outl = 0, outl2; 499 int outl = 0, outl2;
493 tap_packet *p = new tap_packet; 500 tap_packet *p = new tap_packet;
494 u8 *d; 501 u8 *d;
495 u32 l = len - data_hdr_size ();
496 502
497 require (EVP_CipherInit_ex (cctx, 0, 0, 0, 0, 0)); 503 seqno = ntohl (ctr);
504
505 require (EVP_DecryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr)));
498 506
499#if ENABLE_COMPRESSION 507#if ENABLE_COMPRESSION
500 u8 cdata[MAX_MTU]; 508 u8 cdata[MAX_MTU];
501 509
502 if (type == PT_DATA_COMPRESSED) 510 if (type == PT_DATA_COMPRESSED)
503 d = cdata; 511 d = cdata;
504 else 512 else
505#endif 513#endif
506 d = &(*p)[6 + 6] - DATAHDR; 514 d = &(*p)[6 + 6];
507
508 // we play do evil games with the struct layout atm.
509 // pending better solutions, we at least do some verification.
510 // this is fine, as we left ISO territory long ago.
511 require (DATAHDR <= 16);
512 require ((u8 *)(&p->len + 1) == &(*p)[0]);
513 515
514 // this can overwrite the len/dst/src fields 516 // this can overwrite the len/dst/src fields
515 require (EVP_DecryptUpdate (cctx, 517 require (EVP_DecryptUpdate (cctx,
516 d, &outl2, 518 d, &outl2,
517 (unsigned char *)&data, len - data_hdr_size ())); 519 (unsigned char *)&data, len - data_hdr_size ()));
518 outl += outl2; 520 outl += outl2;
519 521
522 // it seems this is a nop for us, but we do it anyways
520 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2)); 523 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2));
521 outl += outl2; 524 outl += outl2;
522 525
523 seqno = ntohl (*(u32 *)(d + RAND_SIZE));
524
525 id2mac (dst () ? dst() : THISNODE->id, p->dst); 526 id2mac (dst () ? dst() : THISNODE->id, p->dst);
526 id2mac (src (), p->src); 527 id2mac (src (), p->src);
527 528
528#if ENABLE_COMPRESSION 529#if ENABLE_COMPRESSION
529 if (type == PT_DATA_COMPRESSED) 530 if (type == PT_DATA_COMPRESSED)
530 { 531 {
531 u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; 532 u32 cl = (d[0] << 8) | d[1];
532 533
533 p->len = lzf_decompress (d + DATAHDR + 2, cl < MAX_MTU ? cl : 0, 534 p->len = lzf_decompress (d + 2, cl < MAX_MTU - 2 ? cl : 0,
534 &(*p)[6 + 6], MAX_MTU) 535 &(*p)[6 + 6], MAX_MTU)
535 + 6 + 6; 536 + 6 + 6;
536 } 537 }
537 else 538 else
538 p->len = outl + (6 + 6 - DATAHDR); 539 p->len = outl + (6 + 6);
539#endif 540#endif
540 541
541 return p; 542 return p;
542} 543}
543 544
579void 580void
580config_packet::setup (ptype type, int dst) 581config_packet::setup (ptype type, int dst)
581{ 582{
582 prot_major = PROTOCOL_MAJOR; 583 prot_major = PROTOCOL_MAJOR;
583 prot_minor = PROTOCOL_MINOR; 584 prot_minor = PROTOCOL_MINOR;
584 randsize = RAND_SIZE;
585 flags = 0; 585 flags = 0;
586 features = get_features (); 586 features = get_features ();
587 587
588 strncpy ((char *)serial, conf.serial, sizeof (serial)); 588 strncpy ((char *)serial, conf.serial, sizeof (serial));
589 589
599config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const 599config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const
600{ 600{
601 if (prot_major != PROTOCOL_MAJOR) 601 if (prot_major != PROTOCOL_MAJOR)
602 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"), 602 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"),
603 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR); 603 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR);
604 else if (randsize != RAND_SIZE)
605 slog (L_WARN, _("%s(%s): rand size mismatch (remote %d <=> local %d)"),
606 conf->nodename, (const char *)rsi, randsize, RAND_SIZE);
607 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) 604 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ())))
608 slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"), 605 slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"),
609 conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); 606 conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ()));
610 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) 607 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ())))
611 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"), 608 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"),
715 delete ictx; ictx = new crypto_ctx (rcv_auth, snd_auth, rcv_ecdh_a, rcv_auth.ecdh, 0); 712 delete ictx; ictx = new crypto_ctx (rcv_auth, snd_auth, rcv_ecdh_a, rcv_auth.ecdh, 0);
716 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff); 713 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff);
717 714
718 delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1); 715 delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1);
719 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff; 716 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff;
720
721 oiv.reset ();
722 717
723 // make sure rekeying timeouts are slightly asymmetric 718 // make sure rekeying timeouts are slightly asymmetric
724 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0); 719 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
725 rekey.start (rekey_interval, rekey_interval); 720 rekey.start (rekey_interval, rekey_interval);
726 721

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines