diff options
author | lloyd <[email protected]> | 2015-01-08 12:57:15 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2015-01-08 12:57:15 +0000 |
commit | e1d118f4973e2d5f58971acfb8aa28f4fc3085e2 (patch) | |
tree | 27f6b90c8e87ed000ce2c0540e4bcab63891a730 | |
parent | a62473b5f0a893db620d8658d75374a50a67e496 (diff) |
Change TLS session encryption to use AES-256/GCM instead of CBC+HMAC
-rw-r--r-- | doc/manual/tls.rst | 8 | ||||
-rw-r--r-- | doc/relnotes/1_11_13.rst | 28 | ||||
-rw-r--r-- | src/lib/constructs/cryptobox_psk/cryptobox_psk.cpp | 133 | ||||
-rw-r--r-- | src/lib/constructs/cryptobox_psk/cryptobox_psk.h | 47 | ||||
-rw-r--r-- | src/lib/constructs/cryptobox_psk/info.txt | 10 | ||||
-rw-r--r-- | src/lib/tls/info.txt | 2 | ||||
-rw-r--r-- | src/lib/tls/tls_session.cpp | 36 |
7 files changed, 53 insertions, 211 deletions
diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst index 0faf9e4d4..b3ec1c0ea 100644 --- a/doc/manual/tls.rst +++ b/doc/manual/tls.rst @@ -81,6 +81,7 @@ available: .. cpp:class:: TLS::Channel .. cpp:function:: size_t received_data(const byte buf[], size_t buf_size) + .. cpp:function:: size_t received_data(const std::vector<byte>& buf) This function is used to provide data sent by the counterparty (eg data that you read off the socket layer). Depending on the @@ -94,6 +95,8 @@ available: will return 0 instead. .. cpp:function:: void send(const byte buf[], size_t buf_size) + .. cpp:function:: void send(const std::string& str) + .. cpp:function:: void send(const std::vector<byte>& vec) Create one or more new TLS application records containing the provided data and send them. This will eventually result in at @@ -173,7 +176,6 @@ available: Per :rfc:`5705`, *label* should begin with "EXPERIMENTAL" unless the label has been standardized in an RFC. - .. _tls_client: TLS Clients @@ -184,7 +186,7 @@ TLS Clients .. cpp:function:: TLS::Client( \ std::function<void, const byte*, size_t> output_fn, \ std::function<void, const byte*, size_t> data_cb, \ - std::function<TLS::Alert, const byte*, size_t> alert_cb, + std::function<TLS::Alert, const byte*, size_t> alert_cb, \ std::function<bool, const TLS::Session&> handshake_cb, \ TLS::Session_Manager& session_manager, \ Credentials_Manager& credendials_manager, \ @@ -279,7 +281,7 @@ TLS Servers .. cpp:function:: TLS::Server( \ std::function<void, const byte*, size_t> output_fn, \ std::function<void, const byte*, size_t> data_cb, \ - std::function<TLS::Alert, const byte*, size_t> alert_cb, + std::function<TLS::Alert, const byte*, size_t> alert_cb, \ TLS::Session_Manager& session_manager, \ Credentials_Manager& creds, \ const TLS::Policy& policy, \ diff --git a/doc/relnotes/1_11_13.rst b/doc/relnotes/1_11_13.rst index f72c0f56b..b69073859 100644 --- a/doc/relnotes/1_11_13.rst +++ b/doc/relnotes/1_11_13.rst @@ -1,16 +1,32 @@ Version 1.11.13, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* The format of TLS sessions has changed. The PEM formatted version - now uses "TLS SESSION" instead of "SSL SESSION" as the header, - and the version number of the binary format has also changed. +* Add DTLS-SRTP negotiation defined in RFC 5764 * Add SHA-512/256 -* Add DTLS-SRTP negotiation defined in RFC 5764 +* The format of serialized TLS sessions has changed. Additiionally, PEM + formatted sessions now use the label of "TLS SESSION" instead of "SSL SESSION". + +* Serialized TLS sessions are now encrypted using AES-256/GCM instead of a + CBC+HMAC construction. + +* The cryptobox_psk module added in 1.11.4 and previously used for TLS session + encryption has been removed. + +* When sending a TLS heartbeat message, the number of pad bytes to use can now + be specified, making it easier to use for PMTU discovery. + +* If available, zero_mem now uses RtlSecureZeroMemory or memset_s instead of a + byte-at-a-time loop. + +* The functions base64_encode and base64_decode would erroneously + throw an exception if passed a zero-length input. Github issue 37. -* The Python install script added in version 1.11.10 failed to place - the headers into a versioned subdirectory. +* The Python install script added in version 1.11.10 failed to place the + headers into a versioned subdirectory. * Fix the install script when running under Python3. +* Avoid code that triggers iterator debugging asserts under MSVC 2013. Github + pull 36 from Simon Warta. diff --git a/src/lib/constructs/cryptobox_psk/cryptobox_psk.cpp b/src/lib/constructs/cryptobox_psk/cryptobox_psk.cpp deleted file mode 100644 index 8fb3a9aae..000000000 --- a/src/lib/constructs/cryptobox_psk/cryptobox_psk.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* -* Cryptobox Message Routines -* (C) 2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/cryptobox_psk.h> -#include <botan/pipe.h> -#include <botan/lookup.h> -#include <botan/loadstor.h> - -namespace Botan { - -namespace CryptoBox { - -namespace { - -const u32bit CRYPTOBOX_MAGIC = 0x571B0E4F; -const std::string CRYPTOBOX_CIPHER = "AES-256/CBC"; -const std::string CRYPTOBOX_MAC = "HMAC(SHA-256)"; -const std::string CRYPTOBOX_KDF = "KDF2(SHA-256)"; - -const size_t MAGIC_LENGTH = 4; -const size_t KEY_KDF_SALT_LENGTH = 10; -const size_t MAC_KEY_LENGTH = 32; -const size_t CIPHER_KEY_LENGTH = 32; -const size_t CIPHER_IV_LENGTH = 16; -const size_t MAC_OUTPUT_LENGTH = 32; - -} - -std::vector<byte> encrypt(const byte input[], size_t input_len, - const SymmetricKey& master_key, - RandomNumberGenerator& rng) - { - std::unique_ptr<KDF> kdf(get_kdf(CRYPTOBOX_KDF)); - - const secure_vector<byte> cipher_key_salt = - rng.random_vec(KEY_KDF_SALT_LENGTH); - - const secure_vector<byte> mac_key_salt = - rng.random_vec(KEY_KDF_SALT_LENGTH); - - SymmetricKey cipher_key = - kdf->derive_key(CIPHER_KEY_LENGTH, - master_key.bits_of(), - cipher_key_salt); - - SymmetricKey mac_key = - kdf->derive_key(MAC_KEY_LENGTH, - master_key.bits_of(), - mac_key_salt); - - InitializationVector cipher_iv(rng, 16); - - std::unique_ptr<MessageAuthenticationCode> mac(get_mac(CRYPTOBOX_MAC)); - mac->set_key(mac_key); - - Pipe pipe(get_cipher(CRYPTOBOX_CIPHER, cipher_key, cipher_iv, ENCRYPTION)); - pipe.process_msg(input, input_len); - secure_vector<byte> ctext = pipe.read_all(0); - - std::vector<byte> out(MAGIC_LENGTH); - store_be(CRYPTOBOX_MAGIC, &out[0]); - out += cipher_key_salt; - out += mac_key_salt; - out += cipher_iv.bits_of(); - out += ctext; - - mac->update(out); - - out += mac->final(); - return out; - } - -secure_vector<byte> decrypt(const byte input[], size_t input_len, - const SymmetricKey& master_key) - { - const size_t MIN_CTEXT_SIZE = 16; // due to using CBC with padding - - const size_t MIN_POSSIBLE_LENGTH = - MAGIC_LENGTH + - 2 * KEY_KDF_SALT_LENGTH + - CIPHER_IV_LENGTH + - MIN_CTEXT_SIZE + - MAC_OUTPUT_LENGTH; - - if(input_len < MIN_POSSIBLE_LENGTH) - throw Decoding_Error("Encrypted input too short to be valid"); - - if(load_be<u32bit>(input, 0) != CRYPTOBOX_MAGIC) - throw Decoding_Error("Unknown header value in cryptobox"); - - std::unique_ptr<KDF> kdf(get_kdf(CRYPTOBOX_KDF)); - - const byte* cipher_key_salt = &input[MAGIC_LENGTH]; - - const byte* mac_key_salt = &input[MAGIC_LENGTH + KEY_KDF_SALT_LENGTH]; - - SymmetricKey mac_key = kdf->derive_key(MAC_KEY_LENGTH, - master_key.bits_of(), - mac_key_salt, - KEY_KDF_SALT_LENGTH); - - std::unique_ptr<MessageAuthenticationCode> mac(get_mac(CRYPTOBOX_MAC)); - mac->set_key(mac_key); - - mac->update(&input[0], input_len - MAC_OUTPUT_LENGTH); - secure_vector<byte> computed_mac = mac->final(); - - if(!same_mem(&input[input_len - MAC_OUTPUT_LENGTH], &computed_mac[0], computed_mac.size())) - throw Decoding_Error("MAC verification failed"); - - SymmetricKey cipher_key = - kdf->derive_key(CIPHER_KEY_LENGTH, - master_key.bits_of(), - cipher_key_salt, KEY_KDF_SALT_LENGTH); - - InitializationVector cipher_iv(&input[MAGIC_LENGTH+2*KEY_KDF_SALT_LENGTH], - CIPHER_IV_LENGTH); - - const size_t CTEXT_OFFSET = MAGIC_LENGTH + 2 * KEY_KDF_SALT_LENGTH + CIPHER_IV_LENGTH; - - Pipe pipe(get_cipher(CRYPTOBOX_CIPHER, cipher_key, cipher_iv, DECRYPTION)); - pipe.process_msg(&input[CTEXT_OFFSET], - input_len - (MAC_OUTPUT_LENGTH + CTEXT_OFFSET)); - return pipe.read_all(); - } - -} - -} diff --git a/src/lib/constructs/cryptobox_psk/cryptobox_psk.h b/src/lib/constructs/cryptobox_psk/cryptobox_psk.h deleted file mode 100644 index 2f16ee461..000000000 --- a/src/lib/constructs/cryptobox_psk/cryptobox_psk.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* Cryptobox Message Routines -* (C) 2009,2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_CRYPTOBOX_PSK_H__ -#define BOTAN_CRYPTOBOX_PSK_H__ - -#include <string> -#include <botan/rng.h> -#include <botan/symkey.h> - -namespace Botan { - -/** -* This namespace holds various high-level crypto functions -*/ -namespace CryptoBox { - -/** -* Encrypt a message using a shared secret key -* @param input the input data -* @param input_len the length of input in bytes -* @param key the key used to encrypt the message -* @param rng a ref to a random number generator, such as AutoSeeded_RNG -*/ -BOTAN_DLL std::vector<byte> encrypt(const byte input[], size_t input_len, - const SymmetricKey& key, - RandomNumberGenerator& rng); - -/** -* Encrypt a message using a shared secret key -* @param input the input data -* @param input_len the length of input in bytes -* @param key the key used to encrypt the message -* @param rng a ref to a random number generator, such as AutoSeeded_RNG -*/ -BOTAN_DLL secure_vector<byte> decrypt(const byte input[], size_t input_len, - const SymmetricKey& key); - -} - -} - -#endif diff --git a/src/lib/constructs/cryptobox_psk/info.txt b/src/lib/constructs/cryptobox_psk/info.txt deleted file mode 100644 index 03f7525f5..000000000 --- a/src/lib/constructs/cryptobox_psk/info.txt +++ /dev/null @@ -1,10 +0,0 @@ -define CRYPTOBOX_PSK 20131128 - -<requires> -aes -cbc -hmac -kdf2 -rng -sha2_64 -</requires> diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index b3d9066b6..530ee1121 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -68,9 +68,7 @@ tls_version.cpp aead aes asn1 -cbc credentials -cryptobox_psk dh ecdh ecdsa diff --git a/src/lib/tls/tls_session.cpp b/src/lib/tls/tls_session.cpp index 5080d9f79..1891e6e4e 100644 --- a/src/lib/tls/tls_session.cpp +++ b/src/lib/tls/tls_session.cpp @@ -10,7 +10,7 @@ #include <botan/ber_dec.h> #include <botan/asn1_str.h> #include <botan/pem.h> -#include <botan/cryptobox_psk.h> +#include <botan/aead.h> namespace Botan { @@ -151,26 +151,42 @@ std::chrono::seconds Session::session_age() const } std::vector<byte> -Session::encrypt(const SymmetricKey& master_key, - RandomNumberGenerator& rng) const +Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const { - const auto der = this->DER_encode(); + std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", ENCRYPTION)); + const size_t nonce_len = aead->default_nonce_length(); + aead->set_key(key); - return CryptoBox::encrypt(&der[0], der.size(), master_key, rng); + const secure_vector<byte> nonce = rng.random_vec(nonce_len); + + secure_vector<byte> buf = rng.random_vec(nonce_len); + buf += this->DER_encode(); + aead->start(&buf[0], nonce_len); + aead->finish(buf, nonce_len); + return unlock(buf); } -Session Session::decrypt(const byte buf[], size_t buf_len, - const SymmetricKey& master_key) +Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key) { try { - const auto ber = CryptoBox::decrypt(buf, buf_len, master_key); + std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", DECRYPTION)); + const size_t nonce_len = aead->default_nonce_length(); + + if(in_len < nonce_len + aead->tag_size()) + throw Decoding_Error("Encrypted session too short to be valid"); + + aead->set_key(key); + + aead->start(in, nonce_len); + secure_vector<byte> buf(in + nonce_len, in + in_len); + aead->finish(buf, 0); - return Session(&ber[0], ber.size()); + return Session(&buf[0], buf.size()); } catch(std::exception& e) { - throw Decoding_Error("Failed to decrypt encrypted session -" + + throw Decoding_Error("Failed to decrypt serialized TLS session: " + std::string(e.what())); } } |