// Derive an encryption key from a user-supplied buffer static HCRYPTKEY DeriveKey(const void *pKey, int nKeyLen) { HCRYPTHASH hHash = 0; HCRYPTKEY hKey; if (!pKey || !nKeyLen) return 0; if (!InitializeProvider()) { return MAXDWORD; } if (CryptCreateHash(g_hProvider, CALG_SHA1, 0, 0, &hHash)) { if (CryptHashData(hHash, (LPBYTE)pKey, nKeyLen, 0)) { CryptDeriveKey(g_hProvider, CALG_RC4, hHash, 0, &hKey); } CryptDestroyHash(hHash); } return hKey; }
VOID MupGetProviderInformation ( VOID ) /*++ Routine Description: This routine reads MUP information from the registry and saves it for future use. Arguments: None. Return Value: None. --*/ { HANDLE handle; NTSTATUS status; UNICODE_STRING valueName; UNICODE_STRING keyName; OBJECT_ATTRIBUTES objectAttributes; PVOID buffer = NULL; PWCH providerName; ULONG lengthRequired; BOOLEAN done; ULONG priority; PWCH sep; PAGED_CODE(); RtlInitUnicodeString( &keyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Networkprovider\\Order" ); InitializeObjectAttributes( &objectAttributes, &keyName, OBJ_CASE_INSENSITIVE, 0, NULL ); status = ZwOpenKey( &handle, KEY_QUERY_VALUE, &objectAttributes ); if ( !NT_SUCCESS( status )) { return; } RtlInitUnicodeString( &valueName, L"ProviderOrder" ); status = ZwQueryValueKey( handle, &valueName, KeyValueFullInformation, buffer, 0, &lengthRequired ); if ( status == STATUS_BUFFER_TOO_SMALL ) { buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM'); if ( buffer == NULL) { return; } status = ZwQueryValueKey( handle, &valueName, KeyValueFullInformation, buffer, lengthRequired, &lengthRequired ); } ZwClose( handle ); if ( !NT_SUCCESS( status) ) { if ( buffer != NULL ) { ExFreePool( buffer ); } return; } // // Scan the ordered list of providers, and create record for each. // providerName = (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset); done = FALSE; priority = 0; while ( !done ) { sep = wcschr( providerName, L','); if ( sep == NULL ) { done = TRUE; } else { *sep = L'\0'; } InitializeProvider( providerName, priority ); priority++; providerName = sep+1; } ExFreePool( buffer ); return; }