155714Skris/* crypto/hmac/hmactest.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <string.h>
6155714Skris#include <stdlib.h>
6255714Skris
63109998Smarkm#include "../e_os.h"
64109998Smarkm
65109998Smarkm#ifdef OPENSSL_NO_HMAC
6655714Skrisint main(int argc, char *argv[])
6755714Skris{
6855714Skris    printf("No HMAC support\n");
69296341Sdelphij    return (0);
7055714Skris}
7155714Skris#else
72296341Sdelphij# include <openssl/hmac.h>
73296341Sdelphij# ifndef OPENSSL_NO_MD5
74296341Sdelphij#  include <openssl/md5.h>
75296341Sdelphij# endif
7655714Skris
77296341Sdelphij# ifdef CHARSET_EBCDIC
78296341Sdelphij#  include <openssl/ebcdic.h>
79296341Sdelphij# endif
8055714Skris
81296341Sdelphij# ifndef OPENSSL_NO_MD5
82296341Sdelphijstatic struct test_st {
83296341Sdelphij    unsigned char key[16];
84296341Sdelphij    int key_len;
85296341Sdelphij    unsigned char data[64];
86296341Sdelphij    int data_len;
87296341Sdelphij    unsigned char *digest;
88296341Sdelphij} test[8] = {
89296341Sdelphij    {
90296341Sdelphij        "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
91296341Sdelphij        (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
92296341Sdelphij    },
93296341Sdelphij    {
94296341Sdelphij        {
95296341Sdelphij            0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
96296341Sdelphij            0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
97296341Sdelphij        }, 16, "Hi There", 8,
98296341Sdelphij        (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
99296341Sdelphij    },
100296341Sdelphij    {
101296341Sdelphij        "Jefe", 4, "what do ya want for nothing?", 28,
102296341Sdelphij        (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
103296341Sdelphij    },
104296341Sdelphij    {
105296341Sdelphij        {
106296341Sdelphij            0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
107296341Sdelphij            0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
108296341Sdelphij        }, 16, {
109296341Sdelphij            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
110296341Sdelphij            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
111296341Sdelphij            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
112296341Sdelphij            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
113296341Sdelphij            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
114296341Sdelphij        }, 50, (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
115296341Sdelphij    },
116296341Sdelphij    {
117296341Sdelphij        "", 0, "My test data", 12,
118296341Sdelphij        (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
119296341Sdelphij    },
120296341Sdelphij    {
121296341Sdelphij        "", 0, "My test data", 12,
122296341Sdelphij        (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
123296341Sdelphij    },
124296341Sdelphij    {
125296341Sdelphij        "123456", 6, "My test data", 12,
126296341Sdelphij        (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
127296341Sdelphij    },
128296341Sdelphij    {
129296341Sdelphij        "12345", 5, "My test data again", 12,
130296341Sdelphij        (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131296341Sdelphij    }
132296341Sdelphij};
133296341Sdelphij# endif
13455714Skris
135296341Sdelphijstatic char *pt(unsigned char *md, unsigned int len);
136296341Sdelphij
13755714Skrisint main(int argc, char *argv[])
138296341Sdelphij{
139296341Sdelphij# ifndef OPENSSL_NO_MD5
140296341Sdelphij    int i;
141296341Sdelphij    char *p;
142296341Sdelphij# endif
143296341Sdelphij    int err = 0;
144296341Sdelphij    HMAC_CTX ctx, ctx2;
145296341Sdelphij    unsigned char buf[EVP_MAX_MD_SIZE];
146296341Sdelphij    unsigned int len;
14755714Skris
148296341Sdelphij# ifdef OPENSSL_NO_MD5
149296341Sdelphij    printf("test skipped: MD5 disabled\n");
150296341Sdelphij# else
151109998Smarkm
152296341Sdelphij#  ifdef CHARSET_EBCDIC
153296341Sdelphij    ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
154296341Sdelphij    ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
155296341Sdelphij    ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
156296341Sdelphij    ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
157296341Sdelphij#  endif
15855714Skris
159296341Sdelphij    for (i = 0; i < 4; i++) {
160296341Sdelphij        p = pt(HMAC(EVP_md5(),
161296341Sdelphij                    test[i].key, test[i].key_len,
162296341Sdelphij                    test[i].data, test[i].data_len, NULL, NULL),
163296341Sdelphij                    MD5_DIGEST_LENGTH);
16455714Skris
165296341Sdelphij        if (strcmp(p, (char *)test[i].digest) != 0) {
166296341Sdelphij            printf("Error calculating HMAC on %d entry'\n", i);
167296341Sdelphij            printf("got %s instead of %s\n", p, test[i].digest);
168296341Sdelphij            err++;
169296341Sdelphij        } else
170296341Sdelphij            printf("test %d ok\n", i);
171296341Sdelphij    }
172296341Sdelphij# endif                         /* OPENSSL_NO_MD5 */
17355714Skris
174296341Sdelphij/* test4 */
175296341Sdelphij    HMAC_CTX_init(&ctx);
176296341Sdelphij    if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
177296341Sdelphij        printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
178296341Sdelphij        err++;
179296341Sdelphij        goto test5;
180296341Sdelphij    }
181296341Sdelphij    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
182296341Sdelphij        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
183296341Sdelphij        err++;
184296341Sdelphij        goto test5;
185296341Sdelphij    }
186296341Sdelphij    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
187296341Sdelphij        printf("Should fail to initialise HMAC with empty key (test 4)\n");
188296341Sdelphij        err++;
189296341Sdelphij        goto test5;
190296341Sdelphij    }
191296341Sdelphij    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
192296341Sdelphij        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
193296341Sdelphij        err++;
194296341Sdelphij        goto test5;
195296341Sdelphij    }
196296341Sdelphij    printf("test 4 ok\n");
197296341Sdelphijtest5:
198296341Sdelphij    HMAC_CTX_init(&ctx);
199296341Sdelphij    if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
200296341Sdelphij        printf("Should fail to initialise HMAC with empty MD (test 5)\n");
201296341Sdelphij        err++;
202296341Sdelphij        goto test6;
203296341Sdelphij    }
204296341Sdelphij    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
205296341Sdelphij        printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
206296341Sdelphij        err++;
207296341Sdelphij        goto test6;
208296341Sdelphij    }
209296341Sdelphij    if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
210296341Sdelphij        printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
211296341Sdelphij        err++;
212296341Sdelphij        goto test6;
213296341Sdelphij    }
214296341Sdelphij    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
215296341Sdelphij        printf("Failed to initialise HMAC (test 5)\n");
216296341Sdelphij        err++;
217296341Sdelphij        goto test6;
218296341Sdelphij    }
219296341Sdelphij    if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
220296341Sdelphij        printf("Error updating HMAC with data (test 5)\n");
221296341Sdelphij        err++;
222296341Sdelphij        goto test6;
223296341Sdelphij    }
224296341Sdelphij    if (!HMAC_Final(&ctx, buf, &len)) {
225296341Sdelphij        printf("Error finalising data (test 5)\n");
226296341Sdelphij        err++;
227296341Sdelphij        goto test6;
228296341Sdelphij    }
229296341Sdelphij    p = pt(buf, len);
230296341Sdelphij    if (strcmp(p, (char *)test[4].digest) != 0) {
231296341Sdelphij        printf("Error calculating interim HMAC on test 5\n");
232296341Sdelphij        printf("got %s instead of %s\n", p, test[4].digest);
233296341Sdelphij        err++;
234296341Sdelphij        goto test6;
235296341Sdelphij    }
236296341Sdelphij    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
237296341Sdelphij        printf("Should disallow changing MD without a new key (test 5)\n");
238296341Sdelphij        err++;
239296341Sdelphij        goto test6;
240296341Sdelphij    }
241296341Sdelphij    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
242296341Sdelphij        printf("Failed to reinitialise HMAC (test 5)\n");
243296341Sdelphij        err++;
244296341Sdelphij        goto test6;
245296341Sdelphij    }
246296341Sdelphij    if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
247296341Sdelphij        printf("Error updating HMAC with data (sha256) (test 5)\n");
248296341Sdelphij        err++;
249296341Sdelphij        goto test6;
250296341Sdelphij    }
251296341Sdelphij    if (!HMAC_Final(&ctx, buf, &len)) {
252296341Sdelphij        printf("Error finalising data (sha256) (test 5)\n");
253296341Sdelphij        err++;
254296341Sdelphij        goto test6;
255296341Sdelphij    }
256296341Sdelphij    p = pt(buf, len);
257296341Sdelphij    if (strcmp(p, (char *)test[5].digest) != 0) {
258296341Sdelphij        printf("Error calculating 2nd interim HMAC on test 5\n");
259296341Sdelphij        printf("got %s instead of %s\n", p, test[5].digest);
260296341Sdelphij        err++;
261296341Sdelphij        goto test6;
262296341Sdelphij    }
263296341Sdelphij    if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
264296341Sdelphij        printf("Failed to reinitialise HMAC with key (test 5)\n");
265296341Sdelphij        err++;
266296341Sdelphij        goto test6;
267296341Sdelphij    }
268296341Sdelphij    if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
269296341Sdelphij        printf("Error updating HMAC with data (new key) (test 5)\n");
270296341Sdelphij        err++;
271296341Sdelphij        goto test6;
272296341Sdelphij    }
273296341Sdelphij    if (!HMAC_Final(&ctx, buf, &len)) {
274296341Sdelphij        printf("Error finalising data (new key) (test 5)\n");
275296341Sdelphij        err++;
276296341Sdelphij        goto test6;
277296341Sdelphij    }
278296341Sdelphij    p = pt(buf, len);
279296341Sdelphij    if (strcmp(p, (char *)test[6].digest) != 0) {
280296341Sdelphij        printf("error calculating HMAC on test 5\n");
281296341Sdelphij        printf("got %s instead of %s\n", p, test[6].digest);
282296341Sdelphij        err++;
283296341Sdelphij    } else {
284296341Sdelphij        printf("test 5 ok\n");
285296341Sdelphij    }
286296341Sdelphijtest6:
287296341Sdelphij    HMAC_CTX_init(&ctx);
288296341Sdelphij    if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
289296341Sdelphij        printf("Failed to initialise HMAC (test 6)\n");
290296341Sdelphij        err++;
291296341Sdelphij        goto end;
292296341Sdelphij    }
293296341Sdelphij    if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
294296341Sdelphij        printf("Error updating HMAC with data (test 6)\n");
295296341Sdelphij        err++;
296296341Sdelphij        goto end;
297296341Sdelphij    }
298296341Sdelphij    if (!HMAC_CTX_copy(&ctx2, &ctx)) {
299296341Sdelphij        printf("Failed to copy HMAC_CTX (test 6)\n");
300296341Sdelphij        err++;
301296341Sdelphij        goto end;
302296341Sdelphij    }
303296341Sdelphij    if (!HMAC_Final(&ctx2, buf, &len)) {
304296341Sdelphij        printf("Error finalising data (test 6)\n");
305296341Sdelphij        err++;
306296341Sdelphij        goto end;
307296341Sdelphij    }
308296341Sdelphij    p = pt(buf, len);
309296341Sdelphij    if (strcmp(p, (char *)test[7].digest) != 0) {
310296341Sdelphij        printf("Error calculating HMAC on test 6\n");
311296341Sdelphij        printf("got %s instead of %s\n", p, test[7].digest);
312296341Sdelphij        err++;
313296341Sdelphij    } else {
314296341Sdelphij        printf("test 6 ok\n");
315296341Sdelphij    }
316296341Sdelphijend:
317296341Sdelphij    EXIT(err);
318296341Sdelphij    return (0);
319296341Sdelphij}
32055714Skris
321296341Sdelphij# ifndef OPENSSL_NO_MD5
322296341Sdelphijstatic char *pt(unsigned char *md, unsigned int len)
323296341Sdelphij{
324296341Sdelphij    unsigned int i;
325296341Sdelphij    static char buf[80];
326296341Sdelphij
327296341Sdelphij    for (i = 0; i < len; i++)
328296341Sdelphij        sprintf(&(buf[i * 2]), "%02x", md[i]);
329296341Sdelphij    return (buf);
330296341Sdelphij}
331296341Sdelphij# endif
33255714Skris#endif
333