Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
81d71ee0
Commit
81d71ee0
authored
Nov 29, 2023
by
Hans Leidekker
Committed by
Alexandre Julliard
Nov 30, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcrypt: Implement BCryptDeriveKey().
parent
cfa655c4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
201 additions
and
20 deletions
+201
-20
bcrypt_internal.h
dlls/bcrypt/bcrypt_internal.h
+10
-0
bcrypt_main.c
dlls/bcrypt/bcrypt_main.c
+122
-18
gnutls.c
dlls/bcrypt/gnutls.c
+69
-2
No files found.
dlls/bcrypt/bcrypt_internal.h
View file @
81d71ee0
...
...
@@ -302,6 +302,15 @@ struct key_asymmetric_import_params
ULONG
len
;
};
struct
key_asymmetric_derive_key_params
{
struct
key
*
privkey
;
struct
key
*
pubkey
;
UCHAR
*
output
;
ULONG
output_len
;
ULONG
*
ret_len
;
};
enum
key_funcs
{
unix_process_attach
,
...
...
@@ -321,6 +330,7 @@ enum key_funcs
unix_key_asymmetric_destroy
,
unix_key_asymmetric_export
,
unix_key_asymmetric_import
,
unix_key_asymmetric_derive_key
,
unix_funcs_count
,
};
...
...
dlls/bcrypt/bcrypt_main.c
View file @
81d71ee0
...
...
@@ -17,6 +17,7 @@
*
*/
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
...
...
@@ -1134,24 +1135,13 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULON
return
hash_finalize
(
hash
,
output
);
}
NTSTATUS
WINAPI
BCryptHash
(
BCRYPT_ALG_HANDLE
handle
,
UCHAR
*
secret
,
ULONG
secre
t_len
,
UCHAR
*
input
,
ULONG
input_len
,
UCHAR
*
output
,
ULONG
output_len
)
static
NTSTATUS
hash_single
(
struct
algorithm
*
alg
,
UCHAR
*
secret
,
ULONG
secret_len
,
UCHAR
*
input
,
ULONG
inpu
t_len
,
UCHAR
*
output
,
ULONG
output_len
)
{
struct
algorithm
*
alg
=
get_alg_object
(
handle
);
struct
hash
*
hash
;
NTSTATUS
status
;
TRACE
(
"%p, %p, %lu, %p, %lu, %p, %lu
\n
"
,
handle
,
secret
,
secret_len
,
input
,
input_len
,
output
,
output_len
);
if
(
!
alg
)
return
STATUS_INVALID_HANDLE
;
if
(
!
output
)
return
STATUS_INVALID_PARAMETER
;
if
((
status
=
hash_create
(
alg
,
secret
,
secret_len
,
0
,
&
hash
)))
return
status
;
if
(
output_len
!=
builtin_algorithms
[
hash
->
alg_id
].
hash_length
)
{
hash_destroy
(
hash
);
return
STATUS_INVALID_PARAMETER
;
}
if
((
status
=
hash_update
(
&
hash
->
inner
,
hash
->
alg_id
,
input
,
input_len
)))
{
hash_destroy
(
hash
);
...
...
@@ -1162,6 +1152,19 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE handle, UCHAR *secret, ULONG secre
return
status
;
}
NTSTATUS
WINAPI
BCryptHash
(
BCRYPT_ALG_HANDLE
handle
,
UCHAR
*
secret
,
ULONG
secret_len
,
UCHAR
*
input
,
ULONG
input_len
,
UCHAR
*
output
,
ULONG
output_len
)
{
struct
algorithm
*
alg
=
get_alg_object
(
handle
);
TRACE
(
"%p, %p, %lu, %p, %lu, %p, %lu
\n
"
,
handle
,
secret
,
secret_len
,
input
,
input_len
,
output
,
output_len
);
if
(
!
alg
)
return
STATUS_INVALID_HANDLE
;
if
(
!
output
||
output_len
!=
builtin_algorithms
[
alg
->
id
].
hash_length
)
return
STATUS_INVALID_PARAMETER
;
return
hash_single
(
alg
,
secret
,
secret_len
,
input
,
input_len
,
output
,
output_len
);
}
static
NTSTATUS
key_asymmetric_create
(
enum
alg_id
alg_id
,
ULONG
bitlen
,
struct
key
**
ret_key
)
{
struct
key
*
key
;
...
...
@@ -2471,17 +2474,118 @@ NTSTATUS WINAPI BCryptDestroySecret( BCRYPT_SECRET_HANDLE handle )
return
STATUS_SUCCESS
;
}
NTSTATUS
WINAPI
BCryptDeriveKey
(
BCRYPT_SECRET_HANDLE
handle
,
const
WCHAR
*
kdf
,
BCryptBufferDesc
*
parameter
,
UCHAR
*
derived
,
ULONG
derived_size
,
ULONG
*
result
,
ULONG
flags
)
static
void
reverse_bytes
(
UCHAR
*
buf
,
ULONG
len
)
{
ULONG
i
;
for
(
i
=
0
;
i
<
len
/
2
;
i
++
)
{
UCHAR
tmp
=
buf
[
i
];
buf
[
i
]
=
buf
[
len
-
i
-
1
];
buf
[
len
-
i
-
1
]
=
tmp
;
}
}
static
NTSTATUS
derive_key_raw
(
struct
secret
*
secret
,
UCHAR
*
output
,
ULONG
output_len
,
ULONG
*
ret_len
)
{
struct
key_asymmetric_derive_key_params
params
;
NTSTATUS
status
;
params
.
privkey
=
secret
->
privkey
;
params
.
pubkey
=
secret
->
pubkey
;
params
.
output
=
output
;
params
.
output_len
=
output_len
;
params
.
ret_len
=
ret_len
;
if
(
!
(
status
=
UNIX_CALL
(
key_asymmetric_derive_key
,
&
params
))
&&
output
)
reverse_bytes
(
output
,
*
ret_len
);
return
status
;
}
static
BCRYPT_ALG_HANDLE
hash_handle_from_desc
(
BCryptBufferDesc
*
desc
)
{
ULONG
i
;
if
(
!
desc
)
return
BCRYPT_SHA1_ALG_HANDLE
;
for
(
i
=
0
;
i
<
desc
->
cBuffers
;
i
++
)
{
if
(
desc
->
pBuffers
[
i
].
BufferType
==
KDF_HASH_ALGORITHM
)
{
const
WCHAR
*
str
=
desc
->
pBuffers
[
i
].
pvBuffer
;
if
(
!
wcscmp
(
str
,
BCRYPT_SHA1_ALGORITHM
))
return
BCRYPT_SHA1_ALG_HANDLE
;
else
if
(
!
wcscmp
(
str
,
BCRYPT_SHA256_ALGORITHM
))
return
BCRYPT_SHA256_ALG_HANDLE
;
else
if
(
!
wcscmp
(
str
,
BCRYPT_SHA384_ALGORITHM
))
return
BCRYPT_SHA384_ALG_HANDLE
;
else
if
(
!
wcscmp
(
str
,
BCRYPT_SHA512_ALGORITHM
))
return
BCRYPT_SHA512_ALG_HANDLE
;
else
{
FIXME
(
"hash algorithm %s not supported
\n
"
,
debugstr_w
(
str
)
);
return
NULL
;
}
}
else
FIXME
(
"buffer type %lu not supported
\n
"
,
desc
->
pBuffers
[
i
].
BufferType
);
}
return
BCRYPT_SHA1_ALG_HANDLE
;
}
static
NTSTATUS
derive_key_hash
(
struct
secret
*
secret
,
BCryptBufferDesc
*
desc
,
UCHAR
*
output
,
ULONG
output_len
,
ULONG
*
ret_len
)
{
struct
key_asymmetric_derive_key_params
params
;
struct
algorithm
*
alg
=
get_alg_object
(
hash_handle_from_desc
(
desc
)
);
ULONG
hash_len
,
derived_key_len
=
secret
->
privkey
->
u
.
a
.
bitlen
/
8
;
UCHAR
hash_buf
[
MAX_HASH_OUTPUT_BYTES
];
UCHAR
*
derived_key
;
NTSTATUS
status
;
if
(
!
alg
)
return
STATUS_NOT_SUPPORTED
;
if
(
!
(
derived_key
=
malloc
(
derived_key_len
)))
return
STATUS_NO_MEMORY
;
params
.
privkey
=
secret
->
privkey
;
params
.
pubkey
=
secret
->
pubkey
;
params
.
output
=
derived_key
;
params
.
output_len
=
derived_key_len
;
params
.
ret_len
=
ret_len
;
if
((
status
=
UNIX_CALL
(
key_asymmetric_derive_key
,
&
params
)))
{
free
(
derived_key
);
return
status
;
}
hash_len
=
builtin_algorithms
[
alg
->
id
].
hash_length
;
assert
(
hash_len
<=
sizeof
(
hash_buf
)
);
if
(
!
(
status
=
hash_single
(
alg
,
NULL
,
0
,
derived_key
,
*
params
.
ret_len
,
hash_buf
,
hash_len
)))
{
if
(
!
output
)
*
ret_len
=
hash_len
;
else
{
*
ret_len
=
min
(
hash_len
,
output_len
);
memcpy
(
output
,
hash_buf
,
*
ret_len
);
}
}
free
(
derived_key
);
return
status
;
}
NTSTATUS
WINAPI
BCryptDeriveKey
(
BCRYPT_SECRET_HANDLE
handle
,
const
WCHAR
*
kdf
,
BCryptBufferDesc
*
desc
,
UCHAR
*
output
,
ULONG
output_len
,
ULONG
*
ret_len
,
ULONG
flags
)
{
struct
secret
*
secret
=
get_secret_object
(
handle
);
FIXME
(
"%p, %s, %p, %p, %lu, %p, %#lx
\n
"
,
secret
,
debugstr_w
(
kdf
),
parameter
,
derived
,
derived_size
,
result
,
flags
);
TRACE
(
"%p, %s, %p, %p, %lu, %p, %#lx
\n
"
,
secret
,
debugstr_w
(
kdf
),
desc
,
output
,
output_len
,
ret_len
,
flags
);
if
(
!
secret
)
return
STATUS_INVALID_HANDLE
;
if
(
!
kdf
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
kdf
||
!
ret_len
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
wcscmp
(
kdf
,
BCRYPT_KDF_RAW_SECRET
))
{
return
derive_key_raw
(
secret
,
output
,
output_len
,
ret_len
);
}
else
if
(
!
wcscmp
(
kdf
,
BCRYPT_KDF_HASH
))
{
return
derive_key_hash
(
secret
,
desc
,
output
,
output_len
,
ret_len
);
}
return
STATUS_INTERNAL_ERROR
;
FIXME
(
"kdf %s not supportedi
\n
"
,
debugstr_w
(
kdf
)
);
return
STATUS_NOT_SUPPORTED
;
}
BOOL
WINAPI
DllMain
(
HINSTANCE
hinst
,
DWORD
reason
,
LPVOID
reserved
)
...
...
dlls/bcrypt/gnutls.c
View file @
81d71ee0
...
...
@@ -144,6 +144,10 @@ static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_d
static
int
(
*
pgnutls_pubkey_set_spki
)(
gnutls_pubkey_t
,
const
gnutls_x509_spki_t
,
unsigned
int
);
static
int
(
*
pgnutls_privkey_set_spki
)(
gnutls_privkey_t
,
const
gnutls_x509_spki_t
,
unsigned
int
);
/* Not present in gnutls version < 3.8.2 */
static
int
(
*
pgnutls_privkey_derive_secret
)(
gnutls_privkey_t
,
gnutls_pubkey_t
,
const
gnutls_datum_t
*
,
gnutls_datum_t
*
,
unsigned
int
);
static
void
*
libgnutls_handle
;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR
(
gnutls_cipher_decrypt2
);
...
...
@@ -302,6 +306,12 @@ static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x50
return
GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
}
static
int
compat_gnutls_privkey_derive_secret
(
gnutls_privkey_t
privkey
,
gnutls_pubkey_t
pubkey
,
const
gnutls_datum_t
*
nonce
,
gnutls_datum_t
*
secret
,
unsigned
int
flags
)
{
return
GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
}
static
void
gnutls_log
(
int
level
,
const
char
*
msg
)
{
TRACE
(
"<%d> %s"
,
level
,
msg
);
...
...
@@ -365,6 +375,7 @@ static NTSTATUS gnutls_process_attach( void *args )
LOAD_FUNCPTR_OPT
(
gnutls_decode_rs_value
)
LOAD_FUNCPTR_OPT
(
gnutls_pk_to_sign
)
LOAD_FUNCPTR_OPT
(
gnutls_privkey_decrypt_data
)
LOAD_FUNCPTR_OPT
(
gnutls_privkey_derive_secret
)
LOAD_FUNCPTR_OPT
(
gnutls_privkey_export_dsa_raw
)
LOAD_FUNCPTR_OPT
(
gnutls_privkey_export_ecc_raw
)
LOAD_FUNCPTR_OPT
(
gnutls_privkey_export_rsa_raw
)
...
...
@@ -2250,6 +2261,30 @@ static NTSTATUS key_asymmetric_encrypt( void *args )
return
status
;
}
static
NTSTATUS
key_asymmetric_derive_key
(
void
*
args
)
{
const
struct
key_asymmetric_derive_key_params
*
params
=
args
;
gnutls_datum_t
s
;
int
ret
;
if
((
ret
=
pgnutls_privkey_derive_secret
(
key_data
(
params
->
privkey
)
->
a
.
privkey
,
key_data
(
params
->
pubkey
)
->
a
.
pubkey
,
NULL
,
&
s
,
0
)))
{
pgnutls_perror
(
ret
);
return
STATUS_INTERNAL_ERROR
;
}
if
(
!
params
->
output
)
*
params
->
ret_len
=
s
.
size
;
else
{
*
params
->
ret_len
=
min
(
params
->
output_len
,
s
.
size
);
memcpy
(
params
->
output
,
s
.
data
,
*
params
->
ret_len
);
}
free
(
s
.
data
);
return
STATUS_SUCCESS
;
}
const
unixlib_entry_t
__wine_unix_call_funcs
[]
=
{
gnutls_process_attach
,
...
...
@@ -2268,7 +2303,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
key_asymmetric_verify
,
key_asymmetric_destroy
,
key_asymmetric_export
,
key_asymmetric_import
key_asymmetric_import
,
key_asymmetric_derive_key
,
};
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_funcs
)
==
unix_funcs_count
);
...
...
@@ -2733,6 +2769,36 @@ static NTSTATUS wow64_key_asymmetric_import( void *args )
return
ret
;
}
static
NTSTATUS
wow64_key_asymmetric_derive_key
(
void
*
args
)
{
struct
{
PTR32
privkey
;
PTR32
pubkey
;
PTR32
output
;
ULONG
output_len
;
PTR32
ret_len
;
}
const
*
params32
=
args
;
NTSTATUS
ret
;
struct
key
privkey
,
pubkey
;
struct
key32
*
privkey32
=
ULongToPtr
(
params32
->
privkey
);
struct
key32
*
pubkey32
=
ULongToPtr
(
params32
->
pubkey
);
struct
key_asymmetric_derive_key_params
params
=
{
get_asymmetric_key
(
privkey32
,
&
privkey
),
get_asymmetric_key
(
pubkey32
,
&
pubkey
),
ULongToPtr
(
params32
->
output
),
params32
->
output_len
,
ULongToPtr
(
params32
->
ret_len
),
};
ret
=
key_asymmetric_derive_key
(
&
params
);
put_asymmetric_key32
(
&
privkey
,
privkey32
);
put_asymmetric_key32
(
&
pubkey
,
pubkey32
);
return
ret
;
}
const
unixlib_entry_t
__wine_unix_call_wow64_funcs
[]
=
{
gnutls_process_attach
,
...
...
@@ -2751,7 +2817,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
wow64_key_asymmetric_verify
,
wow64_key_asymmetric_destroy
,
wow64_key_asymmetric_export
,
wow64_key_asymmetric_import
wow64_key_asymmetric_import
,
wow64_key_asymmetric_derive_key
,
};
C_ASSERT
(
ARRAYSIZE
(
__wine_unix_call_wow64_funcs
)
==
unix_funcs_count
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment