1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Example computing a SHA-256 hash using the PSA Crypto API 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * The example computes the SHA-256 hash of a test string using the 5a8e1175bSopenharmony_ci * one-shot API call psa_hash_compute() and the using multi-part 6a8e1175bSopenharmony_ci * operation, which requires psa_hash_setup(), psa_hash_update() and 7a8e1175bSopenharmony_ci * psa_hash_finish(). The multi-part operation is popular on embedded 8a8e1175bSopenharmony_ci * devices where a rolling hash needs to be computed. 9a8e1175bSopenharmony_ci * 10a8e1175bSopenharmony_ci * 11a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 12a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 13a8e1175bSopenharmony_ci */ 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ci#include "psa/crypto.h" 16a8e1175bSopenharmony_ci#include <string.h> 17a8e1175bSopenharmony_ci#include <stdio.h> 18a8e1175bSopenharmony_ci#include <stdlib.h> 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 21a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci/* Information about hashing with the PSA API can be 24a8e1175bSopenharmony_ci * found here: 25a8e1175bSopenharmony_ci * https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html 26a8e1175bSopenharmony_ci * 27a8e1175bSopenharmony_ci * The algorithm used by this demo is SHA 256. 28a8e1175bSopenharmony_ci * Please see include/psa/crypto_values.h to see the other 29a8e1175bSopenharmony_ci * algorithms that are supported by Mbed TLS. 30a8e1175bSopenharmony_ci * If you switch to a different algorithm you will need to update 31a8e1175bSopenharmony_ci * the hash data in the EXAMPLE_HASH_VALUE macro below. */ 32a8e1175bSopenharmony_ci 33a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256) 34a8e1175bSopenharmony_ciint main(void) 35a8e1175bSopenharmony_ci{ 36a8e1175bSopenharmony_ci mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" 37a8e1175bSopenharmony_ci "not defined.\r\n"); 38a8e1175bSopenharmony_ci return EXIT_SUCCESS; 39a8e1175bSopenharmony_ci} 40a8e1175bSopenharmony_ci#else 41a8e1175bSopenharmony_ci 42a8e1175bSopenharmony_ci#define HASH_ALG PSA_ALG_SHA_256 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ciconst uint8_t sample_message[] = "Hello World!"; 45a8e1175bSopenharmony_ci/* sample_message is terminated with a null byte which is not part of 46a8e1175bSopenharmony_ci * the message itself so we make sure to subtract it in order to get 47a8e1175bSopenharmony_ci * the message length. */ 48a8e1175bSopenharmony_ciconst size_t sample_message_length = sizeof(sample_message) - 1; 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci#define EXPECTED_HASH_VALUE { \ 51a8e1175bSopenharmony_ci 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \ 52a8e1175bSopenharmony_ci 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \ 53a8e1175bSopenharmony_ci 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \ 54a8e1175bSopenharmony_ci} 55a8e1175bSopenharmony_ci 56a8e1175bSopenharmony_ciconst uint8_t expected_hash[] = EXPECTED_HASH_VALUE; 57a8e1175bSopenharmony_ciconst size_t expected_hash_len = sizeof(expected_hash); 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_ciint main(void) 60a8e1175bSopenharmony_ci{ 61a8e1175bSopenharmony_ci psa_status_t status; 62a8e1175bSopenharmony_ci uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)]; 63a8e1175bSopenharmony_ci size_t hash_length; 64a8e1175bSopenharmony_ci psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; 65a8e1175bSopenharmony_ci psa_hash_operation_t cloned_hash_operation = PSA_HASH_OPERATION_INIT; 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci mbedtls_printf("PSA Crypto API: SHA-256 example\n\n"); 68a8e1175bSopenharmony_ci 69a8e1175bSopenharmony_ci status = psa_crypto_init(); 70a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 71a8e1175bSopenharmony_ci mbedtls_printf("psa_crypto_init failed\n"); 72a8e1175bSopenharmony_ci return EXIT_FAILURE; 73a8e1175bSopenharmony_ci } 74a8e1175bSopenharmony_ci 75a8e1175bSopenharmony_ci /* Compute hash using multi-part operation */ 76a8e1175bSopenharmony_ci status = psa_hash_setup(&hash_operation, HASH_ALG); 77a8e1175bSopenharmony_ci if (status == PSA_ERROR_NOT_SUPPORTED) { 78a8e1175bSopenharmony_ci mbedtls_printf("unknown hash algorithm supplied\n"); 79a8e1175bSopenharmony_ci return EXIT_FAILURE; 80a8e1175bSopenharmony_ci } else if (status != PSA_SUCCESS) { 81a8e1175bSopenharmony_ci mbedtls_printf("psa_hash_setup failed\n"); 82a8e1175bSopenharmony_ci return EXIT_FAILURE; 83a8e1175bSopenharmony_ci } 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci status = psa_hash_update(&hash_operation, sample_message, sample_message_length); 86a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 87a8e1175bSopenharmony_ci mbedtls_printf("psa_hash_update failed\n"); 88a8e1175bSopenharmony_ci goto cleanup; 89a8e1175bSopenharmony_ci } 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci status = psa_hash_clone(&hash_operation, &cloned_hash_operation); 92a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 93a8e1175bSopenharmony_ci mbedtls_printf("PSA hash clone failed\n"); 94a8e1175bSopenharmony_ci goto cleanup; 95a8e1175bSopenharmony_ci } 96a8e1175bSopenharmony_ci 97a8e1175bSopenharmony_ci status = psa_hash_finish(&hash_operation, hash, sizeof(hash), &hash_length); 98a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 99a8e1175bSopenharmony_ci mbedtls_printf("psa_hash_finish failed\n"); 100a8e1175bSopenharmony_ci goto cleanup; 101a8e1175bSopenharmony_ci } 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_ci /* Check the result of the operation against the sample */ 104a8e1175bSopenharmony_ci if (hash_length != expected_hash_len || 105a8e1175bSopenharmony_ci (memcmp(hash, expected_hash, expected_hash_len) != 0)) { 106a8e1175bSopenharmony_ci mbedtls_printf("Multi-part hash operation gave the wrong result!\n\n"); 107a8e1175bSopenharmony_ci goto cleanup; 108a8e1175bSopenharmony_ci } 109a8e1175bSopenharmony_ci 110a8e1175bSopenharmony_ci status = 111a8e1175bSopenharmony_ci psa_hash_verify(&cloned_hash_operation, expected_hash, 112a8e1175bSopenharmony_ci expected_hash_len); 113a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 114a8e1175bSopenharmony_ci mbedtls_printf("psa_hash_verify failed\n"); 115a8e1175bSopenharmony_ci goto cleanup; 116a8e1175bSopenharmony_ci } else { 117a8e1175bSopenharmony_ci mbedtls_printf("Multi-part hash operation successful!\n"); 118a8e1175bSopenharmony_ci } 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci /* Clear local variables prior to one-shot hash demo */ 121a8e1175bSopenharmony_ci memset(hash, 0, sizeof(hash)); 122a8e1175bSopenharmony_ci hash_length = 0; 123a8e1175bSopenharmony_ci 124a8e1175bSopenharmony_ci /* Compute hash using one-shot function call */ 125a8e1175bSopenharmony_ci status = psa_hash_compute(HASH_ALG, 126a8e1175bSopenharmony_ci sample_message, sample_message_length, 127a8e1175bSopenharmony_ci hash, sizeof(hash), 128a8e1175bSopenharmony_ci &hash_length); 129a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 130a8e1175bSopenharmony_ci mbedtls_printf("psa_hash_compute failed\n"); 131a8e1175bSopenharmony_ci goto cleanup; 132a8e1175bSopenharmony_ci } 133a8e1175bSopenharmony_ci 134a8e1175bSopenharmony_ci if (hash_length != expected_hash_len || 135a8e1175bSopenharmony_ci (memcmp(hash, expected_hash, expected_hash_len) != 0)) { 136a8e1175bSopenharmony_ci mbedtls_printf("One-shot hash operation gave the wrong result!\n\n"); 137a8e1175bSopenharmony_ci goto cleanup; 138a8e1175bSopenharmony_ci } 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ci mbedtls_printf("One-shot hash operation successful!\n\n"); 141a8e1175bSopenharmony_ci 142a8e1175bSopenharmony_ci /* Print out result */ 143a8e1175bSopenharmony_ci mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message); 144a8e1175bSopenharmony_ci 145a8e1175bSopenharmony_ci for (size_t j = 0; j < expected_hash_len; j++) { 146a8e1175bSopenharmony_ci mbedtls_printf("%02x", hash[j]); 147a8e1175bSopenharmony_ci } 148a8e1175bSopenharmony_ci 149a8e1175bSopenharmony_ci mbedtls_printf("\n"); 150a8e1175bSopenharmony_ci 151a8e1175bSopenharmony_ci mbedtls_psa_crypto_free(); 152a8e1175bSopenharmony_ci return EXIT_SUCCESS; 153a8e1175bSopenharmony_ci 154a8e1175bSopenharmony_cicleanup: 155a8e1175bSopenharmony_ci psa_hash_abort(&hash_operation); 156a8e1175bSopenharmony_ci psa_hash_abort(&cloned_hash_operation); 157a8e1175bSopenharmony_ci return EXIT_FAILURE; 158a8e1175bSopenharmony_ci} 159a8e1175bSopenharmony_ci#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */ 160