Esempio n. 1
0
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);
}
Esempio n. 2
0
void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
{
    if (context->server)
    {
        context->SendSigningKey = context->ServerSigningKey;
        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);
    }
    else
    {
        context->SendSigningKey = context->ClientSigningKey;
        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);
    }
}
Esempio n. 3
0
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 end2;
	}

	crypt_client_random = calloc(1, rand_len);
	if (!crypt_client_random)
		goto end2;
	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 = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
		if (!rdp->fips_encrypt)
		{
			WLog_ERR(TAG, "unable to allocate des3 encrypt key");
			goto end;
		}

		rdp->fips_decrypt = crypto_des3_decrypt_init(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;
	}

	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);

	ret = TRUE;
end:
	free(crypt_client_random);
end2:
	free(client_random);

	return ret;
}
Esempio n. 4
0
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;

	crypto_nonce(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 = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
		if (!rdp->fips_encrypt)
		{
			WLog_ERR(TAG, "unable to allocate des3 encrypt key");
			goto end;
		}
		rdp->fips_decrypt = crypto_des3_decrypt_init(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;
	}

	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);

	ret = TRUE;
end:
	free(crypt_client_random);
	return ret;
}