From f1c75cf6ef7e9f9de1ec7fd798df941b972ec71c Mon Sep 17 00:00:00 2001 From: Erik de Jong Date: Mon, 13 Feb 2017 19:31:26 +0100 Subject: Rewrite dissectors to use Libgcrypt functions. As discussed on the mailinglist, rewriting dissectors to use Libgcrypt functions as Libgcrypt will be mandatory after change 20030. Removal of following functions: - crypt_md4 - crypt_rc4* - aes_cmac_encrypt_* - md5_* - sha1_* - sha256_* Further candidates: - aes_* - rijndael_* - ... Added functions: - ws_hmac_buffer Added const macros: - HASH_MD5_LENGTH - HASH_SHA1_LENGTH Changes on epan/crypt/* verified with captures from https://wiki.wireshark.org/HowToDecrypt802.11 Changes on packet-snmp.c and packet-radius.c verified with captures from https://wiki.wireshark.org/SampleCapture Changes on packet-tacacs.c verified with capture from http://ccie-in-3-months.blogspot.nl/2009/04/decoding-login-credentials-regardless.html Change-Id: Iea6ba2bf207cf0f1bf2117068fb1abcfeaafaa46 Link: https://www.wireshark.org/lists/wireshark-dev/201702/msg00011.html Reviewed-on: https://code.wireshark.org/review/20095 Petri-Dish: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu --- CMakeLists.txt | 1 + Makefile.am | 3 +- debian/libwsutil0.symbols | 25 +- editcap.c | 14 +- epan/crypt/airpdcap.c | 166 +++++--- epan/crypt/airpdcap_ccmp.c | 63 +-- epan/crypt/airpdcap_rijndael.c | 19 +- epan/dissectors/asn1/cms/packet-cms-template.c | 30 +- .../asn1/kerberos/packet-kerberos-template.c | 28 +- epan/dissectors/asn1/snmp/packet-snmp-template.c | 66 +-- .../asn1/spnego/packet-spnego-template.c | 85 ++-- epan/dissectors/file-file.c | 1 - epan/dissectors/packet-3com-njack.c | 28 +- epan/dissectors/packet-cms.c | 42 +- epan/dissectors/packet-corosync-totemnet.c | 41 +- epan/dissectors/packet-data.c | 12 +- epan/dissectors/packet-dcerpc-netlogon.c | 102 +++-- epan/dissectors/packet-frame.c | 12 +- epan/dissectors/packet-kerberos.c | 40 +- epan/dissectors/packet-l2tp.c | 77 ++-- epan/dissectors/packet-ntlmssp.c | 326 +++++++-------- epan/dissectors/packet-radius.c | 53 ++- epan/dissectors/packet-sigcomp.c | 26 +- epan/dissectors/packet-snmp.c | 76 ++-- epan/dissectors/packet-spnego.c | 89 ++-- epan/dissectors/packet-tacacs.c | 26 +- epan/dissectors/packet-tcp.c | 13 +- wsutil/CMakeLists.txt | 6 +- wsutil/Makefile.am | 11 +- wsutil/md4.c | 185 --------- wsutil/md4.h | 29 -- wsutil/md5.c | 373 ----------------- wsutil/md5.h | 97 ----- wsutil/rc4.c | 112 ----- wsutil/rc4.h | 42 -- wsutil/sha1.c | 456 --------------------- wsutil/sha1.h | 69 ---- wsutil/sha2.c | 281 ------------- wsutil/sha2.h | 75 ---- wsutil/wsgcrypt.c | 57 +++ wsutil/wsgcrypt.h | 11 + 41 files changed, 831 insertions(+), 2437 deletions(-) delete mode 100644 wsutil/md4.c delete mode 100644 wsutil/md4.h delete mode 100644 wsutil/md5.c delete mode 100644 wsutil/md5.h delete mode 100644 wsutil/rc4.c delete mode 100644 wsutil/rc4.h delete mode 100644 wsutil/sha1.c delete mode 100644 wsutil/sha1.h delete mode 100644 wsutil/sha2.c delete mode 100644 wsutil/sha2.h create mode 100644 wsutil/wsgcrypt.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b2df5e31..7c12d6eedd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2459,6 +2459,7 @@ if(BUILD_editcap) set(editcap_LIBS wiretap ${ZLIB_LIBRARIES} + ${GCRYPT_LIBRARIES} ${CMAKE_DL_LIBS} ) set(editcap_FILES diff --git a/Makefile.am b/Makefile.am index a559e1b281..7708681cb5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -672,7 +672,8 @@ editcap_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS) editcap_LDADD = \ wiretap/libwiretap.la \ wsutil/libwsutil.la \ - @GLIB_LIBS@ + @GLIB_LIBS@ \ + @LIBGCRYPT_LIBS@ reordercap_SOURCES = \ reordercap.c \ diff --git a/debian/libwsutil0.symbols b/debian/libwsutil0.symbols index 204b14d6da..f17a4be127 100644 --- a/debian/libwsutil0.symbols +++ b/debian/libwsutil0.symbols @@ -43,9 +43,6 @@ libwsutil.so.0 libwsutil0 #MINVER# create_tempdir@Base 1.12.0~rc1 create_tempfile@Base 1.12.0~rc1 crypt_des_ecb@Base 1.12.0~rc1 - crypt_md4@Base 1.12.0~rc1 - crypt_rc4@Base 1.12.0~rc1 - crypt_rc4_init@Base 1.12.0~rc1 data_file_url@Base 2.3.0 delete_persconffile_profile@Base 1.12.0~rc1 file_exists@Base 1.12.0~rc1 @@ -95,13 +92,6 @@ libwsutil.so.0 libwsutil0 #MINVER# linear2ulaw@Base 1.12.0~rc1 local_interfaces_to_list@Base 2.1.2 log_resource_usage@Base 2.1.2 - md5_append@Base 1.12.0~rc1 - md5_finish@Base 1.12.0~rc1 - md5_hmac@Base 1.12.0~rc1 - md5_hmac_append@Base 1.12.0~rc1 - md5_hmac_finish@Base 1.12.0~rc1 - md5_hmac_init@Base 1.12.0~rc1 - md5_init@Base 1.12.0~rc1 mktime_utc@Base 1.12.0~rc1 mpa_bitrate@Base 1.10.0 mpa_frequency@Base 1.10.0 @@ -141,20 +131,6 @@ libwsutil.so.0 libwsutil0 #MINVER# set_persconffile_dir@Base 1.12.0~rc1 set_persdatafile_dir@Base 1.12.0~rc1 set_profile_name@Base 1.12.0~rc1 - sha1_finish@Base 1.12.0~rc1 - sha1_hmac@Base 1.12.0~rc1 - sha1_hmac_finish@Base 1.12.0~rc1 - sha1_hmac_starts@Base 1.12.0~rc1 - sha1_hmac_update@Base 1.12.0~rc1 - sha1_starts@Base 1.12.0~rc1 - sha1_update@Base 1.12.0~rc1 - sha256_finish@Base 2.1.0 - sha256_hmac@Base 2.1.0 - sha256_hmac_finish@Base 2.1.0 - sha256_hmac_starts@Base 2.1.0 - sha256_hmac_update@Base 2.1.0 - sha256_starts@Base 2.1.0 - sha256_update@Base 2.1.0 sober128_add_entropy@Base 1.99.0 sober128_read@Base 1.99.0 sober128_start@Base 1.99.0 @@ -182,6 +158,7 @@ libwsutil.so.0 libwsutil0 #MINVER# ws_hexstrtou32@Base 2.3.0 ws_hexstrtou64@Base 2.3.0 ws_hexstrtou8@Base 2.3.0 + ws_hmac_buffer@Base 2.3.0 ws_inet_ntop4@Base 2.1.2 ws_inet_ntop6@Base 2.1.2 ws_inet_pton4@Base 2.1.2 diff --git a/editcap.c b/editcap.c index 712ce0fb07..adca86c037 100644 --- a/editcap.c +++ b/editcap.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #include #include #include @@ -113,7 +113,7 @@ struct select_item { * Duplicate frame detection */ typedef struct _fd_hash_t { - md5_byte_t digest[16]; + guint8 digest[16]; guint32 len; nstime_t frame_time; } fd_hash_t; @@ -587,7 +587,6 @@ remove_vlan_info(const struct wtap_pkthdr *phdr, guint8* fd, guint32* len) { static gboolean is_duplicate(guint8* fd, guint32 len) { int i; - md5_state_t ms; /*Hint to ignore some bytes at the start of the frame for the digest calculation(-I option) */ guint32 offset = ignored_bytes; @@ -606,9 +605,7 @@ is_duplicate(guint8* fd, guint32 len) { cur_dup_entry = 0; /* Calculate our digest */ - md5_init(&ms); - md5_append(&ms, new_fd, new_len); - md5_finish(&ms, fd_hash[cur_dup_entry].digest); + gcry_md_hash_buffer(GCRY_MD_MD5, fd_hash[cur_dup_entry].digest, new_fd, new_len); fd_hash[cur_dup_entry].len = len; @@ -629,7 +626,6 @@ is_duplicate(guint8* fd, guint32 len) { static gboolean is_duplicate_rel_time(guint8* fd, guint32 len, const nstime_t *current) { int i; - md5_state_t ms; /*Hint to ignore some bytes at the start of the frame for the digest calculation(-I option) */ guint32 offset = ignored_bytes; @@ -648,9 +644,7 @@ is_duplicate_rel_time(guint8* fd, guint32 len, const nstime_t *current) { cur_dup_entry = 0; /* Calculate our digest */ - md5_init(&ms); - md5_append(&ms, new_fd, new_len); - md5_finish(&ms, fd_hash[cur_dup_entry].digest); + gcry_md_hash_buffer(GCRY_MD_MD5, fd_hash[cur_dup_entry].digest, new_fd, new_len); fd_hash[cur_dup_entry].len = len; fd_hash[cur_dup_entry].frame_time.secs = current->secs; diff --git a/epan/crypt/airpdcap.c b/epan/crypt/airpdcap.c index b1f5bdcc3e..fa5fe978f1 100644 --- a/epan/crypt/airpdcap.c +++ b/epan/crypt/airpdcap.c @@ -46,13 +46,9 @@ #include +#include #include -#include -#include -#include -#include #include -#include #include #include @@ -379,12 +375,12 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption_ if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){ guint8 new_key[32]; - guint8 dummy[256]; + guint8 dummy[256] = { 0 }; /* TKIP key */ /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */ /* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */ - rc4_state_struct rc4_state; + gcry_cipher_hd_t rc4_handle; /* The WPA group key just contains the GTK bytes so deducing the type is straightforward */ /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */ @@ -395,11 +391,18 @@ AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8 *decryption_ memcpy(new_key+16, decryption_key, 16); DEBUG_DUMP("FullDecrKey:", new_key, 32); - crypt_rc4_init(&rc4_state, new_key, sizeof(new_key)); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return AIRPDCAP_RET_NO_VALID_HANDSHAKE; + } + if (gcry_cipher_setkey(rc4_handle, new_key, sizeof(new_key))) { + gcry_cipher_close(rc4_handle); + return AIRPDCAP_RET_NO_VALID_HANDSHAKE; + } /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */ - crypt_rc4(&rc4_state, dummy, 256); - crypt_rc4(&rc4_state, szEncryptedKey, key_bytes_len); + gcry_cipher_decrypt(rc4_handle, dummy, 256, NULL, 0); + gcry_cipher_decrypt(rc4_handle, szEncryptedKey, key_bytes_len, NULL, 0); + gcry_cipher_close(rc4_handle); } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){ /* AES CCMP key */ @@ -1536,7 +1539,8 @@ AirPDcapRsnaMicCheck( USHORT key_ver) { UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN]; - UCHAR c_mic[20]; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */ + UCHAR c_mic[HASH_SHA1_LENGTH] = { 0 }; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */ + int algo; /* copy the MIC from the EAPOL packet */ memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN); @@ -1546,13 +1550,18 @@ AirPDcapRsnaMicCheck( if (key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP) { /* use HMAC-MD5 for the EAPOL-Key MIC */ - md5_hmac(eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN, c_mic); + algo = GCRY_MD_MD5; } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) { /* use HMAC-SHA1-128 for the EAPOL-Key MIC */ - sha1_hmac(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic); - } else + algo = GCRY_MD_SHA1; + } else { /* key descriptor version not recognized */ return AIRPDCAP_RET_UNSUCCESS; + } + + if (ws_hmac_buffer(algo, c_mic, eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN)) { + return AIRPDCAP_RET_UNSUCCESS; + } /* compare calculated MIC with the Key MIC and return result (0 means success) */ return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN); @@ -1856,7 +1865,9 @@ AirPDcapRsnaPrfX( for(i = 0; i < (x+159)/160; i++) { R[offset] = i; - sha1_hmac(pmk, 32, R, 100, &output[20 * i]); + if (ws_hmac_buffer(GCRY_MD_SHA1, &output[HASH_SHA1_LENGTH * i], R, 100, pmk, 32)) { + return; + } } memcpy(ptk, output, x/8); } @@ -1873,8 +1884,7 @@ AirPDcapRsnaPwd2PskStep( const INT count, UCHAR *output) { - UCHAR digest[MAX_SSID_LENGTH+4]; /* SSID plus 4 bytes of count */ - UCHAR digest1[SHA1_DIGEST_LEN]; + UCHAR digest[MAX_SSID_LENGTH+4] = { 0 }; /* SSID plus 4 bytes of count */ INT i, j; if (ssidLength > MAX_SSID_LENGTH) { @@ -1882,26 +1892,26 @@ AirPDcapRsnaPwd2PskStep( return AIRPDCAP_RET_UNSUCCESS; } - memset(digest, 0, sizeof digest); - memset(digest1, 0, sizeof digest1); - /* U1 = PRF(P, S || INT(i)) */ memcpy(digest, ssid, ssidLength); digest[ssidLength] = (UCHAR)((count>>24) & 0xff); digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff); digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff); digest[ssidLength+3] = (UCHAR)(count & 0xff); - sha1_hmac(ppBytes, ppLength, digest, (guint32) ssidLength+4, digest1); + if (ws_hmac_buffer(GCRY_MD_SHA1, digest, digest, (guint32) ssidLength + 4, ppBytes, ppLength)) { + return AIRPDCAP_RET_UNSUCCESS; + } /* output = U1 */ - memcpy(output, digest1, SHA1_DIGEST_LEN); + memcpy(output, digest, 20); for (i = 1; i < iterations; i++) { /* Un = PRF(P, Un-1) */ - sha1_hmac(ppBytes, ppLength, digest1, SHA1_DIGEST_LEN, digest); + if (ws_hmac_buffer(GCRY_MD_SHA1, digest, digest, HASH_SHA1_LENGTH, ppBytes, ppLength)) { + return AIRPDCAP_RET_UNSUCCESS; + } - memcpy(digest1, digest, SHA1_DIGEST_LEN); /* output = output xor Un */ - for (j = 0; j < SHA1_DIGEST_LEN; j++) { + for (j = 0; j < 20; j++) { output[j] ^= digest[j]; } } @@ -1916,18 +1926,16 @@ AirPDcapRsnaPwd2Psk( const size_t ssidLength, UCHAR *output) { - UCHAR m_output[2*SHA1_DIGEST_LEN]; + UCHAR m_output[40] = { 0 }; GByteArray *pp_ba = g_byte_array_new(); - memset(m_output, 0, 2*SHA1_DIGEST_LEN); - if (!uri_str_to_bytes(passphrase, pp_ba)) { g_byte_array_free(pp_ba, TRUE); return 0; } AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output); - AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[SHA1_DIGEST_LEN]); + AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[20]); memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN); g_byte_array_free(pp_ba, TRUE); @@ -2174,66 +2182,88 @@ AirPDcapTDLSDeriveKey( guint8 action) { - sha256_hmac_context sha_ctx; - aes_cmac_ctx aes_ctx; + gcry_md_hd_t sha256_handle; + gcry_md_hd_t hmac_handle; const guint8 *snonce, *anonce, *initiator, *responder, *bssid; - guint8 key_input[SHA256_DIGEST_LEN]; - guint8 mic[16], iter[2], length[2], seq_num = action + 1; + guint8 key_input[32]; + guint8 mic[16], seq_num = action + 1; +#if GCRYPT_VERSION_NUMBER >= 0x010600 + guint8 zeros[16] = { 0 }; + gcry_mac_hd_t cmac_handle; + size_t cmac_len = 16; +#endif /* Get key input */ anonce = &data[offset_fte + 20]; snonce = &data[offset_fte + 52]; - sha256_starts(&(sha_ctx.ctx)); + + gcry_md_open (&sha256_handle, GCRY_MD_SHA256, 0); if (memcmp(anonce, snonce, AIRPDCAP_WPA_NONCE_LEN) < 0) { - sha256_update(&(sha_ctx.ctx), anonce, AIRPDCAP_WPA_NONCE_LEN); - sha256_update(&(sha_ctx.ctx), snonce, AIRPDCAP_WPA_NONCE_LEN); + gcry_md_write(sha256_handle, anonce, AIRPDCAP_WPA_NONCE_LEN); + gcry_md_write(sha256_handle, snonce, AIRPDCAP_WPA_NONCE_LEN); } else { - sha256_update(&(sha_ctx.ctx), snonce, AIRPDCAP_WPA_NONCE_LEN); - sha256_update(&(sha_ctx.ctx), anonce, AIRPDCAP_WPA_NONCE_LEN); + gcry_md_write(sha256_handle, snonce, AIRPDCAP_WPA_NONCE_LEN); + gcry_md_write(sha256_handle, anonce, AIRPDCAP_WPA_NONCE_LEN); } - sha256_finish(&(sha_ctx.ctx), key_input); + memcpy(key_input, gcry_md_read(sha256_handle, 0), 32); + gcry_md_close(sha256_handle); /* Derive key */ bssid = &data[offset_link + 2]; initiator = &data[offset_link + 8]; responder = &data[offset_link + 14]; - sha256_hmac_starts(&sha_ctx, key_input, SHA256_DIGEST_LEN); - iter[0] = 1; - iter[1] = 0; - sha256_hmac_update(&sha_ctx, (const guint8 *)&iter, 2); - sha256_hmac_update(&sha_ctx, "TDLS PMK", 8); + if (gcry_md_open(&hmac_handle, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC)) { + return AIRPDCAP_RET_UNSUCCESS; + } + if (gcry_md_setkey(hmac_handle, key_input, 32)) { + gcry_md_close(hmac_handle); + return AIRPDCAP_RET_UNSUCCESS; + } + gcry_md_putc(hmac_handle, 1); + gcry_md_putc(hmac_handle, 0); + gcry_md_write(hmac_handle, "TDLS PMK", 8); if (memcmp(initiator, responder, AIRPDCAP_MAC_LEN) < 0) { - sha256_hmac_update(&sha_ctx, initiator, AIRPDCAP_MAC_LEN); - sha256_hmac_update(&sha_ctx, responder, AIRPDCAP_MAC_LEN); + gcry_md_write(hmac_handle, initiator, AIRPDCAP_MAC_LEN); + gcry_md_write(hmac_handle, responder, AIRPDCAP_MAC_LEN); } else { - sha256_hmac_update(&sha_ctx, responder, AIRPDCAP_MAC_LEN); - sha256_hmac_update(&sha_ctx, initiator, AIRPDCAP_MAC_LEN); + gcry_md_write(hmac_handle, responder, AIRPDCAP_MAC_LEN); + gcry_md_write(hmac_handle, initiator, AIRPDCAP_MAC_LEN); } - sha256_hmac_update(&sha_ctx, bssid, AIRPDCAP_MAC_LEN); - length[0] = 256 & 0xff; - length[1] = (256 >> 8) & 0xff; - sha256_hmac_update(&sha_ctx, (const guint8 *)&length, 2); - sha256_hmac_finish(&sha_ctx, key_input); + gcry_md_write(hmac_handle, bssid, AIRPDCAP_MAC_LEN); + gcry_md_putc(hmac_handle, 0); + gcry_md_putc(hmac_handle, 1); + memcpy(key_input, gcry_md_read(hmac_handle, 0), 32); + gcry_md_close(hmac_handle); /* Check MIC */ - aes_cmac_encrypt_starts(&aes_ctx, key_input, 16); - aes_cmac_encrypt_update(&aes_ctx, initiator, AIRPDCAP_MAC_LEN); - aes_cmac_encrypt_update(&aes_ctx, responder, AIRPDCAP_MAC_LEN); - aes_cmac_encrypt_update(&aes_ctx, &seq_num, 1); - aes_cmac_encrypt_update(&aes_ctx, &data[offset_link], data[offset_link + 1] + 2); - aes_cmac_encrypt_update(&aes_ctx, &data[offset_rsne], data[offset_rsne + 1] + 2); - aes_cmac_encrypt_update(&aes_ctx, &data[offset_timeout], data[offset_timeout + 1] + 2); - aes_cmac_encrypt_update(&aes_ctx, &data[offset_fte], 4); - memset(mic, 0, 16); - aes_cmac_encrypt_update(&aes_ctx, mic, 16); - aes_cmac_encrypt_update(&aes_ctx, &data[offset_fte + 20], data[offset_fte + 1] + 2 - 20); - aes_cmac_encrypt_finish(&aes_ctx, mic); - - if (memcmp(mic, &data[offset_fte + 4],16)) { +#if GCRYPT_VERSION_NUMBER >= 0x010600 + if (gcry_mac_open(&cmac_handle, GCRY_MAC_CMAC_AES, 0, NULL)) { + return AIRPDCAP_RET_UNSUCCESS; + } + if (gcry_mac_setkey(cmac_handle, key_input, 16)) { + gcry_mac_close(cmac_handle); + return AIRPDCAP_RET_UNSUCCESS; + } + gcry_mac_write(cmac_handle, initiator, AIRPDCAP_MAC_LEN); + gcry_mac_write(cmac_handle, responder, AIRPDCAP_MAC_LEN); + gcry_mac_write(cmac_handle, &seq_num, 1); + gcry_mac_write(cmac_handle, &data[offset_link], data[offset_link + 1] + 2); + gcry_mac_write(cmac_handle, &data[offset_rsne], data[offset_rsne + 1] + 2); + gcry_mac_write(cmac_handle, &data[offset_timeout], data[offset_timeout + 1] + 2); + gcry_mac_write(cmac_handle, &data[offset_fte], 4); + gcry_mac_write(cmac_handle, zeros, 16); + gcry_mac_write(cmac_handle, &data[offset_fte + 20], data[offset_fte + 1] + 2 - 20); + gcry_mac_read(cmac_handle, mic, &cmac_len); + if (memcmp(mic, &data[offset_fte + 4], 16)) { AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapTDLSDeriveKey", "MIC verification failed", AIRPDCAP_DEBUG_LEVEL_3); + gcry_mac_close(cmac_handle); return AIRPDCAP_RET_UNSUCCESS; } - + gcry_mac_close(cmac_handle); +#else + AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapTDLSDeriveKey", "MIC verification failed, need libgcrypt >= 1.6", AIRPDCAP_DEBUG_LEVEL_3); + return AIRPDCAP_RET_UNSUCCESS; +#endif memcpy(AIRPDCAP_GET_TK(sa->wpa.ptk), &key_input[16], 16); memcpy(sa->wpa.nonce, snonce, AIRPDCAP_WPA_NONCE_LEN); sa->validKey = TRUE; diff --git a/epan/crypt/airpdcap_ccmp.c b/epan/crypt/airpdcap_ccmp.c index ac27c26181..40ec32c686 100644 --- a/epan/crypt/airpdcap_ccmp.c +++ b/epan/crypt/airpdcap_ccmp.c @@ -38,7 +38,7 @@ /****************************************************************************/ /* File includes */ - +#include "config.h" #include "airpdcap_system.h" #include "airpdcap_int.h" @@ -46,7 +46,7 @@ #include "airpdcap_debug.h" #include -#include +#include /****************************************************************************/ /* Internal definitions */ @@ -68,15 +68,15 @@ /****************************************************************************/ /* Internal macros */ -#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) { \ - /* Decrypt, with counter */ \ - _b0[14] = (UINT8)((_i >> 8) & 0xff); \ - _b0[15] = (UINT8)(_i & 0xff); \ - rijndael_encrypt(&key, _b0, _b); \ - XOR_BLOCK(_pos, _b, _len); \ - /* Authentication */ \ - XOR_BLOCK(_a, _pos, _len); \ - rijndael_encrypt(&key, _a, _a); \ +#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) { \ + /* Decrypt, with counter */ \ + _b0[14] = (UINT8)((_i >> 8) & 0xff); \ + _b0[15] = (UINT8)(_i & 0xff); \ + gcry_cipher_encrypt(rijndael_handle, _b, AES_BLOCK_LEN, _b0, AES_BLOCK_LEN); \ + XOR_BLOCK(_pos, _b, _len); \ + /* Authentication */ \ + XOR_BLOCK(_a, _pos, _len); \ + gcry_cipher_encrypt(rijndael_handle, _a, AES_BLOCK_LEN, NULL, 0); \ } #define READ_6(b0, b1, b2, b3, b4, b5) \ @@ -89,8 +89,8 @@ /* Internal function prototypes declarations */ static void ccmp_init_blocks( - rijndael_ctx *ctx, - PAIRPDCAP_MAC_FRAME wh, + gcry_cipher_hd_t rijndael_handle, + PAIRPDCAP_MAC_FRAME wh, UINT64 pn, size_t dlen, UINT8 b0[AES_BLOCK_LEN], @@ -103,8 +103,8 @@ static void ccmp_init_blocks( /* Function definitions */ static void ccmp_init_blocks( - rijndael_ctx *ctx, - PAIRPDCAP_MAC_FRAME wh, + gcry_cipher_hd_t rijndael_handle, + PAIRPDCAP_MAC_FRAME wh, UINT64 pn, size_t dlen, UINT8 b0[AES_BLOCK_LEN], @@ -198,14 +198,14 @@ static void ccmp_init_blocks( } /* Start with the first block and AAD */ - rijndael_encrypt(ctx, b0, a); + gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, b0, AES_BLOCK_LEN); XOR_BLOCK(a, aad, AES_BLOCK_LEN); - rijndael_encrypt(ctx, a, a); + gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, NULL, 0); XOR_BLOCK(a, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - rijndael_encrypt(ctx, a, a); + gcry_cipher_encrypt(rijndael_handle, a, AES_BLOCK_LEN, NULL, 0); b0[0] &= 0x07; b0[14] = b0[15] = 0; - rijndael_encrypt(ctx, b0, b); + gcry_cipher_encrypt(rijndael_handle, b, AES_BLOCK_LEN, b0, AES_BLOCK_LEN); /** //XOR( m + len - 8, b, 8 ); **/ #undef IS_QOS_DATA @@ -214,7 +214,7 @@ static void ccmp_init_blocks( INT AirPDcapCcmpDecrypt( UINT8 *m, - gint mac_header_len, + gint mac_header_len, INT len, UCHAR TK1[16]) { @@ -227,19 +227,27 @@ INT AirPDcapCcmpDecrypt( UINT8 *pos; UINT space; INT z = mac_header_len; - rijndael_ctx key; + gcry_cipher_hd_t rijndael_handle; UINT64 PN; UINT8 *ivp=m+z; PN = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]); - /* freebsd */ - rijndael_set_key(&key, TK1, 128); + if (gcry_cipher_open(&rijndael_handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)) { + return 1; + } + if (gcry_cipher_setkey(rijndael_handle, TK1, 16)) { + gcry_cipher_close(rijndael_handle); + return 1; + } + wh = (PAIRPDCAP_MAC_FRAME )m; data_len = len - (z + AIRPDCAP_CCMP_HEADER+AIRPDCAP_CCMP_TRAILER); - if (data_len < 1) - return 0; - ccmp_init_blocks(&key, wh, PN, data_len, b0, aad, a, b); + if (data_len < 1) { + gcry_cipher_close(rijndael_handle); + return 0; + } + ccmp_init_blocks(rijndael_handle, wh, PN, data_len, b0, aad, a, b); memcpy(mic, m+len-AIRPDCAP_CCMP_TRAILER, AIRPDCAP_CCMP_TRAILER); XOR_BLOCK(mic, b, AIRPDCAP_CCMP_TRAILER); @@ -258,7 +266,8 @@ INT AirPDcapCcmpDecrypt( if (space != 0) /* short last block */ CCMP_DECRYPT(i, b, b0, pos, a, space); - /* MIC Key ?= MIC */ + gcry_cipher_close(rijndael_handle); + /* MIC Key ?= MIC */ if (memcmp(mic, a, AIRPDCAP_CCMP_TRAILER) == 0) { return 0; } diff --git a/epan/crypt/airpdcap_rijndael.c b/epan/crypt/airpdcap_rijndael.c index c7782c3f9e..e5f1f93b4b 100644 --- a/epan/crypt/airpdcap_rijndael.c +++ b/epan/crypt/airpdcap_rijndael.c @@ -23,12 +23,12 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#include "config.h" #include "airpdcap_rijndael.h" -#include "airpdcap_debug.h" +#include "airpdcap_debug.h" #include -#include +#include /* Based on RFC 3394 and NIST AES Key Wrap Specification pseudo-code. @@ -42,7 +42,7 @@ AES_unwrap(UCHAR *kek, UINT16 key_len, UCHAR *cipher_text, UINT16 cipher_len) UCHAR a[8], b[16]; UCHAR *r; gint16 i, j, n; - rijndael_ctx ctx; + gcry_cipher_hd_t rijndael_handle; if (kek == NULL || cipher_len < 16 || cipher_text == NULL) { return NULL; /* "should not happen" */ @@ -61,6 +61,13 @@ AES_unwrap(UCHAR *kek, UINT16 key_len, UCHAR *cipher_text, UINT16 cipher_len) /* Compute intermediate values */ + if (gcry_cipher_open(&rijndael_handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)) { + return output; + } + if (gcry_cipher_setkey(rijndael_handle, kek, key_len)) { + gcry_cipher_close(rijndael_handle); + return output; + } for (j=5; j >= 0; --j){ r = output + (n - 1) * 8; /* DEBUG_DUMP("r1", (r-8), 8); */ @@ -72,14 +79,14 @@ AES_unwrap(UCHAR *kek, UINT16 key_len, UCHAR *cipher_text, UINT16 cipher_len) b[7] ^= t; /* DEBUG_DUMP("a plus t", b, 8); */ memcpy(b+8, r, 8); - rijndael_set_key(&ctx, kek, key_len*8 /*bits*/); - rijndael_decrypt(&ctx, b, b); /* NOTE: we are using the same src and dst buffer. It's ok. */ + gcry_cipher_decrypt(rijndael_handle, b, 16, NULL, 0); /* DEBUG_DUMP("aes decrypt", b, 16) */ memcpy(a,b,8); memcpy(r, b+8, 8); r -= 8; } } + gcry_cipher_close(rijndael_handle); /* DEBUG_DUMP("a", a, 8); */ /* DEBUG_DUMP("output", output, cipher_len - 8); */ diff --git a/epan/dissectors/asn1/cms/packet-cms-template.c b/epan/dissectors/asn1/cms/packet-cms-template.c index 62e2b2f144..e7e8fc917e 100644 --- a/epan/dissectors/asn1/cms/packet-cms-template.c +++ b/epan/dissectors/asn1/cms/packet-cms-template.c @@ -27,8 +27,7 @@ #include #include #include -#include -#include +#include #include "packet-ber.h" #include "packet-cms.h" @@ -65,7 +64,6 @@ static proto_tree *cap_tree=NULL; #define HASH_SHA1 "1.3.14.3.2.26" #define HASH_MD5 "1.2.840.113549.2.5" -#define MD5_BUFFER_SIZE 16 /* SHA-2 variants */ @@ -74,39 +72,23 @@ static proto_tree *cap_tree=NULL; #define HASH_SHA256 "2.16.840.1.101.3.4.2.1" #define SHA256_BUFFER_SIZE 32 -unsigned char digest_buf[MAX(SHA1_DIGEST_LEN, MD5_BUFFER_SIZE)]; +unsigned char digest_buf[MAX(HASH_SHA1_LENGTH, HASH_MD5_LENGTH)]; static void cms_verify_msg_digest(proto_item *pi, tvbuff_t *content, const char *alg, tvbuff_t *tvb, int offset) { - sha1_context sha1_ctx; - md5_state_t md5_ctx; int i= 0, buffer_size = 0; /* we only support two algorithms at the moment - if we do add SHA2 we should add a registration process to use a registration process */ if(strcmp(alg, HASH_SHA1) == 0) { - - sha1_starts(&sha1_ctx); - - sha1_update(&sha1_ctx, tvb_get_ptr(content, 0, tvb_captured_length(content)), - tvb_captured_length(content)); - - sha1_finish(&sha1_ctx, digest_buf); - - buffer_size = SHA1_DIGEST_LEN; + gcry_md_hash_buffer(GCRY_MD_SHA1, digest_buf, tvb_get_ptr(content, 0, tvb_captured_length(content)), tvb_captured_length(content)); + buffer_size = HASH_SHA1_LENGTH; } else if(strcmp(alg, HASH_MD5) == 0) { - - md5_init(&md5_ctx); - - md5_append(&md5_ctx, tvb_get_ptr(content, 0, tvb_captured_length(content)), - tvb_captured_length(content)); - - md5_finish(&md5_ctx, digest_buf); - - buffer_size = MD5_BUFFER_SIZE; + gcry_md_hash_buffer(GCRY_MD_MD5, digest_buf, tvb_get_ptr(content, 0, tvb_captured_length(content)), tvb_captured_length(content)); + buffer_size = HASH_MD5_LENGTH; } if(buffer_size) { diff --git a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c index 861c3264d3..bbd3905720 100644 --- a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c +++ b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include "packet-kerberos.h" @@ -692,10 +693,10 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, int id_offset, offset; guint8 key[DES3_KEY_SIZE]; guint8 initial_vector[DES_BLOCK_SIZE]; - md5_state_t md5s; - md5_byte_t digest[16]; - md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - md5_byte_t confounder[8]; + gcry_md_hd_t md5_handle; + guint8 *digest; + guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + guint8 confounder[8]; gboolean ind; GSList *ske; service_key_t *sk; @@ -721,11 +722,11 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, decrypted_data = wmem_alloc(wmem_packet_scope(), length); for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){ gboolean do_continue = FALSE; + gboolean digest_ok; sk = (service_key_t *) ske->data; des_fix_parity(DES3_KEY_SIZE, key, sk->contents); - md5_init(&md5s); memset(initial_vector, 0, DES_BLOCK_SIZE); des3_set_key(&ctx, key); cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector, @@ -757,12 +758,17 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, continue; } - md5_append(&md5s, confounder, 8); - md5_append(&md5s, zero_fill, 16); - md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len); - md5_finish(&md5s, digest); - - if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) { + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return NULL; + } + gcry_md_write(md5_handle, confounder, 8); + gcry_md_write(md5_handle, zero_fill, 16); + gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len); + digest = gcry_md_read(md5_handle, 0); + + digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0); + gcry_md_close(md5_handle); + if (digest_ok) { plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len); tvb_free(encr_tvb); diff --git a/epan/dissectors/asn1/snmp/packet-snmp-template.c b/epan/dissectors/asn1/snmp/packet-snmp-template.c index bb36534d4d..7343744e1d 100644 --- a/epan/dissectors/asn1/snmp/packet-snmp-template.c +++ b/epan/dissectors/asn1/snmp/packet-snmp-template.c @@ -60,13 +60,10 @@ #include #include #include -#include -#include #include "packet-ipx.h" #include "packet-hpext.h" #include "packet-ber.h" #include "packet-snmp.h" - #include #define PNAME "Simple Network Management Protocol" @@ -106,7 +103,7 @@ static void snmp_usm_password_to_key_sha1(const guint8 *password, guint password static snmp_usm_auth_model_t model_md5 = {snmp_usm_password_to_key_md5, snmp_usm_auth_md5, 16}; -static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, SHA1_DIGEST_LEN}; +static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, 20}; static const value_string auth_types[] = { {0,"MD5"}, @@ -1575,9 +1572,11 @@ snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_l msg[i] = '\0'; } - calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), 16); + calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), HASH_MD5_LENGTH); - md5_hmac(msg, msg_len, key, key_len, calc_auth); + if (ws_hmac_buffer(GCRY_MD_MD5, calc_auth, msg, msg_len, key, key_len)) { + return FALSE; + } if (calc_auth_p) *calc_auth_p = calc_auth; if (calc_auth_len_p) *calc_auth_len_p = 12; @@ -1639,9 +1638,11 @@ snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_a msg[i] = '\0'; } - calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), SHA1_DIGEST_LEN); + calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), HASH_SHA1_LENGTH); - sha1_hmac(key, key_len, msg, msg_len, calc_auth); + if (ws_hmac_buffer(GCRY_MD_SHA1, calc_auth, msg, msg_len, key, key_len)) { + return FALSE; + } if (calc_auth_p) *calc_auth_p = calc_auth; if (calc_auth_len_p) *calc_auth_len_p = 12; @@ -2131,12 +2132,14 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key) { - md5_state_t MD; guint8 *cp, password_buf[64]; guint32 password_index = 0; guint32 count = 0, i; guint8 key1[16]; - md5_init(&MD); /* initialize MD5 */ + gcry_md_hd_t md5_handle; + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } /**********************************************/ /* Use while loop until we've done 1 Megabyte */ @@ -2154,10 +2157,11 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, } else { *cp = 0; } - md5_append(&MD, password_buf, 64); + gcry_md_write(md5_handle, password_buf, 64); count += 64; } - md5_finish(&MD, key1); /* tell MD5 we're done */ + memcpy(key1, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); /*****************************************************/ /* Now localize the key with the engineID and pass */ @@ -2166,11 +2170,14 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, /* checking is done in snmp_users_update_cb. */ /*****************************************************/ - md5_init(&MD); - md5_append(&MD, key1, 16); - md5_append(&MD, engineID, engineLength); - md5_append(&MD, key1, 16); - md5_finish(&MD, key); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, key1, HASH_MD5_LENGTH); + gcry_md_write(md5_handle, engineID, engineLength); + gcry_md_write(md5_handle, key1, HASH_MD5_LENGTH); + memcpy(key, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); return; } @@ -2187,12 +2194,14 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key) { - sha1_context SH; + gcry_md_hd_t sha1_handle; guint8 *cp, password_buf[64]; guint32 password_index = 0; guint32 count = 0, i; - sha1_starts(&SH); /* initialize SHA */ + if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) { + return; + } /**********************************************/ /* Use while loop until we've done 1 Megabyte */ @@ -2210,10 +2219,11 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, } else { *cp = 0; } - sha1_update (&SH, password_buf, 64); + gcry_md_write(sha1_handle, password_buf, 64); count += 64; } - sha1_finish(&SH, key); + memcpy(key, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(sha1_handle); /*****************************************************/ /* Now localize the key with the engineID and pass */ @@ -2221,12 +2231,14 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, /* We ignore invalid engineLengths here. More strict */ /* checking is done in snmp_users_update_cb. */ /*****************************************************/ - - sha1_starts(&SH); - sha1_update(&SH, key, SHA1_DIGEST_LEN); - sha1_update(&SH, engineID, engineLength); - sha1_update(&SH, key, SHA1_DIGEST_LEN); - sha1_finish(&SH, key); + if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) { + return; + } + gcry_md_write(sha1_handle, key, HASH_SHA1_LENGTH); + gcry_md_write(sha1_handle, engineID, engineLength); + gcry_md_write(sha1_handle, key, HASH_SHA1_LENGTH); + memcpy(key, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(sha1_handle); return; } diff --git a/epan/dissectors/asn1/spnego/packet-spnego-template.c b/epan/dissectors/asn1/spnego/packet-spnego-template.c index da3564fdda..13b338a855 100644 --- a/epan/dissectors/asn1/spnego/packet-spnego-template.c +++ b/epan/dissectors/asn1/spnego/packet-spnego-template.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "packet-dcerpc.h" #include "packet-gssapi.h" #include "packet-kerberos.h" @@ -314,8 +314,6 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d } #ifdef HAVE_KERBEROS -#include - #ifndef KEYTYPE_ARCFOUR_56 # define KEYTYPE_ARCFOUR_56 24 #endif @@ -332,23 +330,25 @@ arcfour_mic_key(const guint8 *key_data, size_t key_size, int key_type, const guint8 *cksum_data, size_t cksum_size, guint8 *key6_data) { - guint8 k5_data[16]; - guint8 T[4]; - - memset(T, 0, 4); + guint8 k5_data[HASH_MD5_LENGTH]; + guint8 T[4] = { 0 }; if (key_type == KEYTYPE_ARCFOUR_56) { guint8 L40[14] = "fortybits"; - memcpy(L40 + 10, T, sizeof(T)); - md5_hmac(L40, 14, key_data, key_size, k5_data); + if (ws_hmac_buffer(GCRY_MD_MD5, k5_data, L40, 14, key_data, key_size)) { + return 0; + } memset(&k5_data[7], 0xAB, 9); } else { - md5_hmac(T, 4, key_data, key_size, k5_data); + if (ws_hmac_buffer(GCRY_MD_MD5, k5_data, T, 4, key_data, key_size)) { + return 0; + } } - md5_hmac(cksum_data, cksum_size, k5_data, 16, key6_data); - + if (ws_hmac_buffer(GCRY_MD_MD5, key6_data, cksum_data, cksum_size, k5_data, HASH_MD5_LENGTH)) { + return 0; + } return 0; } @@ -379,26 +379,35 @@ arcfour_mic_cksum(guint8 *key_data, int key_length, const guint8 *v3, size_t l3) { static const guint8 signature[] = "signaturekey"; - guint8 ksign_c[16]; + guint8 ksign_c[HASH_MD5_LENGTH]; guint8 t[4]; - md5_state_t ms; - guint8 digest[16]; + guint8 digest[HASH_MD5_LENGTH]; int rc4_usage; - guint8 cksum[16]; + guint8 cksum[HASH_MD5_LENGTH]; + gcry_md_hd_t md5_handle; rc4_usage=usage2arcfour(usage); - md5_hmac(signature, sizeof(signature), key_data, key_length, ksign_c); - md5_init(&ms); + if (ws_hmac_buffer(GCRY_MD_MD5, ksign_c, signature, sizeof(signature), key_data, key_length)) { + return 0; + } + + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return 0; + } t[0] = (rc4_usage >> 0) & 0xFF; t[1] = (rc4_usage >> 8) & 0xFF; t[2] = (rc4_usage >> 16) & 0xFF; t[3] = (rc4_usage >> 24) & 0xFF; - md5_append(&ms, t, 4); - md5_append(&ms, v1, l1); - md5_append(&ms, v2, l2); - md5_append(&ms, v3, l3); - md5_finish(&ms, digest); - md5_hmac(digest, 16, ksign_c, 16, cksum); + gcry_md_write(md5_handle, t, 4); + gcry_md_write(md5_handle, v1, l1); + gcry_md_write(md5_handle, v2, l2); + gcry_md_write(md5_handle, v3, l3); + memcpy(digest, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); + + if (ws_hmac_buffer(GCRY_MD_MD5, cksum, digest, HASH_MD5_LENGTH, ksign_c, HASH_MD5_LENGTH)) { + return 0; + } memcpy(sgn_cksum, cksum, 8); @@ -446,7 +455,7 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf int cmp; int conf_flag; int padlen = 0; - rc4_state_struct rc4_state; + gcry_cipher_hd_t rc4_handle; int i; datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); @@ -471,9 +480,16 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf return -5; } - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); - crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return -12; + } + if (gcry_cipher_setkey(rc4_handle, k6_data, sizeof(k6_data))) { + gcry_cipher_close(rc4_handle); + return -13; + } + gcry_cipher_decrypt(rc4_handle, (guint8 *)SND_SEQ, 8, NULL, 0); + gcry_cipher_close(rc4_handle); memset(k6_data, 0, sizeof(k6_data)); @@ -497,11 +513,18 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf if(conf_flag) { - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - crypt_rc4(&rc4_state, Confounder, 8); - memcpy(output_message_buffer, input_message_buffer, datalen); - crypt_rc4(&rc4_state, output_message_buffer, datalen); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return -14; + } + if (gcry_cipher_setkey(rc4_handle, k6_data, sizeof(k6_data))) { + gcry_cipher_close(rc4_handle); + return -15; + } + + gcry_cipher_decrypt(rc4_handle, Confounder, 8, NULL, 0); + gcry_cipher_decrypt(rc4_handle, output_message_buffer, datalen, input_message_buffer, datalen); + gcry_cipher_close(rc4_handle); } else { tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); memcpy(output_message_buffer, input_message_buffer, datalen); diff --git a/epan/dissectors/file-file.c b/epan/dissectors/file-file.c index b633fc2275..f926a75077 100644 --- a/epan/dissectors/file-file.c +++ b/epan/dissectors/file-file.c @@ -38,7 +38,6 @@ #include #include -#include #include #include diff --git a/epan/dissectors/packet-3com-njack.c b/epan/dissectors/packet-3com-njack.c index 26207c07c5..c66a83cb70 100644 --- a/epan/dissectors/packet-3com-njack.c +++ b/epan/dissectors/packet-3com-njack.c @@ -508,7 +508,7 @@ dissect_tlvs(tvbuff_t *tvb, proto_tree *njack_tree, guint32 offset) } #if 0 -#include +#include static gboolean verify_password(tvbuff_t *tvb, const char *password) @@ -525,8 +525,8 @@ verify_password(tvbuff_t *tvb, const char *password) guint8 *workbuffer; guint i; guint8 byte; - md5_state_t md_ctx; - md5_byte_t *digest; + gcry_md_hd_t md5_handle; + guint8 *digest; workbuffer=wmem_alloc(wmem_packet_scope(), 32); digest=wmem_alloc(wmem_packet_scope(), 16); @@ -539,14 +539,20 @@ verify_password(tvbuff_t *tvb, const char *password) for (byte = 1; i<32; i++, byte++) { workbuffer[i] = byte; } - md5_init(&md_ctx); - md5_append(&md_ctx, workbuffer, 32); - md5_finish(&md_ctx, digest); - md5_init(&md_ctx); - md5_append(&md_ctx, packetdata, 12); - md5_append(&md_ctx, digest, 16); - md5_append(&md_ctx, packetdata + 28, length - 28); - md5_finish(&md_ctx, digest); + + if (gcry_md_open (&md5_handle, GCRY_MD_MD5, 0)) { + return FALSE; + } + gcry_md_write(md5_handle, workbuffer, 32); + memcpy(digest, gcry_md_read(md5_handle, 0), 16); + gcry_md_reset(md5_handle); + + gcry_md_write(md5_handle, packetdata, 12); + gcry_md_write(md5_handle, digest, 16); + gcry_md_write(md5_handle, packetdata + 28, length - 28); + memcpy(digest, gcry_md_read(md5_handle, 0), 16); + gcry_md_close(md5_handle); + fprintf(stderr, "Calculated digest: "); /* debugging */ for (i = 0; i < 16; i++) { fprintf(stderr, "%02X", digest[i]); /* debugging */ diff --git a/epan/dissectors/packet-cms.c b/epan/dissectors/packet-cms.c index aafa52e46c..3cbdbe5c9d 100644 --- a/epan/dissectors/packet-cms.c +++ b/epan/dissectors/packet-cms.c @@ -35,8 +35,7 @@ #include #include #include -#include -#include +#include #include "packet-ber.h" #include "packet-cms.h" @@ -184,7 +183,7 @@ static int hf_cms_issuerUniqueID = -1; /* UniqueIdentifier */ static int hf_cms_extensions = -1; /* Extensions */ /*--- End of included file: packet-cms-hf.c ---*/ -#line 52 "./asn1/cms/packet-cms-template.c" +#line 51 "./asn1/cms/packet-cms-template.c" /* Initialize the subtree pointers */ @@ -247,7 +246,7 @@ static gint ett_cms_T_subject = -1; static gint ett_cms_SEQUENCE_OF_Attribute = -1; /*--- End of included file: packet-cms-ett.c ---*/ -#line 55 "./asn1/cms/packet-cms-template.c" +#line 54 "./asn1/cms/packet-cms-template.c" static int dissect_cms_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) ; /* XXX kill a compiler warning until asn2wrs stops generating these silly wrappers */ @@ -261,7 +260,6 @@ static proto_tree *cap_tree=NULL; #define HASH_SHA1 "1.3.14.3.2.26" #define HASH_MD5 "1.2.840.113549.2.5" -#define MD5_BUFFER_SIZE 16 /* SHA-2 variants */ @@ -270,39 +268,23 @@ static proto_tree *cap_tree=NULL; #define HASH_SHA256 "2.16.840.1.101.3.4.2.1" #define SHA256_BUFFER_SIZE 32 -unsigned char digest_buf[MAX(SHA1_DIGEST_LEN, MD5_BUFFER_SIZE)]; +unsigned char digest_buf[MAX(HASH_SHA1_LENGTH, HASH_MD5_LENGTH)]; static void cms_verify_msg_digest(proto_item *pi, tvbuff_t *content, const char *alg, tvbuff_t *tvb, int offset) { - sha1_context sha1_ctx; - md5_state_t md5_ctx; int i= 0, buffer_size = 0; /* we only support two algorithms at the moment - if we do add SHA2 we should add a registration process to use a registration process */ if(strcmp(alg, HASH_SHA1) == 0) { - - sha1_starts(&sha1_ctx); - - sha1_update(&sha1_ctx, tvb_get_ptr(content, 0, tvb_captured_length(content)), - tvb_captured_length(content)); - - sha1_finish(&sha1_ctx, digest_buf); - - buffer_size = SHA1_DIGEST_LEN; + gcry_md_hash_buffer(GCRY_MD_SHA1, digest_buf, tvb_get_ptr(content, 0, tvb_captured_length(content)), tvb_captured_length(content)); + buffer_size = HASH_SHA1_LENGTH; } else if(strcmp(alg, HASH_MD5) == 0) { - - md5_init(&md5_ctx); - - md5_append(&md5_ctx, tvb_get_ptr(content, 0, tvb_captured_length(content)), - tvb_captured_length(content)); - - md5_finish(&md5_ctx, digest_buf); - - buffer_size = MD5_BUFFER_SIZE; + gcry_md_hash_buffer(GCRY_MD_MD5, digest_buf, tvb_get_ptr(content, 0, tvb_captured_length(content)), tvb_captured_length(content)); + buffer_size = HASH_MD5_LENGTH; } if(buffer_size) { @@ -1868,7 +1850,7 @@ static int dissect_RC2CBCParameters_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U /*--- End of included file: packet-cms-fn.c ---*/ -#line 132 "./asn1/cms/packet-cms-template.c" +#line 114 "./asn1/cms/packet-cms-template.c" /*--- proto_register_cms ----------------------------------------------*/ void proto_register_cms(void) { @@ -2376,7 +2358,7 @@ void proto_register_cms(void) { NULL, HFILL }}, /*--- End of included file: packet-cms-hfarr.c ---*/ -#line 143 "./asn1/cms/packet-cms-template.c" +#line 125 "./asn1/cms/packet-cms-template.c" }; /* List of subtrees */ @@ -2441,7 +2423,7 @@ void proto_register_cms(void) { &ett_cms_SEQUENCE_OF_Attribute, /*--- End of included file: packet-cms-ettarr.c ---*/ -#line 148 "./asn1/cms/packet-cms-template.c" +#line 130 "./asn1/cms/packet-cms-template.c" }; /* Register protocol */ @@ -2488,7 +2470,7 @@ void proto_reg_handoff_cms(void) { /*--- End of included file: packet-cms-dis-tab.c ---*/ -#line 171 "./asn1/cms/packet-cms-template.c" +#line 153 "./asn1/cms/packet-cms-template.c" oid_add_from_string("id-data","1.2.840.113549.1.7.1"); oid_add_from_string("id-alg-des-ede3-cbc","1.2.840.113549.3.7"); diff --git a/epan/dissectors/packet-corosync-totemnet.c b/epan/dissectors/packet-corosync-totemnet.c index 9932df087f..a0e5df2460 100644 --- a/epan/dissectors/packet-corosync-totemnet.c +++ b/epan/dissectors/packet-corosync-totemnet.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include static dissector_handle_t corosync_totemsrp_handle; @@ -62,8 +62,7 @@ static gchar** corosync_totemnet_private_keys_list = NULL; /* Initialize the subtree pointers */ static gint ett_corosync_totemnet_security_header = -1; - -#define SALT_SIZE 16 +#define SALT_SIZE 16 #define TOTEM_CRYPTO_SOBER 0 #define TOTEM_CRYPTO_NSS 1 @@ -95,10 +94,10 @@ dissect_corosync_totemnet_security_header(tvbuff_t *tvb, proto_tree_add_item(tree, hf_corosync_totemnet_security_header_hash_digest, - tvb, 0, SHA1_DIGEST_LEN, ENC_NA); + tvb, 0, HASH_SHA1_LENGTH, ENC_NA); proto_tree_add_item(tree, hf_corosync_totemnet_security_header_salt, - tvb, SHA1_DIGEST_LEN, SALT_SIZE, ENC_NA); + tvb, HASH_SHA1_LENGTH, SALT_SIZE, ENC_NA); if (check_crypt_type) { @@ -114,7 +113,7 @@ dissect_corosync_totemnet_security_header(tvbuff_t *tvb, PROTO_ITEM_SET_GENERATED(key_item); } } - return SHA1_DIGEST_LEN + SALT_SIZE; + return HASH_SHA1_LENGTH + SALT_SIZE; } /* About totemnet.c of corosync cluster engine: @@ -258,12 +257,12 @@ dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, const gchar* key_for_trial) { unsigned char keys[48]; - sober128_prng keygen_prng_state; - sober128_prng stream_prng_state; + sober128_prng keygen_prng_state; + sober128_prng stream_prng_state; unsigned char *hmac_key = &keys[32]; unsigned char *cipher_key = &keys[16]; unsigned char *initial_vector = &keys[0]; - unsigned char digest_comparison[SHA1_DIGEST_LEN]; + unsigned char digest_comparison[HASH_SHA1_LENGTH]; int io_len; guint8 *io_base; @@ -275,7 +274,7 @@ dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, unsigned char* salt; io_len = tvb_reported_length(tvb) - (check_crypt_type? 1: 0); - if (io_len < SHA1_DIGEST_LEN + SALT_SIZE) { + if (io_len < HASH_SHA1_LENGTH + SALT_SIZE) { return 0; } @@ -286,7 +285,7 @@ dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, } hash_digest = io_base; - salt = io_base + SHA1_DIGEST_LEN; + salt = io_base + HASH_SHA1_LENGTH; memset(private_key, 0, sizeof(private_key)); @@ -314,19 +313,19 @@ dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, /* * Authenticate contents of message */ - sha1_hmac(hmac_key, 16, - io_base + SHA1_DIGEST_LEN, io_len - SHA1_DIGEST_LEN, - digest_comparison); + if (ws_hmac_buffer(GCRY_MD_SHA1, digest_comparison, io_base + HASH_SHA1_LENGTH, io_len - HASH_SHA1_LENGTH, hmac_key, 16)) { + return 0; + } - if (memcmp (digest_comparison, hash_digest, SHA1_DIGEST_LEN) != 0) + if (memcmp (digest_comparison, hash_digest, HASH_SHA1_LENGTH) != 0) return 0; /* * Decrypt the contents of the message with the cipher key */ - sober128_read (io_base + SHA1_DIGEST_LEN + SALT_SIZE, - io_len - (SHA1_DIGEST_LEN + SALT_SIZE), + sober128_read (io_base + HASH_SHA1_LENGTH + SALT_SIZE, + io_len - (HASH_SHA1_LENGTH + SALT_SIZE), &stream_prng_state); @@ -348,11 +347,11 @@ dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, check_crypt_type, key_for_trial); next_tvb = tvb_new_subset_length_caplen(decrypted_tvb, - SHA1_DIGEST_LEN + SALT_SIZE, - io_len - (SHA1_DIGEST_LEN + SALT_SIZE), - io_len - (SHA1_DIGEST_LEN + SALT_SIZE)); + HASH_SHA1_LENGTH + SALT_SIZE, + io_len - (HASH_SHA1_LENGTH + SALT_SIZE), + io_len - (HASH_SHA1_LENGTH + SALT_SIZE)); - return call_dissector(corosync_totemsrp_handle, next_tvb, pinfo, parent_tree) + SHA1_DIGEST_LEN + SALT_SIZE; + return call_dissector(corosync_totemsrp_handle, next_tvb, pinfo, parent_tree) + HASH_SHA1_LENGTH + SALT_SIZE; } } diff --git a/epan/dissectors/packet-data.c b/epan/dissectors/packet-data.c index 30247fdc38..0af98910e3 100644 --- a/epan/dissectors/packet-data.c +++ b/epan/dissectors/packet-data.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include /* proto_data cannot be static because it's referenced in the @@ -90,17 +90,13 @@ dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ if(generate_md5_hash) { const guint8 *cp; - md5_state_t md_ctx; - md5_byte_t digest[16]; + guint8 digest[HASH_MD5_LENGTH]; const gchar *digest_string; cp = tvb_get_ptr(tvb, 0, bytes); - md5_init(&md_ctx); - md5_append(&md_ctx, cp, bytes); - md5_finish(&md_ctx, digest); - - digest_string = bytestring_to_str(wmem_packet_scope(), digest, 16, '\0'); + gcry_md_hash_buffer(GCRY_MD_MD5, digest, cp, bytes); + digest_string = bytestring_to_str(wmem_packet_scope(), digest, HASH_MD5_LENGTH, '\0'); ti = proto_tree_add_string(data_tree, &hfi_data_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } diff --git a/epan/dissectors/packet-dcerpc-netlogon.c b/epan/dissectors/packet-dcerpc-netlogon.c index a4b1541867..12873d6cdd 100644 --- a/epan/dissectors/packet-dcerpc-netlogon.c +++ b/epan/dissectors/packet-dcerpc-netlogon.c @@ -26,9 +26,7 @@ #include -#include -#include -#include +#include #include /* for dissect_mscldap_string */ @@ -6590,7 +6588,7 @@ static guint32 get_keytab_as_list(md4_pass **p_pass_list, const char* ntlm_pass) debugprintf("Password: %s\n",ntlm_pass); password_len = (int)strlen(ntlm_pass); str_to_unicode(ntlm_pass,ntlm_pass_unicode); - crypt_md4(ntlm_pass_hash.md4,ntlm_pass_unicode,password_len*2); + gcry_md_hash_buffer(GCRY_MD_MD4, ntlm_pass_hash.md4, ntlm_pass_unicode, password_len*2); printnbyte(ntlm_pass_hash.md4,16,"Hash of the NT pass: ","\n"); add_ntlm = 1; } @@ -6666,19 +6664,19 @@ netlogon_dissect_netrserverauthenticate23_reply(tvbuff_t *tvb, int offset, #endif if( flags & NETLOGON_FLAG_STRONGKEY ) { #ifdef HAVE_KERBEROS - guint8 zeros[4]; - guint8 md5[16]; - md5_state_t md5state; - guint8 buf[8]; + guint8 zeros[4] = { 0 }; + guint8 md5[HASH_MD5_LENGTH]; + gcry_md_hd_t md5_handle; + guint8 buf[8] = { 0 }; guint64 calculated_cred; - - memset(zeros,0,4); - md5_init(&md5state); - md5_append(&md5state,zeros,4); - md5_append(&md5state,(unsigned char*)&vars->client_challenge,8); - md5_append(&md5state,(unsigned char*)&vars->server_challenge,8); - md5_finish(&md5state,md5); + if (!gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + gcry_md_write(md5_handle, zeros, 4); + gcry_md_write(md5_handle, (guint8*)&vars->client_challenge, 8); + gcry_md_write(md5_handle, (guint8*)&vars->server_challenge, 8); + memcpy(md5, gcry_md_read(md5_handle, 0), 16); + gcry_md_close(md5_handle); + } printnbyte(md5,8,"MD5:","\n"); printnbyte((guint8*)&vars->client_challenge,8,"Client challenge:","\n"); printnbyte((guint8*)&vars->server_challenge,8,"Server challenge:","\n"); @@ -6686,15 +6684,16 @@ netlogon_dissect_netrserverauthenticate23_reply(tvbuff_t *tvb, int offset, for(i=0;iserver_challenge,session_key,1); - crypt_des_ecb((unsigned char*)&calculated_cred,buf,session_key+7,1); + if (!ws_hmac_buffer(GCRY_MD_MD5, session_key, md5, HASH_MD5_LENGTH, (guint8*) &password, 16)) { + crypt_des_ecb(buf,(unsigned char*)&vars->server_challenge,session_key,1); + crypt_des_ecb((unsigned char*)&calculated_cred,buf,session_key+7,1); #if 0 - printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n"); + printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n"); #endif - if(calculated_cred==server_cred) { - found = 1; - break; + if(calculated_cred==server_cred) { + found = 1; + break; + } } } #endif @@ -7638,23 +7637,25 @@ static const value_string seal_algs[] = { static int get_seal_key(const guint8 *session_key,int key_len,guint64 sequence,guint8* seal_key) { - guint8 zeros[4]; + guint8 zeros[4] = { 0 }; guint8 *buf = (guint8 *)wmem_alloc(wmem_packet_scope(), key_len); - guint8 buf2[16]; + guint8 buf2[HASH_MD5_LENGTH]; guint8 zero_sk[16]; int i = 0; memset(zero_sk,0,16); memset(seal_key,0,16); if(memcmp(session_key,zero_sk,16)) { - memset(zeros,0,4); for(i=0;ican_decrypt == TRUE) { - rc4_state_struct rc4state; + gcry_cipher_hd_t rc4_handle; int data_len; guint64 copyconfounder = vars->confounder; @@ -7718,11 +7727,18 @@ dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_, if (data_len < 0) { return NULL; } - crypt_rc4_init(&rc4state,vars->encryption_key,16); - crypt_rc4(&rc4state,(guint8*)©confounder,8); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return NULL; + } + if (gcry_cipher_setkey(rc4_handle, vars->encryption_key, 16)) { + gcry_cipher_close(rc4_handle); + return NULL; + } + gcry_cipher_decrypt(rc4_handle, (guint8*)©confounder, 8, NULL, 0); decrypted = (guint8*)tvb_memdup(pinfo->pool, tvb, offset,data_len); - crypt_rc4_init(&rc4state,vars->encryption_key,16); - crypt_rc4(&rc4state,decrypted,data_len); + gcry_cipher_reset(rc4_handle); + gcry_cipher_decrypt(rc4_handle, decrypted, data_len, NULL, 0); + gcry_cipher_close(rc4_handle); buf = tvb_new_child_real_data(tvb, decrypted, data_len, data_len); /* Note: caller does add_new_data_source(...) */ } diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index b4f17367b4..aa9d1f443a 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -453,17 +453,13 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* if (generate_md5_hash) { const guint8 *cp; - md5_state_t md_ctx; - md5_byte_t digest[16]; + guint8 digest[HASH_MD5_LENGTH]; const gchar *digest_string; cp = tvb_get_ptr(tvb, 0, cap_len); - md5_init(&md_ctx); - md5_append(&md_ctx, cp, cap_len); - md5_finish(&md_ctx, digest); - - digest_string = bytestring_to_str(wmem_packet_scope(), digest, 16, '\0'); + gcry_md_hash_buffer(GCRY_MD_MD5, digest, cp, cap_len); + digest_string = bytestring_to_str(wmem_packet_scope(), digest, HASH_MD5_LENGTH, '\0'); ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string); PROTO_ITEM_SET_GENERATED(ti); } diff --git a/epan/dissectors/packet-kerberos.c b/epan/dissectors/packet-kerberos.c index 88d3113b5f..976c74c90c 100644 --- a/epan/dissectors/packet-kerberos.c +++ b/epan/dissectors/packet-kerberos.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include "packet-kerberos.h" @@ -351,7 +352,7 @@ static int hf_kerberos_KDCOptions_renew = -1; static int hf_kerberos_KDCOptions_validate = -1; /*--- End of included file: packet-kerberos-hf.c ---*/ -#line 174 "./asn1/kerberos/packet-kerberos-template.c" +#line 175 "./asn1/kerberos/packet-kerberos-template.c" /* Initialize the subtree pointers */ static gint ett_kerberos = -1; @@ -427,7 +428,7 @@ static gint ett_kerberos_KERB_PA_PAC_REQUEST = -1; static gint ett_kerberos_ChangePasswdData = -1; /*--- End of included file: packet-kerberos-ett.c ---*/ -#line 188 "./asn1/kerberos/packet-kerberos-template.c" +#line 189 "./asn1/kerberos/packet-kerberos-template.c" static expert_field ei_kerberos_decrypted_keytype = EI_INIT; static expert_field ei_kerberos_address = EI_INIT; @@ -456,7 +457,7 @@ static gboolean gbl_do_col_info; #define KERBEROS_ADDR_TYPE_IPV6 24 /*--- End of included file: packet-kerberos-val.h ---*/ -#line 201 "./asn1/kerberos/packet-kerberos-template.c" +#line 202 "./asn1/kerberos/packet-kerberos-template.c" static void call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb) @@ -951,10 +952,10 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, int id_offset, offset; guint8 key[DES3_KEY_SIZE]; guint8 initial_vector[DES_BLOCK_SIZE]; - md5_state_t md5s; - md5_byte_t digest[16]; - md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - md5_byte_t confounder[8]; + gcry_md_hd_t md5_handle; + guint8 *digest; + guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + guint8 confounder[8]; gboolean ind; GSList *ske; service_key_t *sk; @@ -980,11 +981,11 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, decrypted_data = wmem_alloc(wmem_packet_scope(), length); for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){ gboolean do_continue = FALSE; + gboolean digest_ok; sk = (service_key_t *) ske->data; des_fix_parity(DES3_KEY_SIZE, key, sk->contents); - md5_init(&md5s); memset(initial_vector, 0, DES_BLOCK_SIZE); des3_set_key(&ctx, key); cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector, @@ -1016,12 +1017,17 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo, continue; } - md5_append(&md5s, confounder, 8); - md5_append(&md5s, zero_fill, 16); - md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len); - md5_finish(&md5s, digest); - - if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) { + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return NULL; + } + gcry_md_write(md5_handle, confounder, 8); + gcry_md_write(md5_handle, zero_fill, 16); + gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len); + digest = gcry_md_read(md5_handle, 0); + + digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0); + gcry_md_close(md5_handle); + if (digest_ok) { plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len); tvb_free(encr_tvb); @@ -4206,7 +4212,7 @@ dissect_kerberos_ChangePasswdData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, /*--- End of included file: packet-kerberos-fn.c ---*/ -#line 1850 "./asn1/kerberos/packet-kerberos-template.c" +#line 1856 "./asn1/kerberos/packet-kerberos-template.c" /* Make wrappers around exported functions for now */ int @@ -5260,7 +5266,7 @@ void proto_register_kerberos(void) { NULL, HFILL }}, /*--- End of included file: packet-kerberos-hfarr.c ---*/ -#line 2231 "./asn1/kerberos/packet-kerberos-template.c" +#line 2237 "./asn1/kerberos/packet-kerberos-template.c" }; /* List of subtrees */ @@ -5338,7 +5344,7 @@ void proto_register_kerberos(void) { &ett_kerberos_ChangePasswdData, /*--- End of included file: packet-kerberos-ettarr.c ---*/ -#line 2247 "./asn1/kerberos/packet-kerberos-template.c" +#line 2253 "./asn1/kerberos/packet-kerberos-template.c" }; static ei_register_info ei[] = { diff --git a/epan/dissectors/packet-l2tp.c b/epan/dissectors/packet-l2tp.c index 91da4b2f7d..0e9e44eee1 100644 --- a/epan/dissectors/packet-l2tp.c +++ b/epan/dissectors/packet-l2tp.c @@ -67,8 +67,7 @@ #include #include -#include -#include +#include #include "packet-l2tp.h" @@ -974,8 +973,6 @@ static dissector_handle_t l2tp_ip_handle; #define L2TP_HMAC_MD5 0 #define L2TP_HMAC_SHA1 1 -#define L2TP_HMAC_MD5_KEY_LEN 16 -#define L2TP_HMAC_MD5_DIGEST_LEN 16 typedef struct l2tpv3_conversation { address lcce1; @@ -1000,7 +997,7 @@ typedef struct l2tpv3_tunnel { gint lcce2_nonce_len; gchar *shared_key_secret; - guint8 shared_key[L2TP_HMAC_MD5_KEY_LEN]; + guint8 shared_key[HASH_MD5_LENGTH]; GSList *sessions; } l2tpv3_tunnel_t; @@ -1036,7 +1033,9 @@ static void update_shared_key(l2tpv3_tunnel_t *tunnel) if (tunnel->shared_key_secret == NULL || strcmp(secret, tunnel->shared_key_secret) != 0) { /* For secret specification, see RFC 3931 pg 37 */ guint8 data = 2; - md5_hmac(&data, 1, secret, strlen(secret), tunnel->shared_key); + if (ws_hmac_buffer(GCRY_MD_MD5, tunnel->shared_key, &data, 1, secret, strlen(secret))) { + return; + } tunnel->shared_key_secret = wmem_strdup(wmem_file_scope(), secret); } } @@ -1050,35 +1049,41 @@ static void md5_hmac_digest(l2tpv3_tunnel_t *tunnel, packet_info *pinfo, guint8 digest[20]) { - guint8 zero[L2TP_HMAC_MD5_DIGEST_LEN]; - md5_hmac_state_t ms; + guint8 zero[HASH_MD5_LENGTH] = { 0 }; + gcry_md_hd_t hmac_handle; int remainder; int offset = 0; if (tunnel->conv->pt == PT_NONE) /* IP encapsulated L2TPv3 */ offset = 4; - md5_hmac_init(&ms, tunnel->shared_key, L2TP_HMAC_MD5_KEY_LEN); + if (gcry_md_open(&hmac_handle, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC)) { + return; + } + if (gcry_md_setkey(hmac_handle, tunnel->shared_key, HASH_MD5_LENGTH)) { + gcry_md_close(hmac_handle); + return; + } if (msg_type != MESSAGE_TYPE_SCCRQ) { if (tunnel->lcce1_nonce != NULL && tunnel->lcce2_nonce != NULL) { if (addresses_equal(&tunnel->lcce1, &pinfo->src)) { - md5_hmac_append(&ms, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); - md5_hmac_append(&ms, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); } else { - md5_hmac_append(&ms, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); - md5_hmac_append(&ms, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); } } } - md5_hmac_append(&ms, tvb_get_ptr(tvb, offset, idx + 1 - offset), idx + 1 - offset); + gcry_md_write(hmac_handle, tvb_get_ptr(tvb, offset, idx + 1 - offset), idx + 1 - offset); /* Message digest is calculated with an empty message digest field */ - memset(zero, 0, L2TP_HMAC_MD5_DIGEST_LEN); - md5_hmac_append(&ms, zero, avp_len - 1); + gcry_md_write(hmac_handle, zero, avp_len - 1); remainder = length - (idx + avp_len); - md5_hmac_append(&ms, tvb_get_ptr(tvb, idx + avp_len, remainder), remainder); - md5_hmac_finish(&ms, digest); + gcry_md_write(hmac_handle, tvb_get_ptr(tvb, idx + avp_len, remainder), remainder); + memcpy(digest, gcry_md_read(hmac_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(hmac_handle); } static void sha1_hmac_digest(l2tpv3_tunnel_t *tunnel, @@ -1090,35 +1095,41 @@ static void sha1_hmac_digest(l2tpv3_tunnel_t *tunnel, packet_info *pinfo, guint8 digest[20]) { - guint8 zero[SHA1_DIGEST_LEN]; - sha1_hmac_context ms; + guint8 zero[HASH_SHA1_LENGTH] = { 0 }; + gcry_md_hd_t hmac_handle; int remainder; int offset = 0; if (tunnel->conv->pt == PT_NONE) /* IP encapsulated L2TPv3 */ offset = 4; - sha1_hmac_starts(&ms, tunnel->shared_key, L2TP_HMAC_MD5_KEY_LEN); + if (gcry_md_open(&hmac_handle, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC)) { + return; + } + if (gcry_md_setkey(hmac_handle, tunnel->shared_key, HASH_MD5_LENGTH)) { + gcry_md_close(hmac_handle); + return; + } if (msg_type != MESSAGE_TYPE_SCCRQ) { if (tunnel->lcce1_nonce != NULL && tunnel->lcce2_nonce != NULL) { if (addresses_equal(&tunnel->lcce1, &pinfo->src)) { - sha1_hmac_update(&ms, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); - sha1_hmac_update(&ms, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); } else { - sha1_hmac_update(&ms, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); - sha1_hmac_update(&ms, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce2_nonce, tunnel->lcce2_nonce_len); + gcry_md_write(hmac_handle, tunnel->lcce1_nonce, tunnel->lcce1_nonce_len); } } } - sha1_hmac_update(&ms, tvb_get_ptr(tvb, offset, idx + 1 - offset), idx + 1 - offset); + gcry_md_write(hmac_handle, tvb_get_ptr(tvb, offset, idx + 1 - offset), idx + 1 - offset); /* Message digest is calculated with an empty message digest field */ - memset(zero, 0, SHA1_DIGEST_LEN); - sha1_hmac_update(&ms, zero, avp_len - 1); + gcry_md_write(hmac_handle, zero, avp_len - 1); remainder = length - (idx + avp_len); - sha1_hmac_update(&ms, tvb_get_ptr(tvb, idx + avp_len, remainder), remainder); - sha1_hmac_finish(&ms, digest); + gcry_md_write(hmac_handle, tvb_get_ptr(tvb, idx + avp_len, remainder), remainder); + memcpy(digest, gcry_md_read(hmac_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(hmac_handle); } static int check_control_digest(l2tpv3_tunnel_t *tunnel, @@ -1129,7 +1140,7 @@ static int check_control_digest(l2tpv3_tunnel_t *tunnel, int msg_type, packet_info *pinfo) { - guint8 digest[SHA1_DIGEST_LEN]; + guint8 digest[HASH_SHA1_LENGTH]; if (!tunnel) return 1; @@ -1138,12 +1149,12 @@ static int check_control_digest(l2tpv3_tunnel_t *tunnel, switch (tvb_get_guint8(tvb, idx)) { case L2TP_HMAC_MD5: - if ((avp_len - 1) != L2TP_HMAC_MD5_DIGEST_LEN) + if ((avp_len - 1) != HASH_MD5_LENGTH) return -1; md5_hmac_digest(tunnel, tvb, length, idx, avp_len, msg_type, pinfo, digest); break; case L2TP_HMAC_SHA1: - if ((avp_len - 1) != SHA1_DIGEST_LEN) + if ((avp_len - 1) != HASH_SHA1_LENGTH) return -1; sha1_hmac_digest(tunnel, tvb, length, idx, avp_len, msg_type, pinfo, digest); break; diff --git a/epan/dissectors/packet-ntlmssp.c b/epan/dissectors/packet-ntlmssp.c index dcf9a3daab..3749e0d9ce 100644 --- a/epan/dissectors/packet-ntlmssp.c +++ b/epan/dissectors/packet-ntlmssp.c @@ -39,9 +39,7 @@ #include #include -#include -#include -#include +#include #include #include #include @@ -289,8 +287,8 @@ typedef struct _ntlmssp_blob { typedef struct _ntlmssp_info { guint32 flags; int is_auth_ntlm_v2; - rc4_state_struct rc4_state_client; - rc4_state_struct rc4_state_server; + gcry_cipher_hd_t rc4_handle_client; + gcry_cipher_hd_t rc4_handle_server; guint8 sign_key_client[NTLMSSP_KEY_LEN]; guint8 sign_key_server[NTLMSSP_KEY_LEN]; guint32 server_dest_port; @@ -360,6 +358,16 @@ LEBE_Convert(int value) } #endif +static gboolean +ntlmssp_sessions_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_) +{ + ntlmssp_info * conv_ntlmssp_info = (ntlmssp_info *) user_data; + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + /* unregister this callback */ + return FALSE; +} + /* Perform a DES encryption with a 16-byte key and 8-byte data item. It's in fact 3 susbsequent call to crypt_des_ecb with a 7-byte key. @@ -498,7 +506,7 @@ get_md4pass_list(md4_pass** p_pass_list, const char* nt_password) nb_pass++; password_len = (int)strlen(nt_password); str_to_unicode(nt_password, nt_password_unicode); - crypt_md4(nt_password_hash, nt_password_unicode, password_len*2); + gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); } if (nb_pass == 0) { /* Unable to calculate the session key without a password or if password is more than 128 char ......*/ @@ -545,7 +553,7 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge guint8 lm_challenge_response[24]; guint32 i; guint32 j; - rc4_state_struct rc4state; + gcry_cipher_hd_t rc4_handle; size_t user_len; size_t domain_len; md4_pass *pass_list = NULL; @@ -594,14 +602,18 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge memset(buf, 0, BUF_SIZE); memcpy(buf, user_uppercase, user_len*2); memcpy(buf+user_len*2, domain_name_unicode, domain_len*2); - md5_hmac(buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN, ntowf); + if (ws_hmac_buffer(GCRY_MD_MD5, ntowf, buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN)) { + return; + } printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n"); /* LM response */ memset(buf, 0, BUF_SIZE); memcpy(buf, serverchallenge, 8); memcpy(buf+8, clientchallenge, 8); - md5_hmac(buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, lm_challenge_response); + if (ws_hmac_buffer(GCRY_MD_MD5, lm_challenge_response, buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { + return; + } memcpy(lm_challenge_response+NTLMSSP_KEY_LEN, clientchallenge, 8); printnbyte(lm_challenge_response, 24, "LM Response: ", "\n"); @@ -609,7 +621,9 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge memset(buf, 0, BUF_SIZE); memcpy(buf, serverchallenge, 8); memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, MIN(BUF_SIZE - 8, ntlm_response->length-NTLMSSP_KEY_LEN)); - md5_hmac(buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN, nt_proof); + if (ws_hmac_buffer(GCRY_MD_MD5, nt_proof, buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN)) { + return; + } printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n"); if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) { found = TRUE; @@ -620,14 +634,21 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge return; } - md5_hmac(nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, sessionbasekey); + if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { + return; + } + get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags); /* now decrypt session key if needed and setup sessionkey for decrypting further communications */ if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); - crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN); - crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN); + if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { + gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); + } + gcry_cipher_close(rc4_handle); + } } else { @@ -651,7 +672,6 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co unsigned char lm_password_upper[NTLMSSP_KEY_LEN]; unsigned char lm_password_hash[NTLMSSP_KEY_LEN]; unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; - unsigned char challenges_hash[NTLMSSP_KEY_LEN]; unsigned char challenges_hash_first8[8]; unsigned char challenges[NTLMSSP_KEY_LEN]; guint8 md4[NTLMSSP_KEY_LEN]; @@ -660,8 +680,8 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co guint8 keyexchangekey[NTLMSSP_KEY_LEN]; guint8 lm_challenge_response[24]; guint8 nt_challenge_response[24]; - rc4_state_struct rc4state; - md5_state_t md5state; + gcry_cipher_hd_t rc4_handle; + gcry_md_hd_t md5_handle; char nt_password_unicode[256]; size_t password_len; unsigned int i; @@ -679,7 +699,7 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co password_len = strlen(nt_password); /*Do not forget to free nt_password_nt*/ str_to_unicode(nt_password, nt_password_unicode); - crypt_md4(nt_password_hash, nt_password_unicode, password_len*2); + gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); /* Truncate password if too long */ if (password_len > NTLMSSP_KEY_LEN) password_len = NTLMSSP_KEY_LEN; @@ -717,11 +737,13 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co if(clientchallenge){ memcpy(lm_challenge_response, clientchallenge, 8); } - md5_init(&md5state); - md5_append(&md5state, serverchallenge, 8); - md5_append(&md5state, clientchallenge, 8); - md5_finish(&md5state, challenges_hash); - memcpy(challenges_hash_first8, challenges_hash, 8); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + break; + } + gcry_md_write(md5_handle, serverchallenge, 8); + gcry_md_write(md5_handle, clientchallenge, 8); + memcpy(challenges_hash_first8, gcry_md_read(md5_handle, 0), 8); + gcry_md_close(md5_handle); crypt_des_ecb_long(nt_challenge_response, nt_password_hash, challenges_hash_first8); if (ref_nt_challenge_response && !memcmp(ref_nt_challenge_response, nt_challenge_response, 24)) { found = TRUE; @@ -748,14 +770,15 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth * Otherwise it should be lm_password_hash ...*/ - crypt_md4(md4, nt_password_hash, NTLMSSP_KEY_LEN); + gcry_md_hash_buffer(GCRY_MD_MD4, md4, nt_password_hash, NTLMSSP_KEY_LEN); if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) { memcpy(challenges, serverchallenge, 8); if(clientchallenge){ memcpy(challenges+8, clientchallenge, 8); } - /*md5_hmac(text, text_len, key, key_len, digest);*/ - md5_hmac(challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN, sessionbasekey); + if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN)) { + return; + } } else { memcpy(sessionbasekey, md4, NTLMSSP_KEY_LEN); @@ -776,8 +799,12 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co if(encryptedsessionkey){ memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); } - crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN); - crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN); + if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { + gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); + } + gcry_cipher_close(rc4_handle); + } } else { @@ -789,20 +816,21 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co static void get_siging_key(guint8 *sign_key_server, guint8* sign_key_client, const guint8 key[NTLMSSP_KEY_LEN], int keylen) { - md5_state_t md5state; - md5_state_t md5state2; + gcry_md_hd_t md5_handle; memset(sign_key_client, 0, NTLMSSP_KEY_LEN); memset(sign_key_server, 0, NTLMSSP_KEY_LEN); - md5_init(&md5state); - md5_append(&md5state, key, keylen); - md5_append(&md5state, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1); - md5_finish(&md5state, sign_key_client); - md5_init(&md5state2); - md5_append(&md5state2, key, keylen); - md5_append(&md5state2, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1); - md5_finish(&md5state2, sign_key_server); - + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, key, keylen); + gcry_md_write(md5_handle, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1); + memcpy(sign_key_client, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_reset(md5_handle); + gcry_md_write(md5_handle, key, keylen); + gcry_md_write(md5_handle, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1); + memcpy(sign_key_server, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_close(md5_handle); } /* We return either a 128 or 64 bit key @@ -811,8 +839,7 @@ static void get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int flags , int *keylen , guint8 *clientsealkey , guint8 *serversealkey) { - md5_state_t md5state; - md5_state_t md5state2; + gcry_md_hd_t md5_handle; memset(clientsealkey, 0, NTLMSSP_KEY_LEN); memset(serversealkey, 0, NTLMSSP_KEY_LEN); @@ -838,14 +865,17 @@ get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int } } memcpy(serversealkey, clientsealkey, NTLMSSP_KEY_LEN); - md5_init(&md5state); - md5_append(&md5state, clientsealkey,*keylen); - md5_append(&md5state, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1); - md5_finish(&md5state, clientsealkey); - md5_init(&md5state2); - md5_append(&md5state2, serversealkey,*keylen); - md5_append(&md5state2, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1); - md5_finish(&md5state2, serversealkey); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, clientsealkey, *keylen); + gcry_md_write(md5_handle, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1); + memcpy(clientsealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_reset(md5_handle); + gcry_md_write(md5_handle, serversealkey, *keylen); + gcry_md_write(md5_handle, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1); + memcpy(serversealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_close(md5_handle); } else { @@ -1485,6 +1515,7 @@ dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset, */ if (!conv_ntlmssp_info || memcmp(tmp, conv_ntlmssp_info->server_challenge, 8) != 0) { conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); + wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); /* Insert the flags into the conversation */ conv_ntlmssp_info->flags = negotiate_flags; /* Insert the RC4 state information into the conversation */ @@ -1506,12 +1537,23 @@ dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset, create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge, NULL, sspkey, NULL, conv_ntlmssp_info->flags, conv_ntlmssp_info->ntlm_response.contents, conv_ntlmssp_info->lm_response.contents, ntlmssph); if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len); - conv_ntlmssp_info->server_dest_port = pinfo->destport; - conv_ntlmssp_info->rc4_state_initialized = 1; + if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, sspkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + conv_ntlmssp_info->rc4_handle_client = NULL; + } + } + if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, sspkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + conv_ntlmssp_info->rc4_handle_server = NULL; + } + } + if (conv_ntlmssp_info->rc4_handle_client && conv_ntlmssp_info->rc4_handle_server) { + conv_ntlmssp_info->server_dest_port = pinfo->destport; + conv_ntlmssp_info->rc4_state_initialized = 1; + } } - } conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); } @@ -1623,6 +1665,7 @@ dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp); if (conv_ntlmssp_info == NULL) { conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); + wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); } /* XXX: The *conv_ntlmssp_info struct attached to the frame is the @@ -1806,10 +1849,22 @@ dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server, (guint8*)&conv_ntlmssp_info->sign_key_client, sspkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len); - conv_ntlmssp_info->server_dest_port = pinfo->destport; - conv_ntlmssp_info->rc4_state_initialized = 1; + if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, serverkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + conv_ntlmssp_info->rc4_handle_server = NULL; + } + } + if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, clientkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + conv_ntlmssp_info->rc4_handle_client = NULL; + } + } + if (conv_ntlmssp_info->rc4_handle_server && conv_ntlmssp_info->rc4_handle_client) { + conv_ntlmssp_info->server_dest_port = pinfo->destport; + conv_ntlmssp_info->rc4_state_initialized = 1; + } } } } @@ -1857,7 +1912,7 @@ get_sign_key(packet_info *pinfo, int cryptpeer) * Get the encryption state tied to this conversation. cryptpeer indicates * whether to retrieve the client key (1) or the server key (0) */ -static rc4_state_struct * +static gcry_cipher_hd_t get_encrypted_state(packet_info *pinfo, int cryptpeer) { conversation_t *conversation; @@ -1885,9 +1940,9 @@ get_encrypted_state(packet_info *pinfo, int cryptpeer) crypt state tied to the requested peer */ if (cryptpeer == 1) { - return &conv_ntlmssp_info->rc4_state_client; + return conv_ntlmssp_info->rc4_handle_client; } else { - return &conv_ntlmssp_info->rc4_state_server; + return conv_ntlmssp_info->rc4_handle_server; } } } @@ -1900,15 +1955,6 @@ static void decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, packet_info *pinfo, proto_tree *tree, gpointer key); -#if 0 -static tvbuff_t * -dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb, - tvbuff_t *auth_tvb _U_, - int offset, - packet_info *pinfo, - dcerpc_auth_info *auth_info _U_) -#endif - static int dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { @@ -2027,23 +2073,23 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/ } else { - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; + gcry_cipher_hd_t rc4_handle; + gcry_cipher_hd_t rc4_handle_peer; /* Get the pair of RC4 state structures. One is used for to decrypt the payload. The other is used to re-encrypt the payload to represent the peer */ if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { /* client */ - rc4_state = get_encrypted_state(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); + rc4_handle = get_encrypted_state(pinfo, 1); + rc4_handle_peer = get_encrypted_state(pinfo, 0); } else { /* server */ - rc4_state = get_encrypted_state(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); + rc4_handle = get_encrypted_state(pinfo, 0); + rc4_handle_peer = get_encrypted_state(pinfo, 1); } - if (rc4_state == NULL) { + if (rc4_handle == NULL) { /* There is no encryption state, so we cannot decrypt */ return NULL; } @@ -2060,8 +2106,8 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, } /* Do the decryption of the payload */ - crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length); + gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->decrypted_payload, encrypted_block_length, NULL, 0); + /* decrypt the verifier */ /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/ /* We setup a temporary buffer so we can re-encrypt the payload after @@ -2071,7 +2117,7 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) { guint8 *peer_block; peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); + gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0); } packet_ntlmssp_info->payload_decrypted = TRUE; @@ -2190,8 +2236,8 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, proto_tree *decr_tree; conversation_t *conversation; guint8* sign_key; - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; + gcry_cipher_hd_t rc4_handle; + gcry_cipher_hd_t rc4_handle_peer; tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ guint8 *peer_block; guint8 *check_buf; @@ -2239,16 +2285,16 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, } if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { /* client talk to server */ - rc4_state = get_encrypted_state(pinfo, 1); + rc4_handle = get_encrypted_state(pinfo, 1); sign_key = get_sign_key(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); + rc4_handle_peer = get_encrypted_state(pinfo, 0); } else { - rc4_state = get_encrypted_state(pinfo, 0); + rc4_handle = get_encrypted_state(pinfo, 0); sign_key = get_sign_key(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); + rc4_handle_peer = get_encrypted_state(pinfo, 1); } - if (rc4_state == NULL || rc4_state_peer == NULL) { + if (rc4_handle == NULL || rc4_handle_peer == NULL) { /* There is no encryption state, so we cannot decrypt */ return; } @@ -2263,7 +2309,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, /* The spec says that if we have have a key exchange then we have a the signature that is crypted * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7] */ - crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, 8); + if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, 8, NULL, 0)) { + return; + } } /* * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but @@ -2275,7 +2323,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, tvb_memcpy(tvb, &sequence, offset+8, 4); memcpy(check_buf, &sequence, 4); memcpy(check_buf+4, packet_ntlmssp_info->decrypted_payload, packet_ntlmssp_info->payload_len); - md5_hmac(check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN, calculated_md5); + if (ws_hmac_buffer(GCRY_MD_MD5, calculated_md5, check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN)) { + return; + } /* printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n"); printnbyte(calculated_md5, 8, "HMAC : ", "\n"); @@ -2285,8 +2335,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, else { /* The packet has a PAD then a checksum then a sequence and they are encoded in this order so we can decrypt all at once */ /* Do the actual decryption of the verifier */ - crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, - encrypted_block_length); + if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, encrypted_block_length, NULL, 0)) { + return; + } } @@ -2297,7 +2348,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, and it's also not needed when we have key exchange because server and client have independent keys */ if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) { peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->verifier, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); + if (gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0)) { + return; + } } /* Mark the packet as decrypted so that subsequent attempts to dissect @@ -2481,97 +2534,6 @@ wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb, tvbuff_t *auth_tvb _U_, return decrypted_tvb; } -#if 0 -static tvbuff_t * -dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb, - tvbuff_t *auth_tvb _U_, - int offset, - packet_info *pinfo, - dcerpc_auth_info *auth_info _U_) -{ - /* gssapi_decrypted_tvb = NULL */ - tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ - guint8 *peer_block; - conversation_t *conversation; - guint32 encrypted_block_length; - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; - ntlmssp_info *conv_ntlmssp_info = NULL; - ntlmssp_packet_info *packet_ntlmssp_info; - - encrypted_block_length = tvb_length_remaining (data_tvb, offset); - - fprintf(stderr, "Called dissect_ntlmssp_encrypted_payload\n"); - /* Check to see if we already have state for this packet */ - packet_ntlmssp_info = p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY); - if (packet_ntlmssp_info == NULL) { - /* We don't have any packet state, so create one */ - packet_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_packet_info); - p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY, packet_ntlmssp_info); - } - - if (!packet_ntlmssp_info->payload_decrypted) { - /* Pull the challenge info from the conversation */ - conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->srcport, - pinfo->destport, 0); - if (conversation == NULL) { - /* There is no conversation, thus no encryption state */ - return NULL; - - } - conv_ntlmssp_info = conversation_get_proto_data(conversation, - proto_ntlmssp); - if (conv_ntlmssp_info == NULL) { - /* There is no NTLMSSP state tied to the conversation */ - return NULL; - } - /* Get the pair of RC4 state structures. One is used for to decrypt the - payload. The other is used to re-encrypt the payload to represent - the peer */ - if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { - rc4_state = get_encrypted_state(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); - } else { - rc4_state = get_encrypted_state(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); - } - - if (rc4_state == NULL || rc4_state_peer == NULL) { - /* There is no encryption state, so we cannot decrypt */ - return NULL; - } - - /* Store the decrypted contents in the packet state struct - (of course at this point, they aren't decrypted yet) */ - packet_ntlmssp_info->decrypted_payload = tvb_memdup(wmem_file_scope(), data_tvb, offset, - encrypted_block_length); - decrypted_payloads = g_slist_prepend(decrypted_payloads, - packet_ntlmssp_info->decrypted_payload); - - /* Do the decryption of the payload */ - crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length); - - /* We setup a temporary buffer so we can re-encrypt the payload after - decryption. This is to update the opposite peer's RC4 state */ - peer_block = wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); - - packet_ntlmssp_info->payload_decrypted = TRUE; - } - - /* Show the decrypted buffer in a new window */ - decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length, - encrypted_block_length); - - offset += encrypted_block_length; - - return decr_tvb; -} -#endif - static guint header_hash(gconstpointer pointer) { diff --git a/epan/dissectors/packet-radius.c b/epan/dissectors/packet-radius.c index a40e0ad8bc..1909ff43fd 100644 --- a/epan/dissectors/packet-radius.c +++ b/epan/dissectors/packet-radius.c @@ -68,7 +68,7 @@ #include #include #include -#include +#include #include "packet-radius.h" @@ -912,8 +912,8 @@ dissect_rfc4675_egress_vlan_name(proto_tree *tree, tvbuff_t *tvb, packet_info *p static void radius_decrypt_avp(gchar *dest, int dest_len, tvbuff_t *tvb, int offset, int length) { - md5_state_t md_ctx, old_md_ctx; - md5_byte_t digest[AUTHENTICATOR_LENGTH]; + gcry_md_hd_t md5_handle, old_md5_handle; + guint8 digest[HASH_MD5_LENGTH]; int i, j; gint totlen = 0, returned_length, padded_length; guint8 *pd; @@ -932,11 +932,17 @@ radius_decrypt_avp(gchar *dest, int dest_len, tvbuff_t *tvb, int offset, int len if (length > 128) length = 128; - md5_init(&md_ctx); - md5_append(&md_ctx, (const guint8 *)shared_secret, (int)strlen(shared_secret)); - old_md_ctx = md_ctx; - md5_append(&md_ctx, authenticator, AUTHENTICATOR_LENGTH); - md5_finish(&md_ctx, digest); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, (const guint8 *)shared_secret, (int)strlen(shared_secret)); + if (gcry_md_copy(&old_md5_handle, md5_handle)) { + gcry_md_close(md5_handle); + return; + } + gcry_md_write(md5_handle, authenticator, AUTHENTICATOR_LENGTH); + memcpy(digest, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); padded_length = length + ((length % AUTHENTICATOR_LENGTH) ? (AUTHENTICATOR_LENGTH - (length % AUTHENTICATOR_LENGTH)) : 0); @@ -958,10 +964,16 @@ radius_decrypt_avp(gchar *dest, int dest_len, tvbuff_t *tvb, int offset, int len } } - md_ctx = old_md_ctx; - md5_append(&md_ctx, &pd[i], AUTHENTICATOR_LENGTH); - md5_finish(&md_ctx, digest); + if (gcry_md_copy(&md5_handle, old_md5_handle)) { + gcry_md_close(old_md5_handle); + return; + } + gcry_md_write(md5_handle, &pd[i], AUTHENTICATOR_LENGTH); + memcpy(digest, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); } + + gcry_md_close(old_md5_handle); } @@ -1778,8 +1790,9 @@ is_radius(tvbuff_t *tvb) static gboolean valid_authenticator(tvbuff_t *tvb, guint8 request_authenticator[]) { - md5_state_t md_ctx; - md5_byte_t digest[16]; + gcry_md_hd_t md5_handle; + guint8 *digest; + gboolean result; guint tvb_length; guint8 *payload; @@ -1792,12 +1805,16 @@ valid_authenticator(tvbuff_t *tvb, guint8 request_authenticator[]) memcpy(payload+4, request_authenticator, AUTHENTICATOR_LENGTH); /* calculate MD5 hash (payload+shared_secret) */ - md5_init(&md_ctx); - md5_append(&md_ctx, payload, tvb_length); - md5_append(&md_ctx, shared_secret, strlen(shared_secret)); - md5_finish(&md_ctx, digest); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return FALSE; + } + gcry_md_write(md5_handle, payload, tvb_length); + gcry_md_write(md5_handle, shared_secret, strlen(shared_secret)); + digest = gcry_md_read(md5_handle, 0); - return !memcmp(digest, authenticator, AUTHENTICATOR_LENGTH); + result = !memcmp(digest, authenticator, AUTHENTICATOR_LENGTH); + gcry_md_close(md5_handle); + return result; } static int diff --git a/epan/dissectors/packet-sigcomp.c b/epan/dissectors/packet-sigcomp.c index d345137e6c..6983fdc40e 100644 --- a/epan/dissectors/packet-sigcomp.c +++ b/epan/dissectors/packet-sigcomp.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include void proto_register_sigcomp(void); @@ -1784,7 +1784,7 @@ decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet guint maximum_UDVM_cycles; guint8 *sha1buff; unsigned char sha1_digest_buf[STATE_BUFFER_SIZE]; - sha1_context ctx; + gcry_md_hd_t sha1_handle; proto_item *addr_item = NULL; @@ -2486,7 +2486,9 @@ execute_next_instruction: NULL, "byte_copy_right = %u", byte_copy_right); } - sha1_starts( &ctx ); + if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) { + goto decompression_failure; + } while (n= UDVM_MEMORY_SIZE) + if (k + handle_now >= UDVM_MEMORY_SIZE) { + gcry_md_close(sha1_handle); goto decompression_failure; - sha1_update( &ctx, &buff[k], handle_now ); + } + gcry_md_write(sha1_handle, &buff[k], handle_now); k = ( k + handle_now ) & 0xffff; n = ( n + handle_now ) & 0xffff; @@ -2507,7 +2511,8 @@ execute_next_instruction: } } - sha1_finish( &ctx, sha1_digest_buf ); + memcpy(sha1_digest_buf, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(sha1_handle); k = ref_destination; @@ -4368,12 +4373,9 @@ execute_next_instruction: k = ( k + 1 ) & 0xffff; } - sha1_starts( &ctx ); - sha1_update( &ctx, (guint8 *) sha1buff, state_length_buff[n] + 8); - sha1_finish( &ctx, sha1_digest_buf ); + gcry_md_hash_buffer(GCRY_MD_SHA1, sha1_digest_buf, (guint8 *) sha1buff, state_length_buff[n] + 8); if (print_level_3 ) { proto_tree_add_bytes_with_length(udvm_tree, hf_sigcomp_sha1_digest, bytecode_tvb, 0, -1, sha1_digest_buf, STATE_BUFFER_SIZE); - } /* begin partial state-id change cco@iptel.org */ #if 0 @@ -4919,8 +4921,8 @@ dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tr proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset +2; - proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, SHA1_DIGEST_LEN, ENC_NA); - offset = offset +SHA1_DIGEST_LEN; + proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, HASH_SHA1_LENGTH, ENC_NA); + offset = offset + HASH_SHA1_LENGTH; /* Add NACK info to info column */ col_append_fstr(pinfo->cinfo, COL_INFO, " NACK reason=%s, opcode=%s", diff --git a/epan/dissectors/packet-snmp.c b/epan/dissectors/packet-snmp.c index 6473b1003b..1fad9344b2 100644 --- a/epan/dissectors/packet-snmp.c +++ b/epan/dissectors/packet-snmp.c @@ -68,13 +68,10 @@ #include #include #include -#include -#include #include "packet-ipx.h" #include "packet-hpext.h" #include "packet-ber.h" #include "packet-snmp.h" - #include #define PNAME "Simple Network Management Protocol" @@ -114,7 +111,7 @@ static void snmp_usm_password_to_key_sha1(const guint8 *password, guint password static snmp_usm_auth_model_t model_md5 = {snmp_usm_password_to_key_md5, snmp_usm_auth_md5, 16}; -static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, SHA1_DIGEST_LEN}; +static snmp_usm_auth_model_t model_sha1 = {snmp_usm_password_to_key_sha1, snmp_usm_auth_sha1, 20}; static const value_string auth_types[] = { {0,"MD5"}, @@ -294,7 +291,7 @@ static int hf_snmp_priority = -1; /* INTEGER_M1_2147483647 */ static int hf_snmp_operation = -1; /* T_operation */ /*--- End of included file: packet-snmp-hf.c ---*/ -#line 220 "./asn1/snmp/packet-snmp-template.c" +#line 217 "./asn1/snmp/packet-snmp-template.c" /* Initialize the subtree pointers */ static gint ett_smux = -1; @@ -334,7 +331,7 @@ static gint ett_snmp_SimpleOpen_U = -1; static gint ett_snmp_RReqPDU_U = -1; /*--- End of included file: packet-snmp-ett.c ---*/ -#line 236 "./asn1/snmp/packet-snmp-template.c" +#line 233 "./asn1/snmp/packet-snmp-template.c" static expert_field ei_snmp_failed_decrypted_data_pdu = EI_INIT; static expert_field ei_snmp_decrypted_data_bad_formatted = EI_INIT; @@ -1677,9 +1674,11 @@ snmp_usm_auth_md5(snmp_usm_params_t* p, guint8** calc_auth_p, guint* calc_auth_l msg[i] = '\0'; } - calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), 16); + calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), HASH_MD5_LENGTH); - md5_hmac(msg, msg_len, key, key_len, calc_auth); + if (ws_hmac_buffer(GCRY_MD_MD5, calc_auth, msg, msg_len, key, key_len)) { + return FALSE; + } if (calc_auth_p) *calc_auth_p = calc_auth; if (calc_auth_len_p) *calc_auth_len_p = 12; @@ -1741,9 +1740,11 @@ snmp_usm_auth_sha1(snmp_usm_params_t* p _U_, guint8** calc_auth_p, guint* calc_a msg[i] = '\0'; } - calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), SHA1_DIGEST_LEN); + calc_auth = (guint8*)wmem_alloc(wmem_packet_scope(), HASH_SHA1_LENGTH); - sha1_hmac(key, key_len, msg, msg_len, calc_auth); + if (ws_hmac_buffer(GCRY_MD_SHA1, calc_auth, msg, msg_len, key, key_len)) { + return FALSE; + } if (calc_auth_p) *calc_auth_p = calc_auth; if (calc_auth_len_p) *calc_auth_len_p = 12; @@ -3047,7 +3048,7 @@ static int dissect_SMUX_PDUs_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, prot /*--- End of included file: packet-snmp-fn.c ---*/ -#line 1842 "./asn1/snmp/packet-snmp-template.c" +#line 1843 "./asn1/snmp/packet-snmp-template.c" guint @@ -3340,12 +3341,14 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key) { - md5_state_t MD; guint8 *cp, password_buf[64]; guint32 password_index = 0; guint32 count = 0, i; guint8 key1[16]; - md5_init(&MD); /* initialize MD5 */ + gcry_md_hd_t md5_handle; + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } /**********************************************/ /* Use while loop until we've done 1 Megabyte */ @@ -3363,10 +3366,11 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, } else { *cp = 0; } - md5_append(&MD, password_buf, 64); + gcry_md_write(md5_handle, password_buf, 64); count += 64; } - md5_finish(&MD, key1); /* tell MD5 we're done */ + memcpy(key1, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); /*****************************************************/ /* Now localize the key with the engineID and pass */ @@ -3375,11 +3379,14 @@ snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, /* checking is done in snmp_users_update_cb. */ /*****************************************************/ - md5_init(&MD); - md5_append(&MD, key1, 16); - md5_append(&MD, engineID, engineLength); - md5_append(&MD, key1, 16); - md5_finish(&MD, key); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, key1, HASH_MD5_LENGTH); + gcry_md_write(md5_handle, engineID, engineLength); + gcry_md_write(md5_handle, key1, HASH_MD5_LENGTH); + memcpy(key, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); return; } @@ -3396,12 +3403,14 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key) { - sha1_context SH; + gcry_md_hd_t sha1_handle; guint8 *cp, password_buf[64]; guint32 password_index = 0; guint32 count = 0, i; - sha1_starts(&SH); /* initialize SHA */ + if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) { + return; + } /**********************************************/ /* Use while loop until we've done 1 Megabyte */ @@ -3419,10 +3428,11 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, } else { *cp = 0; } - sha1_update (&SH, password_buf, 64); + gcry_md_write(sha1_handle, password_buf, 64); count += 64; } - sha1_finish(&SH, key); + memcpy(key, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(sha1_handle); /*****************************************************/ /* Now localize the key with the engineID and pass */ @@ -3430,12 +3440,14 @@ snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen, /* We ignore invalid engineLengths here. More strict */ /* checking is done in snmp_users_update_cb. */ /*****************************************************/ - - sha1_starts(&SH); - sha1_update(&SH, key, SHA1_DIGEST_LEN); - sha1_update(&SH, engineID, engineLength); - sha1_update(&SH, key, SHA1_DIGEST_LEN); - sha1_finish(&SH, key); + if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) { + return; + } + gcry_md_write(sha1_handle, key, HASH_SHA1_LENGTH); + gcry_md_write(sha1_handle, engineID, engineLength); + gcry_md_write(sha1_handle, key, HASH_SHA1_LENGTH); + memcpy(key, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH); + gcry_md_close(sha1_handle); return; } @@ -3864,7 +3876,7 @@ void proto_register_snmp(void) { NULL, HFILL }}, /*--- End of included file: packet-snmp-hfarr.c ---*/ -#line 2394 "./asn1/snmp/packet-snmp-template.c" +#line 2406 "./asn1/snmp/packet-snmp-template.c" }; /* List of subtrees */ @@ -3904,7 +3916,7 @@ void proto_register_snmp(void) { &ett_snmp_RReqPDU_U, /*--- End of included file: packet-snmp-ettarr.c ---*/ -#line 2410 "./asn1/snmp/packet-snmp-template.c" +#line 2422 "./asn1/snmp/packet-snmp-template.c" }; static ei_register_info ei[] = { { &ei_snmp_failed_decrypted_data_pdu, { "snmp.failed_decrypted_data_pdu", PI_MALFORMED, PI_WARN, "Failed to decrypt encryptedPDU", EXPFILL }}, diff --git a/epan/dissectors/packet-spnego.c b/epan/dissectors/packet-spnego.c index 9c96f23fd4..df7e3ddf3f 100644 --- a/epan/dissectors/packet-spnego.c +++ b/epan/dissectors/packet-spnego.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include "packet-dcerpc.h" #include "packet-gssapi.h" #include "packet-kerberos.h" @@ -766,8 +766,6 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d } #ifdef HAVE_KERBEROS -#include - #ifndef KEYTYPE_ARCFOUR_56 # define KEYTYPE_ARCFOUR_56 24 #endif @@ -784,23 +782,25 @@ arcfour_mic_key(const guint8 *key_data, size_t key_size, int key_type, const guint8 *cksum_data, size_t cksum_size, guint8 *key6_data) { - guint8 k5_data[16]; - guint8 T[4]; - - memset(T, 0, 4); + guint8 k5_data[HASH_MD5_LENGTH]; + guint8 T[4] = { 0 }; if (key_type == KEYTYPE_ARCFOUR_56) { guint8 L40[14] = "fortybits"; - memcpy(L40 + 10, T, sizeof(T)); - md5_hmac(L40, 14, key_data, key_size, k5_data); + if (ws_hmac_buffer(GCRY_MD_MD5, k5_data, L40, 14, key_data, key_size)) { + return 0; + } memset(&k5_data[7], 0xAB, 9); } else { - md5_hmac(T, 4, key_data, key_size, k5_data); + if (ws_hmac_buffer(GCRY_MD_MD5, k5_data, T, 4, key_data, key_size)) { + return 0; + } } - md5_hmac(cksum_data, cksum_size, k5_data, 16, key6_data); - + if (ws_hmac_buffer(GCRY_MD_MD5, key6_data, cksum_data, cksum_size, k5_data, HASH_MD5_LENGTH)) { + return 0; + } return 0; } @@ -831,26 +831,35 @@ arcfour_mic_cksum(guint8 *key_data, int key_length, const guint8 *v3, size_t l3) { static const guint8 signature[] = "signaturekey"; - guint8 ksign_c[16]; + guint8 ksign_c[HASH_MD5_LENGTH]; guint8 t[4]; - md5_state_t ms; - guint8 digest[16]; + guint8 digest[HASH_MD5_LENGTH]; int rc4_usage; - guint8 cksum[16]; + guint8 cksum[HASH_MD5_LENGTH]; + gcry_md_hd_t md5_handle; rc4_usage=usage2arcfour(usage); - md5_hmac(signature, sizeof(signature), key_data, key_length, ksign_c); - md5_init(&ms); + if (ws_hmac_buffer(GCRY_MD_MD5, ksign_c, signature, sizeof(signature), key_data, key_length)) { + return 0; + } + + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return 0; + } t[0] = (rc4_usage >> 0) & 0xFF; t[1] = (rc4_usage >> 8) & 0xFF; t[2] = (rc4_usage >> 16) & 0xFF; t[3] = (rc4_usage >> 24) & 0xFF; - md5_append(&ms, t, 4); - md5_append(&ms, v1, l1); - md5_append(&ms, v2, l2); - md5_append(&ms, v3, l3); - md5_finish(&ms, digest); - md5_hmac(digest, 16, ksign_c, 16, cksum); + gcry_md_write(md5_handle, t, 4); + gcry_md_write(md5_handle, v1, l1); + gcry_md_write(md5_handle, v2, l2); + gcry_md_write(md5_handle, v3, l3); + memcpy(digest, gcry_md_read(md5_handle, 0), HASH_MD5_LENGTH); + gcry_md_close(md5_handle); + + if (ws_hmac_buffer(GCRY_MD_MD5, cksum, digest, HASH_MD5_LENGTH, ksign_c, HASH_MD5_LENGTH)) { + return 0; + } memcpy(sgn_cksum, cksum, 8); @@ -898,7 +907,7 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf int cmp; int conf_flag; int padlen = 0; - rc4_state_struct rc4_state; + gcry_cipher_hd_t rc4_handle; int i; datalen = tvb_captured_length(gssapi_encrypt->gssapi_encrypted_tvb); @@ -923,9 +932,16 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf return -5; } - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, SND_SEQ, 8, 8); - crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return -12; + } + if (gcry_cipher_setkey(rc4_handle, k6_data, sizeof(k6_data))) { + gcry_cipher_close(rc4_handle); + return -13; + } + gcry_cipher_decrypt(rc4_handle, (guint8 *)SND_SEQ, 8, NULL, 0); + gcry_cipher_close(rc4_handle); memset(k6_data, 0, sizeof(k6_data)); @@ -949,11 +965,18 @@ decrypt_arcfour(gssapi_encrypt_info_t* gssapi_encrypt, guint8 *input_message_buf if(conf_flag) { - crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data)); tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); - crypt_rc4(&rc4_state, Confounder, 8); - memcpy(output_message_buffer, input_message_buffer, datalen); - crypt_rc4(&rc4_state, output_message_buffer, datalen); + if (gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + return -14; + } + if (gcry_cipher_setkey(rc4_handle, k6_data, sizeof(k6_data))) { + gcry_cipher_close(rc4_handle); + return -15; + } + + gcry_cipher_decrypt(rc4_handle, Confounder, 8, NULL, 0); + gcry_cipher_decrypt(rc4_handle, output_message_buffer, datalen, input_message_buffer, datalen); + gcry_cipher_close(rc4_handle); } else { tvb_memcpy(gssapi_encrypt->gssapi_wrap_tvb, Confounder, 24, 8); memcpy(output_message_buffer, input_message_buffer, datalen); @@ -1913,7 +1936,7 @@ void proto_register_spnego(void) { NULL, HFILL }}, /*--- End of included file: packet-spnego-hfarr.c ---*/ -#line 1368 "./asn1/spnego/packet-spnego-template.c" +#line 1391 "./asn1/spnego/packet-spnego-template.c" }; /* List of subtrees */ @@ -1936,7 +1959,7 @@ void proto_register_spnego(void) { &ett_spnego_InitialContextToken_U, /*--- End of included file: packet-spnego-ettarr.c ---*/ -#line 1378 "./asn1/spnego/packet-spnego-template.c" +#line 1401 "./asn1/spnego/packet-spnego-template.c" }; static ei_register_info ei[] = { diff --git a/epan/dissectors/packet-tacacs.c b/epan/dissectors/packet-tacacs.c index ec90469db7..b1dc48be6a 100644 --- a/epan/dissectors/packet-tacacs.c +++ b/epan/dissectors/packet-tacacs.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include /* ws_debug_printf */ #include "packet-tacacs.h" @@ -1280,23 +1280,19 @@ proto_reg_handoff_tacplus(void) dissector_add_uint_with_preference("tcp.port", TCP_PORT_TACACS, tacplus_handle); } - -#define MD5_LEN 16 - static void md5_xor( guint8 *data, const char *key, int data_len, guint8 *session_id, guint8 version, guint8 seq_no ) { int i,j; size_t md5_len; - md5_byte_t *md5_buff; - md5_byte_t hash[MD5_LEN]; /* the md5 hash */ - md5_byte_t *mdp; - md5_state_t mdcontext; + guint8 *md5_buff; + guint8 hash[HASH_MD5_LENGTH]; /* the md5 hash */ + guint8 *mdp; md5_len = 4 /* sizeof(session_id) */ + strlen(key) + sizeof(version) + sizeof(seq_no); - md5_buff = (md5_byte_t*)wmem_alloc(wmem_packet_scope(), md5_len+MD5_LEN); + md5_buff = (guint8*)wmem_alloc(wmem_packet_scope(), md5_len + HASH_MD5_LENGTH); mdp = md5_buff; @@ -1308,10 +1304,8 @@ md5_xor( guint8 *data, const char *key, int data_len, guint8 *session_id, guint8 *mdp++ = seq_no; - md5_init(&mdcontext); - md5_append(&mdcontext, md5_buff, md5_len); - md5_finish(&mdcontext,hash); - md5_len += MD5_LEN; + gcry_md_hash_buffer(GCRY_MD_MD5, hash, md5_buff, md5_len); + md5_len += HASH_MD5_LENGTH; for (i = 0; i < data_len; i += 16) { for (j = 0; j < 16; j++) { @@ -1321,10 +1315,8 @@ md5_xor( guint8 *data, const char *key, int data_len, guint8 *session_id, guint8 } data[i + j] ^= hash[j]; } - memcpy(mdp, hash, MD5_LEN); - md5_init(&mdcontext); - md5_append(&mdcontext, md5_buff, md5_len); - md5_finish(&mdcontext,hash); + memcpy(mdp, hash, HASH_MD5_LENGTH); + gcry_md_hash_buffer(GCRY_MD_MD5, hash, md5_buff, md5_len); } } diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 08bd75e29e..57c2812e93 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include "packet-tcp.h" @@ -2432,20 +2432,17 @@ tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_, static void mptcp_cryptodata_sha1(const guint64 key, guint32 *token, guint64 *idsn) { - guint8 digest_buf[SHA1_DIGEST_LEN]; + guint8 digest_buf[HASH_SHA1_LENGTH]; guint64 pseudokey = GUINT64_TO_BE(key); - sha1_context sha1_ctx; guint32 _token; guint64 _isdn; - sha1_starts(&sha1_ctx); - sha1_update(&sha1_ctx, (const guint8 *)&pseudokey, 8); - sha1_finish(&sha1_ctx, digest_buf); + gcry_md_hash_buffer(GCRY_MD_SHA1, digest_buf, (const guint8 *)&pseudokey, 8); /* memcpy to prevent -Wstrict-aliasing errors with GCC 4 */ - memcpy(&_token, &digest_buf[0], sizeof(_token)); + memcpy(&_token, digest_buf, sizeof(_token)); *token = GUINT32_FROM_BE(_token); - memcpy(&_isdn, &digest_buf[SHA1_DIGEST_LEN-8], sizeof(_isdn)); + memcpy(&_isdn, digest_buf + HASH_SHA1_LENGTH - sizeof(_isdn), sizeof(_isdn)); *idsn = GUINT64_FROM_BE(_isdn); } diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index 8e0125b0fa..e915e915e5 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -50,27 +50,23 @@ set(WSUTIL_COMMON_FILES inet_addr.c interface.c jsmn.c - md4.c - md5.c mpeg-audio.c nstime.c cpu_info.c os_version_info.c plugins.c privileges.c - sha1.c - sha2.c sober128.c strnatcmp.c str_util.c strtoi.c - rc4.c report_err.c tempfile.c time_util.c type_util.c unicode-utils.c ws_mempbrk.c + wsgcrypt.c wsjsmn.c ) diff --git a/wsutil/Makefile.am b/wsutil/Makefile.am index eba80f941a..e01840f81d 100644 --- a/wsutil/Makefile.am +++ b/wsutil/Makefile.am @@ -69,8 +69,6 @@ libwsutil_nonrepl_INCLUDES = \ inet_ipv6.h \ interface.h \ jsmn.h \ - md4.h \ - md5.h \ mpeg-audio.h \ nstime.h \ os_version_info.h \ @@ -78,10 +76,7 @@ libwsutil_nonrepl_INCLUDES = \ plugins.h \ privileges.h \ processes.h \ - rc4.h \ report_err.h \ - sha1.h \ - sha2.h \ sign_ext.h \ sober128.h \ socket.h \ @@ -147,17 +142,12 @@ libwsutil_la_SOURCES = \ inet_addr.c \ interface.c \ jsmn.c \ - md4.c \ - md5.c \ mpeg-audio.c \ nstime.c \ os_version_info.c \ plugins.c \ privileges.c \ - rc4.c \ report_err.c \ - sha1.c \ - sha2.c \ sober128.c \ str_util.c \ strtoi.c \ @@ -167,6 +157,7 @@ libwsutil_la_SOURCES = \ type_util.c \ unicode-utils.c \ ws_mempbrk.c \ + wsgcrypt.c \ wsjsmn.c if HAVE_OS_X_FRAMEWORKS diff --git a/wsutil/md4.c b/wsutil/md4.c deleted file mode 100644 index f4a3d88119..0000000000 --- a/wsutil/md4.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - Unix SMB/CIFS implementation. - a implementation of MD4 designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997-1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "config.h" - -#include -#include - -#include "md4.h" - -/* NOTE: This code makes no attempt to be fast! - - It assumes that a int is at least 32 bits long -*/ - -static guint32 A, B, C, D; - -static guint32 F(guint32 X, guint32 Y, guint32 Z) -{ - return (X&Y) | ((~X)&Z); -} - -static guint32 G(guint32 X, guint32 Y, guint32 Z) -{ - return (X&Y) | (X&Z) | (Y&Z); -} - -static guint32 H(guint32 X, guint32 Y, guint32 Z) -{ - return X^Y^Z; -} - -static guint32 lshift(guint32 x, int s) -{ - x &= 0xFFFFFFFF; - return ((x<>(32-s)); -} - -#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (guint32)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (guint32)0x6ED9EBA1,s) - -/* this applies md4 to 64 byte chunks */ -static void mdfour64(guint32 *M) -{ - int j; - guint32 AA, BB, CC, DD; - guint32 X[16]; - - for (j=0;j<16;j++) - X[j] = M[j]; - - AA = A; BB = B; CC = C; DD = D; - - ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); - ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); - ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); - ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); - ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); - ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); - ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); - ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); - - ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); - ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); - ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); - ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); - ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); - ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); - ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); - ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); - - ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); - ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); - ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); - ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); - ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); - ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); - ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); - ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); - - A += AA; B += BB; C += CC; D += DD; - - A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; - - for (j=0;j<16;j++) - X[j] = 0; -} - -static void copy64(guint32 *M, const unsigned char *in) -{ - int i; - - for (i=0;i<16;i++) - M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | - (in[i*4+1]<<8) | (in[i*4+0]<<0); -} - -static void copy4(unsigned char *out, guint32 x) -{ - out[0] = x&0xFF; - out[1] = (x>>8)&0xFF; - out[2] = (x>>16)&0xFF; - out[3] = (x>>24)&0xFF; -} - -/* produce a md4 message digest from data of length n bytes */ -void crypt_md4(unsigned char *out, const unsigned char *in, size_t n) -{ - unsigned char buf[128]; - guint32 M[16]; - guint32 b = (guint32)(n * 8); - int i; - - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - - while (n > 64) { - copy64(M, in); - mdfour64(M); - in += 64; - n -= 64; - } - - for (i=0;i<128;i++) - buf[i] = 0; - memcpy(buf, in, n); - buf[n] = 0x80; - - if (n <= 55) { - copy4(buf+56, b); - copy64(M, buf); - mdfour64(M); - } else { - copy4(buf+120, b); - copy64(M, buf); - mdfour64(M); - copy64(M, buf+64); - mdfour64(M); - } - - for (i=0;i<128;i++) - buf[i] = 0; - copy64(M, buf); - - copy4(out, A); - copy4(out+4, B); - copy4(out+8, C); - copy4(out+12, D); - - A = B = C = D = 0; -} - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 8 - * tab-width: 8 - * indent-tabs-mode: t - * End: - * - * vi: set shiftwidth=8 tabstop=8 noexpandtab: - * :indentSize=8:tabSize=8:noTabs=false: - */ diff --git a/wsutil/md4.h b/wsutil/md4.h deleted file mode 100644 index c93a8c15e0..0000000000 --- a/wsutil/md4.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Unix SMB/CIFS implementation. - a implementation of MD4 designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997-1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef _MD4_H -#define _MD4_H - -#include "ws_symbol_export.h" - -WS_DLL_PUBLIC -void crypt_md4(unsigned char *out, const unsigned char *in, size_t n); - -#endif diff --git a/wsutil/md5.c b/wsutil/md5.c deleted file mode 100644 index 55dcd4c0cd..0000000000 --- a/wsutil/md5.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2003-2006 Benny Prijono - * Copyright (C) 2012 C Elston, Katalix Systems Ltd - * - * Wireshark - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * 2012-08-21 - C Elston - Split md5_hmac function to allow incremental usage. - * - */ - - -#include "config.h" - -#include - -#include "pint.h" -#include "md5.h" -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -#if WORDS_BIGENDIAN == 1 -#define HIGHFIRST 1 -#endif - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(guint32 *buf, unsigned int longs) -{ - guint32 t; - do { - t = pletoh32(buf); - *buf = t; - buf++; - } while (--longs); -} -#endif - -static void MD5Transform(guint32 buf[4], guint32 const in[16]); - - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void md5_init(md5_state_t *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void md5_append( md5_state_t *ctx, const guint8 *buf, size_t len) -{ - guint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((guint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += (guint32) len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - guint8 *p = (guint8 *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void md5_finish(md5_state_t *ctx, guint8 digest[16]) -{ - guint count; - guint8 *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = (guint8 *) ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ctx->in[14] = ctx->bits[0]; - ctx->in[15] = ctx->bits[1]; - - MD5Transform(ctx->buf, ctx->in); - byteReverse(ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(md5_state_t)); /* In case it's sensitive */ -} - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void MD5Transform(guint32 buf[4], guint32 const in[16]) -{ - register guint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* from RFC 2104 HMAC Appendix -- Sample Code */ - -void md5_hmac_init(md5_hmac_state_t *hctx, const guint8* key, size_t key_len) -{ - guint8 k_ipad[65]; /* inner padding - * key XORd with ipad */ - guint8 tk[16]; - int i; - - /* if key is longer than 64 bytes reset it to key=MD5(key) */ - if (key_len > 64) { - md5_state_t tctx; - - md5_init(&tctx); - md5_append(&tctx, key, key_len); - md5_finish(&tctx, tk); - - key = tk; - key_len = 16; - } - - /* - * the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in pads */ - memset(k_ipad, 0, sizeof(k_ipad)); - memset(hctx->k_opad, 0, sizeof(hctx->k_opad)); - memcpy(k_ipad, key, key_len); - memcpy(hctx->k_opad, key, key_len); - - /* XOR key with ipad and opad values */ - for (i=0; i<64; i++) { - k_ipad[i] ^= 0x36; - hctx->k_opad[i] ^= 0x5c; - } - - /* - * perform inner MD5 - */ - md5_init(&hctx->ctx); /* init context for 1st pass */ - md5_append(&hctx->ctx, k_ipad, 64); /* start with inner pad */ -} - -void md5_hmac_append(md5_hmac_state_t *hctx, const guint8* text, size_t text_len) -{ - md5_append(&hctx->ctx, text, text_len); -} - -void md5_hmac_finish(md5_hmac_state_t *hctx, guint8 digest[16]) -{ - md5_state_t context; - - md5_finish(&hctx->ctx, digest); /* finish up 1st pass */ - - /* - * perform outer MD5 - */ - md5_init(&context); /* init context for 2nd pass */ - md5_append(&context, hctx->k_opad, 64); /* start with outer pad */ - md5_append(&context, digest, 16); /* then results of 1st hash */ - md5_finish(&context, digest); /* finish up 2nd pass */ -} - -void md5_hmac(const guint8* text, size_t text_len, const guint8* key, size_t key_len, guint8 digest[16]) -{ - md5_hmac_state_t hctx; - - md5_hmac_init(&hctx, key, key_len); - md5_hmac_append(&hctx, text, text_len); - md5_hmac_finish(&hctx, digest); -} - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/wsutil/md5.h b/wsutil/md5.h deleted file mode 100644 index 229b0692d4..0000000000 --- a/wsutil/md5.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2003-2005 Benny Prijono - * Copyright (C) 2012 C Elston, Katalix Systems Ltd - * - * MD5 code from pjlib-util http://www.pjsip.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * 2012-08-21 - C Elston - Split md5_hmac function to allow incremental usage. - * - */ -#ifndef __MD5_H__ /**@todo Should this be _CRYPT_MD5_H__ ?*/ -#define __MD5_H__ - -#include "ws_symbol_export.h" - -/** - * @file md5.h - * @brief MD5 Functions - */ - -/* Don't define this group for Wireshark - * @defgroup PJLIB_UTIL_MD5 MD5 Functions - * @ingroup PJLIB_UTIL - * @{ - */ - -#define md5_byte_t guint8 - -/** MD5 context. */ -typedef struct md5_state_s -{ - guint32 buf[4]; - guint32 bits[2]; - guint32 in[16]; -} md5_state_t; - -/** Initialize the algorithm. - * @param pms MD5 context. - */ -WS_DLL_PUBLIC -void md5_init(md5_state_t *pms); - -/** Append a string to the message. - * @param pms MD5 context. - * @param data Data. - * @param nbytes Length of data. - */ -WS_DLL_PUBLIC -void md5_append( md5_state_t *pms, - const guint8 *data, size_t nbytes); - -/** Finish the message and return the digest. - * @param pms MD5 context. - * @param digest 16 byte digest. - */ -WS_DLL_PUBLIC -void md5_finish(md5_state_t *pms, guint8 digest[16]); - -typedef struct md5_hmac_state_s -{ - md5_state_t ctx; - guint8 k_opad[65]; -} md5_hmac_state_t; - -WS_DLL_PUBLIC -void md5_hmac_init(md5_hmac_state_t *hctx, - const guint8* key, size_t key_len); - -WS_DLL_PUBLIC -void md5_hmac_append(md5_hmac_state_t *hctx, - const guint8* text, size_t text_len); - -WS_DLL_PUBLIC -void md5_hmac_finish(md5_hmac_state_t *hctx, guint8 digest[16]); - -WS_DLL_PUBLIC -void md5_hmac(const guint8* text, size_t text_len, const guint8* key, - size_t key_len, guint8 digest[16]); - -/* - * @} - */ - -#endif /* _CRYPT_MD5_H__ */ diff --git a/wsutil/rc4.c b/wsutil/rc4.c deleted file mode 100644 index 5f91f6ca1a..0000000000 --- a/wsutil/rc4.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a partial implementation of RC4 designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "config.h" - -#include - -#include "rc4.h" - -/* Perform RC4 on a block of data using specified key. "data" is a pointer - to the block to be processed. Output is written to same memory as input, - so caller may need to make a copy before calling this function, since - the input will be overwritten. - - Taken from Samba source code. Modified to allow us to maintain state - between calls to crypt_rc4. -*/ - -void crypt_rc4_init(rc4_state_struct *rc4_state, - const unsigned char *key, int key_len) -{ - int ind; - unsigned char j = 0; - unsigned char *s_box; - - memset(rc4_state, 0, sizeof(rc4_state_struct)); - s_box = rc4_state->s_box; - - for (ind = 0; ind < 256; ind++) - { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (s_box[ind] + key[ind%key_len]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - -} - -void crypt_rc4(rc4_state_struct *rc4_state, unsigned char *data, int data_len) -{ - unsigned char *s_box; - unsigned char index_i; - unsigned char index_j; - int ind; - - /* retrieve current state from the state struct (so we can resume where - we left off) */ - index_i = rc4_state->index_i; - index_j = rc4_state->index_j; - s_box = rc4_state->s_box; - - for( ind = 0; ind < data_len; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } - - /* Store the updated state */ - rc4_state->index_i = index_i; - rc4_state->index_j = index_j; -} - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local Variables: - * c-basic-offset: 2 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=2 tabstop=8 expandtab: - * :indentSize=2:tabSize=8:noTabs=true: - */ diff --git a/wsutil/rc4.h b/wsutil/rc4.h deleted file mode 100644 index 9f18e6bb00..0000000000 --- a/wsutil/rc4.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a partial implementation of RC4 designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __RC4_H__ -#define __RC4_H__ - -#include "ws_symbol_export.h" - -typedef struct _rc4_state_struct { - unsigned char s_box[256]; - unsigned char index_i; - unsigned char index_j; -} rc4_state_struct; - -WS_DLL_PUBLIC -void crypt_rc4_init(rc4_state_struct *rc4_state, - const unsigned char *key, int key_len); - -WS_DLL_PUBLIC -void crypt_rc4(rc4_state_struct *rc4_state, unsigned char *data, int data_len); - -#endif diff --git a/wsutil/sha1.c b/wsutil/sha1.c deleted file mode 100644 index 9b115d56b2..0000000000 --- a/wsutil/sha1.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2001-2003 Christophe Devine - * Copyright (C) 2012 Chris Elston, Katalix Systems Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Changed to use guint instead of uint 2004 by Anders Broman - * Original code found at http://www.cr0.net:8040/code/crypto/sha1/ - * References: http://www.ietf.org/rfc/rfc3174.txt?number=3174 - * - * 2012-08-21 - C Elston - Split sha1_hmac function to allow incremental usage. - */ - -#include -#include - -#include "sha1.h" - -#define GET_UINT32(n,b,i) \ -{ \ - (n) = ( (guint32) (b)[(i) ] << 24 ) \ - | ( (guint32) (b)[(i) + 1] << 16 ) \ - | ( (guint32) (b)[(i) + 2] << 8 ) \ - | ( (guint32) (b)[(i) + 3] ); \ -} - -#define PUT_UINT32(n,b,i) \ -{ \ - (b)[(i) ] = (guint8) ( (n) >> 24 ); \ - (b)[(i) + 1] = (guint8) ( (n) >> 16 ); \ - (b)[(i) + 2] = (guint8) ( (n) >> 8 ); \ - (b)[(i) + 3] = (guint8) ( (n) ); \ -} - -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, const guint8 data[64] ) -{ - guint32 temp, W[16], A, B, C, D, E; - - GET_UINT32( W[0], data, 0 ); - GET_UINT32( W[1], data, 4 ); - GET_UINT32( W[2], data, 8 ); - GET_UINT32( W[3], data, 12 ); - GET_UINT32( W[4], data, 16 ); - GET_UINT32( W[5], data, 20 ); - GET_UINT32( W[6], data, 24 ); - GET_UINT32( W[7], data, 28 ); - GET_UINT32( W[8], data, 32 ); - GET_UINT32( W[9], data, 36 ); - GET_UINT32( W[10], data, 40 ); - GET_UINT32( W[11], data, 44 ); - GET_UINT32( W[12], data, 48 ); - GET_UINT32( W[13], data, 52 ); - GET_UINT32( W[14], data, 56 ); - GET_UINT32( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -void sha1_update( sha1_context *ctx, const guint8 *input, guint32 length ) -{ - guint32 left, fill; - - if( ! length ) return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += length; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < length ) - ctx->total[1]++; - - if( left && length >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (const void *) input, fill ); - sha1_process( ctx, ctx->buffer ); - length -= fill; - input += fill; - left = 0; - } - - while( length >= 64 ) - { - sha1_process( ctx, input ); - length -= 64; - input += 64; - } - - if( length ) - { - memcpy( (void *) (ctx->buffer + left), - (const void *) input, length ); - } -} - -static guint8 sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void sha1_finish( sha1_context *ctx, guint8 digest[SHA1_DIGEST_LEN] ) -{ - guint32 last, padn; - guint32 high, low; - guint8 msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32( high, msglen, 0 ); - PUT_UINT32( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_UINT32( ctx->state[0], digest, 0 ); - PUT_UINT32( ctx->state[1], digest, 4 ); - PUT_UINT32( ctx->state[2], digest, 8 ); - PUT_UINT32( ctx->state[3], digest, 12 ); - PUT_UINT32( ctx->state[4], digest, 16 ); -} - -void sha1_hmac_starts( sha1_hmac_context *hctx, const guint8 *key, guint32 keylen ) -{ - guint32 i; - guint8 k_ipad[64]; - - memset( k_ipad, 0x36, 64 ); - memset( hctx->k_opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - if( i >= 64 ) break; - - k_ipad[i] ^= key[i]; - hctx->k_opad[i] ^= key[i]; - } - - sha1_starts( &hctx->ctx ); - sha1_update( &hctx->ctx, k_ipad, 64 ); -} - -void sha1_hmac_update( sha1_hmac_context *hctx, const guint8 *buf, guint32 buflen ) -{ - sha1_update( &hctx->ctx, buf, buflen ); -} - -void sha1_hmac_finish( sha1_hmac_context *hctx, guint8 digest[SHA1_DIGEST_LEN] ) -{ - guint8 tmpbuf[SHA1_DIGEST_LEN]; - - sha1_finish( &hctx->ctx, tmpbuf ); - - sha1_starts( &hctx->ctx ); - sha1_update( &hctx->ctx, hctx->k_opad, 64 ); - sha1_update( &hctx->ctx, tmpbuf, SHA1_DIGEST_LEN ); - sha1_finish( &hctx->ctx, digest ); -} - -void sha1_hmac( const guint8 *key, guint32 keylen, const guint8 *buf, guint32 buflen, - guint8 digest[SHA1_DIGEST_LEN] ) -{ - sha1_hmac_context hctx; - - sha1_hmac_starts( &hctx, key, keylen ); - sha1_hmac_update( &hctx, buf, buflen ); - sha1_hmac_finish( &hctx, digest ); -} - -#ifdef TEST - -#include -#include -#include -#include /* ws_debug_printf */ - -/* - * those are the standard FIPS-180-1 test vectors - */ - -static const char *msg[] = -{ - "abc", - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - NULL -}; - -static const char *val[] = -{ - "a9993e364706816aba3e25717850c26c9cd0d89d", - "84983e441c3bd26ebaae4aa1f95129e5e54670f1", - "34aa973cd4c4daa4f61eeb2bdbad27316534016f" -}; - -int main( int argc, char *argv[] ) -{ - FILE *f; - int i, j; - char output[41]; - sha1_context ctx; - unsigned char buf[1000]; - unsigned char sha1sum[SHA1_DIGEST_LEN]; - - if( argc < 2 ) - { - ws_debug_printf( "\n SHA-1 Validation Tests:\n\n" ); - - for( i = 0; i < 3; i++ ) - { - ws_debug_printf( " Test %d ", i + 1 ); - - sha1_starts( &ctx ); - - if( i < 2 ) - { - sha1_update( &ctx, (guint8 *) msg[i], - strlen( msg[i] ) ); - } - else - { - memset( buf, 'a', 1000 ); - - for( j = 0; j < 1000; j++ ) - { - sha1_update( &ctx, (guint8 *) buf, 1000 ); - } - } - - sha1_finish( &ctx, sha1sum ); - - for( j = 0; j < SHA1_DIGEST_LEN; j++ ) - { - g_snprintf( output + j * 2, 41-j*2, "%02x", sha1sum[j] ); - } - - if( memcmp( output, val[i], 40 ) ) - { - ws_debug_printf( "failed!\n" ); - return( 1 ); - } - - ws_debug_printf( "passed.\n" ); - } - - ws_debug_printf( "\n" ); - } - else - { - if( ! ( f = ws_fopen( argv[1], "rb" ) ) ) - { - ws_debug_printf("fopen: %s", g_strerror(errno)); - return( 1 ); - } - - sha1_starts( &ctx ); - - while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - { - sha1_update( &ctx, buf, i ); - } - - sha1_finish( &ctx, sha1sum ); - - for( j = 0; j < SHA1_DIGEST_LEN; j++ ) - { - ws_debug_printf( "%02x", sha1sum[j] ); - } - - ws_debug_printf( " %s\n", argv[1] ); - } - - return( 0 ); -} - -#endif - - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/wsutil/sha1.h b/wsutil/sha1.h deleted file mode 100644 index 52a9842d57..0000000000 --- a/wsutil/sha1.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2001-2003 Christophe Devine - * Copyright (C) 2012 Chris Elston, Katalix Systems Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Changed to use guint instead of uint 2004 by Anders Broman - * Original code found at http://www.cr0.net:8040/code/crypto/sha1/ - * References: http://www.ietf.org/rfc/rfc3174.txt?number=3174 - * - * 2012-08-21 - C Elston - Split sha1_hmac function to allow incremental usage. - */ - -#ifndef _SHA1_H -#define _SHA1_H - -#include "ws_symbol_export.h" - -/* - * Length of a SHA-1 digest, in bytes. 160 bits = 20 bytes. - */ -#define SHA1_DIGEST_LEN 20 - -typedef struct -{ - guint32 total[2]; - guint32 state[5]; - guint8 buffer[64]; -} -sha1_context; - -WS_DLL_PUBLIC -void sha1_starts( sha1_context *ctx ); -WS_DLL_PUBLIC -void sha1_update( sha1_context *ctx, const guint8 *input, guint32 length ); -WS_DLL_PUBLIC -void sha1_finish( sha1_context *ctx, guint8 digest[SHA1_DIGEST_LEN] ); - -typedef struct { - sha1_context ctx; - guint8 k_opad[64]; -} -sha1_hmac_context; - -WS_DLL_PUBLIC -void sha1_hmac_starts( sha1_hmac_context *hctx, const guint8 *key, guint32 keylen ); -WS_DLL_PUBLIC -void sha1_hmac_update( sha1_hmac_context *hctx, const guint8 *buf, guint32 buflen ); -WS_DLL_PUBLIC -void sha1_hmac_finish( sha1_hmac_context *hctx, guint8 digest[SHA1_DIGEST_LEN] ); -WS_DLL_PUBLIC -void sha1_hmac( const guint8 *key, guint32 keylen, const guint8 *buf, guint32 buflen, - guint8 digest[SHA1_DIGEST_LEN] ); - -#endif /* sha1.h */ diff --git a/wsutil/sha2.c b/wsutil/sha2.c deleted file mode 100644 index 2466d7d4f6..0000000000 --- a/wsutil/sha2.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-2 implementation (only sha256 so far) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include -#include - -#include "sha2.h" - -/* the K array */ -static const guint32 K[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - - -#define GET_UINT32(n,b,i) \ - { \ - (n) = ( (guint32) (b)[(i) ] << 24 ) \ - | ( (guint32) (b)[(i) + 1] << 16 ) \ - | ( (guint32) (b)[(i) + 2] << 8 ) \ - | ( (guint32) (b)[(i) + 3] ); \ - } - -#define PUT_UINT32(n,b,i) \ - { \ - (b)[(i) ] = (guint8) ( (n) >> 24 ); \ - (b)[(i) + 1] = (guint8) ( (n) >> 16 ); \ - (b)[(i) + 2] = (guint8) ( (n) >> 8 ); \ - (b)[(i) + 3] = (guint8) ( (n) ); \ - } - -/* Initialize the hash state */ -void sha256_starts( sha256_context *ctx ) -{ - ctx->total = 0; - ctx->state[0] = 0x6A09E667UL; - ctx->state[1] = 0xBB67AE85UL; - ctx->state[2] = 0x3C6EF372UL; - ctx->state[3] = 0xA54FF53AUL; - ctx->state[4] = 0x510E527FUL; - ctx->state[5] = 0x9B05688CUL; - ctx->state[6] = 0x1F83D9ABUL; - ctx->state[7] = 0x5BE0CD19UL; -} - -static void sha256_process( sha256_context *ctx, const guint8 *data ) -{ - guint32 i, temp1, temp2, W[64], A, B, C, D, E, F, G, H; - - /* init W */ - GET_UINT32( W[0], data, 0 ); - GET_UINT32( W[1], data, 4 ); - GET_UINT32( W[2], data, 8 ); - GET_UINT32( W[3], data, 12 ); - GET_UINT32( W[4], data, 16 ); - GET_UINT32( W[5], data, 20 ); - GET_UINT32( W[6], data, 24 ); - GET_UINT32( W[7], data, 28 ); - GET_UINT32( W[8], data, 32 ); - GET_UINT32( W[9], data, 36 ); - GET_UINT32( W[10], data, 40 ); - GET_UINT32( W[11], data, 44 ); - GET_UINT32( W[12], data, 48 ); - GET_UINT32( W[13], data, 52 ); - GET_UINT32( W[14], data, 56 ); - GET_UINT32( W[15], data, 60 ); - -#define RR(x,n) ((x << (32 - n)) | ((x & 0xFFFFFFFF) >> n)) -#define S0(x) (RR(x, 7) ^ RR(x, 18) ^ (x >> 3)) -#define S1(x) (RR(x, 17) ^ RR(x, 19) ^ (x >> 10)) - - for (i = 16; i < 64 ; i++) - { - W[i] = W[i - 16] + S0(W[i - 15]) + W[i - 7] + S1(W[i - 2]); - } - - /* Compression */ - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - F = ctx->state[5]; - G = ctx->state[6]; - H = ctx->state[7]; - -#undef S0 -#undef S1 -#define S0(x) (RR(x, 2) ^ RR(x, 13) ^ RR(x, 22)) -#define S1(x) (RR(x, 6) ^ RR(x, 11) ^ RR(x, 25)) -#define CH(x,y,z) (z ^ (x & (y ^ z))) -#define MAJ(x,y,z) (((x | y) & z) | (x & y)) - - for (i = 0; i < 64; ++i) { - temp1 = H + S1(E) + CH(E, F, G) + K[i] + W[i]; - temp2 = S0(A) + MAJ(A, B, C); - H = G; - G = F; - F = E; - E = D + temp1; - D = C; - C = B; - B = A; - A = temp1 + temp2; - - } - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; - ctx->state[5] += F; - ctx->state[6] += G; - ctx->state[7] += H; -} - -void sha256_update( sha256_context *ctx, const guint8 *input, guint32 length ) -{ - guint32 left, fill; - - if( ! length ) return; - - left = (guint32)(ctx->total % SHA256_BLOCK_SIZE); - fill = SHA256_BLOCK_SIZE - left; - - ctx->total += length; - - if( left && length >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (const void *) input, fill ); - sha256_process( ctx, ctx->buffer ); - length -= fill; - input += fill; - left = 0; - } - - while( length >= SHA256_BLOCK_SIZE ) - { - sha256_process( ctx, input ); - length -= SHA256_BLOCK_SIZE; - input += SHA256_BLOCK_SIZE; - } - - if( length ) - { - memcpy( (void *) (ctx->buffer + left), - (const void *) input, length ); - } -} - -static guint8 sha256_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void sha256_finish( sha256_context *ctx, guint8 digest[SHA256_DIGEST_LEN] ) -{ - guint32 last, padn; - guint64 total_length; - guint8 msglen[8]; - - total_length = ctx->total * 8; - - last = (guint32)(ctx->total % SHA256_BLOCK_SIZE); - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - PUT_UINT32( total_length >> 32, msglen, 0 ); - PUT_UINT32( total_length, msglen, 4 ); - - sha256_update( ctx, sha256_padding, padn ); - sha256_update( ctx, msglen, 8 ); - - PUT_UINT32( ctx->state[0], digest, 0 ); - PUT_UINT32( ctx->state[1], digest, 4 ); - PUT_UINT32( ctx->state[2], digest, 8 ); - PUT_UINT32( ctx->state[3], digest, 12 ); - PUT_UINT32( ctx->state[4], digest, 16 ); - PUT_UINT32( ctx->state[5], digest, 20 ); - PUT_UINT32( ctx->state[6], digest, 24 ); - PUT_UINT32( ctx->state[7], digest, 28 ); -} - -void sha256_hmac_starts( sha256_hmac_context *hctx, const guint8 *key, guint32 keylen ) -{ - guint32 i; - guint8 k_ipad[SHA256_BLOCK_SIZE]; - guint8 key_compress[SHA256_DIGEST_LEN]; - - memset( k_ipad, 0x36, SHA256_BLOCK_SIZE ); - memset( hctx->k_opad, 0x5C, SHA256_BLOCK_SIZE ); - - if (keylen > SHA256_BLOCK_SIZE) - { - sha256_starts( &hctx->ctx ); - sha256_update( &hctx->ctx, key, keylen ); - sha256_finish( &hctx->ctx, key_compress ); - key = key_compress; - keylen = SHA256_DIGEST_LEN; - } - - for( i = 0; i < keylen; i++ ) - { - k_ipad[i] ^= key[i]; - hctx->k_opad[i] ^= key[i]; - } - - sha256_starts( &hctx->ctx ); - sha256_update( &hctx->ctx, k_ipad, SHA256_BLOCK_SIZE ); -} - -void sha256_hmac_update( sha256_hmac_context *hctx, const guint8 *buf, guint32 buflen ) -{ - sha256_update( &hctx->ctx, buf, buflen ); -} - -void sha256_hmac_finish( sha256_hmac_context *hctx, guint8 digest[SHA256_DIGEST_LEN] ) -{ - guint8 tmpbuf[SHA256_DIGEST_LEN]; - - sha256_finish( &hctx->ctx, tmpbuf ); - - sha256_starts( &hctx->ctx ); - sha256_update( &hctx->ctx, hctx->k_opad, SHA256_BLOCK_SIZE ); - sha256_update( &hctx->ctx, tmpbuf, SHA256_DIGEST_LEN ); - sha256_finish( &hctx->ctx, digest ); -} - -void sha256_hmac( const guint8 *key, guint32 keylen, const guint8 *buf, guint32 buflen, - guint8 digest[SHA256_DIGEST_LEN] ) -{ - sha256_hmac_context hctx; - - sha256_hmac_starts( &hctx, key, keylen ); - sha256_hmac_update( &hctx, buf, buflen ); - sha256_hmac_finish( &hctx, digest ); -} - - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/wsutil/sha2.h b/wsutil/sha2.h deleted file mode 100644 index baca2233c1..0000000000 --- a/wsutil/sha2.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-2 implementation (only sha256 so far) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - */ - -#ifndef _SHA2_H -#define _SHA2_H - -#include "ws_symbol_export.h" - -#define SHA256_DIGEST_LEN 32 -#define SHA256_BLOCK_SIZE 64 - -typedef struct -{ - guint64 total; - guint32 state[8]; - guint8 buffer[SHA256_BLOCK_SIZE]; -} - sha256_context; - -WS_DLL_PUBLIC -void sha256_starts( sha256_context *ctx ); -WS_DLL_PUBLIC -void sha256_update( sha256_context *ctx, const guint8 *input, guint32 length ); -WS_DLL_PUBLIC -void sha256_finish( sha256_context *ctx, guint8 digest[SHA256_DIGEST_LEN] ); - - -typedef struct { - sha256_context ctx; - guint8 k_opad[SHA256_BLOCK_SIZE]; -} - sha256_hmac_context; - -WS_DLL_PUBLIC -void sha256_hmac_starts( sha256_hmac_context *hctx, const guint8 *key, guint32 keylen ); -WS_DLL_PUBLIC -void sha256_hmac_update( sha256_hmac_context *hctx, const guint8 *buf, guint32 buflen ); -WS_DLL_PUBLIC -void sha256_hmac_finish( sha256_hmac_context *hctx, guint8 digest[SHA256_DIGEST_LEN] ); -WS_DLL_PUBLIC -void sha256_hmac( const guint8 *key, guint32 keylen, const guint8 *buf, guint32 buflen, - guint8 digest[SHA256_DIGEST_LEN] ); - - - -#endif /* _SHA2_H */ - -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/wsutil/wsgcrypt.c b/wsutil/wsgcrypt.c new file mode 100644 index 0000000000..09753f72a7 --- /dev/null +++ b/wsutil/wsgcrypt.c @@ -0,0 +1,57 @@ +/* wsgcrypt.c + * Helper functions for libgcrypt + * By Erik de Jong + * Copyright 2017 Erik de Jong + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "wsgcrypt.h" + +gcry_error_t ws_hmac_buffer(int algo, void *digest, const void *buffer, size_t length, const void *key, size_t keylen) +{ + gcry_md_hd_t hmac_handle; + gcry_error_t result = gcry_md_open(&hmac_handle, algo, GCRY_MD_FLAG_HMAC); + if (result) { + return result; + } + result = gcry_md_setkey(hmac_handle, key, keylen); + if (result) { + gcry_md_close(hmac_handle); + return result; + } + gcry_md_write(hmac_handle, buffer, length); + memcpy(digest, gcry_md_read(hmac_handle, 0), gcry_md_get_algo_dlen(algo)); + gcry_md_close(hmac_handle); + return GPG_ERR_NO_ERROR; +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ diff --git a/wsutil/wsgcrypt.h b/wsutil/wsgcrypt.h index d56e456cb2..6a5ef8290e 100644 --- a/wsutil/wsgcrypt.h +++ b/wsutil/wsgcrypt.h @@ -28,6 +28,7 @@ #define __WSGCRYPT_H__ #include +#include "ws_symbol_export.h" DIAG_OFF(deprecated-declarations) @@ -35,4 +36,14 @@ DIAG_OFF(deprecated-declarations) DIAG_ON(deprecated-declarations) +#define HASH_MD5_LENGTH 16 +#define HASH_SHA1_LENGTH 20 + +/* Convenience function to calculate the HMAC from the data in BUFFER + of size LENGTH with key KEY of size KEYLEN using the algorithm ALGO avoiding the creating of a + hash object. The hash is returned in the caller provided buffer + DIGEST which must be large enough to hold the digest of the given + algorithm. */ +WS_DLL_PUBLIC gcry_error_t ws_hmac_buffer(int algo, void *digest, const void *buffer, size_t length, const void *key, size_t keylen); + #endif /* __WSGCRYPT_H__ */ -- cgit v1.2.1