First pass at switching to AES256 GCM authenticated encryption
This commit is contained in:
@@ -550,7 +550,7 @@ ssize_t rlocs_encrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsign
|
||||
|
||||
// FIXME: I don't know that this is good. It could be terrible.
|
||||
// We use a PRNG to generate an IV per message, and put it at the start of
|
||||
// the encrypted blob. Since we're using aes256 (hardcoded), IV is 128 bits
|
||||
// the encrypted blob. Since we're using aes256 (hardcoded), IV is 128 bits.
|
||||
if ( dest_len < 48 ) {
|
||||
warn( "dest_len must be at least 48 bytes, maybe more");
|
||||
goto fail;
|
||||
@@ -558,20 +558,33 @@ ssize_t rlocs_encrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsign
|
||||
|
||||
unsigned char *iv = dest;
|
||||
unsigned char *secret = (unsigned char *)&entry->secret[0];
|
||||
|
||||
size_t written = 16;
|
||||
int outl = dest_len - written;
|
||||
|
||||
RAND_pseudo_bytes( iv, 16 );
|
||||
|
||||
if ( !EVP_EncryptInit_ex( &entry->ctx, EVP_aes_256_cbc(), NULL, secret, iv ) ) {
|
||||
warn( "EVP_EncryptInit_ex() failed" );
|
||||
if ( !EVP_EncryptInit_ex( &entry->ctx, EVP_aes_256_gcm(), NULL, NULL, NULL ) ) {
|
||||
warn( "EVP_EncryptInit_ex() (1) failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_CIPHER_CTX_ctrl( &entry->ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) {
|
||||
warn ("Setting IV len to 16 failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_EncryptInit_ex( &entry->ctx, NULL, NULL, secret, iv ) ) {
|
||||
warn( "EVP_EncryptInit_ex() (2) failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_EncryptUpdate( &entry->ctx, dest + written, &outl, data, data_len ) ) {
|
||||
warn( "EVP_EncryptUpdate() failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// TODO: Add the encapsulating IP header as AAD data?
|
||||
|
||||
written += outl;
|
||||
outl = dest_len - written;
|
||||
@@ -580,8 +593,16 @@ ssize_t rlocs_encrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsign
|
||||
warn( "EVP_EncryptFinal_ex() failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
written += outl;
|
||||
|
||||
/* Get the tag */
|
||||
if( !EVP_CIPHER_CTX_ctrl( &entry->ctx, EVP_CTRL_GCM_GET_TAG, 16, dest + written ) ) {
|
||||
warn( "Getting GCM tag for our encrypted data failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return written + outl;
|
||||
return written + 16;
|
||||
|
||||
fail:
|
||||
show_ssl_errors();
|
||||
@@ -599,15 +620,31 @@ ssize_t rlocs_decrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsign
|
||||
|
||||
unsigned char *iv = data;
|
||||
unsigned char *secret = (unsigned char *)&entry->secret[0];
|
||||
|
||||
size_t written = 0;
|
||||
int outl = dest_len;
|
||||
|
||||
if ( !EVP_DecryptInit_ex( &entry->ctx, EVP_aes_256_cbc(), NULL, secret, iv ) ) {
|
||||
warn( "EVP_DecrypttInit_ex() failed" );
|
||||
if ( data_len < 32 ) {
|
||||
warn( "data_len not large enough to contain tag and IV" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_DecryptUpdate( &entry->ctx, dest, &outl, data + 16, data_len - 16 ) ) {
|
||||
if ( !EVP_DecryptInit_ex( &entry->ctx, EVP_aes_256_gcm(), NULL, NULL, NULL ) ) {
|
||||
warn( "EVP_DecryptInit_ex() (1) failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_CIPHER_CTX_ctrl(&entry->ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) {
|
||||
warn ("Setting IV len to 16 failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_DecryptInit_ex( &entry->ctx, NULL, NULL, secret, iv ) ) {
|
||||
warn( "EVP_DecryptInit_ex() (2) failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_DecryptUpdate( &entry->ctx, dest, &outl, data + 16, data_len - 32 ) ) {
|
||||
warn( "EVP_DecryptUpdate() failed" );
|
||||
goto fail;
|
||||
}
|
||||
@@ -615,8 +652,13 @@ ssize_t rlocs_decrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsign
|
||||
written += outl;
|
||||
outl = dest_len - written;
|
||||
|
||||
if( !EVP_CIPHER_CTX_ctrl(&entry->ctx, EVP_CTRL_GCM_SET_TAG, 16, data + (data_len - 16 ) ) ) {
|
||||
warn( "Failed to provide GCM tag to decrypt routine" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( !EVP_DecryptFinal_ex( &entry->ctx, dest + written, &outl ) ) {
|
||||
warn( "EVP_DecryptFinal_ex() failed" );
|
||||
warn( "EVP_DecryptFinal_ex() failed - bad tag?" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user