Support constant values for algorithm handles in `BCryptGenRandom` and make no attempt to dereference such handles (which would cause "Unhandled page fault on read access").
MSDN Documentation: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-h...
---
Values of any constants are taken from this [MIT licensed](https://github.com/microsoft/windows-rs/blob/0debb1200c23f588def4af900bc7137...) repository:
https://github.com/microsoft/windows-rs
I used a Python script to examine the pseudo-handles:
```python import re handles = [] p = re.compile('pub const (BCRYPT_[A-Z0-9_]+_ALG_HANDLE): BCRYPT_ALG_HANDLE = ([0-9]+)u32 as _;') with open('crates/libs/sys/src/Windows/Win32/Security/Cryptography/mod.rs') as f: t = f.read() for match in p.finditer(t): name = match.group(1) value = int(match.group(2)) handles.append((name, value)) handles.sort(key=lambda x: x[1])
for (name, value) in handles: print(f"{value:>3}\t{hex(value):>5}\t{bin(value):>12}\t{name}") ```
Output: ```text 1 0x1 0b1 BCRYPT_MD2_ALG_HANDLE 17 0x11 0b10001 BCRYPT_MD4_ALG_HANDLE 33 0x21 0b100001 BCRYPT_MD5_ALG_HANDLE 49 0x31 0b110001 BCRYPT_SHA1_ALG_HANDLE 65 0x41 0b1000001 BCRYPT_SHA256_ALG_HANDLE 81 0x51 0b1010001 BCRYPT_SHA384_ALG_HANDLE 97 0x61 0b1100001 BCRYPT_SHA512_ALG_HANDLE 113 0x71 0b1110001 BCRYPT_RC4_ALG_HANDLE 129 0x81 0b10000001 BCRYPT_RNG_ALG_HANDLE 145 0x91 0b10010001 BCRYPT_HMAC_MD5_ALG_HANDLE 161 0xa1 0b10100001 BCRYPT_HMAC_SHA1_ALG_HANDLE 177 0xb1 0b10110001 BCRYPT_HMAC_SHA256_ALG_HANDLE 193 0xc1 0b11000001 BCRYPT_HMAC_SHA384_ALG_HANDLE 209 0xd1 0b11010001 BCRYPT_HMAC_SHA512_ALG_HANDLE 225 0xe1 0b11100001 BCRYPT_RSA_ALG_HANDLE 241 0xf1 0b11110001 BCRYPT_ECDSA_ALG_HANDLE 257 0x101 0b100000001 BCRYPT_AES_CMAC_ALG_HANDLE 273 0x111 0b100010001 BCRYPT_AES_GMAC_ALG_HANDLE 289 0x121 0b100100001 BCRYPT_HMAC_MD2_ALG_HANDLE 305 0x131 0b100110001 BCRYPT_HMAC_MD4_ALG_HANDLE 321 0x141 0b101000001 BCRYPT_3DES_CBC_ALG_HANDLE 337 0x151 0b101010001 BCRYPT_3DES_ECB_ALG_HANDLE 353 0x161 0b101100001 BCRYPT_3DES_CFB_ALG_HANDLE 369 0x171 0b101110001 BCRYPT_3DES_112_CBC_ALG_HANDLE 385 0x181 0b110000001 BCRYPT_3DES_112_ECB_ALG_HANDLE 401 0x191 0b110010001 BCRYPT_3DES_112_CFB_ALG_HANDLE 417 0x1a1 0b110100001 BCRYPT_AES_CBC_ALG_HANDLE 433 0x1b1 0b110110001 BCRYPT_AES_ECB_ALG_HANDLE 449 0x1c1 0b111000001 BCRYPT_AES_CFB_ALG_HANDLE 465 0x1d1 0b111010001 BCRYPT_AES_CCM_ALG_HANDLE 481 0x1e1 0b111100001 BCRYPT_AES_GCM_ALG_HANDLE 497 0x1f1 0b111110001 BCRYPT_DES_CBC_ALG_HANDLE 513 0x201 0b1000000001 BCRYPT_DES_ECB_ALG_HANDLE 529 0x211 0b1000010001 BCRYPT_DES_CFB_ALG_HANDLE 545 0x221 0b1000100001 BCRYPT_DESX_CBC_ALG_HANDLE 561 0x231 0b1000110001 BCRYPT_DESX_ECB_ALG_HANDLE 577 0x241 0b1001000001 BCRYPT_DESX_CFB_ALG_HANDLE 593 0x251 0b1001010001 BCRYPT_RC2_CBC_ALG_HANDLE 609 0x261 0b1001100001 BCRYPT_RC2_ECB_ALG_HANDLE 625 0x271 0b1001110001 BCRYPT_RC2_CFB_ALG_HANDLE 641 0x281 0b1010000001 BCRYPT_DH_ALG_HANDLE 657 0x291 0b1010010001 BCRYPT_ECDH_ALG_HANDLE 673 0x2a1 0b1010100001 BCRYPT_ECDH_P256_ALG_HANDLE 689 0x2b1 0b1010110001 BCRYPT_ECDH_P384_ALG_HANDLE 705 0x2c1 0b1011000001 BCRYPT_ECDH_P521_ALG_HANDLE 721 0x2d1 0b1011010001 BCRYPT_DSA_ALG_HANDLE 737 0x2e1 0b1011100001 BCRYPT_ECDSA_P256_ALG_HANDLE 753 0x2f1 0b1011110001 BCRYPT_ECDSA_P384_ALG_HANDLE 769 0x301 0b1100000001 BCRYPT_ECDSA_P521_ALG_HANDLE 785 0x311 0b1100010001 BCRYPT_RSA_SIGN_ALG_HANDLE 801 0x321 0b1100100001 BCRYPT_CAPI_KDF_ALG_HANDLE 817 0x331 0b1100110001 BCRYPT_PBKDF2_ALG_HANDLE 833 0x341 0b1101000001 BCRYPT_SP800108_CTR_HMAC_ALG_HANDLE 849 0x351 0b1101010001 BCRYPT_SP80056A_CONCAT_ALG_HANDLE 865 0x361 0b1101100001 BCRYPT_TLS1_1_KDF_ALG_HANDLE 881 0x371 0b1101110001 BCRYPT_TLS1_2_KDF_ALG_HANDLE 897 0x381 0b1110000001 BCRYPT_XTS_AES_ALG_HANDLE 913 0x391 0b1110010001 BCRYPT_HKDF_ALG_HANDLE 929 0x3a1 0b1110100001 BCRYPT_CHACHA20_POLY1305_ALG_HANDLE ```
-- v4: bcrypt: Add basic support for pseudo-handles
From: Chris Denton christophersdenton@gmail.com
Support constant values for algorithm handles in `BCryptGenRandom` and make no attempt to dereference such handles.
MSDN Documentation: https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-h... --- dlls/bcrypt/bcrypt_main.c | 11 +++++++++++ dlls/bcrypt/tests/bcrypt.c | 8 ++++++++ include/bcrypt.h | 3 +++ 3 files changed, 22 insertions(+)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 0c4c13a4c86..0137cc30adb 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -190,6 +190,17 @@ NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE handle, UCHAR *buffer, ULONG c if (!(flags & BCRYPT_USE_SYSTEM_PREFERRED_RNG)) return STATUS_INVALID_HANDLE; } + else if (((ULONG_PTR)algorithm & 1) == 1) + { + /* Pseudo algorithm handles are denoted by having the lowest bit set. + * An aligned algorithm pointer will never have this bit set. + */ + if (algorithm != BCRYPT_RNG_ALG_HANDLE) + { + FIXME( "pseudo-handle algorithm %p not supported\n", algorithm); + return STATUS_NOT_IMPLEMENTED; + } + } else if (algorithm->hdr.magic != MAGIC_ALG || algorithm->id != ALG_ID_RNG) return STATUS_INVALID_HANDLE;
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 2af105463d4..95a09b9395f 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -57,6 +57,14 @@ static void test_BCryptGenRandom(void) ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret); ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n"); + + /* Test pseudo handle, which was introduced at the same time as BCryptHash */ + if (pBCryptHash) + { + ret = BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, buffer, sizeof(buffer), 0); + ok(ret == STATUS_SUCCESS, "Expected success, got %#lx\n", ret); + } + else win_skip("BCryptGenRandom pseudo handles are not available\n"); }
static void test_BCryptGetFipsAlgorithmMode(void) diff --git a/include/bcrypt.h b/include/bcrypt.h index c9c4cb7b1fd..de31ca358ae 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -401,6 +401,9 @@ typedef PVOID BCRYPT_HANDLE; typedef PVOID BCRYPT_HASH_HANDLE; typedef PVOID BCRYPT_SECRET_HANDLE;
+/* Pseudo handles for BCryptGenRandom */ +#define BCRYPT_RNG_ALG_HANDLE ((BCRYPT_ALG_HANDLE)0x00000081) + /* Flags for BCryptGenRandom */ #define BCRYPT_RNG_USE_ENTROPY_IN_BUFFER 0x00000001 #define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002