Browse code

Add support for CHACHA20-POLY1305 in the data channel

We explicitly only supported GCM as a valid AEAD mode, change that to also
allow ChaCha20-Poly1305 as an AEAD cipher. That works nicely with our new
(GCM) data channel format, because is has the same 96-bit IV.

Note that we need some tricks to not treat the cipher as insecure, because
we used to only look at the block size of a cipher to determine if find a
cipher insecure. But ChaCha20-Poly1305 is a stream cipher, which
essentially
has a 'block size' of 1 byte and is reported as such. So, special-case
this
cipher to be in the list of secure ciphers.

Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20181007223035.21179-1-steffan@karger.me>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17629.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2018/10/08 07:30:34
Showing 6 changed files
... ...
@@ -1,3 +1,13 @@
1
+Overview of changes in 2.5
2
+==========================
3
+
4
+New features
5
+------------
6
+ChaCha20-Poly1305 cipher support
7
+    Added support for using the ChaCha20-Poly1305 cipher in the OpenVPN data
8
+    channel.
9
+
10
+
1 11
 Overview of changes in 2.4
2 12
 ==========================
3 13
 
... ...
@@ -841,7 +841,7 @@ init_key_ctx(struct key_ctx *ctx, const struct key *key,
841 841
         dmsg(D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d",
842 842
              prefix, cipher_kt_block_size(kt->cipher),
843 843
              cipher_kt_iv_size(kt->cipher));
844
-        if (cipher_kt_block_size(kt->cipher) < 128/8)
844
+        if (cipher_kt_insecure(kt->cipher))
845 845
         {
846 846
             msg(M_WARN, "WARNING: INSECURE cipher with block size less than 128"
847 847
                 " bit (%d bit).  This allows attacks like SWEET32.  Mitigate by "
... ...
@@ -285,6 +285,11 @@ int cipher_kt_block_size(const cipher_kt_t *cipher_kt);
285 285
 int cipher_kt_tag_size(const cipher_kt_t *cipher_kt);
286 286
 
287 287
 /**
288
+ * Returns true if we consider this cipher to be insecure.
289
+ */
290
+bool cipher_kt_insecure(const cipher_kt_t *cipher);
291
+
292
+/**
288 293
  * Returns the mode that the cipher runs in.
289 294
  *
290 295
  * @param cipher_kt     Static cipher parameters. May not be NULL.
... ...
@@ -175,7 +175,7 @@ show_available_ciphers(void)
175 175
     while (*ciphers != 0)
176 176
     {
177 177
         const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers);
178
-        if (info && cipher_kt_block_size(info) >= 128/8)
178
+        if (info && !cipher_kt_insecure(info))
179 179
         {
180 180
             print_cipher(info);
181 181
         }
... ...
@@ -188,7 +188,7 @@ show_available_ciphers(void)
188 188
     while (*ciphers != 0)
189 189
     {
190 190
         const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers);
191
-        if (info && cipher_kt_block_size(info) < 128/8)
191
+        if (info && cipher_kt_insecure(info))
192 192
         {
193 193
             print_cipher(info);
194 194
         }
... ...
@@ -550,6 +550,16 @@ cipher_kt_tag_size(const mbedtls_cipher_info_t *cipher_kt)
550 550
     return 0;
551 551
 }
552 552
 
553
+bool
554
+cipher_kt_insecure(const mbedtls_cipher_info_t *cipher_kt)
555
+{
556
+    return !(cipher_kt_block_size(cipher_kt) >= 128 / 8
557
+#ifdef MBEDTLS_CHACHAPOLY_C
558
+             || cipher_kt->type == MBEDTLS_CIPHER_CHACHA20_POLY1305
559
+#endif
560
+             );
561
+}
562
+
553 563
 int
554 564
 cipher_kt_mode(const mbedtls_cipher_info_t *cipher_kt)
555 565
 {
... ...
@@ -573,7 +583,11 @@ cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
573 573
 bool
574 574
 cipher_kt_mode_aead(const cipher_kt_t *cipher)
575 575
 {
576
-    return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_GCM;
576
+    return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
577
+#ifdef MBEDTLS_CHACHAPOLY_C
578
+                      || cipher_kt_mode(cipher) == MBEDTLS_MODE_CHACHAPOLY
579
+#endif
580
+                      );
577 581
 }
578 582
 
579 583
 
... ...
@@ -245,6 +245,7 @@ const cipher_name_pair cipher_name_translation_table[] = {
245 245
     { "AES-128-GCM", "id-aes128-GCM" },
246 246
     { "AES-192-GCM", "id-aes192-GCM" },
247 247
     { "AES-256-GCM", "id-aes256-GCM" },
248
+    { "CHACHA20-POLY1305", "ChaCha20-Poly1305" },
248 249
 };
249 250
 const size_t cipher_name_translation_table_count =
250 251
     sizeof(cipher_name_translation_table) / sizeof(*cipher_name_translation_table);
... ...
@@ -321,7 +322,7 @@ show_available_ciphers(void)
321 321
     qsort(cipher_list, num_ciphers, sizeof(*cipher_list), cipher_name_cmp);
322 322
 
323 323
     for (i = 0; i < num_ciphers; i++) {
324
-        if (cipher_kt_block_size(cipher_list[i]) >= 128/8)
324
+        if (!cipher_kt_insecure(cipher_list[i]))
325 325
         {
326 326
             print_cipher(cipher_list[i]);
327 327
         }
... ...
@@ -330,7 +331,7 @@ show_available_ciphers(void)
330 330
     printf("\nThe following ciphers have a block size of less than 128 bits, \n"
331 331
            "and are therefore deprecated.  Do not use unless you have to.\n\n");
332 332
     for (i = 0; i < num_ciphers; i++) {
333
-        if (cipher_kt_block_size(cipher_list[i]) < 128/8)
333
+        if (cipher_kt_insecure(cipher_list[i]))
334 334
         {
335 335
             print_cipher(cipher_list[i]);
336 336
         }
... ...
@@ -686,6 +687,16 @@ cipher_kt_tag_size(const EVP_CIPHER *cipher_kt)
686 686
     }
687 687
 }
688 688
 
689
+bool
690
+cipher_kt_insecure(const EVP_CIPHER *cipher)
691
+{
692
+    return !(cipher_kt_block_size(cipher) >= 128 / 8
693
+#ifdef NID_chacha20_poly1305
694
+             || EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305
695
+#endif
696
+            );
697
+}
698
+
689 699
 int
690 700
 cipher_kt_mode(const EVP_CIPHER *cipher_kt)
691 701
 {
... ...
@@ -720,10 +731,22 @@ bool
720 720
 cipher_kt_mode_aead(const cipher_kt_t *cipher)
721 721
 {
722 722
 #ifdef HAVE_AEAD_CIPHER_MODES
723
-    return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM);
724
-#else
725
-    return false;
723
+    if (cipher)
724
+    {
725
+        switch (EVP_CIPHER_nid(cipher))
726
+        {
727
+        case NID_aes_128_gcm:
728
+        case NID_aes_192_gcm:
729
+        case NID_aes_256_gcm:
730
+#ifdef NID_chacha20_poly1305
731
+        case NID_chacha20_poly1305:
726 732
 #endif
733
+            return true;
734
+        }
735
+    }
736
+#endif
737
+
738
+    return false;
727 739
 }
728 740
 
729 741
 /*
... ...
@@ -294,7 +294,7 @@ tls_get_cipher_name_pair(const char *cipher_name, size_t len)
294 294
 static void
295 295
 tls_limit_reneg_bytes(const cipher_kt_t *cipher, int *reneg_bytes)
296 296
 {
297
-    if (cipher && (cipher_kt_block_size(cipher) < 128/8))
297
+    if (cipher && cipher_kt_insecure(cipher))
298 298
     {
299 299
         if (*reneg_bytes == -1) /* Not user-specified */
300 300
         {