diff options
author | Jack Lloyd <[email protected]> | 2016-03-23 17:02:55 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-03-23 17:02:55 -0400 |
commit | 858cf5c82260e45e5bf51ff17b63f493d8295356 (patch) | |
tree | 3186029f089ffdb3e1c9e0ac004018d0953ff5e8 /src/lib/tls | |
parent | 646ddaef38845a7ce33e4dcc7a02500a674c7033 (diff) |
Add IETF standard ChaCha20Poly1305 ciphersuites to TLS
Diffstat (limited to 'src/lib/tls')
-rw-r--r-- | src/lib/tls/tls_record.cpp | 66 | ||||
-rw-r--r-- | src/lib/tls/tls_record.h | 12 | ||||
-rw-r--r-- | src/lib/tls/tls_suite_info.cpp | 28 |
3 files changed, 83 insertions, 23 deletions
diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index bdb37baad..efa6e2d18 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -53,12 +53,16 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, m_aead->set_key(cipher_key + mac_key); BOTAN_ASSERT_EQUAL(iv.length(), nonce_bytes_from_handshake(), "Matching nonce sizes"); - m_nonce = iv.bits_of(); + m_nonce = unlock(iv.bits_of()); BOTAN_ASSERT(nonce_bytes_from_record() == 0 || nonce_bytes_from_record() == 8, "Ciphersuite uses implemented IV length"); - m_nonce.resize(m_nonce.size() + 8); + if(m_nonce.size() != 12) + { + m_nonce.resize(m_nonce.size() + 8); + } + return; } @@ -77,20 +81,45 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, m_mac->set_key(mac_key); } -const secure_vector<byte>& Connection_Cipher_State::aead_nonce(u64bit seq) +std::vector<byte> Connection_Cipher_State::aead_nonce(u64bit seq) { - store_be(seq, &m_nonce[nonce_bytes_from_handshake()]); - return m_nonce; + if(nonce_bytes_from_handshake() == 12) + { + std::vector<byte> nonce(12); + store_be(seq, nonce.data() + 4); + xor_buf(nonce, m_nonce.data(), m_nonce.size()); + return nonce; + } + else + { + std::vector<byte> nonce = m_nonce; + store_be(seq, &nonce[nonce_bytes_from_handshake()]); + return nonce; + } } -const secure_vector<byte>& +std::vector<byte> Connection_Cipher_State::aead_nonce(const byte record[], size_t record_len, u64bit seq) { - if(nonce_bytes_from_record()) + if(nonce_bytes_from_handshake() == 12) + { + /* + Assumes if the suite specifies 12 bytes come from the handshake then + use the XOR nonce construction from draft-ietf-tls-chacha20-poly1305 + */ + + std::vector<byte> nonce(12); + store_be(seq, nonce.data() + 4); + xor_buf(nonce, m_nonce.data(), m_nonce.size()); + return nonce; + } + else if(nonce_bytes_from_record() > 0) { if(record_len < nonce_bytes_from_record()) throw Decoding_Error("Invalid AEAD packet too short to be valid"); - copy_mem(&m_nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record()); + std::vector<byte> nonce = m_nonce; + copy_mem(&nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record()); + return nonce; } else { @@ -98,18 +127,21 @@ Connection_Cipher_State::aead_nonce(const byte record[], size_t record_len, u64b nonce_len == 0 is assumed to mean no nonce in the message but instead the AEAD uses the seq number in network order. */ - store_be(seq, &m_nonce[nonce_bytes_from_handshake()]); + std::vector<byte> nonce = m_nonce; + store_be(seq, &nonce[nonce_bytes_from_handshake()]); + return nonce; } - return m_nonce; } -const secure_vector<byte>& +std::vector<byte> Connection_Cipher_State::format_ad(u64bit msg_sequence, byte msg_type, Protocol_Version version, u16bit msg_length) { - m_ad.clear(); + std::vector<byte> m_ad; + m_ad.reserve(13); + for(size_t i = 0; i != 8; ++i) m_ad.push_back(get_byte(i, msg_sequence)); m_ad.push_back(msg_type); @@ -156,7 +188,7 @@ void write_record(secure_vector<byte>& output, { const size_t ctext_size = aead->output_length(msg_length); - const secure_vector<byte>& nonce = cs->aead_nonce(seq); + const std::vector<byte> nonce = cs->aead_nonce(seq); // wrong if start returns something const size_t rec_size = ctext_size + cs->nonce_bytes_from_record(); @@ -167,7 +199,11 @@ void write_record(secure_vector<byte>& output, aead->set_ad(cs->format_ad(seq, msg_type, version, msg_length)); - output += std::make_pair(&nonce[cs->nonce_bytes_from_handshake()], cs->nonce_bytes_from_record()); + if(cs->nonce_bytes_from_record() > 0) + { + output += std::make_pair(&nonce[cs->nonce_bytes_from_handshake()], cs->nonce_bytes_from_record()); + } + BOTAN_ASSERT(aead->start(nonce).empty(), "AEAD doesn't return anything from start"); const size_t offset = output.size(); @@ -350,7 +386,7 @@ void decrypt_record(secure_vector<byte>& output, { if(AEAD_Mode* aead = cs.aead()) { - const secure_vector<byte>& nonce = cs.aead_nonce(record_contents, record_len, record_sequence); + const std::vector<byte> nonce = cs.aead_nonce(record_contents, record_len, record_sequence); const byte* msg = &record_contents[cs.nonce_bytes_from_record()]; const size_t msg_length = record_len - cs.nonce_bytes_from_record(); diff --git a/src/lib/tls/tls_record.h b/src/lib/tls/tls_record.h index d7aa82e71..e3b0b9b58 100644 --- a/src/lib/tls/tls_record.h +++ b/src/lib/tls/tls_record.h @@ -42,13 +42,13 @@ class Connection_Cipher_State AEAD_Mode* aead() { return m_aead.get(); } - const secure_vector<byte>& aead_nonce(u64bit seq); + std::vector<byte> aead_nonce(u64bit seq); - const secure_vector<byte>& aead_nonce(const byte record[], size_t record_len, u64bit seq); + std::vector<byte> aead_nonce(const byte record[], size_t record_len, u64bit seq); - const secure_vector<byte>& format_ad(u64bit seq, byte type, - Protocol_Version version, - u16bit ptext_length); + std::vector<byte> format_ad(u64bit seq, byte type, + Protocol_Version version, + u16bit ptext_length); BlockCipher* block_cipher() { return m_block_cipher.get(); } @@ -82,7 +82,7 @@ class Connection_Cipher_State std::unique_ptr<MessageAuthenticationCode> m_mac; std::unique_ptr<AEAD_Mode> m_aead; - secure_vector<byte> m_nonce, m_ad; + std::vector<byte> m_nonce; size_t m_block_size = 0; size_t m_nonce_bytes_from_handshake; diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp index 0bebecb82..84e2a30a8 100644 --- a/src/lib/tls/tls_suite_info.cpp +++ b/src/lib/tls/tls_suite_info.cpp @@ -2,8 +2,8 @@ * TLS cipher suite information * * This file was automatically generated from the IANA assignments -* (tls-parameters.txt hash 6a934405ed41aa4d6113dad17f815867741430ac) -* by ./src/scripts/tls_suite_info.py on 2016-01-06 +* (tls-parameters.txt hash fe280cb8b13bfdd306a975ab39fda238f77ae3bc) +* by ./src/scripts/tls_suite_info.py on 2016-03-23 * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -159,6 +159,12 @@ std::vector<u16bit> Ciphersuite::all_known_ciphersuite_ids() 0xCC13, 0xCC14, 0xCC15, + 0xCCA8, + 0xCCA9, + 0xCCAA, + 0xCCAB, + 0xCCAC, + 0xCCAD, 0xFFF0, 0xFFF1, 0xFFF2, @@ -604,6 +610,24 @@ Ciphersuite Ciphersuite::by_id(u16bit suite) case 0xCC15: // DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 return Ciphersuite(0xCC15, "RSA", "DH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); + case 0xCCA8: // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCA8, "RSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + + case 0xCCA9: // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCA9, "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + + case 0xCCAA: // DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCAA, "RSA", "DH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + + case 0xCCAB: // PSK_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCAB, "", "PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + + case 0xCCAC: // ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCAC, "", "ECDHE_PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + + case 0xCCAD: // DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 + return Ciphersuite(0xCCAD, "", "DHE_PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); + case 0xFFF0: // ECDHE_RSA_WITH_AES_128_OCB_SHA256 return Ciphersuite(0xFFF0, "RSA", "ECDH", "AES-128/OCB(12)", 16, 4, 0, "AEAD", 0, "SHA-256"); |