Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/demos/mac/hmac-sha512.c
107715 views
1
/*-
2
* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
/*
11
* Example of using EVP_MAC_ methods to calculate
12
* a HMAC of static buffers
13
*/
14
15
#include <string.h>
16
#include <stdio.h>
17
#include <openssl/crypto.h>
18
#include <openssl/core_names.h>
19
#include <openssl/err.h>
20
#include <openssl/evp.h>
21
#include <openssl/hmac.h>
22
#include <openssl/params.h>
23
24
/*
25
* Hard coding the key into an application is very bad.
26
* It is done here solely for educational purposes.
27
*/
28
static unsigned char key[] = {
29
0x25,
30
0xfd,
31
0x12,
32
0x99,
33
0xdf,
34
0xad,
35
0x1a,
36
0x03,
37
0x0a,
38
0x81,
39
0x3c,
40
0x2d,
41
0xcc,
42
0x05,
43
0xd1,
44
0x5c,
45
0x17,
46
0x7a,
47
0x36,
48
0x73,
49
0x17,
50
0xef,
51
0x41,
52
0x75,
53
0x71,
54
0x18,
55
0xe0,
56
0x1a,
57
0xda,
58
0x99,
59
0xc3,
60
0x61,
61
0x38,
62
0xb5,
63
0xb1,
64
0xe0,
65
0x82,
66
0x2c,
67
0x70,
68
0xa4,
69
0xc0,
70
0x8e,
71
0x5e,
72
0xf9,
73
0x93,
74
0x9f,
75
0xcf,
76
0xf7,
77
0x32,
78
0x4d,
79
0x0c,
80
0xbd,
81
0x31,
82
0x12,
83
0x0f,
84
0x9a,
85
0x15,
86
0xee,
87
0x82,
88
0xdb,
89
0x8d,
90
0x29,
91
0x54,
92
0x14,
93
};
94
95
static const unsigned char data[] = "To be, or not to be, that is the question,\n"
96
"Whether tis nobler in the minde to suffer\n"
97
"The ſlings and arrowes of outragious fortune,\n"
98
"Or to take Armes again in a sea of troubles,\n"
99
"And by opposing, end them, to die to sleep;\n"
100
"No more, and by a sleep, to say we end\n"
101
"The heart-ache, and the thousand natural shocks\n"
102
"That flesh is heir to? tis a consumation\n"
103
"Devoutly to be wished. To die to sleep,\n"
104
"To sleepe, perchance to dreame, Aye, there's the rub,\n"
105
"For in that sleep of death what dreams may come\n"
106
"When we haue shuffled off this mortal coil\n"
107
"Must give us pause. There's the respect\n"
108
"That makes calamity of so long life:\n"
109
"For who would bear the Ships and Scorns of time,\n"
110
"The oppressor's wrong, the proud man's Contumely,\n"
111
"The pangs of dispised love, the Law's delay,\n";
112
113
/* The known value of the HMAC/SHA3-512 MAC of the above soliloqy */
114
static const unsigned char expected_output[] = {
115
0x3b,
116
0x77,
117
0x5f,
118
0xf1,
119
0x4f,
120
0x9e,
121
0xb9,
122
0x23,
123
0x8f,
124
0xdc,
125
0xa0,
126
0x68,
127
0x15,
128
0x7b,
129
0x8a,
130
0xf1,
131
0x96,
132
0x23,
133
0xaa,
134
0x3c,
135
0x1f,
136
0xe9,
137
0xdc,
138
0x89,
139
0x11,
140
0x7d,
141
0x58,
142
0x07,
143
0xe7,
144
0x96,
145
0x17,
146
0xe3,
147
0x44,
148
0x8b,
149
0x03,
150
0x37,
151
0x91,
152
0xc0,
153
0x6e,
154
0x06,
155
0x7c,
156
0x54,
157
0xe4,
158
0xa4,
159
0xcc,
160
0xd5,
161
0x16,
162
0xbb,
163
0x5e,
164
0x4d,
165
0x64,
166
0x7d,
167
0x88,
168
0x23,
169
0xc9,
170
0xb7,
171
0x25,
172
0xda,
173
0xbe,
174
0x4b,
175
0xe4,
176
0xd5,
177
0x34,
178
0x30,
179
};
180
181
/*
182
* A property query used for selecting the MAC implementation.
183
*/
184
static const char *propq = NULL;
185
186
int main(void)
187
{
188
int ret = EXIT_FAILURE;
189
OSSL_LIB_CTX *library_context = NULL;
190
EVP_MAC *mac = NULL;
191
EVP_MAC_CTX *mctx = NULL;
192
EVP_MD_CTX *digest_context = NULL;
193
unsigned char *out = NULL;
194
size_t out_len = 0;
195
OSSL_PARAM params[4], *p = params;
196
char digest_name[] = "SHA3-512";
197
198
library_context = OSSL_LIB_CTX_new();
199
if (library_context == NULL) {
200
fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
201
goto end;
202
}
203
204
/* Fetch the HMAC implementation */
205
mac = EVP_MAC_fetch(library_context, "HMAC", propq);
206
if (mac == NULL) {
207
fprintf(stderr, "EVP_MAC_fetch() returned NULL\n");
208
goto end;
209
}
210
211
/* Create a context for the HMAC operation */
212
mctx = EVP_MAC_CTX_new(mac);
213
if (mctx == NULL) {
214
fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n");
215
goto end;
216
}
217
218
/* The underlying digest to be used */
219
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, digest_name,
220
sizeof(digest_name));
221
*p = OSSL_PARAM_construct_end();
222
223
/* Initialise the HMAC operation */
224
if (!EVP_MAC_init(mctx, key, sizeof(key), params)) {
225
fprintf(stderr, "EVP_MAC_init() failed\n");
226
goto end;
227
}
228
229
/* Make one or more calls to process the data to be authenticated */
230
if (!EVP_MAC_update(mctx, data, sizeof(data))) {
231
fprintf(stderr, "EVP_MAC_update() failed\n");
232
goto end;
233
}
234
235
/* Make a call to the final with a NULL buffer to get the length of the MAC */
236
if (!EVP_MAC_final(mctx, NULL, &out_len, 0)) {
237
fprintf(stderr, "EVP_MAC_final() failed\n");
238
goto end;
239
}
240
out = OPENSSL_malloc(out_len);
241
if (out == NULL) {
242
fprintf(stderr, "malloc failed\n");
243
goto end;
244
}
245
/* Make one call to the final to get the MAC */
246
if (!EVP_MAC_final(mctx, out, &out_len, out_len)) {
247
fprintf(stderr, "EVP_MAC_final() failed\n");
248
goto end;
249
}
250
251
printf("Generated MAC:\n");
252
BIO_dump_indent_fp(stdout, out, out_len, 2);
253
putchar('\n');
254
255
if (out_len != sizeof(expected_output)) {
256
fprintf(stderr, "Generated MAC has an unexpected length\n");
257
goto end;
258
}
259
260
if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) {
261
fprintf(stderr, "Generated MAC does not match expected value\n");
262
goto end;
263
}
264
265
ret = EXIT_SUCCESS;
266
end:
267
if (ret != EXIT_SUCCESS)
268
ERR_print_errors_fp(stderr);
269
/* OpenSSL free functions will ignore NULL arguments */
270
OPENSSL_free(out);
271
EVP_MD_CTX_free(digest_context);
272
EVP_MAC_CTX_free(mctx);
273
EVP_MAC_free(mac);
274
OSSL_LIB_CTX_free(library_context);
275
return ret;
276
}
277
278