diff options
author | lloyd <[email protected]> | 2012-03-28 19:46:27 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-03-28 19:46:27 +0000 |
commit | 4c12fa5de1b59f2c58f974412231a19c4dc7c10f (patch) | |
tree | 0a48fbf3f63f153a155963eb98bd00e8f4ef43be /src/tls/tls_session.cpp | |
parent | ff7706d833cdcf754392bf1f7efe5de8190b7990 (diff) |
Rework session crypto code. Drop the 4 bytes of zeros reserved for
flags; if params change just regen the magic value and drop old
sessions. Check the magic value right from the start. Use constants
for internal sizes.
Increase default PBKDF2 iterations in the SQLite session manager
to 64K.
Diffstat (limited to 'src/tls/tls_session.cpp')
-rw-r--r-- | src/tls/tls_session.cpp | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp index c01590000..2a532196d 100644 --- a/src/tls/tls_session.cpp +++ b/src/tls/tls_session.cpp @@ -133,7 +133,16 @@ std::string Session::PEM_encode() const namespace { -const u64bit ENCRYPTED_SESSION_MAGIC = 0xACE4480800000000; +const u32bit SESSION_CRYPTO_MAGIC = 0x571B0E4E; +const std::string SESSION_CRYPTO_CIPHER = "AES-256/CBC"; +const std::string SESSION_CRYPTO_MAC = "HMAC(SHA-256)"; +const std::string SESSION_CRYPTO_KDF = "KDF2(SHA-256)"; + +const size_t MAGIC_LENGTH = 4; +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; } @@ -141,26 +150,30 @@ MemoryVector<byte> Session::encrypt(const SymmetricKey& master_key, RandomNumberGenerator& rng) const { - std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-256)")); + std::auto_ptr<KDF> kdf(get_kdf(SESSION_CRYPTO_KDF)); - SymmetricKey aes_key = kdf->derive_key(32, master_key.bits_of(), - "tls.session.cipher-key"); + SymmetricKey cipher_key = + kdf->derive_key(CIPHER_KEY_LENGTH, + master_key.bits_of(), + "tls.session.cipher-key"); - SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(), - "tls.session.mac-key"); + SymmetricKey mac_key = + kdf->derive_key(MAC_KEY_LENGTH, + master_key.bits_of(), + "tls.session.mac-key"); - InitializationVector aes_iv(rng, 16); + InitializationVector cipher_iv(rng, 16); - std::auto_ptr<MessageAuthenticationCode> mac(get_mac("HMAC(SHA-256)")); - mac->set_key(hmac_key); + std::auto_ptr<MessageAuthenticationCode> mac(get_mac(SESSION_CRYPTO_MAC)); + mac->set_key(mac_key); - Pipe pipe(get_cipher("AES-256/CBC", aes_key, aes_iv, ENCRYPTION)); + Pipe pipe(get_cipher(SESSION_CRYPTO_CIPHER, cipher_key, cipher_iv, ENCRYPTION)); pipe.process_msg(this->DER_encode()); MemoryVector<byte> ctext = pipe.read_all(0); - MemoryVector<byte> out(8); - store_be(ENCRYPTED_SESSION_MAGIC, &out[0]); - out += aes_iv.bits_of(); + MemoryVector<byte> out(MAGIC_LENGTH); + store_be(SESSION_CRYPTO_MAGIC, &out[0]); + out += cipher_iv.bits_of(); out += ctext; mac->update(out); @@ -174,42 +187,45 @@ Session Session::decrypt(const byte buf[], size_t buf_len, { try { - /* - 8 bytes header - 16 bytes IV - 32 bytes MAC - 16 bytes per AES block * 4 blocks (absolute min amount due to - 48 bytes master secret) - */ - if(buf_len < (8 + 16 + 32 + 4*16)) + const size_t MIN_CTEXT_SIZE = 4 * 16; // due to 48 byte master secret + + if(buf_len < (MAGIC_LENGTH + + CIPHER_IV_LENGTH + + MIN_CTEXT_SIZE + + MAC_OUTPUT_LENGTH)) throw Decoding_Error("Encrypted TLS session too short to be valid"); - std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-256)")); + if(load_be<u32bit>(buf, 0) != SESSION_CRYPTO_MAGIC) + throw Decoding_Error("Unknown header value in encrypted session"); + + std::auto_ptr<KDF> kdf(get_kdf(SESSION_CRYPTO_KDF)); - SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(), - "tls.session.mac-key"); + SymmetricKey mac_key = + kdf->derive_key(MAC_KEY_LENGTH, + master_key.bits_of(), + "tls.session.mac-key"); - std::auto_ptr<MessageAuthenticationCode> mac(get_mac("HMAC(SHA-256)")); - mac->set_key(hmac_key); + std::auto_ptr<MessageAuthenticationCode> mac(get_mac(SESSION_CRYPTO_MAC)); + mac->set_key(mac_key); - mac->update(&buf[0], buf_len - 32); + mac->update(&buf[0], buf_len - MAC_OUTPUT_LENGTH); MemoryVector<byte> computed_mac = mac->final(); - if(!same_mem(&buf[buf_len - 32], &computed_mac[0], computed_mac.size())) + if(!same_mem(&buf[buf_len - MAC_OUTPUT_LENGTH], &computed_mac[0], computed_mac.size())) throw Decoding_Error("MAC verification failed for encrypted session"); - const u64bit header = load_be<u64bit>(buf, 0); - - if(header != ENCRYPTED_SESSION_MAGIC) - throw Decoding_Error("Unknown header value in encrypted session"); + SymmetricKey cipher_key = + kdf->derive_key(CIPHER_KEY_LENGTH, + master_key.bits_of(), + "tls.session.cipher-key"); - SymmetricKey aes_key = kdf->derive_key(32, master_key.bits_of(), - "tls.session.cipher-key"); + InitializationVector cipher_iv(&buf[MAGIC_LENGTH], CIPHER_IV_LENGTH); - InitializationVector aes_iv(&buf[8], 16); + const size_t CTEXT_OFFSET = MAGIC_LENGTH + CIPHER_IV_LENGTH; - Pipe pipe(get_cipher("AES-256/CBC", aes_key, aes_iv, DECRYPTION)); - pipe.process_msg(&buf[8+16], buf_len - (32 + 8 + 16)); + Pipe pipe(get_cipher(SESSION_CRYPTO_CIPHER, cipher_key, cipher_iv, DECRYPTION)); + pipe.process_msg(&buf[CTEXT_OFFSET], + buf_len - (MAC_OUTPUT_LENGTH + CTEXT_OFFSET)); SecureVector<byte> ber = pipe.read_all(); return Session(&ber[0], ber.size()); |