From: Hans Leidekker <hans@codeweavers.com> --- dlls/bcrypt/bcrypt_main.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/bcrypt/tests/bcrypt.c | 35 +++++++++++++++++++++++++++++++++++ include/bcrypt.h | 7 +++++-- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index af300614b75..b6e635ff257 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -52,6 +52,7 @@ enum alg_id { /* cipher */ ALG_ID_3DES, + ALG_ID_CHACHA20_POLY1305, ALG_ID_AES, ALG_ID_RC4, @@ -145,6 +146,7 @@ struct gcm_key }; #define BLOCK_LENGTH_RC4 1 +#define BLOCK_LENGTH_CHACHA20_POLY1305 1 #define BLOCK_LENGTH_3DES 8 #define BLOCK_LENGTH_AES 16 @@ -345,6 +347,7 @@ static const struct builtin_algorithms[] = { { BCRYPT_3DES_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 522, 0, 0 }, + { BCRYPT_CHACHA20_POLY1305_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 166, 0, 0 }, { BCRYPT_AES_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 654, 0, 0 }, { BCRYPT_RC4_ALGORITHM, BCRYPT_CIPHER_INTERFACE, 654, 0, 0 }, { BCRYPT_SHA256_ALGORITHM, BCRYPT_HASH_INTERFACE, 286, 32, 512 }, @@ -490,6 +493,13 @@ static const struct algorithm pseudo_algorithms[] = {{ MAGIC_ALG }, ALG_ID_RSA_SIGN }, {{ 0 }}, /* CAPI_KDF */ {{ MAGIC_ALG }, ALG_ID_PBKDF2 }, + {{ 0 }}, /* SP800108_CTR_HMAC */ + {{ 0 }}, /* SP80056A_CONCAT */ + {{ 0 }}, /* TLS1_1_KDF */ + {{ 0 }}, /* TLS1_2_KDF */ + {{ 0 }}, /* XTS_AES */ + {{ 0 }}, /* HKDF */ + {{ MAGIC_ALG }, ALG_ID_CHACHA20_POLY1305 }, }; /* Algorithm pseudo-handles are denoted by having the lowest bit set. @@ -860,6 +870,20 @@ static NTSTATUS get_pbkdf2_property( enum chain_mode mode, const WCHAR *prop, UC return STATUS_NOT_IMPLEMENTED; } +static NTSTATUS get_chacha20_poly1305_property( const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) +{ + if (!wcscmp( prop, BCRYPT_BLOCK_LENGTH )) + { + *ret_size = sizeof(ULONG); + if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL; + if (buf) *(ULONG *)buf = BLOCK_LENGTH_CHACHA20_POLY1305; + return STATUS_SUCCESS; + } + + FIXME( "unsupported property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) { @@ -873,6 +897,9 @@ static NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop case ALG_ID_3DES: return get_3des_property( alg->mode, prop, buf, size, ret_size ); + case ALG_ID_CHACHA20_POLY1305: + return get_chacha20_poly1305_property( prop, buf, size, ret_size ); + case ALG_ID_AES: return get_aes_property( alg->mode, prop, buf, size, ret_size ); @@ -918,6 +945,17 @@ static NTSTATUS set_alg_property( struct algorithm *alg, const WCHAR *prop, UCHA FIXME( "unsupported 3des algorithm property %s\n", debugstr_w(prop) ); return STATUS_NOT_IMPLEMENTED; + case ALG_ID_CHACHA20_POLY1305: + if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) + { + if (!wcscmp( (WCHAR *)value, BCRYPT_CHAIN_MODE_NA )) return STATUS_SUCCESS; + + FIXME( "unsupported mode %s\n", debugstr_w((WCHAR *)value) ); + return STATUS_NOT_IMPLEMENTED; + } + FIXME( "unsupported CHACHA20_POLY1305 algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + case ALG_ID_AES: if (!wcscmp( prop, BCRYPT_CHAINING_MODE )) { diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index b7c7fddbffa..de87293431e 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -4888,6 +4888,40 @@ static void test_PBKDF2(void) ok(status == STATUS_SUCCESS, "got %#lx\n", status); } +static void test_CHACHA20_POLY1305(void) +{ + BCRYPT_ALG_HANDLE alg; + NTSTATUS status; + ULONG len, size; + + status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_CHACHA20_POLY1305_ALGORITHM, NULL, 0); + if (status == STATUS_NOT_FOUND) + { + win_skip("CHACHA20_POLY1305 not supported\n"); + return; + } + ok(status == STATUS_SUCCESS, "got %#lx\n", status); + + len = size = 0; + status = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(status == STATUS_SUCCESS, "got %#lx\n", status); + ok(len, "expected non-zero len\n"); + ok(size == sizeof(len), "got %lu\n", size); + + len = size = 0; + status = BCryptGetProperty(alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(status == STATUS_SUCCESS, "got %#lx\n", status); + ok(len == 1, "got %lu\n", len); + ok(size == sizeof(len), "got %lu\n", size); + + size = sizeof(BCRYPT_CHAIN_MODE_NA); + status = BCryptSetProperty(alg, BCRYPT_CHAINING_MODE, (UCHAR *)BCRYPT_CHAIN_MODE_NA, size, 0); + ok(!status, "got %#lx\n", status); + + status = BCryptCloseAlgorithmProvider(alg, 0); + ok(status == STATUS_SUCCESS, "got %#lx\n", status); +} + START_TEST(bcrypt) { HMODULE module; @@ -4928,6 +4962,7 @@ START_TEST(bcrypt) test_rsa_encrypt(); test_RC4(); test_PBKDF2(); + test_CHACHA20_POLY1305(); FreeLibrary(module); } diff --git a/include/bcrypt.h b/include/bcrypt.h index a3441fbf72f..a5d044561e3 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -94,6 +94,7 @@ extern "C" { #define BCRYPT_3DES_ALGORITHM L"3DES" #define BCRYPT_AES_ALGORITHM L"AES" +#define BCRYPT_CHACHA20_POLY1305_ALGORITHM L"CHACHA20_POLY1305" #define BCRYPT_DES_ALGORITHM L"DES" #define BCRYPT_DH_ALGORITHM L"DH" #define BCRYPT_DSA_ALGORITHM L"DSA" @@ -108,6 +109,7 @@ extern "C" { #define BCRYPT_MD2_ALGORITHM L"MD2" #define BCRYPT_MD4_ALGORITHM L"MD4" #define BCRYPT_MD5_ALGORITHM L"MD5" +#define BCRYPT_PBKDF2_ALGORITHM L"PBKDF2" #define BCRYPT_RC2_ALGORITHM L"RC2" #define BCRYPT_RC4_ALGORITHM L"RC4" #define BCRYPT_RNG_ALGORITHM L"RNG" @@ -117,7 +119,6 @@ extern "C" { #define BCRYPT_SHA256_ALGORITHM L"SHA256" #define BCRYPT_SHA384_ALGORITHM L"SHA384" #define BCRYPT_SHA512_ALGORITHM L"SHA512" -#define BCRYPT_PBKDF2_ALGORITHM L"PBKDF2" #define BCRYPT_CHAIN_MODE_NA L"ChainingModeN/A" #define BCRYPT_CHAIN_MODE_CBC L"ChainingModeCBC" @@ -188,6 +189,7 @@ static const WCHAR MS_PLATFORM_CRYPTO_PROVIDER[] = \ static const WCHAR BCRYPT_3DES_ALGORITHM[] = {'3','D','E','S',0}; static const WCHAR BCRYPT_AES_ALGORITHM[] = {'A','E','S',0}; +static const WCHAR BCRYPT_CHACHA20_POLY1305_ALGORITHM[] = {'C','H','A','C','H','A','2','0','_','P','O','L','Y','1','3','0','5',0}; static const WCHAR BCRYPT_DES_ALGORITHM[] = {'D','E','S',0}; static const WCHAR BCRYPT_DH_ALGORITHM[] = {'D','H',0}; static const WCHAR BCRYPT_DSA_ALGORITHM[] = {'D','S','A',0}; @@ -202,6 +204,7 @@ static const WCHAR BCRYPT_ECDSA_P521_ALGORITHM[] = {'E','C','D','S','A','_','P', static const WCHAR BCRYPT_MD2_ALGORITHM[] = {'M','D','2',0}; static const WCHAR BCRYPT_MD4_ALGORITHM[] = {'M','D','4',0}; static const WCHAR BCRYPT_MD5_ALGORITHM[] = {'M','D','5',0}; +static const WCHAR BCRYPT_PBKDF2_ALGORITHM[] = {'P','B','K','D','F','2',0}; static const WCHAR BCRYPT_RC2_ALGORITHM[] = {'R','C','2',0}; static const WCHAR BCRYPT_RC4_ALGORITHM[] = {'R','C','4',0}; static const WCHAR BCRYPT_RNG_ALGORITHM[] = {'R','N','G',0}; @@ -211,7 +214,6 @@ static const WCHAR BCRYPT_SHA1_ALGORITHM[] = {'S','H','A','1',0}; static const WCHAR BCRYPT_SHA256_ALGORITHM[] = {'S','H','A','2','5','6',0}; static const WCHAR BCRYPT_SHA384_ALGORITHM[] = {'S','H','A','3','8','4',0}; static const WCHAR BCRYPT_SHA512_ALGORITHM[] = {'S','H','A','5','1','2',0}; -static const WCHAR BCRYPT_PBKDF2_ALGORITHM[] = {'P','B','K','D','F','2',0}; static const WCHAR BCRYPT_CHAIN_MODE_NA[] = {'C','h','a','i','n','i','n','g','M','o','d','e','N','/','A',0}; static const WCHAR BCRYPT_CHAIN_MODE_CBC[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','B','C',0}; @@ -552,6 +554,7 @@ typedef PVOID BCRYPT_SECRET_HANDLE; #define BCRYPT_TLS1_2_KDF_ALG_HANDLE ((BCRYPT_ALG_HANDLE)0x00000371) #define BCRYPT_XTS_AES_ALG_HANDLE ((BCRYPT_ALG_HANDLE)0x00000381) #define BCRYPT_HKDF_ALG_HANDLE ((BCRYPT_ALG_HANDLE)0x00000391) +#define BCRYPT_CHACHA20_POLY1305_ALG_HANDLE ((BCRYPT_ALG_HANDLE)0x000003a1) /* Flags for BCryptGenRandom */ #define BCRYPT_RNG_USE_ENTROPY_IN_BUFFER 0x00000001 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11137