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.108 by root, Fri Oct 11 04:07:24 2013 UTC vs.
Revision 1.113 by root, Thu Jan 29 00:21:39 2015 UTC

43 43
44// openssl 0.9.8 compatibility 44// openssl 0.9.8 compatibility
45#if OPENSSL_VERSION_NUMBER < 0x10100000 45#if OPENSSL_VERSION_NUMBER < 0x10100000
46 #define require101(exp) exp 46 #define require101(exp) exp
47#else 47#else
48 #define require101(exp) equire (exp) 48 #define require101(exp) require (exp)
49#endif 49#endif
50 50
51#include "conf.h" 51#include "conf.h"
52#include "slog.h" 52#include "slog.h"
53#include "device.h" 53#include "device.h"
56#include "hkdf.h" 56#include "hkdf.h"
57 57
58#include "netcompat.h" 58#include "netcompat.h"
59 59
60#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic 60#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic
61#define MAGIC "HUHN\xbd\xc6\xdb\x82" // 8 bytes of magic//D
62 61
63#define ULTRA_FAST 1 62#define ULTRA_FAST 1
64#define HLOG 15 63#define HLOG 15
65#include "lzf/lzf.h" 64#include "lzf/lzf.h"
66#include "lzf/lzf_c.c" 65#include "lzf/lzf_c.c"
390bool 389bool
391hmac_packet::hmac_chk (crypto_ctx *ctx) 390hmac_packet::hmac_chk (crypto_ctx *ctx)
392{ 391{
393 unsigned char hmac_digest[EVP_MAX_MD_SIZE]; 392 unsigned char hmac_digest[EVP_MAX_MD_SIZE];
394 hmac_gen (ctx, hmac_digest); 393 hmac_gen (ctx, hmac_digest);
395 return !memcmp (hmac, hmac_digest, HMACLENGTH); 394 return slow_memeq (hmac, hmac_digest, HMACLENGTH);
396} 395}
397 396
398void 397void
399vpn_packet::set_hdr (ptype type_, unsigned int dst) 398vpn_packet::set_hdr (ptype type_, unsigned int dst)
400{ 399{
406 srcdst = ((src >> 8) << 4) | (dst >> 8); 405 srcdst = ((src >> 8) << 4) | (dst >> 8);
407 dst1 = dst; 406 dst1 = dst;
408} 407}
409 408
410#define MAXVPNDATA (MAX_MTU - 6 - 6) 409#define MAXVPNDATA (MAX_MTU - 6 - 6)
411#define DATAHDR (sizeof (u32) + RAND_SIZE)
412 410
413struct vpndata_packet : vpn_packet 411struct vpndata_packet : vpn_packet
414{ 412{
415 u8 data[MAXVPNDATA + DATAHDR]; // seqno 413 u32 ctr; // seqno
414 u8 data[MAXVPNDATA];
416 415
417 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);
418 tap_packet *unpack (connection *conn, u32 &seqno); 417 tap_packet *unpack (connection *conn, u32 &seqno);
419 418
420private: 419private:
421 const u32 data_hdr_size () const 420 const u32 data_hdr_size () const
422 { 421 {
423 return sizeof (vpndata_packet) - sizeof (net_packet) - MAXVPNDATA - DATAHDR; 422 // the distance from beginning of packet to data member
423 return data - at (0);
424 } 424 }
425}; 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}
426 448
427void 449void
428vpndata_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)
429{ 451{
430 EVP_CIPHER_CTX *cctx = &conn->octx->cctx; 452 EVP_CIPHER_CTX *cctx = &conn->octx->cctx;
448 d[1] = cl; 470 d[1] = cl;
449 } 471 }
450 } 472 }
451#endif 473#endif
452 474
453 require (EVP_CipherInit_ex (cctx, 0, 0, 0, 0, 1)); 475 ctr = htonl (seqno);
454 476
455 struct { 477 require (EVP_EncryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr)));
456#if RAND_SIZE
457 u8 rnd[RAND_SIZE];
458#endif
459 u32 seqno;
460 } datahdr;
461
462 datahdr.seqno = ntohl (seqno);
463#if RAND_SIZE
464 // NB: a constant (per session) random prefix
465 // is likely enough, but we don't take any chances.
466 conn->oiv.get (datahdr.rnd, RAND_SIZE);
467#endif
468 478
469 require (EVP_EncryptUpdate (cctx, 479 require (EVP_EncryptUpdate (cctx,
470 (unsigned char *) data + outl, &outl2, 480 (unsigned char *)data + outl, &outl2,
471 (unsigned char *) &datahdr, DATAHDR)); 481 (unsigned char *)d, l));
472 outl += outl2; 482 outl += outl2;
473 483
474 require (EVP_EncryptUpdate (cctx, 484 // it seems this is a nop for us, but we do it anyways
475 (unsigned char *) data + outl, &outl2, 485 require (EVP_EncryptFinal_ex (cctx, (unsigned char *)data + outl, &outl2));
476 (unsigned char *) d, l));
477 outl += outl2; 486 outl += outl2;
478 487
479 require (EVP_EncryptFinal_ex (cctx, (unsigned char *) data + outl, &outl2));
480 outl += outl2;
481
482 len = outl + data_hdr_size (); 488 len = data_hdr_size () + outl;
483 489
484 set_hdr (type, dst); 490 set_hdr (type, dst);
485 491
486 hmac_set (conn->octx); 492 hmac_set (conn->octx);
487} 493}
491{ 497{
492 EVP_CIPHER_CTX *cctx = &conn->ictx->cctx; 498 EVP_CIPHER_CTX *cctx = &conn->ictx->cctx;
493 int outl = 0, outl2; 499 int outl = 0, outl2;
494 tap_packet *p = new tap_packet; 500 tap_packet *p = new tap_packet;
495 u8 *d; 501 u8 *d;
496 u32 l = len - data_hdr_size ();
497 502
498 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)));
499 506
500#if ENABLE_COMPRESSION 507#if ENABLE_COMPRESSION
501 u8 cdata[MAX_MTU]; 508 u8 cdata[MAX_MTU];
502 509
503 if (type == PT_DATA_COMPRESSED) 510 if (type == PT_DATA_COMPRESSED)
504 d = cdata; 511 d = cdata;
505 else 512 else
506#endif 513#endif
507 d = &(*p)[6 + 6] - DATAHDR; 514 d = &(*p)[6 + 6];
508
509 // we play do evil games with the struct layout atm.
510 // pending better solutions, we at least do some verification.
511 // this is fine, as we left ISO territory long ago.
512 require (DATAHDR <= 16);
513 require ((u8 *)(&p->len + 1) == &(*p)[0]);
514 515
515 // this can overwrite the len/dst/src fields 516 // this can overwrite the len/dst/src fields
516 require (EVP_DecryptUpdate (cctx, 517 require (EVP_DecryptUpdate (cctx,
517 d, &outl2, 518 d, &outl2,
518 (unsigned char *)&data, len - data_hdr_size ())); 519 (unsigned char *)&data, len - data_hdr_size ()));
519 outl += outl2; 520 outl += outl2;
520 521
522 // it seems this is a nop for us, but we do it anyways
521 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2)); 523 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2));
522 outl += outl2; 524 outl += outl2;
523 525
524 seqno = ntohl (*(u32 *)(d + RAND_SIZE));
525
526 id2mac (dst () ? dst() : THISNODE->id, p->dst); 526 id2mac (dst () ? dst() : THISNODE->id, p->dst);
527 id2mac (src (), p->src); 527 id2mac (src (), p->src);
528 528
529#if ENABLE_COMPRESSION 529#if ENABLE_COMPRESSION
530 if (type == PT_DATA_COMPRESSED) 530 if (type == PT_DATA_COMPRESSED)
531 { 531 {
532 u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; 532 u32 cl = (d[0] << 8) | d[1];
533 533
534 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,
535 &(*p)[6 + 6], MAX_MTU) 535 &(*p)[6 + 6], MAX_MTU)
536 + 6 + 6; 536 + 6 + 6;
537 } 537 }
538 else 538 else
539 p->len = outl + (6 + 6 - DATAHDR); 539 p->len = outl + (6 + 6);
540#endif 540#endif
541 541
542 return p; 542 return p;
543} 543}
544 544
580void 580void
581config_packet::setup (ptype type, int dst) 581config_packet::setup (ptype type, int dst)
582{ 582{
583 prot_major = PROTOCOL_MAJOR; 583 prot_major = PROTOCOL_MAJOR;
584 prot_minor = PROTOCOL_MINOR; 584 prot_minor = PROTOCOL_MINOR;
585 randsize = RAND_SIZE;
586 flags = 0; 585 flags = 0;
587 features = get_features (); 586 features = get_features ();
588 587
589 strncpy ((char *)serial, conf.serial, sizeof (serial)); 588 strncpy ((char *)serial, conf.serial, sizeof (serial));
590 589
600config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const 599config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const
601{ 600{
602 if (prot_major != PROTOCOL_MAJOR) 601 if (prot_major != PROTOCOL_MAJOR)
603 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)"),
604 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR); 603 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR);
605 else if (randsize != RAND_SIZE)
606 slog (L_WARN, _("%s(%s): rand size mismatch (remote %d <=> local %d)"),
607 conf->nodename, (const char *)rsi, randsize, RAND_SIZE);
608 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) 604 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ())))
609 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)"),
610 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 ()));
611 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) 607 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ())))
612 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)"),
717 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff); 713 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff);
718 714
719 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);
720 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff; 716 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff;
721 717
722 oiv.reset ();
723
724 // make sure rekeying timeouts are slightly asymmetric 718 // make sure rekeying timeouts are slightly asymmetric
725 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);
726 rekey.start (rekey_interval, rekey_interval); 720 rekey.start (rekey_interval, rekey_interval);
727 721
728 hmac_error = 0.; 722 hmac_error = 0.;
881 ? (retry_cnt & 3) + 1 875 ? (retry_cnt & 3) + 1
882 : 1 << (retry_cnt >> 2)); 876 : 1 << (retry_cnt >> 2));
883 877
884 reset_si (); 878 reset_si ();
885 879
886 bool slow = si.prot & PROT_SLOW; 880 bool slow = (si.prot & PROT_SLOW) || (conf->low_power || THISNODE->low_power);
887 881
888 if (si.prot && !si.host && vpn->can_direct (THISNODE, conf)) 882 if (si.prot && !si.host && vpn->can_direct (THISNODE, conf))
889 { 883 {
890 /*TODO*/ /* start the timer so we don't recurse endlessly */ 884 /*TODO*/ /* start the timer so we don't recurse endlessly */
891 w.start (1); 885 w.start (1);
901 895
902 slow = slow || (dsi.prot & PROT_SLOW); 896 slow = slow || (dsi.prot & PROT_SLOW);
903 897
904 if (dsi.valid () && auth_rate_limiter.can (dsi)) 898 if (dsi.valid () && auth_rate_limiter.can (dsi))
905 { 899 {
906 if (retry_cnt < 4) 900 // use ping after the first few retries
901 // TODO: on rekeys, the other node might not interpret ping correctly,
902 // TODO: as it will still have a valid connection
903 if (retry_cnt < 4 && (!conf->low_power || THISNODE->low_power))
907 send_auth_request (dsi, true); 904 send_auth_request (dsi, true);
908 else 905 else
909 send_ping (dsi, 0); 906 send_ping (dsi, 0);
910 } 907 }
911 } 908 }
912 909
913 retry_int *= slow ? 8. : 0.9; 910 retry_int *= slow ? 4. : 0.9;
914 911
915 if (retry_int < conf->max_retry) 912 if (retry_int < conf->max_retry)
916 retry_cnt++; 913 retry_cnt++;
917 else 914 else
918 retry_int = conf->max_retry; 915 retry_int = conf->max_retry;
993 990
994void 991void
995connection::post_inject_queue () 992connection::post_inject_queue ()
996{ 993{
997 // force a connection every now and when when packets are sent (max 1/s) 994 // force a connection every now and when when packets are sent (max 1/s)
998 if (ev_now () - last_establish_attempt >= 0.95) // arbitrary 995 if (ev_now () - last_establish_attempt >= (conf->low_power || THISNODE->low_power ? 2.95 : 0.95)) // arbitrary
999 establish_connection.stop (); 996 establish_connection.stop ();
1000 997
1001 establish_connection (); 998 establish_connection ();
1002} 999}
1003 1000
1115 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"), 1112 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
1116 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0)); 1113 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
1117 } 1114 }
1118 else 1115 else
1119 { 1116 {
1120 bool chg = !have_rcv_auth || memcmp (&rcv_auth, &auth, sizeof auth); 1117 bool chg = !have_rcv_auth || !slow_memeq (&rcv_auth, &auth, sizeof auth);
1121 1118
1122 rcv_auth = auth; 1119 rcv_auth = auth;
1123 have_rcv_auth = true; 1120 have_rcv_auth = true;
1124 1121
1125 send_auth_response (rsi); 1122 send_auth_response (rsi);
1148 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); 1145 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename);
1149 1146
1150 auth_mac local_mac; 1147 auth_mac local_mac;
1151 auth_hash (snd_auth, p->response.ecdh, local_mac); 1148 auth_hash (snd_auth, p->response.ecdh, local_mac);
1152 1149
1153 if (memcmp (&p->response.mac, local_mac, sizeof local_mac)) 1150 if (!slow_memeq (&p->response.mac, local_mac, sizeof local_mac))
1154 { 1151 {
1155 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), 1152 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."),
1156 conf->nodename, (const char *)rsi); 1153 conf->nodename, (const char *)rsi);
1157 } 1154 }
1158 else if (!have_snd_auth) 1155 else if (!have_snd_auth)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines