Commit ce2ae79f authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

bcrypt: Add support for RSA OAEP padding.

Needs GnuTLS 3.8.4.
parent 1304bf7f
...@@ -241,19 +241,23 @@ struct key_asymmetric_decrypt_params ...@@ -241,19 +241,23 @@ struct key_asymmetric_decrypt_params
struct key *key; struct key *key;
UCHAR *input; UCHAR *input;
unsigned input_len; unsigned input_len;
void *padding;
UCHAR *output; UCHAR *output;
ULONG output_len; ULONG output_len;
ULONG *ret_len; ULONG *ret_len;
ULONG flags;
}; };
struct key_asymmetric_encrypt_params struct key_asymmetric_encrypt_params
{ {
struct key *key; struct key *key;
UCHAR *input; UCHAR *input;
unsigned input_len; unsigned input_len;
void *padding;
UCHAR *output; UCHAR *output;
ULONG output_len; ULONG output_len;
ULONG *ret_len; ULONG *ret_len;
ULONG flags;
}; };
struct key_asymmetric_duplicate_params struct key_asymmetric_duplicate_params
......
...@@ -732,7 +732,7 @@ static NTSTATUS get_rsa_property( enum chain_mode mode, const WCHAR *prop, UCHAR ...@@ -732,7 +732,7 @@ static NTSTATUS get_rsa_property( enum chain_mode mode, const WCHAR *prop, UCHAR
{ {
*ret_size = sizeof(ULONG); *ret_size = sizeof(ULONG);
if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL; if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
if (buf) *(ULONG *)buf = BCRYPT_SUPPORTED_PAD_PKCS1_SIG; if (buf) *(ULONG *)buf = BCRYPT_SUPPORTED_PAD_PKCS1_SIG | BCRYPT_SUPPORTED_PAD_OAEP;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
...@@ -2254,7 +2254,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp ...@@ -2254,7 +2254,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
} }
else else
{ {
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP) if (flags & BCRYPT_PAD_NONE)
{ {
FIXME( "flags %#lx not implemented\n", flags ); FIXME( "flags %#lx not implemented\n", flags );
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
...@@ -2263,10 +2263,12 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp ...@@ -2263,10 +2263,12 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
asymmetric_params.input = input; asymmetric_params.input = input;
asymmetric_params.input_len = input_len; asymmetric_params.input_len = input_len;
asymmetric_params.padding = padding;
asymmetric_params.key = key; asymmetric_params.key = key;
asymmetric_params.output = output; asymmetric_params.output = output;
asymmetric_params.output_len = output_len; asymmetric_params.output_len = output_len;
asymmetric_params.ret_len = ret_len; asymmetric_params.ret_len = ret_len;
asymmetric_params.flags = flags;
ret = UNIX_CALL(key_asymmetric_encrypt, &asymmetric_params); ret = UNIX_CALL(key_asymmetric_encrypt, &asymmetric_params);
} }
...@@ -2299,7 +2301,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp ...@@ -2299,7 +2301,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
} }
else else
{ {
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP) if (flags & BCRYPT_PAD_NONE)
{ {
FIXME( "flags %#lx not implemented\n", flags ); FIXME( "flags %#lx not implemented\n", flags );
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
...@@ -2309,9 +2311,11 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp ...@@ -2309,9 +2311,11 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
params.key = key; params.key = key;
params.input = input; params.input = input;
params.input_len = input_len; params.input_len = input_len;
params.padding = padding;
params.output = output; params.output = output;
params.output_len = output_len; params.output_len = output_len;
params.ret_len = ret_len; params.ret_len = ret_len;
params.flags = flags;
ret = UNIX_CALL(key_asymmetric_decrypt, &params); ret = UNIX_CALL(key_asymmetric_decrypt, &params);
} }
......
...@@ -162,6 +162,9 @@ static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_pa ...@@ -162,6 +162,9 @@ static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_pa
const gnutls_datum_t *); const gnutls_datum_t *);
static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *); static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
/* Not present in gnutls version < 3.8.4 */
static int (*pgnutls_x509_spki_set_rsa_oaep_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, gnutls_datum_t *);
static void *libgnutls_handle; static void *libgnutls_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f #define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(gnutls_cipher_decrypt2); MAKE_FUNCPTR(gnutls_cipher_decrypt2);
...@@ -303,6 +306,12 @@ static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki) ...@@ -303,6 +306,12 @@ static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
{ {
} }
static int compat_gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
gnutls_datum_t *label)
{
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig, static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
unsigned int salt_size) unsigned int salt_size)
{ {
...@@ -444,6 +453,7 @@ static NTSTATUS gnutls_process_attach( void *args ) ...@@ -444,6 +453,7 @@ static NTSTATUS gnutls_process_attach( void *args )
LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2) LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit) LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
LOAD_FUNCPTR_OPT(gnutls_x509_spki_init) LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_oaep_params)
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params) LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
#undef LOAD_FUNCPTR_OPT #undef LOAD_FUNCPTR_OPT
...@@ -2617,6 +2627,27 @@ static NTSTATUS key_asymmetric_duplicate( void *args ) ...@@ -2617,6 +2627,27 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
{
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_oaep_params( spki, dig, label );
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_decrypt( void *args ) static NTSTATUS key_asymmetric_decrypt( void *args )
{ {
const struct key_asymmetric_decrypt_params *params = args; const struct key_asymmetric_decrypt_params *params = args;
...@@ -2624,6 +2655,28 @@ static NTSTATUS key_asymmetric_decrypt( void *args ) ...@@ -2624,6 +2655,28 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
NTSTATUS status = STATUS_SUCCESS; NTSTATUS status = STATUS_SUCCESS;
int ret; int ret;
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
{
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
gnutls_digest_algorithm_t dig;
gnutls_datum_t label;
if (!pad || !pad->pszAlgId)
{
WARN( "padding info not found\n" );
return STATUS_INVALID_PARAMETER;
}
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
{
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
return STATUS_NOT_SUPPORTED;
}
label.data = pad->pbLabel;
label.size = pad->cbLabel;
if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
}
e.data = params->input; e.data = params->input;
e.size = params->input_len; e.size = params->input_len;
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d ))) if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
...@@ -2634,12 +2687,33 @@ static NTSTATUS key_asymmetric_decrypt( void *args ) ...@@ -2634,12 +2687,33 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
*params->ret_len = d.size; *params->ret_len = d.size;
if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len ); if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
else status = STATUS_BUFFER_TOO_SMALL; else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
free( d.data ); free( d.data );
return status; return status;
} }
static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
{
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_oaep_params( spki, dig, label );
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_encrypt( void *args ) static NTSTATUS key_asymmetric_encrypt( void *args )
{ {
const struct key_asymmetric_encrypt_params *params = args; const struct key_asymmetric_encrypt_params *params = args;
...@@ -2649,6 +2723,28 @@ static NTSTATUS key_asymmetric_encrypt( void *args ) ...@@ -2649,6 +2723,28 @@ static NTSTATUS key_asymmetric_encrypt( void *args )
if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE; if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
{
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
gnutls_digest_algorithm_t dig;
gnutls_datum_t label;
if (!pad || !pad->pszAlgId || !pad->pbLabel)
{
WARN( "padding info not found\n" );
return STATUS_INVALID_PARAMETER;
}
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
{
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
return STATUS_NOT_SUPPORTED;
}
label.data = pad->pbLabel;
label.size = pad->cbLabel;
if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
}
d.data = params->input; d.data = params->input;
d.size = params->input_len; d.size = params->input_len;
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e))) if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
...@@ -2751,6 +2847,7 @@ struct key32 ...@@ -2751,6 +2847,7 @@ struct key32
union padding union padding
{ {
BCRYPT_OAEP_PADDING_INFO oaep;
BCRYPT_PKCS1_PADDING_INFO pkcs1; BCRYPT_PKCS1_PADDING_INFO pkcs1;
BCRYPT_PSS_PADDING_INFO pss; BCRYPT_PSS_PADDING_INFO pss;
}; };
...@@ -2760,6 +2857,12 @@ union padding32 ...@@ -2760,6 +2857,12 @@ union padding32
struct struct
{ {
PTR32 pszAlgId; PTR32 pszAlgId;
PTR32 pbLabel;
ULONG cbLabel;
} oaep;
struct
{
PTR32 pszAlgId;
} pkcs1; } pkcs1;
struct struct
{ {
...@@ -2774,13 +2877,21 @@ static union padding *get_padding( union padding32 *padding32, union padding *pa ...@@ -2774,13 +2877,21 @@ static union padding *get_padding( union padding32 *padding32, union padding *pa
switch (flags) switch (flags)
{ {
case BCRYPT_PAD_OAEP:
padding->oaep.pszAlgId = ULongToPtr( padding32->oaep.pszAlgId );
padding->oaep.pbLabel = ULongToPtr( padding32->oaep.pbLabel );
padding->oaep.cbLabel = padding32->oaep.cbLabel;
return padding;
case BCRYPT_PAD_PKCS1: case BCRYPT_PAD_PKCS1:
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId ); padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
return padding; return padding;
case BCRYPT_PAD_PSS: case BCRYPT_PAD_PSS:
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId ); padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
padding->pss.cbSalt = padding32->pss.cbSalt; padding->pss.cbSalt = padding32->pss.cbSalt;
return padding; return padding;
default: default:
break; break;
} }
...@@ -2965,22 +3076,27 @@ static NTSTATUS wow64_key_asymmetric_decrypt( void *args ) ...@@ -2965,22 +3076,27 @@ static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
PTR32 key; PTR32 key;
PTR32 input; PTR32 input;
ULONG input_len; ULONG input_len;
PTR32 padding;
PTR32 output; PTR32 output;
ULONG output_len; ULONG output_len;
PTR32 ret_len; PTR32 ret_len;
ULONG flags;
} const *params32 = args; } const *params32 = args;
NTSTATUS ret; NTSTATUS ret;
struct key key; struct key key;
union padding padding;
struct key32 *key32 = ULongToPtr( params32->key ); struct key32 *key32 = ULongToPtr( params32->key );
struct key_asymmetric_decrypt_params params = struct key_asymmetric_decrypt_params params =
{ {
get_asymmetric_key( key32, &key ), get_asymmetric_key( key32, &key ),
ULongToPtr(params32->input), ULongToPtr(params32->input),
params32->input_len, params32->input_len,
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
ULongToPtr(params32->output), ULongToPtr(params32->output),
params32->output_len, params32->output_len,
ULongToPtr(params32->ret_len) ULongToPtr(params32->ret_len),
params32->flags
}; };
ret = key_asymmetric_decrypt( &params ); ret = key_asymmetric_decrypt( &params );
...@@ -2995,22 +3111,27 @@ static NTSTATUS wow64_key_asymmetric_encrypt( void *args ) ...@@ -2995,22 +3111,27 @@ static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
PTR32 key; PTR32 key;
PTR32 input; PTR32 input;
ULONG input_len; ULONG input_len;
PTR32 padding;
PTR32 output; PTR32 output;
ULONG output_len; ULONG output_len;
PTR32 ret_len; PTR32 ret_len;
ULONG flags;
} const *params32 = args; } const *params32 = args;
NTSTATUS ret; NTSTATUS ret;
struct key key; struct key key;
union padding padding;
struct key32 *key32 = ULongToPtr( params32->key ); struct key32 *key32 = ULongToPtr( params32->key );
struct key_asymmetric_encrypt_params params = struct key_asymmetric_encrypt_params params =
{ {
get_asymmetric_key( key32, &key ), get_asymmetric_key( key32, &key ),
ULongToPtr(params32->input), ULongToPtr(params32->input),
params32->input_len, params32->input_len,
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
ULongToPtr(params32->output), ULongToPtr(params32->output),
params32->output_len, params32->output_len,
ULongToPtr(params32->ret_len) ULongToPtr(params32->ret_len),
params32->flags
}; };
ret = key_asymmetric_encrypt( &params ); ret = key_asymmetric_encrypt( &params );
......
...@@ -2444,20 +2444,16 @@ static const UCHAR rsa_encrypted_no_padding[] = ...@@ -2444,20 +2444,16 @@ static const UCHAR rsa_encrypted_no_padding[] =
static void test_rsa_encrypt(void) static void test_rsa_encrypt(void)
{ {
static UCHAR input[] = "Hello World!"; UCHAR input[] = "Hello World!", input_no_padding[64] = { 0 }, encrypted[64], decrypted[64];
static UCHAR input_no_padding[64] = { 0 }; BCRYPT_ALG_HANDLE rsa;
UCHAR encrypted[64], decrypted[64]; BCRYPT_KEY_HANDLE key, key2;
BCRYPT_ALG_HANDLE rsa = 0; NTSTATUS ret;
BCRYPT_KEY_HANDLE key = 0, key2; DWORD encrypted_size, decrypted_size;
NTSTATUS ret = 0; UCHAR *encrypted_a = NULL, *encrypted_b = NULL;
DWORD encrypted_size = 60;
UCHAR *encrypted_a = NULL;
UCHAR *encrypted_b = NULL;
DWORD decrypted_size = 0;
BCRYPT_OAEP_PADDING_INFO oaep_pad; BCRYPT_OAEP_PADDING_INFO oaep_pad;
oaep_pad.pszAlgId = BCRYPT_MD5_ALGORITHM; oaep_pad.pszAlgId = BCRYPT_SHA256_ALGORITHM;
oaep_pad.pbLabel = (PUCHAR)"test"; oaep_pad.pbLabel = (UCHAR *)"test";
oaep_pad.cbLabel = 5; oaep_pad.cbLabel = 5;
ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0); ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0);
...@@ -2478,10 +2474,11 @@ static void test_rsa_encrypt(void) ...@@ -2478,10 +2474,11 @@ static void test_rsa_encrypt(void)
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0); ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
todo_wine {
/* No padding */ /* No padding */
todo_wine {
memset(input_no_padding, 0, sizeof(input_no_padding)); memset(input_no_padding, 0, sizeof(input_no_padding));
strcpy((char *)input_no_padding, "Hello World"); strcpy((char *)input_no_padding, "Hello World");
encrypted_size = 0;
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE); ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size); ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
...@@ -2496,22 +2493,32 @@ static void test_rsa_encrypt(void) ...@@ -2496,22 +2493,32 @@ static void test_rsa_encrypt(void)
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, 12, &encrypted_size, BCRYPT_PAD_NONE); ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, 12, &encrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE); ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE); ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
}
ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n"); ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n");
ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n"); ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n");
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE); todo_wine {
decrypted_size = 0;
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size); ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE); ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "unexpected output\n");
ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "Decrypted output it's not what expected\n");
} }
encrypted_size = 60;
/* PKCS1 Padding */ /* PKCS1 Padding */
encrypted_size = 0;
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_PKCS1); ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size); ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
...@@ -2523,21 +2530,53 @@ static void test_rsa_encrypt(void) ...@@ -2523,21 +2530,53 @@ static void test_rsa_encrypt(void)
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1); ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1); ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n"); ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1); decrypted_size = 0;
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size); ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
todo_wine { ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
encrypted_size = 60; ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2, (UCHAR *)&rsaLegacyPrivateBlob,
sizeof(rsaLegacyPrivateBlob), 0);
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0, encrypted, sizeof(encrypted),
&encrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
memset(decrypted, 0, sizeof(decrypted));
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0, decrypted, sizeof(decrypted),
&decrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
BCryptDestroyKey(key2);
BCryptDestroyKey(key);
/* OAEP Padding */ /* OAEP Padding */
ret = BCryptGenerateKeyPair(rsa, &key, 640 /* minimum size for sha256 hash */, 0);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ret = BCryptFinalizeKeyPair(key, 0);
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
todo_wine {
encrypted_size = 0;
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP); ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size); ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
encrypted_a = realloc(encrypted_a, encrypted_size); encrypted_a = realloc(encrypted_a, encrypted_size);
memset(encrypted_a, 0, encrypted_size); memset(encrypted_a, 0, encrypted_size);
...@@ -2546,38 +2585,28 @@ static void test_rsa_encrypt(void) ...@@ -2546,38 +2585,28 @@ static void test_rsa_encrypt(void)
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP); ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP); ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret); ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n"); ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
decrypted_size = 0; decrypted_size = 0;
memset(decrypted, 0, sizeof(decrypted)); memset(decrypted, 0, sizeof(decrypted));
BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP); ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size); ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP); ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
} }
free(encrypted_a); free(encrypted_a);
free(encrypted_b); free(encrypted_b);
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2,
(UCHAR *)&rsaLegacyPrivateBlob, sizeof(rsaLegacyPrivateBlob), 0);
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0,
encrypted, sizeof(encrypted), &encrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
memset(decrypted, 0, sizeof(decrypted));
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0,
decrypted, sizeof(decrypted), &decrypted_size, BCRYPT_PAD_PKCS1);
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
BCryptDestroyKey(key2);
BCryptDestroyKey(key); BCryptDestroyKey(key);
if (pBCryptHash) if (pBCryptHash)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment