From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/tests/bcrypt.c | 69 ++++++-------------------------------- 1 file changed, 11 insertions(+), 58 deletions(-)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 2035ce346e6..1ad9cc3763c 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -1977,12 +1977,7 @@ static void test_key_import_export(void)
key = NULL; ret = BCryptImportKey(aes, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, buffer1, sizeof(buffer1), 0); - ok(ret == STATUS_SUCCESS || broken(ret == STATUS_INVALID_PARAMETER) /* vista */, "got %#lx\n", ret); - if (ret == STATUS_INVALID_PARAMETER) - { - win_skip("broken BCryptImportKey\n"); - return; - } + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); ok(key != NULL, "key not set\n");
size = 0; @@ -2076,11 +2071,7 @@ static void test_ECDSA(void) ULONG size;
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0); - if (status) - { - skip("Failed to open ECDSA provider: %#lx, skipping test\n", status); - return; - } + ok(!status, "got %#lx\n", status);
ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; memcpy(ecckey + 1, eccPubkey, sizeof(eccPubkey)); @@ -2406,11 +2397,7 @@ static void test_RSA(void) DWORD keylen;
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0); - if (ret) - { - win_skip("Failed to open RSA provider: %#lx, skipping test\n", ret); - return; - } + ok(!ret, "got %#lx\n", ret);
schemes = size = 0; ret = BCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0); @@ -2590,11 +2577,7 @@ static void test_RSA_SIGN(void) BYTE *buf, buf2[sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(rsaPublicBlob)];
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_SIGN_ALGORITHM, NULL, 0); - if (ret) - { - win_skip("Failed to open RSA_SIGN provider: %#lx, skipping test\n", ret); - return; - } + ok(!ret, "got %#lx\n", ret);
ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0); ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret); @@ -2750,11 +2733,7 @@ static void test_ECDH(void) ULONG size;
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDH_P256_ALGORITHM, NULL, 0); - if (status) - { - skip("Failed to open BCRYPT_ECDH_P256_ALGORITHM provider %#lx\n", status); - return; - } + ok(status == STATUS_SUCCESS, "got %#lx\n", status);
key = NULL; status = BCryptGenerateKeyPair(alg, &key, 256, 0); @@ -2827,15 +2806,12 @@ static void test_ECDH(void) ok(status == STATUS_SUCCESS, "got %#lx\n", status); if (status != STATUS_SUCCESS) goto derive_end;
- /* verify result on windows 10 */ status = BCryptDeriveKey(secret, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &size, 0); - - if (status == STATUS_NOT_SUPPORTED) + if (status == STATUS_NOT_SUPPORTED) /* < win10 */ { win_skip("BCRYPT_KDF_RAW_SECRET not supported\n"); goto raw_secret_end; } - todo_wine ok(status == STATUS_SUCCESS, "got %#lx\n", status); if (status != STATUS_SUCCESS) goto raw_secret_end;
@@ -2964,11 +2940,7 @@ static void test_BCryptSignHash(void)
/* RSA */ ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0); - if (ret) - { - win_skip("failed to open RSA provider: %#lx\n", ret); - return; - } + ok(!ret, "got %#lx\n", ret);
/* public key */ ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsapublic, sizeof(rsapublic), 0); @@ -3025,11 +2997,7 @@ static void test_BCryptSignHash(void)
/* ECDSA */ ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0); - if (ret) - { - win_skip("failed to open ECDSA provider: %#lx\n", ret); - return; - } + ok(!ret, "got %#lx\n", ret);
ret = BCryptGenerateKeyPair(alg, &key, 256, 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); @@ -3124,13 +3092,7 @@ static void test_aes_vector(void) memcpy(data + sizeof(*blob), secret, sizeof(secret)); size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + sizeof(secret); ret = BCryptImportKey(alg, NULL, BCRYPT_KEY_DATA_BLOB, &key, NULL, 0, data, size, 0); - ok(!ret || broken(ret == STATUS_INVALID_PARAMETER) /* vista */, "got %#lx\n", ret); - if (ret == STATUS_INVALID_PARAMETER) - { - win_skip("broken BCryptImportKey\n"); - BCryptCloseAlgorithmProvider(alg, 0); - return; - } + ok(!ret, "got %#lx\n", ret);
/* zero initialization vector */ size = 0; @@ -3180,12 +3142,7 @@ static void test_BcryptDeriveKeyCapi(void) ok(!ret, "got %#lx\n", ret);
ret = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0); - ok(!ret || broken(ret == STATUS_INVALID_PARAMETER) /* win2k8 */, "got %#lx\n", ret); - if (ret == STATUS_INVALID_PARAMETER) - { - win_skip( "broken BCryptCreateHash\n" ); - return; - } + ok(!ret, "got %#lx\n", ret);
ret = BCryptDeriveKeyCapi(NULL, NULL, NULL, 0, 0); ok(ret == STATUS_INVALID_PARAMETER || ret == STATUS_INVALID_HANDLE /* win7 */, "got %#lx\n", ret); @@ -3408,11 +3365,7 @@ static void test_SecretAgreement(void) ULONG size;
status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDH_P256_ALGORITHM, NULL, 0); - if (status) - { - skip("Failed to open BCRYPT_ECDH_P256_ALGORITHM provider %#lx\n", status); - return; - } + ok(status == STATUS_SUCCESS, "got %#lx\n", status);
key = NULL; status = BCryptGenerateKeyPair(alg, &key, 256, 0);
From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/gnutls.c | 124 ++++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 55 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 5c88a4c2a3e..fa4a0793cda 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -663,11 +663,12 @@ static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d return size; }
-#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p ) +#define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p ) static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len ) { BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf; gnutls_datum_t m, e; + ULONG size = key->u.a.bitlen / 8; UCHAR *dst; int ret;
@@ -684,14 +685,14 @@ static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, U return STATUS_INTERNAL_ERROR; }
- *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1); + *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ); if (len >= *ret_len && buf) { dst = (UCHAR *)(rsa_blob + 1); - rsa_blob->cbPublicExp = export_gnutls_datum( dst, key->u.a.bitlen / 8, &e, 0 ); + rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
dst += rsa_blob->cbPublicExp; - rsa_blob->cbModulus = export_gnutls_datum( dst, key->u.a.bitlen / 8, &m, 1 ); + rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsa_blob->BitLength = key->u.a.bitlen; @@ -759,16 +760,14 @@ static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, U return STATUS_NOT_IMPLEMENTED; }
- *ret_len = sizeof(*ecc_blob) + size * 2; + *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ); if (len >= *ret_len && buf) { ecc_blob->dwMagic = magic; ecc_blob->cbKey = size;
dst = (UCHAR *)(ecc_blob + 1); - export_gnutls_datum( dst, size, &x, 1 ); - - dst += size; + dst += export_gnutls_datum( dst, size, &x, 1 ); export_gnutls_datum( dst, size, &y, 1 ); }
@@ -780,9 +779,17 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U { BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf; gnutls_datum_t p, q, g, y; + ULONG size = key->u.a.bitlen / 8; + NTSTATUS status = STATUS_SUCCESS; UCHAR *dst; int ret;
+ if (key->u.a.bitlen > 1024) + { + FIXME( "bitlen > 1024 not supported\n" ); + return STATUS_NOT_IMPLEMENTED; + } + if (key_data(key)->a.pubkey) ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y ); else if (key_data(key)->a.privkey) @@ -796,35 +803,32 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U return STATUS_INTERNAL_ERROR; }
- if (key->u.a.bitlen > 1024) + if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q)) { - FIXME( "bitlen > 1024 not supported\n" ); - return STATUS_NOT_IMPLEMENTED; + status = STATUS_INVALID_PARAMETER; + goto done; }
- *ret_len = sizeof(*dsa_blob) + key->u.a.bitlen / 8 * 3; + *ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 ); if (len >= *ret_len && buf) { dst = (UCHAR *)(dsa_blob + 1); - export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 ); - - dst += key->u.a.bitlen / 8; - export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 ); - - dst += key->u.a.bitlen / 8; - export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 ); + dst += export_gnutls_datum( dst, size, &p, 1 ); + dst += export_gnutls_datum( dst, size, &g, 1 ); + export_gnutls_datum( dst, size, &y, 1 );
dst = dsa_blob->q; export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; - dsa_blob->cbKey = key->u.a.bitlen / 8; + dsa_blob->cbKey = size; memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */ memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */ }
+done: free( p.data ); free( q.data ); free( g.data ); free( y.data ); - return STATUS_SUCCESS; + return status; }
static void reverse_bytes( UCHAR *buf, ULONG len ) @@ -846,8 +850,10 @@ static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG l BLOBHEADER *hdr = (BLOBHEADER *)buf; DSSPUBKEY *dsskey; gnutls_datum_t p, q, g, y; + ULONG size = key->u.a.bitlen / 8; + NTSTATUS status = STATUS_SUCCESS; UCHAR *dst; - int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed); + int ret;
if (key->u.a.bitlen > 1024) { @@ -868,7 +874,14 @@ static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG l return STATUS_INTERNAL_ERROR; }
- *ret_len = size + key->u.a.bitlen / 8 * 3 + Q_SIZE; + if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE) + { + status = STATUS_INVALID_PARAMETER; + goto done; + } + + *ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) + + EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 ); if (len >= *ret_len && buf) { hdr->bType = PUBLICKEYBLOB; @@ -881,27 +894,28 @@ static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG l dsskey->bitlen = key->u.a.bitlen;
dst = (UCHAR *)(dsskey + 1); - export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 ); - reverse_bytes( dst, key->u.a.bitlen / 8 ); - dst += key->u.a.bitlen / 8; + export_gnutls_datum( dst, size, &p, 1 ); + reverse_bytes( dst, size ); + dst += size;
export_gnutls_datum( dst, Q_SIZE, &q, 1 ); reverse_bytes( dst, Q_SIZE ); dst += Q_SIZE;
- export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 ); - reverse_bytes( dst, key->u.a.bitlen / 8 ); - dst += key->u.a.bitlen / 8; + export_gnutls_datum( dst, size, &g, 1 ); + reverse_bytes( dst, size ); + dst += size;
- export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 ); - reverse_bytes( dst, key->u.a.bitlen / 8 ); - dst += key->u.a.bitlen / 8; + export_gnutls_datum( dst, size, &y, 1 ); + reverse_bytes( dst, size ); + dst += size;
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) ); }
+done: free( p.data ); free( q.data ); free( g.data ); free( y.data ); - return STATUS_SUCCESS; + return status; }
static NTSTATUS key_asymmetric_generate( void *args ) @@ -1029,7 +1043,7 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r return STATUS_NOT_IMPLEMENTED; }
- *ret_len = sizeof(*ecc_blob) + size * 3; + *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 ); if (len >= *ret_len && buf) { ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf; @@ -1037,12 +1051,8 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r ecc_blob->cbKey = size;
dst = (UCHAR *)(ecc_blob + 1); - export_gnutls_datum( dst, size, &x, 1 ); - dst += size; - - export_gnutls_datum( dst, size, &y, 1 ); - dst += size; - + dst += export_gnutls_datum( dst, size, &x, 1 ); + dst += export_gnutls_datum( dst, size, &y, 1 ); export_gnutls_datum( dst, size, &d, 1 ); }
@@ -1105,7 +1115,7 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG { BCRYPT_RSAKEY_BLOB *rsa_blob; gnutls_datum_t m, e, d, p, q, u, e1, e2; - ULONG bitlen = key->u.a.bitlen; + ULONG size = key->u.a.bitlen / 8; BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL); UCHAR *dst; int ret; @@ -1118,40 +1128,43 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG return STATUS_INTERNAL_ERROR; }
- *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1) + EXPORT_SIZE(p,16,1) + EXPORT_SIZE(q,16,1); - if (full) *ret_len += EXPORT_SIZE(e1,16,1) + EXPORT_SIZE(e2,16,1) + EXPORT_SIZE(u,16,1) + EXPORT_SIZE(d,8,1); + *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) + + EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 ); + + if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) + + EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
if (len >= *ret_len && buf) { rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf; rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC; - rsa_blob->BitLength = bitlen; + rsa_blob->BitLength = key->u.a.bitlen;
dst = (UCHAR *)(rsa_blob + 1); - rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 ); + rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
dst += rsa_blob->cbPublicExp; - rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 ); + rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
dst += rsa_blob->cbModulus; - rsa_blob->cbPrime1 = export_gnutls_datum( dst, bitlen / 16, &p, 1 ); + rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
dst += rsa_blob->cbPrime1; - rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 ); + rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
if (full) { dst += rsa_blob->cbPrime2; - export_gnutls_datum( dst, bitlen / 16, &e1, 1 ); + export_gnutls_datum( dst, size / 2, &e1, 1 );
dst += rsa_blob->cbPrime1; - export_gnutls_datum( dst, bitlen / 16, &e2, 1 ); + export_gnutls_datum( dst, size / 2, &e2, 1 );
dst += rsa_blob->cbPrime2; - export_gnutls_datum( dst, bitlen / 16, &u, 1 ); + export_gnutls_datum( dst, size / 2, &u, 1 );
dst += rsa_blob->cbPrime1; - export_gnutls_datum( dst, bitlen / 8, &d, 1 ); + export_gnutls_datum( dst, size, &d, 1 ); } }
@@ -1199,8 +1212,9 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO BLOBHEADER *hdr; DSSPUBKEY *pubkey; gnutls_datum_t p, q, g, y, x; + ULONG size = key->u.a.bitlen / 8; UCHAR *dst; - int ret, size; + int ret;
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
@@ -1217,8 +1231,8 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO return STATUS_NOT_SUPPORTED; }
- size = key->u.a.bitlen / 8; - *ret_len = sizeof(*hdr) + sizeof(*pubkey) + size * 2 + 40 + sizeof(key->u.a.dss_seed); + *ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) + + EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20; if (len >= *ret_len && buf) { hdr = (BLOBHEADER *)buf;
From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/gnutls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index fa4a0793cda..aeef64fd642 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -659,7 +659,7 @@ static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d size = buflen; }
- if (buffer) memcpy( buffer + offset, src, size ); + if (buffer) memcpy( buffer + offset, src, size - offset ); return size; }
From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/bcrypt_main.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 6f6d713c6ac..a222cd03d72 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1039,10 +1039,10 @@ NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG s return hash_update( &hash->inner, hash->alg_id, input, size ); }
-static NTSTATUS hash_finalize( struct hash *hash, UCHAR *output, ULONG size ) +static NTSTATUS hash_finalize( struct hash *hash, UCHAR *output ) { UCHAR buffer[MAX_HASH_OUTPUT_BYTES]; - int hash_length; + ULONG hash_length = builtin_algorithms[hash->alg_id].hash_length; NTSTATUS status;
if (!(hash->flags & HASH_FLAG_HMAC)) @@ -1052,7 +1052,6 @@ static NTSTATUS hash_finalize( struct hash *hash, UCHAR *output, ULONG size ) return STATUS_SUCCESS; }
- hash_length = builtin_algorithms[hash->alg_id].hash_length; if ((status = hash_finish( &hash->inner, hash->alg_id, buffer ))) return status; if ((status = hash_update( &hash->outer, hash->alg_id, buffer, hash_length ))) return status; if ((status = hash_finish( &hash->outer, hash->alg_id, output ))) return status; @@ -1070,7 +1069,7 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULON if (!hash) return STATUS_INVALID_HANDLE; if (!output || size != builtin_algorithms[hash->alg_id].hash_length) return STATUS_INVALID_PARAMETER;
- return hash_finalize( hash, output, size ); + return hash_finalize( hash, output ); }
NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE handle, UCHAR *secret, ULONG secret_len, @@ -1096,7 +1095,7 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE handle, UCHAR *secret, ULONG secre hash_destroy( hash ); return status; } - status = hash_finalize( hash, output, output_len ); + status = hash_finalize( hash, output ); hash_destroy( hash ); return status; } @@ -2159,9 +2158,9 @@ NTSTATUS WINAPI BCryptDeriveKeyCapi( BCRYPT_HASH_HANDLE handle, BCRYPT_ALG_HANDL return STATUS_NOT_IMPLEMENTED; }
- len = builtin_algorithms[hash->alg_id].hash_length; - if ((status = hash_finalize( hash, buf, len ))) return status; + if ((status = hash_finalize( hash, buf ))) return status;
+ len = builtin_algorithms[hash->alg_id].hash_length; if (len < keylen) { UCHAR pad1[HMAC_PAD_LEN], pad2[HMAC_PAD_LEN]; @@ -2175,11 +2174,11 @@ NTSTATUS WINAPI BCryptDeriveKeyCapi( BCRYPT_HASH_HANDLE handle, BCRYPT_ALG_HANDL
if ((status = hash_prepare( hash )) || (status = hash_update( &hash->inner, hash->alg_id, pad1, sizeof(pad1) )) || - (status = hash_finalize( hash, buf, len ))) return status; + (status = hash_finalize( hash, buf ))) return status;
if ((status = hash_prepare( hash )) || (status = hash_update( &hash->inner, hash->alg_id, pad2, sizeof(pad2) )) || - (status = hash_finalize( hash, buf + len, len ))) return status; + (status = hash_finalize( hash, buf + len ))) return status; }
memcpy( key, buf, keylen ); @@ -2219,7 +2218,7 @@ static NTSTATUS pbkdf2( struct hash *hash, UCHAR *pwd, ULONG pwd_len, UCHAR *sal return status; }
- if ((status = hash_finalize( hash, buf, hash_len ))) + if ((status = hash_finalize( hash, buf ))) { free( buf ); return status;
From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/bcrypt_main.c | 46 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index a222cd03d72..72501faf90e 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -121,6 +121,26 @@ builtin_algorithms[] = { BCRYPT_RNG_ALGORITHM, BCRYPT_RNG_INTERFACE, 0, 0, 0 }, };
+static inline BOOL is_symmetric_key( struct key *key ) +{ + return builtin_algorithms[key->alg_id].class == BCRYPT_CIPHER_INTERFACE; +} + +static inline BOOL is_asymmetric_encryption_key( struct key *key ) +{ + return builtin_algorithms[key->alg_id].class == BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE; +} + +static inline BOOL is_agreement_key( struct key *key ) +{ + return builtin_algorithms[key->alg_id].class == BCRYPT_SECRET_AGREEMENT_INTERFACE; +} + +static inline BOOL is_signature_key( struct key *key ) +{ + return builtin_algorithms[key->alg_id].class == BCRYPT_SIGNATURE_INTERFACE || key->alg_id == ALG_ID_RSA; +} + static BOOL match_operation_type( ULONG type, ULONG class ) { if (!type) return TRUE; @@ -1119,11 +1139,6 @@ static NTSTATUS key_asymmetric_create( enum alg_id alg_id, ULONG bitlen, struct return STATUS_SUCCESS; }
-static BOOL key_is_symmetric( struct key *key ) -{ - return builtin_algorithms[key->alg_id].class == BCRYPT_CIPHER_INTERFACE; -} - static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2 ) { if (!vector && !vector2) return TRUE; @@ -1505,7 +1520,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
static void key_destroy( struct key *key ) { - if (key_is_symmetric( key )) + if (is_symmetric_key( key )) { UNIX_CALL( key_symmetric_destroy, key ); free( key->u.s.vector ); @@ -1868,7 +1883,7 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy ) key_copy->hdr = key_orig->hdr; key_copy->alg_id = key_orig->alg_id;
- if (key_is_symmetric( key_orig )) + if (is_symmetric_key( key_orig )) { if (!(buffer = malloc( key_orig->u.s.secret_len ))) return STATUS_NO_MEMORY; memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len ); @@ -1977,11 +1992,7 @@ NTSTATUS WINAPI BCryptSignHash( BCRYPT_KEY_HANDLE handle, void *padding, UCHAR * ret_len, flags );
if (!key) return STATUS_INVALID_HANDLE; - if (key_is_symmetric( key )) - { - FIXME( "signing with symmetric keys not yet supported\n" ); - return STATUS_NOT_IMPLEMENTED; - } + if (!is_signature_key( key )) return STATUS_NOT_SUPPORTED;
params.key = key; params.padding = padding; @@ -2003,8 +2014,8 @@ NTSTATUS WINAPI BCryptVerifySignature( BCRYPT_KEY_HANDLE handle, void *padding, TRACE( "%p, %p, %p, %lu, %p, %lu, %#lx\n", handle, padding, hash, hash_len, signature, signature_len, flags );
if (!key) return STATUS_INVALID_HANDLE; + if (!is_signature_key( key )) return STATUS_NOT_SUPPORTED; if (!hash || !hash_len || !signature || !signature_len) return STATUS_INVALID_PARAMETER; - if (key_is_symmetric( key )) return STATUS_NOT_SUPPORTED;
params.key = key; params.padding = padding; @@ -2039,7 +2050,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
if (!key) return STATUS_INVALID_HANDLE;
- if (key_is_symmetric( key )) + if (is_symmetric_key( key )) { if (flags & ~BCRYPT_BLOCK_PADDING) { @@ -2057,6 +2068,8 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp FIXME( "flags %#lx not implemented\n", flags ); return STATUS_NOT_IMPLEMENTED; } + if (!is_asymmetric_encryption_key( key )) return STATUS_NOT_SUPPORTED; + asymmetric_params.input = input; asymmetric_params.input_len = input_len; asymmetric_params.key = key; @@ -2081,7 +2094,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
if (!key) return STATUS_INVALID_HANDLE;
- if (key_is_symmetric( key )) + if (is_symmetric_key( key )) { if (flags & ~BCRYPT_BLOCK_PADDING) { @@ -2100,6 +2113,8 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp FIXME( "flags %#lx not implemented\n", flags ); return STATUS_NOT_IMPLEMENTED; } + if (!is_asymmetric_encryption_key( key )) return STATUS_NOT_SUPPORTED; + params.key = key; params.input = input; params.input_len = input_len; @@ -2300,6 +2315,7 @@ NTSTATUS WINAPI BCryptSecretAgreement( BCRYPT_KEY_HANDLE privkey_handle, BCRYPT_ FIXME( "%p, %p, %p, %#lx\n", privkey_handle, pubkey_handle, ret_handle, flags );
if (!privkey || !pubkey) return STATUS_INVALID_HANDLE; + if (!is_agreement_key( privkey ) || !is_agreement_key( pubkey )) return STATUS_NOT_SUPPORTED; if (!ret_handle) return STATUS_INVALID_PARAMETER;
if (!(secret = calloc( 1, sizeof(*secret) ))) return STATUS_NO_MEMORY;
From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/gnutls.c | 99 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 15 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index aeef64fd642..d5ffe88e2b4 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -1877,17 +1877,11 @@ static NTSTATUS key_asymmetric_destroy( void *args ) return STATUS_SUCCESS; }
-static NTSTATUS key_asymmetric_duplicate( void *args ) +static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy ) { - const struct key_asymmetric_duplicate_params *params = args; - struct key *key_orig = params->key_orig; - struct key *key_copy = params->key_copy; gnutls_privkey_t privkey; - gnutls_pubkey_t pubkey; int ret;
- if (!key_data(key_orig)->a.privkey) return STATUS_SUCCESS; - if ((ret = pgnutls_privkey_init( &privkey ))) { pgnutls_perror( ret ); @@ -1959,25 +1953,100 @@ static NTSTATUS key_asymmetric_duplicate( void *args ) return STATUS_INTERNAL_ERROR; }
- if (key_data(key_orig)->a.pubkey) + key_data(key_copy)->a.privkey = privkey; + return STATUS_SUCCESS; +} + +static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy ) +{ + gnutls_pubkey_t pubkey; + int ret; + + if ((ret = pgnutls_pubkey_init( &pubkey ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + + switch (key_orig->alg_id) { - if ((ret = pgnutls_pubkey_init( &pubkey ))) + case ALG_ID_RSA: + case ALG_ID_RSA_SIGN: + { + gnutls_datum_t m, e; + if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e ))) { pgnutls_perror( ret ); - pgnutls_privkey_deinit( privkey ); return STATUS_INTERNAL_ERROR; } - if ((ret = pgnutls_pubkey_import_privkey( pubkey, key_data(key_orig)->a.privkey, 0, 0 ))) + ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e ); + free( m.data ); free( e.data ); + if (ret) { pgnutls_perror( ret ); - pgnutls_pubkey_deinit( pubkey ); - pgnutls_privkey_deinit( privkey ); return STATUS_INTERNAL_ERROR; } - key_data(key_copy)->a.pubkey = pubkey; + break; + } + case ALG_ID_DSA: + { + gnutls_datum_t p, q, g, y; + if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y ); + free( p.data ); free( q.data ); free( g.data ); free( y.data ); + if (ret) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + key_copy->u.a.dss_seed = key_orig->u.a.dss_seed; + break; + } + case ALG_ID_ECDH_P256: + case ALG_ID_ECDH_P384: + case ALG_ID_ECDSA_P256: + case ALG_ID_ECDSA_P384: + { + gnutls_ecc_curve_t curve; + gnutls_datum_t x, y; + if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y ); + free( x.data ); free( y.data ); + if (ret) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + break; + } + default: + ERR( "unhandled algorithm %u\n", key_orig->alg_id ); + return STATUS_INTERNAL_ERROR; }
- key_data(key_copy)->a.privkey = privkey; + key_data(key_copy)->a.pubkey = pubkey; + return STATUS_SUCCESS; +} + +static NTSTATUS key_asymmetric_duplicate( void *args ) +{ + const struct key_asymmetric_duplicate_params *params = args; + NTSTATUS status; + + if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy ))) + return status; + + if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy ))) + return status; + return STATUS_SUCCESS; }
From: Hans Leidekker hans@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53972 --- dlls/bcrypt/gnutls.c | 175 +++++++++++++++++++++++++++++++------ dlls/bcrypt/tests/bcrypt.c | 47 ++++++---- include/bcrypt.h | 9 +- 3 files changed, 187 insertions(+), 44 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index d5ffe88e2b4..9425cccd066 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -134,6 +134,11 @@ static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datu
/* Not present in gnutls version < 3.6.0 */ static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *); +static int (*pgnutls_x509_spki_init)(gnutls_x509_spki_t *); +static void (*pgnutls_x509_spki_deinit)(gnutls_x509_spki_t); +static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, unsigned int); +static int (*pgnutls_pubkey_set_spki)(gnutls_pubkey_t, const gnutls_x509_spki_t, unsigned int); +static int (*pgnutls_privkey_set_spki)(gnutls_privkey_t, const gnutls_x509_spki_t, unsigned int);
static void *libgnutls_handle; #define MAKE_FUNCPTR(f) static typeof(f) * p##f @@ -269,6 +274,30 @@ static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int f return GNUTLS_E_UNKNOWN_PK_ALGORITHM; }
+static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t *spki) +{ + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; +} + +static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki) +{ +} + +static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig, + unsigned int salt_size) +{ +} + +static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key, const gnutls_x509_spki_t spki, unsigned int flags) +{ + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; +} + +static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags) +{ + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; +} + static void gnutls_log( int level, const char *msg ) { TRACE( "<%d> %s", level, msg ); @@ -329,23 +358,29 @@ static NTSTATUS gnutls_process_attach( void *args )
LOAD_FUNCPTR_OPT(gnutls_cipher_tag) LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth) + LOAD_FUNCPTR_OPT(gnutls_decode_rs_value) + LOAD_FUNCPTR_OPT(gnutls_pk_to_sign) + LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data) + LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw) + LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw) + LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw) + LOAD_FUNCPTR_OPT(gnutls_privkey_generate) + LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw) + LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw) + LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki) + LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data) LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw) LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw) LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw) + LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw) LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw) - LOAD_FUNCPTR_OPT(gnutls_pk_to_sign) - LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2) LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw) - LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_generate) - LOAD_FUNCPTR_OPT(gnutls_decode_rs_value) - LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw) - LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data) - LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data) + LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki) + LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2) + LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit) + LOAD_FUNCPTR_OPT(gnutls_x509_spki_init) + LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params) + #undef LOAD_FUNCPTR_OPT
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS) @@ -1631,6 +1666,27 @@ static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id ) return GNUTLS_DIG_UNKNOWN; }
+static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size ) +{ + gnutls_x509_spki_t spki; + int ret; + + if (((ret = pgnutls_x509_spki_init( &spki ) < 0))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size ); + ret = pgnutls_pubkey_set_spki( key, spki, 0 ); + pgnutls_x509_spki_deinit( spki ); + if (ret < 0) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + return STATUS_SUCCESS; +} + static NTSTATUS key_asymmetric_verify( void *args ) { const struct key_asymmetric_verify_params *params = args; @@ -1667,17 +1723,34 @@ static NTSTATUS key_asymmetric_verify( void *args ) case ALG_ID_RSA: case ALG_ID_RSA_SIGN: { - BCRYPT_PKCS1_PADDING_INFO *info = params->padding; - - if (!(flags & BCRYPT_PAD_PKCS1) || !info) return STATUS_INVALID_PARAMETER; - if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE; - - if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN) + if (flags & BCRYPT_PAD_PKCS1) { - FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) ); - return STATUS_NOT_SUPPORTED; + BCRYPT_PKCS1_PADDING_INFO *info = params->padding; + + if (!info) return STATUS_INVALID_PARAMETER; + if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE; + if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN) + { + FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) ); + return STATUS_NOT_SUPPORTED; + } + pk_alg = GNUTLS_PK_RSA; } - pk_alg = GNUTLS_PK_RSA; + else if (flags & BCRYPT_PAD_PSS) + { + BCRYPT_PSS_PADDING_INFO *info = params->padding; + + if (!info) return STATUS_INVALID_PARAMETER; + if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE; + if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN) + { + FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) ); + return STATUS_NOT_SUPPORTED; + } + if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status; + pk_alg = GNUTLS_PK_RSA_PSS; + } + else return STATUS_INVALID_PARAMETER; break; } case ALG_ID_DSA: @@ -1777,12 +1850,32 @@ static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signat } }
+static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size ) +{ + gnutls_x509_spki_t spki; + int ret; + + if (((ret = pgnutls_x509_spki_init( &spki ) < 0))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size ); + ret = pgnutls_privkey_set_spki( key, spki, 0 ); + pgnutls_x509_spki_deinit( spki ); + if (ret < 0) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + return STATUS_SUCCESS; +} + static NTSTATUS key_asymmetric_sign( void *args ) { const struct key_asymmetric_sign_params *params = args; struct key *key = params->key; - unsigned flags = params->flags; - BCRYPT_PKCS1_PADDING_INFO *pad = params->padding; + unsigned int flags = params->flags, gnutls_flags = 0; gnutls_datum_t hash, signature; gnutls_digest_algorithm_t hash_alg; NTSTATUS status; @@ -1803,10 +1896,14 @@ static NTSTATUS key_asymmetric_sign( void *args ) return STATUS_INVALID_PARAMETER; }
- if (flags == BCRYPT_PAD_PKCS1 && pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg) + if (flags == BCRYPT_PAD_PKCS1) { - WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg ); - return STATUS_INVALID_PARAMETER; + BCRYPT_PKCS1_PADDING_INFO *pad = params->padding; + if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg) + { + WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg ); + return STATUS_INVALID_PARAMETER; + } } } else if (key->alg_id == ALG_ID_DSA) @@ -1821,17 +1918,41 @@ static NTSTATUS key_asymmetric_sign( void *args ) } else if (flags == BCRYPT_PAD_PKCS1) { + BCRYPT_PKCS1_PADDING_INFO *pad = params->padding; + if (!pad || !pad->pszAlgId) { WARN( "padding info not found\n" ); return STATUS_INVALID_PARAMETER; } + if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN) + { + FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) ); + return STATUS_NOT_SUPPORTED; + } + } + else if (flags == BCRYPT_PAD_PSS) + { + BCRYPT_PSS_PADDING_INFO *pad = params->padding;
+ if (!pad || !pad->pszAlgId) + { + WARN( "padding info not found\n" ); + return STATUS_INVALID_PARAMETER; + } + if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN) + { + FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id ); + return STATUS_NOT_SUPPORTED; + } if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN) { FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) ); return STATUS_NOT_SUPPORTED; } + + if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status; + gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; } else if (!flags) { @@ -1857,7 +1978,7 @@ static NTSTATUS key_asymmetric_sign( void *args ) signature.data = NULL; signature.size = 0;
- if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, 0, &hash, &signature ))) + if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature ))) { pgnutls_perror( ret ); return STATUS_INTERNAL_ERROR; diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 1ad9cc3763c..39cdd015c90 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -2386,11 +2386,16 @@ static void test_RSA(void) { static UCHAR hash[] = {0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b}; + static UCHAR hash48[] = + {0x62,0xb2,0x1e,0x90,0xc9,0x02,0x2b,0x10,0x16,0x71,0xba,0x1f,0x80,0x8f,0x86,0x31,0xa8,0x14,0x9f,0x0f, + 0x12,0x90,0x40,0x55,0x83,0x9a,0x35,0xc1,0xca,0x78,0xae,0x53,0x1b,0xb3,0x36,0x06,0xba,0x90,0x89,0x12, + 0xa8,0x42,0x21,0x10,0x9d,0x29,0xcd,0x7e}; BCRYPT_PKCS1_PADDING_INFO pad; + BCRYPT_PSS_PADDING_INFO pad_pss; BCRYPT_ALG_HANDLE alg; BCRYPT_KEY_HANDLE key; BCRYPT_RSAKEY_BLOB *rsablob; - UCHAR sig[64]; + UCHAR sig[256], sig_pss[256]; ULONG len, size, size2, schemes; NTSTATUS ret; BYTE *buf; @@ -2441,7 +2446,7 @@ static void test_RSA(void) ret = BCryptGenerateKeyPair(alg, &key, 1024, 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
- keylen = 512; + keylen = 2048; ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, 2, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret); ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0); @@ -2455,8 +2460,18 @@ static void test_RSA(void)
pad.pszAlgId = BCRYPT_SHA1_ALGORITHM; memset(sig, 0, sizeof(sig)); + len = 0; ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1); ok(!ret, "got %#lx\n", ret); + ok(len == 256, "got %lu\n", len); + + pad_pss.pszAlgId = BCRYPT_SHA384_ALGORITHM; + pad_pss.cbSalt = 48; + memset(sig_pss, 0, sizeof(sig_pss)); + len = 0; + ret = BCryptSignHash(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), &len, BCRYPT_PAD_PSS); + ok(!ret, "got %#lx\n", ret); + ok(len == 256, "got %lu\n", len);
/* export private key */ size = 0; @@ -2469,11 +2484,11 @@ static void test_RSA(void) ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); rsablob = (BCRYPT_RSAKEY_BLOB *)buf; ok(rsablob->Magic == BCRYPT_RSAPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic); - ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength); + ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength); ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp); - ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus); - ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1); - ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2); + ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus); + ok(rsablob->cbPrime1 == 128, "got %lu\n", rsablob->cbPrime1); + ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2); size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus + rsablob->cbPrime1 + rsablob->cbPrime2; ok(size == size2, "got %lu expected %lu\n", size2, size); free(buf); @@ -2488,11 +2503,11 @@ static void test_RSA(void) ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); rsablob = (BCRYPT_RSAKEY_BLOB *)buf; ok(rsablob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC, "got %#lx\n", rsablob->Magic); - ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength); + ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength); ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp); - ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus); - ok(rsablob->cbPrime1 == 32, "got %lu\n", rsablob->cbPrime1); - ok(rsablob->cbPrime2 == 32, "got %lu\n", rsablob->cbPrime2); + ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus); + ok(rsablob->cbPrime1 == 128, "got %lu\n", rsablob->cbPrime1); + ok(rsablob->cbPrime2 == 128, "got %lu\n", rsablob->cbPrime2); size2 = sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus * 2 + rsablob->cbPrime1 * 3 + rsablob->cbPrime2 * 2; ok(size == size2, "got %lu expected %lu\n", size2, size); free(buf); @@ -2508,9 +2523,9 @@ static void test_RSA(void) ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); rsablob = (BCRYPT_RSAKEY_BLOB *)buf; ok(rsablob->Magic == BCRYPT_RSAPUBLIC_MAGIC, "got %#lx\n", rsablob->Magic); - ok(rsablob->BitLength == 512, "got %lu\n", rsablob->BitLength); + ok(rsablob->BitLength == 2048, "got %lu\n", rsablob->BitLength); ok(rsablob->cbPublicExp == 3, "got %lu\n", rsablob->cbPublicExp); - ok(rsablob->cbModulus == 64, "got %lu\n", rsablob->cbModulus); + ok(rsablob->cbModulus == 256, "got %lu\n", rsablob->cbModulus); ok(!rsablob->cbPrime1, "got %lu\n", rsablob->cbPrime1); ok(!rsablob->cbPrime2, "got %lu\n", rsablob->cbPrime2); ok(size == sizeof(*rsablob) + rsablob->cbPublicExp + rsablob->cbModulus, "got %lu\n", size); @@ -2525,7 +2540,9 @@ static void test_RSA(void) ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); free(buf);
- ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, len, BCRYPT_PAD_PKCS1); + ret = BCryptVerifySignature(key, &pad, hash, sizeof(hash), sig, sizeof(sig), BCRYPT_PAD_PKCS1); + ok(!ret, "got %#lx\n", ret); + ret = BCryptVerifySignature(key, &pad_pss, hash48, sizeof(hash48), sig_pss, sizeof(sig_pss), BCRYPT_PAD_PSS); ok(!ret, "got %#lx\n", ret); ret = BCryptDestroyKey(key); ok(!ret, "got %#lx\n", ret); @@ -2561,9 +2578,6 @@ static void test_RSA(void)
ret = BCryptCloseAlgorithmProvider(alg, 0); ok(!ret, "got %#lx\n", ret); - - /* RSA encryption */ - test_rsa_encrypt(); }
static void test_RSA_SIGN(void) @@ -3457,6 +3471,7 @@ START_TEST(bcrypt) test_BcryptDeriveKeyCapi(); test_DSA(); test_SecretAgreement(); + test_rsa_encrypt();
FreeLibrary(module); } diff --git a/include/bcrypt.h b/include/bcrypt.h index 52cb3d21bb3..6822491ed36 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -286,7 +286,14 @@ typedef struct _BCRYPT_PKCS1_PADDING_INFO LPCWSTR pszAlgId; } BCRYPT_PKCS1_PADDING_INFO;
-typedef struct _BCRYPT_OAEP_PADDING_INFO { +typedef struct _BCRYPT_PSS_PADDING_INFO +{ + LPCWSTR pszAlgId; + ULONG cbSalt; +} BCRYPT_PSS_PADDING_INFO; + +typedef struct _BCRYPT_OAEP_PADDING_INFO +{ LPCWSTR pszAlgId; PUCHAR pbLabel; ULONG cbLabel;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=127256
Your paranoid android.
=== debian11 (32 bit report) ===
wmvcore: wmvcore.c:529: Test failed: got wrong thread