/* Process a Server Platform Challenge packet */ static void licence_process_platform_challenge(rdpLicence * licence, STREAM s) { uint8 *in_token = NULL, *in_sig; uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE]; uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE]; uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE]; uint8 out_sig[LICENCE_SIGNATURE_SIZE]; CryptoRc4 crypt_key; /* Parse incoming packet and save the encrypted token */ licence_parse_authreq(licence, s, &in_token, &in_sig); memcpy(out_token, in_token, LICENCE_TOKEN_SIZE); /* Decrypt the token. It should read TEST in Unicode. */ crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token); crypto_rc4_free(crypt_key); /* Generate a signature for a buffer of token and HWID */ licence_generate_hwid(licence, hwid); memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE); memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE); sec_sign(out_sig, 16, licence->licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer)); /* Now encrypt the HWID */ crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid); crypto_rc4_free(crypt_key); licence_send_authresp(licence, out_token, crypt_hwid, out_sig); }
void license_decrypt_platform_challenge(rdpLicense* license) { CryptoRc4 rc4; license->platform_challenge->data = (uint8*) xmalloc(license->encrypted_platform_challenge->length); license->platform_challenge->length = license->encrypted_platform_challenge->length; rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); crypto_rc4(rc4, license->encrypted_platform_challenge->length, license->encrypted_platform_challenge->data, license->platform_challenge->data); #ifdef WITH_DEBUG_LICENSE printf("encrypted_platform challenge:\n"); freerdp_hexdump(license->encrypted_platform_challenge->data, license->encrypted_platform_challenge->length); printf("platform challenge:\n"); freerdp_hexdump(license->platform_challenge->data, license->platform_challenge->length); #endif crypto_rc4_free(rc4); }
BOOL license_decrypt_platform_challenge(rdpLicense* license) { CryptoRc4 rc4; license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length); if (!license->PlatformChallenge->data) return FALSE; license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length; rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { WLog_ERR(TAG, "unable to allocate a rc4"); free(license->PlatformChallenge->data); license->PlatformChallenge->data = NULL; return FALSE; } crypto_rc4(rc4, license->EncryptedPlatformChallenge->length, license->EncryptedPlatformChallenge->data, license->PlatformChallenge->data); crypto_rc4_free(rc4); return TRUE; }
rdpBlob* crypto_kdcmsg_decrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype) { rdpBlob* decmsg; uint8* K1; uint8* K3; uint32 len; krbEdata* edata; CryptoRc4 rc4; K1 = xzalloc(16); K3 = xzalloc(16); len = msg->length; edata = xzalloc(len); HMAC(EVP_md5(), (void*) key, 16, (uint8*) &msgtype, 4, (void*) K1, NULL); HMAC(EVP_md5(), (void*) K1, 16, (uint8*) msg->data , 16, (void*) K3, NULL); rc4 = crypto_rc4_init(K3, 16); crypto_rc4(rc4, len - 16, (uint8*)(((uint8*) msg->data) + 16), (uint8*) edata->Confounder); crypto_rc4_free(rc4); HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL); if(memcmp(msg->data, &edata->Checksum, 16)) { xfree(edata) ; xfree(K1) ; xfree(K3) ; return NULL; } decmsg = xnew(rdpBlob); freerdp_blob_alloc(decmsg, len); memcpy(decmsg->data, edata, len); xfree(K1); xfree(K3); xfree(edata); return decmsg; }
rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype) { rdpBlob* encmsg; uint8* K1; uint8* K3; uint32 len; krbEdata* edata; CryptoRc4 rc4; K1 = xzalloc(16); K3 = xzalloc(16); len = ((msg->length > 16) ? msg->length : 16); len += sizeof(krbEdata); edata = xzalloc(len); encmsg = xnew(rdpBlob); freerdp_blob_alloc(encmsg, len); HMAC(EVP_md5(), (void*) key, 16, (uint8*)&msgtype, 4, (void*) K1, NULL); crypto_nonce((uint8*)(edata->Confounder), 8); memcpy(&(edata->data[0]), msg->data, msg->length); HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL); HMAC(EVP_md5(), (void*) K1, 16, (uint8*)&(edata->Checksum), 16, (void*)K3, NULL); memcpy(encmsg->data, &(edata->Checksum), 16); rc4 = crypto_rc4_init(K3, 16); crypto_rc4(rc4, len - 16, (uint8*) edata->Confounder, (uint8*)(((uint8*) encmsg->data) + 16)); crypto_rc4_free(rc4); xfree(K1); xfree(K3); xfree(edata); return encmsg; }
BOOL license_send_platform_challenge_response_packet(rdpLicense* license) { wStream* s; int length; BYTE* buffer; CryptoRc4 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 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { WLog_ERR(TAG, "unable to allocate a rc4"); return FALSE; } buffer = (BYTE*) malloc(HWID_LENGTH); if (!buffer) return FALSE; crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer); crypto_rc4_free(rc4); 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); }
void license_send_platform_challenge_response_packet(rdpLicense* license) { wStream* s; int length; BYTE* buffer; CryptoRc4 rc4; BYTE mac_data[16]; 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); CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length); CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH); security_mac_data(license->MacSaltKey, buffer, length, mac_data); free(buffer); buffer = (BYTE*) malloc(HWID_LENGTH); rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__); return; } crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer); crypto_rc4_free(rc4); license->EncryptedHardwareId->type = BB_DATA_BLOB; license->EncryptedHardwareId->data = buffer; license->EncryptedHardwareId->length = HWID_LENGTH; #ifdef WITH_DEBUG_LICENSE fprintf(stderr, "LicensingEncryptionKey:\n"); winpr_HexDump(license->LicensingEncryptionKey, 16); fprintf(stderr, "\n"); fprintf(stderr, "HardwareId:\n"); winpr_HexDump(license->HardwareId, HWID_LENGTH); fprintf(stderr, "\n"); fprintf(stderr, "EncryptedHardwareId:\n"); winpr_HexDump(license->EncryptedHardwareId->data, HWID_LENGTH); fprintf(stderr, "\n"); #endif license_write_platform_challenge_response_packet(license, s, mac_data); license_send(license, s, PLATFORM_CHALLENGE_RESPONSE); }
void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext) { CryptoRc4 rc4; /* Initialize RC4 cipher with key */ rc4 = crypto_rc4_init((void*) key, 16); /* Encrypt plaintext with key */ crypto_rc4(rc4, length, (void*) plaintext, (void*) ciphertext); /* Free RC4 Cipher */ crypto_rc4_free(rc4); }
void license_decrypt_platform_challenge(rdpLicense* license) { CryptoRc4 rc4; license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length); license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length; rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); crypto_rc4(rc4, license->EncryptedPlatformChallenge->length, license->EncryptedPlatformChallenge->data, license->PlatformChallenge->data); crypto_rc4_free(rc4); }
void license_send_platform_challenge_response_packet(rdpLicense* license) { STREAM* s; int length; uint8* buffer; CryptoRc4 rc4; uint8 mac_data[16]; s = license_send_stream_init(license); DEBUG_LICENSE("Sending Platform Challenge Response Packet"); license->encrypted_platform_challenge->type = BB_DATA_BLOB; length = license->platform_challenge->length + HWID_LENGTH; buffer = (uint8*) xmalloc(length); memcpy(buffer, license->platform_challenge->data, license->platform_challenge->length); memcpy(&buffer[license->platform_challenge->length], license->hwid, HWID_LENGTH); security_mac_data(license->mac_salt_key, buffer, length, mac_data); xfree(buffer); buffer = (uint8*) xmalloc(HWID_LENGTH); rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer); crypto_rc4_free(rc4); #ifdef WITH_DEBUG_LICENSE printf("Licensing Encryption Key:\n"); freerdp_hexdump(license->licensing_encryption_key, 16); printf("HardwareID:\n"); freerdp_hexdump(license->hwid, 20); printf("Encrypted HardwareID:\n"); freerdp_hexdump(buffer, 20); #endif license->encrypted_hwid->type = BB_DATA_BLOB; license->encrypted_hwid->data = buffer; license->encrypted_hwid->length = HWID_LENGTH; license_write_platform_challenge_response_packet(license, s, mac_data); license_send(license, s, PLATFORM_CHALLENGE_RESPONSE); }
void license_decrypt_platform_challenge(rdpLicense* license) { CryptoRc4 rc4; license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length); license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length; rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__); return; } crypto_rc4(rc4, license->EncryptedPlatformChallenge->length, license->EncryptedPlatformChallenge->data, license->PlatformChallenge->data); crypto_rc4_free(rc4); }
/* Process a Server New (or Upgrade) License packet */ static void licence_process_new_license(rdpLicence * licence, STREAM s) { int i; uint32 length; uint32 os_major; uint32 os_minor; CryptoRc4 crypt_key; /* Licensing Binary BLOB with EncryptedLicenseInfo: */ in_uint8s(s, 2); /* wBlobType should be 0x0009 (BB_ENCRYPTED_DATA_BLOB) */ in_uint16_le(s, length); /* wBlobLen */ /* RC4-encrypted New License Information */ if (!s_check_rem(s, length)) return; crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, length, s->p, s->p); /* decrypt in place */ crypto_rc4_free(crypt_key); /* dwVersion */ in_uint16_le(s, os_major); /* OS major version */ in_uint16_le(s, os_minor); /* OS minor version */ /* Skip Scope, CompanyName and ProductId */ for (i = 0; i < 3; i++) { in_uint32_le(s, length); if (!s_check_rem(s, length)) return; in_uint8s(s, length); } /* LicenseInfo - CAL from license server */ in_uint32_le(s, length); if (!s_check_rem(s, length)) return; licence->licence_issued = True; save_licence(s->p, length); }
SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, uint32 MessageSeqNo, uint32* pfQOP) { int index; int length; void* data; HMAC_CTX hmac; uint8 digest[16]; uint8 checksum[8]; uint32 version = 1; NTLM_CONTEXT* context; uint8 expected_signature[16]; PSecBuffer data_buffer = NULL; PSecBuffer signature_buffer = NULL; context = sspi_SecureHandleGetLowerPointer(phContext); for (index = 0; index < (int) pMessage->cBuffers; index++) { if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA) data_buffer = &pMessage->pBuffers[index]; else if (pMessage->pBuffers[index].BufferType == SECBUFFER_TOKEN) signature_buffer = &pMessage->pBuffers[index]; } if (!data_buffer) return SEC_E_INVALID_TOKEN; if (!signature_buffer) return SEC_E_INVALID_TOKEN; /* Copy original data buffer */ length = data_buffer->cbBuffer; data = xmalloc(length); memcpy(data, data_buffer->pvBuffer, length); /* Decrypt message using with RC4 */ crypto_rc4(context->RecvRc4Seal, length, data, data_buffer->pvBuffer); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac, context->RecvSigningKey, 16, EVP_md5(), NULL); HMAC_Update(&hmac, (void*) &(MessageSeqNo), 4); HMAC_Update(&hmac, data_buffer->pvBuffer, data_buffer->cbBuffer); HMAC_Final(&hmac, digest, NULL); HMAC_CTX_cleanup(&hmac); xfree(data); /* RC4-encrypt first 8 bytes of digest */ crypto_rc4(context->RecvRc4Seal, 8, digest, checksum); /* Concatenate version, ciphertext and sequence number to build signature */ memcpy(expected_signature, (void*) &version, 4); memcpy(&expected_signature[4], (void*) checksum, 8); memcpy(&expected_signature[12], (void*) &(MessageSeqNo), 4); context->RecvSeqNum++; if (memcmp(signature_buffer->pvBuffer, expected_signature, 16) != 0) { /* signature verification failed! */ printf("signature verification failed, something nasty is going on!\n"); return SEC_E_MESSAGE_ALTERED; } return SEC_E_OK; }
SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, uint32 fQOP, PSecBufferDesc pMessage, uint32 MessageSeqNo) { int index; int length; void* data; HMAC_CTX hmac; uint8 digest[16]; uint8 checksum[8]; uint8* signature; uint32 version = 1; NTLM_CONTEXT* context; PSecBuffer data_buffer = NULL; PSecBuffer signature_buffer = NULL; context = sspi_SecureHandleGetLowerPointer(phContext); for (index = 0; index < (int) pMessage->cBuffers; index++) { if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA) data_buffer = &pMessage->pBuffers[index]; else if (pMessage->pBuffers[index].BufferType == SECBUFFER_TOKEN) signature_buffer = &pMessage->pBuffers[index]; } if (!data_buffer) return SEC_E_INVALID_TOKEN; if (!signature_buffer) return SEC_E_INVALID_TOKEN; /* Copy original data buffer */ length = data_buffer->cbBuffer; data = xmalloc(length); memcpy(data, data_buffer->pvBuffer, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac, context->SendSigningKey, 16, EVP_md5(), NULL); HMAC_Update(&hmac, (void*) &(MessageSeqNo), 4); HMAC_Update(&hmac, data, length); HMAC_Final(&hmac, digest, NULL); HMAC_CTX_cleanup(&hmac); /* Encrypt message using with RC4, result overwrites original buffer */ if (context->confidentiality) crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer); else memcpy(data_buffer->pvBuffer, data, length); xfree(data); #ifdef WITH_DEBUG_NTLM printf("Data Buffer (length = %d)\n", length); freerdp_hexdump(data, length); printf("\n"); printf("Encrypted Data Buffer (length = %d)\n", data_buffer->cbBuffer); freerdp_hexdump(data_buffer->pvBuffer, data_buffer->cbBuffer); printf("\n"); #endif /* RC4-encrypt first 8 bytes of digest */ crypto_rc4(context->SendRc4Seal, 8, digest, checksum); signature = (uint8*) signature_buffer->pvBuffer; /* Concatenate version, ciphertext and sequence number to build signature */ memcpy(signature, (void*) &version, 4); memcpy(&signature[4], (void*) checksum, 8); memcpy(&signature[12], (void*) &(MessageSeqNo), 4); context->SendSeqNum++; #ifdef WITH_DEBUG_NTLM printf("Signature (length = %d)\n", signature_buffer->cbBuffer); freerdp_hexdump(signature_buffer->pvBuffer, signature_buffer->cbBuffer); printf("\n"); #endif return SEC_E_OK; }
/* Process a Server License Request packet */ static void licence_process_request(rdpLicence * licence, STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint32 dwVersion; uint32 cbCompanyName; uint32 cbProductId; uint16 wBlobType, wBlobLen; uint32 ScopeCount, i; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; CryptoRc4 crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* ServerRandom */ /* ProductInfo: */ in_uint32_le(s, dwVersion); in_uint32_le(s, cbCompanyName); in_uint8s(s, cbCompanyName); /* pbCompanyName */ in_uint32_le(s, cbProductId); in_uint8s(s, cbProductId); /* pbProductId - "A02"? */ /* KeyExchangeList */ in_uint16_le(s, wBlobType); /* BB_KEY_EXCHG_ALG_BLOB (0x000D) */ in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); /* KEY_EXCHANGE_ALG_RSA 0x00000001 */ /* ServerCertificate */ in_uint16_le(s, wBlobType); /* BB_CERTIFICATE_BLOB (0x0003). */ in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); /* cert to use for licensing instead of the one from MCS Connect Response */ /* ScopeList */ in_uint32_le(s, ScopeCount); for (i=0; i<ScopeCount; i++) { in_uint16_le(s, wBlobType); in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); } /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(licence, null_data, server_random, null_data); licence_size = load_licence(&licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(licence, hwid); sec_sign(signature, 16, licence->licence_sign_key, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, sizeof(hwid), hwid, hwid); crypto_rc4_free(crypt_key); licence_present(licence, null_data, null_data, licence_data, licence_size, hwid, signature); xfree(licence_data); return; } licence_send_request(licence, null_data, null_data, licence->sec->rdp->settings->username, licence->sec->rdp->settings->hostname); }