Add a class for aligned buffers

This simplifies the core crypto routines, especially the error handling.  In
fact there was already one error path where we were failing to call free().
This commit is contained in:
Keegan McAllister
2012-03-24 21:37:43 -04:00
committed by Keith Winstein
parent c19bce27e6
commit 0734640e14
2 changed files with 42 additions and 28 deletions
+19 -28
View File
@@ -46,7 +46,8 @@ long int myatoi( const char *str )
return ret; return ret;
} }
static void * aligned_alloc( int len ) AlignedBuffer::AlignedBuffer( size_t len, const char *data )
: m_len( len ), m_data( NULL )
{ {
void *ptr = NULL; void *ptr = NULL;
@@ -72,7 +73,11 @@ static void * aligned_alloc( int len )
} }
#endif /* !defined(HAVE_POSIX_MEMALIGN) */ #endif /* !defined(HAVE_POSIX_MEMALIGN) */
return ptr; m_data = (char *) ptr;
if ( data ) {
memcpy( m_data, data, len );
}
} }
Base64Key::Base64Key( string printable_key ) Base64Key::Base64Key( string printable_key )
@@ -193,10 +198,8 @@ string Session::encrypt( Message plaintext )
const size_t pt_len = plaintext.text.size(); const size_t pt_len = plaintext.text.size();
const int ciphertext_len = pt_len + 16; const int ciphertext_len = pt_len + 16;
char *ciphertext = (char *)aligned_alloc( ciphertext_len ); AlignedBuffer ciphertext( ciphertext_len );
char *pt = (char *)aligned_alloc( pt_len ); AlignedBuffer pt( pt_len, plaintext.text.data() );
memcpy( pt, plaintext.text.data(), plaintext.text.size() );
if ( (uint64_t( plaintext.nonce.data() ) & 0xf) != 0 ) { if ( (uint64_t( plaintext.nonce.data() ) & 0xf) != 0 ) {
throw CryptoException( "Bad alignment." ); throw CryptoException( "Bad alignment." );
@@ -204,15 +207,13 @@ string Session::encrypt( Message plaintext )
if ( ciphertext_len != ae_encrypt( ctx, /* ctx */ if ( ciphertext_len != ae_encrypt( ctx, /* ctx */
plaintext.nonce.data(), /* nonce */ plaintext.nonce.data(), /* nonce */
pt, /* pt */ pt.data(), /* pt */
pt_len, /* pt_len */ pt.len(), /* pt_len */
NULL, /* ad */ NULL, /* ad */
0, /* ad_len */ 0, /* ad_len */
ciphertext, /* ct */ ciphertext.data(), /* ct */
NULL, /* tag */ NULL, /* tag */
AE_FINALIZE ) ) { /* final */ AE_FINALIZE ) ) { /* final */
free( pt );
free( ciphertext );
throw CryptoException( "ae_encrypt() returned error." ); throw CryptoException( "ae_encrypt() returned error." );
} }
@@ -235,14 +236,10 @@ string Session::encrypt( Message plaintext )
client use the same key, so we actually need to die after 2^47 blocks. client use the same key, so we actually need to die after 2^47 blocks.
*/ */
if ( blocks_encrypted >> 47 ) { if ( blocks_encrypted >> 47 ) {
free( pt );
free( ciphertext );
throw CryptoException( "Encrypted 2^47 blocks.", true ); throw CryptoException( "Encrypted 2^47 blocks.", true );
} }
string text( (char *)ciphertext, ciphertext_len ); string text( ciphertext.data(), ciphertext.len() );
free( pt );
free( ciphertext );
return plaintext.nonce.cc_str() + text; return plaintext.nonce.cc_str() + text;
} }
@@ -264,28 +261,22 @@ Message Session::decrypt( string ciphertext )
} }
Nonce __attribute__((__aligned__ (16))) nonce( str, 8 ); Nonce __attribute__((__aligned__ (16))) nonce( str, 8 );
char *body = (char *)aligned_alloc( body_len ); AlignedBuffer body( body_len, str + 8 );
memcpy( body, str + 8, body_len ); AlignedBuffer plaintext( pt_len );
char *plaintext = (char *)aligned_alloc( pt_len );
if ( pt_len != ae_decrypt( ctx, /* ctx */ if ( pt_len != ae_decrypt( ctx, /* ctx */
nonce.data(), /* nonce */ nonce.data(), /* nonce */
body, /* ct */ body.data(), /* ct */
body_len, /* ct_len */ body.len(), /* ct_len */
NULL, /* ad */ NULL, /* ad */
0, /* ad_len */ 0, /* ad_len */
plaintext, /* pt */ plaintext.data(), /* pt */
NULL, /* tag */ NULL, /* tag */
AE_FINALIZE ) ) { /* final */ AE_FINALIZE ) ) { /* final */
free( plaintext );
free( body );
throw CryptoException( "Packet failed integrity check." ); throw CryptoException( "Packet failed integrity check." );
} }
Message ret( nonce, string( plaintext, pt_len ) ); Message ret( nonce, string( plaintext.data(), plaintext.len() ) );
free( plaintext );
free( body );
return ret; return ret;
} }
+23
View File
@@ -23,6 +23,7 @@
#include <string> #include <string>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
using std::string; using std::string;
@@ -37,6 +38,28 @@ namespace Crypto {
: text( s_text ), fatal( s_fatal ) {}; : text( s_text ), fatal( s_fatal ) {};
}; };
/* 16-byte-aligned buffer, with length. */
class AlignedBuffer {
private:
size_t m_len;
char *m_data;
public:
AlignedBuffer( size_t len, const char *data = NULL );
~AlignedBuffer() {
free( m_data );
}
char * data( void ) const { return m_data; }
size_t len( void ) const { return m_len; }
private:
/* Not implemented */
AlignedBuffer( const AlignedBuffer& );
AlignedBuffer& operator=( const AlignedBuffer& );
};
class Base64Key { class Base64Key {
private: private:
unsigned char key[ 16 ]; unsigned char key[ 16 ];