diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index c3da023c7..4776e8b14 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -490,19 +490,19 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { - rdp->fips_encrypt = winpr_Cipher_New( WINPR_CIPHER_DES_EDE3_CBC, - WINPR_ENCRYPT, - rdp->fips_encrypt_key, - fips_ivec); + rdp->fips_encrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC, + WINPR_ENCRYPT, + rdp->fips_encrypt_key, + fips_ivec); if (!rdp->fips_encrypt) { WLog_ERR(TAG, "unable to allocate des3 encrypt key"); goto end; } rdp->fips_decrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC, - WINPR_DECRYPT, - rdp->fips_decrypt_key, - fips_ivec); + WINPR_DECRYPT, + rdp->fips_decrypt_key, + fips_ivec); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 4b5ee5f5c..ee5f65fd4 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -45,7 +45,6 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] = BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { - WINPR_HMAC_CTX* hmac; BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; @@ -70,11 +69,7 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ - if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, AutoReconnectRandom, 16))) - return FALSE; - if (!winpr_HMAC_Update(hmac, ClientRandom, 32)) - return FALSE; - if (!winpr_HMAC_Final(hmac, clientCookie->securityVerifier, 16)) + if (!winpr_HMAC(WINPR_MD_MD5, AutoReconnectRandom, 16, ClientRandom, 32, clientCookie->securityVerifier, 16)) return FALSE; return TRUE; diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index 4d5a03e47..f10e3d42e 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -127,36 +127,46 @@ fips_oddparity_table[256] = static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length, const BYTE* salt1, const BYTE* salt2, BYTE* output) { - WINPR_DIGEST_CTX* md5; - WINPR_DIGEST_CTX* sha1; + WINPR_DIGEST_CTX* sha1 = NULL; + WINPR_DIGEST_CTX* md5 = NULL; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; + BOOL result = FALSE; /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */ /* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */ - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; + if (!(sha1 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1)) + goto out; if (!winpr_Digest_Update(sha1, input, length)) /* Input */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, salt, 48)) /* Salt (48 bytes) */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, salt1, 32)) /* Salt1 (32 bytes) */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, salt2, 32)) /* Salt2 (32 bytes) */ - return FALSE; + goto out; if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) - return FALSE; + goto out; /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */ - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) - return FALSE; + if (!(md5 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, salt, 48)) /* Salt (48 bytes) */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ - return FALSE; + goto out; if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) - return FALSE; - return TRUE; + goto out; + + result = TRUE; +out: + winpr_Digest_Free(sha1); + winpr_Digest_Free(md5); + return result; } static BOOL security_premaster_hash(const char* input, int length, const BYTE* premaster_secret, @@ -200,19 +210,26 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output) { - WINPR_DIGEST_CTX* md5; + WINPR_DIGEST_CTX* md5 = NULL; + BOOL result = FALSE; - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + if (!(md5 = winpr_Digest_New())) return FALSE; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, in0, 16)) - return FALSE; + goto out; if (!winpr_Digest_Update(md5, in1, 32)) - return FALSE; + goto out; if (!winpr_Digest_Update(md5, in2, 32)) - return FALSE; + goto out; if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) - return FALSE; - return TRUE; + goto out; + + result = TRUE; +out: + winpr_Digest_Free(md5); + return result; } BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random, @@ -233,92 +250,112 @@ void security_UINT32_le(BYTE* output, UINT32 value) BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output) { - WINPR_DIGEST_CTX* md5; - WINPR_DIGEST_CTX* sha1; + WINPR_DIGEST_CTX* sha1 = NULL; + WINPR_DIGEST_CTX* md5 = NULL; BYTE length_le[4]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; + BOOL result = FALSE; /* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */ security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */ - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; + if (!(sha1 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1)) + goto out; if (!winpr_Digest_Update(sha1, mac_salt_key, 16)) /* MacSaltKey */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, data, length)) /* data */ - return FALSE; + goto out; if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) - return FALSE; + goto out; /* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */ - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) - return FALSE; + if (!(md5 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, mac_salt_key, 16)) /* MacSaltKey */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ - return FALSE; + goto out; if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH)) - return FALSE; - return TRUE; + goto out; + + result = TRUE; +out: + winpr_Digest_Free(sha1); + winpr_Digest_Free(md5); + return result; } BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output) { - WINPR_DIGEST_CTX* md5; - WINPR_DIGEST_CTX* sha1; + WINPR_DIGEST_CTX* sha1 = NULL; + WINPR_DIGEST_CTX* md5 = NULL; BYTE length_le[4]; BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; + BOOL result = FALSE; security_UINT32_le(length_le, length); /* length must be little-endian */ /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; + if (!(sha1 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1)) + goto out; if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, data, length)) /* data */ - return FALSE; + goto out; if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) - return FALSE; + goto out; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) - return FALSE; + if (!(md5 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ - return FALSE; + goto out; if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest))) - return FALSE; + goto out; memcpy(output, md5_digest, 8); - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(sha1); + winpr_Digest_Free(md5); + return result; } BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output) { - WINPR_DIGEST_CTX* md5; - WINPR_DIGEST_CTX* sha1; + WINPR_DIGEST_CTX* sha1 = NULL; + WINPR_DIGEST_CTX* md5 = NULL; BYTE length_le[4]; BYTE use_count_le[4]; BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH]; BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH]; + BOOL result = FALSE; security_UINT32_le(length_le, length); /* length must be little-endian */ @@ -336,35 +373,43 @@ BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, } /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ - if (!(sha1 = winpr_Digest_New( WINPR_MD_SHA1))) - return FALSE; + if (!(sha1 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1)) + goto out; if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, data, length)) /* data */ - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */ - return FALSE; + goto out; if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest))) - return FALSE; + goto out; /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) - return FALSE; + if (!(md5 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */ - return FALSE; + goto out; if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */ - return FALSE; + goto out; if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest))) - return FALSE; + goto out; memcpy(output, md5_digest, 8); - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(sha1); + winpr_Digest_Free(md5); + return result; } static BOOL security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random, @@ -437,34 +482,39 @@ 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]; - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) + if (!(sha1 = winpr_Digest_New())) return FALSE; - if (!winpr_Digest_Update(sha1, client_random + 16, 16)) - return FALSE; - if (!winpr_Digest_Update(sha1, server_random + 16, 16)) - return FALSE; - if (!winpr_Digest_Final(sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t))) + + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) || + !winpr_Digest_Update(sha1, client_random + 16, 16) || + !winpr_Digest_Update(sha1, server_random + 16, 16) || + !winpr_Digest_Final(sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t))) + { + winpr_Digest_Free(sha1); return FALSE; + } client_encrypt_key_t[20] = client_encrypt_key_t[0]; - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; - if (!winpr_Digest_Update(sha1, client_random, 16)) - return FALSE; - if (!winpr_Digest_Update(sha1, server_random, 16)) - return FALSE; - if (!winpr_Digest_Final(sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t))) + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) || + !winpr_Digest_Update(sha1, client_random, 16) || + !winpr_Digest_Update(sha1, server_random, 16) || + !winpr_Digest_Final(sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t))) + { + winpr_Digest_Free(sha1); return FALSE; + } client_decrypt_key_t[20] = client_decrypt_key_t[0]; - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; - if (!winpr_Digest_Update(sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) - return FALSE; - if (!winpr_Digest_Update(sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH)) - return FALSE; - if (!winpr_Digest_Final(sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) || + !winpr_Digest_Update(sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH) || + !winpr_Digest_Update(sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH) || + !winpr_Digest_Final(sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + { + winpr_Digest_Free(sha1); return FALSE; + } + + winpr_Digest_Free(sha1); if (rdp->settings->ServerMode) { @@ -536,48 +586,56 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) { BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH]; - WINPR_DIGEST_CTX* md5; - WINPR_DIGEST_CTX* sha1; - WINPR_RC4_CTX* rc4; + WINPR_DIGEST_CTX* sha1 = NULL; + WINPR_DIGEST_CTX* md5 = NULL; + WINPR_RC4_CTX* rc4 = NULL; BOOL rc; BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */ + BOOL result = FALSE; - if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1))) - return FALSE; + if (!(sha1 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1)) + goto out; if (!winpr_Digest_Update(sha1, update_key, key_len)) - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) - return FALSE; + goto out; if (!winpr_Digest_Update(sha1, key, key_len)) - return FALSE; + goto out; if (!winpr_Digest_Final(sha1, sha1h, sizeof(sha1h))) - return FALSE; + goto out; - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) - return FALSE; + if (!(md5 = winpr_Digest_New())) + goto out; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; if (!winpr_Digest_Update(md5, update_key, key_len)) - return FALSE; + goto out; if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) - return FALSE; + goto out; if (!winpr_Digest_Update(md5, sha1h, sizeof(sha1h))) - return FALSE; + goto out; if (!winpr_Digest_Final(md5, key, WINPR_MD5_DIGEST_LENGTH)) - return FALSE; + goto out; if (!(rc4 = winpr_RC4_New(key, key_len))) - return FALSE; - rc = winpr_RC4_Update(rc4, key_len, key, key); - winpr_RC4_Free(rc4); - - if (!rc) - return FALSE; + goto out; + if (!winpr_RC4_Update(rc4, key_len, key, key)) + goto out; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT) memcpy(key, salt, 3); else if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_56BIT) memcpy(key, salt, 1); - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(sha1); + winpr_Digest_Free(md5); + winpr_RC4_Free(rc4); + + return result; } BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp) @@ -631,20 +689,26 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* BYTE buf[WINPR_SHA1_DIGEST_LENGTH]; BYTE use_count_le[4]; WINPR_HMAC_CTX* hmac; + BOOL result = FALSE; security_UINT32_le(use_count_le, rdp->encrypt_use_count); - if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))) + if (!(hmac = winpr_HMAC_New())) return FALSE; + if (!winpr_HMAC_Init(hmac, WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + goto out; if (!winpr_HMAC_Update(hmac, data, length)) - return FALSE; + goto out; if (!winpr_HMAC_Update(hmac, use_count_le, 4)) - return FALSE; + goto out; if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) - return FALSE; + goto out; memmove(output, buf, 8); - return TRUE; + result = TRUE; +out: + winpr_HMAC_Free(hmac); + return result; } BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp) @@ -671,22 +735,26 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig BYTE buf[WINPR_SHA1_DIGEST_LENGTH]; BYTE use_count_le[4]; WINPR_HMAC_CTX* hmac; + BOOL result = FALSE; security_UINT32_le(use_count_le, rdp->decrypt_use_count); - if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))) + if (!(hmac = winpr_HMAC_New())) return FALSE; + if (!winpr_HMAC_Init(hmac, WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)) + goto out; if (!winpr_HMAC_Update(hmac, data, length)) - return FALSE; + goto out; if (!winpr_HMAC_Update(hmac, use_count_le, 4)) - return FALSE; + goto out; if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH)) - return FALSE; + goto out; rdp->decrypt_use_count++; - if (memcmp(sig, buf, 8)) - return FALSE; - - return TRUE; + if (!memcmp(sig, buf, 8)) + result = TRUE; +out: + winpr_HMAC_Free(hmac); + return result; } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index e839fa2ca..d833109ee 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -249,17 +249,11 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) { case BIO_CTRL_RESET: SSL_shutdown(tls->ssl); -#if 1 + if (SSL_in_connect_init(tls->ssl)) SSL_set_connect_state(tls->ssl); else if (SSL_in_accept_init(tls->ssl)) SSL_set_accept_state(tls->ssl); -#else - if (tls->ssl->handshake_func == tls->ssl->method->ssl_connect) - SSL_set_connect_state(tls->ssl); - else if (tls->ssl->handshake_func == tls->ssl->method->ssl_accept) - SSL_set_accept_state(tls->ssl); -#endif SSL_clear(tls->ssl); diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h index 233f05163..3ee989ec9 100644 --- a/winpr/include/winpr/crypto.h +++ b/winpr/include/winpr/crypto.h @@ -642,10 +642,11 @@ typedef struct _winpr_hmac_ctx_private_st WINPR_HMAC_CTX; extern "C" { #endif -WINPR_API WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen); +WINPR_API WINPR_HMAC_CTX* winpr_HMAC_New(void); +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 void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx); +WINPR_API void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx); 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); @@ -663,7 +664,8 @@ typedef struct _winpr_digest_ctx_private_st WINPR_DIGEST_CTX; extern "C" { #endif -WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md); +WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(void); +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 void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx); diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c index b9948682f..c60e07d17 100644 --- a/winpr/libwinpr/crypto/cipher.c +++ b/winpr/libwinpr/crypto/cipher.c @@ -39,7 +39,6 @@ #include #endif - /** * RC4 */ @@ -69,12 +68,13 @@ BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE { #if defined(WITH_OPENSSL) RC4((RC4_KEY*) ctx, length, input, output); + return TRUE; #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C) - if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0) - return FALSE; + if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) == 0) + return TRUE; #endif - return TRUE; + return FALSE; } void winpr_RC4_Free(WINPR_RC4_CTX* ctx) @@ -308,6 +308,7 @@ const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher) return evp; } + #elif defined(WITH_MBEDTLS) mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher) { @@ -592,15 +593,18 @@ BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, #if defined(WITH_OPENSSL) int outl = (int) *olen; - if (EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx, output, &outl, input, ilen) != 1) - return FALSE; + if (EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx, output, &outl, input, ilen) == 1) + { + *olen = (size_t) outl; + return TRUE; + } - *olen = (size_t) outl; #elif defined(WITH_MBEDTLS) - if (mbedtls_cipher_update((mbedtls_cipher_context_t*) ctx, input, ilen, output, olen) != 0) - return FALSE; + if (mbedtls_cipher_update((mbedtls_cipher_context_t*) ctx, input, ilen, output, olen) == 0) + return TRUE; #endif - return TRUE; + + return FALSE; } BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen) @@ -608,15 +612,18 @@ 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 FALSE; + if (EVP_CipherFinal_ex((EVP_CIPHER_CTX*) ctx, output, &outl) == 1) + { + *olen = (size_t) outl; + return TRUE; + } - *olen = (size_t) outl; #elif defined(WITH_MBEDTLS) - if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) != 0) - return FALSE; + if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) == 0) + return TRUE; #endif - return TRUE; + + return FALSE; } void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx) diff --git a/winpr/libwinpr/crypto/hash.c b/winpr/libwinpr/crypto/hash.c index ccc768ced..fb61933f5 100644 --- a/winpr/libwinpr/crypto/hash.c +++ b/winpr/libwinpr/crypto/hash.c @@ -142,32 +142,126 @@ mbedtls_md_type_t winpr_mbedtls_get_md_type(int md) } #endif - -WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen) +WINPR_HMAC_CTX* winpr_HMAC_New(void) { WINPR_HMAC_CTX* ctx = NULL; #if defined(WITH_OPENSSL) - const EVP_MD* evp = winpr_openssl_get_evp_md(md); - HMAC_CTX* hmac; - - if (!evp) - return NULL; - + HMAC_CTX* hmac = NULL; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) - if (!(hmac = calloc(1, sizeof(HMAC_CTX)))) + if (!(hmac = (HMAC_CTX*) calloc(1, sizeof(HMAC_CTX)))) return NULL; - HMAC_CTX_init(hmac); #else if (!(hmac = HMAC_CTX_new())) return NULL; #endif + ctx = (WINPR_HMAC_CTX*) hmac; + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* hmac; + if (!(hmac = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) + return NULL; + + mbedtls_md_init(hmac); + + ctx = (WINPR_HMAC_CTX*) hmac; +#endif + + return ctx; +} + +BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen) +{ +#if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; + const EVP_MD* evp = winpr_openssl_get_evp_md(md); + + if (!evp || !hmac) + return FALSE; #if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Init_ex(hmac, key, keylen, evp, NULL); + HMAC_Init_ex(hmac, key, keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */ + return TRUE; #else - if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) != 1) + if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) == 1) + return TRUE; +#endif + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx; + mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); + const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); + + if (!md_info || !hmac) + return FALSE; + + if (hmac->md_info != md_info) + { + mbedtls_md_free(hmac); /* can be called at any time after mbedtls_md_init */ + + if (mbedtls_md_setup(hmac, md_info, 1) != 0) + return FALSE; + } + + if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0) + return TRUE; +#endif + + return FALSE; +} + +BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen) +{ +#if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */ + return TRUE; +#else + if (HMAC_Update(hmac, input, ilen) == 1) + return TRUE; +#endif + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0) + return TRUE; +#endif + + return FALSE; +} + +BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen) +{ + if (!ctx) + return FALSE; + +#if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */ + return TRUE; +#else + if (HMAC_Final(hmac, output, NULL) == 1) + return TRUE; +#endif + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mbedtls_md_hmac_finish(mdctx, output) == 0) + return TRUE; +#endif + + return FALSE; +} + +void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx) +{ +#if defined(WITH_OPENSSL) + HMAC_CTX* hmac = (HMAC_CTX*) ctx; + if (hmac) { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) HMAC_CTX_cleanup(hmac); @@ -175,178 +269,103 @@ WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen) #else HMAC_CTX_free(hmac); #endif - return NULL; } -#endif - ctx = (WINPR_HMAC_CTX*) hmac; #elif defined(WITH_MBEDTLS) - mbedtls_md_context_t* mdctx; - mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); - const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); - - if (!md_info) - return NULL; - - if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) - return NULL; - - mbedtls_md_init(mdctx); - - if (mbedtls_md_setup(mdctx, md_info, 1) != 0) + mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx; + if (hmac) { - mbedtls_md_free(mdctx); - free(mdctx); - return NULL; + mbedtls_md_free(hmac); + free(hmac); } - - if (mbedtls_md_hmac_starts(mdctx, key, keylen) != 0) - { - mbedtls_md_free(mdctx); - free(mdctx); - return NULL; - } - ctx = (WINPR_HMAC_CTX*) mdctx; #endif - return ctx; -} - -BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen) -{ -#if defined(WITH_OPENSSL) - HMAC_CTX* hmac = (HMAC_CTX*) ctx; -#if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Update(hmac, input, ilen); -#else - if (HMAC_Update(hmac, input, ilen) != 1) - return FALSE; -#endif - -#elif defined(WITH_MBEDTLS) - mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; - if (mbedtls_md_hmac_update(mdctx, input, ilen) != 0) - return FALSE; -#endif - return TRUE; -} - -BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen) -{ - /* TODO - if (olen < ctx->digestLength) - return FALSE; - */ - BOOL ret = TRUE; -#if defined(WITH_OPENSSL) - HMAC_CTX* hmac = (HMAC_CTX*) ctx; -#if (OPENSSL_VERSION_NUMBER < 0x10000000L) - HMAC_Final(hmac, output, NULL); -#else - if (HMAC_Final(hmac, output, NULL) != 1) - ret = FALSE; -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - HMAC_CTX_cleanup(hmac); - free(hmac); -#else - HMAC_CTX_free(hmac); -#endif - -#elif defined(WITH_MBEDTLS) - mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; - if (mbedtls_md_hmac_finish(mdctx, output) != 0) - ret = FALSE; - - mbedtls_md_free((mbedtls_md_context_t*) ctx); - free(mdctx); -#endif - return ret; } 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 = winpr_HMAC_New(md, key, keylen); + BOOL result = FALSE; + WINPR_HMAC_CTX *ctx = winpr_HMAC_New(); if (!ctx) return FALSE; + if (!winpr_HMAC_Init(ctx, md, key, keylen)) + goto out; if (!winpr_HMAC_Update(ctx, input, ilen)) - return FALSE; - + goto out; if (!winpr_HMAC_Final(ctx, output, olen)) - return FALSE; + goto out; - return TRUE; + result = TRUE; +out: + winpr_HMAC_Free(ctx); + return result; } /** * Generic Digest API */ -WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md) +WINPR_DIGEST_CTX* winpr_Digest_New(void) { WINPR_DIGEST_CTX* ctx = NULL; #if defined(WITH_OPENSSL) - const EVP_MD* evp = winpr_openssl_get_evp_md(md); EVP_MD_CTX* mdctx; - - if (!evp) - return NULL; - #if (OPENSSL_VERSION_NUMBER < 0x10100000L) mdctx = EVP_MD_CTX_create(); #else mdctx = EVP_MD_CTX_new(); #endif - if (!mdctx) - return NULL; - - if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1) - { -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - EVP_MD_CTX_destroy(mdctx); -#else - EVP_MD_CTX_free(mdctx); -#endif - return NULL; - } ctx = (WINPR_DIGEST_CTX*) mdctx; #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* mdctx; - mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); - const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); - - if (!md_info) - return NULL; - - if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) - return NULL; - - mbedtls_md_init(mdctx); - - if (mbedtls_md_setup(mdctx, md_info, 0) != 0) - { - mbedtls_md_free(mdctx); - free(mdctx); - return NULL; - } - - if (mbedtls_md_starts(mdctx) != 0) - { - mbedtls_md_free(mdctx); - free(mdctx); - return NULL; - } + mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)); + if (mdctx) + mbedtls_md_init(mdctx); ctx = (WINPR_DIGEST_CTX*) mdctx; #endif return ctx; } +BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md) +{ +#if defined(WITH_OPENSSL) + EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; + const EVP_MD* evp = winpr_openssl_get_evp_md(md); + + if (!mdctx || !evp) + return FALSE; + + if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1) + return FALSE; + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); + const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); + + if (!md_info) + return FALSE; + + if (mdctx->md_info != md_info) + { + mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */ + + if (mbedtls_md_setup(mdctx, md_info, 0) != 0) + return FALSE; + } + + if (mbedtls_md_starts(mdctx) != 0) + return FALSE; +#endif + + return TRUE; +} + BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) { #if defined(WITH_OPENSSL) @@ -363,42 +382,60 @@ BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen) BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen) { - // TODO: output length check - BOOL ret = TRUE; #if defined(WITH_OPENSSL) EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; - if (EVP_DigestFinal_ex(mdctx, output, NULL) != 1) - ret = FALSE; - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - EVP_MD_CTX_destroy(mdctx); -#else - EVP_MD_CTX_free(mdctx); -#endif + if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1) + return TRUE; #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; - if (mbedtls_md_finish(mdctx, output) != 0) - ret = FALSE; - - mbedtls_md_free(mdctx); - free(mdctx); + if (mbedtls_md_finish(mdctx, output) == 0) + return TRUE; +#endif + + return FALSE; +} + +void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx) +{ +#if defined(WITH_OPENSSL) + EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; + if (mdctx) + { +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif + } + +#elif defined(WITH_MBEDTLS) + mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; + if (mdctx) + { + mbedtls_md_free(mdctx); + free(mdctx); + } #endif - return ret; } BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen) { - WINPR_DIGEST_CTX *ctx = winpr_Digest_New(md); + BOOL result = FALSE; + WINPR_DIGEST_CTX *ctx = winpr_Digest_New(); if (!ctx) return FALSE; + if (!winpr_Digest_Init(ctx, md)) + goto out; if (!winpr_Digest_Update(ctx, input, ilen)) - return FALSE; - + goto out; if (!winpr_Digest_Final(ctx, output, olen)) - return FALSE; + goto out; - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(ctx); + return result; } diff --git a/winpr/libwinpr/crypto/test/TestCryptoHash.c b/winpr/libwinpr/crypto/test/TestCryptoHash.c index f5b990d65..a5101c81f 100644 --- a/winpr/libwinpr/crypto/test/TestCryptoHash.c +++ b/winpr/libwinpr/crypto/test/TestCryptoHash.c @@ -8,25 +8,30 @@ static const BYTE* TEST_MD5_HASH = (BYTE*) "\x09\x8f\x6b\xcd\x46\x21\xd3\x73\xca static BOOL test_crypto_hash_md5(void) { + BOOL result = FALSE; BYTE hash[WINPR_MD5_DIGEST_LENGTH]; WINPR_DIGEST_CTX* ctx; - if (!(ctx = winpr_Digest_New(WINPR_MD_MD5))) + if (!(ctx = winpr_Digest_New())) { fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; } + if (!winpr_Digest_Init(ctx, WINPR_MD_MD5)) + { + fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__); + goto out; + } if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA))) { fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); - return FALSE; + goto out; } if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) { fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); - return FALSE; + goto out; } - if (memcmp(hash, TEST_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) { char* actual; @@ -40,10 +45,13 @@ static BOOL test_crypto_hash_md5(void) free(actual); free(expected); - return FALSE; + goto out; } - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(ctx); + return result; } static const char* TEST_MD4_DATA = "test"; @@ -51,25 +59,30 @@ static const BYTE* TEST_MD4_HASH = (BYTE*) "\xdb\x34\x6d\x69\x1d\x7a\xcc\x4d\xc2 static BOOL test_crypto_hash_md4(void) { + BOOL result = FALSE; BYTE hash[WINPR_MD4_DIGEST_LENGTH]; WINPR_DIGEST_CTX* ctx; - if (!(ctx = winpr_Digest_New(WINPR_MD_MD4))) + if (!(ctx = winpr_Digest_New())) { fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; } + if (!winpr_Digest_Init(ctx, WINPR_MD_MD4)) + { + fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__); + goto out; + } if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA))) { fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); - return FALSE; + goto out; } if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) { fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); - return FALSE; + goto out; } - if (memcmp(hash, TEST_MD4_HASH, WINPR_MD4_DIGEST_LENGTH) != 0) { char* actual; @@ -83,10 +96,13 @@ static BOOL test_crypto_hash_md4(void) free(actual); free(expected); - return FALSE; + goto out; } - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(ctx); + return result; } static const char* TEST_SHA1_DATA = "test"; @@ -94,23 +110,29 @@ static const BYTE* TEST_SHA1_HASH = (BYTE*) "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1 static BOOL test_crypto_hash_sha1(void) { + BOOL result = FALSE; BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; WINPR_DIGEST_CTX* ctx; - if (!(ctx = winpr_Digest_New(WINPR_MD_SHA1))) + if (!(ctx = winpr_Digest_New())) { fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__); return FALSE; } + if (!winpr_Digest_Init(ctx, WINPR_MD_SHA1)) + { + fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__); + goto out; + } if (!winpr_Digest_Update(ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA))) { fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__); - return FALSE; + goto out; } if (!winpr_Digest_Final(ctx, hash, sizeof(hash))) { fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__); - return FALSE; + goto out; } if (memcmp(hash, TEST_SHA1_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) @@ -126,10 +148,13 @@ static BOOL test_crypto_hash_sha1(void) free(actual); free(expected); - return FALSE; + goto out; } - return TRUE; + result = TRUE; +out: + winpr_Digest_Free(ctx); + return result; } static const char* TEST_HMAC_MD5_DATA = "Hi There"; @@ -140,21 +165,28 @@ static BOOL test_crypto_hash_hmac_md5(void) { BYTE hash[WINPR_MD5_DIGEST_LENGTH]; WINPR_HMAC_CTX* ctx; + BOOL result = FALSE; - if (!(ctx = winpr_HMAC_New(WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH))) + if (!(ctx = winpr_HMAC_New())) { fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__); return FALSE; } + + if (!winpr_HMAC_Init(ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH)) + { + fprintf(stderr, "%s: winpr_HMAC_Init failed\n", __FUNCTION__); + goto out; + } if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA))) { fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__); - return FALSE; + goto out; } if (!winpr_HMAC_Final(ctx, hash, sizeof(hash))) { fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__); - return FALSE; + goto out; } if (memcmp(hash, TEST_HMAC_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0) @@ -170,10 +202,13 @@ static BOOL test_crypto_hash_hmac_md5(void) free(actual); free(expected); - return FALSE; + goto out; } - return TRUE; + result = TRUE; +out: + winpr_HMAC_Free(ctx); + return result; } static const char* TEST_HMAC_SHA1_DATA = "Hi There"; @@ -184,21 +219,28 @@ static BOOL test_crypto_hash_hmac_sha1(void) { BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; WINPR_HMAC_CTX* ctx; + BOOL result = FALSE; - if (!(ctx = winpr_HMAC_New(WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH))) + if (!(ctx = winpr_HMAC_New())) { fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__); return FALSE; } + + if (!winpr_HMAC_Init(ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH)) + { + fprintf(stderr, "%s: winpr_HMAC_Init failed\n", __FUNCTION__); + goto out; + } if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA))) { fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__); - return FALSE; + goto out; } if (!winpr_HMAC_Final(ctx, hash, sizeof(hash))) { fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__); - return FALSE; + goto out; } if (memcmp(hash, TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0) @@ -214,10 +256,13 @@ static BOOL test_crypto_hash_hmac_sha1(void) free(actual); free(expected); - return FALSE; + goto out; } - return TRUE; + result = TRUE; +out: + winpr_HMAC_Free(ctx); + return result; } int TestCryptoHash(int argc, char* argv[]) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 2eff5aa29..90ee89c40 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -943,17 +943,22 @@ 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 */ - if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH))) + hmac = winpr_HMAC_New(); + if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH)) { + Data_Write_UINT32(&value, SeqNo); + winpr_HMAC_Update(hmac, (void*) &value, 4); + winpr_HMAC_Update(hmac, (void*) data, length); + winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); + winpr_HMAC_Free(hmac); + } + else + { + winpr_HMAC_Free(hmac); free(data); return SEC_E_INSUFFICIENT_MEMORY; } - Data_Write_UINT32(&value, SeqNo); - winpr_HMAC_Update(hmac, (void*) &value, 4); - winpr_HMAC_Update(hmac, (void*) data, length); - winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); - /* Encrypt message using with RC4, result overwrites original buffer */ if (context->confidentiality) @@ -1032,15 +1037,21 @@ 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 */ - if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH))) + hmac = winpr_HMAC_New(); + if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH)) { + Data_Write_UINT32(&value, SeqNo); + winpr_HMAC_Update(hmac, (void*) &value, 4); + winpr_HMAC_Update(hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer); + winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); + winpr_HMAC_Free(hmac); + } + else + { + winpr_HMAC_Free(hmac); free(data); return SEC_E_INSUFFICIENT_MEMORY; } - Data_Write_UINT32(&value, SeqNo); - winpr_HMAC_Update(hmac, (void*) &value, 4); - winpr_HMAC_Update(hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer); - 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 4d643b58f..48c9b65c6 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -246,14 +246,14 @@ typedef struct gss_channel_bindings_struct { } *gss_channel_bindings_t; */ -static void ntlm_md5_update_uint32_be(WINPR_DIGEST_CTX* md5, UINT32 num) +static BOOL ntlm_md5_update_uint32_be(WINPR_DIGEST_CTX* md5, UINT32 num) { BYTE be32[4]; be32[0] = (num >> 0) & 0xFF; be32[1] = (num >> 8) & 0xFF; be32[2] = (num >> 16) & 0xFF; be32[3] = (num >> 24) & 0xFF; - winpr_Digest_Update(md5, be32, 4); + return winpr_Digest_Update(md5, be32, 4); } void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) @@ -269,20 +269,33 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) if (!ChannelBindings) return; - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + if (!(md5 = winpr_Digest_New())) return; + if (!winpr_Digest_Init(md5, WINPR_MD_MD5)) + goto out; + ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS); ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; - ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType); - ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength); - ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType); - ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength); - ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength); + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType)) + goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength)) + goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType)) + goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength)) + goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength)) + goto out; - winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); - winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); + if (!winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength)) + goto out; + if (!winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH)) + goto out; + +out: + winpr_Digest_Free(md5); } 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 8fb194c73..4f492c1f6 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -549,7 +549,6 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic, { int length; BYTE* value; - WINPR_DIGEST_CTX* md5; length = WINPR_MD5_DIGEST_LENGTH + sign_magic->cbBuffer; value = (BYTE*) malloc(length); @@ -561,13 +560,11 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic, CopyMemory(value, exported_session_key, WINPR_MD5_DIGEST_LENGTH); CopyMemory(&value[WINPR_MD5_DIGEST_LENGTH], sign_magic->pvBuffer, sign_magic->cbBuffer); - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + if (!winpr_Digest(WINPR_MD_MD5, value, length, signing_key, WINPR_MD5_DIGEST_LENGTH)) { free(value); return -1; } - winpr_Digest_Update(md5, value, length); - winpr_Digest_Final(md5, signing_key, WINPR_MD5_DIGEST_LENGTH); free(value); return 1; } @@ -611,7 +608,6 @@ void ntlm_generate_server_signing_key(NTLM_CONTEXT* context) int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, BYTE* sealing_key) { BYTE* p; - WINPR_DIGEST_CTX* md5; SecBuffer buffer; if (!sspi_SecBufferAlloc(&buffer, WINPR_MD5_DIGEST_LENGTH + seal_magic->cbBuffer)) @@ -622,13 +618,12 @@ int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, CopyMemory(p, exported_session_key, WINPR_MD5_DIGEST_LENGTH); CopyMemory(&p[WINPR_MD5_DIGEST_LENGTH], seal_magic->pvBuffer, seal_magic->cbBuffer); - if (!(md5 = winpr_Digest_New(WINPR_MD_MD5))) + if (!winpr_Digest(WINPR_MD_MD5, buffer.pvBuffer, buffer.cbBuffer, sealing_key, WINPR_MD5_DIGEST_LENGTH)) { sspi_SecBufferFree(&buffer); return -1; } - winpr_Digest_Update(md5, buffer.pvBuffer, buffer.cbBuffer); - winpr_Digest_Final(md5, sealing_key, WINPR_MD5_DIGEST_LENGTH); + sspi_SecBufferFree(&buffer); return 1; } @@ -695,13 +690,17 @@ void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context) * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey */ - WINPR_HMAC_CTX* hmac = winpr_HMAC_New(WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH); + WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); - if (hmac) + if (!hmac) + return; + + if (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_MD5_DIGEST_LENGTH); } + winpr_HMAC_Free(hmac); } diff --git a/winpr/libwinpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c index 4ca9c8d55..7dd05eeb3 100644 --- a/winpr/libwinpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -35,22 +35,20 @@ BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash) { BOOL allocate = !NtHash; - WINPR_DIGEST_CTX* md4; if (!Password) return NULL; - if (!(md4 = winpr_Digest_New(WINPR_MD_MD4))) - return NULL; - if (!winpr_Digest_Update(md4, (BYTE*) Password, (size_t) PasswordLength)) - return NULL; if (!NtHash && !(NtHash = malloc(WINPR_MD4_DIGEST_LENGTH))) return NULL; - if (!winpr_Digest_Final(md4, NtHash, WINPR_MD4_DIGEST_LENGTH)) + + if (!winpr_Digest(WINPR_MD_MD4, (BYTE*) Password, (size_t) PasswordLength, NtHash, WINPR_MD4_DIGEST_LENGTH)) { if (allocate) + { free(NtHash); - return NULL; + NtHash = NULL; + } } return NtHash;