Commit 745df591 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

bcrypt: Force symmetric key reset if necessary.

parent 8e127868
...@@ -1000,14 +1000,6 @@ static BOOL key_is_symmetric( struct key *key ) ...@@ -1000,14 +1000,6 @@ static BOOL key_is_symmetric( struct key *key )
return builtin_algorithms[key->alg_id].class == BCRYPT_CIPHER_INTERFACE; return builtin_algorithms[key->alg_id].class == BCRYPT_CIPHER_INTERFACE;
} }
static BOOL is_zero_vector( const UCHAR *vector, ULONG len )
{
ULONG i;
if (!vector) return FALSE;
for (i = 0; i < len; i++) if (vector[i]) return FALSE;
return TRUE;
}
static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2 ) static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector2, ULONG len2 )
{ {
if (!vector && !vector2) return TRUE; if (!vector && !vector2) return TRUE;
...@@ -1015,10 +1007,9 @@ static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector ...@@ -1015,10 +1007,9 @@ static BOOL is_equal_vector( const UCHAR *vector, ULONG len, const UCHAR *vector
return !memcmp( vector, vector2, len ); return !memcmp( vector, vector2, len );
} }
static NTSTATUS key_symmetric_set_vector( struct key *key, UCHAR *vector, ULONG vector_len ) static NTSTATUS key_symmetric_set_vector( struct key *key, UCHAR *vector, ULONG vector_len, BOOL force_reset )
{ {
BOOL needs_reset = (!is_zero_vector( vector, vector_len ) || BOOL needs_reset = force_reset || !is_equal_vector( key->u.s.vector, key->u.s.vector_len, vector, vector_len );
!is_equal_vector( key->u.s.vector, key->u.s.vector_len, vector, vector_len ));
free( key->u.s.vector ); free( key->u.s.vector );
key->u.s.vector = NULL; key->u.s.vector = NULL;
...@@ -1155,7 +1146,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp ...@@ -1155,7 +1146,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp
if (auth_info->dwFlags & BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG) if (auth_info->dwFlags & BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG)
FIXME( "call chaining not implemented\n" ); FIXME( "call chaining not implemented\n" );
if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce ))) if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce, TRUE )))
return status; return status;
*ret_len = input_len; *ret_len = input_len;
...@@ -1191,7 +1182,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp ...@@ -1191,7 +1182,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp
if (!output) return STATUS_SUCCESS; if (!output) return STATUS_SUCCESS;
if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER; if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER;
if ((status = key_symmetric_set_vector( key, iv, iv_len ))) return status; if ((status = key_symmetric_set_vector( key, iv, iv_len, flags & BCRYPT_BLOCK_PADDING ))) return status;
encrypt_params.key = key; encrypt_params.key = key;
encrypt_params.input = input; encrypt_params.input = input;
...@@ -1202,7 +1193,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp ...@@ -1202,7 +1193,7 @@ static NTSTATUS key_symmetric_encrypt( struct key *key, UCHAR *input, ULONG inp
{ {
if ((status = UNIX_CALL( key_symmetric_encrypt, &encrypt_params ))) if ((status = UNIX_CALL( key_symmetric_encrypt, &encrypt_params )))
return status; return status;
if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0 ))) if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0, TRUE )))
return status; return status;
bytes_left -= key->u.s.block_size; bytes_left -= key->u.s.block_size;
encrypt_params.input += key->u.s.block_size; encrypt_params.input += key->u.s.block_size;
...@@ -1241,7 +1232,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu ...@@ -1241,7 +1232,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER; if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER;
if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER; if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER;
if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce ))) if ((status = key_symmetric_set_vector( key, auth_info->pbNonce, auth_info->cbNonce, TRUE )))
return status; return status;
*ret_len = input_len; *ret_len = input_len;
...@@ -1283,7 +1274,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu ...@@ -1283,7 +1274,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
else if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; else if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER; if (key->u.s.mode == MODE_ID_ECB && iv) return STATUS_INVALID_PARAMETER;
if ((status = key_symmetric_set_vector( key, iv, iv_len ))) return status; if ((status = key_symmetric_set_vector( key, iv, iv_len, flags & BCRYPT_BLOCK_PADDING ))) return status;
decrypt_params.key = key; decrypt_params.key = key;
decrypt_params.input = input; decrypt_params.input = input;
...@@ -1293,7 +1284,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu ...@@ -1293,7 +1284,7 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
while (bytes_left >= key->u.s.block_size) while (bytes_left >= key->u.s.block_size)
{ {
if ((status = UNIX_CALL( key_symmetric_decrypt, &decrypt_params ))) return status; if ((status = UNIX_CALL( key_symmetric_decrypt, &decrypt_params ))) return status;
if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0 ))) if (key->u.s.mode == MODE_ID_ECB && (status = key_symmetric_set_vector( key, NULL, 0, TRUE )))
return status; return status;
bytes_left -= key->u.s.block_size; bytes_left -= key->u.s.block_size;
decrypt_params.input += key->u.s.block_size; decrypt_params.input += key->u.s.block_size;
......
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