aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-01-08 12:57:15 +0000
committerlloyd <[email protected]>2015-01-08 12:57:15 +0000
commite1d118f4973e2d5f58971acfb8aa28f4fc3085e2 (patch)
tree27f6b90c8e87ed000ce2c0540e4bcab63891a730
parenta62473b5f0a893db620d8658d75374a50a67e496 (diff)
Change TLS session encryption to use AES-256/GCM instead of CBC+HMAC
-rw-r--r--doc/manual/tls.rst8
-rw-r--r--doc/relnotes/1_11_13.rst28
-rw-r--r--src/lib/constructs/cryptobox_psk/cryptobox_psk.cpp133
-rw-r--r--src/lib/constructs/cryptobox_psk/cryptobox_psk.h47
-rw-r--r--src/lib/constructs/cryptobox_psk/info.txt10
-rw-r--r--src/lib/tls/info.txt2
-rw-r--r--src/lib/tls/tls_session.cpp36
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()));
}
}