mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/johanna/md5-fips'
* origin/topic/johanna/md5-fips: A few more updates to the digest functions. Tell OpenSSL that MD5 is not used for security in order to allow bro to work properly on a FIPS system I changed a couple places that looked like memory management pitfalls: moved some cleanup code into the dtors of HashVal derived classes (seemed like it got stuck in ctors by accident) and also added a cautionary cleanup in the MIME code. Plus minor formatting changes.
This commit is contained in:
commit
7a3ecd76b4
15 changed files with 228 additions and 145 deletions
6
CHANGES
6
CHANGES
|
@ -1,4 +1,10 @@
|
|||
|
||||
2.6-103 | 2019-01-24 17:09:05 -0600
|
||||
|
||||
* Change digest.h functions to use EVP_MD_CTX interface (Johanna Amann)
|
||||
|
||||
* Improve support for FIPS systems (Robert Clark)
|
||||
|
||||
2.6-98 | 2019-01-24 12:52:18 -0800
|
||||
|
||||
* Added ERSPAN III testing (Stu H)
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.6-98
|
||||
2.6-103
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
#include "bro-config.h"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include "EquivClass.h"
|
||||
#include "DFA.h"
|
||||
#include "digest.h"
|
||||
|
||||
unsigned int DFA_State::transition_counter = 0;
|
||||
|
||||
|
@ -337,7 +336,7 @@ DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas,
|
|||
// We use the short MD5 instead of the full string for the
|
||||
// HashKey because the data is copied into the key.
|
||||
u_char digest[16];
|
||||
MD5(id_tag, p - id_tag, digest);
|
||||
internal_md5(id_tag, p - id_tag, digest);
|
||||
|
||||
*hash = new HashKey(&digest, sizeof(digest));
|
||||
CacheEntry* e = states.Lookup(*hash);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "bro-config.h"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
|
@ -36,6 +35,7 @@
|
|||
#include "Var.h"
|
||||
#include "Reporter.h"
|
||||
#include "iosource/Manager.h"
|
||||
#include "digest.h"
|
||||
|
||||
extern "C" {
|
||||
extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||
|
@ -468,7 +468,7 @@ void DNS_Mgr::InitPostScript()
|
|||
static TableVal* fake_name_lookup_result(const char* name)
|
||||
{
|
||||
uint32 hash[4];
|
||||
MD5(reinterpret_cast<const u_char*>(name), strlen(name),
|
||||
internal_md5(reinterpret_cast<const u_char*>(name), strlen(name),
|
||||
reinterpret_cast<u_char*>(hash));
|
||||
ListVal* hv = new ListVal(TYPE_ADDR);
|
||||
hv->Append(new AddrVal(hash));
|
||||
|
|
172
src/OpaqueVal.cc
172
src/OpaqueVal.cc
|
@ -81,10 +81,15 @@ MD5Val::MD5Val() : HashVal(md5_type)
|
|||
{
|
||||
}
|
||||
|
||||
MD5Val::~MD5Val()
|
||||
{
|
||||
if ( IsValid() )
|
||||
EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
|
||||
void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH])
|
||||
{
|
||||
MD5_CTX h;
|
||||
md5_init(&h);
|
||||
EVP_MD_CTX* h = hash_init(Hash_MD5);
|
||||
|
||||
loop_over_list(vlist, i)
|
||||
{
|
||||
|
@ -92,17 +97,17 @@ void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH])
|
|||
if ( v->Type()->Tag() == TYPE_STRING )
|
||||
{
|
||||
const BroString* str = v->AsString();
|
||||
md5_update(&h, str->Bytes(), str->Len());
|
||||
hash_update(h, str->Bytes(), str->Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
ODesc d(DESC_BINARY);
|
||||
v->Describe(&d);
|
||||
md5_update(&h, (const u_char *) d.Bytes(), d.Len());
|
||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
||||
}
|
||||
}
|
||||
|
||||
md5_final(&h, result);
|
||||
hash_final(h, result);
|
||||
}
|
||||
|
||||
void MD5Val::hmac(val_list& vlist,
|
||||
|
@ -113,13 +118,13 @@ void MD5Val::hmac(val_list& vlist,
|
|||
for ( int i = 0; i < MD5_DIGEST_LENGTH; ++i )
|
||||
result[i] ^= key[i];
|
||||
|
||||
MD5(result, MD5_DIGEST_LENGTH, result);
|
||||
internal_md5(result, MD5_DIGEST_LENGTH, result);
|
||||
}
|
||||
|
||||
bool MD5Val::DoInit()
|
||||
{
|
||||
assert(! IsValid());
|
||||
md5_init(&ctx);
|
||||
ctx = hash_init(Hash_MD5);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -128,7 +133,7 @@ bool MD5Val::DoFeed(const void* data, size_t size)
|
|||
if ( ! IsValid() )
|
||||
return false;
|
||||
|
||||
md5_update(&ctx, data, size);
|
||||
hash_update(ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -138,7 +143,7 @@ StringVal* MD5Val::DoGet()
|
|||
return val_mgr->GetEmptyString();
|
||||
|
||||
u_char digest[MD5_DIGEST_LENGTH];
|
||||
md5_final(&ctx, digest);
|
||||
hash_final(ctx, digest);
|
||||
return new StringVal(md5_digest_print(digest));
|
||||
}
|
||||
|
||||
|
@ -151,21 +156,23 @@ bool MD5Val::DoSerialize(SerialInfo* info) const
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
if ( ! (SERIALIZE(ctx.A) &&
|
||||
SERIALIZE(ctx.B) &&
|
||||
SERIALIZE(ctx.C) &&
|
||||
SERIALIZE(ctx.D) &&
|
||||
SERIALIZE(ctx.Nl) &&
|
||||
SERIALIZE(ctx.Nh)) )
|
||||
MD5_CTX* md = (MD5_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if ( ! (SERIALIZE(md->A) &&
|
||||
SERIALIZE(md->B) &&
|
||||
SERIALIZE(md->C) &&
|
||||
SERIALIZE(md->D) &&
|
||||
SERIALIZE(md->Nl) &&
|
||||
SERIALIZE(md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < MD5_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! SERIALIZE(ctx.data[i]) )
|
||||
if ( ! SERIALIZE(md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! SERIALIZE(ctx.num) )
|
||||
if ( ! SERIALIZE(md->num) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -178,21 +185,24 @@ bool MD5Val::DoUnserialize(UnserialInfo* info)
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
if ( ! (UNSERIALIZE(&ctx.A) &&
|
||||
UNSERIALIZE(&ctx.B) &&
|
||||
UNSERIALIZE(&ctx.C) &&
|
||||
UNSERIALIZE(&ctx.D) &&
|
||||
UNSERIALIZE(&ctx.Nl) &&
|
||||
UNSERIALIZE(&ctx.Nh)) )
|
||||
ctx = hash_init(Hash_MD5);
|
||||
MD5_CTX* md = (MD5_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if ( ! (UNSERIALIZE(&md->A) &&
|
||||
UNSERIALIZE(&md->B) &&
|
||||
UNSERIALIZE(&md->C) &&
|
||||
UNSERIALIZE(&md->D) &&
|
||||
UNSERIALIZE(&md->Nl) &&
|
||||
UNSERIALIZE(&md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < MD5_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! UNSERIALIZE(&ctx.data[i]) )
|
||||
if ( ! UNSERIALIZE(&md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! UNSERIALIZE(&ctx.num) )
|
||||
if ( ! UNSERIALIZE(&md->num) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -202,10 +212,15 @@ SHA1Val::SHA1Val() : HashVal(sha1_type)
|
|||
{
|
||||
}
|
||||
|
||||
SHA1Val::~SHA1Val()
|
||||
{
|
||||
if ( IsValid() )
|
||||
EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
|
||||
void SHA1Val::digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH])
|
||||
{
|
||||
SHA_CTX h;
|
||||
sha1_init(&h);
|
||||
EVP_MD_CTX* h = hash_init(Hash_SHA1);
|
||||
|
||||
loop_over_list(vlist, i)
|
||||
{
|
||||
|
@ -213,23 +228,23 @@ void SHA1Val::digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH])
|
|||
if ( v->Type()->Tag() == TYPE_STRING )
|
||||
{
|
||||
const BroString* str = v->AsString();
|
||||
sha1_update(&h, str->Bytes(), str->Len());
|
||||
hash_update(h, str->Bytes(), str->Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
ODesc d(DESC_BINARY);
|
||||
v->Describe(&d);
|
||||
sha1_update(&h, (const u_char *) d.Bytes(), d.Len());
|
||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
||||
}
|
||||
}
|
||||
|
||||
sha1_final(&h, result);
|
||||
hash_final(h, result);
|
||||
}
|
||||
|
||||
bool SHA1Val::DoInit()
|
||||
{
|
||||
assert(! IsValid());
|
||||
sha1_init(&ctx);
|
||||
ctx = hash_init(Hash_SHA1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -238,7 +253,7 @@ bool SHA1Val::DoFeed(const void* data, size_t size)
|
|||
if ( ! IsValid() )
|
||||
return false;
|
||||
|
||||
sha1_update(&ctx, data, size);
|
||||
hash_update(ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -248,7 +263,7 @@ StringVal* SHA1Val::DoGet()
|
|||
return val_mgr->GetEmptyString();
|
||||
|
||||
u_char digest[SHA_DIGEST_LENGTH];
|
||||
sha1_final(&ctx, digest);
|
||||
hash_final(ctx, digest);
|
||||
return new StringVal(sha1_digest_print(digest));
|
||||
}
|
||||
|
||||
|
@ -261,22 +276,24 @@ bool SHA1Val::DoSerialize(SerialInfo* info) const
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
if ( ! (SERIALIZE(ctx.h0) &&
|
||||
SERIALIZE(ctx.h1) &&
|
||||
SERIALIZE(ctx.h2) &&
|
||||
SERIALIZE(ctx.h3) &&
|
||||
SERIALIZE(ctx.h4) &&
|
||||
SERIALIZE(ctx.Nl) &&
|
||||
SERIALIZE(ctx.Nh)) )
|
||||
SHA_CTX* md = (SHA_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if ( ! (SERIALIZE(md->h0) &&
|
||||
SERIALIZE(md->h1) &&
|
||||
SERIALIZE(md->h2) &&
|
||||
SERIALIZE(md->h3) &&
|
||||
SERIALIZE(md->h4) &&
|
||||
SERIALIZE(md->Nl) &&
|
||||
SERIALIZE(md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < SHA_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! SERIALIZE(ctx.data[i]) )
|
||||
if ( ! SERIALIZE(md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! SERIALIZE(ctx.num) )
|
||||
if ( ! SERIALIZE(md->num) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -289,22 +306,25 @@ bool SHA1Val::DoUnserialize(UnserialInfo* info)
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
if ( ! (UNSERIALIZE(&ctx.h0) &&
|
||||
UNSERIALIZE(&ctx.h1) &&
|
||||
UNSERIALIZE(&ctx.h2) &&
|
||||
UNSERIALIZE(&ctx.h3) &&
|
||||
UNSERIALIZE(&ctx.h4) &&
|
||||
UNSERIALIZE(&ctx.Nl) &&
|
||||
UNSERIALIZE(&ctx.Nh)) )
|
||||
ctx = hash_init(Hash_SHA1);
|
||||
SHA_CTX* md = (SHA_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if ( ! (UNSERIALIZE(&md->h0) &&
|
||||
UNSERIALIZE(&md->h1) &&
|
||||
UNSERIALIZE(&md->h2) &&
|
||||
UNSERIALIZE(&md->h3) &&
|
||||
UNSERIALIZE(&md->h4) &&
|
||||
UNSERIALIZE(&md->Nl) &&
|
||||
UNSERIALIZE(&md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < SHA_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! UNSERIALIZE(&ctx.data[i]) )
|
||||
if ( ! UNSERIALIZE(&md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! UNSERIALIZE(&ctx.num) )
|
||||
if ( ! UNSERIALIZE(&md->num) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -314,10 +334,15 @@ SHA256Val::SHA256Val() : HashVal(sha256_type)
|
|||
{
|
||||
}
|
||||
|
||||
SHA256Val::~SHA256Val()
|
||||
{
|
||||
if ( IsValid() )
|
||||
EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
|
||||
void SHA256Val::digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH])
|
||||
{
|
||||
SHA256_CTX h;
|
||||
sha256_init(&h);
|
||||
EVP_MD_CTX* h = hash_init(Hash_SHA256);
|
||||
|
||||
loop_over_list(vlist, i)
|
||||
{
|
||||
|
@ -325,23 +350,23 @@ void SHA256Val::digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH])
|
|||
if ( v->Type()->Tag() == TYPE_STRING )
|
||||
{
|
||||
const BroString* str = v->AsString();
|
||||
sha256_update(&h, str->Bytes(), str->Len());
|
||||
hash_update(h, str->Bytes(), str->Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
ODesc d(DESC_BINARY);
|
||||
v->Describe(&d);
|
||||
sha256_update(&h, (const u_char *) d.Bytes(), d.Len());
|
||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
||||
}
|
||||
}
|
||||
|
||||
sha256_final(&h, result);
|
||||
hash_final(h, result);
|
||||
}
|
||||
|
||||
bool SHA256Val::DoInit()
|
||||
{
|
||||
assert( ! IsValid() );
|
||||
sha256_init(&ctx);
|
||||
ctx = hash_init(Hash_SHA256);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -350,7 +375,7 @@ bool SHA256Val::DoFeed(const void* data, size_t size)
|
|||
if ( ! IsValid() )
|
||||
return false;
|
||||
|
||||
sha256_update(&ctx, data, size);
|
||||
hash_update(ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -360,7 +385,7 @@ StringVal* SHA256Val::DoGet()
|
|||
return val_mgr->GetEmptyString();
|
||||
|
||||
u_char digest[SHA256_DIGEST_LENGTH];
|
||||
sha256_final(&ctx, digest);
|
||||
hash_final(ctx, digest);
|
||||
return new StringVal(sha256_digest_print(digest));
|
||||
}
|
||||
|
||||
|
@ -373,24 +398,26 @@ bool SHA256Val::DoSerialize(SerialInfo* info) const
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
SHA256_CTX* md = (SHA256_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
for ( int i = 0; i < 8; ++i )
|
||||
{
|
||||
if ( ! SERIALIZE(ctx.h[i]) )
|
||||
if ( ! SERIALIZE(md->h[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! (SERIALIZE(ctx.Nl) &&
|
||||
SERIALIZE(ctx.Nh)) )
|
||||
if ( ! (SERIALIZE(md->Nl) &&
|
||||
SERIALIZE(md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < SHA_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! SERIALIZE(ctx.data[i]) )
|
||||
if ( ! SERIALIZE(md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! (SERIALIZE(ctx.num) &&
|
||||
SERIALIZE(ctx.md_len)) )
|
||||
if ( ! (SERIALIZE(md->num) &&
|
||||
SERIALIZE(md->md_len)) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -403,25 +430,28 @@ bool SHA256Val::DoUnserialize(UnserialInfo* info)
|
|||
if ( ! IsValid() )
|
||||
return true;
|
||||
|
||||
ctx = hash_init(Hash_SHA256);
|
||||
SHA256_CTX* md = (SHA256_CTX*) EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
for ( int i = 0; i < 8; ++i )
|
||||
{
|
||||
if ( ! UNSERIALIZE(&ctx.h[i]) )
|
||||
if ( ! UNSERIALIZE(&md->h[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! (UNSERIALIZE(&ctx.Nl) &&
|
||||
UNSERIALIZE(&ctx.Nh)) )
|
||||
if ( ! (UNSERIALIZE(&md->Nl) &&
|
||||
UNSERIALIZE(&md->Nh)) )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < SHA_LBLOCK; ++i )
|
||||
{
|
||||
if ( ! UNSERIALIZE(&ctx.data[i]) )
|
||||
if ( ! UNSERIALIZE(&md->data[i]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ( ! (UNSERIALIZE(&ctx.num) &&
|
||||
UNSERIALIZE(&ctx.md_len)) )
|
||||
if ( ! (UNSERIALIZE(&md->num) &&
|
||||
UNSERIALIZE(&md->md_len)) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
u_char result[MD5_DIGEST_LENGTH]);
|
||||
|
||||
MD5Val();
|
||||
~MD5Val();
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
@ -56,7 +57,7 @@ protected:
|
|||
DECLARE_SERIAL(MD5Val);
|
||||
|
||||
private:
|
||||
MD5_CTX ctx;
|
||||
EVP_MD_CTX* ctx;
|
||||
};
|
||||
|
||||
class SHA1Val : public HashVal {
|
||||
|
@ -64,6 +65,7 @@ public:
|
|||
static void digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH]);
|
||||
|
||||
SHA1Val();
|
||||
~SHA1Val();
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
@ -75,7 +77,7 @@ protected:
|
|||
DECLARE_SERIAL(SHA1Val);
|
||||
|
||||
private:
|
||||
SHA_CTX ctx;
|
||||
EVP_MD_CTX* ctx;
|
||||
};
|
||||
|
||||
class SHA256Val : public HashVal {
|
||||
|
@ -83,6 +85,7 @@ public:
|
|||
static void digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH]);
|
||||
|
||||
SHA256Val();
|
||||
~SHA256Val();
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
@ -94,7 +97,7 @@ protected:
|
|||
DECLARE_SERIAL(SHA256Val);
|
||||
|
||||
private:
|
||||
SHA256_CTX ctx;
|
||||
EVP_MD_CTX* ctx;
|
||||
};
|
||||
|
||||
class EntropyVal : public OpaqueVal {
|
||||
|
|
|
@ -1310,7 +1310,7 @@ TableVal* MIME_Message::BuildHeaderTable(MIME_HeaderList& hlist)
|
|||
}
|
||||
|
||||
MIME_Mail::MIME_Mail(analyzer::Analyzer* mail_analyzer, bool orig, int buf_size)
|
||||
: MIME_Message(mail_analyzer), md5_hash()
|
||||
: MIME_Message(mail_analyzer), md5_hash()
|
||||
{
|
||||
analyzer = mail_analyzer;
|
||||
|
||||
|
@ -1335,7 +1335,7 @@ MIME_Mail::MIME_Mail(analyzer::Analyzer* mail_analyzer, bool orig, int buf_size)
|
|||
if ( mime_content_hash )
|
||||
{
|
||||
compute_content_hash = 1;
|
||||
md5_init(&md5_hash);
|
||||
md5_hash = hash_init(Hash_MD5);
|
||||
}
|
||||
else
|
||||
compute_content_hash = 0;
|
||||
|
@ -1355,7 +1355,8 @@ void MIME_Mail::Done()
|
|||
if ( compute_content_hash && mime_content_hash )
|
||||
{
|
||||
u_char* digest = new u_char[16];
|
||||
md5_final(&md5_hash, digest);
|
||||
hash_final(md5_hash, digest);
|
||||
md5_hash = nullptr;
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(analyzer->BuildConnVal());
|
||||
|
@ -1371,6 +1372,9 @@ void MIME_Mail::Done()
|
|||
|
||||
MIME_Mail::~MIME_Mail()
|
||||
{
|
||||
if ( md5_hash )
|
||||
EVP_MD_CTX_free(md5_hash);
|
||||
|
||||
delete_strings(all_content);
|
||||
delete data_buffer;
|
||||
delete top_level;
|
||||
|
@ -1456,7 +1460,7 @@ void MIME_Mail::SubmitData(int len, const char* buf)
|
|||
if ( compute_content_hash )
|
||||
{
|
||||
content_hash_length += len;
|
||||
md5_update(&md5_hash, (const u_char*) buf, len);
|
||||
hash_update(md5_hash, (const u_char*) buf, len);
|
||||
}
|
||||
|
||||
if ( mime_entity_data || mime_all_data )
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define ANALYZER_PROTOCOL_MIME_MIME_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
@ -252,7 +252,7 @@ protected:
|
|||
int data_start;
|
||||
int compute_content_hash;
|
||||
int content_hash_length;
|
||||
MD5_CTX md5_hash;
|
||||
EVP_MD_CTX* md5_hash;
|
||||
vector<const BroString*> entity_content;
|
||||
vector<const BroString*> all_content;
|
||||
|
||||
|
|
105
src/digest.h
105
src/digest.h
|
@ -9,9 +9,22 @@
|
|||
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
|
||||
inline void* EVP_MD_CTX_md_data(const EVP_MD_CTX* ctx)
|
||||
{
|
||||
return ctx->md_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "Reporter.h"
|
||||
|
||||
enum HashAlgorithm { Hash_MD5, Hash_SHA1, Hash_SHA224, Hash_SHA256, Hash_SHA384, Hash_SHA512 };
|
||||
|
||||
inline const char* digest_print(const u_char* digest, size_t n)
|
||||
{
|
||||
static char buf[256]; // big enough for any of md5/sha1/sha256
|
||||
|
@ -35,58 +48,70 @@ inline const char* sha256_digest_print(const u_char digest[SHA256_DIGEST_LENGTH]
|
|||
return digest_print(digest, SHA256_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
inline void md5_init(MD5_CTX* c)
|
||||
inline EVP_MD_CTX* hash_init(HashAlgorithm alg)
|
||||
{
|
||||
if ( ! MD5_Init(c) )
|
||||
reporter->InternalError("MD5_Init failed");
|
||||
EVP_MD_CTX* c = EVP_MD_CTX_new();
|
||||
const EVP_MD* md;
|
||||
|
||||
switch (alg)
|
||||
{
|
||||
case Hash_MD5:
|
||||
#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
|
||||
/* Allow this to work even if FIPS disables it */
|
||||
EVP_MD_CTX_set_flags(c, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
#endif
|
||||
md = EVP_md5();
|
||||
break;
|
||||
case Hash_SHA1:
|
||||
md = EVP_sha1();
|
||||
break;
|
||||
case Hash_SHA224:
|
||||
md = EVP_sha224();
|
||||
break;
|
||||
case Hash_SHA256:
|
||||
md = EVP_sha256();
|
||||
break;
|
||||
case Hash_SHA384:
|
||||
md = EVP_sha384();
|
||||
break;
|
||||
case Hash_SHA512:
|
||||
md = EVP_sha512();
|
||||
break;
|
||||
default:
|
||||
reporter->InternalError("Unknown hash algorithm passed to hash_init");
|
||||
}
|
||||
|
||||
if ( ! EVP_DigestInit_ex(c, md, NULL) )
|
||||
reporter->InternalError("EVP_DigestInit failed");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
inline void md5_update(MD5_CTX* c, const void* data, unsigned long len)
|
||||
inline void hash_update(EVP_MD_CTX* c, const void* data, unsigned long len)
|
||||
{
|
||||
if ( ! MD5_Update(c, data, len) )
|
||||
reporter->InternalError("MD5_Update failed");
|
||||
if ( ! EVP_DigestUpdate(c, data, len) )
|
||||
reporter->InternalError("EVP_DigestUpdate failed");
|
||||
}
|
||||
|
||||
inline void md5_final(MD5_CTX* c, u_char md[MD5_DIGEST_LENGTH])
|
||||
inline void hash_final(EVP_MD_CTX* c, u_char* md)
|
||||
{
|
||||
if ( ! MD5_Final(md, c) )
|
||||
reporter->InternalError("MD5_Final failed");
|
||||
if ( ! EVP_DigestFinal(c, md, NULL) )
|
||||
reporter->InternalError("EVP_DigestFinal failed");
|
||||
|
||||
EVP_MD_CTX_free(c);
|
||||
}
|
||||
|
||||
inline void sha1_init(SHA_CTX* c)
|
||||
inline unsigned char* internal_md5(const unsigned char* data, unsigned long len, unsigned char* out)
|
||||
{
|
||||
if ( ! SHA1_Init(c) )
|
||||
reporter->InternalError("SHA_Init failed");
|
||||
}
|
||||
static unsigned char static_out[MD5_DIGEST_LENGTH];
|
||||
|
||||
inline void sha1_update(SHA_CTX* c, const void* data, unsigned long len)
|
||||
{
|
||||
if ( ! SHA1_Update(c, data, len) )
|
||||
reporter->InternalError("SHA_Update failed");
|
||||
}
|
||||
if ( ! out )
|
||||
out = static_out; // use static array for return, see OpenSSL man page
|
||||
|
||||
inline void sha1_final(SHA_CTX* c, u_char md[SHA_DIGEST_LENGTH])
|
||||
{
|
||||
if ( ! SHA1_Final(md, c) )
|
||||
reporter->InternalError("SHA_Final failed");
|
||||
}
|
||||
|
||||
inline void sha256_init(SHA256_CTX* c)
|
||||
{
|
||||
if ( ! SHA256_Init(c) )
|
||||
reporter->InternalError("SHA256_Init failed");
|
||||
}
|
||||
|
||||
inline void sha256_update(SHA256_CTX* c, const void* data, unsigned long len)
|
||||
{
|
||||
if ( ! SHA256_Update(c, data, len) )
|
||||
reporter->InternalError("SHA256_Update failed");
|
||||
}
|
||||
|
||||
inline void sha256_final(SHA256_CTX* c, u_char md[SHA256_DIGEST_LENGTH])
|
||||
{
|
||||
if ( ! SHA256_Final(md, c) )
|
||||
reporter->InternalError("SHA256_Final failed");
|
||||
EVP_MD_CTX* c = hash_init(Hash_MD5);
|
||||
hash_update(c, data, len);
|
||||
hash_final(c, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif //bro_digest_h
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Var.h"
|
||||
#include "Event.h"
|
||||
#include "UID.h"
|
||||
#include "digest.h"
|
||||
|
||||
#include "plugin/Manager.h"
|
||||
#include "analyzer/Manager.h"
|
||||
|
@ -93,7 +94,7 @@ string Manager::HashHandle(const string& handle) const
|
|||
uint64 hash[2];
|
||||
string msg(handle + salt);
|
||||
|
||||
MD5(reinterpret_cast<const u_char*>(msg.data()), msg.size(),
|
||||
internal_md5(reinterpret_cast<const u_char*>(msg.data()), msg.size(),
|
||||
reinterpret_cast<u_char*>(hash));
|
||||
|
||||
return Bro::UID(bits_per_uid, hash, 2).Base62("F");
|
||||
|
|
|
@ -496,13 +496,12 @@ uint64 BitVector::Hash() const
|
|||
{
|
||||
u_char buf[SHA256_DIGEST_LENGTH];
|
||||
uint64 digest;
|
||||
SHA256_CTX ctx;
|
||||
sha256_init(&ctx);
|
||||
EVP_MD_CTX* ctx = hash_init(Hash_SHA256);
|
||||
|
||||
for ( size_type i = 0; i < Blocks(); ++i )
|
||||
sha256_update(&ctx, &bits[i], sizeof(bits[i]));
|
||||
hash_update(ctx, &bits[i], sizeof(bits[i]));
|
||||
|
||||
sha256_final(&ctx, buf);
|
||||
hash_final(ctx, buf);
|
||||
memcpy(&digest, buf, sizeof(digest)); // Use the first bytes as digest
|
||||
return digest;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <typeinfo>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "Hasher.h"
|
||||
#include "NetVar.h"
|
||||
|
@ -15,24 +15,23 @@ Hasher::seed_t Hasher::MakeSeed(const void* data, size_t size)
|
|||
{
|
||||
u_char buf[SHA256_DIGEST_LENGTH];
|
||||
seed_t tmpseed;
|
||||
SHA256_CTX ctx;
|
||||
sha256_init(&ctx);
|
||||
EVP_MD_CTX* ctx = hash_init(Hash_SHA256);
|
||||
|
||||
assert(sizeof(tmpseed) == 16);
|
||||
|
||||
if ( data )
|
||||
sha256_update(&ctx, data, size);
|
||||
hash_update(ctx, data, size);
|
||||
|
||||
else if ( global_hash_seed && global_hash_seed->Len() > 0 )
|
||||
sha256_update(&ctx, global_hash_seed->Bytes(), global_hash_seed->Len());
|
||||
hash_update(ctx, global_hash_seed->Bytes(), global_hash_seed->Len());
|
||||
|
||||
else
|
||||
{
|
||||
unsigned int first_seed = initial_seed();
|
||||
sha256_update(&ctx, &first_seed, sizeof(first_seed));
|
||||
hash_update(ctx, &first_seed, sizeof(first_seed));
|
||||
}
|
||||
|
||||
sha256_final(&ctx, buf);
|
||||
hash_final(ctx, buf);
|
||||
memcpy(&tmpseed, buf, sizeof(tmpseed)); // Use the first bytes as seed.
|
||||
return tmpseed;
|
||||
}
|
||||
|
@ -123,13 +122,13 @@ Hasher::digest UHF::hash(const void* x, size_t n) const
|
|||
Hasher::digest rval;
|
||||
} u;
|
||||
|
||||
MD5(reinterpret_cast<const unsigned char*>(x), n, u.d);
|
||||
internal_md5(reinterpret_cast<const unsigned char*>(x), n, u.d);
|
||||
|
||||
const unsigned char* s = reinterpret_cast<const unsigned char*>(&seed);
|
||||
for ( size_t i = 0; i < 16; ++i )
|
||||
u.d[i] ^= s[i % sizeof(seed)];
|
||||
|
||||
MD5(u.d, 16, u.d);
|
||||
internal_md5(u.d, 16, u.d);
|
||||
return u.rval;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "digest.h"
|
||||
#include "input.h"
|
||||
#include "util.h"
|
||||
#include "Obj.h"
|
||||
|
@ -712,12 +713,12 @@ void hmac_md5(size_t size, const unsigned char* bytes, unsigned char digest[16])
|
|||
if ( ! hmac_key_set )
|
||||
reporter->InternalError("HMAC-MD5 invoked before the HMAC key is set");
|
||||
|
||||
MD5(bytes, size, digest);
|
||||
internal_md5(bytes, size, digest);
|
||||
|
||||
for ( int i = 0; i < 16; ++i )
|
||||
digest[i] ^= shared_hmac_md5_key[i];
|
||||
|
||||
MD5(digest, 16, digest);
|
||||
internal_md5(digest, 16, digest);
|
||||
}
|
||||
|
||||
static bool read_random_seeds(const char* read_file, uint32* seed,
|
||||
|
@ -871,7 +872,7 @@ void init_random_seed(const char* read_file, const char* write_file)
|
|||
if ( ! hmac_key_set )
|
||||
{
|
||||
assert(sizeof(buf) - 16 == 64);
|
||||
MD5((const u_char*) buf, sizeof(buf) - 16, shared_hmac_md5_key); // The last 128 bits of buf are for siphash
|
||||
internal_md5((const u_char*) buf, sizeof(buf) - 16, shared_hmac_md5_key); // The last 128 bits of buf are for siphash
|
||||
hmac_key_set = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,4 +44,6 @@ three
|
|||
[zero, one, two]
|
||||
[s=abc]
|
||||
[c=123, r1=[s=xyz]]
|
||||
opaque of md5, T
|
||||
opaque of sha1, T
|
||||
opaque of sha256, T
|
||||
|
|
|
@ -57,6 +57,20 @@ event bro_init()
|
|||
print (Broker::data(R1($s="abc")) as R1);
|
||||
print (Broker::data(R2($c=123, $r1=R1($s="xyz"))) as R2);
|
||||
|
||||
local md5h1 = md5_hash_init();
|
||||
md5_hash_update(md5h1, "abc");
|
||||
local md5h2 = (Broker::data(md5h1) as opaque of md5);
|
||||
local md5s1 = md5_hash_finish(md5h1);
|
||||
local md5s2 = md5_hash_finish(md5h2);
|
||||
print "opaque of md5", md5s1 == md5s2;
|
||||
|
||||
local sha1h1 = sha1_hash_init();
|
||||
sha1_hash_update(sha1h1, "abc");
|
||||
local sha1h2 = (Broker::data(sha1h1) as opaque of sha1);
|
||||
local sha1s1 = sha1_hash_finish(sha1h1);
|
||||
local sha1s2 = sha1_hash_finish(sha1h2);
|
||||
print "opaque of sha1", sha1s1 == sha1s2;
|
||||
|
||||
local h1 = sha256_hash_init();
|
||||
sha256_hash_update(h1, "abc");
|
||||
local h2 = (Broker::data(h1) as opaque of sha256);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue