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>
... | ... |
@@ -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 |
{ |