Updated RC4 API, fixed crashing bug.
This commit is contained in:
parent
238ff3b315
commit
92c15783dc
@ -513,12 +513,27 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
|
if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
|
||||||
winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
|
goto end;
|
||||||
|
if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
|
||||||
|
goto end;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
end:
|
end:
|
||||||
free(crypt_client_random);
|
free(crypt_client_random);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||||
|
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||||
|
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||||
|
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||||
|
|
||||||
|
rdp->fips_decrypt = NULL;
|
||||||
|
rdp->fips_encrypt = NULL;
|
||||||
|
rdp->rc4_decrypt_key = NULL;
|
||||||
|
rdp->rc4_encrypt_key = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,12 +590,12 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
|||||||
if (rand_len != key_len + 8)
|
if (rand_len != key_len + 8)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "invalid encrypted client random length");
|
WLog_ERR(TAG, "invalid encrypted client random length");
|
||||||
goto end2;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypt_client_random = calloc(1, rand_len);
|
crypt_client_random = calloc(1, rand_len);
|
||||||
if (!crypt_client_random)
|
if (!crypt_client_random)
|
||||||
goto end2;
|
goto end;
|
||||||
Stream_Read(s, crypt_client_random, rand_len);
|
Stream_Read(s, crypt_client_random, rand_len);
|
||||||
|
|
||||||
mod = rdp->settings->RdpServerRsaKey->Modulus;
|
mod = rdp->settings->RdpServerRsaKey->Modulus;
|
||||||
@ -589,9 +604,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
|||||||
|
|
||||||
/* now calculate encrypt / decrypt and update keys */
|
/* now calculate encrypt / decrypt and update keys */
|
||||||
if (!security_establish_keys(client_random, rdp))
|
if (!security_establish_keys(client_random, rdp))
|
||||||
{
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
|
||||||
|
|
||||||
rdp->do_crypt = TRUE;
|
rdp->do_crypt = TRUE;
|
||||||
|
|
||||||
@ -621,15 +634,28 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
|
if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
|
||||||
winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
|
goto end;
|
||||||
|
if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
|
||||||
|
goto end;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
end:
|
end:
|
||||||
free(crypt_client_random);
|
free(crypt_client_random);
|
||||||
end2:
|
|
||||||
free(client_random);
|
free(client_random);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||||
|
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||||
|
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||||
|
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||||
|
|
||||||
|
rdp->fips_encrypt = NULL;
|
||||||
|
rdp->fips_decrypt = NULL;
|
||||||
|
rdp->rc4_encrypt_key = NULL;
|
||||||
|
rdp->rc4_decrypt_key = NULL;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,20 +458,22 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
|
|||||||
|
|
||||||
BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
||||||
{
|
{
|
||||||
WINPR_RC4_CTX rc4;
|
BOOL rc;
|
||||||
|
WINPR_RC4_CTX* rc4;
|
||||||
|
|
||||||
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
|
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
|
||||||
if (!license->PlatformChallenge->data)
|
if (!license->PlatformChallenge->data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
|
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
|
||||||
|
|
||||||
winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
if (!winpr_RC4_New(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH))
|
||||||
winpr_RC4_Update(&rc4, license->EncryptedPlatformChallenge->length,
|
return FALSE;
|
||||||
|
rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
|
||||||
license->EncryptedPlatformChallenge->data,
|
license->EncryptedPlatformChallenge->data,
|
||||||
license->PlatformChallenge->data);
|
license->PlatformChallenge->data);
|
||||||
|
|
||||||
winpr_RC4_Final(&rc4);
|
winpr_RC4_Free(rc4);
|
||||||
return TRUE;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1015,7 +1017,7 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
|||||||
wStream* s;
|
wStream* s;
|
||||||
int length;
|
int length;
|
||||||
BYTE* buffer;
|
BYTE* buffer;
|
||||||
WINPR_RC4_CTX rc4;
|
WINPR_RC4_CTX* rc4;
|
||||||
BYTE mac_data[16];
|
BYTE mac_data[16];
|
||||||
BOOL status;
|
BOOL status;
|
||||||
|
|
||||||
@ -1036,14 +1038,20 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
|||||||
if (!status)
|
if (!status)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
if (!winpr_RC4_New(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
buffer = (BYTE*) malloc(HWID_LENGTH);
|
buffer = (BYTE*) malloc(HWID_LENGTH);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
winpr_RC4_Update(&rc4, HWID_LENGTH, license->HardwareId, buffer);
|
status = winpr_RC4_Update(rc4, HWID_LENGTH, license->HardwareId, buffer);
|
||||||
winpr_RC4_Final(&rc4);
|
winpr_RC4_Free(rc4);
|
||||||
|
if (!status)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
license->EncryptedHardwareId->type = BB_DATA_BLOB;
|
license->EncryptedHardwareId->type = BB_DATA_BLOB;
|
||||||
license->EncryptedHardwareId->data = buffer;
|
license->EncryptedHardwareId->data = buffer;
|
||||||
|
@ -1590,13 +1590,13 @@ void rdp_reset(rdpRdp* rdp)
|
|||||||
|
|
||||||
if (rdp->rc4_decrypt_key)
|
if (rdp->rc4_decrypt_key)
|
||||||
{
|
{
|
||||||
winpr_RC4_Final(rdp->rc4_decrypt_key);
|
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||||
rdp->rc4_decrypt_key = NULL;
|
rdp->rc4_decrypt_key = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rdp->rc4_encrypt_key)
|
if (rdp->rc4_encrypt_key)
|
||||||
{
|
{
|
||||||
winpr_RC4_Final(rdp->rc4_encrypt_key);
|
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||||
rdp->rc4_encrypt_key = NULL;
|
rdp->rc4_encrypt_key = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1661,8 +1661,8 @@ void rdp_free(rdpRdp* rdp)
|
|||||||
{
|
{
|
||||||
if (rdp)
|
if (rdp)
|
||||||
{
|
{
|
||||||
winpr_RC4_Final(rdp->rc4_decrypt_key);
|
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||||
winpr_RC4_Final(rdp->rc4_encrypt_key);
|
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||||
free(rdp->fips_hmac);
|
free(rdp->fips_hmac);
|
||||||
|
@ -538,7 +538,8 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
|||||||
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
|
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
|
||||||
WINPR_MD5_CTX md5;
|
WINPR_MD5_CTX md5;
|
||||||
WINPR_SHA1_CTX sha1;
|
WINPR_SHA1_CTX sha1;
|
||||||
WINPR_RC4_CTX rc4;
|
WINPR_RC4_CTX* rc4;
|
||||||
|
BOOL rc;
|
||||||
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
|
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
|
||||||
|
|
||||||
if (!winpr_SHA1_Init(&sha1))
|
if (!winpr_SHA1_Init(&sha1))
|
||||||
@ -563,11 +564,12 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
|||||||
if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH))
|
if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!winpr_RC4_Init(&rc4, key, key_len))
|
if (!winpr_RC4_New(&rc4, key, key_len))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!winpr_RC4_Update(&rc4, key_len, key, key))
|
rc = winpr_RC4_Update(rc4, key_len, key, key);
|
||||||
return FALSE;
|
winpr_RC4_Free(rc4);
|
||||||
if (!winpr_RC4_Final(&rc4))
|
|
||||||
|
if (!rc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
|
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
|
||||||
@ -585,9 +587,8 @@ 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))
|
if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!winpr_RC4_Final(rdp->rc4_encrypt_key))
|
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||||
return FALSE;
|
if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
|
||||||
if (!winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rdp->encrypt_use_count = 0;
|
rdp->encrypt_use_count = 0;
|
||||||
@ -609,9 +610,8 @@ 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))
|
if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!winpr_RC4_Final(rdp->rc4_decrypt_key))
|
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||||
return FALSE;
|
if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
|
||||||
if (!winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rdp->decrypt_use_count = 0;
|
rdp->decrypt_use_count = 0;
|
||||||
|
@ -901,9 +901,9 @@ typedef union _WINPR_RC4_CTX WINPR_RC4_CTX;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WINPR_API BOOL winpr_RC4_Init(WINPR_RC4_CTX* ctx, const BYTE* key, size_t keylen);
|
WINPR_API BOOL winpr_RC4_New(WINPR_RC4_CTX** ctx, const BYTE* key, size_t keylen);
|
||||||
WINPR_API BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output);
|
WINPR_API BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output);
|
||||||
WINPR_API BOOL winpr_RC4_Final(WINPR_RC4_CTX* ctx);
|
WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -43,15 +43,26 @@
|
|||||||
* RC4
|
* RC4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL winpr_RC4_Init(WINPR_RC4_CTX* ctx, const BYTE* key, size_t keylen)
|
BOOL winpr_RC4_New(WINPR_RC4_CTX** octx, const BYTE* key, size_t keylen)
|
||||||
{
|
{
|
||||||
|
WINPR_RC4_CTX* ctx = NULL;
|
||||||
|
|
||||||
|
if (!octx || !key || (keylen == 0))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ctx = calloc(1, sizeof(WINPR_RC4_CTX));
|
||||||
|
if (!ctx)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
#if defined(WITH_OPENSSL)
|
#if defined(WITH_OPENSSL)
|
||||||
RC4_set_key((RC4_KEY*) ctx, keylen, key);
|
RC4_set_key((RC4_KEY*) ctx, keylen, key);
|
||||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||||
mbedtls_arc4_init((mbedtls_arc4_context*) ctx);
|
mbedtls_arc4_init((mbedtls_arc4_context*) ctx);
|
||||||
mbedtls_arc4_setup((mbedtls_arc4_context*) ctx, key, keylen);
|
mbedtls_arc4_setup((mbedtls_arc4_context*) ctx, key, keylen);
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
*octx = ctx;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
|
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
|
||||||
@ -60,20 +71,23 @@ BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE
|
|||||||
RC4((RC4_KEY*) ctx, length, input, output);
|
RC4((RC4_KEY*) ctx, length, input, output);
|
||||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||||
if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0)
|
if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL winpr_RC4_Final(WINPR_RC4_CTX* ctx)
|
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
|
||||||
{
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
#if defined(WITH_OPENSSL)
|
#if defined(WITH_OPENSSL)
|
||||||
|
|
||||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||||
mbedtls_arc4_free((mbedtls_arc4_context*) ctx);
|
mbedtls_arc4_free((mbedtls_arc4_context*) ctx);
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -502,7 +516,7 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher)
|
|||||||
|
|
||||||
BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* key, const BYTE* iv)
|
BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* key, const BYTE* iv)
|
||||||
{
|
{
|
||||||
WINPR_CIPHER_CTX* ctx;
|
WINPR_CIPHER_CTX* ctx;
|
||||||
#if defined(WITH_OPENSSL)
|
#if defined(WITH_OPENSSL)
|
||||||
int operation;
|
int operation;
|
||||||
const EVP_CIPHER* evp;
|
const EVP_CIPHER* evp;
|
||||||
@ -514,10 +528,10 @@ BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* k
|
|||||||
const mbedtls_cipher_info_t* cipher_info;
|
const mbedtls_cipher_info_t* cipher_info;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
|
ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
#if defined(WITH_OPENSSL)
|
#if defined(WITH_OPENSSL)
|
||||||
octx = (EVP_CIPHER_CTX*)ctx;
|
octx = (EVP_CIPHER_CTX*)ctx;
|
||||||
evp = winpr_openssl_get_evp_cipher(cipher);
|
evp = winpr_openssl_get_evp_cipher(cipher);
|
||||||
@ -551,7 +565,7 @@ BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* k
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*cctx = ctx;
|
*cctx = ctx;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,8 +603,8 @@ BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen)
|
|||||||
|
|
||||||
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
|
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
|
||||||
{
|
{
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(WITH_OPENSSL)
|
#if defined(WITH_OPENSSL)
|
||||||
EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
|
EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
|
||||||
|
@ -7,22 +7,26 @@ static const BYTE* TEST_RC4_KEY = (BYTE*) "Key";
|
|||||||
static const char* TEST_RC4_PLAINTEXT = "Plaintext";
|
static const char* TEST_RC4_PLAINTEXT = "Plaintext";
|
||||||
static const BYTE* TEST_RC4_CIPHERTEXT = (BYTE*) "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3";
|
static const BYTE* TEST_RC4_CIPHERTEXT = (BYTE*) "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3";
|
||||||
|
|
||||||
BOOL test_crypto_cipher_rc4()
|
static BOOL test_crypto_cipher_rc4()
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
BYTE* text;
|
BOOL rc = FALSE;
|
||||||
WINPR_RC4_CTX ctx;
|
BYTE* text = NULL;
|
||||||
|
WINPR_RC4_CTX* ctx;
|
||||||
|
|
||||||
len = strlen(TEST_RC4_PLAINTEXT);
|
len = strlen(TEST_RC4_PLAINTEXT);
|
||||||
|
|
||||||
text = (BYTE*) calloc(1, len);
|
text = (BYTE*) calloc(1, len);
|
||||||
|
|
||||||
if (!text)
|
if (!text)
|
||||||
return FALSE;
|
goto out;
|
||||||
|
|
||||||
winpr_RC4_Init(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY));
|
if (!winpr_RC4_New(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY)))
|
||||||
winpr_RC4_Update(&ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
|
goto out;
|
||||||
winpr_RC4_Final(&ctx);
|
rc = winpr_RC4_Update(ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
|
||||||
|
winpr_RC4_Free(ctx);
|
||||||
|
if (!rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0)
|
if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0)
|
||||||
{
|
{
|
||||||
@ -36,11 +40,14 @@ BOOL test_crypto_cipher_rc4()
|
|||||||
|
|
||||||
free(actual);
|
free(actual);
|
||||||
free(expected);
|
free(expected);
|
||||||
|
goto out;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
rc = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(text);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const BYTE* TEST_RAND_DATA = (BYTE*)
|
static const BYTE* TEST_RAND_DATA = (BYTE*)
|
||||||
@ -56,7 +63,7 @@ static const BYTE* TEST_CIPHER_KEY = (BYTE*)
|
|||||||
static const BYTE* TEST_CIPHER_IV = (BYTE*)
|
static const BYTE* TEST_CIPHER_IV = (BYTE*)
|
||||||
"\xFE\xE3\x9F\xF0\xD1\x5E\x37\x0C\xAB\xAB\x9B\x04\xF3\xDB\x99\x15";
|
"\xFE\xE3\x9F\xF0\xD1\x5E\x37\x0C\xAB\xAB\x9B\x04\xF3\xDB\x99\x15";
|
||||||
|
|
||||||
BOOL test_crypto_cipher_key()
|
static BOOL test_crypto_cipher_key()
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
BYTE key[32];
|
BYTE key[32];
|
||||||
|
@ -239,6 +239,8 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
|
|||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
winpr_RC4_Free(context->SendRc4Seal);
|
||||||
|
winpr_RC4_Free(context->RecvRc4Seal);
|
||||||
sspi_SecBufferFree(&context->NegotiateMessage);
|
sspi_SecBufferFree(&context->NegotiateMessage);
|
||||||
sspi_SecBufferFree(&context->ChallengeMessage);
|
sspi_SecBufferFree(&context->ChallengeMessage);
|
||||||
sspi_SecBufferFree(&context->AuthenticateMessage);
|
sspi_SecBufferFree(&context->AuthenticateMessage);
|
||||||
@ -931,7 +933,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
|
|||||||
/* Encrypt message using with RC4, result overwrites original buffer */
|
/* Encrypt message using with RC4, result overwrites original buffer */
|
||||||
|
|
||||||
if (context->confidentiality)
|
if (context->confidentiality)
|
||||||
winpr_RC4_Update(&context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
|
winpr_RC4_Update(context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
|
||||||
else
|
else
|
||||||
CopyMemory(data_buffer->pvBuffer, data, length);
|
CopyMemory(data_buffer->pvBuffer, data, length);
|
||||||
|
|
||||||
@ -943,7 +945,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
|
|||||||
#endif
|
#endif
|
||||||
free(data);
|
free(data);
|
||||||
/* RC4-encrypt first 8 bytes of digest */
|
/* RC4-encrypt first 8 bytes of digest */
|
||||||
winpr_RC4_Update(&context->SendRc4Seal, 8, digest, checksum);
|
winpr_RC4_Update(context->SendRc4Seal, 8, digest, checksum);
|
||||||
signature = (BYTE*) signature_buffer->pvBuffer;
|
signature = (BYTE*) signature_buffer->pvBuffer;
|
||||||
/* Concatenate version, ciphertext and sequence number to build signature */
|
/* Concatenate version, ciphertext and sequence number to build signature */
|
||||||
CopyMemory(signature, (void*) &version, 4);
|
CopyMemory(signature, (void*) &version, 4);
|
||||||
@ -1000,7 +1002,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
|
|||||||
/* Decrypt message using with RC4, result overwrites original buffer */
|
/* Decrypt message using with RC4, result overwrites original buffer */
|
||||||
|
|
||||||
if (context->confidentiality)
|
if (context->confidentiality)
|
||||||
winpr_RC4_Update(&context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
|
winpr_RC4_Update(context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
|
||||||
else
|
else
|
||||||
CopyMemory(data_buffer->pvBuffer, data, length);
|
CopyMemory(data_buffer->pvBuffer, data, length);
|
||||||
|
|
||||||
@ -1017,7 +1019,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
|
|||||||
#endif
|
#endif
|
||||||
free(data);
|
free(data);
|
||||||
/* RC4-encrypt first 8 bytes of digest */
|
/* RC4-encrypt first 8 bytes of digest */
|
||||||
winpr_RC4_Update(&context->RecvRc4Seal, 8, digest, checksum);
|
winpr_RC4_Update(context->RecvRc4Seal, 8, digest, checksum);
|
||||||
/* Concatenate version, ciphertext and sequence number to build signature */
|
/* Concatenate version, ciphertext and sequence number to build signature */
|
||||||
CopyMemory(expected_signature, (void*) &version, 4);
|
CopyMemory(expected_signature, (void*) &version, 4);
|
||||||
CopyMemory(&expected_signature[4], (void*) checksum, 8);
|
CopyMemory(&expected_signature[4], (void*) checksum, 8);
|
||||||
|
@ -225,8 +225,8 @@ struct _NTLM_CONTEXT
|
|||||||
BYTE MachineID[32];
|
BYTE MachineID[32];
|
||||||
BOOL SendVersionInfo;
|
BOOL SendVersionInfo;
|
||||||
BOOL confidentiality;
|
BOOL confidentiality;
|
||||||
WINPR_RC4_CTX SendRc4Seal;
|
WINPR_RC4_CTX* SendRc4Seal;
|
||||||
WINPR_RC4_CTX RecvRc4Seal;
|
WINPR_RC4_CTX* RecvRc4Seal;
|
||||||
BYTE* SendSigningKey;
|
BYTE* SendSigningKey;
|
||||||
BYTE* RecvSigningKey;
|
BYTE* RecvSigningKey;
|
||||||
BYTE* SendSealingKey;
|
BYTE* SendSealingKey;
|
||||||
|
@ -341,8 +341,8 @@ int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context)
|
|||||||
response = (BYTE*) context->LmChallengeResponse.pvBuffer;
|
response = (BYTE*) context->LmChallengeResponse.pvBuffer;
|
||||||
/* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
|
/* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
|
||||||
winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
||||||
(BYTE*) value, WINPR_MD5_DIGEST_LENGTH,
|
(BYTE*) value, WINPR_MD5_DIGEST_LENGTH,
|
||||||
(BYTE*) response, 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) */
|
/* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
|
||||||
CopyMemory(&response[16], context->ClientChallenge, 8);
|
CopyMemory(&response[16], context->ClientChallenge, 8);
|
||||||
return 1;
|
return 1;
|
||||||
@ -412,8 +412,8 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
|||||||
CopyMemory(blob, context->ServerChallenge, 8);
|
CopyMemory(blob, context->ServerChallenge, 8);
|
||||||
CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
|
CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
|
||||||
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
||||||
(BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer,
|
(BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer,
|
||||||
(BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH);
|
(BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH);
|
||||||
|
|
||||||
/* NtChallengeResponse, Concatenate NTProofStr with temp */
|
/* NtChallengeResponse, Concatenate NTProofStr with temp */
|
||||||
|
|
||||||
@ -425,8 +425,8 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
|||||||
CopyMemory(&blob[16], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
|
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 */
|
/* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
|
||||||
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
|
||||||
(BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH,
|
(BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH,
|
||||||
(BYTE*) context->SessionBaseKey, WINPR_MD5_DIGEST_LENGTH);
|
(BYTE*) context->SessionBaseKey, WINPR_MD5_DIGEST_LENGTH);
|
||||||
sspi_SecBufferFree(&ntlm_v2_temp);
|
sspi_SecBufferFree(&ntlm_v2_temp);
|
||||||
sspi_SecBufferFree(&ntlm_v2_temp_chal);
|
sspi_SecBufferFree(&ntlm_v2_temp_chal);
|
||||||
return 1;
|
return 1;
|
||||||
@ -442,10 +442,12 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
|||||||
|
|
||||||
void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
|
void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
|
||||||
{
|
{
|
||||||
WINPR_RC4_CTX rc4;
|
WINPR_RC4_CTX* rc4;
|
||||||
winpr_RC4_Init(&rc4, (void*) key, 16);
|
if (winpr_RC4_New(&rc4, (void*) key, 16))
|
||||||
winpr_RC4_Update(&rc4, length, (void*) plaintext, (void*) ciphertext);
|
{
|
||||||
winpr_RC4_Final(&rc4);
|
winpr_RC4_Update(rc4, length, (void*) plaintext, (void*) ciphertext);
|
||||||
|
winpr_RC4_Free(rc4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -662,8 +664,8 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
|
|||||||
context->RecvSigningKey = context->ClientSigningKey;
|
context->RecvSigningKey = context->ClientSigningKey;
|
||||||
context->SendSealingKey = context->ClientSealingKey;
|
context->SendSealingKey = context->ClientSealingKey;
|
||||||
context->RecvSealingKey = context->ServerSealingKey;
|
context->RecvSealingKey = context->ServerSealingKey;
|
||||||
winpr_RC4_Init(&context->SendRc4Seal, context->ServerSealingKey, 16);
|
winpr_RC4_New(&context->SendRc4Seal, context->ServerSealingKey, 16);
|
||||||
winpr_RC4_Init(&context->RecvRc4Seal, context->ClientSealingKey, 16);
|
winpr_RC4_New(&context->RecvRc4Seal, context->ClientSealingKey, 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -671,8 +673,8 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
|
|||||||
context->RecvSigningKey = context->ServerSigningKey;
|
context->RecvSigningKey = context->ServerSigningKey;
|
||||||
context->SendSealingKey = context->ServerSealingKey;
|
context->SendSealingKey = context->ServerSealingKey;
|
||||||
context->RecvSealingKey = context->ClientSealingKey;
|
context->RecvSealingKey = context->ClientSealingKey;
|
||||||
winpr_RC4_Init(&context->SendRc4Seal, context->ClientSealingKey, 16);
|
winpr_RC4_New(&context->SendRc4Seal, context->ClientSealingKey, 16);
|
||||||
winpr_RC4_Init(&context->RecvRc4Seal, context->ServerSealingKey, 16);
|
winpr_RC4_New(&context->RecvRc4Seal, context->ServerSealingKey, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user