bcrypt: Add support for RSA OAEP padding.
Needs GnuTLS 3.8.4.
This commit is contained in:
parent
1304bf7fb9
commit
ce2ae79f9d
4 changed files with 210 additions and 52 deletions
|
@ -241,19 +241,23 @@ struct key_asymmetric_decrypt_params
|
|||
struct key *key;
|
||||
UCHAR *input;
|
||||
unsigned input_len;
|
||||
void *padding;
|
||||
UCHAR *output;
|
||||
ULONG output_len;
|
||||
ULONG *ret_len;
|
||||
ULONG flags;
|
||||
};
|
||||
|
||||
struct key_asymmetric_encrypt_params
|
||||
{
|
||||
struct key *key;
|
||||
UCHAR *input;
|
||||
unsigned input_len;
|
||||
unsigned input_len;
|
||||
void *padding;
|
||||
UCHAR *output;
|
||||
ULONG output_len;
|
||||
ULONG output_len;
|
||||
ULONG *ret_len;
|
||||
ULONG flags;
|
||||
};
|
||||
|
||||
struct key_asymmetric_duplicate_params
|
||||
|
|
|
@ -732,7 +732,7 @@ static NTSTATUS get_rsa_property( enum chain_mode mode, const WCHAR *prop, UCHAR
|
|||
{
|
||||
*ret_size = sizeof(ULONG);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2254,7 +2254,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP)
|
||||
if (flags & BCRYPT_PAD_NONE)
|
||||
{
|
||||
FIXME( "flags %#lx not implemented\n", flags );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -2263,10 +2263,12 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
|
||||
asymmetric_params.input = input;
|
||||
asymmetric_params.input_len = input_len;
|
||||
asymmetric_params.padding = padding;
|
||||
asymmetric_params.key = key;
|
||||
asymmetric_params.output = output;
|
||||
asymmetric_params.output_len = output_len;
|
||||
asymmetric_params.ret_len = ret_len;
|
||||
asymmetric_params.flags = flags;
|
||||
ret = UNIX_CALL(key_asymmetric_encrypt, &asymmetric_params);
|
||||
}
|
||||
|
||||
|
@ -2299,7 +2301,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP)
|
||||
if (flags & BCRYPT_PAD_NONE)
|
||||
{
|
||||
FIXME( "flags %#lx not implemented\n", flags );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -2309,9 +2311,11 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
params.key = key;
|
||||
params.input = input;
|
||||
params.input_len = input_len;
|
||||
params.padding = padding;
|
||||
params.output = output;
|
||||
params.output_len = output_len;
|
||||
params.ret_len = ret_len;
|
||||
params.flags = flags;
|
||||
ret = UNIX_CALL(key_asymmetric_decrypt, ¶ms);
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,9 @@ static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_pa
|
|||
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;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
|
||||
|
@ -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,
|
||||
unsigned int salt_size)
|
||||
{
|
||||
|
@ -444,6 +453,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
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_oaep_params)
|
||||
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
|
||||
|
||||
#undef LOAD_FUNCPTR_OPT
|
||||
|
@ -2617,6 +2627,27 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
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 )
|
||||
{
|
||||
const struct key_asymmetric_decrypt_params *params = args;
|
||||
|
@ -2624,6 +2655,28 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
|
|||
NTSTATUS status = STATUS_SUCCESS;
|
||||
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.size = params->input_len;
|
||||
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 )
|
|||
|
||||
*params->ret_len = d.size;
|
||||
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 );
|
||||
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 )
|
||||
{
|
||||
const struct key_asymmetric_encrypt_params *params = args;
|
||||
|
@ -2649,6 +2723,28 @@ static NTSTATUS key_asymmetric_encrypt( void *args )
|
|||
|
||||
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.size = params->input_len;
|
||||
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
|
||||
|
@ -2751,12 +2847,19 @@ struct key32
|
|||
|
||||
union padding
|
||||
{
|
||||
BCRYPT_OAEP_PADDING_INFO oaep;
|
||||
BCRYPT_PKCS1_PADDING_INFO pkcs1;
|
||||
BCRYPT_PSS_PADDING_INFO pss;
|
||||
};
|
||||
|
||||
union padding32
|
||||
{
|
||||
struct
|
||||
{
|
||||
PTR32 pszAlgId;
|
||||
PTR32 pbLabel;
|
||||
ULONG cbLabel;
|
||||
} oaep;
|
||||
struct
|
||||
{
|
||||
PTR32 pszAlgId;
|
||||
|
@ -2774,13 +2877,21 @@ static union padding *get_padding( union padding32 *padding32, union padding *pa
|
|||
|
||||
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:
|
||||
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
|
||||
return padding;
|
||||
|
||||
case BCRYPT_PAD_PSS:
|
||||
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
|
||||
padding->pss.cbSalt = padding32->pss.cbSalt;
|
||||
return padding;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2965,22 +3076,27 @@ static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
|
|||
PTR32 key;
|
||||
PTR32 input;
|
||||
ULONG input_len;
|
||||
PTR32 padding;
|
||||
PTR32 output;
|
||||
ULONG output_len;
|
||||
PTR32 ret_len;
|
||||
ULONG flags;
|
||||
} const *params32 = args;
|
||||
|
||||
NTSTATUS ret;
|
||||
struct key key;
|
||||
union padding padding;
|
||||
struct key32 *key32 = ULongToPtr( params32->key );
|
||||
struct key_asymmetric_decrypt_params params =
|
||||
{
|
||||
get_asymmetric_key( key32, &key ),
|
||||
ULongToPtr(params32->input),
|
||||
params32->input_len,
|
||||
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
|
||||
ULongToPtr(params32->output),
|
||||
params32->output_len,
|
||||
ULongToPtr(params32->ret_len)
|
||||
ULongToPtr(params32->ret_len),
|
||||
params32->flags
|
||||
};
|
||||
|
||||
ret = key_asymmetric_decrypt( ¶ms );
|
||||
|
@ -2995,22 +3111,27 @@ static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
|
|||
PTR32 key;
|
||||
PTR32 input;
|
||||
ULONG input_len;
|
||||
PTR32 padding;
|
||||
PTR32 output;
|
||||
ULONG output_len;
|
||||
PTR32 ret_len;
|
||||
ULONG flags;
|
||||
} const *params32 = args;
|
||||
|
||||
NTSTATUS ret;
|
||||
struct key key;
|
||||
union padding padding;
|
||||
struct key32 *key32 = ULongToPtr( params32->key );
|
||||
struct key_asymmetric_encrypt_params params =
|
||||
{
|
||||
get_asymmetric_key( key32, &key ),
|
||||
ULongToPtr(params32->input),
|
||||
params32->input_len,
|
||||
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
|
||||
ULongToPtr(params32->output),
|
||||
params32->output_len,
|
||||
ULongToPtr(params32->ret_len)
|
||||
ULongToPtr(params32->ret_len),
|
||||
params32->flags
|
||||
};
|
||||
|
||||
ret = key_asymmetric_encrypt( ¶ms );
|
||||
|
|
|
@ -2444,20 +2444,16 @@ static const UCHAR rsa_encrypted_no_padding[] =
|
|||
|
||||
static void test_rsa_encrypt(void)
|
||||
{
|
||||
static UCHAR input[] = "Hello World!";
|
||||
static UCHAR input_no_padding[64] = { 0 };
|
||||
UCHAR encrypted[64], decrypted[64];
|
||||
BCRYPT_ALG_HANDLE rsa = 0;
|
||||
BCRYPT_KEY_HANDLE key = 0, key2;
|
||||
NTSTATUS ret = 0;
|
||||
DWORD encrypted_size = 60;
|
||||
UCHAR *encrypted_a = NULL;
|
||||
UCHAR *encrypted_b = NULL;
|
||||
DWORD decrypted_size = 0;
|
||||
UCHAR input[] = "Hello World!", input_no_padding[64] = { 0 }, encrypted[64], decrypted[64];
|
||||
BCRYPT_ALG_HANDLE rsa;
|
||||
BCRYPT_KEY_HANDLE key, key2;
|
||||
NTSTATUS ret;
|
||||
DWORD encrypted_size, decrypted_size;
|
||||
UCHAR *encrypted_a = NULL, *encrypted_b = NULL;
|
||||
BCRYPT_OAEP_PADDING_INFO oaep_pad;
|
||||
|
||||
oaep_pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
|
||||
oaep_pad.pbLabel = (PUCHAR)"test";
|
||||
oaep_pad.pszAlgId = BCRYPT_SHA256_ALGORITHM;
|
||||
oaep_pad.pbLabel = (UCHAR *)"test";
|
||||
oaep_pad.cbLabel = 5;
|
||||
|
||||
ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0);
|
||||
|
@ -2478,10 +2474,11 @@ static void test_rsa_encrypt(void)
|
|||
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
|
||||
|
||||
todo_wine {
|
||||
/* No padding */
|
||||
todo_wine {
|
||||
memset(input_no_padding, 0, sizeof(input_no_padding));
|
||||
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);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
@ -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);
|
||||
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);
|
||||
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);
|
||||
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_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);
|
||||
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)), "Decrypted output it's not what expected\n");
|
||||
|
||||
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(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "unexpected output\n");
|
||||
}
|
||||
|
||||
encrypted_size = 60;
|
||||
/* PKCS1 Padding */
|
||||
encrypted_size = 0;
|
||||
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(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
@ -2523,22 +2530,54 @@ static void test_rsa_encrypt(void)
|
|||
|
||||
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(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);
|
||||
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");
|
||||
|
||||
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);
|
||||
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 {
|
||||
encrypted_size = 60;
|
||||
/* OAEP Padding */
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &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");
|
||||
|
||||
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 */
|
||||
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);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
|
||||
|
||||
encrypted_a = realloc(encrypted_a, encrypted_size);
|
||||
memset(encrypted_a, 0, encrypted_size);
|
||||
encrypted_b = realloc(encrypted_b, encrypted_size);
|
||||
|
@ -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);
|
||||
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);
|
||||
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");
|
||||
|
||||
decrypted_size = 0;
|
||||
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);
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
|
||||
|
||||
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(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
|
||||
}
|
||||
|
||||
free(encrypted_a);
|
||||
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);
|
||||
|
||||
if (pBCryptHash)
|
||||
|
|
Loading…
Add table
Reference in a new issue