goto end;
}
- winpr_RC4_Init(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);
+ if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_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;
end:
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;
}
if (rand_len != key_len + 8)
{
WLog_ERR(TAG, "invalid encrypted client random length");
- goto end2;
+ goto end;
}
crypt_client_random = calloc(1, rand_len);
if (!crypt_client_random)
- goto end2;
+ goto end;
Stream_Read(s, crypt_client_random, rand_len);
mod = rdp->settings->RdpServerRsaKey->Modulus;
/* now calculate encrypt / decrypt and update keys */
if (!security_establish_keys(client_random, rdp))
- {
goto end;
- }
rdp->do_crypt = TRUE;
goto end;
}
- winpr_RC4_Init(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);
+ if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_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;
end:
free(crypt_client_random);
-end2:
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;
}
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);
if (!license->PlatformChallenge->data)
return FALSE;
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
- winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
- winpr_RC4_Update(&rc4, license->EncryptedPlatformChallenge->length,
+ if (!winpr_RC4_New(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH))
+ return FALSE;
+ rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
- winpr_RC4_Final(&rc4);
- return TRUE;
+ winpr_RC4_Free(rc4);
+ return rc;
}
/**
wStream* s;
int length;
BYTE* buffer;
- WINPR_RC4_CTX rc4;
+ WINPR_RC4_CTX* rc4;
BYTE mac_data[16];
BOOL status;
if (!status)
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);
if (!buffer)
return FALSE;
- winpr_RC4_Update(&rc4, HWID_LENGTH, license->HardwareId, buffer);
- winpr_RC4_Final(&rc4);
+ status = winpr_RC4_Update(rc4, HWID_LENGTH, license->HardwareId, buffer);
+ winpr_RC4_Free(rc4);
+ if (!status)
+ {
+ free(buffer);
+ return FALSE;
+ }
license->EncryptedHardwareId->type = BB_DATA_BLOB;
license->EncryptedHardwareId->data = buffer;
if (rdp->rc4_decrypt_key)
{
- winpr_RC4_Final(rdp->rc4_decrypt_key);
+ winpr_RC4_Free(rdp->rc4_decrypt_key);
rdp->rc4_decrypt_key = NULL;
}
if (rdp->rc4_encrypt_key)
{
- winpr_RC4_Final(rdp->rc4_encrypt_key);
+ winpr_RC4_Free(rdp->rc4_encrypt_key);
rdp->rc4_encrypt_key = NULL;
}
{
if (rdp)
{
- winpr_RC4_Final(rdp->rc4_decrypt_key);
- winpr_RC4_Final(rdp->rc4_encrypt_key);
+ winpr_RC4_Free(rdp->rc4_decrypt_key);
+ winpr_RC4_Free(rdp->rc4_encrypt_key);
winpr_Cipher_Free(rdp->fips_encrypt);
winpr_Cipher_Free(rdp->fips_decrypt);
free(rdp->fips_hmac);
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
WINPR_MD5_CTX md5;
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 */
if (!winpr_SHA1_Init(&sha1))
if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH))
return FALSE;
- if (!winpr_RC4_Init(&rc4, key, key_len))
+ if (!winpr_RC4_New(&rc4, key, key_len))
return FALSE;
- if (!winpr_RC4_Update(&rc4, key_len, key, key))
- return FALSE;
- if (!winpr_RC4_Final(&rc4))
+ rc = winpr_RC4_Update(rc4, key_len, key, key);
+ winpr_RC4_Free(rc4);
+
+ if (!rc)
return FALSE;
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
return FALSE;
- 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))
+ winpr_RC4_Free(rdp->rc4_encrypt_key);
+ if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
return FALSE;
rdp->encrypt_use_count = 0;
{
if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
return FALSE;
- 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))
+ winpr_RC4_Free(rdp->rc4_decrypt_key);
+ if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
return FALSE;
rdp->decrypt_use_count = 0;
extern "C" {
#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_Final(WINPR_RC4_CTX* ctx);
+WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx);
#ifdef __cplusplus
}
* 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)
RC4_set_key((RC4_KEY*) ctx, keylen, key);
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
mbedtls_arc4_init((mbedtls_arc4_context*) ctx);
mbedtls_arc4_setup((mbedtls_arc4_context*) ctx, key, keylen);
#endif
- return TRUE;
+ *octx = ctx;
+
+ return TRUE;
}
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
RC4((RC4_KEY*) ctx, length, input, output);
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0)
- return FALSE;
+ return FALSE;
#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)
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
mbedtls_arc4_free((mbedtls_arc4_context*) ctx);
#endif
- return TRUE;
+ free(ctx);
}
/**
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)
int operation;
const EVP_CIPHER* evp;
const mbedtls_cipher_info_t* cipher_info;
#endif
- ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
- if (!ctx)
- return FALSE;
-
+ ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
+ if (!ctx)
+ return FALSE;
+
#if defined(WITH_OPENSSL)
octx = (EVP_CIPHER_CTX*)ctx;
evp = winpr_openssl_get_evp_cipher(cipher);
return FALSE;
#endif
- *cctx = ctx;
+ *cctx = ctx;
return TRUE;
}
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
{
- if (!ctx)
- return;
+ if (!ctx)
+ return;
#if defined(WITH_OPENSSL)
EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
static const char* TEST_RC4_PLAINTEXT = "Plaintext";
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;
- BYTE* text;
- WINPR_RC4_CTX ctx;
+ BOOL rc = FALSE;
+ BYTE* text = NULL;
+ WINPR_RC4_CTX* ctx;
len = strlen(TEST_RC4_PLAINTEXT);
text = (BYTE*) calloc(1, len);
if (!text)
- return FALSE;
+ goto out;
- winpr_RC4_Init(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY));
- winpr_RC4_Update(&ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
- winpr_RC4_Final(&ctx);
+ if (!winpr_RC4_New(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY)))
+ goto out;
+ 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)
{
free(actual);
free(expected);
-
- return FALSE;
+ goto out;
}
- return TRUE;
+ rc = TRUE;
+
+out:
+ free(text);
+ return rc;
}
static const BYTE* TEST_RAND_DATA = (BYTE*)
static const BYTE* TEST_CIPHER_IV = (BYTE*)
"\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;
BYTE key[32];
if (!context)
return;
+ winpr_RC4_Free(context->SendRc4Seal);
+ winpr_RC4_Free(context->RecvRc4Seal);
sspi_SecBufferFree(&context->NegotiateMessage);
sspi_SecBufferFree(&context->ChallengeMessage);
sspi_SecBufferFree(&context->AuthenticateMessage);
/* Encrypt message using with RC4, result overwrites original buffer */
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
CopyMemory(data_buffer->pvBuffer, data, length);
#endif
free(data);
/* 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;
/* Concatenate version, ciphertext and sequence number to build signature */
CopyMemory(signature, (void*) &version, 4);
/* Decrypt message using with RC4, result overwrites original buffer */
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
CopyMemory(data_buffer->pvBuffer, data, length);
#endif
free(data);
/* 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 */
CopyMemory(expected_signature, (void*) &version, 4);
CopyMemory(&expected_signature[4], (void*) checksum, 8);
BYTE MachineID[32];
BOOL SendVersionInfo;
BOOL confidentiality;
- WINPR_RC4_CTX SendRc4Seal;
- WINPR_RC4_CTX RecvRc4Seal;
+ WINPR_RC4_CTX* SendRc4Seal;
+ WINPR_RC4_CTX* RecvRc4Seal;
BYTE* SendSigningKey;
BYTE* RecvSigningKey;
BYTE* SendSealingKey;
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, WINPR_MD5_DIGEST_LENGTH,
- (BYTE*) value, WINPR_MD5_DIGEST_LENGTH,
- (BYTE*) response, 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;
CopyMemory(blob, context->ServerChallenge, 8);
CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
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);
+ (BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer,
+ (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH);
/* NtChallengeResponse, Concatenate NTProofStr with temp */
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, WINPR_MD5_DIGEST_LENGTH,
- (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH,
- (BYTE*) context->SessionBaseKey, 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;
void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
{
- WINPR_RC4_CTX rc4;
- winpr_RC4_Init(&rc4, (void*) key, 16);
- winpr_RC4_Update(&rc4, length, (void*) plaintext, (void*) ciphertext);
- winpr_RC4_Final(&rc4);
+ WINPR_RC4_CTX* rc4;
+ if (winpr_RC4_New(&rc4, (void*) key, 16))
+ {
+ winpr_RC4_Update(rc4, length, (void*) plaintext, (void*) ciphertext);
+ winpr_RC4_Free(rc4);
+ }
}
/**
context->RecvSigningKey = context->ClientSigningKey;
context->SendSealingKey = context->ClientSealingKey;
context->RecvSealingKey = context->ServerSealingKey;
- winpr_RC4_Init(&context->SendRc4Seal, context->ServerSealingKey, 16);
- winpr_RC4_Init(&context->RecvRc4Seal, context->ClientSealingKey, 16);
+ winpr_RC4_New(&context->SendRc4Seal, context->ServerSealingKey, 16);
+ winpr_RC4_New(&context->RecvRc4Seal, context->ClientSealingKey, 16);
}
else
{
context->RecvSigningKey = context->ServerSigningKey;
context->SendSealingKey = context->ServerSealingKey;
context->RecvSealingKey = context->ClientSealingKey;
- winpr_RC4_Init(&context->SendRc4Seal, context->ClientSealingKey, 16);
- winpr_RC4_Init(&context->RecvRc4Seal, context->ServerSealingKey, 16);
+ winpr_RC4_New(&context->SendRc4Seal, context->ClientSealingKey, 16);
+ winpr_RC4_New(&context->RecvRc4Seal, context->ServerSealingKey, 16);
}
}