From f997421098d7b67230497fac3842f770ea68a12c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 24 Feb 2016 21:45:09 +0100 Subject: [PATCH] Unified hmac functions. --- include/freerdp/crypto/crypto.h | 16 -- libfreerdp/common/assistance.c | 4 +- libfreerdp/core/certificate.c | 9 +- libfreerdp/core/connection.c | 4 +- libfreerdp/core/gcc.c | 9 +- libfreerdp/core/info.c | 16 +- libfreerdp/core/license.c | 9 +- libfreerdp/core/rdp.c | 4 +- libfreerdp/core/rdp.h | 2 +- libfreerdp/core/security.c | 263 +++++++++++++------- libfreerdp/crypto/crypto.c | 49 ---- winpr/include/winpr/crypto.h | 61 ++--- winpr/libwinpr/crypto/cipher.c | 30 +-- winpr/libwinpr/crypto/hash.c | 126 ++++++---- winpr/libwinpr/crypto/test/TestCryptoHash.c | 85 ++++--- winpr/libwinpr/sspi/NTLM/ntlm.c | 14 +- winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c | 4 +- winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 39 +-- winpr/libwinpr/utils/ntlm.c | 25 +- 19 files changed, 421 insertions(+), 348 deletions(-) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index ae74e1d90..89b3eef26 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -25,10 +25,8 @@ #include #include -#include #include #include -#include #if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) #define D2I_X509_CONST const @@ -46,11 +44,6 @@ struct crypto_des3_struct EVP_CIPHER_CTX des3_ctx; }; -struct crypto_hmac_struct -{ - HMAC_CTX hmac_ctx; -}; - struct crypto_cert_struct { X509 * px509; @@ -69,15 +62,6 @@ FREERDP_API BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE FREERDP_API BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data); FREERDP_API void crypto_des3_free(CryptoDes3 des3); -typedef struct crypto_hmac_struct* CryptoHmac; - -FREERDP_API CryptoHmac crypto_hmac_new(void); -FREERDP_API BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length); -FREERDP_API BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length); -FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length); -FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length); -FREERDP_API void crypto_hmac_free(CryptoHmac hmac); - typedef struct crypto_cert_struct* CryptoCert; #include diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index c69d72998..32b7bb534 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -548,7 +548,7 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas int cbPasswordW; int cbPassStubW; int EncryptedSize; - BYTE PasswordHash[16]; + BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH]; EVP_CIPHER_CTX rc4Ctx; BYTE* pbIn, *pbOut; int cbOut, cbIn, cbFinal; @@ -572,7 +572,7 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas free (PasswordW); return NULL; } - if (!winpr_MD5_Final(&md5Ctx, (BYTE*) PasswordHash)) + if (!winpr_MD5_Final(&md5Ctx, (BYTE*) PasswordHash, sizeof(PasswordHash))) { free (PasswordW); return NULL; diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index e5999b836..9ce68f355 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -404,9 +404,12 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific BYTE encsig[TSSK_KEY_LENGTH + 8]; BYTE md5hash[WINPR_MD5_DIGEST_LENGTH]; - winpr_MD5_Init(&md5ctx); - winpr_MD5_Update(&md5ctx, sigdata, sigdatalen); - winpr_MD5_Final(&md5ctx, md5hash); + if (!winpr_MD5_Init(&md5ctx)) + return FALSE; + if (!winpr_MD5_Update(&md5ctx, sigdata, sigdatalen)) + return FALSE; + if (!winpr_MD5_Final(&md5ctx, md5hash, sizeof(md5hash))) + return FALSE; Stream_Read(s, encsig, siglen); /* Last 8 bytes shall be all zero. */ diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 91e498f17..44b6deb5c 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -503,7 +503,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) goto end; } - rdp->fips_hmac = crypto_hmac_new(); + rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); @@ -611,7 +611,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) goto end; } - rdp->fips_hmac = crypto_hmac_new(); + rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 5914b64cd..86aff0004 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1376,9 +1376,12 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) memcpy(signature, initial_signature, sizeof(initial_signature)); - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, sigData, sigDataLen); - winpr_MD5_Final(&md5, signature); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, sigData, sigDataLen)) + return FALSE; + if (!winpr_MD5_Final(&md5, signature, sizeof(signature))) + return FALSE; crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 6fbff79da..dc034b90e 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -44,7 +44,7 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] = BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { - CryptoHmac hmac; + WINPR_HMAC_CTX hmac; BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; @@ -67,18 +67,14 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) if (settings->SelectedProtocol == PROTOCOL_RDP) CopyMemory(ClientRandom, settings->ClientRandom, settings->ClientRandomLength); - hmac = crypto_hmac_new(); - - if (!hmac) - return FALSE; - /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ - if (!crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16)) + if (!winpr_HMAC_Init(&hmac, WINPR_MD_MD5, AutoReconnectRandom, 16)) + return FALSE; + if (!winpr_HMAC_Update(&hmac, ClientRandom, 32)) + return FALSE; + if (!winpr_HMAC_Final(&hmac, clientCookie->securityVerifier, 16)) return FALSE; - crypto_hmac_update(hmac, ClientRandom, 32); - crypto_hmac_final(hmac, clientCookie->securityVerifier, 16); - crypto_hmac_free(hmac); return TRUE; } diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 2dba07c40..bfb988192 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -391,9 +391,12 @@ BOOL license_generate_hwid(rdpLicense* license) ZeroMemory(macAddress, sizeof(macAddress)); ZeroMemory(license->HardwareId, HWID_LENGTH); - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, macAddress, sizeof(macAddress)); - winpr_MD5_Final(&md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, macAddress, sizeof(macAddress))) + return FALSE; + if (!winpr_MD5_Final(&md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH)) + return FALSE; return TRUE; } diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index abb6cd0ed..8c507ff76 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1614,7 +1614,7 @@ void rdp_reset(rdpRdp* rdp) if (rdp->fips_hmac) { - crypto_hmac_free(rdp->fips_hmac); + free(rdp->fips_hmac); rdp->fips_hmac = NULL; } @@ -1665,7 +1665,7 @@ void rdp_free(rdpRdp* rdp) winpr_RC4_Final(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); - crypto_hmac_free(rdp->fips_hmac); + free(rdp->fips_hmac); freerdp_settings_free(rdp->settings); freerdp_settings_free(rdp->settingsCopy); transport_free(rdp->transport); diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index e5eae3dcb..1fb88effc 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -156,7 +156,7 @@ struct rdp_rdp int encrypt_checksum_use_count; struct crypto_des3_struct* fips_encrypt; struct crypto_des3_struct* fips_decrypt; - struct crypto_hmac_struct* fips_hmac; + WINPR_HMAC_CTX* fips_hmac; UINT32 sec_flags; BOOL do_crypt; BOOL do_crypt_license; diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index 67e0c5d16..b63022763 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -134,18 +134,28 @@ static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */ /* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */ - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, input, length); /* Input */ - winpr_SHA1_Update(&sha1, salt, 48); /* Salt (48 bytes) */ - winpr_SHA1_Update(&sha1, salt1, 32); /* Salt1 (32 bytes) */ - winpr_SHA1_Update(&sha1, salt2, 32); /* Salt2 (32 bytes) */ - winpr_SHA1_Final(&sha1, sha1_digest); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, input, length)) /* Input */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, salt, 48)) /* Salt (48 bytes) */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, salt1, 32)) /* Salt1 (32 bytes) */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, salt2, 32)) /* Salt2 (32 bytes) */ + return FALSE; + if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + return FALSE; /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */ - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, salt, 48); /* Salt (48 bytes) */ - winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ - winpr_MD5_Final(&md5, output); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, salt, 48)) /* Salt (48 bytes) */ + return FALSE; + if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + return FALSE; + if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + return FALSE; return TRUE; } @@ -192,11 +202,16 @@ BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BY { WINPR_MD5_CTX md5; - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, in0, 16); - winpr_MD5_Update(&md5, in1, 32); - winpr_MD5_Update(&md5, in2, 32); - winpr_MD5_Final(&md5, output); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, in0, 16)) + return FALSE; + if (!winpr_MD5_Update(&md5, in1, 32)) + return FALSE; + if (!winpr_MD5_Update(&md5, in2, 32)) + return FALSE; + if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + return FALSE; return TRUE; } @@ -228,19 +243,30 @@ BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */ - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, mac_salt_key, 16); /* MacSaltKey */ - winpr_SHA1_Update(&sha1, pad1, sizeof(pad1)); /* pad1 */ - winpr_SHA1_Update(&sha1, length_le, sizeof(length_le)); /* length */ - winpr_SHA1_Update(&sha1, data, length); /* data */ - winpr_SHA1_Final(&sha1, sha1_digest); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, mac_salt_key, 16)) /* MacSaltKey */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + return FALSE; + if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + return FALSE; /* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */ - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, mac_salt_key, 16); /* MacSaltKey */ - winpr_MD5_Update(&md5, pad2, sizeof(pad2)); /* pad2 */ - winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ - winpr_MD5_Final(&md5, output); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, mac_salt_key, 16)) /* MacSaltKey */ + return FALSE; + if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + return FALSE; + if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + return FALSE; + if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH)) + return FALSE; return TRUE; } @@ -255,19 +281,30 @@ BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ - winpr_SHA1_Update(&sha1, pad1, sizeof(pad1)); /* pad1 */ - winpr_SHA1_Update(&sha1, length_le, sizeof(length_le)); /* length */ - winpr_SHA1_Update(&sha1, data, length); /* data */ - winpr_SHA1_Final(&sha1, sha1_digest); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + return FALSE; + if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + return FALSE; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ - winpr_MD5_Update(&md5, pad2, sizeof(pad2)); /* pad2 */ - winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ - winpr_MD5_Final(&md5, md5_digest); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + return FALSE; + if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + return FALSE; + if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + return FALSE; + if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest))) + return FALSE; memcpy(output, md5_digest, 8); return TRUE; @@ -299,20 +336,32 @@ BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, } /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ - winpr_SHA1_Update(&sha1, pad1, sizeof(pad1)); /* pad1 */ - winpr_SHA1_Update(&sha1, length_le, sizeof(length_le)); /* length */ - winpr_SHA1_Update(&sha1, data, length); /* data */ - winpr_SHA1_Update(&sha1, use_count_le, sizeof(use_count_le)); /* encryptionCount */ - winpr_SHA1_Final(&sha1, sha1_digest); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, data, length)) /* data */ + return FALSE; + if (!winpr_SHA1_Update(&sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */ + return FALSE; + if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest))) + return FALSE; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ - winpr_MD5_Update(&md5, pad2, sizeof(pad2)); /* pad2 */ - winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ - winpr_MD5_Final(&md5, md5_digest); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ + return FALSE; + if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */ + return FALSE; + if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ + return FALSE; + if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest))) + return FALSE; memcpy(output, md5_digest, 8); return TRUE; @@ -388,22 +437,34 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) BYTE client_encrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1]; BYTE client_decrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1]; - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, client_random + 16, 16); - winpr_SHA1_Update(&sha1, server_random + 16, 16); - winpr_SHA1_Final(&sha1, client_encrypt_key_t); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, client_random + 16, 16)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, server_random + 16, 16)) + return FALSE; + if (!winpr_SHA1_Final(&sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t))) + return FALSE; client_encrypt_key_t[20] = client_encrypt_key_t[0]; - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, client_random, 16); - winpr_SHA1_Update(&sha1, server_random, 16); - winpr_SHA1_Final(&sha1, client_decrypt_key_t); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, client_random, 16)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, server_random, 16)) + return FALSE; + if (!winpr_SHA1_Final(&sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t))) + return FALSE; client_decrypt_key_t[20] = client_decrypt_key_t[0]; - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, client_decrypt_key_t, 20); - winpr_SHA1_Update(&sha1, client_encrypt_key_t, 20); - winpr_SHA1_Final(&sha1, rdp->fips_sign_key); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, client_decrypt_key_t, 20)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, client_encrypt_key_t, 20)) + return FALSE; + if (!winpr_SHA1_Final(&sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + return FALSE; if (rdp->settings->ServerMode) { @@ -480,21 +541,34 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) WINPR_RC4_CTX rc4; BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */ - winpr_SHA1_Init(&sha1); - winpr_SHA1_Update(&sha1, update_key, key_len); - winpr_SHA1_Update(&sha1, pad1, sizeof(pad1)); - winpr_SHA1_Update(&sha1, key, key_len); - winpr_SHA1_Final(&sha1, sha1h); + if (!winpr_SHA1_Init(&sha1)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, update_key, key_len)) + return FALSE; + if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) + return FALSE; + if (!winpr_SHA1_Update(&sha1, key, key_len)) + return FALSE; + if (!winpr_SHA1_Final(&sha1, sha1h, sizeof(sha1h))) + return FALSE; - winpr_MD5_Init(&md5); - winpr_MD5_Update(&md5, update_key, key_len); - winpr_MD5_Update(&md5, pad2, sizeof(pad2)); - winpr_MD5_Update(&md5, sha1h, sizeof(sha1h)); - winpr_MD5_Final(&md5, key); + if (!winpr_MD5_Init(&md5)) + return FALSE; + if (!winpr_MD5_Update(&md5, update_key, key_len)) + return FALSE; + if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) + return FALSE; + if (!winpr_MD5_Update(&md5, sha1h, sizeof(sha1h))) + return FALSE; + if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH)) + return FALSE; - winpr_RC4_Init(&rc4, key, key_len); - winpr_RC4_Update(&rc4, key_len, key, key); - winpr_RC4_Final(&rc4); + if (!winpr_RC4_Init(&rc4, key, key_len)) + return FALSE; + if (!winpr_RC4_Update(&rc4, key_len, key, key)) + return FALSE; + if (!winpr_RC4_Final(&rc4)) + return FALSE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT) memcpy(key, salt, 3); @@ -511,13 +585,16 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp) if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp)) return FALSE; - winpr_RC4_Final(rdp->rc4_encrypt_key); - winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len); + if (!winpr_RC4_Final(rdp->rc4_encrypt_key)) + return FALSE; + if (!winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len)) + return FALSE; rdp->encrypt_use_count = 0; } - winpr_RC4_Update(rdp->rc4_encrypt_key, length, data, data); + if (!winpr_RC4_Update(rdp->rc4_encrypt_key, length, data, data)) + return FALSE; rdp->encrypt_use_count++; rdp->encrypt_checksum_use_count++; return TRUE; @@ -532,12 +609,15 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp) { if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp)) return FALSE; - winpr_RC4_Final(rdp->rc4_decrypt_key); - winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len); + if (!winpr_RC4_Final(rdp->rc4_decrypt_key)) + return FALSE; + if (!winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len)) + return FALSE; rdp->decrypt_use_count = 0; } - winpr_RC4_Update(rdp->rc4_decrypt_key, length, data, data); + if (!winpr_RC4_Update(rdp->rc4_decrypt_key, length, data, data)) + return FALSE; rdp->decrypt_use_count += 1; rdp->decrypt_checksum_use_count++; return TRUE; @@ -550,12 +630,14 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* security_UINT32_le(use_count_le, rdp->encrypt_use_count); - if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20)) + if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1, rdp->fips_sign_key, 20)) + return FALSE; + if (!winpr_HMAC_Update(rdp->fips_hmac, data, length)) + return FALSE; + if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4)) + return FALSE; + if (!winpr_HMAC_Final(rdp->fips_hmac, buf, 20)) return FALSE; - - crypto_hmac_update(rdp->fips_hmac, data, length); - crypto_hmac_update(rdp->fips_hmac, use_count_le, 4); - crypto_hmac_final(rdp->fips_hmac, buf, 20); memmove(output, buf, 8); return TRUE; @@ -581,11 +663,14 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig security_UINT32_le(use_count_le, rdp->decrypt_use_count); - if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20)) + if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1, rdp->fips_sign_key, 20)) + return FALSE; + if (!winpr_HMAC_Update(rdp->fips_hmac, data, length)) + return FALSE; + if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4)) + return FALSE; + if (!winpr_HMAC_Final(rdp->fips_hmac, buf, 20)) return FALSE; - crypto_hmac_update(rdp->fips_hmac, data, length); - crypto_hmac_update(rdp->fips_hmac, use_count_le, 4); - crypto_hmac_final(rdp->fips_hmac, buf, 20); rdp->decrypt_use_count++; diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 654efeb38..dfb1dbc8b 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -77,55 +77,6 @@ void crypto_des3_free(CryptoDes3 des3) free(des3); } -CryptoHmac crypto_hmac_new(void) -{ - CryptoHmac hmac = malloc(sizeof(*hmac)); - if (!hmac) - return NULL; - - HMAC_CTX_init(&hmac->hmac_ctx); - return hmac; -} - -BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00909000) - return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL) == 1; -#else - HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL); - return TRUE; -#endif -} - -BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00909000) - return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL) == 1; -#else - HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL); - return TRUE; -#endif -} - -void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length) -{ - HMAC_Update(&hmac->hmac_ctx, data, length); -} - -void crypto_hmac_final(CryptoHmac hmac, BYTE* out_data, UINT32 length) -{ - HMAC_Final(&hmac->hmac_ctx, out_data, &length); -} - -void crypto_hmac_free(CryptoHmac hmac) -{ - if (hmac == NULL) - return; - - HMAC_CTX_cleanup(&hmac->hmac_ctx); - free(hmac); -} - CryptoCert crypto_cert_read(BYTE* data, UINT32 length) { CryptoCert cert = malloc(sizeof(*cert)); diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h index b0f2ef57e..886a5174f 100644 --- a/winpr/include/winpr/crypto.h +++ b/winpr/include/winpr/crypto.h @@ -650,8 +650,8 @@ extern "C" { WINPR_API BOOL winpr_MD5_Init(WINPR_MD5_CTX* ctx); WINPR_API BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output); -WINPR_API BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output); +WINPR_API BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus } @@ -685,14 +685,16 @@ union _WINPR_MD4_CTX }; typedef union _WINPR_MD4_CTX WINPR_MD4_CTX; +#define WINPR_MD4_DIGEST_LENGTH 16 + #ifdef __cplusplus extern "C" { #endif WINPR_API BOOL winpr_MD4_Init(WINPR_MD4_CTX* ctx); WINPR_API BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output); -WINPR_API BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output); +WINPR_API BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus } @@ -734,8 +736,8 @@ extern "C" { WINPR_API BOOL winpr_SHA1_Init(WINPR_SHA1_CTX* ctx); WINPR_API BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output); -WINPR_API BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output); +WINPR_API BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus } @@ -744,17 +746,19 @@ WINPR_API BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output); /** * HMAC */ - -#define WINPR_MD_NONE 0 -#define WINPR_MD_MD2 1 -#define WINPR_MD_MD4 2 -#define WINPR_MD_MD5 3 -#define WINPR_MD_SHA1 4 -#define WINPR_MD_SHA224 5 -#define WINPR_MD_SHA256 6 -#define WINPR_MD_SHA384 7 -#define WINPR_MD_SHA512 8 -#define WINPR_MD_RIPEMD160 9 +typedef enum +{ + WINPR_MD_NONE = 0, + WINPR_MD_MD2 = 1, + WINPR_MD_MD4 = 2, + WINPR_MD_MD5 = 3, + WINPR_MD_SHA1 = 4, + WINPR_MD_SHA224 = 5, + WINPR_MD_SHA256 = 6, + WINPR_MD_SHA384 = 7, + WINPR_MD_SHA512 = 8, + WINPR_MD_RIPEMD160 = 9 +} WINPR_MD_TYPE; struct _OPENSSL_EVP_MD_CTX { @@ -797,10 +801,11 @@ typedef union _WINPR_HMAC_CTX WINPR_HMAC_CTX; extern "C" { #endif -WINPR_API int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen); -WINPR_API int winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API int winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output); -WINPR_API int winpr_HMAC(int md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output); +WINPR_API BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen); +WINPR_API BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen); +WINPR_API BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, + const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus } @@ -842,10 +847,10 @@ typedef union _WINPR_DIGEST_CTX WINPR_DIGEST_CTX; extern "C" { #endif -WINPR_API int winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, int md); -WINPR_API int winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen); -WINPR_API int winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output); -WINPR_API int winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output); +WINPR_API BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md); +WINPR_API BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen); +WINPR_API BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t ilen); +WINPR_API BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen); #ifdef __cplusplus } @@ -1011,9 +1016,9 @@ typedef union _WINPR_CIPHER_CTX WINPR_CIPHER_CTX; extern "C" { #endif -WINPR_API int winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv); -WINPR_API int winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, BYTE* output, size_t* olen); -WINPR_API int winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen); +WINPR_API BOOL winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv); +WINPR_API BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, BYTE* output, size_t* olen); +WINPR_API BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen); #ifdef __cplusplus } diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c index 5f4521a2d..7c5461273 100644 --- a/winpr/libwinpr/crypto/cipher.c +++ b/winpr/libwinpr/crypto/cipher.c @@ -500,7 +500,7 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher) } #endif -int winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv) +BOOL winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv) { #if defined(WITH_OPENSSL) int operation; @@ -508,13 +508,13 @@ int winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key evp = winpr_openssl_get_evp_cipher(cipher); if (!evp) - return -1; + return FALSE; operation = (op == WINPR_ENCRYPT) ? 1 : 0; EVP_CIPHER_CTX_init((EVP_CIPHER_CTX*) ctx); if (EVP_CipherInit_ex((EVP_CIPHER_CTX*) ctx, evp, NULL, key, iv, operation) != 1) - return -1; + return FALSE; #elif defined(WITH_MBEDTLS) int key_bitlen; mbedtls_operation_t operation; @@ -524,55 +524,55 @@ int winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key cipher_info = mbedtls_cipher_info_from_type(cipher_type); if (!cipher_info) - return -1; + return FALSE; operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; mbedtls_cipher_init((mbedtls_cipher_context_t*) ctx); if (mbedtls_cipher_setup((mbedtls_cipher_context_t*) ctx, cipher_info) != 0) - return -1; + return FALSE; key_bitlen = mbedtls_cipher_get_key_bitlen((mbedtls_cipher_context_t*) ctx); if (mbedtls_cipher_setkey((mbedtls_cipher_context_t*) ctx, key, key_bitlen, operation) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, BYTE* output, size_t* olen) +BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, BYTE* output, size_t* olen) { #if defined(WITH_OPENSSL) int outl = (int) *olen; if (EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx, output, &outl, input, ilen) != 1) - return -1; + return FALSE; *olen = (size_t) outl; #elif defined(WITH_MBEDTLS) if (mbedtls_cipher_update((mbedtls_cipher_context_t*) ctx, input, ilen, output, olen) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen) +BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen) { #if defined(WITH_OPENSSL) int outl = (int) *olen; if (EVP_CipherFinal_ex((EVP_CIPHER_CTX*) ctx, output, &outl) != 1) - return -1; + return FALSE; EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx); *olen = (size_t) outl; #elif defined(WITH_MBEDTLS) if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) != 0) - return -1; + return FALSE; mbedtls_cipher_free((mbedtls_cipher_context_t*) ctx); #endif - return 0; + return TRUE; } /** diff --git a/winpr/libwinpr/crypto/hash.c b/winpr/libwinpr/crypto/hash.c index 8b5e11599..9761d7893 100644 --- a/winpr/libwinpr/crypto/hash.c +++ b/winpr/libwinpr/crypto/hash.c @@ -68,8 +68,11 @@ BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen) return TRUE; } -BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output) +BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output, size_t ilen) { + if (ilen < WINPR_MD5_DIGEST_LENGTH) + return FALSE; + #if defined(WITH_OPENSSL) if (MD5_Final(output, (MD5_CTX*) ctx) != 1) return FALSE; @@ -81,7 +84,7 @@ BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output) return TRUE; } -BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output) +BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen) { WINPR_MD5_CTX ctx; @@ -89,7 +92,7 @@ BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output) return FALSE; if (!winpr_MD5_Update(&ctx, input, ilen)) return FALSE; - return winpr_MD5_Final(&ctx, output); + return winpr_MD5_Final(&ctx, output, olen); } /** @@ -120,8 +123,11 @@ BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen) return TRUE; } -BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output) +BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output, size_t olen) { + if (olen < WINPR_MD4_DIGEST_LENGTH) + return FALSE; + #if defined(WITH_OPENSSL) if (MD4_Final(output, (MD4_CTX*) ctx) != 1) return FALSE; @@ -133,7 +139,7 @@ BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output) return TRUE; } -BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output) +BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen) { WINPR_MD4_CTX ctx; @@ -141,7 +147,7 @@ BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output) return FALSE; if (!winpr_MD4_Update(&ctx, input, ilen)) return FALSE; - return winpr_MD4_Final(&ctx, output); + return winpr_MD4_Final(&ctx, output, olen); } /** @@ -173,8 +179,11 @@ BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen) return TRUE; } -BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output) +BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output, size_t olen) { + if (olen < WINPR_SHA1_DIGEST_LENGTH) + return FALSE; + #if defined(WITH_OPENSSL) if (SHA1_Final(output, (SHA_CTX*) ctx) != 1) return FALSE; @@ -186,7 +195,7 @@ BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output) return TRUE; } -BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output) +BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output, size_t olen) { WINPR_SHA1_CTX ctx; @@ -194,7 +203,7 @@ BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output) return FALSE; if (!winpr_SHA1_Update(&ctx, input, ilen)) return FALSE; - return winpr_SHA1_Final(&ctx, output); + return winpr_SHA1_Final(&ctx, output, olen); } /** @@ -299,13 +308,13 @@ mbedtls_md_type_t winpr_mbedtls_get_md_type(int md) } #endif -int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen) +BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen) { #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!evp) - return -1; + return FALSE; HMAC_CTX_init((HMAC_CTX*) ctx); @@ -313,7 +322,7 @@ int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen) HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL); #else if (HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL) != 1) - return -1; + return FALSE; #endif #elif defined(WITH_MBEDTLS) @@ -322,143 +331,150 @@ int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen) md_info = mbedtls_md_info_from_type(md_type); if (!md_info) - return -1; + return FALSE; mbedtls_md_init((mbedtls_md_context_t*) ctx); if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 1) != 0) - return -1; + return FALSE; if (mbedtls_md_hmac_starts((mbedtls_md_context_t*) ctx, key, keylen) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen) +BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen) { #if defined(WITH_OPENSSL) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) HMAC_Update((HMAC_CTX*) ctx, input, ilen); #else if (HMAC_Update((HMAC_CTX*) ctx, input, ilen) != 1) - return -1; + return FALSE; #endif #elif defined(WITH_MBEDTLS) if (mbedtls_md_hmac_update((mbedtls_md_context_t*) ctx, input, ilen) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output) +BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen) { + /* TODO + if (olen < ctx->digestLength) + return FALSE; + */ + #if defined(WITH_OPENSSL) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) HMAC_Final((HMAC_CTX*) ctx, output, NULL); #else if (HMAC_Final((HMAC_CTX*) ctx, output, NULL) != 1) - return -1; + return FALSE; #endif HMAC_CTX_cleanup((HMAC_CTX*) ctx); #elif defined(WITH_MBEDTLS) if (mbedtls_md_hmac_finish((mbedtls_md_context_t*) ctx, output) != 0) - return -1; + return FALSE; mbedtls_md_free((mbedtls_md_context_t*) ctx); #endif - return 0; + return TRUE; } -int winpr_HMAC(int md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output) +BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, + const BYTE* input, size_t ilen, BYTE* output, size_t olen) { WINPR_HMAC_CTX ctx; - if (winpr_HMAC_Init(&ctx, md, key, keylen) != 0) - return -1; + if (!winpr_HMAC_Init(&ctx, md, key, keylen)) + return FALSE; - if (winpr_HMAC_Update(&ctx, input, ilen) != 0) - return -1; + if (!winpr_HMAC_Update(&ctx, input, ilen)) + return FALSE; - if (winpr_HMAC_Final(&ctx, output) != 0) - return -1; + if (!winpr_HMAC_Final(&ctx, output, olen)) + return FALSE; - return 0; + return TRUE; } /** * Generic Digest API */ -int winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, int md) +BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md) { #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!evp) - return -1; + return FALSE; EVP_MD_CTX_init((EVP_MD_CTX*) ctx); if (EVP_DigestInit_ex((EVP_MD_CTX*) ctx, evp, NULL) != 1) - return -1; + return FALSE; #elif defined(WITH_MBEDTLS) const mbedtls_md_info_t* md_info; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); md_info = mbedtls_md_info_from_type(md_type); if (!md_info) - return -1; + return FALSE; mbedtls_md_init((mbedtls_md_context_t*) ctx); if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 0) != 0) - return -1; + return FALSE; if (mbedtls_md_starts((mbedtls_md_context_t*) ctx) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) +BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) { #if defined(WITH_OPENSSL) if (EVP_DigestUpdate((EVP_MD_CTX*) ctx, input, ilen) != 1) - return -1; + return FALSE; #elif defined(WITH_MBEDTLS) if (mbedtls_md_update((mbedtls_md_context_t*) ctx, input, ilen) != 0) - return -1; + return FALSE; #endif - return 0; + return TRUE; } -int winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output) +BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen) { + // TODO: output length check #if defined(WITH_OPENSSL) if (EVP_DigestFinal_ex((EVP_MD_CTX*) ctx, output, NULL) != 1) - return -1; + return FALSE; #elif defined(WITH_MBEDTLS) if (mbedtls_md_finish((mbedtls_md_context_t*) ctx, output) != 0) - return -1; + return FALSE; mbedtls_md_free((mbedtls_md_context_t*) ctx); #endif - return 0; + return TRUE; } -int winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output) +BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen) { WINPR_DIGEST_CTX ctx; - if (winpr_Digest_Init(&ctx, md) != 0) - return -1; + if (!winpr_Digest_Init(&ctx, md)) + return FALSE; - if (winpr_Digest_Update(&ctx, input, ilen) != 0) - return -1; + if (!winpr_Digest_Update(&ctx, input, ilen)) + return FALSE; - if (winpr_Digest_Final(&ctx, output) != 0) - return -1; + if (!winpr_Digest_Final(&ctx, output, olen)) + return FALSE; - return 0; + return TRUE; } diff --git a/winpr/libwinpr/crypto/test/TestCryptoHash.c b/winpr/libwinpr/crypto/test/TestCryptoHash.c index 8178469ac..ec6d5ad6d 100644 --- a/winpr/libwinpr/crypto/test/TestCryptoHash.c +++ b/winpr/libwinpr/crypto/test/TestCryptoHash.c @@ -8,20 +8,23 @@ static const BYTE* TEST_MD5_HASH = (BYTE*) "\x09\x8f\x6b\xcd\x46\x21\xd3\x73\xca BOOL test_crypto_hash_md5() { - BYTE hash[16]; + BYTE hash[WINPR_MD5_DIGEST_LENGTH]; WINPR_MD5_CTX ctx; - winpr_MD5_Init(&ctx); - winpr_MD5_Update(&ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA)); - winpr_MD5_Final(&ctx, hash); + if (!winpr_MD5_Init(&ctx)) + return FALSE; + if (!winpr_MD5_Update(&ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA))) + return FALSE; + if (!winpr_MD5_Final(&ctx, hash, sizeof(hash))) + return FALSE; - if (memcmp(hash, TEST_MD5_HASH, 16) != 0) + if (memcmp(hash, TEST_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { char* actual; char* expected; - actual = winpr_BinToHexString(hash, 16, FALSE); - expected = winpr_BinToHexString(TEST_MD5_HASH, 16, FALSE); + actual = winpr_BinToHexString(hash, WINPR_MD5_DIGEST_LENGTH, FALSE); + expected = winpr_BinToHexString(TEST_MD5_HASH, WINPR_MD5_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected MD5 hash: Actual: %s Expected: %s\n", actual, expected); @@ -39,20 +42,23 @@ static const BYTE* TEST_MD4_HASH = (BYTE*) "\xdb\x34\x6d\x69\x1d\x7a\xcc\x4d\xc2 BOOL test_crypto_hash_md4() { - BYTE hash[16]; + BYTE hash[WINPR_MD4_DIGEST_LENGTH]; WINPR_MD4_CTX ctx; - winpr_MD4_Init(&ctx); - winpr_MD4_Update(&ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA)); - winpr_MD4_Final(&ctx, hash); + if (!winpr_MD4_Init(&ctx)) + return FALSE; + if (!winpr_MD4_Update(&ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA))) + return FALSE; + if (!winpr_MD4_Final(&ctx, hash, sizeof(hash))) + return FALSE; - if (memcmp(hash, TEST_MD4_HASH, 16) != 0) + if (memcmp(hash, TEST_MD4_HASH, WINPR_MD4_DIGEST_LENGTH) != 0) { char* actual; char* expected; - actual = winpr_BinToHexString(hash, 16, FALSE); - expected = winpr_BinToHexString(TEST_MD4_HASH, 16, FALSE); + actual = winpr_BinToHexString(hash, WINPR_MD4_DIGEST_LENGTH, FALSE); + expected = winpr_BinToHexString(TEST_MD4_HASH, WINPR_MD4_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected MD4 hash: Actual: %s Expected: %s\n", actual, expected); @@ -70,20 +76,23 @@ static const BYTE* TEST_SHA1_HASH = (BYTE*) "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1 BOOL test_crypto_hash_sha1() { - BYTE hash[20]; + BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; WINPR_SHA1_CTX ctx; - winpr_SHA1_Init(&ctx); - winpr_SHA1_Update(&ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA)); - winpr_SHA1_Final(&ctx, hash); + if (!winpr_SHA1_Init(&ctx)) + return FALSE; + if (!winpr_SHA1_Update(&ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA))) + return FALSE; + if (!winpr_SHA1_Final(&ctx, hash, sizeof(hash))) + return FALSE; - if (memcmp(hash, TEST_SHA1_HASH, 20) != 0) + if (memcmp(hash, TEST_SHA1_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { char* actual; char* expected; - actual = winpr_BinToHexString(hash, 20, FALSE); - expected = winpr_BinToHexString(TEST_SHA1_HASH, 20, FALSE); + actual = winpr_BinToHexString(hash, WINPR_MD5_DIGEST_LENGTH, FALSE); + expected = winpr_BinToHexString(TEST_SHA1_HASH, WINPR_MD5_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected SHA1 hash: Actual: %s Expected: %s\n", actual, expected); @@ -102,20 +111,23 @@ static const BYTE* TEST_HMAC_MD5_HASH = (BYTE*) "\x92\x94\x72\x7a\x36\x38\xbb\x1 BOOL test_crypto_hash_hmac_md5() { - BYTE hash[16]; + BYTE hash[WINPR_MD5_DIGEST_LENGTH]; WINPR_HMAC_CTX ctx; - winpr_HMAC_Init(&ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, 16); - winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA)); - winpr_HMAC_Final(&ctx, hash); + if (!winpr_HMAC_Init(&ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_SHA1_DIGEST_LENGTH)) + return FALSE; + if (!winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA))) + return FALSE; + if (!winpr_HMAC_Final(&ctx, hash, sizeof(hash))) + return FALSE; - if (memcmp(hash, TEST_HMAC_MD5_HASH, 16) != 0) + if (memcmp(hash, TEST_HMAC_MD5_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0) { char* actual; char* expected; - actual = winpr_BinToHexString(hash, 16, FALSE); - expected = winpr_BinToHexString(TEST_HMAC_MD5_HASH, 16, FALSE); + actual = winpr_BinToHexString(hash, WINPR_SHA1_DIGEST_LENGTH, FALSE); + expected = winpr_BinToHexString(TEST_HMAC_MD5_HASH, WINPR_SHA1_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected HMAC-MD5 hash: Actual: %s Expected: %s\n", actual, expected); @@ -134,20 +146,23 @@ static const BYTE* TEST_HMAC_SHA1_HASH = (BYTE*) "\xb6\x17\x31\x86\x55\x05\x72\x BOOL test_crypto_hash_hmac_sha1() { - BYTE hash[20]; + BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; WINPR_HMAC_CTX ctx; - winpr_HMAC_Init(&ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, 20); - winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA)); - winpr_HMAC_Final(&ctx, hash); + if (!winpr_HMAC_Init(&ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH)) + return FALSE; + if (!winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA))) + return FALSE; + if (!winpr_HMAC_Final(&ctx, hash, sizeof(hash))) + return FALSE; - if (memcmp(hash, TEST_HMAC_SHA1_HASH, 20) != 0) + if (memcmp(hash, TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0) { char* actual; char* expected; - actual = winpr_BinToHexString(hash, 20, FALSE); - expected = winpr_BinToHexString(TEST_HMAC_SHA1_HASH, 20, FALSE); + actual = winpr_BinToHexString(hash, WINPR_SHA1_DIGEST_LENGTH, FALSE); + expected = winpr_BinToHexString(TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected HMAC-SHA1 hash: Actual: %s Expected: %s\n", actual, expected); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 2a7beb0b5..99d63dd2e 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -889,7 +889,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, int length; void* data; UINT32 SeqNo; - BYTE digest[16]; + BYTE digest[WINPR_MD5_DIGEST_LENGTH]; BYTE checksum[8]; BYTE* signature; ULONG version = 1; @@ -923,10 +923,10 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, CopyMemory(data, data_buffer->pvBuffer, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->SendSigningKey, 16); + winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH); winpr_HMAC_Update(&hmac, (void*) &(SeqNo), 4); winpr_HMAC_Update(&hmac, (void*) data, length); - winpr_HMAC_Final(&hmac, digest); + winpr_HMAC_Final(&hmac, digest, WINPR_MD5_DIGEST_LENGTH); /* Encrypt message using with RC4, result overwrites original buffer */ @@ -963,12 +963,12 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD int length; void* data; UINT32 SeqNo; - BYTE digest[16]; + BYTE digest[WINPR_MD5_DIGEST_LENGTH]; BYTE checksum[8]; UINT32 version = 1; WINPR_HMAC_CTX hmac; NTLM_CONTEXT* context; - BYTE expected_signature[16]; + BYTE expected_signature[WINPR_MD5_DIGEST_LENGTH]; PSecBuffer data_buffer = NULL; PSecBuffer signature_buffer = NULL; SeqNo = (UINT32) MessageSeqNo; @@ -1005,10 +1005,10 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD CopyMemory(data_buffer->pvBuffer, data, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->RecvSigningKey, 16); + winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH); winpr_HMAC_Update(&hmac, (void*) &(SeqNo), 4); winpr_HMAC_Update(&hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer); - winpr_HMAC_Final(&hmac, digest); + winpr_HMAC_Final(&hmac, digest, WINPR_MD5_DIGEST_LENGTH); #ifdef WITH_DEBUG_NTLM WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length); winpr_HexDump(TAG, WLOG_DEBUG, data, length); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index d3b980222..96d37384a 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -260,7 +260,7 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) UINT32 ChannelBindingTokenLength; SEC_CHANNEL_BINDINGS* ChannelBindings; - ZeroMemory(context->ChannelBindingsHash, 16); + ZeroMemory(context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); ChannelBindings = context->Bindings.Bindings; if (!ChannelBindings) @@ -275,7 +275,7 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength); ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength); winpr_MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); - winpr_MD5_Final(&md5, context->ChannelBindingsHash); + winpr_MD5_Final(&md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); } void ntlm_compute_single_host_data(NTLM_CONTEXT* context) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index b2973c4ac..b341dbca8 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -315,7 +315,7 @@ int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash) int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context) { BYTE* response; - BYTE value[16]; + BYTE value[WINPR_MD5_DIGEST_LENGTH]; if (context->LmCompatibilityLevel < 2) { @@ -340,7 +340,9 @@ int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context) response = (BYTE*) context->LmChallengeResponse.pvBuffer; /* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */ - winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, 16, (BYTE*) value, 16, (BYTE*) response); + winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH, + (BYTE*) value, WINPR_MD5_DIGEST_LENGTH, + (BYTE*) response, WINPR_MD5_DIGEST_LENGTH); /* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */ CopyMemory(&response[16], context->ClientChallenge, 8); return 1; @@ -356,7 +358,7 @@ int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context) int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context) { BYTE* blob; - BYTE nt_proof_str[16]; + BYTE nt_proof_str[WINPR_MD5_DIGEST_LENGTH]; SecBuffer ntlm_v2_temp; SecBuffer ntlm_v2_temp_chal; PSecBuffer TargetInfo; @@ -385,7 +387,7 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context) WLog_DBG(TAG, "Workstation (length = %d)", context->Workstation.Length); winpr_HexDump(TAG, WLOG_DEBUG, (BYTE*) context->Workstation.Buffer, context->Workstation.Length); WLog_DBG(TAG, "NTOWFv2, NTLMv2 Hash"); - winpr_HexDump(TAG, WLOG_DEBUG, context->NtlmV2Hash, 16); + winpr_HexDump(TAG, WLOG_DEBUG, context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH); #endif /* Construct temp */ blob[0] = 1; /* RespType (1 byte) */ @@ -409,8 +411,9 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context) blob = (BYTE*) ntlm_v2_temp_chal.pvBuffer; CopyMemory(blob, context->ServerChallenge, 8); CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer); - winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, 16, (BYTE*) ntlm_v2_temp_chal.pvBuffer, - ntlm_v2_temp_chal.cbBuffer, (BYTE*) nt_proof_str); + winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH, + (BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer, + (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH); /* NtChallengeResponse, Concatenate NTProofStr with temp */ @@ -421,7 +424,9 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context) CopyMemory(blob, nt_proof_str, 16); CopyMemory(&blob[16], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer); /* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */ - winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, 16, (BYTE*) nt_proof_str, 16, (BYTE*) context->SessionBaseKey); + winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH, + (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH, + (BYTE*) context->SessionBaseKey, WINPR_MD5_DIGEST_LENGTH); sspi_SecBufferFree(&ntlm_v2_temp); sspi_SecBufferFree(&ntlm_v2_temp_chal); return 1; @@ -544,18 +549,18 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic, BYTE* value; WINPR_MD5_CTX md5; - length = 16 + sign_magic->cbBuffer; + length = WINPR_MD5_DIGEST_LENGTH + sign_magic->cbBuffer; value = (BYTE*) malloc(length); if (!value) return -1; /* Concatenate ExportedSessionKey with sign magic */ - CopyMemory(value, exported_session_key, 16); - CopyMemory(&value[16], sign_magic->pvBuffer, sign_magic->cbBuffer); + CopyMemory(value, exported_session_key, WINPR_MD5_DIGEST_LENGTH); + CopyMemory(&value[WINPR_MD5_DIGEST_LENGTH], sign_magic->pvBuffer, sign_magic->cbBuffer); winpr_MD5_Init(&md5); winpr_MD5_Update(&md5, value, length); - winpr_MD5_Final(&md5, signing_key); + winpr_MD5_Final(&md5, signing_key, WINPR_MD5_DIGEST_LENGTH); free(value); return 1; } @@ -602,16 +607,16 @@ int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, WINPR_MD5_CTX md5; SecBuffer buffer; - if (!sspi_SecBufferAlloc(&buffer, 16 + seal_magic->cbBuffer)) + if (!sspi_SecBufferAlloc(&buffer, WINPR_MD5_DIGEST_LENGTH + seal_magic->cbBuffer)) return -1; p = (BYTE*) buffer.pvBuffer; /* Concatenate ExportedSessionKey with seal magic */ - CopyMemory(p, exported_session_key, 16); - CopyMemory(&p[16], seal_magic->pvBuffer, seal_magic->cbBuffer); + CopyMemory(p, exported_session_key, WINPR_MD5_DIGEST_LENGTH); + CopyMemory(&p[WINPR_MD5_DIGEST_LENGTH], seal_magic->pvBuffer, seal_magic->cbBuffer); winpr_MD5_Init(&md5); winpr_MD5_Update(&md5, buffer.pvBuffer, buffer.cbBuffer); - winpr_MD5_Final(&md5, sealing_key); + winpr_MD5_Final(&md5, sealing_key, WINPR_MD5_DIGEST_LENGTH); sspi_SecBufferFree(&buffer); return 1; } @@ -679,9 +684,9 @@ void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context) * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey */ - winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->ExportedSessionKey, 16); + winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH); winpr_HMAC_Update(&hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); winpr_HMAC_Update(&hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); winpr_HMAC_Update(&hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); - winpr_HMAC_Final(&hmac, context->MessageIntegrityCheck); + winpr_HMAC_Final(&hmac, context->MessageIntegrityCheck, WINPR_MD5_DIGEST_LENGTH); } diff --git a/winpr/libwinpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c index 709d4d89c..be1deaedc 100644 --- a/winpr/libwinpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -42,9 +42,12 @@ BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash) if (!NtHash && !(NtHash = malloc(16))) return NULL; - winpr_MD4_Init(&md4); - winpr_MD4_Update(&md4, (BYTE*) Password, (size_t) PasswordLength); - winpr_MD4_Final(&md4, NtHash); + if (!winpr_MD4_Init(&md4)) + return NULL; + if (!winpr_MD4_Update(&md4, (BYTE*) Password, (size_t) PasswordLength)) + return NULL; + if (!winpr_MD4_Final(&md4, NtHash, WINPR_MD4_DIGEST_LENGTH)) + return NULL; return NtHash; } @@ -77,11 +80,12 @@ BYTE* NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User, { BYTE* buffer; BYTE NtHashV1[16]; + BYTE* result = NtHash; if ((!User) || (!Password)) return NULL; - if (!NtHash && !(NtHash = (BYTE*) malloc(16))) + if (!NtHash && !(NtHash = (BYTE*) malloc(WINPR_MD4_DIGEST_LENGTH))) return NULL; if (!NTOWFv1W(Password, PasswordLength, NtHashV1)) @@ -103,11 +107,12 @@ BYTE* NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User, CopyMemory(&buffer[UserLength], Domain, DomainLength); /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */ - winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash); + if (!winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash, WINPR_MD4_DIGEST_LENGTH)) + result = NULL; free(buffer); - return NtHash; + return result; } BYTE* NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, @@ -141,11 +146,12 @@ out_fail: BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Domain, UINT32 DomainLength, BYTE* NtHash) { BYTE* buffer; + BYTE* result = NtHash; if (!User) return NULL; - if (!NtHash && !(NtHash = (BYTE*) malloc(16))) + if (!NtHash && !(NtHash = (BYTE*) malloc(WINPR_MD4_DIGEST_LENGTH))) return NULL; if (!(buffer = (BYTE*) malloc(UserLength + DomainLength))) @@ -165,11 +171,12 @@ BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Do } /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */ - winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash); + if (!winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash, WINPR_MD4_DIGEST_LENGTH)) + result = NULL; free(buffer); - return NtHash; + return result; } BYTE* NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domain, UINT32 DomainLength, BYTE* NtHash)