1238438Sdteske/*
2238438Sdteske * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3249746Sdteske *
4238438Sdteske * Licensed under the Apache License 2.0 (the "License").  You may not use
5238438Sdteske * this file except in compliance with the License.  You can obtain a copy
6238438Sdteske * in the file LICENSE in the source distribution or at
7238438Sdteske * https://www.openssl.org/source/license.html
8238438Sdteske */
9238438Sdteske
10238438Sdteske/*
11238438Sdteske * HMAC low level APIs are deprecated for public use, but still ok for internal
12238438Sdteske * use.
13238438Sdteske */
14238438Sdteske#include "internal/deprecated.h"
15238438Sdteske
16238438Sdteske#include <stdio.h>
17238438Sdteske#include <string.h>
18238438Sdteske#include <stdlib.h>
19238438Sdteske
20238438Sdteske#include "internal/nelem.h"
21238438Sdteske
22238438Sdteske# include <openssl/hmac.h>
23238438Sdteske# include <openssl/sha.h>
24238438Sdteske# ifndef OPENSSL_NO_MD5
25238438Sdteske#  include <openssl/md5.h>
26238438Sdteske# endif
27238438Sdteske
28238438Sdteske# ifdef CHARSET_EBCDIC
29238438Sdteske#  include <openssl/ebcdic.h>
30238438Sdteske# endif
31240684Sdteske
32240684Sdteske#include "testutil.h"
33244675Sdteske
34240684Sdteske# ifndef OPENSSL_NO_MD5
35240684Sdteskestatic struct test_st {
36240684Sdteske    const char key[16];
37238438Sdteske    int key_len;
38240684Sdteske    const unsigned char data[64];
39238438Sdteske    int data_len;
40238438Sdteske    const char *digest;
41242107Sdteske} test[8] = {
42242107Sdteske    {
43243112Sdteske        "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
44238438Sdteske        "e9139d1e6ee064ef8cf514fc7dc83e86",
45238438Sdteske    },
46238438Sdteske    {
47238438Sdteske        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
48238438Sdteske        16, "Hi There", 8,
49238438Sdteske        "9294727a3638bb1c13f48ef8158bfc9d",
50238438Sdteske    },
51238438Sdteske    {
52238438Sdteske        "Jefe", 4, "what do ya want for nothing?", 28,
53238438Sdteske        "750c783e6ab0b503eaa86e310a5db738",
54238438Sdteske    },
55238438Sdteske    {
56238438Sdteske        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
57238438Sdteske        16, {
58238438Sdteske            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
59238438Sdteske            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
60238438Sdteske            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
61238438Sdteske            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
62238438Sdteske            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
63238438Sdteske        }, 50, "56be34521d144c88dbb8c733f0e8b3f6",
64238438Sdteske    },
65238438Sdteske    {
66238438Sdteske        "", 0, "My test data", 12,
67238438Sdteske        "61afdecb95429ef494d61fdee15990cabf0826fc"
68238438Sdteske    },
69238438Sdteske    {
70238438Sdteske        "", 0, "My test data", 12,
71238438Sdteske        "2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
72238438Sdteske    },
73240768Sdteske    {
74240768Sdteske        "123456", 6, "My test data", 12,
75238438Sdteske        "bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
76238438Sdteske    },
77238438Sdteske    {
78238438Sdteske        "12345", 5, "My test data again", 18,
79238438Sdteske        "a12396ceddd2a85f4c656bc1e0aa50c78cffde3e"
80241899Sdteske    }
81245401Sdteske};
82242096Sdteske# endif
83238438Sdteske
84238438Sdteskestatic char *pt(unsigned char *md, unsigned int len);
85240768Sdteske
86240768Sdteske#define UC(a)	((const unsigned char *)(a))
87240768Sdteske
88240768Sdteske
89240768Sdteske# ifndef OPENSSL_NO_MD5
90238438Sdteskestatic int test_hmac_md5(int idx)
91238438Sdteske{
92238438Sdteske    char *p;
93238438Sdteske#  ifdef CHARSET_EBCDIC
94238438Sdteske    ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
95238438Sdteske    ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
96238438Sdteske    ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
97238438Sdteske    ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
98238438Sdteske#  endif
99238438Sdteske
100249746Sdteske    p = pt(HMAC(EVP_md5(),
101238438Sdteske                test[idx].key, test[idx].key_len,
102238438Sdteske                UC(test[idx].data), test[idx].data_len, NULL, NULL),
103238438Sdteske                MD5_DIGEST_LENGTH);
104238438Sdteske
105238438Sdteske    return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest);
106238438Sdteske}
107238438Sdteske# endif
108238438Sdteske
109238438Sdteskestatic int test_hmac_bad(void)
110238438Sdteske{
111238438Sdteske    HMAC_CTX *ctx = NULL;
112238438Sdteske    int ret = 0;
113238438Sdteske
114238438Sdteske    ctx = HMAC_CTX_new();
115238438Sdteske    if (!TEST_ptr(ctx)
116238438Sdteske        || !TEST_ptr_null(HMAC_CTX_get_md(ctx))
117241899Sdteske        || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL))
118241899Sdteske        || !TEST_false(HMAC_Update(ctx,  UC(test[4].data), test[4].data_len))
119241899Sdteske        || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL))
120241899Sdteske        || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)))
121238438Sdteske        goto err;
122241899Sdteske
123241899Sdteske    ret = 1;
124242107Sdteskeerr:
125241899Sdteske    HMAC_CTX_free(ctx);
126241899Sdteske    return ret;
127241899Sdteske}
128241899Sdteske
129238438Sdteskestatic int test_hmac_run(void)
130241899Sdteske{
131241899Sdteske    char *p;
132241899Sdteske    HMAC_CTX *ctx = NULL;
133238438Sdteske    unsigned char buf[EVP_MAX_MD_SIZE];
134238438Sdteske    unsigned int len;
135238438Sdteske    int ret = 0;
136238438Sdteske
137238438Sdteske    if (!TEST_ptr(ctx = HMAC_CTX_new()))
138238438Sdteske        return 0;
139238438Sdteske    HMAC_CTX_reset(ctx);
140238438Sdteske
141238438Sdteske    if (!TEST_ptr(ctx)
142238438Sdteske        || !TEST_ptr_null(HMAC_CTX_get_md(ctx))
143238438Sdteske        || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL))
144238438Sdteske        || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len))
145238438Sdteske        || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)))
146238438Sdteske        goto err;
147238438Sdteske
148238438Sdteske    if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL))
149238438Sdteske        || !TEST_true(HMAC_Update(ctx, UC(test[4].data), test[4].data_len))
150238438Sdteske        || !TEST_true(HMAC_Final(ctx, buf, &len)))
151238438Sdteske        goto err;
152238438Sdteske
153238438Sdteske    p = pt(buf, len);
154238438Sdteske    if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
155238438Sdteske        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