void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context, BYTE* mic, UINT32 size) { /* * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE, * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey */ WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); assert(size >= WINPR_MD5_DIGEST_LENGTH); if (!hmac) return; if (winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH)) { winpr_HMAC_Update(hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); winpr_HMAC_Update(hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); winpr_HMAC_Update(hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); winpr_HMAC_Final(hmac, mic, WINPR_MD5_DIGEST_LENGTH); } winpr_HMAC_Free(hmac); }
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context) { WINPR_HMAC_CTX hmac; /* * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE, * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey */ winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH); winpr_HMAC_Update(&hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); winpr_HMAC_Update(&hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); winpr_HMAC_Update(&hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); winpr_HMAC_Final(&hmac, context->MessageIntegrityCheck, WINPR_MD5_DIGEST_LENGTH); }
static BOOL test_crypto_hash_hmac_sha1(void) { BYTE hash[WINPR_SHA1_DIGEST_LENGTH]; WINPR_HMAC_CTX ctx; if (!winpr_HMAC_Init(&ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH)) return FALSE; if (!winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA))) return FALSE; if (!winpr_HMAC_Final(&ctx, hash, sizeof(hash))) return FALSE; if (memcmp(hash, TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0) { char* actual; char* expected; actual = winpr_BinToHexString(hash, WINPR_SHA1_DIGEST_LENGTH, FALSE); expected = winpr_BinToHexString(TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH, FALSE); fprintf(stderr, "unexpected HMAC-SHA1 hash: Actual: %s Expected: %s\n", actual, expected); free(actual); free(expected); return FALSE; } return TRUE; }
int winpr_HMAC(int md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output) { WINPR_HMAC_CTX ctx; if (winpr_HMAC_Init(&ctx, md, key, keylen) != 0) return -1; if (winpr_HMAC_Update(&ctx, input, ilen) != 0) return -1; if (winpr_HMAC_Final(&ctx, output) != 0) return -1; return 0; }
BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output, size_t olen) { BOOL result = FALSE; WINPR_HMAC_CTX *ctx = winpr_HMAC_New(); if (!ctx) return FALSE; if (!winpr_HMAC_Init(ctx, md, key, keylen)) goto out; if (!winpr_HMAC_Update(ctx, input, ilen)) goto out; if (!winpr_HMAC_Final(ctx, output, olen)) goto out; result = TRUE; out: winpr_HMAC_Free(ctx); return result; }
BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { WINPR_HMAC_CTX hmac; BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; ARC_CS_PRIVATE_PACKET* clientCookie; rdpSettings* settings = rdp->settings; serverCookie = settings->ServerAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie; clientCookie->cbLen = 28; clientCookie->version = serverCookie->version; clientCookie->logonId = serverCookie->logonId; ZeroMemory(clientCookie->securityVerifier, 16); ZeroMemory(AutoReconnectRandom, sizeof(AutoReconnectRandom)); CopyMemory(AutoReconnectRandom, serverCookie->arcRandomBits, 16); ZeroMemory(ClientRandom, sizeof(ClientRandom)); if (settings->SelectedProtocol == PROTOCOL_RDP) CopyMemory(ClientRandom, settings->ClientRandom, settings->ClientRandomLength); /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ if (!winpr_HMAC_Init(&hmac, WINPR_MD_MD5, AutoReconnectRandom, 16)) return FALSE; if (!winpr_HMAC_Update(&hmac, ClientRandom, 32)) return FALSE; if (!winpr_HMAC_Final(&hmac, clientCookie->securityVerifier, 16)) return FALSE; return TRUE; }
SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { int index; int length; void* data; UINT32 SeqNo; UINT32 value; BYTE digest[WINPR_MD5_DIGEST_LENGTH]; BYTE checksum[8]; BYTE* signature; ULONG version = 1; WINPR_HMAC_CTX* hmac; NTLM_CONTEXT* context; PSecBuffer data_buffer = NULL; PSecBuffer signature_buffer = NULL; SeqNo = MessageSeqNo; context = (NTLM_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 = malloc(length); if (!data) return SEC_E_INSUFFICIENT_MEMORY; CopyMemory(data, data_buffer->pvBuffer, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ hmac = winpr_HMAC_New(); if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH)) { Data_Write_UINT32(&value, SeqNo); winpr_HMAC_Update(hmac, (void*) &value, 4); winpr_HMAC_Update(hmac, (void*) data, length); winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH); winpr_HMAC_Free(hmac); } else { winpr_HMAC_Free(hmac); free(data); return SEC_E_INSUFFICIENT_MEMORY; } /* Encrypt message using with RC4, result overwrites original buffer */ if (context->confidentiality) winpr_RC4_Update(context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer); else CopyMemory(data_buffer->pvBuffer, data, length); #ifdef WITH_DEBUG_NTLM WLog_DBG(TAG, "Data Buffer (length = %d)", length); winpr_HexDump(TAG, WLOG_DEBUG, data, length); WLog_DBG(TAG, "Encrypted Data Buffer (length = %"PRIu32")", data_buffer->cbBuffer); winpr_HexDump(TAG, WLOG_DEBUG, data_buffer->pvBuffer, data_buffer->cbBuffer); #endif free(data); /* RC4-encrypt first 8 bytes of digest */ winpr_RC4_Update(context->SendRc4Seal, 8, digest, checksum); signature = (BYTE*) signature_buffer->pvBuffer; /* Concatenate version, ciphertext and sequence number to build signature */ Data_Write_UINT32(signature, version); CopyMemory(&signature[4], (void*) checksum, 8); Data_Write_UINT32(&signature[12], SeqNo); context->SendSeqNum++; #ifdef WITH_DEBUG_NTLM WLog_DBG(TAG, "Signature (length = %"PRIu32")", signature_buffer->cbBuffer); winpr_HexDump(TAG, WLOG_DEBUG, signature_buffer->pvBuffer, signature_buffer->cbBuffer); #endif return SEC_E_OK; }