Skip to content

Implement psa_hash_compute and psa_hash_compare #327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 31, 2020
4 changes: 2 additions & 2 deletions include/psa/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
const uint8_t *hash,
const size_t hash_length);
size_t hash_length);

/** The type of the state data structure for multipart hash operations.
*
Expand Down Expand Up @@ -1300,7 +1300,7 @@ psa_status_t psa_mac_verify(psa_key_handle_t handle,
const uint8_t *input,
size_t input_length,
const uint8_t *mac,
const size_t mac_length);
size_t mac_length);

/** The type of the state data structure for multipart MAC operations.
*
Expand Down
62 changes: 54 additions & 8 deletions library/psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -2351,6 +2351,58 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
return( PSA_SUCCESS );
}

psa_status_t psa_hash_compute( psa_algorithm_t alg,
const uint8_t *input, size_t input_length,
uint8_t *hash, size_t hash_size,
size_t *hash_length )
{
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

*hash_length = hash_size;
status = psa_hash_setup( &operation, alg );
if( status != PSA_SUCCESS )
goto exit;
status = psa_hash_update( &operation, input, input_length );
if( status != PSA_SUCCESS )
goto exit;
status = psa_hash_finish( &operation, hash, hash_size, hash_length );
if( status != PSA_SUCCESS )
goto exit;

exit:
if( status == PSA_SUCCESS )
status = psa_hash_abort( &operation );
else
psa_hash_abort( &operation );
return( status );
}

psa_status_t psa_hash_compare( psa_algorithm_t alg,
const uint8_t *input, size_t input_length,
const uint8_t *hash, size_t hash_length )
{
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

status = psa_hash_setup( &operation, alg );
if( status != PSA_SUCCESS )
goto exit;
status = psa_hash_update( &operation, input, input_length );
if( status != PSA_SUCCESS )
goto exit;
status = psa_hash_verify( &operation, hash, hash_length );
if( status != PSA_SUCCESS )
goto exit;

exit:
if( status == PSA_SUCCESS )
status = psa_hash_abort( &operation );
else
psa_hash_abort( &operation );
return( status );
}

psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation )
{
Expand Down Expand Up @@ -2685,14 +2737,8 @@ static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,

if( key_length > block_size )
{
status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
if( status != PSA_SUCCESS )
goto cleanup;
status = psa_hash_update( &hmac->hash_ctx, key, key_length );
if( status != PSA_SUCCESS )
goto cleanup;
status = psa_hash_finish( &hmac->hash_ctx,
ipad, sizeof( ipad ), &key_length );
status = psa_hash_compute( hash_alg, key, key_length,
ipad, sizeof( ipad ), &key_length );
if( status != PSA_SUCCESS )
goto cleanup;
}
Expand Down
24 changes: 18 additions & 6 deletions tests/scripts/check-test-cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,30 @@
#
# This file is part of Mbed TLS (https://tls.mbed.org)

import argparse
import glob
import os
import re
import sys

class Results:
"""Store file and line information about errors or warnings in test suites."""
def __init__(self):

def __init__(self, options):
self.errors = 0
self.warnings = 0
self.ignore_warnings = options.quiet

def error(self, file_name, line_number, fmt, *args):
sys.stderr.write(('{}:{}:ERROR:' + fmt + '\n').
format(file_name, line_number, *args))
self.errors += 1

def warning(self, file_name, line_number, fmt, *args):
sys.stderr.write(('{}:{}:Warning:' + fmt + '\n')
.format(file_name, line_number, *args))
self.warnings += 1
if not self.ignore_warnings:
sys.stderr.write(('{}:{}:Warning:' + fmt + '\n')
.format(file_name, line_number, *args))
self.warnings += 1

def collect_test_directories():
"""Get the relative path for the TLS and Crypto test directories."""
Expand Down Expand Up @@ -108,16 +112,24 @@ def check_ssl_opt_sh(results, file_name):
file_name, line_number, description)

def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--quiet', '-q',
action='store_true',
help='Hide warnings')
parser.add_argument('--verbose', '-v',
action='store_false', dest='quiet',
help='Show warnings (default: on; undoes --quiet)')
options = parser.parse_args()
test_directories = collect_test_directories()
results = Results()
results = Results(options)
for directory in test_directories:
for data_file_name in glob.glob(os.path.join(directory, 'suites',
'*.data')):
check_test_suite(results, data_file_name)
ssl_opt_sh = os.path.join(directory, 'ssl-opt.sh')
if os.path.exists(ssl_opt_sh):
check_ssl_opt_sh(results, ssl_opt_sh)
if results.warnings or results.errors:
if (results.warnings or results.errors) and not options.quiet:
sys.stderr.write('{}: {} errors, {} warnings\n'
.format(sys.argv[0], results.errors, results.warnings))
sys.exit(1 if results.errors else 0)
Expand Down
Loading