diff options
author | Keith Winstein <keithw@mit.edu> | 2012-04-24 17:22:54 -0400 |
---|---|---|
committer | Keith Winstein <keithw@mit.edu> | 2012-04-24 18:40:01 -0400 |
commit | 22e7cf60d32a0b2028578e3a214bf44be9870513 (patch) | |
tree | dce1bc026b8bc80aacfdeee0b89c185ca44ad762 | |
parent | 3ccfe64bfbe5c150999a9336680c5c75a2fa8238 (diff) |
Keep aligned buffers around, instead of allocing on each packet
Fixes #238 github issue.
Also fixes armel "Bad alignment" problem.
-rw-r--r-- | src/crypto/crypto.cc | 55 | ||||
-rw-r--r-- | src/crypto/crypto.h | 11 | ||||
-rw-r--r-- | src/network/network.cc | 8 | ||||
-rw-r--r-- | src/network/network.h | 1 |
4 files changed, 44 insertions, 31 deletions
diff --git a/src/crypto/crypto.cc b/src/crypto/crypto.cc index 71b9fcd..9d5c03b 100644 --- a/src/crypto/crypto.cc +++ b/src/crypto/crypto.cc @@ -139,7 +139,10 @@ string Base64Key::printable_key( void ) const Session::Session( Base64Key s_key ) : key( s_key ), ctx_buf( ae_ctx_sizeof() ), - ctx( (ae_ctx *)ctx_buf.data() ), blocks_encrypted( 0 ) + ctx( (ae_ctx *)ctx_buf.data() ), blocks_encrypted( 0 ), + plaintext_buffer( RECEIVE_MTU ), + ciphertext_buffer( RECEIVE_MTU ), + nonce_buffer( Nonce::NONCE_LEN ) { if ( AE_SUCCESS != ae_init( ctx, key.data(), 16, 12, 16 ) ) { throw CryptoException( "Could not initialize AES-OCB context." ); @@ -194,20 +197,19 @@ string Session::encrypt( Message plaintext ) const size_t pt_len = plaintext.text.size(); const int ciphertext_len = pt_len + 16; - AlignedBuffer ciphertext( ciphertext_len ); - AlignedBuffer pt( pt_len, plaintext.text.data() ); + assert( (size_t)ciphertext_len <= ciphertext_buffer.len() ); + assert( pt_len <= plaintext_buffer.len() ); - if ( (uint64_t( plaintext.nonce.data() ) & 0xf) != 0 ) { - throw CryptoException( "Bad alignment." ); - } + memcpy( plaintext_buffer.data(), plaintext.text.data(), pt_len ); + memcpy( nonce_buffer.data(), plaintext.nonce.data(), Nonce::NONCE_LEN ); if ( ciphertext_len != ae_encrypt( ctx, /* ctx */ - plaintext.nonce.data(), /* nonce */ - pt.data(), /* pt */ - pt.len(), /* pt_len */ + nonce_buffer.data(), /* nonce */ + plaintext_buffer.data(), /* pt */ + pt_len, /* pt_len */ NULL, /* ad */ 0, /* ad_len */ - ciphertext.data(), /* ct */ + ciphertext_buffer.data(), /* ct */ NULL, /* tag */ AE_FINALIZE ) ) { /* final */ throw CryptoException( "ae_encrypt() returned error." ); @@ -235,7 +237,7 @@ string Session::encrypt( Message plaintext ) throw CryptoException( "Encrypted 2^47 blocks.", true ); } - string text( ciphertext.data(), ciphertext.len() ); + string text( ciphertext_buffer.data(), ciphertext_len ); return plaintext.nonce.cc_str() + text; } @@ -256,23 +258,26 @@ Message Session::decrypt( string ciphertext ) exit( 1 ); } - Nonce __attribute__((__aligned__ (16))) nonce( str, 8 ); - AlignedBuffer body( body_len, str + 8 ); - AlignedBuffer plaintext( pt_len ); - - if ( pt_len != ae_decrypt( ctx, /* ctx */ - nonce.data(), /* nonce */ - body.data(), /* ct */ - body.len(), /* ct_len */ - NULL, /* ad */ - 0, /* ad_len */ - plaintext.data(), /* pt */ - NULL, /* tag */ - AE_FINALIZE ) ) { /* final */ + assert( (size_t)body_len <= ciphertext_buffer.len() ); + assert( (size_t)pt_len <= plaintext_buffer.len() ); + + Nonce nonce( str, 8 ); + memcpy( ciphertext_buffer.data(), str + 8, body_len ); + memcpy( nonce_buffer.data(), nonce.data(), Nonce::NONCE_LEN ); + + if ( pt_len != ae_decrypt( ctx, /* ctx */ + nonce_buffer.data(), /* nonce */ + ciphertext_buffer.data(), /* ct */ + body_len, /* ct_len */ + NULL, /* ad */ + 0, /* ad_len */ + plaintext_buffer.data(), /* pt */ + NULL, /* tag */ + AE_FINALIZE ) ) { /* final */ throw CryptoException( "Packet failed integrity check." ); } - Message ret( nonce, string( plaintext.data(), plaintext.len() ) ); + Message ret( nonce, string( plaintext_buffer.data(), pt_len ) ); return ret; } diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index bbd70b4..1754c4c 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -73,8 +73,11 @@ namespace Crypto { }; class Nonce { + public: + static const int NONCE_LEN = 12; + private: - char bytes[ 12 ] __attribute__((__aligned__ (16))); + char bytes[ NONCE_LEN ]; public: Nonce( uint64_t val ); @@ -101,8 +104,14 @@ namespace Crypto { AlignedBuffer ctx_buf; ae_ctx *ctx; uint64_t blocks_encrypted; + + AlignedBuffer plaintext_buffer; + AlignedBuffer ciphertext_buffer; + AlignedBuffer nonce_buffer; public: + static const int RECEIVE_MTU = 2048; + Session( Base64Key s_key ); ~Session(); diff --git a/src/network/network.cc b/src/network/network.cc index 609aa68..7dfe225 100644 --- a/src/network/network.cc +++ b/src/network/network.cc @@ -276,20 +276,20 @@ string Connection::recv( void ) { struct sockaddr_in packet_remote_addr; - char buf[ RECEIVE_MTU ]; + char buf[ Session::RECEIVE_MTU ]; socklen_t addrlen = sizeof( packet_remote_addr ); - ssize_t received_len = recvfrom( sock, buf, RECEIVE_MTU, 0, (sockaddr *)&packet_remote_addr, &addrlen ); + ssize_t received_len = recvfrom( sock, buf, Session::RECEIVE_MTU, 0, (sockaddr *)&packet_remote_addr, &addrlen ); if ( received_len < 0 ) { throw NetworkException( "recvfrom", errno ); } - if ( received_len > RECEIVE_MTU ) { + if ( received_len > Session::RECEIVE_MTU ) { char buffer[ 2048 ]; snprintf( buffer, 2048, "Received oversize datagram (size %d) and limit is %d\n", - static_cast<int>( received_len ), RECEIVE_MTU ); + static_cast<int>( received_len ), Session::RECEIVE_MTU ); throw NetworkException( buffer, errno ); } diff --git a/src/network/network.h b/src/network/network.h index 347a53b..a190f7e 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -69,7 +69,6 @@ namespace Network { class Connection { private: - static const int RECEIVE_MTU = 2048; static const int SEND_MTU = 1400; static const uint64_t MIN_RTO = 50; /* ms */ static const uint64_t MAX_RTO = 1000; /* ms */ |