blob: 019b7ff54b8cef5c91e6fb2f78ca0756fedb367a [file] [log] [blame]
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +01001/*
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +01002 * This is a simple example of multi-part HMAC computation using the PSA
3 * Crypto API. It comes with a companion program hmac_non_psa.c, which does
4 * the same operations with the legacy MD API. The goal is that comparing the
5 * two programs will help people migrating to the PSA Crypto API.
Manuel Pégourié-Gonnard0e725c32022-01-27 11:15:33 +01006 *
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +01007 * Copyright The Mbed TLS Contributors
8 * SPDX-License-Identifier: Apache-2.0
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
11 * not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23/*
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010024 * When in comes to multi-part HMAC operations, the `mbedtls_md_context`
25 * serves a dual purpose (1) hold the key, and (2) save progress information
26 * for the current operation. With PSA those roles are held by two disinct
27 * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for
28 * multi-part progress.
29 *
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +010030 * This program and its companion hmac_non_psa.c illustrate this by doing the
31 * same sequence of multi-part HMAC computation with both APIs; looking at the
32 * two side by side should make the differences and similarities clear.
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010033 */
34
35#include <stdio.h>
36
37#include "mbedtls/build_info.h"
38
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +010039#if !defined(MBEDTLS_PSA_CRYPTO_C) || \
Manuel Pégourié-Gonnard9efbf532022-01-17 11:57:44 +010040 defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010041int main( void )
42{
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +010043 printf( "MBEDTLS_PSA_CRYPTO_C not defined, "
Manuel Pégourié-Gonnard9efbf532022-01-17 11:57:44 +010044 "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010045 return( 0 );
46}
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +010047#else
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010048
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010049#include "psa/crypto.h"
50
51/*
52 * Dummy inputs for HMAC
53 */
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +010054const unsigned char msg1_part1[] = { 0x01, 0x02 };
55const unsigned char msg1_part2[] = { 0x03, 0x04 };
56const unsigned char msg2_part1[] = { 0x05, 0x05 };
57const unsigned char msg2_part2[] = { 0x06, 0x06 };
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010058
59const unsigned char key_bytes[32] = { 0 };
60
61unsigned char out[32];
62
63void print_out( const char *title )
64{
65 printf( "%s:", title );
66 for( size_t i = 0; i < sizeof( out ); i++ )
67 printf( " %02x", out[i] );
68 printf( "\n" );
69}
70
71#define CHK( code ) \
72 do { \
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010073 status = code; \
74 if( status != PSA_SUCCESS ) \
75 goto exit; \
76 } while( 0 )
77
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +010078psa_status_t hmac_demo(void)
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +010079{
80 psa_status_t status;
81 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
82 psa_key_id_t key = 0;
83 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
84
85 /* prepare key */
86 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
87 psa_set_key_algorithm( &attributes, alg );
88 psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
89 psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) );
90
91 status = psa_import_key( &attributes, key_bytes, sizeof( key_bytes ), &key );
92 if( status != PSA_SUCCESS )
93 return( status );
94
95 /* prepare operation */
96 psa_mac_operation_t op = PSA_MAC_OPERATION_INIT;
97 size_t out_len = 0;
98
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +010099 /* compute HMAC(key, msg1_part1 | msg1_part2) */
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100100 CHK( psa_mac_sign_setup( &op, key, alg ) );
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +0100101 CHK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) );
102 CHK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100103 CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +0100104 print_out( "msg1" );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100105
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +0100106 /* compute HMAC(key, msg2_part1 | msg2_part2) */
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100107 CHK( psa_mac_sign_setup( &op, key, alg ) );
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +0100108 CHK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) );
109 CHK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100110 CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
Manuel Pégourié-Gonnardbeef9c22022-01-27 11:42:47 +0100111 print_out( "msg2" );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100112
113exit:
114 psa_mac_abort( &op );
Manuel Pégourié-Gonnard1a45c712022-01-27 12:17:20 +0100115 psa_destroy_key( key );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100116
117 return( status );
118}
119
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100120int main(void)
121{
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100122 psa_status_t status = psa_crypto_init();
123 if( status != PSA_SUCCESS )
124 printf( "psa init: %d\n", status );
125
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +0100126 status = hmac_demo();
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100127 if( status != PSA_SUCCESS )
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +0100128 printf( "hmac_demo: %d\n", status );
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +0100129}
130
Manuel Pégourié-Gonnardedf6e832022-01-27 12:36:39 +0100131#endif