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