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.110 by root, Thu Jan 9 08:15:05 2014 UTC vs.
Revision 1.115 by root, Thu Jun 30 16:31:00 2016 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003-2008,2010,2011,2013 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2010,2011,2013,2016 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
39#include <openssl/rand.h> 39#include <openssl/rand.h>
40#include <openssl/evp.h> 40#include <openssl/evp.h>
41#include <openssl/rsa.h> 41#include <openssl/rsa.h>
42#include <openssl/err.h> 42#include <openssl/err.h>
43 43
44// openssl 0.9.8 compatibility
45#if OPENSSL_VERSION_NUMBER < 0x10100000
46 #define require101(exp) exp
47#else
48 #define require101(exp) equire (exp)
49#endif
50
51#include "conf.h" 44#include "conf.h"
52#include "slog.h" 45#include "slog.h"
46#include "crypto.h"
53#include "device.h" 47#include "device.h"
54#include "vpn.h" 48#include "vpn.h"
55#include "connection.h" 49#include "connection.h"
56#include "hkdf.h" 50#include "hkdf.h"
57 51
58#include "netcompat.h" 52#include "netcompat.h"
59 53
60#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic 54#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 55
63#define ULTRA_FAST 1 56#define ULTRA_FAST 1
64#define HLOG 15 57#define HLOG 15
65#include "lzf/lzf.h" 58#include "lzf/lzf.h"
66#include "lzf/lzf_c.c" 59#include "lzf/lzf_c.c"
110 103
111////////////////////////////////////////////////////////////////////////////// 104//////////////////////////////////////////////////////////////////////////////
112 105
113struct crypto_ctx 106struct crypto_ctx
114{ 107{
115 EVP_CIPHER_CTX cctx; 108 cipher cctx;
116 HMAC_CTX hctx; 109 hmac hctx;
117 110
118 crypto_ctx (const auth_data &auth1, const auth_data &auth2, const ecdh_key &a, const ecdh_key &b, int enc); 111 crypto_ctx (const auth_data &auth1, const auth_data &auth2, const ecdh_key &a, const ecdh_key &b, int enc);
119 ~crypto_ctx (); 112 ~crypto_ctx ();
120}; 113};
121 114
133 kdf.extract (auth1.rsa.mac_key, sizeof (auth1.rsa.mac_key)); 126 kdf.extract (auth1.rsa.mac_key, sizeof (auth1.rsa.mac_key));
134 kdf.extract (s, sizeof (s)); 127 kdf.extract (s, sizeof (s));
135 kdf.extract_done (HKDF_PRF_HASH ()); 128 kdf.extract_done (HKDF_PRF_HASH ());
136 kdf.expand (mac_key, sizeof (mac_key), mac_info, sizeof (mac_info)); 129 kdf.expand (mac_key, sizeof (mac_key), mac_info, sizeof (mac_info));
137 130
138 HMAC_CTX_init (&hctx); 131 hctx.init (mac_key, MAC_KEYSIZE, MAC_DIGEST ());
139 require101 (HMAC_Init_ex (&hctx, mac_key, MAC_KEYSIZE, MAC_DIGEST (), 0));
140 } 132 }
141 133
142 { 134 {
143 u8 cipher_key[CIPHER_KEYSIZE]; 135 u8 cipher_key[CIPHER_KEYSIZE];
144 static const unsigned char cipher_info[] = "gvpe cipher key"; 136 static const unsigned char cipher_info[] = "gvpe cipher key";
147 kdf.extract (auth1.rsa.cipher_key, sizeof (auth1.rsa.cipher_key)); 139 kdf.extract (auth1.rsa.cipher_key, sizeof (auth1.rsa.cipher_key));
148 kdf.extract (s, sizeof (s)); 140 kdf.extract (s, sizeof (s));
149 kdf.extract_done (HKDF_PRF_HASH ()); 141 kdf.extract_done (HKDF_PRF_HASH ());
150 kdf.expand (cipher_key, sizeof (cipher_key), cipher_info, sizeof (cipher_info)); 142 kdf.expand (cipher_key, sizeof (cipher_key), cipher_info, sizeof (cipher_info));
151 143
152 EVP_CIPHER_CTX_init (&cctx); 144 EVP_CIPHER_CTX_init (cctx);
153 require (EVP_CipherInit_ex (&cctx, CIPHER (), 0, cipher_key, 0, enc)); 145 require (EVP_CipherInit_ex (cctx, CIPHER (), 0, cipher_key, 0, enc));
154 } 146 }
155} 147}
156 148
157crypto_ctx::~crypto_ctx () 149crypto_ctx::~crypto_ctx ()
158{ 150{
159 require (EVP_CIPHER_CTX_cleanup (&cctx)); 151 require (EVP_CIPHER_CTX_cleanup (cctx));
160 HMAC_CTX_cleanup (&hctx);
161} 152}
162 153
163static inline void 154static inline void
164auth_encrypt (RSA *key, const auth_data &auth, auth_encr &encr) 155auth_encrypt (RSA *key, const auth_data &auth, auth_encr &encr)
165{ 156{
370///////////////////////////////////////////////////////////////////////////// 361/////////////////////////////////////////////////////////////////////////////
371 362
372void 363void
373hmac_packet::hmac_gen (crypto_ctx *ctx, u8 *hmac_digest) 364hmac_packet::hmac_gen (crypto_ctx *ctx, u8 *hmac_digest)
374{ 365{
375 HMAC_CTX *hctx = &ctx->hctx; 366 ctx->hctx.init ();
376
377 require101 (HMAC_Init_ex (hctx, 0, 0, 0, 0));
378 require101 (HMAC_Update (hctx, ((unsigned char *) this) + sizeof (hmac_packet), len - sizeof (hmac_packet))); 367 ctx->hctx.add (((unsigned char *) this) + sizeof (hmac_packet), len - sizeof (hmac_packet));
379 require101 (HMAC_Final (hctx, hmac_digest, 0)); 368 ctx->hctx.digest (hmac_digest);
380} 369}
381 370
382void 371void
383hmac_packet::hmac_set (crypto_ctx *ctx) 372hmac_packet::hmac_set (crypto_ctx *ctx)
384{ 373{
406 srcdst = ((src >> 8) << 4) | (dst >> 8); 395 srcdst = ((src >> 8) << 4) | (dst >> 8);
407 dst1 = dst; 396 dst1 = dst;
408} 397}
409 398
410#define MAXVPNDATA (MAX_MTU - 6 - 6) 399#define MAXVPNDATA (MAX_MTU - 6 - 6)
411#define DATAHDR (sizeof (u32) + RAND_SIZE)
412 400
413struct vpndata_packet : vpn_packet 401struct vpndata_packet : vpn_packet
414{ 402{
415 u8 data[MAXVPNDATA + DATAHDR]; // seqno 403 u32 ctr; // seqno
404 u8 data[MAXVPNDATA];
416 405
417 void setup (connection *conn, int dst, u8 *d, u32 len, u32 seqno); 406 void setup (connection *conn, int dst, u8 *d, u32 len, u32 seqno);
418 tap_packet *unpack (connection *conn, u32 &seqno); 407 tap_packet *unpack (connection *conn, u32 &seqno);
419 408
420private: 409private:
421 const u32 data_hdr_size () const 410 const u32 data_hdr_size () const
422 { 411 {
423 return sizeof (vpndata_packet) - sizeof (net_packet) - MAXVPNDATA - DATAHDR; 412 // the distance from beginning of packet to data member
413 return data - at (0);
424 } 414 }
425}; 415};
426 416
417// expands packet counter (unlike seqno, in network byte order) to counter mode IV
418static unsigned char *
419expand_iv (u32 ctr)
420{
421 static u32 iv[IV_SIZE (CIPHER) / 4];
422
423 require (sizeof (iv) == 4 * 4);
424 require (IV_SIZE (CIPHER) % 4 == 0);
425
426 iv[0] =
427 iv[1] =
428 iv[2] = ctr;
429
430 // I would reuse ctr here to to avoid potential endianness issues,
431 // but it seems openssl wraps around. While this would be still ok,
432 // and I don't even know if its true, let's play safe and initialise
433 // to 0.
434 iv[3] = 0;
435
436 return (unsigned char *)iv;
437}
438
427void 439void
428vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno) 440vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno)
429{ 441{
430 EVP_CIPHER_CTX *cctx = &conn->octx->cctx; 442 EVP_CIPHER_CTX *cctx = conn->octx->cctx;
431 int outl = 0, outl2; 443 int outl = 0, outl2;
432 ptype type = PT_DATA_UNCOMPRESSED; 444 ptype type = PT_DATA_UNCOMPRESSED;
433 445
434#if ENABLE_COMPRESSION 446#if ENABLE_COMPRESSION
435 u8 cdata[MAX_MTU]; 447 u8 cdata[MAX_MTU];
448 d[1] = cl; 460 d[1] = cl;
449 } 461 }
450 } 462 }
451#endif 463#endif
452 464
453 require (EVP_CipherInit_ex (cctx, 0, 0, 0, 0, 1)); 465 ctr = htonl (seqno);
454 466
455 struct { 467 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 468
469 require (EVP_EncryptUpdate (cctx, 469 require (EVP_EncryptUpdate (cctx,
470 (unsigned char *) data + outl, &outl2, 470 (unsigned char *)data + outl, &outl2,
471 (unsigned char *) &datahdr, DATAHDR)); 471 (unsigned char *)d, l));
472 outl += outl2; 472 outl += outl2;
473 473
474 require (EVP_EncryptUpdate (cctx, 474 // it seems this is a nop for us, but we do it anyways
475 (unsigned char *) data + outl, &outl2, 475 require (EVP_EncryptFinal_ex (cctx, (unsigned char *)data + outl, &outl2));
476 (unsigned char *) d, l));
477 outl += outl2; 476 outl += outl2;
478 477
479 require (EVP_EncryptFinal_ex (cctx, (unsigned char *) data + outl, &outl2));
480 outl += outl2;
481
482 len = outl + data_hdr_size (); 478 len = data_hdr_size () + outl;
483 479
484 set_hdr (type, dst); 480 set_hdr (type, dst);
485 481
486 hmac_set (conn->octx); 482 hmac_set (conn->octx);
487} 483}
488 484
489tap_packet * 485tap_packet *
490vpndata_packet::unpack (connection *conn, u32 &seqno) 486vpndata_packet::unpack (connection *conn, u32 &seqno)
491{ 487{
492 EVP_CIPHER_CTX *cctx = &conn->ictx->cctx; 488 EVP_CIPHER_CTX *cctx = conn->ictx->cctx;
493 int outl = 0, outl2; 489 int outl = 0, outl2;
494 tap_packet *p = new tap_packet; 490 tap_packet *p = new tap_packet;
495 u8 *d; 491 u8 *d;
496 u32 l = len - data_hdr_size ();
497 492
498 require (EVP_CipherInit_ex (cctx, 0, 0, 0, 0, 0)); 493 seqno = ntohl (ctr);
494
495 require (EVP_DecryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr)));
499 496
500#if ENABLE_COMPRESSION 497#if ENABLE_COMPRESSION
501 u8 cdata[MAX_MTU]; 498 u8 cdata[MAX_MTU];
502 499
503 if (type == PT_DATA_COMPRESSED) 500 if (type == PT_DATA_COMPRESSED)
504 d = cdata; 501 d = cdata;
505 else 502 else
506#endif 503#endif
507 d = &(*p)[6 + 6] - DATAHDR; 504 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 505
515 // this can overwrite the len/dst/src fields 506 // this can overwrite the len/dst/src fields
516 require (EVP_DecryptUpdate (cctx, 507 require (EVP_DecryptUpdate (cctx,
517 d, &outl2, 508 d, &outl2,
518 (unsigned char *)&data, len - data_hdr_size ())); 509 (unsigned char *)&data, len - data_hdr_size ()));
519 outl += outl2; 510 outl += outl2;
520 511
512 // it seems this is a nop for us, but we do it anyways
521 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2)); 513 require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2));
522 outl += outl2; 514 outl += outl2;
523 515
524 seqno = ntohl (*(u32 *)(d + RAND_SIZE));
525
526 id2mac (dst () ? dst() : THISNODE->id, p->dst); 516 id2mac (dst () ? dst() : THISNODE->id, p->dst);
527 id2mac (src (), p->src); 517 id2mac (src (), p->src);
528 518
529#if ENABLE_COMPRESSION 519#if ENABLE_COMPRESSION
530 if (type == PT_DATA_COMPRESSED) 520 if (type == PT_DATA_COMPRESSED)
531 { 521 {
532 u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; 522 u32 cl = (d[0] << 8) | d[1];
533 523
534 p->len = lzf_decompress (d + DATAHDR + 2, cl < MAX_MTU ? cl : 0, 524 p->len = lzf_decompress (d + 2, cl < MAX_MTU - 2 ? cl : 0,
535 &(*p)[6 + 6], MAX_MTU) 525 &(*p)[6 + 6], MAX_MTU)
536 + 6 + 6; 526 + 6 + 6;
537 } 527 }
538 else 528 else
539 p->len = outl + (6 + 6 - DATAHDR); 529 p->len = outl + (6 + 6);
540#endif 530#endif
541 531
542 return p; 532 return p;
543} 533}
544 534
580void 570void
581config_packet::setup (ptype type, int dst) 571config_packet::setup (ptype type, int dst)
582{ 572{
583 prot_major = PROTOCOL_MAJOR; 573 prot_major = PROTOCOL_MAJOR;
584 prot_minor = PROTOCOL_MINOR; 574 prot_minor = PROTOCOL_MINOR;
585 randsize = RAND_SIZE;
586 flags = 0; 575 flags = 0;
587 features = get_features (); 576 features = get_features ();
588 577
589 strncpy ((char *)serial, conf.serial, sizeof (serial)); 578 strncpy ((char *)serial, conf.serial, sizeof (serial));
590 579
600config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const 589config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const
601{ 590{
602 if (prot_major != PROTOCOL_MAJOR) 591 if (prot_major != PROTOCOL_MAJOR)
603 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"), 592 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"),
604 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR); 593 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 ()))) 594 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ())))
609 slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"), 595 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 ())); 596 conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ()));
611 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) 597 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ())))
612 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"), 598 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"),
716 delete ictx; ictx = new crypto_ctx (rcv_auth, snd_auth, rcv_ecdh_a, rcv_auth.ecdh, 0); 702 delete ictx; ictx = new crypto_ctx (rcv_auth, snd_auth, rcv_ecdh_a, rcv_auth.ecdh, 0);
717 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff); 703 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff);
718 704
719 delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1); 705 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; 706 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff;
721
722 oiv.reset ();
723 707
724 // make sure rekeying timeouts are slightly asymmetric 708 // make sure rekeying timeouts are slightly asymmetric
725 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0); 709 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
726 rekey.start (rekey_interval, rekey_interval); 710 rekey.start (rekey_interval, rekey_interval);
727 711

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines