Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
98ea906b
Commit
98ea906b
authored
Mar 06, 2019
by
Hans Leidekker
Committed by
Alexandre Julliard
Mar 06, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcrypt: Implement BCRYPT_HASH_REUSABLE_FLAG.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
89f124ff
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
173 additions
and
77 deletions
+173
-77
bcrypt_main.c
dlls/bcrypt/bcrypt_main.c
+65
-37
bcrypt.c
dlls/bcrypt/tests/bcrypt.c
+105
-40
bcrypt.h
include/bcrypt.h
+3
-0
No files found.
dlls/bcrypt/bcrypt_main.c
View file @
98ea906b
...
...
@@ -366,13 +366,17 @@ static NTSTATUS hash_finish( struct hash_impl *hash, enum alg_id alg_id,
return
STATUS_SUCCESS
;
}
#define HASH_FLAG_HMAC 0x01
#define HASH_FLAG_REUSABLE 0x02
struct
hash
{
struct
object
hdr
;
enum
alg_id
alg_id
;
BOOL
hmac
;
struct
hash_impl
outer
;
struct
hash_impl
inner
;
struct
object
hdr
;
enum
alg_id
alg_id
;
ULONG
flags
;
UCHAR
*
secret
;
ULONG
secret_len
;
struct
hash_impl
outer
;
struct
hash_impl
inner
;
};
#define BLOCK_LENGTH_AES 16
...
...
@@ -587,19 +591,45 @@ NTSTATUS WINAPI BCryptGetProperty( BCRYPT_HANDLE handle, LPCWSTR prop, UCHAR *bu
}
}
static
NTSTATUS
prepare_hash
(
struct
hash
*
hash
)
{
UCHAR
buffer
[
MAX_HASH_BLOCK_BITS
/
8
]
=
{
0
};
int
block_bytes
,
i
;
NTSTATUS
status
;
/* initialize hash */
if
((
status
=
hash_init
(
&
hash
->
inner
,
hash
->
alg_id
)))
return
status
;
if
(
!
(
hash
->
flags
&
HASH_FLAG_HMAC
))
return
STATUS_SUCCESS
;
/* initialize hmac */
if
((
status
=
hash_init
(
&
hash
->
outer
,
hash
->
alg_id
)))
return
status
;
block_bytes
=
alg_props
[
hash
->
alg_id
].
block_bits
/
8
;
if
(
hash
->
secret_len
>
block_bytes
)
{
struct
hash_impl
temp
;
if
((
status
=
hash_init
(
&
temp
,
hash
->
alg_id
)))
return
status
;
if
((
status
=
hash_update
(
&
temp
,
hash
->
alg_id
,
hash
->
secret
,
hash
->
secret_len
)))
return
status
;
if
((
status
=
hash_finish
(
&
temp
,
hash
->
alg_id
,
buffer
,
alg_props
[
hash
->
alg_id
].
hash_length
)))
return
status
;
}
else
memcpy
(
buffer
,
hash
->
secret
,
hash
->
secret_len
);
for
(
i
=
0
;
i
<
block_bytes
;
i
++
)
buffer
[
i
]
^=
0x5c
;
if
((
status
=
hash_update
(
&
hash
->
outer
,
hash
->
alg_id
,
buffer
,
block_bytes
)))
return
status
;
for
(
i
=
0
;
i
<
block_bytes
;
i
++
)
buffer
[
i
]
^=
(
0x5c
^
0x36
);
return
hash_update
(
&
hash
->
inner
,
hash
->
alg_id
,
buffer
,
block_bytes
);
}
NTSTATUS
WINAPI
BCryptCreateHash
(
BCRYPT_ALG_HANDLE
algorithm
,
BCRYPT_HASH_HANDLE
*
handle
,
UCHAR
*
object
,
ULONG
objectlen
,
UCHAR
*
secret
,
ULONG
secretlen
,
ULONG
flags
)
{
struct
algorithm
*
alg
=
algorithm
;
UCHAR
buffer
[
MAX_HASH_BLOCK_BITS
/
8
]
=
{
0
};
struct
hash
*
hash
;
int
block_bytes
;
NTSTATUS
status
;
int
i
;
TRACE
(
"%p, %p, %p, %u, %p, %u, %08x - stub
\n
"
,
algorithm
,
handle
,
object
,
objectlen
,
secret
,
secretlen
,
flags
);
if
(
flags
)
if
(
flags
&
~
BCRYPT_HASH_REUSABLE_FLAG
)
{
FIXME
(
"unimplemented flags %08x
\n
"
,
flags
);
return
STATUS_NOT_IMPLEMENTED
;
...
...
@@ -608,38 +638,23 @@ NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDL
if
(
!
alg
||
alg
->
hdr
.
magic
!=
MAGIC_ALG
)
return
STATUS_INVALID_HANDLE
;
if
(
object
)
FIXME
(
"ignoring object buffer
\n
"
);
if
(
!
(
hash
=
heap_alloc
(
sizeof
(
*
hash
)
)))
return
STATUS_NO_MEMORY
;
if
(
!
(
hash
=
heap_alloc
_zero
(
sizeof
(
*
hash
)
)))
return
STATUS_NO_MEMORY
;
hash
->
hdr
.
magic
=
MAGIC_HASH
;
hash
->
alg_id
=
alg
->
id
;
hash
->
hmac
=
alg
->
hmac
;
/* initialize hash */
if
((
status
=
hash_init
(
&
hash
->
inner
,
hash
->
alg_id
)))
goto
end
;
if
(
!
hash
->
hmac
)
goto
end
;
if
(
alg
->
hmac
)
hash
->
flags
=
HASH_FLAG_HMAC
;
if
(
flags
&
BCRYPT_HASH_REUSABLE_FLAG
)
hash
->
flags
|=
HASH_FLAG_REUSABLE
;
/* initialize hmac */
if
((
status
=
hash_init
(
&
hash
->
outer
,
hash
->
alg_id
)))
goto
end
;
block_bytes
=
alg_props
[
hash
->
alg_id
].
block_bits
/
8
;
if
(
secretlen
>
block_bytes
)
{
struct
hash_impl
temp
;
if
((
status
=
hash_init
(
&
temp
,
hash
->
alg_id
)))
goto
end
;
if
((
status
=
hash_update
(
&
temp
,
hash
->
alg_id
,
secret
,
secretlen
)))
goto
end
;
if
((
status
=
hash_finish
(
&
temp
,
hash
->
alg_id
,
buffer
,
alg_props
[
hash
->
alg_id
].
hash_length
)))
goto
end
;
}
else
if
(
secretlen
&&
!
(
hash
->
secret
=
heap_alloc
(
secretlen
)))
{
memcpy
(
buffer
,
secret
,
secretlen
);
heap_free
(
hash
);
return
STATUS_NO_MEMORY
;
}
for
(
i
=
0
;
i
<
block_bytes
;
i
++
)
buffer
[
i
]
^=
0x5c
;
if
((
status
=
hash_update
(
&
hash
->
outer
,
hash
->
alg_id
,
buffer
,
block_bytes
)))
goto
end
;
for
(
i
=
0
;
i
<
block_bytes
;
i
++
)
buffer
[
i
]
^=
(
0x5c
^
0x36
);
status
=
hash_update
(
&
hash
->
inner
,
hash
->
alg_id
,
buffer
,
block_bytes
);
memcpy
(
hash
->
secret
,
secret
,
secretlen
);
hash
->
secret_len
=
secretlen
;
end:
if
(
status
!=
STATUS_SUCCESS
)
if
((
status
=
prepare_hash
(
hash
))
!=
STATUS_SUCCESS
)
{
heap_free
(
hash
->
secret
);
heap_free
(
hash
);
return
status
;
}
...
...
@@ -664,6 +679,12 @@ NTSTATUS WINAPI BCryptDuplicateHash( BCRYPT_HASH_HANDLE handle, BCRYPT_HASH_HAND
return
STATUS_NO_MEMORY
;
memcpy
(
hash_copy
,
hash_orig
,
sizeof
(
*
hash_orig
)
);
if
(
hash_orig
->
secret
&&
!
(
hash_copy
->
secret
=
heap_alloc
(
hash_orig
->
secret_len
)))
{
heap_free
(
hash_copy
);
return
STATUS_NO_MEMORY
;
}
memcpy
(
hash_copy
->
secret
,
hash_orig
->
secret
,
hash_orig
->
secret_len
);
*
handle_copy
=
hash_copy
;
return
STATUS_SUCCESS
;
...
...
@@ -677,6 +698,7 @@ NTSTATUS WINAPI BCryptDestroyHash( BCRYPT_HASH_HANDLE handle )
if
(
!
hash
||
hash
->
hdr
.
magic
!=
MAGIC_HASH
)
return
STATUS_INVALID_PARAMETER
;
hash
->
hdr
.
magic
=
0
;
heap_free
(
hash
->
secret
);
heap_free
(
hash
);
return
STATUS_SUCCESS
;
}
...
...
@@ -705,13 +727,19 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULON
if
(
!
hash
||
hash
->
hdr
.
magic
!=
MAGIC_HASH
)
return
STATUS_INVALID_HANDLE
;
if
(
!
output
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
hash
->
hmac
)
return
hash_finish
(
&
hash
->
inner
,
hash
->
alg_id
,
output
,
size
);
if
(
!
(
hash
->
flags
&
HASH_FLAG_HMAC
))
{
if
((
status
=
hash_finish
(
&
hash
->
inner
,
hash
->
alg_id
,
output
,
size
)))
return
status
;
if
(
hash
->
flags
&
HASH_FLAG_REUSABLE
)
return
prepare_hash
(
hash
);
return
STATUS_SUCCESS
;
}
hash_length
=
alg_props
[
hash
->
alg_id
].
hash_length
;
if
((
status
=
hash_finish
(
&
hash
->
inner
,
hash
->
alg_id
,
buffer
,
hash_length
)))
return
status
;
if
((
status
=
hash_update
(
&
hash
->
outer
,
hash
->
alg_id
,
buffer
,
hash_length
)))
return
status
;
return
hash_finish
(
&
hash
->
outer
,
hash
->
alg_id
,
output
,
size
);
if
((
status
=
hash_finish
(
&
hash
->
outer
,
hash
->
alg_id
,
output
,
size
)))
return
status
;
if
(
hash
->
flags
&
HASH_FLAG_REUSABLE
)
return
prepare_hash
(
hash
);
return
STATUS_SUCCESS
;
}
NTSTATUS
WINAPI
BCryptHash
(
BCRYPT_ALG_HANDLE
algorithm
,
UCHAR
*
secret
,
ULONG
secretlen
,
...
...
dlls/bcrypt/tests/bcrypt.c
View file @
98ea906b
...
...
@@ -221,7 +221,9 @@ struct hash_test
const
char
*
alg
;
unsigned
hash_size
;
const
char
*
hash
;
const
char
*
hash2
;
const
char
*
hmac_hash
;
const
char
*
hmac_hash2
;
};
static
void
test_hash
(
const
struct
hash_test
*
test
)
...
...
@@ -269,6 +271,35 @@ static void test_hash(const struct hash_test *test)
ret
=
pBCryptDestroyHash
(
hash
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
hash
=
NULL
;
len
=
sizeof
(
buf
);
ret
=
pBCryptCreateHash
(
alg
,
&
hash
,
buf
,
len
,
NULL
,
0
,
BCRYPT_HASH_REUSABLE_FLAG
);
ok
(
ret
==
STATUS_SUCCESS
||
broken
(
ret
==
STATUS_INVALID_PARAMETER
)
/* < win8 */
,
"got %08x
\n
"
,
ret
);
if
(
ret
==
STATUS_SUCCESS
)
{
ret
=
pBCryptHashData
(
hash
,
(
UCHAR
*
)
"test"
,
sizeof
(
"test"
),
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
memset
(
hash_buf
,
0
,
sizeof
(
hash_buf
));
ret
=
pBCryptFinishHash
(
hash
,
hash_buf
,
test
->
hash_size
,
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
format_hash
(
hash_buf
,
test
->
hash_size
,
str
);
ok
(
!
strcmp
(
str
,
test
->
hash
),
"got %s
\n
"
,
str
);
/* reuse it */
ret
=
pBCryptHashData
(
hash
,
(
UCHAR
*
)
"tset"
,
sizeof
(
"tset"
),
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
memset
(
hash_buf
,
0
,
sizeof
(
hash_buf
));
ret
=
pBCryptFinishHash
(
hash
,
hash_buf
,
test
->
hash_size
,
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
format_hash
(
hash_buf
,
test
->
hash_size
,
str
);
ok
(
!
strcmp
(
str
,
test
->
hash2
),
"got %s
\n
"
,
str
);
ret
=
pBCryptDestroyHash
(
hash
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
}
ret
=
pBCryptCloseAlgorithmProvider
(
alg
,
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
...
...
@@ -298,6 +329,35 @@ static void test_hash(const struct hash_test *test)
ret
=
pBCryptDestroyHash
(
hash
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
hash
=
NULL
;
len
=
sizeof
(
buf_hmac
);
ret
=
pBCryptCreateHash
(
alg
,
&
hash
,
buf_hmac
,
len
,
(
UCHAR
*
)
"key"
,
sizeof
(
"key"
),
BCRYPT_HASH_REUSABLE_FLAG
);
ok
(
ret
==
STATUS_SUCCESS
||
broken
(
ret
==
STATUS_INVALID_PARAMETER
)
/* < win8 */
,
"got %08x
\n
"
,
ret
);
if
(
ret
==
STATUS_SUCCESS
)
{
ret
=
pBCryptHashData
(
hash
,
(
UCHAR
*
)
"test"
,
sizeof
(
"test"
),
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
memset
(
hmac_hash
,
0
,
sizeof
(
hmac_hash
));
ret
=
pBCryptFinishHash
(
hash
,
hmac_hash
,
test
->
hash_size
,
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
format_hash
(
hmac_hash
,
test
->
hash_size
,
str
);
ok
(
!
strcmp
(
str
,
test
->
hmac_hash
),
"got %s
\n
"
,
str
);
/* reuse it */
ret
=
pBCryptHashData
(
hash
,
(
UCHAR
*
)
"tset"
,
sizeof
(
"tset"
),
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
memset
(
hmac_hash
,
0
,
sizeof
(
hmac_hash
));
ret
=
pBCryptFinishHash
(
hash
,
hmac_hash
,
test
->
hash_size
,
0
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
format_hash
(
hmac_hash
,
test
->
hash_size
,
str
);
ok
(
!
strcmp
(
str
,
test
->
hmac_hash2
),
"got %s
\n
"
,
str
);
ret
=
pBCryptDestroyHash
(
hash
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %08x
\n
"
,
ret
);
}
ret
=
pBCryptDestroyHash
(
hash
);
ok
(
ret
==
STATUS_INVALID_PARAMETER
,
"got %08x
\n
"
,
ret
);
...
...
@@ -310,52 +370,57 @@ static void test_hash(const struct hash_test *test)
static
void
test_hashes
(
void
)
{
static
const
struct
hash_test
tests
[]
=
{
{
"SHA1"
,
20
,
"961fa64958818f767707072755d7018dcd278e94"
,
"2472cf65d0e090618d769d3e46f0d9446cf212da"
static
const
struct
hash_test
tests
[]
=
{
{
"SHA1"
,
20
,
"961fa64958818f767707072755d7018dcd278e94"
,
"9314f62ff64197143c91fc86de37e9ae776a3fb8"
,
"2472cf65d0e090618d769d3e46f0d9446cf212da"
,
"b2d2ba8cfd714d474cf0d9622cc5d15e1f53d53f"
,
},
{
"SHA25
6"
,
32
,
"ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126
"
,
"34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72"
{
"SHA256"
,
32
,
"ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb112
6"
,
"ea0938c118a7b15954f41b85195f2b42aec3a9429c63f593cfa65c137ffaa986"
,
"34c1aa473a4468a91d06e7cdbc75bc4f93b830ccfc2a47ffd74e8e6ed29e4c72
"
,
"55feb7052060bd99e33f36eb0982c7f4856eb6a84fbefe19a1afd9faafc3af6f"
,
},
{
"SHA384"
,
48
,
"62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae53"
"63eed1e743a692d70e0504b0cfd12ef9"
,
"4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37d"
"fdc836d96a704c03283bc05b4f6c5eb8"
{
"SHA384"
,
48
,
"62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae53"
"63eed1e743a692d70e0504b0cfd12ef9"
,
"724db7c0bbc51ef1ac3fc793083fc54c0e5c423faec9b11378c01c236b19aaaf"
"a45177ad055feaf003968cc40ece44c7"
,
"4b3e6d6ff2da121790ab7e7b9247583e3a7eed2db5bd4dabc680303b1608f37d"
"fdc836d96a704c03283bc05b4f6c5eb8"
,
"03e1818e5c165a0e54619e513acb06c393e1a6cb0ddbb4036b5f29617b334642"
"e6e0be8b214d8508595b17a8c4b4e7db"
,
},
{
"SHA512"
,
64
,
"d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1"
"ef6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca"
,
"415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f"
"2eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513"
{
"SHA512"
,
64
,
"d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1"
"ef6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca"
,
"7752d707b54d2b00e7d1c09120d189475b0fd2e31ebb988cf0a01fc8492ddc0b"
"3ca9c9ca61d9d7d1fb65ca7665e87f043c1d5bc9f786f8345e951c2d91ac594f"
,
"415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f"
"2eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513"
,
"1487bcecba46ae677622fa499e4cb2f0fdf92f6f3427cba76382d537a06e49c3"
"3e70a2fc1fc730092bf21128c3704cc6387f6dfbf7e2f9f315bbb894505a1205"
,
},
{
"MD2
"
,
16
,
"1bb33606ba908912a84221109d29cd7e
"
,
"7f05b0638d77f4a27f3a9c4d353cd648"
{
"MD2"
,
16
,
"1bb33606ba908912a84221109d29cd7e
"
,
"b9a6ad9323b17e2d0cd389dddd6ef78a"
,
"7f05b0638d77f4a27f3a9c4d353cd648
"
,
"05980873e6bfdd05dd7b30078de7e42a"
,
},
{
"MD4
"
,
16
,
"74b5db93c0b41e36ca7074338fc0b637
"
,
"bc2e8ac4d8248ed21b8d26227a30ea3a"
{
"MD4"
,
16
,
"74b5db93c0b41e36ca7074338fc0b637
"
,
"a14a9ff2059a8c28f47b01e6bc48a1bf"
,
"bc2e8ac4d8248ed21b8d26227a30ea3a
"
,
"b609db0eb4b8669db74f2c20099701e4"
,
},
{
"MD5
"
,
16
,
"e2a3e68d23ce348b8f68b3079de3d4c9
"
,
"7bda029b93fa8d817fcc9e13d6bdf092"
{
"MD5"
,
16
,
"e2a3e68d23ce348b8f68b3079de3d4c9
"
,
"bcdd7ca574342aa9db0e212348eacb16"
,
"7bda029b93fa8d817fcc9e13d6bdf092
"
,
"dd636ab8e9592c5088e57c37d44c5bb3"
,
}
};
unsigned
i
;
...
...
include/bcrypt.h
View file @
98ea906b
...
...
@@ -222,6 +222,9 @@ typedef PVOID BCRYPT_HASH_HANDLE;
/* Flags for BCryptEncrypt/BCryptDecrypt */
#define BCRYPT_BLOCK_PADDING 0x00000001
/* Flags for BCryptCreateHash */
#define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
NTSTATUS
WINAPI
BCryptCloseAlgorithmProvider
(
BCRYPT_ALG_HANDLE
,
ULONG
);
NTSTATUS
WINAPI
BCryptCreateHash
(
BCRYPT_ALG_HANDLE
,
BCRYPT_HASH_HANDLE
*
,
PUCHAR
,
ULONG
,
PUCHAR
,
ULONG
,
ULONG
);
NTSTATUS
WINAPI
BCryptDecrypt
(
BCRYPT_KEY_HANDLE
,
PUCHAR
,
ULONG
,
VOID
*
,
PUCHAR
,
ULONG
,
PUCHAR
,
ULONG
,
ULONG
*
,
ULONG
);
...
...
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