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:
Benjamin Barenblat
2023-08-07 21:53:48 -04:00
committed by Alex Chernyakhovsky
parent 0b15dc94fa
commit 3acaa1c4d3
77 changed files with 4838 additions and 4848 deletions
+28 -32
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;