quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa_hash.c (5266B)


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