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

bcrypt: Add support for BCRYPT_DSA_ALGORITHM.

parent d1ae4a56
......@@ -137,6 +137,7 @@ enum alg_id
ALG_ID_RSA_SIGN,
ALG_ID_ECDSA_P256,
ALG_ID_ECDSA_P384,
ALG_ID_DSA,
/* rng */
ALG_ID_RNG,
......
......@@ -118,6 +118,7 @@ builtin_algorithms[] =
{ BCRYPT_RSA_SIGN_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 },
{ BCRYPT_ECDSA_P256_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 },
{ BCRYPT_ECDSA_P384_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 },
{ BCRYPT_DSA_ALGORITHM, BCRYPT_SIGNATURE_INTERFACE, 0, 0, 0 },
{ BCRYPT_RNG_ALGORITHM, BCRYPT_RNG_INTERFACE, 0, 0, 0 },
};
......@@ -541,6 +542,13 @@ static NTSTATUS get_rsa_property( enum mode_id mode, const WCHAR *prop, UCHAR *b
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS get_dsa_property( enum mode_id mode, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
{
if (!strcmpW( prop, BCRYPT_PADDING_SCHEMES )) return STATUS_NOT_SUPPORTED;
FIXME( "unsupported property %s\n", debugstr_w(prop) );
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size )
{
NTSTATUS status;
......@@ -557,11 +565,14 @@ NTSTATUS get_alg_property( const struct algorithm *alg, const WCHAR *prop, UCHAR
case ALG_ID_RSA:
return get_rsa_property( alg->mode, prop, buf, size, ret_size );
case ALG_ID_DSA:
return get_dsa_property( alg->mode, prop, buf, size, ret_size );
default:
break;
}
FIXME( "unsupported property %s\n", debugstr_w(prop) );
FIXME( "unsupported property %s algorithm %u\n", debugstr_w(prop), alg->id );
return STATUS_NOT_IMPLEMENTED;
}
......@@ -924,15 +935,8 @@ static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, U
memcpy( output + sizeof(len), key->u.s.secret, key->u.s.secret_len );
return STATUS_SUCCESS;
}
else if (!strcmpW( type, BCRYPT_RSAPUBLIC_BLOB ))
{
*size = key->u.a.pubkey_len;
if (output_len < key->u.a.pubkey_len) return STATUS_SUCCESS;
memcpy( output, key->u.a.pubkey, key->u.a.pubkey_len );
return STATUS_SUCCESS;
}
else if (!strcmpW( type, BCRYPT_ECCPUBLIC_BLOB ))
else if (!strcmpW( type, BCRYPT_RSAPUBLIC_BLOB ) || !strcmpW( type, BCRYPT_DSA_PUBLIC_BLOB ) ||
!strcmpW( type, BCRYPT_ECCPUBLIC_BLOB ))
{
*size = key->u.a.pubkey_len;
if (output_len < key->u.a.pubkey_len) return STATUS_SUCCESS;
......@@ -1241,6 +1245,28 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
*ret_key = key;
return STATUS_SUCCESS;
}
else if (!strcmpW( type, BCRYPT_DSA_PUBLIC_BLOB ))
{
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
ULONG size;
if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
return STATUS_NOT_SUPPORTED;
if (!(key = heap_alloc_zero( sizeof(*key) ))) return STATUS_NO_MEMORY;
key->hdr.magic = MAGIC_KEY;
size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
if ((status = key_asymmetric_init( key, alg, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size )))
{
heap_free( key );
return status;
}
*ret_key = key;
return STATUS_SUCCESS;
}
FIXME( "unsupported key type %s\n", debugstr_w(type) );
return STATUS_NOT_SUPPORTED;
......
......@@ -2422,6 +2422,101 @@ static void test_BcryptDeriveKeyCapi(void)
ok(!ret, "got %08x\n", ret);
}
static UCHAR dsaHash[] =
{
0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b
};
static UCHAR dsaSignature[] =
{
0x5f,0x95,0x1f,0x08,0x19,0x44,0xa5,0xab,0x28,0x11,0x51,0x68,0x82,0x9b,0xe4,0xc3,0x04,0x1b,0xc9,0xdc,
0x41,0x2a,0x89,0xd4,0x4a,0x8b,0x86,0xaf,0x98,0x2c,0x59,0x0b,0xd2,0x88,0xf6,0xe8,0x29,0x13,0x84,0x49
};
static UCHAR dsaPublicBlob[] =
{
0x44,0x53,0x50,0x42,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xd2,0x92,0xbb,0x92,0xb9,0x00,0xc5,0xed,
0x52,0xcc,0x48,0x4a,0x44,0x1d,0xd3,0x74,0xfb,0x75,0xd1,0x7e,0xb6,0x24,0x9b,0x5d,0x57,0x0a,0x8a,0xc4,
0x5d,0xab,0x9c,0x26,0x86,0xc6,0x25,0x16,0x20,0xf9,0xa9,0x71,0xbc,0x1d,0x30,0xc4,0xef,0x8c,0xc4,0xdf,
0x1a,0xaf,0x96,0xdf,0x90,0xd8,0x85,0x9d,0xf9,0x2c,0x86,0x8c,0x91,0x39,0x6c,0x6d,0x11,0x4e,0x53,0x63,
0x2a,0x2b,0x26,0xa7,0xf9,0x76,0x74,0x51,0xbf,0x08,0x87,0x6f,0xe0,0x71,0x91,0x24,0x8a,0xc2,0x84,0x2d,
0x84,0x9c,0x5f,0x94,0xaa,0x38,0x53,0x77,0x84,0xba,0xbc,0xff,0x49,0x3a,0x08,0x0f,0x38,0xb5,0x91,0x5c,
0x06,0x15,0xa4,0x27,0xf4,0xa5,0x59,0xaa,0x1c,0x41,0xa3,0xa0,0xbb,0xf7,0x32,0x86,0xfb,0x94,0x41,0xff,
0xcd,0xed,0x69,0xeb,0xc6,0x5e,0xb6,0xa8,0x15,0x82,0x3b,0x60,0x1e,0x91,0x55,0xd5,0x2c,0xa5,0x74,0x5a,
0x65,0x8f,0xc6,0x56,0xc4,0x3f,0x4e,0xe3,0x3a,0x71,0xb2,0x63,0x66,0xa4,0x0d,0x0d,0xf9,0xdd,0x1e,0x48,
0x81,0xe9,0xbf,0x8f,0xbb,0x85,0x47,0x81,0x68,0x11,0xb5,0x91,0x6b,0xc4,0x05,0xef,0xa3,0xc7,0xbf,0x26,
0x53,0x4f,0xc4,0x10,0xfd,0xfa,0xed,0x61,0x64,0xd6,0x2e,0xad,0x04,0x3e,0x82,0xed,0xb2,0x22,0x76,0xd0,
0x44,0xad,0xc1,0x4c,0xde,0x33,0xa3,0x61,0x55,0xec,0x24,0xe5,0x79,0x45,0xcf,0x94,0x39,0x92,0x9f,0xd8,
0x24,0xce,0x85,0xb9
};
static void test_DSA(void)
{
BCRYPT_ALG_HANDLE alg;
BCRYPT_KEY_HANDLE key;
BCRYPT_DSA_KEY_BLOB *dsablob;
UCHAR sig[40], schemes;
ULONG len, size;
NTSTATUS ret;
BYTE *buf;
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_DSA_ALGORITHM, NULL, 0);
ok(!ret, "got %08x\n", ret);
ret = pBCryptGetProperty(alg, L"PaddingSchemes", (UCHAR *)&schemes, sizeof(schemes), &size, 0);
ok(ret == STATUS_NOT_SUPPORTED, "got %08x\n", ret);
ret = pBCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, dsaPublicBlob, sizeof(dsaPublicBlob), 0);
ok(!ret, "got %08x\n", ret);
ret = pBCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), dsaSignature, sizeof(dsaSignature), 0);
ok(!ret, "got %08x\n", ret);
ret = pBCryptDestroyKey(key);
ok(!ret, "got %08x\n", ret);
/* sign/verify with export/import round-trip */
ret = pBCryptGenerateKeyPair(alg, &key, 512, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ret = pBCryptFinalizeKeyPair(key, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
len = 0;
memset(sig, 0, sizeof(sig));
ret = pBCryptSignHash(key, NULL, dsaHash, sizeof(dsaHash), sig, sizeof(sig), &len, 0);
ok(!ret, "got %08x\n", ret);
ok(len == 40, "got %u\n", len);
size = 0;
ret = pBCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, NULL, 0, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(size, "size not set\n");
buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
ret = pBCryptExportKey(key, NULL, BCRYPT_DSA_PUBLIC_BLOB, buf, size, &size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
dsablob = (BCRYPT_DSA_KEY_BLOB *)buf;
ok(dsablob->dwMagic == BCRYPT_DSA_PUBLIC_MAGIC, "got %08x\n", dsablob->dwMagic);
ok(dsablob->cbKey == 64, "got %u\n", dsablob->cbKey);
ok(size == sizeof(*dsablob) + dsablob->cbKey * 3, "got %u\n", size);
ret = pBCryptDestroyKey(key);
ok(!ret, "got %08x\n", ret);
ret = pBCryptImportKeyPair(alg, NULL, BCRYPT_DSA_PUBLIC_BLOB, &key, buf, size, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
HeapFree(GetProcessHeap(), 0, buf);
ret = pBCryptVerifySignature(key, NULL, dsaHash, sizeof(dsaHash), sig, len, 0);
ok(!ret, "got %08x\n", ret);
ret = pBCryptDestroyKey(key);
ok(!ret, "got %08x\n", ret);
ret = pBCryptCloseAlgorithmProvider(alg, 0);
ok(!ret, "got %08x\n", ret);
}
START_TEST(bcrypt)
{
HMODULE module;
......@@ -2486,6 +2581,7 @@ START_TEST(bcrypt)
test_BCryptEnumAlgorithms();
test_aes_vector();
test_BcryptDeriveKeyCapi();
test_DSA();
FreeLibrary(module);
}
......@@ -66,14 +66,25 @@ typedef LONG NTSTATUS;
#define BCRYPT_ECCPRIVATE_BLOB L"ECCPRIVATEBLOB"
#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB"
#define BCRYPT_RSAPRIVATE_BLOB L"RSAPRIVATEBLOB"
#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB"
#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB"
#define MS_PRIMITIVE_PROVIDER L"Microsoft Primitive Provider"
#define MS_PLATFORM_CRYPTO_PROVIDER L"Microsoft Platform Crypto Provider"
#define BCRYPT_3DES_ALGORITHM L"3DES"
#define BCRYPT_AES_ALGORITHM L"AES"
#define BCRYPT_DES_ALGORITHM L"DES"
#define BCRYPT_DSA_ALGORITHM L"DSA"
#define BCRYPT_ECDH_P256_ALGORITHM L"ECDH_P256"
#define BCRYPT_ECDSA_P256_ALGORITHM L"ECDSA_P256"
#define BCRYPT_ECDSA_P384_ALGORITHM L"ECDSA_P384"
#define BCRYPT_ECDSA_P521_ALGORITHM L"ECDSA_P521"
#define BCRYPT_MD2_ALGORITHM L"MD2"
#define BCRYPT_MD4_ALGORITHM L"MD4"
#define BCRYPT_MD5_ALGORITHM L"MD5"
#define BCRYPT_RC2_ALGORITHM L"RC2"
#define BCRYPT_RC4_ALGORITHM L"RC4"
#define BCRYPT_RNG_ALGORITHM L"RNG"
#define BCRYPT_RSA_ALGORITHM L"RSA"
#define BCRYPT_RSA_SIGN_ALGORITHM L"RSA_SIGN"
......@@ -81,10 +92,6 @@ typedef LONG NTSTATUS;
#define BCRYPT_SHA256_ALGORITHM L"SHA256"
#define BCRYPT_SHA384_ALGORITHM L"SHA384"
#define BCRYPT_SHA512_ALGORITHM L"SHA512"
#define BCRYPT_ECDH_P256_ALGORITHM L"ECDH_P256"
#define BCRYPT_ECDSA_P256_ALGORITHM L"ECDSA_P256"
#define BCRYPT_ECDSA_P384_ALGORITHM L"ECDSA_P384"
#define BCRYPT_ECDSA_P521_ALGORITHM L"ECDSA_P521"
#define BCRYPT_CHAIN_MODE_NA L"ChainingModeN/A"
#define BCRYPT_CHAIN_MODE_CBC L"ChainingModeCBC"
......@@ -124,16 +131,27 @@ static const WCHAR BCRYPT_ECCPUBLIC_BLOB[] = {'E','C','C','P','U','B','L','I','C
static const WCHAR BCRYPT_ECCPRIVATE_BLOB[] = {'E','C','C','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPUBLIC_BLOB[] = {'R','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPRIVATE_BLOB[] = {'R','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PUBLIC_BLOB[] = {'D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PRIVATE_BLOB[] = {'D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR MS_PRIMITIVE_PROVIDER[] = \
{'M','i','c','r','o','s','o','f','t',' ','P','r','i','m','i','t','i','v','e',' ','P','r','o','v','i','d','e','r',0};
static const WCHAR MS_PLATFORM_CRYPTO_PROVIDER[] = \
{'M','i','c','r','o','s','o','f','t',' ','P','l','a','t','f','o','r','m',' ','C','r','y','p','t','o',' ','P','r','o','v','i','d','e','r',0};
static const WCHAR BCRYPT_3DES_ALGORITHM[] = {'3','D','E','S',0};
static const WCHAR BCRYPT_AES_ALGORITHM[] = {'A','E','S',0};
static const WCHAR BCRYPT_DES_ALGORITHM[] = {'D','E','S',0};
static const WCHAR BCRYPT_DSA_ALGORITHM[] = {'D','S','A',0};
static const WCHAR BCRYPT_ECDH_P256_ALGORITHM[] = {'E','C','D','H','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDSA_P256_ALGORITHM[] = {'E','C','D','S','A','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDSA_P384_ALGORITHM[] = {'E','C','D','S','A','_','P','3','8','4',0};
static const WCHAR BCRYPT_ECDSA_P521_ALGORITHM[] = {'E','C','D','S','A','_','P','5','2','1',0};
static const WCHAR BCRYPT_MD2_ALGORITHM[] = {'M','D','2',0};
static const WCHAR BCRYPT_MD4_ALGORITHM[] = {'M','D','4',0};
static const WCHAR BCRYPT_MD5_ALGORITHM[] = {'M','D','5',0};
static const WCHAR BCRYPT_RC2_ALGORITHM[] = {'R','C','2',0};
static const WCHAR BCRYPT_RC4_ALGORITHM[] = {'R','C','4',0};
static const WCHAR BCRYPT_RNG_ALGORITHM[] = {'R','N','G',0};
static const WCHAR BCRYPT_RSA_ALGORITHM[] = {'R','S','A',0};
static const WCHAR BCRYPT_RSA_SIGN_ALGORITHM[] = {'R','S','A','_','S','I','G','N',0};
......@@ -141,10 +159,6 @@ static const WCHAR BCRYPT_SHA1_ALGORITHM[] = {'S','H','A','1',0};
static const WCHAR BCRYPT_SHA256_ALGORITHM[] = {'S','H','A','2','5','6',0};
static const WCHAR BCRYPT_SHA384_ALGORITHM[] = {'S','H','A','3','8','4',0};
static const WCHAR BCRYPT_SHA512_ALGORITHM[] = {'S','H','A','5','1','2',0};
static const WCHAR BCRYPT_ECDH_P256_ALGORITHM[] = {'E','C','D','H','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDSA_P256_ALGORITHM[] = {'E','C','D','S','A','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDSA_P384_ALGORITHM[] = {'E','C','D','S','A','_','P','3','8','4',0};
static const WCHAR BCRYPT_ECDSA_P521_ALGORITHM[] = {'E','C','D','S','A','_','P','5','2','1',0};
static const WCHAR BCRYPT_CHAIN_MODE_NA[] = {'C','h','a','i','n','i','n','g','M','o','d','e','N','/','A',0};
static const WCHAR BCRYPT_CHAIN_MODE_CBC[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','B','C',0};
......@@ -257,6 +271,45 @@ typedef struct _BCRYPT_PKCS1_PADDING_INFO
#define BCRYPT_PAD_PSS 0x00000008
#define BCRYPT_PAD_PKCS1_OPTIONAL_HASH_OID 0x00000010
#define BCRYPT_DSA_PUBLIC_MAGIC 0x42505344
#define BCRYPT_DSA_PRIVATE_MAGIC 0x56505344
typedef struct _BCRYPT_DSA_KEY_BLOB
{
ULONG dwMagic;
ULONG cbKey;
UCHAR Count[4];
UCHAR Seed[20];
UCHAR q[20];
} BCRYPT_DSA_KEY_BLOB, *PBCRYPT_DSA_KEY_BLOB;
#define BCRYPT_DSA_PUBLIC_MAGIC_V2 0x32425044
#define BCRYPT_DSA_PRIVATE_MAGIC_V2 0x32565044
typedef enum
{
DSA_HASH_ALGORITHM_SHA1,
DSA_HASH_ALGORITHM_SHA256,
DSA_HASH_ALGORITHM_SHA512
} HASHALGORITHM_ENUM;
typedef enum
{
DSA_FIPS186_2,
DSA_FIPS186_3
} DSAFIPSVERSION_ENUM;
typedef struct _BCRYPT_DSA_KEY_BLOB_V2
{
ULONG dwMagic;
ULONG cbKey;
HASHALGORITHM_ENUM hashAlgorithm;
DSAFIPSVERSION_ENUM standardVersion;
ULONG cbSeedLength;
ULONG cbGroupSize;
UCHAR Count[4];
} BCRYPT_DSA_KEY_BLOB_V2, *PBCRYPT_DSA_KEY_BLOB_V2;
#define BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION 1
#define BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG 0x00000001
......
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