summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Winstein <keithw@mit.edu>2012-04-24 17:22:54 -0400
committerKeith Winstein <keithw@mit.edu>2012-04-24 18:40:01 -0400
commit22e7cf60d32a0b2028578e3a214bf44be9870513 (patch)
treedce1bc026b8bc80aacfdeee0b89c185ca44ad762
parent3ccfe64bfbe5c150999a9336680c5c75a2fa8238 (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.cc55
-rw-r--r--src/crypto/crypto.h11
-rw-r--r--src/network/network.cc8
-rw-r--r--src/network/network.h1
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 */