core/crypto/kat/hash_kat.c (216 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. #include <stdint.h> #include "hash_kat.h" #include "common/buffer_util.h" #include "crypto/kat/hash_kat_vectors.h" #include "crypto/kat/hmac_kat_vectors.h" /** * Run a SHA known answer test (KAT) against for a single hash algorithm executing the complete * hash in a single 'calculate' call. * * @param hash The hash engine to use for the self-test. * @param hash_algo The hash algorithm to self-test. * @param expected The expected output for digest calculation. * @param kat_error Error code to report if the KAT fails. * * @return 0 if the tests completed successfully or an error code. */ static int hash_kat_run_calculate_self_test (const struct hash_engine *hash, enum hash_type hash_algo, const uint8_t *expected, int kat_error) { uint8_t digest[HASH_MAX_HASH_LEN]; size_t digest_length; int status; /* Test the calculate API. */ status = hash_calculate (hash, hash_algo, SHA_KAT_VECTORS_CALCULATE_DATA, SHA_KAT_VECTORS_CALCULATE_DATA_LEN, digest, sizeof (digest)); if (ROT_IS_ERROR (status)) { return status; } digest_length = status; status = buffer_compare (digest, expected, digest_length); if (status != 0) { return kat_error; } return 0; } /** * Run a SHA-1 known answer test (KAT) using a single call to calculate the digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_calculate_sha1 (const struct hash_engine *hash) { return hash_kat_run_calculate_self_test (hash, HASH_TYPE_SHA1, SHA_KAT_VECTORS_CALCULATE_SHA1_DIGEST, HASH_ENGINE_SHA1_SELF_TEST_FAILED); } /** * Run a SHA-256 known answer test (KAT) using a single call to calculate the digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_calculate_sha256 (const struct hash_engine *hash) { return hash_kat_run_calculate_self_test (hash, HASH_TYPE_SHA256, SHA_KAT_VECTORS_CALCULATE_SHA256_DIGEST, HASH_ENGINE_SHA256_SELF_TEST_FAILED); } /** * Run a SHA-384 known answer test (KAT) using a single call to calculate the digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_calculate_sha384 (const struct hash_engine *hash) { return hash_kat_run_calculate_self_test (hash, HASH_TYPE_SHA384, SHA_KAT_VECTORS_CALCULATE_SHA384_DIGEST, HASH_ENGINE_SHA384_SELF_TEST_FAILED); } /** * Run a SHA-512 known answer test (KAT) using a single call to calculate the digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_calculate_sha512 (const struct hash_engine *hash) { return hash_kat_run_calculate_self_test (hash, HASH_TYPE_SHA512, SHA_KAT_VECTORS_CALCULATE_SHA512_DIGEST, HASH_ENGINE_SHA512_SELF_TEST_FAILED); } /** * Run SHA known answer tests (KAT) for all supported algorithms using a single call to calculate * each digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_all_calculate_self_tests (const struct hash_engine *hash) { int status; #ifdef HASH_ENABLE_SHA1 status = hash_kat_run_self_test_calculate_sha1 (hash); if (status != 0) { return status; } #endif status = hash_kat_run_self_test_calculate_sha256 (hash); if (status != 0) { return status; } #ifdef HASH_ENABLE_SHA384 status = hash_kat_run_self_test_calculate_sha384 (hash); if (status != 0) { return status; } #endif #ifdef HASH_ENABLE_SHA512 status = hash_kat_run_self_test_calculate_sha512 (hash); if (status != 0) { return status; } #endif return 0; } /** * Run a SHA known answer test (KAT) for a single hash algorithm using the multi-step * start/update/finish set of calls. * * @param hash The hash engine to use for the self-test. * @param hash_algo The hash algorithm to self-test. * @param expected The expected output for digest calculation. * @param kat_error Error code to report if the KAT fails. * * @return 0 if the tests completed successfully or an error code. */ static int hash_kat_run_update_self_test (const struct hash_engine *hash, enum hash_type hash_algo, const uint8_t *expected, int kat_error) { uint8_t digest[HASH_MAX_HASH_LEN]; size_t digest_length; int status; /* Test the start/update/finish APIs. */ status = hash_start_new_hash (hash, hash_algo); if (status != 0) { return status; } digest_length = hash_get_hash_length (hash_algo); status = hash->update (hash, SHA_KAT_VECTORS_UPDATE_DATA_1, SHA_KAT_VECTORS_UPDATE_DATA_1_LEN); if (status != 0) { goto exit; } status = hash->update (hash, SHA_KAT_VECTORS_UPDATE_DATA_2, SHA_KAT_VECTORS_UPDATE_DATA_2_LEN); if (status != 0) { goto exit; } status = hash->finish (hash, digest, sizeof (digest)); if (status != 0) { goto exit; } status = buffer_compare (digest, expected, digest_length); if (status != 0) { return kat_error; } exit: if (status != 0) { hash->cancel (hash); } return status; } /** * Run a SHA-1 known answer test (KAT) using the start/update/finish sequence for digest * calculation. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_update_sha1 (const struct hash_engine *hash) { return hash_kat_run_update_self_test (hash, HASH_TYPE_SHA1, SHA_KAT_VECTORS_UPDATE_SHA1_DIGEST, HASH_ENGINE_SHA1_SELF_TEST_FAILED); } /** * Run a SHA-256 known answer test (KAT) using the start/update/finish sequence for digest * calculation. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_update_sha256 (const struct hash_engine *hash) { return hash_kat_run_update_self_test (hash, HASH_TYPE_SHA256, SHA_KAT_VECTORS_UPDATE_SHA256_DIGEST, HASH_ENGINE_SHA256_SELF_TEST_FAILED); } /** * Run a SHA-384 known answer test (KAT) using the start/update/finish sequence for digest * calculation. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_update_sha384 (const struct hash_engine *hash) { return hash_kat_run_update_self_test (hash, HASH_TYPE_SHA384, SHA_KAT_VECTORS_UPDATE_SHA384_DIGEST, HASH_ENGINE_SHA384_SELF_TEST_FAILED); } /** * Run a SHA-512 known answer test (KAT) using the start/update/finish sequence for digest * calculation. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_self_test_update_sha512 (const struct hash_engine *hash) { return hash_kat_run_update_self_test (hash, HASH_TYPE_SHA512, SHA_KAT_VECTORS_UPDATE_SHA512_DIGEST, HASH_ENGINE_SHA512_SELF_TEST_FAILED); } /** * Run SHA known answer tests (KAT) for all supported algorithms using the start/update/finish * sequence for calculating each digest. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_run_all_update_self_tests (const struct hash_engine *hash) { int status; #ifdef HASH_ENABLE_SHA1 status = hash_kat_run_self_test_update_sha1 (hash); if (status != 0) { return status; } #endif status = hash_kat_run_self_test_update_sha256 (hash); if (status != 0) { return status; } #ifdef HASH_ENABLE_SHA384 status = hash_kat_run_self_test_update_sha384 (hash); if (status != 0) { return status; } #endif #ifdef HASH_ENABLE_SHA512 status = hash_kat_run_self_test_update_sha512 (hash); if (status != 0) { return status; } #endif return 0; } /** * Run an HMAC known answer test (KAT) using a specific hash algorithm. * * @param hash The hash engine to use for the self-test. * @param hash_algo The hash algorithm to self-test. * @param expected The expected output for the HMAC calculation. * @param kat_error Error code to report if the KAT fails. * * @return 0 if the tests completed successfully or an error code. */ static int hash_kat_hmac_run_self_test (const struct hash_engine *hash, enum hmac_hash hash_algo, const uint8_t *expected, int kat_error) { uint8_t mac[HASH_MAX_HASH_LEN]; size_t mac_length; int status; mac_length = hash_hmac_get_hmac_length (hash_algo); /* Test direct HMAC generation. */ status = hash_generate_hmac (hash, HMAC_KAT_VECTORS_CALCULATE_KEY, HMAC_KAT_VECTORS_CALCULATE_KEY_LEN, HMAC_KAT_VECTORS_CALCULATE_DATA, HMAC_KAT_VECTORS_CALCULATE_DATA_LEN, hash_algo, mac, sizeof (mac)); if (status != 0) { return status; } status = buffer_compare (mac, expected, mac_length); if (status != 0) { return kat_error; } return 0; } /** * Run a SHA-1 HMAC known answer test (KAT). * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_hmac_run_self_test_sha1 (const struct hash_engine *hash) { return hash_kat_hmac_run_self_test (hash, HMAC_SHA1, HMAC_KAT_VECTORS_CALCULATE_SHA1_MAC, HASH_ENGINE_HMAC_SHA1_SELF_TEST_FAILED); } /** * Run a SHA-256 HMAC known answer test (KAT). * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_hmac_run_self_test_sha256 (const struct hash_engine *hash) { return hash_kat_hmac_run_self_test (hash, HMAC_SHA256, HMAC_KAT_VECTORS_CALCULATE_SHA256_MAC, HASH_ENGINE_HMAC_SHA256_SELF_TEST_FAILED); } /** * Run a SHA-384 HMAC known answer test (KAT). * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_hmac_run_self_test_sha384 (const struct hash_engine *hash) { return hash_kat_hmac_run_self_test (hash, HMAC_SHA384, HMAC_KAT_VECTORS_CALCULATE_SHA384_MAC, HASH_ENGINE_HMAC_SHA384_SELF_TEST_FAILED); } /** * Run a SHA-512 HMAC known answer test (KAT). * * In addition to testing the SHA-512 HMAC instantiation, this will also fully self-test the * provided hash engine for SHA-512. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_hmac_run_self_test_sha512 (const struct hash_engine *hash) { return hash_kat_hmac_run_self_test (hash, HMAC_SHA512, HMAC_KAT_VECTORS_CALCULATE_SHA512_MAC, HASH_ENGINE_HMAC_SHA512_SELF_TEST_FAILED); } /** * Run HMAC known answer tests (KAT) for all supported algorithms. * * @param hash The hash engine to use for the self-test. * * @return 0 if the tests completed successfully or an error code. */ int hash_kat_hmac_run_all_self_tests (const struct hash_engine *hash) { int status; #ifdef HASH_ENABLE_SHA1 status = hash_kat_hmac_run_self_test_sha1 (hash); if (status != 0) { return status; } #endif status = hash_kat_hmac_run_self_test_sha256 (hash); if (status != 0) { return status; } #ifdef HASH_ENABLE_SHA384 status = hash_kat_hmac_run_self_test_sha384 (hash); if (status != 0) { return status; } #endif #ifdef HASH_ENABLE_SHA512 status = hash_kat_hmac_run_self_test_sha512 (hash); if (status != 0) { return status; } #endif return 0; }