From: Hans Leidekker hans@codeweavers.com
--- dlls/bcrypt/bcrypt_main.c | 18 +++++++- dlls/bcrypt/gnutls.c | 88 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index a4eacd4a993..19d25c8a20b 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1780,6 +1780,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP { BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input; DWORD bitlen, magic; + enum ecc_curve_id curve;
if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
@@ -1787,31 +1788,37 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP { case ALG_ID_ECDH_P256: bitlen = 256; + curve = ECC_CURVE_P256R1; magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC; break;
case ALG_ID_ECDH_P384: bitlen = 384; + curve = ECC_CURVE_P384R1; magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC; break;
case ALG_ID_ECDH_P521: bitlen = 521; + curve = ECC_CURVE_P521R1; magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC; break;
case ALG_ID_ECDSA_P256: bitlen = 256; + curve = ECC_CURVE_P256R1; magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; break;
case ALG_ID_ECDSA_P384: bitlen = 384; + curve = ECC_CURVE_P384R1; magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC; break;
case ALG_ID_ECDSA_P521: bitlen = 521; + curve = ECC_CURVE_P521R1; magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC; break;
@@ -1824,7 +1831,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP if (ecc_blob->cbKey != len_from_bitlen( bitlen ) || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2) return STATUS_INVALID_PARAMETER;
- if ((status = key_asymmetric_create( alg->id, 0, bitlen, &key ))) return status; + if ((status = key_asymmetric_create( alg->id, curve, bitlen, &key ))) return status; params.key = key; params.flags = KEY_IMPORT_FLAG_PUBLIC; params.buf = input; @@ -1839,6 +1846,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP { BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input; DWORD bitlen, magic; + enum ecc_curve_id curve;
if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
@@ -1846,31 +1854,37 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP { case ALG_ID_ECDH_P256: bitlen = 256; + curve = ECC_CURVE_P256R1; magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC; break;
case ALG_ID_ECDH_P384: bitlen = 384; + curve = ECC_CURVE_P384R1; magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC; break;
case ALG_ID_ECDH_P521: bitlen = 521; + curve = ECC_CURVE_P521R1; magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC; break;
case ALG_ID_ECDSA_P256: bitlen = 256; + curve = ECC_CURVE_P256R1; magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC; break;
case ALG_ID_ECDSA_P384: bitlen = 384; + curve = ECC_CURVE_P384R1; magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC; break;
case ALG_ID_ECDSA_P521: bitlen = 521; + curve = ECC_CURVE_P521R1; magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC; break;
@@ -1883,7 +1897,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP if (ecc_blob->cbKey != len_from_bitlen( bitlen ) || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3) return STATUS_INVALID_PARAMETER;
- if ((status = key_asymmetric_create( alg->id, 0, bitlen, &key ))) return status; + if ((status = key_asymmetric_create( alg->id, curve, bitlen, &key ))) return status; params.key = key; params.flags = 0; params.buf = input; diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 49b7b8f1378..4ff8cff280f 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -825,6 +825,26 @@ static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, U
switch (key->alg_id) { + case ALG_ID_ECDH: + switch (key->u.a.curve_id) + { + case ECC_CURVE_P256R1: + magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC; + size = 32; + break; + case ECC_CURVE_P384R1: + magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC; + size = 48; + break; + case ECC_CURVE_P521R1: + magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC; + size = 66; + break; + default: + FIXME( "unsupported curve %u\n", key->u.a.curve_id ); + return STATUS_NOT_IMPLEMENTED; + } + case ALG_ID_ECDH_P256: magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC; size = 32; @@ -840,6 +860,26 @@ static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, U size = 66; break;
+ case ALG_ID_ECDSA: + switch (key->u.a.curve_id) + { + case ECC_CURVE_P256R1: + magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; + size = 32; + break; + case ECC_CURVE_P384R1: + magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC; + size = 48; + break; + case ECC_CURVE_P521R1: + magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC; + size = 66; + break; + default: + FIXME( "unsupported curve %u\n", key->u.a.curve_id ); + return STATUS_NOT_IMPLEMENTED; + } + case ALG_ID_ECDSA_P256: magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; size = 32; @@ -1212,6 +1252,26 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r
switch (key->alg_id) { + case ALG_ID_ECDH: + switch (key->u.a.curve_id) + { + case ECC_CURVE_P256R1: + magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC; + size = 32; + break; + case ECC_CURVE_P384R1: + magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC; + size = 48; + break; + case ECC_CURVE_P521R1: + magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC; + size = 66; + break; + default: + FIXME( "unsupported curve %u\n", key->u.a.curve_id ); + return STATUS_NOT_IMPLEMENTED; + } + case ALG_ID_ECDH_P256: magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC; size = 32; @@ -1227,6 +1287,26 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r size = 66; break;
+ case ALG_ID_ECDSA: + switch (key->u.a.curve_id) + { + case ECC_CURVE_P256R1: + magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC; + size = 32; + break; + case ECC_CURVE_P384R1: + magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC; + size = 48; + break; + case ECC_CURVE_P521R1: + magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC; + size = 66; + break; + default: + FIXME( "unsupported curve %u\n", key->u.a.curve_id ); + return STATUS_NOT_IMPLEMENTED; + } + case ALG_ID_ECDSA_P256: magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC; size = 32; @@ -1860,9 +1940,11 @@ static NTSTATUS key_asymmetric_export( void *args )
switch (key->alg_id) { + case ALG_ID_ECDH: case ALG_ID_ECDH_P256: case ALG_ID_ECDH_P384: case ALG_ID_ECDH_P521: + case ALG_ID_ECDSA: case ALG_ID_ECDSA_P256: case ALG_ID_ECDSA_P384: case ALG_ID_ECDSA_P521: @@ -2048,9 +2130,11 @@ static NTSTATUS key_asymmetric_import( void *args )
switch (key->alg_id) { + case ALG_ID_ECDH: case ALG_ID_ECDH_P256: case ALG_ID_ECDH_P384: case ALG_ID_ECDH_P521: + case ALG_ID_ECDSA: case ALG_ID_ECDSA_P256: case ALG_ID_ECDSA_P384: case ALG_ID_ECDSA_P521: @@ -2558,9 +2642,11 @@ static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy ) if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed; break; } + case ALG_ID_ECDH: case ALG_ID_ECDH_P256: case ALG_ID_ECDH_P384: case ALG_ID_ECDH_P521: + case ALG_ID_ECDSA: case ALG_ID_ECDSA_P256: case ALG_ID_ECDSA_P384: case ALG_ID_ECDSA_P521: @@ -2639,9 +2725,11 @@ static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy ) if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed; break; } + case ALG_ID_ECDH: case ALG_ID_ECDH_P256: case ALG_ID_ECDH_P384: case ALG_ID_ECDH_P521: + case ALG_ID_ECDSA: case ALG_ID_ECDSA_P256: case ALG_ID_ECDSA_P384: case ALG_ID_ECDSA_P521: