blob: cde78f18bbcc1e47d75ee1f616b544eebe6fa5f6 [file] [log] [blame]
Manuel Pégourié-Gonnard667b5562021-11-22 13:00:17 +01001/*
2 * Copyright The Mbed TLS Contributors
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * This is a simple example of multi-part HMAC computation using both the old
20 * MD API and the new PSA API; its goal is to help migration to PSA Crypto.
21 *
22 * When in comes to multi-part HMAC operations, the `mbedtls_md_context`
23 * serves a dual purpose (1) hold the key, and (2) save progress information
24 * for the current operation. With PSA those roles are held by two disinct
25 * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for
26 * multi-part progress.
27 *
28 * This program illustrates this by doing the same sequence of multi-part HMAC
29 * computation with both APIs; looking at the two function md() and mac() side
30 * by side should make the differences and similarities clear.
31 */
32
33#include <stdio.h>
34
35#include "mbedtls/build_info.h"
36
37#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_MD_C)
38int main( void )
39{
40 printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C not defined.\r\n" );
41 return( 0 );
42}
43#else /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */
44
45#include "mbedtls/md.h"
46#include "psa/crypto.h"
47
48/*
49 * Dummy inputs for HMAC
50 */
51const unsigned char part1[] = { 0x01, 0x02 };
52const unsigned char part2[] = { 0x03, 0x04 };
53const unsigned char part3[] = { 0x05, 0x05 };
54const unsigned char part4[] = { 0x06, 0x06 };
55
56const unsigned char key_bytes[32] = { 0 };
57
58unsigned char out[32];
59
60void print_out( const char *title )
61{
62 printf( "%s:", title );
63 for( size_t i = 0; i < sizeof( out ); i++ )
64 printf( " %02x", out[i] );
65 printf( "\n" );
66}
67
68#define CHK( code ) \
69 do { \
70 ret = code; \
71 if( ret != 0 ) \
72 goto exit; \
73 } while( 0 )
74
75int md(void)
76{
77 int ret;
78 mbedtls_md_context_t ctx;
79
80 mbedtls_md_init( &ctx );
81
82 /* prepare context and load key */
83 CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) );
84 CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) );
85
86 /* compute HMAC(key, part 1 | part 2) */
87 CHK( mbedtls_md_hmac_update( &ctx, part1, sizeof( part1 ) ) );
88 CHK( mbedtls_md_hmac_update( &ctx, part2, sizeof( part2 ) ) );
89 CHK( mbedtls_md_hmac_finish( &ctx, out ) );
90 print_out( "12" );
91
92 /* compute HMAC(key, part 3 | part 4) */
93 CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation
94 CHK( mbedtls_md_hmac_update( &ctx, part3, sizeof( part3 ) ) );
95 CHK( mbedtls_md_hmac_update( &ctx, part4, sizeof( part4 ) ) );
96 CHK( mbedtls_md_hmac_finish( &ctx, out ) );
97 print_out( "34" );
98
99exit:
100 mbedtls_md_free( &ctx );
101
102 return( ret );
103}
104
105#undef CHK
106
107#define CHK( code ) \
108 do { \
109 status = code; \
110 if( status != PSA_SUCCESS ) \
111 goto exit; \
112 } while( 0 )
113
114psa_status_t mac(void)
115{
116 psa_status_t status;
117 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
118 psa_key_id_t key = 0;
119 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
120
121 /* prepare key */
122 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
123 psa_set_key_algorithm( &attributes, alg );
124 psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
125 psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) );
126
127 status = psa_import_key( &attributes, key_bytes, sizeof( key_bytes ), &key );
128 if( status != PSA_SUCCESS )
129 return( status );
130
131 /* prepare operation */
132 psa_mac_operation_t op = PSA_MAC_OPERATION_INIT;
133 size_t out_len = 0;
134
135 /* compute HMAC(key, part 1 | part 2) */
136 CHK( psa_mac_sign_setup( &op, key, alg ) );
137 CHK( psa_mac_update( &op, part1, sizeof( part1 ) ) );
138 CHK( psa_mac_update( &op, part2, sizeof( part2 ) ) );
139 CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
140 print_out( "12" );
141
142 /* compute HMAC(key, part 3 | part 4) */
143 CHK( psa_mac_sign_setup( &op, key, alg ) );
144 CHK( psa_mac_update( &op, part3, sizeof( part3 ) ) );
145 CHK( psa_mac_update( &op, part4, sizeof( part4 ) ) );
146 CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) );
147 print_out( "34" );
148
149exit:
150 psa_mac_abort( &op );
151
152 return( status );
153}
154
155#undef CHK
156
157int main(void)
158{
159 printf( "MD\n" );
160 int ret = md();
161 if( ret != 0 )
162 printf( "ret = %d (-0x%04x)\n", ret, -ret );
163
164 psa_status_t status = psa_crypto_init();
165 if( status != PSA_SUCCESS )
166 printf( "psa init: %d\n", status );
167
168 printf( "\nPSA\n" );
169 status = mac();
170 if( status != PSA_SUCCESS )
171 printf( "psa mac: %d\n", status );
172}
173
174#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */