Signed-off-by: Hans Leidekker hans@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;