1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-31 20:09:02 +00:00

Add compatibility with LibreSSL. Closes #543

This commit is contained in:
dmiller
2016-09-09 14:08:48 +00:00
parent f607178541
commit 182bcf8c1c
5 changed files with 193 additions and 178 deletions

View File

@@ -130,8 +130,13 @@
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined LIBRESSL_VERSION_NUMBER
#define HAVE_OPAQUE_EVP_PKEY 1
#endif
#endif /* HAVE_OPENSSL */
extern NpingOps o;
Crypto::Crypto(){
@@ -178,23 +183,7 @@ int Crypto::aes128_cbc_encrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
#ifdef HAVE_OPENSSL
if( o.doCrypto() ){
int flen=0, flen2=0;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_EncryptInit() failed");
result=OP_FAILURE;
}else if( EVP_EncryptUpdate(&ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_EncryptFinal(&ctx, dst_buff+flen, &flen2)==0 ){
nping_print(DBG_4, "EVP_EncryptFinal() failed");
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(&ctx);
#else
#if HAVE_OPAQUE_EVP_PKEY
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_reset(ctx);
EVP_CIPHER_CTX_set_padding(ctx, 0);
@@ -210,6 +199,22 @@ int Crypto::aes128_cbc_encrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(ctx);
#else
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_EncryptInit() failed");
result=OP_FAILURE;
}else if( EVP_EncryptUpdate(&ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_EncryptFinal(&ctx, dst_buff+flen, &flen2)==0 ){
nping_print(DBG_4, "EVP_EncryptFinal() failed");
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(&ctx);
#endif
return result;
}
@@ -231,21 +236,7 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
#ifdef HAVE_OPENSSL
if( o.doCrypto() ){
int flen1=0, flen2=0;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_DecryptInit() failed");
result=OP_FAILURE;
}else if( EVP_DecryptUpdate(&ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_DecryptFinal(&ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#else
#if HAVE_OPAQUE_EVP_PKEY
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_reset(ctx);
EVP_CIPHER_CTX_set_padding(ctx, 0);
@@ -259,6 +250,20 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
}else if( EVP_DecryptFinal(ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#else
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_DecryptInit() failed");
result=OP_FAILURE;
}else if( EVP_DecryptUpdate(&ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_DecryptFinal(&ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#endif
/* We do not return OP_FAILURE in this case because the
* EVP_DecryptFinal() function seems to be buggy and fails when it shouldn't.
@@ -286,10 +291,10 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
//ERR_free_strings();
//ERR_pop_to_mark();
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX_cleanup(&ctx);
#else
#if HAVE_OPAQUE_EVP_PKEY
EVP_CIPHER_CTX_reset(ctx);
#else
EVP_CIPHER_CTX_cleanup(&ctx);
#endif
return result;
}
@@ -327,31 +332,7 @@ u8 *Crypto::deriveKey(const u8 *from, size_t fromlen, size_t *final_len){
static u8 hash[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
static u8 next[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
unsigned int lastlen;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if( EVP_MD_size(EVP_sha256()) != SHA256_HASH_LEN )
nping_fatal(QT_2, "OpenSSL is broken. SHA256 len is %d\n", EVP_MD_size(EVP_sha256()) );
/* Compute the SHA256 hash of the supplied buffer */
EVP_DigestInit(&ctx, EVP_sha256());
EVP_DigestUpdate(&ctx, from, fromlen);
EVP_DigestFinal(&ctx, hash, &lastlen);
/* Now compute the 1000th hash of that hash */
for(int i=0; i<TIMES_KEY_DERIVATION; i++){
EVP_MD_CTX_init(&ctx);
EVP_DigestInit(&ctx, EVP_sha256());
EVP_DigestUpdate(&ctx, hash, SHA256_HASH_LEN);
EVP_DigestFinal(&ctx, next, &lastlen);
memcpy(hash, next, SHA256_HASH_LEN);
}
if(final_len!=NULL)
*final_len=SHA256_HASH_LEN;
EVP_MD_CTX_cleanup(&ctx);
#else
#if HAVE_OPAQUE_EVP_PKEY
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_MD_CTX_init(ctx);
@@ -375,6 +356,30 @@ u8 *Crypto::deriveKey(const u8 *from, size_t fromlen, size_t *final_len){
*final_len=SHA256_HASH_LEN;
EVP_MD_CTX_free(ctx);
#else
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if( EVP_MD_size(EVP_sha256()) != SHA256_HASH_LEN )
nping_fatal(QT_2, "OpenSSL is broken. SHA256 len is %d\n", EVP_MD_size(EVP_sha256()) );
/* Compute the SHA256 hash of the supplied buffer */
EVP_DigestInit(&ctx, EVP_sha256());
EVP_DigestUpdate(&ctx, from, fromlen);
EVP_DigestFinal(&ctx, hash, &lastlen);
/* Now compute the 1000th hash of that hash */
for(int i=0; i<TIMES_KEY_DERIVATION; i++){
EVP_MD_CTX_init(&ctx);
EVP_DigestInit(&ctx, EVP_sha256());
EVP_DigestUpdate(&ctx, hash, SHA256_HASH_LEN);
EVP_DigestFinal(&ctx, next, &lastlen);
memcpy(hash, next, SHA256_HASH_LEN);
}
if(final_len!=NULL)
*final_len=SHA256_HASH_LEN;
EVP_MD_CTX_cleanup(&ctx);
#endif
return hash;
}