void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext) { WINPR_RC4_CTX* rc4 = winpr_RC4_New(key, 16); if (rc4) { winpr_RC4_Update(rc4, length, plaintext, ciphertext); winpr_RC4_Free(rc4); } }
void ntlm_ContextFree(NTLM_CONTEXT* context) { 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); sspi_SecBufferFree(&context->ChallengeTargetInfo); sspi_SecBufferFree(&context->TargetName); sspi_SecBufferFree(&context->NtChallengeResponse); sspi_SecBufferFree(&context->LmChallengeResponse); free(context->ServicePrincipalName.Buffer); free(context->Workstation.Buffer); free(context); }
BOOL license_send_platform_challenge_response_packet(rdpLicense* license) { wStream* s; int length; BYTE* buffer; WINPR_RC4_CTX* rc4; BYTE mac_data[16]; BOOL status; DEBUG_LICENSE("Sending Platform Challenge Response Packet"); s = license_send_stream_init(license); license->EncryptedPlatformChallenge->type = BB_DATA_BLOB; length = license->PlatformChallenge->length + HWID_LENGTH; buffer = (BYTE*) malloc(length); if (!buffer) return FALSE; CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length); CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH); status = security_mac_data(license->MacSaltKey, buffer, length, mac_data); free(buffer); if (!status) return FALSE; rc4 = winpr_RC4_New(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) return FALSE; buffer = (BYTE*) malloc(HWID_LENGTH); if (!buffer) return FALSE; 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; license->EncryptedHardwareId->length = HWID_LENGTH; #ifdef WITH_DEBUG_LICENSE WLog_DBG(TAG, "LicensingEncryptionKey:"); winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, 16); WLog_DBG(TAG, "HardwareId:"); winpr_HexDump(TAG, WLOG_DEBUG, license->HardwareId, HWID_LENGTH); WLog_DBG(TAG, "EncryptedHardwareId:"); winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH); #endif return license_write_platform_challenge_response_packet(license, s, mac_data) && license_send(license, s, PLATFORM_CHALLENGE_RESPONSE); }
BOOL license_decrypt_platform_challenge(rdpLicense* license) { 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; if ((rc4 = winpr_RC4_New(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL) return FALSE; rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length, license->EncryptedPlatformChallenge->data, license->PlatformChallenge->data); winpr_RC4_Free(rc4); return rc; }
BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) { BYTE* client_random = NULL; BYTE* crypt_client_random = NULL; UINT32 rand_len, key_len; UINT16 channel_id, length, sec_flags; BYTE* mod; BYTE* priv_exp; BOOL ret = FALSE; if (!rdp->settings->UseRdpSecurityLayer) { /* No RDP Security. */ return TRUE; } if (!rdp_read_header(rdp, s, &length, &channel_id)) { WLog_ERR(TAG, "invalid RDP header"); return FALSE; } if (!rdp_read_security_header(s, &sec_flags)) { WLog_ERR(TAG, "invalid security header"); return FALSE; } if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { WLog_ERR(TAG, "missing SEC_EXCHANGE_PKT in security header"); return FALSE; } rdp->do_crypt_license = (sec_flags & SEC_LICENSE_ENCRYPT_SC) != 0 ? TRUE : FALSE; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, rand_len); /* rand_len already includes 8 bytes of padding */ if (Stream_GetRemainingLength(s) < rand_len) return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; client_random = malloc(key_len); if (!client_random) return FALSE; if (rand_len != key_len + 8) { WLog_ERR(TAG, "invalid encrypted client random length"); goto end; } crypt_client_random = calloc(1, rand_len); if (!crypt_client_random) goto end; Stream_Read(s, crypt_client_random, rand_len); mod = rdp->settings->RdpServerRsaKey->Modulus; priv_exp = rdp->settings->RdpServerRsaKey->PrivateExponent; crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) goto end; rdp->do_crypt = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { 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); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key || rdp->rc4_encrypt_key) goto end; ret = TRUE; end: free(crypt_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; }
static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; BYTE* exp; wStream* s; UINT32 length; UINT32 key_len; int status = 0; BOOL ret = FALSE; rdpSettings* settings; BYTE* crypt_client_random = NULL; settings = rdp->settings; if (!settings->UseRdpSecurityLayer) { /* no RDP encryption */ return TRUE; } /* encrypt client random */ free(settings->ClientRandom); settings->ClientRandomLength = CLIENT_RANDOM_LENGTH; settings->ClientRandom = malloc(settings->ClientRandomLength); if (!settings->ClientRandom) return FALSE; winpr_RAND(settings->ClientRandom, settings->ClientRandomLength); key_len = settings->RdpServerCertificate->cert_info.ModulusLength; mod = settings->RdpServerCertificate->cert_info.Modulus; exp = settings->RdpServerCertificate->cert_info.exponent; /* * client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1 * for details */ crypt_client_random = calloc(1, key_len + 8); if (!crypt_client_random) return FALSE; crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; s = Stream_New(NULL, length); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); goto end; } rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT | SEC_LICENSE_ENCRYPT_SC); length = key_len + 8; Stream_Write_UINT32(s, length); Stream_Write(s, crypt_client_random, length); Stream_SealLength(s); status = transport_write(rdp->mcs->transport, s); Stream_Free(s, TRUE); if (status < 0) goto end; rdp->do_crypt_license = TRUE; /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(settings->ClientRandom, rdp)) goto end; rdp->do_crypt = TRUE; if (settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; 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); 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); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX)); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key || !rdp->rc4_encrypt_key) 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; }