From 74cf1686b727d9b41781df66f3f74d63b9c5cfe2 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 16 Nov 2016 12:05:34 -0500 Subject: Add CECPQ1 TLS ciphersuites Tested against BoringSSL (as client + server) and google.com (as client). Fix a stupid crashing bug in NewHope's BoringSSL mode. Remove unneeded error return from curve25519_donna - always returned 0. Default policy prefers ChaChaPoly1305 over GCM and CECPQ1 over ECDH/DH, which means the default no-extra-configuration ciphersuite (for Botan client speaking to Botan server) is a ciphersuite which is both implemented in constant time on all platforms and (hopefully) provides post quantum security. Good Things. --- src/cli/speed.cpp | 2 +- src/lib/pubkey/cecpq1/cecpq1.cpp | 50 ++++++++++++++++++++++++++++++++ src/lib/pubkey/cecpq1/cecpq1.h | 36 +++++++++++++++++++++++ src/lib/pubkey/cecpq1/info.txt | 7 +++++ src/lib/pubkey/curve25519/curve25519.cpp | 25 ++++++++-------- src/lib/pubkey/curve25519/curve25519.h | 14 +++++++-- src/lib/pubkey/curve25519/donna.cpp | 3 +- src/lib/pubkey/newhope/newhope.cpp | 4 +-- src/lib/pubkey/newhope/newhope.h | 31 +++++++++++++++----- src/lib/tls/msg_client_kex.cpp | 49 ++++++++++++++++++++++++------- src/lib/tls/msg_server_kex.cpp | 22 +++++++++++++- src/lib/tls/tls_ciphersuite.cpp | 6 ++++ src/lib/tls/tls_messages.h | 18 ++++++++++++ src/lib/tls/tls_policy.cpp | 3 +- src/lib/tls/tls_suite_info.cpp | 8 +++-- src/scripts/tls_suite_info.py | 7 +++++ src/tests/test_newhope.cpp | 4 +-- src/tests/unit_tls.cpp | 4 +++ 18 files changed, 249 insertions(+), 44 deletions(-) create mode 100644 src/lib/pubkey/cecpq1/cecpq1.cpp create mode 100644 src/lib/pubkey/cecpq1/cecpq1.h create mode 100644 src/lib/pubkey/cecpq1/info.txt (limited to 'src') diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index 47cdc03c0..6fac9411c 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -1246,7 +1246,7 @@ class Speed final : public Command while(sharedb_timer.under(msec)) { - std::vector send_a(NEWHOPE_SENDABYTES), send_b(NEWHOPE_SENDBBYTES); + std::vector send_a(Botan::NEWHOPE_SENDABYTES), send_b(Botan::NEWHOPE_SENDBBYTES); std::vector shared_a(32), shared_b(32); Botan::newhope_poly sk_a; diff --git a/src/lib/pubkey/cecpq1/cecpq1.cpp b/src/lib/pubkey/cecpq1/cecpq1.cpp new file mode 100644 index 000000000..d5b6ae702 --- /dev/null +++ b/src/lib/pubkey/cecpq1/cecpq1.cpp @@ -0,0 +1,50 @@ +/* +* CECPQ1 (x25519 + NewHope) +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +void CECPQ1_offer(uint8_t send[CECPQ1_OFFER_BYTES], + CECPQ1_key* offer_key_output, + RandomNumberGenerator& rng) + { + offer_key_output->m_x25519 = rng.random_vec(32); + curve25519_basepoint(send, offer_key_output->m_x25519.data()); + + newhope_keygen(send + 32, &offer_key_output->m_newhope, + rng, Newhope_Mode::BoringSSL); + } + +void CECPQ1_accept(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES], + uint8_t send[CECPQ1_ACCEPT_BYTES], + const uint8_t received[CECPQ1_OFFER_BYTES], + RandomNumberGenerator& rng) + { + secure_vector x25519_key = rng.random_vec(32); + + curve25519_basepoint(send, x25519_key.data()); + + curve25519_donna(shared_key, x25519_key.data(), received); + + newhope_sharedb(shared_key + 32, send + 32, received + 32, + rng, Newhope_Mode::BoringSSL); + } + +void CECPQ1_finish(uint8_t shared_key[CECPQ1_SHARED_KEY_BYTES], + const CECPQ1_key& offer_key, + const uint8_t received[CECPQ1_ACCEPT_BYTES]) + { + curve25519_donna(shared_key, offer_key.m_x25519.data(), received); + + newhope_shareda(shared_key + 32, &offer_key.m_newhope, received + 32, + Newhope_Mode::BoringSSL); + } + +} diff --git a/src/lib/pubkey/cecpq1/cecpq1.h b/src/lib/pubkey/cecpq1/cecpq1.h new file mode 100644 index 000000000..0bda0dd02 --- /dev/null +++ b/src/lib/pubkey/cecpq1/cecpq1.h @@ -0,0 +1,36 @@ +/* +* CECPQ1 (x25519 + NewHope) +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CECPQ1_H__ +#define BOTAN_CECPQ1_H__ + +#include +#include + +namespace Botan { + +struct CECPQ1_key { + secure_vector m_x25519; + newhope_poly m_newhope; +}; + +void BOTAN_DLL CECPQ1_offer(uint8_t* offer_message, + CECPQ1_key* offer_key_output, + RandomNumberGenerator& rng); + +void BOTAN_DLL CECPQ1_accept(uint8_t* shared_key, + uint8_t* accept_message, + const uint8_t* offer_message, + RandomNumberGenerator& rng); + +void BOTAN_DLL CECPQ1_finish(uint8_t* shared_key, + const CECPQ1_key& offer_key, + const uint8_t* accept_message); + +} + +#endif diff --git a/src/lib/pubkey/cecpq1/info.txt b/src/lib/pubkey/cecpq1/info.txt new file mode 100644 index 000000000..614ba3962 --- /dev/null +++ b/src/lib/pubkey/cecpq1/info.txt @@ -0,0 +1,7 @@ +define CECPQ1 20161116 + + +newhope +curve25519 + + diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp index 216d02600..dd97e1f1d 100644 --- a/src/lib/pubkey/curve25519/curve25519.cpp +++ b/src/lib/pubkey/curve25519/curve25519.cpp @@ -12,6 +12,12 @@ namespace Botan { +void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32]) + { + const byte basepoint[32] = { 9 }; + curve25519_donna(mypublic, secret, basepoint); + } + namespace { void size_check(size_t size, const char* thing) @@ -24,17 +30,7 @@ secure_vector curve25519(const secure_vector& secret, const byte pubval[32]) { secure_vector out(32); - const int rc = curve25519_donna(out.data(), secret.data(), pubval); - BOTAN_ASSERT_EQUAL(rc, 0, "Return value of curve25519_donna is ok"); - return out; - } - -std::vector curve25519_basepoint(const secure_vector& secret) - { - const byte basepoint[32] = { 9 }; - std::vector out(32); - const int rc = curve25519_donna(out.data(), secret.data(), basepoint); - BOTAN_ASSERT_EQUAL(rc, 0, "Return value of curve25519_donna is ok"); + curve25519_donna(out.data(), secret.data(), pubval); return out; } @@ -74,7 +70,8 @@ std::vector Curve25519_PublicKey::x509_subject_public_key() const Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng) { m_private = rng.random_vec(32); - m_public = curve25519_basepoint(m_private); + m_public.resize(32); + curve25519_basepoint(m_public.data(), m_private.data()); } Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&, @@ -103,7 +100,9 @@ secure_vector Curve25519_PrivateKey::pkcs8_private_key() const bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const { - return curve25519_basepoint(m_private) == m_public; + std::vector public_point(32); + curve25519_basepoint(public_point.data(), m_private.data()); + return public_point == m_public; } secure_vector Curve25519_PrivateKey::agree(const byte w[], size_t w_len) const diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index 938bc42d4..40d9d81da 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -103,9 +103,17 @@ class BOTAN_DLL Curve25519_PrivateKey : public Curve25519_PublicKey, * The types above are just wrappers for curve25519_donna, plus defining * encodings for public and private keys. */ -int BOTAN_DLL curve25519_donna(uint8_t mypublic[32], - const uint8_t secret[32], - const uint8_t basepoint[32]); +void BOTAN_DLL curve25519_donna(uint8_t mypublic[32], + const uint8_t secret[32], + const uint8_t basepoint[32]); + +/** +* Exponentiate by the x25519 base point +* @param mypublic output value +* @param secret random scalar +*/ +void BOTAN_DLL curve25519_basepoint(uint8_t mypublic[32], + const uint8_t secret[32]); } diff --git a/src/lib/pubkey/curve25519/donna.cpp b/src/lib/pubkey/curve25519/donna.cpp index 86b92b0bf..22400015f 100644 --- a/src/lib/pubkey/curve25519/donna.cpp +++ b/src/lib/pubkey/curve25519/donna.cpp @@ -433,7 +433,7 @@ crecip(felem out, const felem z) { /* 2^255 - 21 */ fmul(out, t0, a); } -int +void curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { CT::poison(secret, 32); @@ -457,7 +457,6 @@ curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { CT::unpoison(secret, 32); CT::unpoison(basepoint, 32); CT::unpoison(mypublic, 32); - return 0; } } diff --git a/src/lib/pubkey/newhope/newhope.cpp b/src/lib/pubkey/newhope/newhope.cpp index 356fd416e..77194207e 100644 --- a/src/lib/pubkey/newhope/newhope.cpp +++ b/src/lib/pubkey/newhope/newhope.cpp @@ -666,13 +666,13 @@ void gen_a(poly *a, const uint8_t *seed, Newhope_Mode mode) if(mode == Newhope_Mode::BoringSSL) { - xof = StreamCipher::create("CTR(AES-128)"); + xof = StreamCipher::create_or_throw("CTR-BE(AES-128)"); xof->set_key(seed, 16); xof->set_iv(seed + 16, 16); } else { - xof = StreamCipher::create("SHAKE-128"); + xof = StreamCipher::create_or_throw("SHAKE-128"); xof->set_key(seed, NEWHOPE_SEED_BYTES); } diff --git a/src/lib/pubkey/newhope/newhope.h b/src/lib/pubkey/newhope/newhope.h index 667f1c4cf..df18bc586 100644 --- a/src/lib/pubkey/newhope/newhope.h +++ b/src/lib/pubkey/newhope/newhope.h @@ -21,36 +21,53 @@ namespace Botan { * Currently pubkey.h does not support a 2-phase KEM scheme of * the sort NEWHOPE exports. */ -#define NEWHOPE_SENDABYTES 1824 -#define NEWHOPE_SENDBBYTES 2048 -typedef struct { - uint16_t coeffs[1024]; -} newhope_poly; +// TODO: change to just a secure_vector +class newhope_poly + { + public: + uint16_t coeffs[1024]; + ~newhope_poly() { secure_scrub_memory(coeffs, sizeof(coeffs)); } + }; + +enum Newhope_Params { + NEWHOPE_SENDABYTES = 1824, + NEWHOPE_SENDBBYTES = 2048, + + NEWHOPE_OFFER_BYTES = 1824, + NEWHOPE_ACCEPT_BYTES = 2048, + NEWHOPE_SHARED_KEY_BYTES = 32, + + CECPQ1_OFFER_BYTES = NEWHOPE_OFFER_BYTES + 32, + CECPQ1_ACCEPT_BYTES = NEWHOPE_ACCEPT_BYTES + 32, + CECPQ1_SHARED_KEY_BYTES = NEWHOPE_SHARED_KEY_BYTES + 32 +}; /** * This chooses the XOF + hash for NewHope - * The official NewHope specification and reference implementation use * SHA-3 and SHAKE-128. BoringSSL instead uses SHA-256 and AES-128 in -* CTR mode. +* CTR mode. CECPQ1 (x25519+NewHope) always uses BoringSSL's mode */ enum class Newhope_Mode { SHA3, BoringSSL }; +// offer void BOTAN_DLL newhope_keygen(uint8_t *send, newhope_poly *sk, RandomNumberGenerator& rng, Newhope_Mode = Newhope_Mode::SHA3); +// accept void BOTAN_DLL newhope_sharedb(uint8_t *sharedkey, uint8_t *send, const uint8_t *received, RandomNumberGenerator& rng, Newhope_Mode mode = Newhope_Mode::SHA3); +// finish void BOTAN_DLL newhope_shareda(uint8_t *sharedkey, const newhope_poly *ska, const uint8_t *received, diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index 6dc8295a6..05926ac2d 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -1,6 +1,6 @@ /* * Client Key Exchange Message -* (C) 2004-2010 Jack Lloyd +* (C) 2004-2010,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -24,6 +24,10 @@ #include #endif +#if defined(BOTAN_HAS_CECPQ1) + #include +#endif + #if defined(BOTAN_HAS_SRP6) #include #endif @@ -55,9 +59,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, identity_hint = reader.get_string(2, 0, 65535); } - const std::string psk_identity = creds.psk_identity("tls-client", - hostname, - identity_hint); + const std::string psk_identity = + creds.psk_identity("tls-client", hostname, identity_hint); append_tls_length_value(m_key_material, psk_identity, 2); @@ -78,9 +81,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, { std::string identity_hint = reader.get_string(2, 0, 65535); - const std::string psk_identity = creds.psk_identity("tls-client", - hostname, - identity_hint); + const std::string psk_identity = + creds.psk_identity("tls-client", hostname, identity_hint); append_tls_length_value(m_key_material, psk_identity, 2); @@ -154,7 +156,6 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, } const std::vector ecdh_key = reader.get_range(1, 1, 255); - std::vector our_ecdh_public; secure_vector ecdh_secret; @@ -229,10 +230,25 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, m_pre_master = srp_vals.second.bits_of(); } #endif + +#if defined(BOTAN_HAS_CECPQ1) + else if(kex_algo == "CECPQ1") + { + const std::vector cecpq1_offer = reader.get_range(2, 1, 65535); + + if(cecpq1_offer.size() != CECPQ1_OFFER_BYTES) + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid CECPQ1 key size"); + + std::vector newhope_accept(CECPQ1_ACCEPT_BYTES); + secure_vector shared_secret(CECPQ1_SHARED_KEY_BYTES); + CECPQ1_accept(shared_secret.data(), newhope_accept.data(), cecpq1_offer.data(), rng); + append_tls_length_value(m_key_material, newhope_accept, 2); + m_pre_master = shared_secret; + } +#endif else { - throw Internal_Error("Client_Key_Exchange: Unknown kex " + - kex_algo); + throw Internal_Error("Client_Key_Exchange: Unknown kex " + kex_algo); } reader.assert_done(); @@ -358,6 +374,19 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector& contents, m_pre_master = srp.step2(BigInt::decode(reader.get_range(2, 0, 65535))).bits_of(); } +#endif +#if defined(BOTAN_HAS_CECPQ1) + else if(kex_algo == "CECPQ1") + { + const CECPQ1_key& cecpq1_offer = state.server_kex()->cecpq1_key(); + + const std::vector cecpq1_accept = reader.get_range(2, 0, 65535); + if(cecpq1_accept.size() != CECPQ1_ACCEPT_BYTES) + throw Decoding_Error("Invalid size for CECPQ1 accept message"); + + m_pre_master.resize(CECPQ1_SHARED_KEY_BYTES); + CECPQ1_finish(m_pre_master.data(), cecpq1_offer, cecpq1_accept.data()); + } #endif else if(kex_algo == "DH" || kex_algo == "DHE_PSK" || kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 4515ea450..521ef4e20 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -1,6 +1,6 @@ /* * Server Key Exchange Message -* (C) 2004-2010,2012,2015 Jack Lloyd +* (C) 2004-2010,2012,2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -21,6 +21,10 @@ #include #endif +#if defined(BOTAN_HAS_CECPQ1) + #include +#endif + #if defined(BOTAN_HAS_SRP6) #include #endif @@ -138,9 +142,20 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, salt, 1); append_tls_length_value(m_params, BigInt::encode(B), 2); } +#endif +#if defined(BOTAN_HAS_CECPQ1) + else if(kex_algo == "CECPQ1") + { + std::vector cecpq1_offer(CECPQ1_OFFER_BYTES); + m_cecpq1_key.reset(new CECPQ1_key); + CECPQ1_offer(cecpq1_offer.data(), m_cecpq1_key.get(), rng); + append_tls_length_value(m_params, cecpq1_offer, 2); + } #endif else if(kex_algo != "PSK") + { throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); + } if(state.ciphersuite().sig_algo() != "") { @@ -205,6 +220,11 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector& buf, reader.get_range(1, 1, 255); reader.get_range(2, 1, 65535); } + else if(kex_algo == "CECPQ1") + { + // u16 blob + reader.get_range(2, 1, 65535); + } else if(kex_algo != "PSK") throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo); diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index aa00334c5..3c29c3c2b 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -141,6 +141,12 @@ bool Ciphersuite::is_usable() const { #if !defined(BOTAN_HAS_DIFFIE_HELLMAN) return false; +#endif + } + else if(kex_algo() == "CECPQ1") + { +#if !defined(BOTAN_HAS_CECPQ1) + return false; #endif } diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 1e012a899..5e6962329 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -29,6 +29,10 @@ class Credentials_Manager; class SRP6_Server_Session; #endif +#if defined(BOTAN_HAS_CECPQ1) +class CECPQ1_key; +#endif + namespace TLS { class Session; @@ -566,6 +570,15 @@ class Server_Key_Exchange final : public Handshake_Message } #endif +#if defined(BOTAN_HAS_CECPQ1) + // Only valid for CECPQ1 negotiation + const CECPQ1_key& cecpq1_key() const + { + BOTAN_ASSERT_NONNULL(m_cecpq1_key); + return *m_cecpq1_key; + } +#endif + Server_Key_Exchange(Handshake_IO& io, Handshake_State& state, const Policy& policy, @@ -585,6 +598,11 @@ class Server_Key_Exchange final : public Handshake_Message #if defined(BOTAN_HAS_SRP6) std::unique_ptr m_srp_params; #endif + +#if defined(BOTAN_HAS_CECPQ1) + std::unique_ptr m_cecpq1_key; +#endif + std::unique_ptr m_kex_key; std::vector m_params; diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index c7c285716..1bb0951bb 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -21,9 +21,9 @@ std::vector Policy::allowed_ciphers() const return { //"AES-256/OCB(12)", //"AES-128/OCB(12)", + "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM", - "ChaCha20Poly1305", "AES-256/CCM", "AES-128/CCM", //"AES-256/CCM(8)", @@ -71,6 +71,7 @@ std::vector Policy::allowed_key_exchange_methods() const //"ECDHE_PSK", //"DHE_PSK", //"PSK", + "CECPQ1", "ECDH", "DH", //"RSA", diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp index 7a2c62d56..cc89934e0 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 9546b3c8be1a1202e1d4a07c2a9d7d6394ae4a21) -* by ./src/scripts/tls_suite_info.py on 2016-08-16 +* (tls-parameters.txt hash 67a567fcf1ac67cb8cfc4af96c20c3efb05c1fc1) +* by ./src/scripts/tls_suite_info.py on 2016-11-16 * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -81,6 +81,10 @@ const std::vector& Ciphersuite::all_known_ciphersuites() Ciphersuite(0x00C3, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", "DSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), Ciphersuite(0x00C4, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", "RSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), Ciphersuite(0x00C5, "DH_anon_WITH_CAMELLIA_256_CBC_SHA256", "", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), + Ciphersuite(0x16B7, "CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "CECPQ1", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), + Ciphersuite(0x16B8, "CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDSA", "CECPQ1", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), + Ciphersuite(0x16B9, "CECPQ1_RSA_WITH_AES_256_GCM_SHA384", "RSA", "CECPQ1", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), + Ciphersuite(0x16BA, "CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384", "ECDSA", "CECPQ1", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), Ciphersuite(0xC008, "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20, ""), Ciphersuite(0xC009, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), Ciphersuite(0xC00A, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), diff --git a/src/scripts/tls_suite_info.py b/src/scripts/tls_suite_info.py index 1d059b3f9..955859d9f 100755 --- a/src/scripts/tls_suite_info.py +++ b/src/scripts/tls_suite_info.py @@ -87,6 +87,7 @@ def to_ciphersuite_info(code, name): 'DHE_PSK': 'DHE_PSK', 'PSK_DHE': 'DHE_PSK', 'ECDHE_PSK': 'ECDHE_PSK', + 'CECPQ1': 'CECPQ1', } mac_keylen = { @@ -236,6 +237,12 @@ def main(args = None): define_custom_ciphersuite('ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', 'CC14') define_custom_ciphersuite('DHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'CC15') + # CECPQ1 + define_custom_ciphersuite('CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256', '16B7') + define_custom_ciphersuite('CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256', '16B8') + define_custom_ciphersuite('CECPQ1_RSA_WITH_AES_256_GCM_SHA384', '16B9') + define_custom_ciphersuite('CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384', '16BA') + # Expermental things if options.with_ocb: define_custom_ciphersuite('DHE_RSA_WITH_AES_128_OCB_SHA256', 'FFC0') diff --git a/src/tests/test_newhope.cpp b/src/tests/test_newhope.cpp index 894896777..95641bcaa 100644 --- a/src/tests/test_newhope.cpp +++ b/src/tests/test_newhope.cpp @@ -104,7 +104,7 @@ class NEWHOPE_Tests : public Text_Based_Test Botan::SHA_3_256 sha3; - std::vector send_a(NEWHOPE_SENDABYTES); + std::vector send_a(Botan::NEWHOPE_SENDABYTES); Botan::newhope_poly a_sk; Botan::newhope_keygen(send_a.data(), &a_sk, drbg_a); @@ -114,7 +114,7 @@ class NEWHOPE_Tests : public Text_Based_Test result.test_eq("Hash Output A", h_send_a, h_output_a); std::vector sharedkey_b(32); - std::vector send_b(NEWHOPE_SENDBBYTES); + std::vector send_b(Botan::NEWHOPE_SENDBBYTES); Botan::newhope_sharedb(sharedkey_b.data(), send_b.data(), send_a.data(), drbg_b); result.test_eq("Key B", sharedkey_b, shared_key); diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index 4ebc54252..e80fe5c63 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -978,6 +978,10 @@ class TLS_Unit_Tests : public Test test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", { { "signature_methods", "RSA" } }); +#if defined(BOTAN_HAS_CECPQ1) + test_modern_versions(results, *client_ses, *server_ses, *creds, "CECPQ1", "AES-256/GCM", "AEAD"); +#endif + test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", { { "use_ecc_point_compression", "true" } }); test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", -- cgit v1.2.3