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