… | |
… | |
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" |
… | |
… | |
390 | bool |
389 | bool |
391 | hmac_packet::hmac_chk (crypto_ctx *ctx) |
390 | hmac_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 | |
398 | void |
397 | void |
399 | vpn_packet::set_hdr (ptype type_, unsigned int dst) |
398 | vpn_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 | |
413 | struct vpndata_packet : vpn_packet |
411 | struct 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 | |
420 | private: |
419 | private: |
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 |
|
|
428 | static unsigned char * |
|
|
429 | expand_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 | |
427 | void |
449 | void |
428 | vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno) |
450 | vpndata_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 | |
… | |
… | |
580 | void |
580 | void |
581 | config_packet::setup (ptype type, int dst) |
581 | config_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 | |
… | |
… | |
600 | config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const |
599 | config_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 | |
994 | void |
991 | void |
995 | connection::post_inject_queue () |
992 | connection::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) |