diff options
author | DexesTTP <dexes.ttp@gmail.com> | 2021-05-17 22:34:03 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-19 09:18:45 +0200 |
commit | 6d190b299e1f80387a117104841e9382a9814bdc (patch) | |
tree | 166ce8e002eab90df80f9fa7d84c42b9254f0744 /Userland | |
parent | 17a1f51579b07837ba8ccc43cc9672cbab271f09 (diff) | |
download | serenity-6d190b299e1f80387a117104841e9382a9814bdc.zip |
LibTLS: Define cipher suite parameters and components in a macro
Instead of sprinkling the definition of the ciper suites all over the
TLS implementation, let's regroup it all once and for all in a single
place, and then add our new implementations there.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibTLS/CipherSuite.h | 25 | ||||
-rw-r--r-- | Userland/Libraries/LibTLS/TLSv12.h | 115 |
2 files changed, 84 insertions, 56 deletions
diff --git a/Userland/Libraries/LibTLS/CipherSuite.h b/Userland/Libraries/LibTLS/CipherSuite.h index 8f6638ca06..7fadbf839a 100644 --- a/Userland/Libraries/LibTLS/CipherSuite.h +++ b/Userland/Libraries/LibTLS/CipherSuite.h @@ -42,6 +42,31 @@ enum class SignatureAlgorithm : u8 { ECDSA = 3, }; +enum class CipherAlgorithm { + AES_128_CBC, + AES_128_GCM, + AES_128_CCM, + AES_128_CCM_8, + AES_256_CBC, + AES_256_GCM, +}; + +constexpr size_t cipher_key_size(CipherAlgorithm algorithm) +{ + switch (algorithm) { + case CipherAlgorithm::AES_128_CBC: + case CipherAlgorithm::AES_128_GCM: + case CipherAlgorithm::AES_128_CCM: + case CipherAlgorithm::AES_128_CCM_8: + return 128; + case CipherAlgorithm::AES_256_CBC: + case CipherAlgorithm::AES_256_GCM: + return 256; + default: + return 128; + } +} + struct SignatureAndHashAlgorithm { HashAlgorithm hash; SignatureAlgorithm signature; diff --git a/Userland/Libraries/LibTLS/TLSv12.h b/Userland/Libraries/LibTLS/TLSv12.h index 46a6383074..16ff12f8d9 100644 --- a/Userland/Libraries/LibTLS/TLSv12.h +++ b/Userland/Libraries/LibTLS/TLSv12.h @@ -163,18 +163,39 @@ enum ClientVerificationStaus { VerificationNeeded, }; +// Note for the 16 iv length instead of 8: +// 4 bytes of fixed IV, 8 random (nonce) bytes, 4 bytes for counter +// GCM specifically asks us to transmit only the nonce, the counter is zero +// and the fixed IV is derived from the premaster key. +#define ENUMERATE_CIPHERS(C) \ + C(false, CipherSuite::AES_128_GCM_SHA256, SignatureAlgorithm::Anonymous, CipherAlgorithm::AES_128_GCM, Crypto::Hash::SHA256, 8, true) \ + C(false, CipherSuite::AES_256_GCM_SHA384, SignatureAlgorithm::Anonymous, CipherAlgorithm::AES_256_GCM, Crypto::Hash::SHA384, 8, true) \ + C(false, CipherSuite::AES_128_CCM_SHA256, SignatureAlgorithm::Anonymous, CipherAlgorithm::AES_128_CCM, Crypto::Hash::SHA256, 16, false) \ + C(false, CipherSuite::AES_128_CCM_8_SHA256, SignatureAlgorithm::Anonymous, CipherAlgorithm::AES_128_CCM_8, Crypto::Hash::SHA256, 16, false) \ + C(true, CipherSuite::RSA_WITH_AES_128_CBC_SHA, SignatureAlgorithm::RSA, CipherAlgorithm::AES_128_CBC, Crypto::Hash::SHA1, 16, false) \ + C(true, CipherSuite::RSA_WITH_AES_256_CBC_SHA, SignatureAlgorithm::RSA, CipherAlgorithm::AES_256_CBC, Crypto::Hash::SHA1, 16, false) \ + C(true, CipherSuite::RSA_WITH_AES_128_CBC_SHA256, SignatureAlgorithm::RSA, CipherAlgorithm::AES_128_CBC, Crypto::Hash::SHA256, 16, false) \ + C(true, CipherSuite::RSA_WITH_AES_256_CBC_SHA256, SignatureAlgorithm::RSA, CipherAlgorithm::AES_256_CBC, Crypto::Hash::SHA256, 16, false) \ + C(true, CipherSuite::RSA_WITH_AES_128_GCM_SHA256, SignatureAlgorithm::RSA, CipherAlgorithm::AES_128_GCM, Crypto::Hash::SHA256, 8, true) \ + C(false, CipherSuite::RSA_WITH_AES_256_GCM_SHA384, SignatureAlgorithm::RSA, CipherAlgorithm::AES_256_GCM, Crypto::Hash::SHA384, 8, true) + struct Options { + static Vector<CipherSuite> default_usable_cipher_suites() + { + Vector<CipherSuite> cipher_suites; +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + if constexpr (is_supported) \ + cipher_suites.empend(suite); + ENUMERATE_CIPHERS(C) +#undef C + return cipher_suites; + } + Vector<CipherSuite> usable_cipher_suites = default_usable_cipher_suites(); + #define OPTION_WITH_DEFAULTS(typ, name, ...) \ static typ default_##name() { return typ { __VA_ARGS__ }; } \ typ name = default_##name(); - OPTION_WITH_DEFAULTS(Vector<CipherSuite>, usable_cipher_suites, - CipherSuite::RSA_WITH_AES_128_CBC_SHA256, - CipherSuite::RSA_WITH_AES_256_CBC_SHA256, - CipherSuite::RSA_WITH_AES_128_CBC_SHA, - CipherSuite::RSA_WITH_AES_256_CBC_SHA, - CipherSuite::RSA_WITH_AES_128_GCM_SHA256) - OPTION_WITH_DEFAULTS(Version, version, Version::V12) OPTION_WITH_DEFAULTS(Vector<SignatureAndHashAlgorithm>, supported_signature_algorithms, { HashAlgorithm::SHA512, SignatureAlgorithm::RSA }, @@ -297,11 +318,15 @@ public: bool supports_cipher(CipherSuite suite) const { - return suite == CipherSuite::RSA_WITH_AES_128_CBC_SHA256 - || suite == CipherSuite::RSA_WITH_AES_256_CBC_SHA256 - || suite == CipherSuite::RSA_WITH_AES_128_CBC_SHA - || suite == CipherSuite::RSA_WITH_AES_256_CBC_SHA - || suite == CipherSuite::RSA_WITH_AES_128_GCM_SHA256; + switch (suite) { +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + case suite: \ + return is_supported; + ENUMERATE_CIPHERS(C) +#undef C + default: + return false; + } } bool supports_version(Version v) const @@ -376,72 +401,50 @@ private: size_t key_length() const { switch (m_context.cipher) { - case CipherSuite::AES_128_CCM_8_SHA256: - case CipherSuite::AES_128_CCM_SHA256: - case CipherSuite::AES_128_GCM_SHA256: - case CipherSuite::Invalid: - case CipherSuite::RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite::RSA_WITH_AES_128_CBC_SHA: - case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + case suite: \ + return cipher_key_size(cipher) / 8; + ENUMERATE_CIPHERS(C) +#undef C default: return 128 / 8; - case CipherSuite::AES_256_GCM_SHA384: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: - return 256 / 8; } } + size_t mac_length() const { switch (m_context.cipher) { - case CipherSuite::RSA_WITH_AES_128_CBC_SHA: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA: - return Crypto::Hash::SHA1::digest_size(); - case CipherSuite::AES_256_GCM_SHA384: - case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: - return Crypto::Hash::SHA512::digest_size(); - case CipherSuite::AES_128_CCM_8_SHA256: - case CipherSuite::AES_128_CCM_SHA256: - case CipherSuite::AES_128_GCM_SHA256: - case CipherSuite::Invalid: - case CipherSuite::RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + case suite: \ + return hash ::digest_size(); + ENUMERATE_CIPHERS(C) +#undef C default: return Crypto::Hash::SHA256::digest_size(); } } + size_t iv_length() const { switch (m_context.cipher) { - case CipherSuite::AES_128_CCM_8_SHA256: - case CipherSuite::AES_128_CCM_SHA256: - case CipherSuite::Invalid: - case CipherSuite::RSA_WITH_AES_128_CBC_SHA256: - case CipherSuite::RSA_WITH_AES_128_CBC_SHA: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: - case CipherSuite::RSA_WITH_AES_256_CBC_SHA: +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + case suite: \ + return iv_size; + ENUMERATE_CIPHERS(C) +#undef C default: return 16; - case CipherSuite::AES_128_GCM_SHA256: - case CipherSuite::AES_256_GCM_SHA384: - case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: - return 8; // 4 bytes of fixed IV, 8 random (nonce) bytes, 4 bytes for counter - // GCM specifically asks us to transmit only the nonce, the counter is zero - // and the fixed IV is derived from the premaster key. } } bool is_aead() const { switch (m_context.cipher) { - case CipherSuite::AES_128_GCM_SHA256: - case CipherSuite::AES_256_GCM_SHA384: - case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: - case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: - return true; +#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \ + case suite: \ + return is_aead; + ENUMERATE_CIPHERS(C) +#undef C default: return false; } |