diff --git a/pass-1/rlocs.c b/pass-1/rlocs.c index 52bdec7..9ae3bad 100644 --- a/pass-1/rlocs.c +++ b/pass-1/rlocs.c @@ -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; }