xref: /freebsd/crypto/openssl/test/hmactest.c (revision 0d0c8621fd181e507f0fb50ffcca606faf66a8c2)
1e0c4386eSCy Schubert /*
2e0c4386eSCy Schubert  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  *
4e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8e0c4386eSCy Schubert  */
9e0c4386eSCy Schubert 
10e0c4386eSCy Schubert /*
11e0c4386eSCy Schubert  * HMAC low level APIs are deprecated for public use, but still ok for internal
12e0c4386eSCy Schubert  * use.
13e0c4386eSCy Schubert  */
14e0c4386eSCy Schubert #include "internal/deprecated.h"
15e0c4386eSCy Schubert 
16e0c4386eSCy Schubert #include <stdio.h>
17e0c4386eSCy Schubert #include <string.h>
18e0c4386eSCy Schubert #include <stdlib.h>
19e0c4386eSCy Schubert 
20e0c4386eSCy Schubert #include "internal/nelem.h"
21e0c4386eSCy Schubert 
22e0c4386eSCy Schubert # include <openssl/hmac.h>
23e0c4386eSCy Schubert # include <openssl/sha.h>
24e0c4386eSCy Schubert # ifndef OPENSSL_NO_MD5
25e0c4386eSCy Schubert #  include <openssl/md5.h>
26e0c4386eSCy Schubert # endif
27e0c4386eSCy Schubert 
28e0c4386eSCy Schubert # ifdef CHARSET_EBCDIC
29e0c4386eSCy Schubert #  include <openssl/ebcdic.h>
30e0c4386eSCy Schubert # endif
31e0c4386eSCy Schubert 
32e0c4386eSCy Schubert #include "testutil.h"
33e0c4386eSCy Schubert 
34e0c4386eSCy Schubert # ifndef OPENSSL_NO_MD5
35e0c4386eSCy Schubert static struct test_st {
36e0c4386eSCy Schubert     const char key[16];
37e0c4386eSCy Schubert     int key_len;
38e0c4386eSCy Schubert     const unsigned char data[64];
39e0c4386eSCy Schubert     int data_len;
40e0c4386eSCy Schubert     const char *digest;
41e0c4386eSCy Schubert } test[8] = {
42e0c4386eSCy Schubert     {
43e0c4386eSCy Schubert         "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
44e0c4386eSCy Schubert         "e9139d1e6ee064ef8cf514fc7dc83e86",
45e0c4386eSCy Schubert     },
46e0c4386eSCy Schubert     {
47e0c4386eSCy Schubert         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
48e0c4386eSCy Schubert         16, "Hi There", 8,
49e0c4386eSCy Schubert         "9294727a3638bb1c13f48ef8158bfc9d",
50e0c4386eSCy Schubert     },
51e0c4386eSCy Schubert     {
52e0c4386eSCy Schubert         "Jefe", 4, "what do ya want for nothing?", 28,
53e0c4386eSCy Schubert         "750c783e6ab0b503eaa86e310a5db738",
54e0c4386eSCy Schubert     },
55e0c4386eSCy Schubert     {
56e0c4386eSCy Schubert         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
57e0c4386eSCy Schubert         16, {
58e0c4386eSCy Schubert             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
59e0c4386eSCy Schubert             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
60e0c4386eSCy Schubert             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
61e0c4386eSCy Schubert             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
62e0c4386eSCy Schubert             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
63e0c4386eSCy Schubert         }, 50, "56be34521d144c88dbb8c733f0e8b3f6",
64e0c4386eSCy Schubert     },
65e0c4386eSCy Schubert     {
66e0c4386eSCy Schubert         "", 0, "My test data", 12,
67e0c4386eSCy Schubert         "61afdecb95429ef494d61fdee15990cabf0826fc"
68e0c4386eSCy Schubert     },
69e0c4386eSCy Schubert     {
70e0c4386eSCy Schubert         "", 0, "My test data", 12,
71e0c4386eSCy Schubert         "2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
72e0c4386eSCy Schubert     },
73e0c4386eSCy Schubert     {
74e0c4386eSCy Schubert         "123456", 6, "My test data", 12,
75e0c4386eSCy Schubert         "bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
76e0c4386eSCy Schubert     },
77e0c4386eSCy Schubert     {
78e0c4386eSCy Schubert         "12345", 5, "My test data again", 18,
79e0c4386eSCy Schubert         "a12396ceddd2a85f4c656bc1e0aa50c78cffde3e"
80e0c4386eSCy Schubert     }
81e0c4386eSCy Schubert };
82e0c4386eSCy Schubert # endif
83e0c4386eSCy Schubert 
84e0c4386eSCy Schubert static char *pt(unsigned char *md, unsigned int len);
85e0c4386eSCy Schubert 
86e0c4386eSCy Schubert 
87e0c4386eSCy Schubert # ifndef OPENSSL_NO_MD5
test_hmac_md5(int idx)88e0c4386eSCy Schubert static int test_hmac_md5(int idx)
89e0c4386eSCy Schubert {
90e0c4386eSCy Schubert     char *p;
91e0c4386eSCy Schubert #  ifdef CHARSET_EBCDIC
92e0c4386eSCy Schubert     ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
93e0c4386eSCy Schubert     ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
94e0c4386eSCy Schubert     ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
95e0c4386eSCy Schubert     ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
96e0c4386eSCy Schubert #  endif
97e0c4386eSCy Schubert 
98e0c4386eSCy Schubert     p = pt(HMAC(EVP_md5(),
99e0c4386eSCy Schubert                 test[idx].key, test[idx].key_len,
100e0c4386eSCy Schubert                 test[idx].data, test[idx].data_len, NULL, NULL),
101e0c4386eSCy Schubert                 MD5_DIGEST_LENGTH);
102e0c4386eSCy Schubert 
103e0c4386eSCy Schubert     return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest);
104e0c4386eSCy Schubert }
105e0c4386eSCy Schubert # endif
106e0c4386eSCy Schubert 
test_hmac_bad(void)107e0c4386eSCy Schubert static int test_hmac_bad(void)
108e0c4386eSCy Schubert {
109e0c4386eSCy Schubert     HMAC_CTX *ctx = NULL;
110e0c4386eSCy Schubert     int ret = 0;
111e0c4386eSCy Schubert 
112e0c4386eSCy Schubert     ctx = HMAC_CTX_new();
113e0c4386eSCy Schubert     if (!TEST_ptr(ctx)
114e0c4386eSCy Schubert         || !TEST_ptr_null(HMAC_CTX_get_md(ctx))
115e0c4386eSCy Schubert         || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL))
116e0c4386eSCy Schubert         || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len))
117e0c4386eSCy Schubert         || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL))
118e0c4386eSCy Schubert         || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)))
119e0c4386eSCy Schubert         goto err;
120e0c4386eSCy Schubert 
121e0c4386eSCy Schubert     ret = 1;
122e0c4386eSCy Schubert err:
123e0c4386eSCy Schubert     HMAC_CTX_free(ctx);
124e0c4386eSCy Schubert     return ret;
125e0c4386eSCy Schubert }
126e0c4386eSCy Schubert 
test_hmac_run(void)127e0c4386eSCy Schubert static int test_hmac_run(void)
128e0c4386eSCy Schubert {
129e0c4386eSCy Schubert     char *p;
130e0c4386eSCy Schubert     HMAC_CTX *ctx = NULL;
131e0c4386eSCy Schubert     unsigned char buf[EVP_MAX_MD_SIZE];
132e0c4386eSCy Schubert     unsigned int len;
133e0c4386eSCy Schubert     int ret = 0;
134e0c4386eSCy Schubert 
135e0c4386eSCy Schubert     if (!TEST_ptr(ctx = HMAC_CTX_new()))
136e0c4386eSCy Schubert         return 0;
137e0c4386eSCy Schubert     HMAC_CTX_reset(ctx);
138e0c4386eSCy Schubert 
139e0c4386eSCy Schubert     if (!TEST_ptr(ctx)
140e0c4386eSCy Schubert         || !TEST_ptr_null(HMAC_CTX_get_md(ctx))
141e0c4386eSCy Schubert         || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL))
142e0c4386eSCy Schubert         || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len))
143e0c4386eSCy Schubert         || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)))
144e0c4386eSCy Schubert         goto err;
145e0c4386eSCy Schubert 
146e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL))
147e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[4].data, test[4].data_len))
148e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx, buf, &len)))
149e0c4386eSCy Schubert         goto err;
150e0c4386eSCy Schubert 
151e0c4386eSCy Schubert     p = pt(buf, len);
152e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
153e0c4386eSCy Schubert         goto err;
154e0c4386eSCy Schubert 
155e0c4386eSCy Schubert     if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)))
156e0c4386eSCy Schubert         goto err;
157e0c4386eSCy Schubert 
158e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, test[5].key, test[5].key_len, EVP_sha256(), NULL))
159e0c4386eSCy Schubert         || !TEST_ptr_eq(HMAC_CTX_get_md(ctx), EVP_sha256())
160e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[5].data, test[5].data_len))
161e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx, buf, &len)))
162e0c4386eSCy Schubert         goto err;
163e0c4386eSCy Schubert 
164e0c4386eSCy Schubert     p = pt(buf, len);
165e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest))
166e0c4386eSCy Schubert         goto err;
167e0c4386eSCy Schubert 
168e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL))
169e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len))
170e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx, buf, &len)))
171e0c4386eSCy Schubert         goto err;
172e0c4386eSCy Schubert     p = pt(buf, len);
173e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
174e0c4386eSCy Schubert         goto err;
175e0c4386eSCy Schubert 
176e0c4386eSCy Schubert     /* Test reusing a key */
177e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL))
178e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len))
179e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx, buf, &len)))
180e0c4386eSCy Schubert         goto err;
181e0c4386eSCy Schubert     p = pt(buf, len);
182e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
183e0c4386eSCy Schubert         goto err;
184e0c4386eSCy Schubert 
185e0c4386eSCy Schubert     /*
186e0c4386eSCy Schubert      * Test reusing a key where the digest is provided again but is the same as
187e0c4386eSCy Schubert      * last time
188e0c4386eSCy Schubert      */
189e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL))
190e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len))
191e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx, buf, &len)))
192e0c4386eSCy Schubert         goto err;
193e0c4386eSCy Schubert     p = pt(buf, len);
194e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
195e0c4386eSCy Schubert         goto err;
196e0c4386eSCy Schubert 
197e0c4386eSCy Schubert     ret = 1;
198e0c4386eSCy Schubert err:
199e0c4386eSCy Schubert     HMAC_CTX_free(ctx);
200e0c4386eSCy Schubert     return ret;
201e0c4386eSCy Schubert }
202e0c4386eSCy Schubert 
203e0c4386eSCy Schubert 
test_hmac_single_shot(void)204e0c4386eSCy Schubert static int test_hmac_single_shot(void)
205e0c4386eSCy Schubert {
206e0c4386eSCy Schubert     char *p;
207e0c4386eSCy Schubert 
208e0c4386eSCy Schubert     /* Test single-shot with NULL key. */
209e0c4386eSCy Schubert     p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len,
210e0c4386eSCy Schubert                 NULL, NULL), SHA_DIGEST_LENGTH);
211e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
212e0c4386eSCy Schubert         return 0;
213e0c4386eSCy Schubert 
214e0c4386eSCy Schubert     return 1;
215e0c4386eSCy Schubert }
216e0c4386eSCy Schubert 
217e0c4386eSCy Schubert 
test_hmac_copy(void)218e0c4386eSCy Schubert static int test_hmac_copy(void)
219e0c4386eSCy Schubert {
220e0c4386eSCy Schubert     char *p;
221e0c4386eSCy Schubert     HMAC_CTX *ctx = NULL, *ctx2 = NULL;
222e0c4386eSCy Schubert     unsigned char buf[EVP_MAX_MD_SIZE];
223e0c4386eSCy Schubert     unsigned int len;
224e0c4386eSCy Schubert     int ret = 0;
225e0c4386eSCy Schubert 
226e0c4386eSCy Schubert     ctx = HMAC_CTX_new();
227e0c4386eSCy Schubert     ctx2 = HMAC_CTX_new();
228e0c4386eSCy Schubert     if (!TEST_ptr(ctx) || !TEST_ptr(ctx2))
229e0c4386eSCy Schubert         goto err;
230e0c4386eSCy Schubert 
231e0c4386eSCy Schubert     if (!TEST_true(HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL))
232e0c4386eSCy Schubert         || !TEST_true(HMAC_Update(ctx, test[7].data, test[7].data_len))
233e0c4386eSCy Schubert         || !TEST_true(HMAC_CTX_copy(ctx2, ctx))
234e0c4386eSCy Schubert         || !TEST_true(HMAC_Final(ctx2, buf, &len)))
235e0c4386eSCy Schubert         goto err;
236e0c4386eSCy Schubert 
237e0c4386eSCy Schubert     p = pt(buf, len);
238e0c4386eSCy Schubert     if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest))
239e0c4386eSCy Schubert         goto err;
240e0c4386eSCy Schubert 
241e0c4386eSCy Schubert     ret = 1;
242e0c4386eSCy Schubert err:
243e0c4386eSCy Schubert     HMAC_CTX_free(ctx2);
244e0c4386eSCy Schubert     HMAC_CTX_free(ctx);
245e0c4386eSCy Schubert     return ret;
246e0c4386eSCy Schubert }
247e0c4386eSCy Schubert 
test_hmac_copy_uninited(void)248e0c4386eSCy Schubert static int test_hmac_copy_uninited(void)
249e0c4386eSCy Schubert {
250e0c4386eSCy Schubert     const unsigned char key[24] = {0};
251e0c4386eSCy Schubert     const unsigned char ct[166] = {0};
252e0c4386eSCy Schubert     EVP_PKEY *pkey = NULL;
253e0c4386eSCy Schubert     EVP_MD_CTX *ctx = NULL;
254e0c4386eSCy Schubert     EVP_MD_CTX *ctx_tmp = NULL;
255e0c4386eSCy Schubert     int res = 0;
256e0c4386eSCy Schubert 
257e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_MD_CTX_new())
258e0c4386eSCy Schubert             || !TEST_ptr(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
259e0c4386eSCy Schubert                                                      key, sizeof(key)))
260e0c4386eSCy Schubert             || !TEST_true(EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey))
261e0c4386eSCy Schubert             || !TEST_ptr(ctx_tmp = EVP_MD_CTX_new())
262e0c4386eSCy Schubert             || !TEST_true(EVP_MD_CTX_copy(ctx_tmp, ctx)))
263e0c4386eSCy Schubert         goto err;
264e0c4386eSCy Schubert     EVP_MD_CTX_free(ctx);
265e0c4386eSCy Schubert     ctx = ctx_tmp;
266e0c4386eSCy Schubert     ctx_tmp = NULL;
267e0c4386eSCy Schubert 
268e0c4386eSCy Schubert     if (!TEST_true(EVP_DigestSignUpdate(ctx, ct, sizeof(ct))))
269e0c4386eSCy Schubert         goto err;
270e0c4386eSCy Schubert     res = 1;
271e0c4386eSCy Schubert  err:
272e0c4386eSCy Schubert     EVP_MD_CTX_free(ctx);
273e0c4386eSCy Schubert     EVP_MD_CTX_free(ctx_tmp);
274e0c4386eSCy Schubert     EVP_PKEY_free(pkey);
275e0c4386eSCy Schubert     return res;
276e0c4386eSCy Schubert }
277e0c4386eSCy Schubert 
278e0c4386eSCy Schubert #ifndef OPENSSL_NO_MD5
279*0d0c8621SEnji Cooper # define OSSL_HEX_CHARS_PER_BYTE 2
pt(unsigned char * md,unsigned int len)280e0c4386eSCy Schubert static char *pt(unsigned char *md, unsigned int len)
281e0c4386eSCy Schubert {
282e0c4386eSCy Schubert     unsigned int i;
283*0d0c8621SEnji Cooper     static char buf[201];
284e0c4386eSCy Schubert 
285e0c4386eSCy Schubert     if (md == NULL)
286e0c4386eSCy Schubert         return NULL;
287*0d0c8621SEnji Cooper     for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++)
288*0d0c8621SEnji Cooper         BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE,
289*0d0c8621SEnji Cooper                      OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]);
290e0c4386eSCy Schubert     return buf;
291e0c4386eSCy Schubert }
292e0c4386eSCy Schubert #endif
293e0c4386eSCy Schubert 
setup_tests(void)294e0c4386eSCy Schubert int setup_tests(void)
295e0c4386eSCy Schubert {
296e0c4386eSCy Schubert     ADD_ALL_TESTS(test_hmac_md5, 4);
297e0c4386eSCy Schubert     ADD_TEST(test_hmac_single_shot);
298e0c4386eSCy Schubert     ADD_TEST(test_hmac_bad);
299e0c4386eSCy Schubert     ADD_TEST(test_hmac_run);
300e0c4386eSCy Schubert     ADD_TEST(test_hmac_copy);
301e0c4386eSCy Schubert     ADD_TEST(test_hmac_copy_uninited);
302e0c4386eSCy Schubert     return 1;
303e0c4386eSCy Schubert }
304e0c4386eSCy Schubert 
305