Browse code

Add client-side support for cipher negotiation

Based on the 'IV_NCP=2' mechanism described in
http://permalink.gmane.org/gmane.network.openvpn.devel/9385.

This is the first patch of a set that adds support for cipher negotiation.
Follow-up patches will add ways to restrict or disable the mechanism, and
add server-side support.

v2:
* Account for crypto overhead through struct frame. This is less
transparant, but the code has been built to work this way. The
previous approach didn't work with TCP mode (or --port-share).
* Calculate the link-mtu sent in the options string based on the crypto
parameters specified in the config file (prevents link-mtu warnings in
older peers when connecting).

v3:
* Use existing max_int() function, instead of new MAX() macro.
* Fix typo in comment.
* Do not regenerate keys if the server sends a second push msg
* Only push IV_NCP if we're pull-client (and thus can do NCP)

v4:
* Fix rebase errors (OPT_P_NCP sneaked in, but is not introduced till 4/5,
and tls_peer_info_ncp_ver() is not needed until 5/5).
* Don't remove comment about key_id increment behaviour in init.c (but
still add the extra comments in the .h files).

Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1467149635-9726-1-git-send-email-steffan@karger.me>
URL: http://article.gmane.org/gmane.network.openvpn.devel/12007
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2016/06/29 06:33:55
Showing 9 changed files
... ...
@@ -35,6 +35,7 @@
35 35
 
36 36
 #include "crypto.h"
37 37
 #include "error.h"
38
+#include "integer.h"
38 39
 #include "misc.h"
39 40
 
40 41
 #include "memdbg.h"
... ...
@@ -709,10 +710,6 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
709 709
   return ret;
710 710
 }
711 711
 
712
-/*
713
- * How many bytes will we add to frame buffer for a given
714
- * set of crypto options?
715
- */
716 712
 void
717 713
 crypto_adjust_frame_parameters(struct frame *frame,
718 714
 			       const struct key_type* kt,
... ...
@@ -746,6 +743,14 @@ crypto_adjust_frame_parameters(struct frame *frame,
746 746
       __func__, crypto_overhead);
747 747
 }
748 748
 
749
+size_t
750
+crypto_max_overhead(void)
751
+{
752
+  return packet_id_size(true) + OPENVPN_MAX_IV_LENGTH +
753
+      OPENVPN_MAX_CIPHER_BLOCK_SIZE +
754
+      max_int (OPENVPN_MAX_HMAC_SIZE, OPENVPN_AEAD_TAG_LENGTH);
755
+}
756
+
749 757
 /*
750 758
  * Build a struct key_type.
751 759
  */
... ...
@@ -774,6 +779,9 @@ init_key_type (struct key_type *kt, const char *ciphername,
774 774
 #endif
775 775
 	    ))
776 776
 	msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
777
+
778
+      if (OPENVPN_MAX_CIPHER_BLOCK_SIZE < cipher_kt_block_size(kt->cipher))
779
+	msg (M_FATAL, "Cipher '%s' not allowed: block size too big.", ciphername);
777 780
     }
778 781
   else
779 782
     {
... ...
@@ -785,6 +793,9 @@ init_key_type (struct key_type *kt, const char *ciphername,
785 785
       if (!aead_cipher) { /* Ignore auth for AEAD ciphers */
786 786
 	kt->digest = md_kt_get (authname);
787 787
 	kt->hmac_length = md_kt_size (kt->digest);
788
+
789
+	if (OPENVPN_MAX_HMAC_SIZE < kt->hmac_length)
790
+	  msg (M_FATAL, "HMAC '%s' not allowed: digest size too big.", authname);
788 791
       }
789 792
     }
790 793
   else if (!aead_cipher)
... ...
@@ -226,6 +226,7 @@ struct key_ctx_bi
226 226
 				 *   direction. */
227 227
   struct key_ctx decrypt;       /**< cipher and/or HMAC contexts for
228 228
                                  *   receiving direction. */
229
+  bool initialized;
229 230
 };
230 231
 
231 232
 /**
... ...
@@ -385,6 +386,7 @@ bool openvpn_decrypt (struct buffer *buf, struct buffer work,
385 385
 
386 386
 /** @} name Functions for performing security operations on data channel packets */
387 387
 
388
+/** Calculate crypto overhead and adjust frame to account for that */
388 389
 void crypto_adjust_frame_parameters(struct frame *frame,
389 390
 				    const struct key_type* kt,
390 391
 				    bool cipher_defined,
... ...
@@ -392,6 +394,8 @@ void crypto_adjust_frame_parameters(struct frame *frame,
392 392
 				    bool packet_id,
393 393
 				    bool packet_id_long_form);
394 394
 
395
+/** Return the worst-case OpenVPN crypto overhead (in bytes) */
396
+size_t crypto_max_overhead(void);
395 397
 
396 398
 /* Minimum length of the nonce used by the PRNG */
397 399
 #define NONCE_SECRET_LEN_MIN 16
... ...
@@ -41,6 +41,12 @@
41 41
 /* TLS uses a tag of 128 bytes, let's do the same for OpenVPN */
42 42
 #define OPENVPN_AEAD_TAG_LENGTH 16
43 43
 
44
+/* Maximum cipher block size (bytes) */
45
+#define OPENVPN_MAX_CIPHER_BLOCK_SIZE 32
46
+
47
+/* Maximum HMAC digest size (bytes) */
48
+#define OPENVPN_MAX_HMAC_SIZE 	64
49
+
44 50
 /** Struct used in cipher name translation table */
45 51
 typedef struct {
46 52
   const char *openvpn_name;	/**< Cipher name used by OpenVPN */
... ...
@@ -1825,6 +1825,7 @@ pull_permission_mask (const struct context *c)
1825 1825
     | OPT_P_SHAPER
1826 1826
     | OPT_P_TIMER
1827 1827
     | OPT_P_COMP
1828
+    | OPT_P_CRYPTO
1828 1829
     | OPT_P_PERSIST
1829 1830
     | OPT_P_MESSAGES
1830 1831
     | OPT_P_EXPLICIT_NOTIFY
... ...
@@ -1928,6 +1929,19 @@ do_deferred_options (struct context *c, const unsigned int found)
1928 1928
                        " MTU problems", TUN_MTU_SIZE(&c->c2.frame) );
1929 1929
 	}
1930 1930
     }
1931
+
1932
+  /* process (potentially pushed) crypto options */
1933
+  if (c->options.pull)
1934
+    {
1935
+      struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
1936
+      if (found & OPT_P_CRYPTO)
1937
+	msg (D_PUSH, "OPTIONS IMPORT: data channel crypto options modified");
1938
+      /* Do not regenerate keys if server sends an extra push request */
1939
+      if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized)
1940
+	{
1941
+	  tls_session_update_crypto_params(session, &c->options, &c->c2.frame);
1942
+	}
1943
+    }
1931 1944
 #endif
1932 1945
 }
1933 1946
 
... ...
@@ -2043,6 +2057,7 @@ frame_finalize_options (struct context *c, const struct options *o)
2043 2043
 			    |FRAME_HEADROOM_MARKER_READ_STREAM);
2044 2044
     }
2045 2045
   
2046
+  frame_add_to_extra_buffer (&c->c2.frame, PAYLOAD_ALIGN);
2046 2047
   frame_finalize (&c->c2.frame,
2047 2048
 		  o->ce.link_mtu_defined,
2048 2049
 		  o->ce.link_mtu,
... ...
@@ -2298,12 +2313,18 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
2298 2298
   /* In short form, unique datagram identifier is 32 bits, in long form 64 bits */
2299 2299
   packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
2300 2300
 
2301
-  /* Compute MTU parameters */
2302
-  crypto_adjust_frame_parameters (&c->c2.frame,
2303
-				  &c->c1.ks.key_type,
2304
-				  options->ciphername_defined,
2305
-				  options->use_iv,
2306
-				  options->replay, packet_id_long_form);
2301
+  /* Compute MTU parameters (postpone if we pull options) */
2302
+  if (c->options.pull)
2303
+    {
2304
+      /* Account for worst-case crypto overhead before allocating buffers */
2305
+      frame_add_to_extra_frame (&c->c2.frame, crypto_max_overhead());
2306
+    }
2307
+  else
2308
+    {
2309
+      crypto_adjust_frame_parameters(&c->c2.frame, &c->c1.ks.key_type,
2310
+	  options->ciphername_defined, options->use_iv, options->replay,
2311
+	  packet_id_long_form);
2312
+    }
2307 2313
   tls_adjust_frame_parameters (&c->c2.frame);
2308 2314
 
2309 2315
   /* Set all command-line TLS-related options */
... ...
@@ -2334,6 +2355,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
2334 2334
   to.renegotiate_packets = options->renegotiate_packets;
2335 2335
   to.renegotiate_seconds = options->renegotiate_seconds;
2336 2336
   to.single_session = options->single_session;
2337
+  to.pull = options->pull;
2337 2338
 #ifdef ENABLE_PUSH_PEER_INFO
2338 2339
   if (options->push_peer_info)		/* all there is */
2339 2340
     to.push_peer_info_detail = 2;
... ...
@@ -78,8 +78,6 @@ frame_finalize (struct frame *frame,
78 78
     }
79 79
 
80 80
   frame->link_mtu_dynamic = frame->link_mtu;
81
-
82
-  frame->extra_buffer += PAYLOAD_ALIGN;
83 81
 }
84 82
 
85 83
 /*
... ...
@@ -2965,6 +2965,38 @@ pre_pull_restore (struct options *o, struct gc_arena *gc)
2965 2965
 
2966 2966
 #ifdef ENABLE_OCC
2967 2967
 
2968
+/**
2969
+ * Calculate the link-mtu to advertise to our peer.  The actual value is not
2970
+ * relevant, because we will possibly perform data channel cipher negotiation
2971
+ * after this, but older clients will log warnings if we do not supply them the
2972
+ * value they expect.  This assumes that the traditional cipher/auth directives
2973
+ * in the config match the config of the peer.
2974
+ */
2975
+static size_t
2976
+calc_options_string_link_mtu(const struct options *o, const struct frame *frame)
2977
+{
2978
+  size_t link_mtu = EXPANDED_SIZE (frame);
2979
+#ifdef ENABLE_CRYPTO
2980
+  if (o->pull || o->mode == MODE_SERVER)
2981
+    {
2982
+      struct frame fake_frame = *frame;
2983
+      struct key_type fake_kt;
2984
+      init_key_type (&fake_kt, o->ciphername, o->ciphername_defined,
2985
+	  o->authname, o->authname_defined, o->keysize, true, false);
2986
+      frame_add_to_extra_frame (&fake_frame, -(crypto_max_overhead()));
2987
+      crypto_adjust_frame_parameters (&fake_frame, &fake_kt,
2988
+	  o->ciphername_defined, o->use_iv, o->replay,
2989
+	  cipher_kt_mode_ofb_cfb (fake_kt.cipher));
2990
+      frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu,
2991
+            o->ce.tun_mtu_defined, o->ce.tun_mtu);
2992
+      msg (D_MTU_DEBUG, "%s: link-mtu %zu -> %d", __func__, link_mtu,
2993
+	  EXPANDED_SIZE (&fake_frame));
2994
+      link_mtu = EXPANDED_SIZE (&fake_frame);
2995
+    }
2996
+#endif
2997
+  return link_mtu;
2998
+}
2999
+
2968 3000
 /*
2969 3001
  * Build an options string to represent data channel encryption options.
2970 3002
  * This string must match exactly between peers.  The keysize is checked
... ...
@@ -3009,7 +3041,6 @@ pre_pull_restore (struct options *o, struct gc_arena *gc)
3009 3009
  * --tls-server [matched with --tls-client on
3010 3010
  *               the other end of the connection]
3011 3011
  */
3012
-
3013 3012
 char *
3014 3013
 options_string (const struct options *o,
3015 3014
 		const struct frame *frame,
... ...
@@ -3027,7 +3058,7 @@ options_string (const struct options *o,
3027 3027
    */
3028 3028
 
3029 3029
   buf_printf (&out, ",dev-type %s", dev_type_string (o->dev, o->dev_type));
3030
-  buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame));
3030
+  buf_printf (&out, ",link-mtu %zu", calc_options_string_link_mtu(o, frame));
3031 3031
   buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame));
3032 3032
   buf_printf (&out, ",proto %s",  proto_remote (o->ce.proto, remote));
3033 3033
 
... ...
@@ -1613,6 +1613,7 @@ generate_key_expansion (struct key_ctx_bi *key,
1613 1613
   key_ctx_update_implicit_iv (&key->decrypt, key2.keys[1-(int)server].hmac,
1614 1614
       MAX_HMAC_KEY_LENGTH);
1615 1615
 
1616
+  key->initialized = true;
1616 1617
   ret = true;
1617 1618
 
1618 1619
  exit:
... ...
@@ -1639,6 +1640,50 @@ key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len) {
1639 1639
     }
1640 1640
 }
1641 1641
 
1642
+bool
1643
+tls_session_update_crypto_params(struct tls_session *session,
1644
+    const struct options *options, struct frame *frame)
1645
+{
1646
+  bool ret = false;
1647
+  struct key_state *ks = &session->key[KS_PRIMARY];	/* primary key */
1648
+
1649
+  ASSERT (!session->opt->server);
1650
+  ASSERT (ks->authenticated);
1651
+
1652
+  init_key_type (&session->opt->key_type, options->ciphername,
1653
+    options->ciphername_defined, options->authname, options->authname_defined,
1654
+    options->keysize, true, true);
1655
+
1656
+  bool packet_id_long_form = cipher_kt_mode_ofb_cfb (session->opt->key_type.cipher);
1657
+  session->opt->crypto_flags_and &= ~(CO_PACKET_ID_LONG_FORM);
1658
+  if (packet_id_long_form)
1659
+    session->opt->crypto_flags_and = CO_PACKET_ID_LONG_FORM;
1660
+
1661
+  /* Update frame parameters: undo worst-case overhead, add actual overhead */
1662
+  frame_add_to_extra_frame (frame, -(crypto_max_overhead()));
1663
+  crypto_adjust_frame_parameters (frame, &session->opt->key_type,
1664
+      options->ciphername_defined, options->use_iv, options->replay,
1665
+      packet_id_long_form);
1666
+  frame_finalize(frame, options->ce.link_mtu_defined, options->ce.link_mtu,
1667
+      options->ce.tun_mtu_defined, options->ce.tun_mtu);
1668
+  frame_print (frame, D_MTU_INFO, "Data Channel MTU parms");
1669
+
1670
+  if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
1671
+			       &session->opt->key_type,
1672
+			       ks->key_src,
1673
+			       &session->session_id,
1674
+			       &ks->session_id_remote,
1675
+			       false))
1676
+    {
1677
+      msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
1678
+      goto cleanup;
1679
+    }
1680
+  ret = true;
1681
+cleanup:
1682
+  CLEAR (*ks->key_src);
1683
+  return ret;
1684
+}
1685
+
1642 1686
 static bool
1643 1687
 random_bytes_to_buf (struct buffer *buf,
1644 1688
 		     uint8_t *out,
... ...
@@ -1885,6 +1930,10 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
1885 1885
       /* support for P_DATA_V2 */
1886 1886
       buf_printf(&out, "IV_PROTO=2\n");
1887 1887
 
1888
+      /* support for Negotiable Crypto Paramters */
1889
+      if (session->opt->pull)
1890
+	buf_printf(&out, "IV_NCP=2\n");
1891
+
1888 1892
       /* push compression status */
1889 1893
 #ifdef USE_COMP
1890 1894
       comp_generate_peer_info_string(&session->opt->comp_options, &out);
... ...
@@ -2211,9 +2260,11 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
2211 2211
     }
2212 2212
 
2213 2213
   /*
2214
-   * Generate tunnel keys if client
2214
+   * Generate tunnel keys if we're a client.
2215
+   * If --pull is enabled, the first key generation is postponed until after the
2216
+   * pull/push, so we can process pushed cipher directives.
2215 2217
    */
2216
-  if (!session->opt->server)
2218
+  if (!session->opt->server && (!session->opt->pull || ks->key_id > 0))
2217 2219
     {
2218 2220
       if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
2219 2221
 				   &session->opt->key_type,
... ...
@@ -2225,7 +2276,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
2225 2225
 	  msg (D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed");
2226 2226
 	  goto error;
2227 2227
 	}
2228
-		      
2228
+
2229 2229
       CLEAR (*ks->key_src);
2230 2230
     }
2231 2231
 
... ...
@@ -2891,6 +2942,14 @@ tls_pre_decrypt (struct tls_multi *multi,
2891 2891
 #endif
2892 2892
 		  && (floated || link_socket_actual_match (from, &ks->remote_addr)))
2893 2893
 		{
2894
+		  if (!ks->crypto_options.key_ctx_bi.initialized)
2895
+		    {
2896
+		      msg (D_TLS_DEBUG_LOW,
2897
+			  "Key %s [%d] not initialized (yet), dropping packet.",
2898
+			  print_link_socket_actual (from, &gc), key_id);
2899
+		      goto error_lite;
2900
+		    }
2901
+
2894 2902
 		  /* return appropriate data channel decrypt key in opt */
2895 2903
 		  *opt = &ks->crypto_options;
2896 2904
 		  if (op == P_DATA_V2)
... ...
@@ -3428,6 +3487,7 @@ tls_pre_encrypt (struct tls_multi *multi,
3428 3428
 	  struct key_state *ks = multi->key_scan[i];
3429 3429
 	  if (ks->state >= S_ACTIVE
3430 3430
 	      && ks->authenticated
3431
+	      && ks->crypto_options.key_ctx_bi.initialized
3431 3432
 #ifdef ENABLE_DEF_AUTH
3432 3433
 	      && !ks->auth_deferred
3433 3434
 #endif
... ...
@@ -475,6 +475,20 @@ bool tls_rec_payload (struct tls_multi *multi,
475 475
 void tls_update_remote_addr (struct tls_multi *multi,
476 476
 			     const struct link_socket_actual *addr);
477 477
 
478
+/**
479
+ * Update TLS session crypto parameters (cipher and auth) and derive data
480
+ * channel keys based on the supplied options.
481
+ *
482
+ * @param session	The TLS session to update.
483
+ * @param options	The options to use when updating session.
484
+ * @param frame		The frame options for this session (frame overhead is
485
+ * 			adjusted based on the selected cipher/auth).
486
+ *
487
+ * @return true if updating succeeded, false otherwise.
488
+ */
489
+bool tls_session_update_crypto_params(struct tls_session *session,
490
+    const struct options *options, struct frame *frame);
491
+
478 492
 #ifdef MANAGEMENT_DEF_AUTH
479 493
 static inline char *
480 494
 tls_get_peer_info(const struct tls_multi *multi)
... ...
@@ -149,7 +149,12 @@ struct key_source2 {
149 149
 struct key_state
150 150
 {
151 151
   int state;
152
-  int key_id;			/* inherited from struct tls_session below */
152
+
153
+  /**
154
+   * Key id for this key_state,  inherited from struct tls_session.
155
+   * @see tls_session::key_id.
156
+   */
157
+  int key_id;
153 158
 
154 159
   struct key_state_ssl ks_ssl;	/* contains SSL object and BIOs for the control channel */
155 160
 
... ...
@@ -231,6 +236,7 @@ struct tls_options
231 231
 #ifdef ENABLE_OCC
232 232
   bool disable_occ;
233 233
 #endif
234
+  bool pull;
234 235
 #ifdef ENABLE_PUSH_PEER_INFO
235 236
   int push_peer_info_detail;
236 237
 #endif
... ...
@@ -367,7 +373,13 @@ struct tls_session
367 367
 
368 368
   int initial_opcode;		/* our initial P_ opcode */
369 369
   struct session_id session_id;	/* our random session ID */
370
-  int key_id;			/* increments with each soft reset (for key renegotiation) */
370
+
371
+  /**
372
+   * The current active key id, used to keep track of renegotiations.
373
+   * key_id increments with each soft reset to KEY_ID_MASK then recycles back
374
+   * to 1.  This way you know that if key_id is 0, it is the first key.
375
+   */
376
+  int key_id;
371 377
 
372 378
   int limit_next;               /* used for traffic shaping on the control channel */
373 379