Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/demos/mac/cmac-aes256.c
108106 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 CMAC 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/cmac.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
0x6c,
30
0xde,
31
0x14,
32
0xf5,
33
0xd5,
34
0x2a,
35
0x4a,
36
0xdf,
37
0x12,
38
0x39,
39
0x1e,
40
0xbf,
41
0x36,
42
0xf9,
43
0x6a,
44
0x46,
45
0x48,
46
0xd0,
47
0xb6,
48
0x51,
49
0x89,
50
0xfc,
51
0x24,
52
0x85,
53
0xa8,
54
0x8d,
55
0xdf,
56
0x7e,
57
0x80,
58
0x14,
59
0xc8,
60
0xce,
61
};
62
63
static const unsigned char data[] = "To be, or not to be, that is the question,\n"
64
"Whether tis nobler in the minde to suffer\n"
65
"The ſlings and arrowes of outragious fortune,\n"
66
"Or to take Armes again in a sea of troubles,\n"
67
"And by opposing, end them, to die to sleep;\n"
68
"No more, and by a sleep, to say we end\n"
69
"The heart-ache, and the thousand natural shocks\n"
70
"That flesh is heir to? tis a consumation\n"
71
"Devoutly to be wished. To die to sleep,\n"
72
"To sleepe, perchance to dreame, Aye, there's the rub,\n"
73
"For in that sleep of death what dreams may come\n"
74
"When we haue shuffled off this mortal coil\n"
75
"Must give us pause. There's the respect\n"
76
"That makes calamity of so long life:\n"
77
"For who would bear the Ships and Scorns of time,\n"
78
"The oppressor's wrong, the proud man's Contumely,\n"
79
"The pangs of dispised love, the Law's delay,\n";
80
81
/* The known value of the CMAC/AES256 MAC of the above soliloqy */
82
static const unsigned char expected_output[] = {
83
0x67,
84
0x92,
85
0x32,
86
0x23,
87
0x50,
88
0x3d,
89
0xc5,
90
0xba,
91
0x78,
92
0xd4,
93
0x6d,
94
0x63,
95
0xf2,
96
0x2b,
97
0xe9,
98
0x56,
99
};
100
101
/*
102
* A property query used for selecting the MAC implementation.
103
*/
104
static const char *propq = NULL;
105
106
int main(void)
107
{
108
int ret = EXIT_FAILURE;
109
OSSL_LIB_CTX *library_context = NULL;
110
EVP_MAC *mac = NULL;
111
EVP_MAC_CTX *mctx = NULL;
112
unsigned char *out = NULL;
113
size_t out_len = 0;
114
OSSL_PARAM params[4], *p = params;
115
char cipher_name[] = "AES-256-CBC";
116
117
library_context = OSSL_LIB_CTX_new();
118
if (library_context == NULL) {
119
fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
120
goto end;
121
}
122
123
/* Fetch the CMAC implementation */
124
mac = EVP_MAC_fetch(library_context, "CMAC", propq);
125
if (mac == NULL) {
126
fprintf(stderr, "EVP_MAC_fetch() returned NULL\n");
127
goto end;
128
}
129
130
/* Create a context for the CMAC operation */
131
mctx = EVP_MAC_CTX_new(mac);
132
if (mctx == NULL) {
133
fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n");
134
goto end;
135
}
136
137
/* The underlying cipher to be used */
138
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
139
sizeof(cipher_name));
140
*p = OSSL_PARAM_construct_end();
141
142
/* Initialise the CMAC operation */
143
if (!EVP_MAC_init(mctx, key, sizeof(key), params)) {
144
fprintf(stderr, "EVP_MAC_init() failed\n");
145
goto end;
146
}
147
148
/* Make one or more calls to process the data to be authenticated */
149
if (!EVP_MAC_update(mctx, data, sizeof(data))) {
150
fprintf(stderr, "EVP_MAC_update() failed\n");
151
goto end;
152
}
153
154
/* Make a call to the final with a NULL buffer to get the length of the MAC */
155
if (!EVP_MAC_final(mctx, NULL, &out_len, 0)) {
156
fprintf(stderr, "EVP_MAC_final() failed\n");
157
goto end;
158
}
159
out = OPENSSL_malloc(out_len);
160
if (out == NULL) {
161
fprintf(stderr, "malloc failed\n");
162
goto end;
163
}
164
/* Make one call to the final to get the MAC */
165
if (!EVP_MAC_final(mctx, out, &out_len, out_len)) {
166
fprintf(stderr, "EVP_MAC_final() failed\n");
167
goto end;
168
}
169
170
printf("Generated MAC:\n");
171
BIO_dump_indent_fp(stdout, out, out_len, 2);
172
putchar('\n');
173
174
if (out_len != sizeof(expected_output)) {
175
fprintf(stderr, "Generated MAC has an unexpected length\n");
176
goto end;
177
}
178
179
if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) {
180
fprintf(stderr, "Generated MAC does not match expected value\n");
181
goto end;
182
}
183
184
ret = EXIT_SUCCESS;
185
end:
186
if (ret != EXIT_SUCCESS)
187
ERR_print_errors_fp(stderr);
188
/* OpenSSL free functions will ignore NULL arguments */
189
OPENSSL_free(out);
190
EVP_MAC_CTX_free(mctx);
191
EVP_MAC_free(mac);
192
OSSL_LIB_CTX_free(library_context);
193
return ret;
194
}
195
196