Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_main.c | 694 +++++++++++++++++++++++-----------------------
1 file changed, 349 insertions(+), 345 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 1e56062b81..29a0a785d9 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -989,23 +989,13 @@ struct key
} u;
};
#else
-struct key_symmetric
-{
- enum mode_id mode;
- ULONG block_size;
-};
-
struct key
{
struct object hdr;
- union
- {
- struct key_symmetric s;
- } u;
};
#endif
-#if defined(HAVE_GNUTLS_CIPHER_INIT) || defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H)
static inline BOOL key_is_symmetric( struct key *key )
{
return alg_props[key->alg_id].symmetric;
@@ -1018,104 +1008,6 @@ static ULONG get_block_size( struct algorithm *alg )
return ret;
}
-static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object,
- ULONG object_len, UCHAR *input, ULONG input_len )
-{
- ULONG len;
-
- if (!strcmpW( type, BCRYPT_KEY_DATA_BLOB ))
- {
- BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)input;
-
- if (input_len < sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)) return STATUS_BUFFER_TOO_SMALL;
- if (header->dwMagic != BCRYPT_KEY_DATA_BLOB_MAGIC) return STATUS_INVALID_PARAMETER;
- if (header->dwVersion != BCRYPT_KEY_DATA_BLOB_VERSION1)
- {
- FIXME( "unknown key data blob version %u\n", header->dwVersion );
- return STATUS_INVALID_PARAMETER;
- }
- len = header->cbKeyData;
- if (len + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) > input_len) return STATUS_INVALID_PARAMETER;
-
- return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, (UCHAR *)&header[1], len, 0 );
- }
- else if (!strcmpW( type, BCRYPT_OPAQUE_KEY_BLOB ))
- {
- if (input_len < sizeof(len)) return STATUS_BUFFER_TOO_SMALL;
- len = *(ULONG *)input;
- if (len + sizeof(len) > input_len) return STATUS_INVALID_PARAMETER;
-
- return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, input + sizeof(len), len, 0 );
- }
-
- FIXME( "unsupported key type %s\n", debugstr_w(type) );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size )
-{
- if (!strcmpW( type, BCRYPT_KEY_DATA_BLOB ))
- {
- BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)output;
- ULONG req_size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + key->u.s.secret_len;
-
- *size = req_size;
- if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
-
- header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
- header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
- header->cbKeyData = key->u.s.secret_len;
- memcpy( &header[1], key->u.s.secret, key->u.s.secret_len );
- return STATUS_SUCCESS;
- }
- else if (!strcmpW( type, BCRYPT_OPAQUE_KEY_BLOB ))
- {
- ULONG len, req_size = sizeof(len) + key->u.s.secret_len;
-
- *size = req_size;
- if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
-
- *(ULONG *)output = key->u.s.secret_len;
- memcpy( output + sizeof(len), key->u.s.secret, key->u.s.secret_len );
- return STATUS_SUCCESS;
- }
-
- FIXME( "unsupported key type %s\n", debugstr_w(type) );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
-{
- UCHAR *buffer;
-
- memset( key_copy, 0, sizeof(*key_copy) );
- key_copy->hdr = key_orig->hdr;
- key_copy->alg_id = key_orig->alg_id;
-
- if (key_is_symmetric( key_orig ))
- {
- if (!(buffer = heap_alloc( key_orig->u.s.secret_len ))) return STATUS_NO_MEMORY;
- memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len );
-
- key_copy->u.s.mode = key_orig->u.s.mode;
- key_copy->u.s.block_size = key_orig->u.s.block_size;
- key_copy->u.s.secret = buffer;
- key_copy->u.s.secret_len = key_orig->u.s.secret_len;
- }
- else
- {
- if (!(buffer = heap_alloc( key_orig->u.a.pubkey_len ))) return STATUS_NO_MEMORY;
- memcpy( buffer, key_orig->u.a.pubkey, key_orig->u.a.pubkey_len );
-
- key_copy->u.a.pubkey = buffer;
- key_copy->u.a.pubkey_len = key_orig->u.a.pubkey_len;
- }
-
- return STATUS_SUCCESS;
-}
-#endif
-
-#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H)
static NTSTATUS key_symmetric_init( struct key *key, struct algorithm *alg, const UCHAR *secret, ULONG secret_len )
{
UCHAR *buffer;
@@ -1645,6 +1537,18 @@ static NTSTATUS key_destroy( struct key *key )
return STATUS_SUCCESS;
}
#elif defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+static inline BOOL key_is_symmetric( struct key *key )
+{
+ return alg_props[key->alg_id].symmetric;
+}
+
+static ULONG get_block_size( struct algorithm *alg )
+{
+ ULONG ret = 0, size = sizeof(ret);
+ get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size );
+ return ret;
+}
+
static NTSTATUS key_symmetric_init( struct key *key, struct algorithm *alg, const UCHAR *secret, ULONG secret_len )
{
UCHAR *buffer;
@@ -1835,297 +1739,164 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_symmetric_set_params( struct key *key, UCHAR *iv, ULONG iv_len )
-{
- ERR( "support for keys not available at build time\n" );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS key_symmetric_set_auth_data( struct key *key, UCHAR *auth_data, ULONG len )
-{
- ERR( "support for keys not available at build time\n" );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
- ULONG output_len )
+static NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len,
+ UCHAR *signature, ULONG signature_len, DWORD flags )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
- ULONG output_len )
+static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object,
+ ULONG object_len, UCHAR *input, ULONG input_len )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
+static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len,
- UCHAR *signature, ULONG signature_len, DWORD flags )
+static NTSTATUS key_destroy( struct key *key )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object,
- ULONG object_len, UCHAR *input, ULONG input_len )
+static inline BOOL key_is_symmetric( struct key *key )
{
ERR( "support for keys not available at build time\n" );
- return STATUS_NOT_IMPLEMENTED;
+ return FALSE;
}
-static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size )
+static NTSTATUS key_encrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS key_destroy( struct key *key )
+static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
-static inline BOOL key_is_symmetric( struct key *key )
-{
- ERR( "support for keys not available at build time\n" );
- return FALSE;
-}
-
-static NTSTATUS key_asymmetric_init( struct key *key, struct algorithm *alg, const UCHAR *pubkey, ULONG pubkey_len )
+static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+ ULONG input_len )
{
ERR( "support for keys not available at build time\n" );
return STATUS_NOT_IMPLEMENTED;
}
#endif
-NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE *handle,
- UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len,
- ULONG flags )
+#if defined(HAVE_GNUTLS_CIPHER_INIT) || defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+static NTSTATUS key_import( BCRYPT_ALG_HANDLE algorithm, const WCHAR *type, BCRYPT_KEY_HANDLE *key, UCHAR *object,
+ ULONG object_len, UCHAR *input, ULONG input_len )
{
- struct algorithm *alg = algorithm;
- struct key *key;
- NTSTATUS status;
-
- TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, secret, secret_len, flags );
+ ULONG len;
- if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
- if (object) FIXME( "ignoring object buffer\n" );
+ if (!strcmpW( type, BCRYPT_KEY_DATA_BLOB ))
+ {
+ BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)input;
- if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
- key->hdr.magic = MAGIC_KEY;
+ if (input_len < sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)) return STATUS_BUFFER_TOO_SMALL;
+ if (header->dwMagic != BCRYPT_KEY_DATA_BLOB_MAGIC) return STATUS_INVALID_PARAMETER;
+ if (header->dwVersion != BCRYPT_KEY_DATA_BLOB_VERSION1)
+ {
+ FIXME( "unknown key data blob version %u\n", header->dwVersion );
+ return STATUS_INVALID_PARAMETER;
+ }
+ len = header->cbKeyData;
+ if (len + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) > input_len) return STATUS_INVALID_PARAMETER;
- if ((status = key_symmetric_init( key, alg, secret, secret_len )))
+ return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, (UCHAR *)&header[1], len, 0 );
+ }
+ else if (!strcmpW( type, BCRYPT_OPAQUE_KEY_BLOB ))
{
- heap_free( key );
- return status;
+ if (input_len < sizeof(len)) return STATUS_BUFFER_TOO_SMALL;
+ len = *(ULONG *)input;
+ if (len + sizeof(len) > input_len) return STATUS_INVALID_PARAMETER;
+
+ return BCryptGenerateSymmetricKey( algorithm, key, object, object_len, input + sizeof(len), len, 0 );
}
- *handle = key;
- return STATUS_SUCCESS;
+ FIXME( "unsupported key type %s\n", debugstr_w(type) );
+ return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS WINAPI BCryptImportKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, LPCWSTR type,
- BCRYPT_KEY_HANDLE *key, PUCHAR object, ULONG object_len, PUCHAR input,
- ULONG input_len, ULONG flags )
+static NTSTATUS key_export( struct key *key, const WCHAR *type, UCHAR *output, ULONG output_len, ULONG *size )
{
- struct algorithm *alg = algorithm;
-
- TRACE("%p, %p, %s, %p, %p, %u, %p, %u, %u\n", algorithm, decrypt_key, debugstr_w(type), key, object,
- object_len, input, input_len, flags);
+ if (!strcmpW( type, BCRYPT_KEY_DATA_BLOB ))
+ {
+ BCRYPT_KEY_DATA_BLOB_HEADER *header = (BCRYPT_KEY_DATA_BLOB_HEADER *)output;
+ ULONG req_size = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + key->u.s.secret_len;
- if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
- if (!key || !type || !input) return STATUS_INVALID_PARAMETER;
+ *size = req_size;
+ if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
- if (decrypt_key)
+ header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
+ header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
+ header->cbKeyData = key->u.s.secret_len;
+ memcpy( &header[1], key->u.s.secret, key->u.s.secret_len );
+ return STATUS_SUCCESS;
+ }
+ else if (!strcmpW( type, BCRYPT_OPAQUE_KEY_BLOB ))
{
- FIXME( "decryption of key not yet supported\n" );
- return STATUS_NOT_IMPLEMENTED;
+ ULONG len, req_size = sizeof(len) + key->u.s.secret_len;
+
+ *size = req_size;
+ if (output_len < req_size) return STATUS_BUFFER_TOO_SMALL;
+
+ *(ULONG *)output = key->u.s.secret_len;
+ memcpy( output + sizeof(len), key->u.s.secret, key->u.s.secret_len );
+ return STATUS_SUCCESS;
}
- return key_import( algorithm, type, key, object, object_len, input, input_len );
+ FIXME( "unsupported key type %s\n", debugstr_w(type) );
+ return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS WINAPI BCryptExportKey( BCRYPT_KEY_HANDLE export_key, BCRYPT_KEY_HANDLE encrypt_key, LPCWSTR type,
- PUCHAR output, ULONG output_len, ULONG *size, ULONG flags )
+static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
{
- struct key *key = export_key;
-
- TRACE("%p, %p, %s, %p, %u, %p, %u\n", key, encrypt_key, debugstr_w(type), output, output_len, size, flags);
+ UCHAR *buffer;
- if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- if (!output || !type || !size) return STATUS_INVALID_PARAMETER;
+ memset( key_copy, 0, sizeof(*key_copy) );
+ key_copy->hdr = key_orig->hdr;
+ key_copy->alg_id = key_orig->alg_id;
- if (encrypt_key)
+ if (key_is_symmetric( key_orig ))
{
- FIXME( "encryption of key not yet supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- return key_export( key, type, output, output_len, size );
-}
-
-NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy,
- UCHAR *object, ULONG object_len, ULONG flags )
-{
- struct key *key_orig = handle;
- struct key *key_copy;
- NTSTATUS status;
-
- TRACE( "%p, %p, %p, %u, %08x\n", handle, handle_copy, object, object_len, flags );
- if (object) FIXME( "ignoring object buffer\n" );
-
- if (!key_orig || key_orig->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- if (!handle_copy) return STATUS_INVALID_PARAMETER;
- if (!(key_copy = heap_alloc( sizeof(*key_copy) ))) return STATUS_NO_MEMORY;
-
- if ((status = key_duplicate( key_orig, key_copy )))
- {
- heap_free( key_copy );
- return status;
- }
-
- *handle_copy = key_copy;
- return STATUS_SUCCESS;
-}
-
-NTSTATUS WINAPI BCryptImportKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, const WCHAR *type,
- BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, ULONG input_len, ULONG flags )
-{
- struct algorithm *alg = algorithm;
- NTSTATUS status;
- struct key *key;
-
- TRACE( "%p, %p, %s, %p, %p, %u, %08x\n", algorithm, decrypt_key, debugstr_w(type), ret_key, input,
- input_len, flags );
-
- if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
- if (!ret_key || !type || !input) return STATUS_INVALID_PARAMETER;
- if (decrypt_key)
- {
- FIXME( "decryption of key not yet supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
-
- if (!strcmpW( type, BCRYPT_ECCPUBLIC_BLOB ))
- {
- BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
- DWORD key_size, magic;
-
- if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
-
- switch (alg->id)
- {
- case ALG_ID_ECDSA_P256:
- key_size = 32;
- magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
- break;
-
- case ALG_ID_ECDSA_P384:
- key_size = 48;
- magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
- break;
-
- default:
- FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
- return STATUS_NOT_SUPPORTED;
- }
-
- if (ecc_blob->dwMagic != magic) return STATUS_NOT_SUPPORTED;
- if (ecc_blob->cbKey != key_size) return STATUS_INVALID_PARAMETER;
-
- if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
- key->hdr.magic = MAGIC_KEY;
- if ((status = key_asymmetric_init( key, alg, (BYTE *)ecc_blob, sizeof(*ecc_blob) + ecc_blob->cbKey * 2 )))
- {
- heap_free( key );
- return status;
- }
+ if (!(buffer = heap_alloc( key_orig->u.s.secret_len ))) return STATUS_NO_MEMORY;
+ memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len );
- *ret_key = key;
- return STATUS_SUCCESS;
+ key_copy->u.s.mode = key_orig->u.s.mode;
+ key_copy->u.s.block_size = key_orig->u.s.block_size;
+ key_copy->u.s.secret = buffer;
+ key_copy->u.s.secret_len = key_orig->u.s.secret_len;
}
- else if (!strcmpW( type, BCRYPT_RSAPUBLIC_BLOB ))
+ else
{
- BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
- ULONG size;
-
- if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
- if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC) return STATUS_NOT_SUPPORTED;
-
- if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
- key->hdr.magic = MAGIC_KEY;
-
- size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
- if ((status = key_asymmetric_init( key, alg, (BYTE *)rsa_blob, size )))
- {
- heap_free( key );
- return status;
- }
+ if (!(buffer = heap_alloc( key_orig->u.a.pubkey_len ))) return STATUS_NO_MEMORY;
+ memcpy( buffer, key_orig->u.a.pubkey, key_orig->u.a.pubkey_len );
- *ret_key = key;
- return STATUS_SUCCESS;
+ key_copy->u.a.pubkey = buffer;
+ key_copy->u.a.pubkey_len = key_orig->u.a.pubkey_len;
}
- FIXME( "unsupported key type %s\n", debugstr_w(type) );
- return STATUS_NOT_SUPPORTED;
-}
-
-NTSTATUS WINAPI BCryptVerifySignature( BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *hash, ULONG hash_len,
- UCHAR *signature, ULONG signature_len, ULONG flags )
-{
- struct key *key = handle;
-
- TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", handle, padding, hash, hash_len, signature, signature_len, flags );
-
- if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- if (!hash || !hash_len || !signature || !signature_len) return STATUS_INVALID_PARAMETER;
- if (key_is_symmetric( key )) return STATUS_NOT_SUPPORTED;
-
- return key_asymmetric_verify( key, padding, hash, hash_len, signature, signature_len, flags );
-}
-
-NTSTATUS WINAPI BCryptDestroyKey( BCRYPT_KEY_HANDLE handle )
-{
- struct key *key = handle;
-
- TRACE( "%p\n", handle );
-
- if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- return key_destroy( key );
+ return STATUS_SUCCESS;
}
-NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len,
- void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output,
- ULONG output_len, ULONG *ret_len, ULONG flags )
+static NTSTATUS key_encrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
{
- struct key *key = handle;
ULONG bytes_left = input_len;
UCHAR *buf, *src, *dst;
NTSTATUS status;
- TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len,
- padding, iv, iv_len, output, output_len, ret_len, flags );
-
- if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- if (!key_is_symmetric( key ))
- {
- FIXME( "encryption with asymmetric keys not yet supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
- if (flags & ~BCRYPT_BLOCK_PADDING)
- {
- FIXME( "flags %08x not implemented\n", flags );
- return STATUS_NOT_IMPLEMENTED;
- }
-
if (key->u.s.mode == MODE_ID_GCM)
{
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding;
@@ -2188,30 +1959,13 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
return status;
}
-NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len,
- void *padding, UCHAR *iv, ULONG iv_len, UCHAR *output,
- ULONG output_len, ULONG *ret_len, ULONG flags )
+static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
{
- struct key *key = handle;
ULONG bytes_left = input_len;
UCHAR *buf, *src, *dst;
NTSTATUS status;
- TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len,
- padding, iv, iv_len, output, output_len, ret_len, flags );
-
- if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
- if (!key_is_symmetric( key ))
- {
- FIXME( "decryption with asymmetric keys not yet supported\n" );
- return STATUS_NOT_IMPLEMENTED;
- }
- if (flags & ~BCRYPT_BLOCK_PADDING)
- {
- FIXME( "flags %08x not supported\n", flags );
- return STATUS_NOT_IMPLEMENTED;
- }
-
if (key->u.s.mode == MODE_ID_GCM)
{
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding;
@@ -2285,6 +2039,256 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
return status;
}
+static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+ ULONG input_len )
+{
+ struct key *key;
+ NTSTATUS status;
+
+ if (!strcmpW( type, BCRYPT_ECCPUBLIC_BLOB ))
+ {
+ BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
+ DWORD key_size, magic;
+
+ if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
+
+ switch (alg->id)
+ {
+ case ALG_ID_ECDSA_P256:
+ key_size = 32;
+ magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+ break;
+
+ case ALG_ID_ECDSA_P384:
+ key_size = 48;
+ magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
+ break;
+
+ default:
+ FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ if (ecc_blob->dwMagic != magic) return STATUS_NOT_SUPPORTED;
+ if (ecc_blob->cbKey != key_size) return STATUS_INVALID_PARAMETER;
+
+ if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
+ key->hdr.magic = MAGIC_KEY;
+ if ((status = key_asymmetric_init( key, alg, (BYTE *)ecc_blob, sizeof(*ecc_blob) + ecc_blob->cbKey * 2 )))
+ {
+ heap_free( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
+ }
+ else if (!strcmpW( type, BCRYPT_RSAPUBLIC_BLOB ))
+ {
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+ ULONG size;
+
+ if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
+ if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC) return STATUS_NOT_SUPPORTED;
+
+ if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
+ key->hdr.magic = MAGIC_KEY;
+
+ size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
+ if ((status = key_asymmetric_init( key, alg, (BYTE *)rsa_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;
+}
+#endif
+
+NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE *handle,
+ UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len,
+ ULONG flags )
+{
+ struct algorithm *alg = algorithm;
+ struct key *key;
+ NTSTATUS status;
+
+ TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, secret, secret_len, flags );
+
+ if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
+ if (object) FIXME( "ignoring object buffer\n" );
+
+ if (!(key = heap_alloc( sizeof(*key) ))) return STATUS_NO_MEMORY;
+ key->hdr.magic = MAGIC_KEY;
+
+ if ((status = key_symmetric_init( key, alg, secret, secret_len )))
+ {
+ heap_free( key );
+ return status;
+ }
+
+ *handle = key;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI BCryptImportKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, LPCWSTR type,
+ BCRYPT_KEY_HANDLE *key, PUCHAR object, ULONG object_len, PUCHAR input,
+ ULONG input_len, ULONG flags )
+{
+ struct algorithm *alg = algorithm;
+
+ TRACE("%p, %p, %s, %p, %p, %u, %p, %u, %u\n", algorithm, decrypt_key, debugstr_w(type), key, object,
+ object_len, input, input_len, flags);
+
+ if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
+ if (!key || !type || !input) return STATUS_INVALID_PARAMETER;
+
+ if (decrypt_key)
+ {
+ FIXME( "decryption of key not yet supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ return key_import( algorithm, type, key, object, object_len, input, input_len );
+}
+
+NTSTATUS WINAPI BCryptExportKey( BCRYPT_KEY_HANDLE export_key, BCRYPT_KEY_HANDLE encrypt_key, LPCWSTR type,
+ PUCHAR output, ULONG output_len, ULONG *size, ULONG flags )
+{
+ struct key *key = export_key;
+
+ TRACE("%p, %p, %s, %p, %u, %p, %u\n", key, encrypt_key, debugstr_w(type), output, output_len, size, flags);
+
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ if (!output || !type || !size) return STATUS_INVALID_PARAMETER;
+
+ if (encrypt_key)
+ {
+ FIXME( "encryption of key not yet supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ return key_export( key, type, output, output_len, size );
+}
+
+NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy,
+ UCHAR *object, ULONG object_len, ULONG flags )
+{
+ struct key *key_orig = handle;
+ struct key *key_copy;
+ NTSTATUS status;
+
+ TRACE( "%p, %p, %p, %u, %08x\n", handle, handle_copy, object, object_len, flags );
+ if (object) FIXME( "ignoring object buffer\n" );
+
+ if (!key_orig || key_orig->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ if (!handle_copy) return STATUS_INVALID_PARAMETER;
+ if (!(key_copy = heap_alloc( sizeof(*key_copy) ))) return STATUS_NO_MEMORY;
+
+ if ((status = key_duplicate( key_orig, key_copy )))
+ {
+ heap_free( key_copy );
+ return status;
+ }
+
+ *handle_copy = key_copy;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI BCryptImportKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_HANDLE decrypt_key, const WCHAR *type,
+ BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, ULONG input_len, ULONG flags )
+{
+ struct algorithm *alg = algorithm;
+
+ TRACE( "%p, %p, %s, %p, %p, %u, %08x\n", algorithm, decrypt_key, debugstr_w(type), ret_key, input,
+ input_len, flags );
+
+ if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
+ if (!ret_key || !type || !input) return STATUS_INVALID_PARAMETER;
+ if (decrypt_key)
+ {
+ FIXME( "decryption of key not yet supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ return key_import_pair( alg, type, ret_key, input, input_len );
+}
+
+NTSTATUS WINAPI BCryptVerifySignature( BCRYPT_KEY_HANDLE handle, void *padding, UCHAR *hash, ULONG hash_len,
+ UCHAR *signature, ULONG signature_len, ULONG flags )
+{
+ struct key *key = handle;
+
+ TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", handle, padding, hash, hash_len, signature, signature_len, flags );
+
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ if (!hash || !hash_len || !signature || !signature_len) return STATUS_INVALID_PARAMETER;
+ if (key_is_symmetric( key )) return STATUS_NOT_SUPPORTED;
+
+ return key_asymmetric_verify( key, padding, hash, hash_len, signature, signature_len, flags );
+}
+
+NTSTATUS WINAPI BCryptDestroyKey( BCRYPT_KEY_HANDLE handle )
+{
+ struct key *key = handle;
+
+ TRACE( "%p\n", handle );
+
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ return key_destroy( key );
+}
+
+NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
+{
+ struct key *key = handle;
+
+ TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len, padding, iv, iv_len, output,
+ output_len, ret_len, flags );
+
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ if (!key_is_symmetric( key ))
+ {
+ FIXME( "encryption with asymmetric keys not yet supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ if (flags & ~BCRYPT_BLOCK_PADDING)
+ {
+ FIXME( "flags %08x not implemented\n", flags );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ return key_encrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags );
+}
+
+NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
+{
+ struct key *key = handle;
+
+ TRACE( "%p, %p, %u, %p, %p, %u, %p, %u, %p, %08x\n", handle, input, input_len, padding, iv, iv_len, output,
+ output_len, ret_len, flags );
+
+ if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
+ if (!key_is_symmetric( key ))
+ {
+ FIXME( "decryption with asymmetric keys not yet supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ if (flags & ~BCRYPT_BLOCK_PADDING)
+ {
+ FIXME( "flags %08x not supported\n", flags );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ return key_decrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags );
+}
+
NTSTATUS WINAPI BCryptSetProperty( BCRYPT_HANDLE handle, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
{
struct object *object = handle;
--
2.11.0