clang-format Mosh
Run clang-format over the Mosh source tree. This is a large change and
has been factored into its own commit for auditability. Reproduce it
with
find . -name \*.cc -or -name \*.h | while read f; do clang-format -i --style=file $f; done
This commit is contained in:
committed by
Alex Chernyakhovsky
parent
0b15dc94fa
commit
3acaa1c4d3
+28
-32
@@ -32,14 +32,14 @@ extern "C" {
|
||||
/* Return status codes: Negative return values indicate an error occurred.
|
||||
* For full explanations of error values, consult the implementation's
|
||||
* documentation. */
|
||||
#define AE_SUCCESS ( 0) /* Indicates successful completion of call */
|
||||
#define AE_INVALID (-1) /* Indicates bad tag during decryption */
|
||||
#define AE_NOT_SUPPORTED (-2) /* Indicates unsupported option requested */
|
||||
#define AE_SUCCESS ( 0 ) /* Indicates successful completion of call */
|
||||
#define AE_INVALID ( -1 ) /* Indicates bad tag during decryption */
|
||||
#define AE_NOT_SUPPORTED ( -2 ) /* Indicates unsupported option requested */
|
||||
|
||||
/* Flags: When data can be processed "incrementally", these flags are used
|
||||
* to indicate whether the submitted data is the last or not. */
|
||||
#define AE_FINALIZE (1) /* This is the last of data */
|
||||
#define AE_PENDING (0) /* More data of is coming */
|
||||
#define AE_FINALIZE ( 1 ) /* This is the last of data */
|
||||
#define AE_PENDING ( 0 ) /* More data of is coming */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
@@ -55,10 +55,10 @@ typedef struct _ae_ctx ae_ctx;
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
ae_ctx* ae_allocate (void *misc); /* Allocate ae_ctx, set optional ptr */
|
||||
void ae_free (ae_ctx *ctx); /* Deallocate ae_ctx struct */
|
||||
int ae_clear (ae_ctx *ctx); /* Undo initialization */
|
||||
int ae_ctx_sizeof(void); /* Return sizeof(ae_ctx) */
|
||||
ae_ctx* ae_allocate( void* misc ); /* Allocate ae_ctx, set optional ptr */
|
||||
void ae_free( ae_ctx* ctx ); /* Deallocate ae_ctx struct */
|
||||
int ae_clear( ae_ctx* ctx ); /* Undo initialization */
|
||||
int ae_ctx_sizeof( void ); /* Return sizeof(ae_ctx) */
|
||||
/* ae_allocate() allocates an ae_ctx structure, but does not initialize it.
|
||||
* ae_free() deallocates an ae_ctx structure, but does not zeroize it.
|
||||
* ae_clear() zeroes sensitive values associated with an ae_ctx structure
|
||||
@@ -72,11 +72,7 @@ int ae_ctx_sizeof(void); /* Return sizeof(ae_ctx) */
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_init(ae_ctx *ctx,
|
||||
const void *key,
|
||||
int key_len,
|
||||
int nonce_len,
|
||||
int tag_len);
|
||||
int ae_init( ae_ctx* ctx, const void* key, int key_len, int nonce_len, int tag_len );
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Initialize an ae_ctx context structure.
|
||||
@@ -95,15 +91,15 @@ int ae_init(ae_ctx *ctx,
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_encrypt(ae_ctx *ctx,
|
||||
const void *nonce,
|
||||
const void *pt,
|
||||
int pt_len,
|
||||
const void *ad,
|
||||
int ad_len,
|
||||
void *ct,
|
||||
void *tag,
|
||||
int final);
|
||||
int ae_encrypt( ae_ctx* ctx,
|
||||
const void* nonce,
|
||||
const void* pt,
|
||||
int pt_len,
|
||||
const void* ad,
|
||||
int ad_len,
|
||||
void* ct,
|
||||
void* tag,
|
||||
int final );
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Encrypt plaintext; provide for authentication of ciphertext/associated data.
|
||||
@@ -132,15 +128,15 @@ int ae_encrypt(ae_ctx *ctx,
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_decrypt(ae_ctx *ctx,
|
||||
const void *nonce,
|
||||
const void *ct,
|
||||
int ct_len,
|
||||
const void *ad,
|
||||
int ad_len,
|
||||
void *pt,
|
||||
const void *tag,
|
||||
int final);
|
||||
int ae_decrypt( ae_ctx* ctx,
|
||||
const void* nonce,
|
||||
const void* ct,
|
||||
int ct_len,
|
||||
const void* ad,
|
||||
int ad_len,
|
||||
void* pt,
|
||||
const void* tag,
|
||||
int final );
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Decrypt ciphertext; provide authenticity of plaintext and associated data.
|
||||
|
||||
+18
-20
@@ -33,8 +33,8 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "src/util/fatal_assert.h"
|
||||
#include "src/crypto/base64.h"
|
||||
#include "src/util/fatal_assert.h"
|
||||
|
||||
static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
@@ -60,27 +60,26 @@ static const unsigned char reverse[] = {
|
||||
};
|
||||
|
||||
/* Reverse maps from an ASCII char to a base64 sixbit value. Returns > 0x3f on failure. */
|
||||
static unsigned char base64_char_to_sixbit(unsigned char c)
|
||||
static unsigned char base64_char_to_sixbit( unsigned char c )
|
||||
{
|
||||
return reverse[c];
|
||||
}
|
||||
|
||||
bool base64_decode( const char *b64, const size_t b64_len,
|
||||
uint8_t *raw, size_t *raw_len )
|
||||
bool base64_decode( const char* b64, const size_t b64_len, uint8_t* raw, size_t* raw_len )
|
||||
{
|
||||
fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
|
||||
fatal_assert( *raw_len == 16 );
|
||||
|
||||
uint32_t bytes = 0;
|
||||
for (int i = 0; i < 22; i++) {
|
||||
unsigned char sixbit = base64_char_to_sixbit(*(b64++));
|
||||
if (sixbit > 0x3f) {
|
||||
for ( int i = 0; i < 22; i++ ) {
|
||||
unsigned char sixbit = base64_char_to_sixbit( *( b64++ ) );
|
||||
if ( sixbit > 0x3f ) {
|
||||
return false;
|
||||
}
|
||||
bytes <<= 6;
|
||||
bytes |= sixbit;
|
||||
/* write groups of 3 */
|
||||
if (i % 4 == 3) {
|
||||
if ( i % 4 == 3 ) {
|
||||
raw[0] = bytes >> 16;
|
||||
raw[1] = bytes >> 8;
|
||||
raw[2] = bytes;
|
||||
@@ -90,33 +89,32 @@ bool base64_decode( const char *b64, const size_t b64_len,
|
||||
}
|
||||
/* last byte of output */
|
||||
*raw = bytes >> 4;
|
||||
if (b64[0] != '=' || b64[1] != '=') {
|
||||
if ( b64[0] != '=' || b64[1] != '=' ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void base64_encode( const uint8_t *raw, const size_t raw_len,
|
||||
char *b64, const size_t b64_len )
|
||||
void base64_encode( const uint8_t* raw, const size_t raw_len, char* b64, const size_t b64_len )
|
||||
{
|
||||
fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
|
||||
fatal_assert( raw_len == 16 );
|
||||
|
||||
/* first 15 bytes of input */
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint32_t bytes = (raw[0] << 16) | (raw[1] << 8) | raw[2];
|
||||
b64[0] = table[(bytes >> 18) & 0x3f];
|
||||
b64[1] = table[(bytes >> 12) & 0x3f];
|
||||
b64[2] = table[(bytes >> 6) & 0x3f];
|
||||
b64[3] = table[(bytes) & 0x3f];
|
||||
for ( int i = 0; i < 5; i++ ) {
|
||||
uint32_t bytes = ( raw[0] << 16 ) | ( raw[1] << 8 ) | raw[2];
|
||||
b64[0] = table[( bytes >> 18 ) & 0x3f];
|
||||
b64[1] = table[( bytes >> 12 ) & 0x3f];
|
||||
b64[2] = table[( bytes >> 6 ) & 0x3f];
|
||||
b64[3] = table[(bytes)&0x3f];
|
||||
raw += 3;
|
||||
b64 += 4;
|
||||
}
|
||||
|
||||
|
||||
/* last byte of input, last 4 of output */
|
||||
uint8_t lastchar = *raw;
|
||||
b64[0] = table[(lastchar >> 2) & 0x3f];
|
||||
b64[1] = table[(lastchar << 4) & 0x3f];
|
||||
b64[0] = table[( lastchar >> 2 ) & 0x3f];
|
||||
b64[1] = table[( lastchar << 4 ) & 0x3f];
|
||||
b64[2] = '=';
|
||||
b64[3] = '=';
|
||||
}
|
||||
|
||||
+2
-4
@@ -32,8 +32,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
bool base64_decode( const char *b64, const size_t b64_len,
|
||||
uint8_t *raw, size_t *raw_len );
|
||||
bool base64_decode( const char* b64, const size_t b64_len, uint8_t* raw, size_t* raw_len );
|
||||
|
||||
void base64_encode( const uint8_t *raw, const size_t raw_len,
|
||||
char *b64, const size_t b64_len );
|
||||
void base64_encode( const uint8_t* raw, const size_t raw_len, char* b64, const size_t b64_len );
|
||||
|
||||
+40
-45
@@ -37,12 +37,12 @@
|
||||
|
||||
#if HAVE_DECL_BE64TOH || HAVE_DECL_BETOH64
|
||||
|
||||
# if defined(HAVE_ENDIAN_H)
|
||||
# include <endian.h>
|
||||
# elif defined(HAVE_SYS_ENDIAN_H)
|
||||
# include <sys/types.h>
|
||||
# include <sys/endian.h>
|
||||
# endif
|
||||
#if defined( HAVE_ENDIAN_H )
|
||||
#include <endian.h>
|
||||
#elif defined( HAVE_SYS_ENDIAN_H )
|
||||
#include <sys/endian.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_BE64TOH && HAVE_DECL_BETOH64
|
||||
#define be64toh betoh64
|
||||
@@ -50,11 +50,11 @@
|
||||
#endif
|
||||
|
||||
#elif HAVE_OSX_SWAP
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64 OSSwapHostToBigInt64
|
||||
# define be64toh OSSwapBigToHostInt64
|
||||
# define htobe16 OSSwapHostToBigInt16
|
||||
# define be16toh OSSwapBigToHostInt16
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define htobe64 OSSwapHostToBigInt64
|
||||
#define be64toh OSSwapBigToHostInt64
|
||||
#define htobe16 OSSwapHostToBigInt16
|
||||
#define be16toh OSSwapBigToHostInt16
|
||||
|
||||
#else
|
||||
|
||||
@@ -70,60 +70,55 @@
|
||||
|
||||
/* Use unions rather than casts, to comply with strict aliasing rules. */
|
||||
|
||||
inline uint64_t htobe64( uint64_t x ) {
|
||||
uint8_t xs[ 8 ] = {
|
||||
static_cast<uint8_t>( ( x >> 56 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 48 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 40 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 32 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 24 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 16 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 8 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x ) & 0xFF ) };
|
||||
inline uint64_t htobe64( uint64_t x )
|
||||
{
|
||||
uint8_t xs[8] = { static_cast<uint8_t>( ( x >> 56 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 48 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 40 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 32 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 24 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 16 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x >> 8 ) & 0xFF ),
|
||||
static_cast<uint8_t>( (x)&0xFF ) };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
const uint8_t* p8;
|
||||
const uint64_t* p64;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p64;
|
||||
}
|
||||
|
||||
inline uint64_t be64toh( uint64_t x ) {
|
||||
inline uint64_t be64toh( uint64_t x )
|
||||
{
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
const uint8_t* p8;
|
||||
const uint64_t* p64;
|
||||
} u;
|
||||
u.p64 = &x;
|
||||
return ( uint64_t( u.p8[ 0 ] ) << 56 )
|
||||
| ( uint64_t( u.p8[ 1 ] ) << 48 )
|
||||
| ( uint64_t( u.p8[ 2 ] ) << 40 )
|
||||
| ( uint64_t( u.p8[ 3 ] ) << 32 )
|
||||
| ( uint64_t( u.p8[ 4 ] ) << 24 )
|
||||
| ( uint64_t( u.p8[ 5 ] ) << 16 )
|
||||
| ( uint64_t( u.p8[ 6 ] ) << 8 )
|
||||
| ( uint64_t( u.p8[ 7 ] ) );
|
||||
return ( uint64_t( u.p8[0] ) << 56 ) | ( uint64_t( u.p8[1] ) << 48 ) | ( uint64_t( u.p8[2] ) << 40 )
|
||||
| ( uint64_t( u.p8[3] ) << 32 ) | ( uint64_t( u.p8[4] ) << 24 ) | ( uint64_t( u.p8[5] ) << 16 )
|
||||
| ( uint64_t( u.p8[6] ) << 8 ) | ( uint64_t( u.p8[7] ) );
|
||||
}
|
||||
|
||||
inline uint16_t htobe16( uint16_t x ) {
|
||||
uint8_t xs[ 2 ] = {
|
||||
static_cast<uint8_t>( ( x >> 8 ) & 0xFF ),
|
||||
static_cast<uint8_t>( ( x ) & 0xFF ) };
|
||||
inline uint16_t htobe16( uint16_t x )
|
||||
{
|
||||
uint8_t xs[2] = { static_cast<uint8_t>( ( x >> 8 ) & 0xFF ), static_cast<uint8_t>( (x)&0xFF ) };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
const uint8_t* p8;
|
||||
const uint16_t* p16;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p16;
|
||||
}
|
||||
|
||||
inline uint16_t be16toh( uint16_t x ) {
|
||||
inline uint16_t be16toh( uint16_t x )
|
||||
{
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
const uint8_t* p8;
|
||||
const uint16_t* p16;
|
||||
} u;
|
||||
u.p16 = &x;
|
||||
return ( uint16_t( u.p8[ 0 ] ) << 8 )
|
||||
| ( uint16_t( u.p8[ 1 ] ) );
|
||||
return ( uint16_t( u.p8[0] ) << 8 ) | ( uint16_t( u.p8[1] ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+47
-50
@@ -39,23 +39,22 @@
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "src/crypto/base64.h"
|
||||
#include "src/crypto/byteorder.h"
|
||||
#include "src/crypto/crypto.h"
|
||||
#include "src/crypto/base64.h"
|
||||
#include "src/util/fatal_assert.h"
|
||||
#include "src/crypto/prng.h"
|
||||
#include "src/util/fatal_assert.h"
|
||||
|
||||
using namespace Crypto;
|
||||
|
||||
long int myatoi( const char *str )
|
||||
long int myatoi( const char* str )
|
||||
{
|
||||
char *end;
|
||||
char* end;
|
||||
|
||||
errno = 0;
|
||||
long int ret = strtol( str, &end, 10 );
|
||||
|
||||
if ( ( errno != 0 )
|
||||
|| ( end != str + strlen( str ) ) ) {
|
||||
if ( ( errno != 0 ) || ( end != str + strlen( str ) ) ) {
|
||||
throw CryptoException( "Bad integer." );
|
||||
}
|
||||
|
||||
@@ -72,16 +71,14 @@ uint64_t Crypto::unique( void )
|
||||
return rv;
|
||||
}
|
||||
|
||||
AlignedBuffer::AlignedBuffer( size_t len, const char *data )
|
||||
: m_len( len ), m_allocated( NULL ), m_data( NULL )
|
||||
AlignedBuffer::AlignedBuffer( size_t len, const char* data ) : m_len( len ), m_allocated( NULL ), m_data( NULL )
|
||||
{
|
||||
size_t alloc_len = len ? len : 1;
|
||||
#if defined(HAVE_POSIX_MEMALIGN)
|
||||
if ( ( 0 != posix_memalign( &m_allocated, 16, alloc_len ) )
|
||||
|| ( m_allocated == NULL ) ) {
|
||||
#if defined( HAVE_POSIX_MEMALIGN )
|
||||
if ( ( 0 != posix_memalign( &m_allocated, 16, alloc_len ) ) || ( m_allocated == NULL ) ) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
m_data = (char *) m_allocated;
|
||||
m_data = (char*)m_allocated;
|
||||
|
||||
#else
|
||||
/* malloc() a region 15 bytes larger than we need, and find
|
||||
@@ -91,15 +88,15 @@ AlignedBuffer::AlignedBuffer( size_t len, const char *data )
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
uintptr_t iptr = (uintptr_t) m_allocated;
|
||||
uintptr_t iptr = (uintptr_t)m_allocated;
|
||||
if ( iptr & 0xF ) {
|
||||
iptr += 16 - ( iptr & 0xF );
|
||||
}
|
||||
assert( !( iptr & 0xF ) );
|
||||
assert( iptr >= (uintptr_t) m_allocated );
|
||||
assert( iptr <= ( 15 + (uintptr_t) m_allocated ) );
|
||||
assert( iptr >= (uintptr_t)m_allocated );
|
||||
assert( iptr <= ( 15 + (uintptr_t)m_allocated ) );
|
||||
|
||||
m_data = (char *) iptr;
|
||||
m_data = (char*)iptr;
|
||||
|
||||
#endif /* !defined(HAVE_POSIX_MEMALIGN) */
|
||||
|
||||
@@ -136,32 +133,28 @@ Base64Key::Base64Key()
|
||||
PRNG().fill( key, sizeof( key ) );
|
||||
}
|
||||
|
||||
Base64Key::Base64Key(PRNG &prng)
|
||||
Base64Key::Base64Key( PRNG& prng )
|
||||
{
|
||||
prng.fill( key, sizeof( key ) );
|
||||
}
|
||||
|
||||
std::string Base64Key::printable_key( void ) const
|
||||
{
|
||||
char base64[ 24 ];
|
||||
|
||||
char base64[24];
|
||||
|
||||
base64_encode( key, 16, base64, 24 );
|
||||
|
||||
if ( (base64[ 23 ] != '=')
|
||||
|| (base64[ 22 ] != '=') ) {
|
||||
if ( ( base64[23] != '=' ) || ( base64[22] != '=' ) ) {
|
||||
throw CryptoException( std::string( "Unexpected output from base64_encode: " ) + std::string( base64, 24 ) );
|
||||
}
|
||||
|
||||
base64[ 22 ] = 0;
|
||||
base64[22] = 0;
|
||||
return std::string( base64 );
|
||||
}
|
||||
|
||||
Session::Session( Base64Key s_key )
|
||||
: key( s_key ), ctx_buf( ae_ctx_sizeof() ),
|
||||
ctx( (ae_ctx *)ctx_buf.data() ), blocks_encrypted( 0 ),
|
||||
plaintext_buffer( RECEIVE_MTU ),
|
||||
ciphertext_buffer( RECEIVE_MTU ),
|
||||
nonce_buffer( Nonce::NONCE_LEN )
|
||||
: key( s_key ), ctx_buf( ae_ctx_sizeof() ), 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." );
|
||||
@@ -188,7 +181,7 @@ uint64_t Nonce::val( void ) const
|
||||
return be64toh( ret );
|
||||
}
|
||||
|
||||
Nonce::Nonce( const char *s_bytes, size_t len )
|
||||
Nonce::Nonce( const char* s_bytes, size_t len )
|
||||
{
|
||||
if ( len != 8 ) {
|
||||
throw CryptoException( "Nonce representation must be 8 octets long." );
|
||||
@@ -198,7 +191,7 @@ Nonce::Nonce( const char *s_bytes, size_t len )
|
||||
memcpy( bytes + 4, s_bytes, 8 );
|
||||
}
|
||||
|
||||
const std::string Session::encrypt( const Message & plaintext )
|
||||
const std::string Session::encrypt( const Message& plaintext )
|
||||
{
|
||||
const size_t pt_len = plaintext.text.size();
|
||||
const int ciphertext_len = pt_len + 16;
|
||||
@@ -209,15 +202,16 @@ const std::string Session::encrypt( const Message & plaintext )
|
||||
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 */
|
||||
nonce_buffer.data(), /* nonce */
|
||||
plaintext_buffer.data(), /* pt */
|
||||
pt_len, /* pt_len */
|
||||
NULL, /* ad */
|
||||
0, /* ad_len */
|
||||
ciphertext_buffer.data(), /* ct */
|
||||
NULL, /* tag */
|
||||
AE_FINALIZE ) ) { /* final */
|
||||
if ( ciphertext_len
|
||||
!= ae_encrypt( ctx, /* ctx */
|
||||
nonce_buffer.data(), /* nonce */
|
||||
plaintext_buffer.data(), /* pt */
|
||||
pt_len, /* pt_len */
|
||||
NULL, /* ad */
|
||||
0, /* ad_len */
|
||||
ciphertext_buffer.data(), /* ct */
|
||||
NULL, /* tag */
|
||||
AE_FINALIZE ) ) { /* final */
|
||||
throw CryptoException( "ae_encrypt() returned error." );
|
||||
}
|
||||
|
||||
@@ -248,7 +242,7 @@ const std::string Session::encrypt( const Message & plaintext )
|
||||
return plaintext.nonce.cc_str() + text;
|
||||
}
|
||||
|
||||
const Message Session::decrypt( const char *str, size_t len )
|
||||
const Message Session::decrypt( const char* str, size_t len )
|
||||
{
|
||||
if ( len < 24 ) {
|
||||
throw CryptoException( "Ciphertext must contain nonce and tag." );
|
||||
@@ -269,15 +263,16 @@ const Message Session::decrypt( const char *str, size_t len )
|
||||
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 */
|
||||
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." );
|
||||
}
|
||||
|
||||
@@ -290,7 +285,8 @@ static rlim_t saved_core_rlimit;
|
||||
|
||||
/* Disable dumping core, as a precaution to avoid saving sensitive data
|
||||
to disk. */
|
||||
void Crypto::disable_dumping_core( void ) {
|
||||
void Crypto::disable_dumping_core( void )
|
||||
{
|
||||
struct rlimit limit;
|
||||
if ( 0 != getrlimit( RLIMIT_CORE, &limit ) ) {
|
||||
/* We don't throw CryptoException because this is called very early
|
||||
@@ -307,7 +303,8 @@ void Crypto::disable_dumping_core( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::reenable_dumping_core( void ) {
|
||||
void Crypto::reenable_dumping_core( void )
|
||||
{
|
||||
/* Silent failure is safe. */
|
||||
struct rlimit limit;
|
||||
if ( 0 == getrlimit( RLIMIT_CORE, &limit ) ) {
|
||||
|
||||
+98
-101
@@ -41,126 +41,123 @@
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
|
||||
long int myatoi( const char *str );
|
||||
long int myatoi( const char* str );
|
||||
|
||||
class PRNG;
|
||||
|
||||
namespace Crypto {
|
||||
class CryptoException : public std::exception {
|
||||
public:
|
||||
std::string text;
|
||||
bool fatal;
|
||||
CryptoException( std::string s_text, bool s_fatal = false )
|
||||
: text( s_text ), fatal( s_fatal ) {};
|
||||
const char *what() const throw () { return text.c_str(); }
|
||||
~CryptoException() throw () {}
|
||||
};
|
||||
class CryptoException : public std::exception
|
||||
{
|
||||
public:
|
||||
std::string text;
|
||||
bool fatal;
|
||||
CryptoException( std::string s_text, bool s_fatal = false ) : text( s_text ), fatal( s_fatal ) {};
|
||||
const char* what() const throw() { return text.c_str(); }
|
||||
~CryptoException() throw() {}
|
||||
};
|
||||
|
||||
/*
|
||||
* OCB (and other algorithms) require a source of nonce/sequence
|
||||
* numbers that never repeats its output. Enforce that with this
|
||||
* function.
|
||||
*/
|
||||
uint64_t unique( void );
|
||||
/*
|
||||
* OCB (and other algorithms) require a source of nonce/sequence
|
||||
* numbers that never repeats its output. Enforce that with this
|
||||
* function.
|
||||
*/
|
||||
uint64_t unique( void );
|
||||
|
||||
/* 16-byte-aligned buffer, with length. */
|
||||
class AlignedBuffer {
|
||||
private:
|
||||
size_t m_len;
|
||||
void *m_allocated;
|
||||
char *m_data;
|
||||
/* 16-byte-aligned buffer, with length. */
|
||||
class AlignedBuffer
|
||||
{
|
||||
private:
|
||||
size_t m_len;
|
||||
void* m_allocated;
|
||||
char* m_data;
|
||||
|
||||
public:
|
||||
AlignedBuffer( size_t len, const char *data = NULL );
|
||||
public:
|
||||
AlignedBuffer( size_t len, const char* data = NULL );
|
||||
|
||||
~AlignedBuffer() {
|
||||
free( m_allocated );
|
||||
}
|
||||
~AlignedBuffer() { free( m_allocated ); }
|
||||
|
||||
char * data( void ) const { return m_data; }
|
||||
size_t len( void ) const { return m_len; }
|
||||
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 & );
|
||||
};
|
||||
private:
|
||||
/* Not implemented */
|
||||
AlignedBuffer( const AlignedBuffer& );
|
||||
AlignedBuffer& operator=( const AlignedBuffer& );
|
||||
};
|
||||
|
||||
class Base64Key {
|
||||
private:
|
||||
unsigned char key[ 16 ];
|
||||
class Base64Key
|
||||
{
|
||||
private:
|
||||
unsigned char key[16];
|
||||
|
||||
public:
|
||||
Base64Key(); /* random key */
|
||||
Base64Key(PRNG &prng);
|
||||
Base64Key( std::string printable_key );
|
||||
std::string printable_key( void ) const;
|
||||
unsigned char *data( void ) { return key; }
|
||||
};
|
||||
public:
|
||||
Base64Key(); /* random key */
|
||||
Base64Key( PRNG& prng );
|
||||
Base64Key( std::string printable_key );
|
||||
std::string printable_key( void ) const;
|
||||
unsigned char* data( void ) { return key; }
|
||||
};
|
||||
|
||||
class Nonce {
|
||||
public:
|
||||
static const int NONCE_LEN = 12;
|
||||
class Nonce
|
||||
{
|
||||
public:
|
||||
static const int NONCE_LEN = 12;
|
||||
|
||||
private:
|
||||
char bytes[ NONCE_LEN ];
|
||||
private:
|
||||
char bytes[NONCE_LEN];
|
||||
|
||||
public:
|
||||
Nonce( uint64_t val );
|
||||
Nonce( const char *s_bytes, size_t len );
|
||||
|
||||
std::string cc_str( void ) const { return std::string( bytes + 4, 8 ); }
|
||||
const char *data( void ) const { return bytes; }
|
||||
uint64_t val( void ) const;
|
||||
};
|
||||
|
||||
class Message {
|
||||
public:
|
||||
const Nonce nonce;
|
||||
const std::string text;
|
||||
|
||||
Message( const char *nonce_bytes, size_t nonce_len,
|
||||
const char *text_bytes, size_t text_len )
|
||||
: nonce( nonce_bytes, nonce_len ),
|
||||
text( text_bytes, text_len ) {}
|
||||
public:
|
||||
Nonce( uint64_t val );
|
||||
Nonce( const char* s_bytes, size_t len );
|
||||
|
||||
Message( const Nonce & s_nonce, const std::string & s_text )
|
||||
: nonce( s_nonce ),
|
||||
text( s_text ) {}
|
||||
};
|
||||
|
||||
class Session {
|
||||
private:
|
||||
Base64Key key;
|
||||
AlignedBuffer ctx_buf;
|
||||
ae_ctx *ctx;
|
||||
uint64_t blocks_encrypted;
|
||||
std::string cc_str( void ) const { return std::string( bytes + 4, 8 ); }
|
||||
const char* data( void ) const { return bytes; }
|
||||
uint64_t val( void ) const;
|
||||
};
|
||||
|
||||
AlignedBuffer plaintext_buffer;
|
||||
AlignedBuffer ciphertext_buffer;
|
||||
AlignedBuffer nonce_buffer;
|
||||
|
||||
public:
|
||||
static const int RECEIVE_MTU = 2048;
|
||||
/* Overhead (not counting the nonce, which is handled by network transport) */
|
||||
static const int ADDED_BYTES = 16 /* final OCB block */;
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
const Nonce nonce;
|
||||
const std::string text;
|
||||
|
||||
Session( Base64Key s_key );
|
||||
~Session();
|
||||
|
||||
const std::string encrypt( const Message & plaintext );
|
||||
const Message decrypt( const char *str, size_t len );
|
||||
const Message decrypt( const std::string & ciphertext ) {
|
||||
return decrypt( ciphertext.data(), ciphertext.size() );
|
||||
}
|
||||
|
||||
Session( const Session & );
|
||||
Session & operator=( const Session & );
|
||||
};
|
||||
Message( const char* nonce_bytes, size_t nonce_len, const char* text_bytes, size_t text_len )
|
||||
: nonce( nonce_bytes, nonce_len ), text( text_bytes, text_len )
|
||||
{}
|
||||
|
||||
void disable_dumping_core( void );
|
||||
void reenable_dumping_core( void );
|
||||
Message( const Nonce& s_nonce, const std::string& s_text ) : nonce( s_nonce ), text( s_text ) {}
|
||||
};
|
||||
|
||||
class Session
|
||||
{
|
||||
private:
|
||||
Base64Key key;
|
||||
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;
|
||||
/* Overhead (not counting the nonce, which is handled by network transport) */
|
||||
static const int ADDED_BYTES = 16 /* final OCB block */;
|
||||
|
||||
Session( Base64Key s_key );
|
||||
~Session();
|
||||
|
||||
const std::string encrypt( const Message& plaintext );
|
||||
const Message decrypt( const char* str, size_t len );
|
||||
const Message decrypt( const std::string& ciphertext ) { return decrypt( ciphertext.data(), ciphertext.size() ); }
|
||||
|
||||
Session( const Session& );
|
||||
Session& operator=( const Session& );
|
||||
};
|
||||
|
||||
void disable_dumping_core( void );
|
||||
void reenable_dumping_core( void );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+99
-78
@@ -1,188 +1,209 @@
|
||||
#include "src/include/config.h"
|
||||
#include "src/crypto/ae.h"
|
||||
#include "src/include/config.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
struct _ae_ctx {
|
||||
EVP_CIPHER_CTX *enc_ctx;
|
||||
EVP_CIPHER_CTX *dec_ctx;
|
||||
struct _ae_ctx
|
||||
{
|
||||
EVP_CIPHER_CTX* enc_ctx;
|
||||
EVP_CIPHER_CTX* dec_ctx;
|
||||
int tag_len;
|
||||
};
|
||||
|
||||
int ae_clear(ae_ctx* ctx) {
|
||||
EVP_CIPHER_CTX_free(ctx->enc_ctx);
|
||||
EVP_CIPHER_CTX_free(ctx->dec_ctx);
|
||||
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
||||
int ae_clear( ae_ctx* ctx )
|
||||
{
|
||||
EVP_CIPHER_CTX_free( ctx->enc_ctx );
|
||||
EVP_CIPHER_CTX_free( ctx->dec_ctx );
|
||||
OPENSSL_cleanse( ctx, sizeof( *ctx ) );
|
||||
return AE_SUCCESS;
|
||||
}
|
||||
|
||||
int ae_ctx_sizeof() {
|
||||
return sizeof(_ae_ctx);
|
||||
int ae_ctx_sizeof()
|
||||
{
|
||||
return sizeof( _ae_ctx );
|
||||
}
|
||||
|
||||
// If direction is 1, initializes encryption. If 0, initializes
|
||||
// decryption. See the documentation of EVP_CipherInit_ex
|
||||
static int ae_evp_cipher_init(EVP_CIPHER_CTX **in_ctx, int direction,
|
||||
const unsigned char *key,
|
||||
int nonce_len, int tag_len) {
|
||||
static int ae_evp_cipher_init( EVP_CIPHER_CTX** in_ctx,
|
||||
int direction,
|
||||
const unsigned char* key,
|
||||
int nonce_len,
|
||||
int tag_len )
|
||||
{
|
||||
// Create an OpenSSL EVP context. It does not yet have any specific
|
||||
// cipher associated with it.
|
||||
if (!(*in_ctx = EVP_CIPHER_CTX_new())) {
|
||||
if ( !( *in_ctx = EVP_CIPHER_CTX_new() ) ) {
|
||||
return -3;
|
||||
}
|
||||
EVP_CIPHER_CTX *ctx = *in_ctx;
|
||||
EVP_CIPHER_CTX* ctx = *in_ctx;
|
||||
// Although OCB-AES has the same initialization process between
|
||||
// encryption and decryption, an EVP_CIPHER_CTX must be initialized
|
||||
// for a specific direction.
|
||||
if (EVP_CipherInit_ex(ctx, EVP_aes_128_ocb(),
|
||||
/*impl=*/NULL, /*key=*/key, /*iv=*/NULL,
|
||||
direction) != 1) {
|
||||
if ( EVP_CipherInit_ex( ctx,
|
||||
EVP_aes_128_ocb(),
|
||||
/*impl=*/NULL,
|
||||
/*key=*/key,
|
||||
/*iv=*/NULL,
|
||||
direction )
|
||||
!= 1 ) {
|
||||
return -3;
|
||||
}
|
||||
// Attempt to set the nonce length. If it fails, the length must not
|
||||
// be supported. However, that should have been handled by the
|
||||
// pre-condition check above.
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
|
||||
nonce_len, NULL) != 1) {
|
||||
if ( EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_AEAD_SET_IVLEN, nonce_len, NULL ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
// A NULL tag length means that EVP_CTRL_AEAD_SET_TAG is only being
|
||||
// used to set the length
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
||||
tag_len, NULL) != 1) {
|
||||
if ( EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
return AE_SUCCESS;
|
||||
}
|
||||
|
||||
int ae_init(ae_ctx *ctx, const void *key, int key_len, int nonce_len,
|
||||
int tag_len) {
|
||||
int ae_init( ae_ctx* ctx, const void* key, int key_len, int nonce_len, int tag_len )
|
||||
{
|
||||
// Pre-condition: Only nonces of length 12 are supported. The
|
||||
// documentation of `ae_init` in ae.h specifies that `ctx` is
|
||||
// untouched if an invalid configuration is requested. Delegating
|
||||
// this to OpenSSL would happen too late; `ctx` has already been
|
||||
// modified.
|
||||
if (nonce_len != 12) {
|
||||
if ( nonce_len != 12 ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
// Pre-condition: Only AES-128 is supported.
|
||||
if (key_len != 16) {
|
||||
if ( key_len != 16 ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
int r = AE_SUCCESS;
|
||||
if ((r = ae_evp_cipher_init(&ctx->enc_ctx, 1,
|
||||
reinterpret_cast<const unsigned char *>(key),
|
||||
nonce_len, tag_len))!= AE_SUCCESS) {
|
||||
if ( ( r = ae_evp_cipher_init(
|
||||
&ctx->enc_ctx, 1, reinterpret_cast<const unsigned char*>( key ), nonce_len, tag_len ) )
|
||||
!= AE_SUCCESS ) {
|
||||
return r;
|
||||
}
|
||||
if ((r = ae_evp_cipher_init(&ctx->dec_ctx, 0,
|
||||
reinterpret_cast<const unsigned char *>(key),
|
||||
nonce_len, tag_len)) != AE_SUCCESS) {
|
||||
if ( ( r = ae_evp_cipher_init(
|
||||
&ctx->dec_ctx, 0, reinterpret_cast<const unsigned char*>( key ), nonce_len, tag_len ) )
|
||||
!= AE_SUCCESS ) {
|
||||
return r;
|
||||
}
|
||||
ctx->tag_len = tag_len;
|
||||
return AE_SUCCESS;
|
||||
}
|
||||
|
||||
int ae_encrypt(ae_ctx *ctx, const void *nonce_ptr, const void *pt_ptr,
|
||||
int pt_len, const void *ad_ptr, int ad_len, void *ct_ptr,
|
||||
void *tag, int final) {
|
||||
const unsigned char *nonce =
|
||||
reinterpret_cast<const unsigned char *>(nonce_ptr);
|
||||
const unsigned char *pt = reinterpret_cast<const unsigned char *>(pt_ptr);
|
||||
const unsigned char* ad = reinterpret_cast<const unsigned char *>(ad_ptr);
|
||||
unsigned char* ct = reinterpret_cast<unsigned char *>(ct_ptr);
|
||||
int ae_encrypt( ae_ctx* ctx,
|
||||
const void* nonce_ptr,
|
||||
const void* pt_ptr,
|
||||
int pt_len,
|
||||
const void* ad_ptr,
|
||||
int ad_len,
|
||||
void* ct_ptr,
|
||||
void* tag,
|
||||
int final )
|
||||
{
|
||||
const unsigned char* nonce = reinterpret_cast<const unsigned char*>( nonce_ptr );
|
||||
const unsigned char* pt = reinterpret_cast<const unsigned char*>( pt_ptr );
|
||||
const unsigned char* ad = reinterpret_cast<const unsigned char*>( ad_ptr );
|
||||
unsigned char* ct = reinterpret_cast<unsigned char*>( ct_ptr );
|
||||
// Streaming mode is not supported; nonce must always be provided.
|
||||
if (final != AE_FINALIZE) {
|
||||
if ( final != AE_FINALIZE ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
if (nonce == NULL) {
|
||||
if ( nonce == NULL ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
if (EVP_EncryptInit_ex(ctx->enc_ctx, /*type=*/NULL, /*impl=*/NULL,
|
||||
/*key=*/NULL, nonce) != 1) {
|
||||
if ( EVP_EncryptInit_ex( ctx->enc_ctx,
|
||||
/*type=*/NULL,
|
||||
/*impl=*/NULL,
|
||||
/*key=*/NULL,
|
||||
nonce )
|
||||
!= 1 ) {
|
||||
return -3;
|
||||
}
|
||||
int len = 0;
|
||||
if (ad != NULL && ad_len > 0 &&
|
||||
EVP_EncryptUpdate(ctx->enc_ctx, /*out=*/NULL, &len, ad, ad_len) != 1) {
|
||||
return -3;
|
||||
if ( ad != NULL && ad_len > 0 && EVP_EncryptUpdate( ctx->enc_ctx, /*out=*/NULL, &len, ad, ad_len ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
len = 0;
|
||||
if (pt != NULL && pt_len > 0 &&
|
||||
EVP_EncryptUpdate(ctx->enc_ctx, ct, &len, pt, pt_len) != 1) {
|
||||
if ( pt != NULL && pt_len > 0 && EVP_EncryptUpdate( ctx->enc_ctx, ct, &len, pt, pt_len ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
int ciphertext_len = len;
|
||||
if (EVP_EncryptFinal_ex(ctx->enc_ctx, ct + ciphertext_len, &len) != 1) {
|
||||
if ( EVP_EncryptFinal_ex( ctx->enc_ctx, ct + ciphertext_len, &len ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
ciphertext_len += len;
|
||||
// If `tag` is provided, the authentication tag goes
|
||||
// there. Otherwise, it is appended after the ciphertext.
|
||||
void *tag_location = tag != NULL ? tag : ct + ciphertext_len;
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->enc_ctx, EVP_CTRL_AEAD_GET_TAG,
|
||||
ctx->tag_len, tag_location) != 1) {
|
||||
void* tag_location = tag != NULL ? tag : ct + ciphertext_len;
|
||||
if ( EVP_CIPHER_CTX_ctrl( ctx->enc_ctx, EVP_CTRL_AEAD_GET_TAG, ctx->tag_len, tag_location ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
if (tag == NULL) {
|
||||
if ( tag == NULL ) {
|
||||
ciphertext_len += ctx->tag_len;
|
||||
}
|
||||
return ciphertext_len;
|
||||
}
|
||||
|
||||
|
||||
int ae_decrypt(ae_ctx *ctx, const void *nonce_ptr, const void *ct_ptr,
|
||||
int ct_len, const void *ad_ptr, int ad_len, void *pt_ptr,
|
||||
const void *tag, int final) {
|
||||
const unsigned char *nonce =
|
||||
reinterpret_cast<const unsigned char *>(nonce_ptr);
|
||||
const unsigned char *ct = reinterpret_cast<const unsigned char *>(ct_ptr);
|
||||
const unsigned char* ad = reinterpret_cast<const unsigned char *>(ad_ptr);
|
||||
unsigned char* pt = reinterpret_cast<unsigned char *>(pt_ptr);
|
||||
if (ct_len < ctx->tag_len) {
|
||||
int ae_decrypt( ae_ctx* ctx,
|
||||
const void* nonce_ptr,
|
||||
const void* ct_ptr,
|
||||
int ct_len,
|
||||
const void* ad_ptr,
|
||||
int ad_len,
|
||||
void* pt_ptr,
|
||||
const void* tag,
|
||||
int final )
|
||||
{
|
||||
const unsigned char* nonce = reinterpret_cast<const unsigned char*>( nonce_ptr );
|
||||
const unsigned char* ct = reinterpret_cast<const unsigned char*>( ct_ptr );
|
||||
const unsigned char* ad = reinterpret_cast<const unsigned char*>( ad_ptr );
|
||||
unsigned char* pt = reinterpret_cast<unsigned char*>( pt_ptr );
|
||||
if ( ct_len < ctx->tag_len ) {
|
||||
return AE_INVALID;
|
||||
}
|
||||
// If an external tag is not provided, then the tag is assumed to be
|
||||
// the final bytes of the cipher text. Subtract it off now so the
|
||||
// plaintext does not accidentally try to decrypt the AEAD tag (and
|
||||
// then cause an authentication failure).
|
||||
if (tag == NULL) {
|
||||
if ( tag == NULL ) {
|
||||
ct_len -= ctx->tag_len;
|
||||
}
|
||||
// Like encryption, nonce must always be provided and streaming is not supported.
|
||||
if (final != AE_FINALIZE) {
|
||||
if ( final != AE_FINALIZE ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
if (nonce == NULL) {
|
||||
if ( nonce == NULL ) {
|
||||
return AE_NOT_SUPPORTED;
|
||||
}
|
||||
if (EVP_DecryptInit_ex(ctx->dec_ctx, /*type=*/NULL, /*impl=*/NULL,
|
||||
/*key=*/NULL, nonce) != 1) {
|
||||
if ( EVP_DecryptInit_ex( ctx->dec_ctx,
|
||||
/*type=*/NULL,
|
||||
/*impl=*/NULL,
|
||||
/*key=*/NULL,
|
||||
nonce )
|
||||
!= 1 ) {
|
||||
return -3;
|
||||
}
|
||||
int len = 0;
|
||||
if (ad != NULL && ad_len > 0 &&
|
||||
EVP_DecryptUpdate(ctx->dec_ctx, /*out=*/NULL, &len, ad, ad_len) != 1) {
|
||||
return -3;
|
||||
if ( ad != NULL && ad_len > 0 && EVP_DecryptUpdate( ctx->dec_ctx, /*out=*/NULL, &len, ad, ad_len ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
len = 0;
|
||||
if (ct != NULL && ct_len > 0 &&
|
||||
EVP_DecryptUpdate(ctx->dec_ctx, pt, &len, ct, ct_len) != 1) {
|
||||
if ( ct != NULL && ct_len > 0 && EVP_DecryptUpdate( ctx->dec_ctx, pt, &len, ct, ct_len ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
int plaintext_len = len;
|
||||
// If `tag` is provided, the authentication is read from
|
||||
// there. Otherwise, it's the last bytes of the ciphertext. (This is
|
||||
// a convention, not a requirement of OCB mode).
|
||||
const void *tag_location = tag != NULL ? tag : ct + ct_len;
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->dec_ctx, EVP_CTRL_AEAD_SET_TAG,
|
||||
ctx->tag_len, (void *)tag_location) != 1) {
|
||||
const void* tag_location = tag != NULL ? tag : ct + ct_len;
|
||||
if ( EVP_CIPHER_CTX_ctrl( ctx->dec_ctx, EVP_CTRL_AEAD_SET_TAG, ctx->tag_len, (void*)tag_location ) != 1 ) {
|
||||
return -3;
|
||||
}
|
||||
if (EVP_DecryptFinal_ex(ctx->dec_ctx, pt + plaintext_len, &len) != 1) {
|
||||
if ( EVP_DecryptFinal_ex( ctx->dec_ctx, pt + plaintext_len, &len ) != 1 ) {
|
||||
return AE_INVALID;
|
||||
}
|
||||
plaintext_len += len;
|
||||
|
||||
+15
-10
@@ -47,41 +47,46 @@ static const char rdev[] = "/dev/urandom";
|
||||
|
||||
using namespace Crypto;
|
||||
|
||||
class PRNG {
|
||||
private:
|
||||
class PRNG
|
||||
{
|
||||
private:
|
||||
std::ifstream randfile;
|
||||
|
||||
/* unimplemented to satisfy -Weffc++ */
|
||||
PRNG( const PRNG & );
|
||||
PRNG & operator=( const PRNG & );
|
||||
PRNG( const PRNG& );
|
||||
PRNG& operator=( const PRNG& );
|
||||
|
||||
public:
|
||||
public:
|
||||
PRNG() : randfile( rdev, std::ifstream::in | std::ifstream::binary ) {}
|
||||
|
||||
void fill( void *dest, size_t size ) {
|
||||
void fill( void* dest, size_t size )
|
||||
{
|
||||
if ( 0 == size ) {
|
||||
return;
|
||||
}
|
||||
|
||||
randfile.read( static_cast<char *>( dest ), size );
|
||||
randfile.read( static_cast<char*>( dest ), size );
|
||||
if ( !randfile ) {
|
||||
throw CryptoException( "Could not read from " + std::string( rdev ) );
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t uint8() {
|
||||
uint8_t uint8()
|
||||
{
|
||||
uint8_t x;
|
||||
fill( &x, 1 );
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t uint32() {
|
||||
uint32_t uint32()
|
||||
{
|
||||
uint32_t x;
|
||||
fill( &x, 4 );
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t uint64() {
|
||||
uint64_t uint64()
|
||||
{
|
||||
uint64_t x;
|
||||
fill( &x, 8 );
|
||||
return x;
|
||||
|
||||
Reference in New Issue
Block a user