1 /* $OpenBSD: hmactest.c,v 1.8 2024/05/30 17:01:38 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 #include <stdio.h>
60 #include <string.h>
61 #include <stdlib.h>
62
63 #include <openssl/hmac.h>
64 #ifndef OPENSSL_NO_MD5
65 #include <openssl/md5.h>
66 #endif
67
68 #ifndef OPENSSL_NO_MD5
69 static struct test_st {
70 unsigned char key[16];
71 int key_len;
72 unsigned char data[64];
73 int data_len;
74 unsigned char *digest;
75 } test[8] = {
76 { "",
77 0,
78 "More text test vectors to stuff up EBCDIC machines :-)",
79 54,
80 (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
81 },
82 { {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
83 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
84 16,
85 "Hi There",
86 8,
87 (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
88 },
89 { "Jefe",
90 4,
91 "what do ya want for nothing?",
92 28,
93 (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
94 },
95 { {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
96 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
97 16,
98 {0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
99 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
100 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
101 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
102 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
103 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
104 0xdd,0xdd},
105 50,
106 (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
107 },
108 { "",
109 0,
110 "My test data",
111 12,
112 (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
113 },
114 { "",
115 0,
116 "My test data",
117 12,
118 (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
119 },
120 { "123456",
121 6,
122 "My test data",
123 12,
124 (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
125 },
126 { "12345",
127 5,
128 "My test data again",
129 12,
130 (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131 }
132 };
133 #endif
134
135 static char *pt(unsigned char *md, unsigned int len);
136
137 int
main(int argc,char * argv[])138 main(int argc, char *argv[])
139 {
140 #ifndef OPENSSL_NO_MD5
141 int i;
142 char *p;
143 #endif
144 int err = 0;
145 HMAC_CTX *ctx = NULL, *ctx2 = NULL;
146 unsigned char buf[EVP_MAX_MD_SIZE];
147 unsigned int len;
148
149 #ifdef OPENSSL_NO_MD5
150 printf("test skipped: MD5 disabled\n");
151 #else
152
153 for (i = 0; i < 4; i++) {
154 p = pt(HMAC(EVP_md5(),
155 test[i].key, test[i].key_len,
156 test[i].data, test[i].data_len, buf, NULL),
157 MD5_DIGEST_LENGTH);
158
159 if (strcmp(p, (char *)test[i].digest) != 0) {
160 printf("error calculating HMAC on %d entry'\n", i);
161 printf("got %s instead of %s\n", p, test[i].digest);
162 err++;
163 } else
164 printf("test %d ok\n", i);
165 }
166 #endif /* OPENSSL_NO_MD5 */
167
168 /* test4 */
169 if ((ctx = HMAC_CTX_new()) == NULL) {
170 printf("HMAC_CTX_init failed (test 4)\n");
171 exit(1);
172 }
173 if (HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) {
174 printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
175 err++;
176 goto test5;
177 }
178 if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
179 printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
180 err++;
181 goto test5;
182 }
183 if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) {
184 printf("Should fail to initialise HMAC with empty key (test 4)\n");
185 err++;
186 goto test5;
187 }
188 if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
189 printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
190 err++;
191 goto test5;
192 }
193 printf("test 4 ok\n");
194 test5:
195 HMAC_CTX_reset(ctx);
196 if (HMAC_Init_ex(ctx, test[4].key, test[4].key_len, NULL, NULL)) {
197 printf("Should fail to initialise HMAC with empty MD (test 5)\n");
198 err++;
199 goto test6;
200 }
201 if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
202 printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
203 err++;
204 goto test6;
205 }
206 if (HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)) {
207 printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
208 err++;
209 goto test6;
210 }
211 if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
212 printf("Failed to initialise HMAC (test 5)\n");
213 err++;
214 goto test6;
215 }
216 if (!HMAC_Update(ctx, test[4].data, test[4].data_len)) {
217 printf("Error updating HMAC with data (test 5)\n");
218 err++;
219 goto test6;
220 }
221 if (!HMAC_Final(ctx, buf, &len)) {
222 printf("Error finalising data (test 5)\n");
223 err++;
224 goto test6;
225 }
226 p = pt(buf, len);
227 if (strcmp(p, (char *)test[4].digest) != 0) {
228 printf("Error calculating interim HMAC on test 5\n");
229 printf("got %s instead of %s\n", p, test[4].digest);
230 err++;
231 goto test6;
232 }
233 if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) {
234 printf("Should disallow changing MD without a new key (test 5)\n");
235 err++;
236 goto test6;
237 }
238 if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
239 printf("Failed to reinitialise HMAC (test 5)\n");
240 err++;
241 goto test6;
242 }
243 if (!HMAC_Update(ctx, test[5].data, test[5].data_len)) {
244 printf("Error updating HMAC with data (sha256) (test 5)\n");
245 err++;
246 goto test6;
247 }
248 if (!HMAC_Final(ctx, buf, &len)) {
249 printf("Error finalising data (sha256) (test 5)\n");
250 err++;
251 goto test6;
252 }
253 p = pt(buf, len);
254 if (strcmp(p, (char *)test[5].digest) != 0) {
255 printf("Error calculating 2nd interim HMAC on test 5\n");
256 printf("got %s instead of %s\n", p, test[5].digest);
257 err++;
258 goto test6;
259 }
260 if (!HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) {
261 printf("Failed to reinitialise HMAC with key (test 5)\n");
262 err++;
263 goto test6;
264 }
265 if (!HMAC_Update(ctx, test[6].data, test[6].data_len)) {
266 printf("Error updating HMAC with data (new key) (test 5)\n");
267 err++;
268 goto test6;
269 }
270 if (!HMAC_Final(ctx, buf, &len)) {
271 printf("Error finalising data (new key) (test 5)\n");
272 err++;
273 goto test6;
274 }
275 p = pt(buf, len);
276 if (strcmp(p, (char *)test[6].digest) != 0) {
277 printf("error calculating HMAC on test 5\n");
278 printf("got %s instead of %s\n", p, test[6].digest);
279 err++;
280 } else {
281 printf("test 5 ok\n");
282 }
283 test6:
284 HMAC_CTX_reset(ctx);
285 if (!HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
286 printf("Failed to initialise HMAC (test 6)\n");
287 err++;
288 goto end;
289 }
290 if (!HMAC_Update(ctx, test[7].data, test[7].data_len)) {
291 printf("Error updating HMAC with data (test 6)\n");
292 err++;
293 goto end;
294 }
295 if ((ctx2 = HMAC_CTX_new()) == NULL) {
296 printf("HMAC_CTX_new failed (test 6)\n");
297 exit(1);
298 }
299 if (!HMAC_CTX_copy(ctx2, ctx)) {
300 printf("Failed to copy HMAC_CTX (test 6)\n");
301 err++;
302 goto end;
303 }
304 if (!HMAC_Final(ctx2, buf, &len)) {
305 printf("Error finalising data (test 6)\n");
306 err++;
307 goto end;
308 }
309 p = pt(buf, len);
310 if (strcmp(p, (char *)test[7].digest) != 0) {
311 printf("Error calculating HMAC on test 6\n");
312 printf("got %s instead of %s\n", p, test[7].digest);
313 err++;
314 } else {
315 printf("test 6 ok\n");
316 }
317 end:
318 HMAC_CTX_free(ctx);
319 HMAC_CTX_free(ctx2);
320 exit(err);
321 return(0);
322 }
323
324 #ifndef OPENSSL_NO_MD5
325 static char *
pt(unsigned char * md,unsigned int len)326 pt(unsigned char *md, unsigned int len)
327 {
328 unsigned int i;
329 static char buf[80];
330
331 for (i = 0; i < len; i++)
332 snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", md[i]);
333 return(buf);
334 }
335 #endif
336