File 0258-ssl-Fix-Chacha20-IV-length-and-nonce-calculation.patch of Package erlang
From 7f014fd65d13575c352b178894187356b2d7d3b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= <peterdmv@erlang.org>
Date: Tue, 2 Apr 2019 15:50:15 +0200
Subject: [PATCH] ssl: Fix Chacha20 IV length and nonce calculation
This commit fixes the IV length (12 bytes) and the calculation of
the nonce for the Chacha20-Poly1305 ciphers.
Change-Id: I4c9efc0bf012bc287c84c7b62c252ecf49ffe32f
---
lib/ssl/src/ssl_cipher.erl | 5 +++--
lib/ssl/src/ssl_record.erl | 14 ++++++++------
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 97878431a6..850dee7d4f 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -745,8 +745,7 @@ effective_key_bits(Cipher) when Cipher == aes_256_cbc;
256.
iv_size(Cipher) when Cipher == null;
- Cipher == rc4_128;
- Cipher == chacha20_poly1305->
+ Cipher == rc4_128 ->
0;
iv_size(Cipher) when Cipher == aes_128_gcm;
Cipher == aes_256_gcm ->
@@ -751,6 +750,8 @@ iv_size(Cipher) when Cipher == aes_128_gcm;
iv_size(Cipher) when Cipher == aes_128_gcm;
Cipher == aes_256_gcm ->
4;
+iv_size(chacha20_poly1305) ->
+ 12;
iv_size(Cipher) ->
block_size(Cipher).
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 9cc131c3cb..867d2cfc5a 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -378,7 +378,7 @@ decipher_aead(Type, #cipher_state{key = Key} = CipherState, AAD0, CipherFragment
try
Nonce = decrypt_nonce(Type, CipherState, CipherFragment),
{AAD, CipherText, CipherTag} = aead_ciphertext_split(Type, CipherState, CipherFragment, AAD0),
- case ssl_cipher:aead_decrypt(Type, Key, Nonce, CipherText, CipherTag, AAD) of
+ case ssl_cipher:aead_decrypt(Type, Key, Nonce, CipherText, CipherTag, AAD) of
Content when is_binary(Content) ->
Content;
_ ->
@@ -456,7 +456,7 @@ initial_security_params(ConnectionEnd) ->
do_cipher_aead(?CHACHA20_POLY1305 = Type, Fragment, #cipher_state{key=Key} = CipherState, AAD0) ->
AAD = ?end_additional_data(AAD0, erlang:iolist_size(Fragment)),
- Nonce = encrypt_nonce(Type, CipherState),
+ Nonce = chacha_nonce(CipherState),
{Content, CipherTag} = ssl_cipher:aead_encrypt(Type, Key, Nonce, Fragment, AAD),
{<<Content/binary, CipherTag/binary>>, CipherState};
do_cipher_aead(Type, Fragment, #cipher_state{key=Key, nonce = ExplicitNonce} = CipherState, AAD0) ->
@@ -465,14 +465,16 @@ do_cipher_aead(Type, Fragment, #cipher_state{key=Key, tag_len = TagLen, nonce =
{Content, CipherTag} = ssl_cipher:aead_encrypt(Type, Key, Nonce, Fragment, AAD),
{<<ExplicitNonce:64/integer, Content/binary, CipherTag/binary>>, CipherState#cipher_state{nonce = ExplicitNonce + 1}}.
-encrypt_nonce(?CHACHA20_POLY1305, #cipher_state{nonce = Nonce, iv = IV}) ->
- crypto:exor(<<?UINT32(0), Nonce/binary>>, IV);
+
+chacha_nonce(#cipher_state{nonce = Nonce, iv = IV}) ->
+ crypto:exor(<<?UINT32(0), Nonce/binary>>, IV).
+
encrypt_nonce(?AES_GCM, #cipher_state{iv = IV, nonce = ExplicitNonce}) ->
<<Salt:4/bytes, _/binary>> = IV,
<<Salt/binary, ExplicitNonce:64/integer>>.
-decrypt_nonce(?CHACHA20_POLY1305, #cipher_state{nonce = Nonce, iv = IV}, _) ->
- crypto:exor(<<Nonce:96/unsigned-big-integer>>, IV);
+decrypt_nonce(?CHACHA20_POLY1305, CipherState, _) ->
+ chacha_nonce(CipherState);
decrypt_nonce(?AES_GCM, #cipher_state{iv = <<Salt:4/bytes, _/binary>>}, <<ExplicitNonce:8/bytes, _/binary>>) ->
<<Salt/binary, ExplicitNonce/binary>>.
--
2.16.4