blob: b5b566c1878df8660f311efb552243326c50d41e [file] [log] [blame]
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +01001/*
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
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License"); you may
15 * not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
22 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 */
26
27
28#include "psa/crypto.h"
29#include <string.h>
30#include <stdio.h>
31#include <stdlib.h>
32
33#include "mbedtls/build_info.h"
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010034#include "mbedtls/platform.h"
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010035
Thomas Daubney606110f2023-07-28 15:57:10 +010036/* The algorithm used by this demo is SHA 256.
37 * Please see include/psa/crypto_values.h to see the other
38 * algorithms that are supported. If you switch to a different
39 * algorithm you will need to update the hash data in the
40 * SAMPLE_HASH_DATA macro below.*/
41
Thomas Daubney1db78fa2023-07-24 16:49:14 +010042#define HASH_ALG PSA_ALG_SHA_256
43
Thomas Daubneyc918c322023-07-28 17:15:03 +010044#define SAMPLE_HASH_DATA { \
45 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
46 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \
47 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010048}
49
Thomas Daubney606110f2023-07-28 15:57:10 +010050const uint8_t sample_message[] = "Hello World!";
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010051
Thomas Daubney606110f2023-07-28 15:57:10 +010052const uint8_t sample_hash[] = SAMPLE_HASH_DATA;
53const size_t sample_hash_len = sizeof(sample_hash);
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010054
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010055#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)
Thomas Daubney209c9c92023-07-18 14:59:45 +010056int main(void)
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010057{
Thomas Daubney2c872342023-07-28 14:21:38 +010058 mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
Thomas Daubney9520df72023-07-25 10:56:54 +010059 "not defined.\r\n");
Thomas Daubney209c9c92023-07-18 14:59:45 +010060 return EXIT_SUCCESS;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010061}
62#else
63
Thomas Daubney209c9c92023-07-18 14:59:45 +010064int main(void)
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010065{
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010066 psa_status_t status;
Thomas Daubney1db78fa2023-07-24 16:49:14 +010067 uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
Thomas Daubney6fc4ca22023-07-28 14:31:06 +010068 size_t hash_length;
Thomas Daubneyc0500372023-07-28 14:44:25 +010069 psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
70 psa_hash_operation_t cloned_hash_operation = PSA_HASH_OPERATION_INIT;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010071
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010072 mbedtls_printf("PSA Crypto API: SHA-256 example\n\n");
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010073
Thomas Daubney209c9c92023-07-18 14:59:45 +010074 status = psa_crypto_init();
75 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010076 mbedtls_printf("psa_crypto_init failed\n");
Thomas Daubney209c9c92023-07-18 14:59:45 +010077 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010078 }
79
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010080 /* Compute hash using multi-part operation */
81
Thomas Daubneyc0500372023-07-28 14:44:25 +010082 status = psa_hash_setup(&hash_operation, HASH_ALG);
Thomas Daubney209c9c92023-07-18 14:59:45 +010083 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010084 mbedtls_printf("psa_hash_setup failed\n");
Thomas Daubneyc0500372023-07-28 14:44:25 +010085 psa_hash_abort(&hash_operation);
86 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +010087 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010088 }
89
Thomas Daubneyc918c322023-07-28 17:15:03 +010090 /* Note: Here we use sizeof(sample_message) - 1 since we don't wish to
91 * include the null byte in the hash computation */
92 status = psa_hash_update(&hash_operation, sample_message, sizeof(sample_message) - 1);
Thomas Daubney209c9c92023-07-18 14:59:45 +010093 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +010094 mbedtls_printf("psa_hash_update failed\n");
Thomas Daubneyc0500372023-07-28 14:44:25 +010095 psa_hash_abort(&hash_operation);
96 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +010097 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +010098 }
99
Thomas Daubneyc0500372023-07-28 14:44:25 +0100100 status = psa_hash_clone(&hash_operation, &cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100101 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100102 mbedtls_printf("PSA hash clone failed");
Thomas Daubneyc0500372023-07-28 14:44:25 +0100103 psa_hash_abort(&hash_operation);
104 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100105 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100106 }
107
Thomas Daubneyc0500372023-07-28 14:44:25 +0100108 status = psa_hash_finish(&hash_operation, hash, sizeof(hash), &hash_length);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100109 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100110 mbedtls_printf("psa_hash_finish failed\n");
Thomas Daubneyc0500372023-07-28 14:44:25 +0100111 psa_hash_abort(&hash_operation);
112 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100113 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100114 }
115
Thomas Daubneyce141242023-07-28 16:14:20 +0100116 /* Check the result of the operation against the sample */
117 if ((memcmp(hash, sample_hash, sample_hash_len) != 0) || hash_length != sample_hash_len)
118 {
119 mbedtls_printf("Multi-part hash operation gave the wrong result!\n\n");
120 psa_hash_abort(&hash_operation);
121 psa_hash_abort(&cloned_hash_operation);
122 return EXIT_FAILURE;
123 }
124
Thomas Daubney209c9c92023-07-18 14:59:45 +0100125 status =
Thomas Daubney606110f2023-07-28 15:57:10 +0100126 psa_hash_verify(&cloned_hash_operation, sample_hash,
127 sample_hash_len);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100128 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100129 mbedtls_printf("psa_hash_verify failed\n");
Thomas Daubneyc0500372023-07-28 14:44:25 +0100130 psa_hash_abort(&hash_operation);
131 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100132 return EXIT_FAILURE;
133 } else {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100134 mbedtls_printf("Multi-part hash operation successful!\n");
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100135 }
136
Thomas Daubney3071c852023-07-28 14:47:47 +0100137 /* Clear local variables prior to one-shot hash demo */
Thomas Daubney209c9c92023-07-18 14:59:45 +0100138 memset(hash, 0, sizeof(hash));
Thomas Daubney6fc4ca22023-07-28 14:31:06 +0100139 hash_length = 0;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100140
Thomas Daubney3071c852023-07-28 14:47:47 +0100141 /* Compute hash using one-shot function call */
Thomas Daubney1db78fa2023-07-24 16:49:14 +0100142 status = psa_hash_compute(HASH_ALG,
Thomas Daubneyc918c322023-07-28 17:15:03 +0100143 sample_message, sizeof(sample_message) - 1,
Thomas Daubney209c9c92023-07-18 14:59:45 +0100144 hash, sizeof(hash),
Thomas Daubney6fc4ca22023-07-28 14:31:06 +0100145 &hash_length);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100146 if (status != PSA_SUCCESS) {
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100147 mbedtls_printf("psa_hash_compute failed\n");
Thomas Daubneyc0500372023-07-28 14:44:25 +0100148 psa_hash_abort(&hash_operation);
149 psa_hash_abort(&cloned_hash_operation);
Thomas Daubney209c9c92023-07-18 14:59:45 +0100150 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100151 }
152
Thomas Daubneyfbe742b2023-07-28 16:17:38 +0100153 if (memcmp(hash, sample_hash, sample_hash_len) != 0 || hash_length != sample_hash_len)
Thomas Daubneya2b75192023-07-28 15:21:46 +0100154 {
155 mbedtls_printf("One-shot hash operation gave the wrong result!\n\n");
156 psa_hash_abort(&hash_operation);
157 psa_hash_abort(&cloned_hash_operation);
158 return EXIT_FAILURE;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100159 }
160
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100161 mbedtls_printf("One-shot hash operation successful!\n\n");
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100162
Thomas Daubney1f987362023-07-28 15:23:06 +0100163 /* Print out result */
Thomas Daubney606110f2023-07-28 15:57:10 +0100164 mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message);
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100165
Thomas Daubney606110f2023-07-28 15:57:10 +0100166 for (size_t j = 0; j < sample_hash_len; j++) {
Thomas Daubney9730cb12023-07-28 15:07:19 +0100167 mbedtls_printf("%02x", hash[j]);
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100168 }
169
Thomas Daubneyf7348ae2023-07-24 12:18:40 +0100170 mbedtls_printf("\n");
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100171
Thomas Daubney209c9c92023-07-18 14:59:45 +0100172 mbedtls_psa_crypto_free();
173 return EXIT_SUCCESS;
Hannes Tschofenigf8b9ebf2023-07-18 13:46:10 +0100174}
Thomas Daubneyc0500372023-07-28 14:44:25 +0100175#endif /* MBEDTLS_PSA_CRYPTO_C && PSA_WANT_ALG_SHA_256 */