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.
8280304Sjkim *
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).
15280304Sjkim *
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.
22280304Sjkim *
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 :-).
37280304Sjkim * 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)"
40280304Sjkim *
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.
52280304Sjkim *
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");
69280304Sjkim    return (0);
7055714Skris}
7155714Skris#else
72280304Sjkim# include <openssl/hmac.h>
73280304Sjkim# ifndef OPENSSL_NO_MD5
74280304Sjkim#  include <openssl/md5.h>
75280304Sjkim# endif
7655714Skris
77280304Sjkim# ifdef CHARSET_EBCDIC
78280304Sjkim#  include <openssl/ebcdic.h>
79280304Sjkim# endif
8055714Skris
81280304Sjkim# ifndef OPENSSL_NO_MD5
82280304Sjkimstatic struct test_st {
83280304Sjkim    unsigned char key[16];
84280304Sjkim    int key_len;
85280304Sjkim    unsigned char data[64];
86280304Sjkim    int data_len;
87280304Sjkim    unsigned char *digest;
88284285Sjkim} test[8] = {
89280304Sjkim    {
90280304Sjkim        "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
91280304Sjkim        (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
92280304Sjkim    },
93280304Sjkim    {
94280304Sjkim        {
95280304Sjkim            0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
96280304Sjkim            0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
97280304Sjkim        }, 16, "Hi There", 8,
98280304Sjkim        (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
99280304Sjkim    },
100280304Sjkim    {
101280304Sjkim        "Jefe", 4, "what do ya want for nothing?", 28,
102280304Sjkim        (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
103280304Sjkim    },
104280304Sjkim    {
105280304Sjkim        {
106280304Sjkim            0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
107280304Sjkim            0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
108280304Sjkim        }, 16, {
109280304Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
110280304Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
111280304Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
112280304Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
113280304Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
114280304Sjkim        }, 50, (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
115280304Sjkim    },
116284285Sjkim    {
117284285Sjkim        "", 0, "My test data", 12,
118284285Sjkim        (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
119284285Sjkim    },
120284285Sjkim    {
121284285Sjkim        "", 0, "My test data", 12,
122284285Sjkim        (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
123284285Sjkim    },
124284285Sjkim    {
125284285Sjkim        "123456", 6, "My test data", 12,
126284285Sjkim        (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
127284285Sjkim    },
128284285Sjkim    {
129284285Sjkim        "12345", 5, "My test data again", 12,
130284285Sjkim        (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131284285Sjkim    }
132280304Sjkim};
133280304Sjkim# endif
13455714Skris
135284285Sjkimstatic char *pt(unsigned char *md, unsigned int len);
136284285Sjkim
13755714Skrisint main(int argc, char *argv[])
138280304Sjkim{
139280304Sjkim# ifndef OPENSSL_NO_MD5
140280304Sjkim    int i;
141280304Sjkim    char *p;
142280304Sjkim# endif
143280304Sjkim    int err = 0;
144284285Sjkim    HMAC_CTX ctx, ctx2;
145284285Sjkim    unsigned char buf[EVP_MAX_MD_SIZE];
146284285Sjkim    unsigned int len;
14755714Skris
148280304Sjkim# ifdef OPENSSL_NO_MD5
149280304Sjkim    printf("test skipped: MD5 disabled\n");
150280304Sjkim# else
151109998Smarkm
152280304Sjkim#  ifdef CHARSET_EBCDIC
153280304Sjkim    ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
154280304Sjkim    ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
155280304Sjkim    ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
156280304Sjkim    ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
157280304Sjkim#  endif
15855714Skris
159280304Sjkim    for (i = 0; i < 4; i++) {
160280304Sjkim        p = pt(HMAC(EVP_md5(),
161280304Sjkim                    test[i].key, test[i].key_len,
162284285Sjkim                    test[i].data, test[i].data_len, NULL, NULL),
163284285Sjkim                    MD5_DIGEST_LENGTH);
16455714Skris
165280304Sjkim        if (strcmp(p, (char *)test[i].digest) != 0) {
166284285Sjkim            printf("Error calculating HMAC on %d entry'\n", i);
167280304Sjkim            printf("got %s instead of %s\n", p, test[i].digest);
168280304Sjkim            err++;
169280304Sjkim        } else
170280304Sjkim            printf("test %d ok\n", i);
171280304Sjkim    }
172280304Sjkim# endif                         /* OPENSSL_NO_MD5 */
173284285Sjkim
174284285Sjkim/* test4 */
175284285Sjkim    HMAC_CTX_init(&ctx);
176284285Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
177284285Sjkim        printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
178284285Sjkim        err++;
179284285Sjkim        goto test5;
180284285Sjkim    }
181284285Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
182284285Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
183284285Sjkim        err++;
184284285Sjkim        goto test5;
185284285Sjkim    }
186284285Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
187284285Sjkim        printf("Should fail to initialise HMAC with empty key (test 4)\n");
188284285Sjkim        err++;
189284285Sjkim        goto test5;
190284285Sjkim    }
191284285Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
192284285Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
193284285Sjkim        err++;
194284285Sjkim        goto test5;
195284285Sjkim    }
196284285Sjkim    printf("test 4 ok\n");
197284285Sjkimtest5:
198284285Sjkim    HMAC_CTX_init(&ctx);
199284285Sjkim    if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
200284285Sjkim        printf("Should fail to initialise HMAC with empty MD (test 5)\n");
201284285Sjkim        err++;
202284285Sjkim        goto test6;
203284285Sjkim    }
204284285Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
205284285Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
206284285Sjkim        err++;
207284285Sjkim        goto test6;
208284285Sjkim    }
209284285Sjkim    if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
210284285Sjkim        printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
211284285Sjkim        err++;
212284285Sjkim        goto test6;
213284285Sjkim    }
214284285Sjkim    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
215284285Sjkim        printf("Failed to initialise HMAC (test 5)\n");
216284285Sjkim        err++;
217284285Sjkim        goto test6;
218284285Sjkim    }
219284285Sjkim    if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
220284285Sjkim        printf("Error updating HMAC with data (test 5)\n");
221284285Sjkim        err++;
222284285Sjkim        goto test6;
223284285Sjkim    }
224284285Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
225284285Sjkim        printf("Error finalising data (test 5)\n");
226284285Sjkim        err++;
227284285Sjkim        goto test6;
228284285Sjkim    }
229284285Sjkim    p = pt(buf, len);
230284285Sjkim    if (strcmp(p, (char *)test[4].digest) != 0) {
231284285Sjkim        printf("Error calculating interim HMAC on test 5\n");
232284285Sjkim        printf("got %s instead of %s\n", p, test[4].digest);
233284285Sjkim        err++;
234284285Sjkim        goto test6;
235284285Sjkim    }
236284330Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
237284330Sjkim        printf("Should disallow changing MD without a new key (test 5)\n");
238284330Sjkim        err++;
239284330Sjkim        goto test6;
240284330Sjkim    }
241284330Sjkim    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
242284285Sjkim        printf("Failed to reinitialise HMAC (test 5)\n");
243284285Sjkim        err++;
244284285Sjkim        goto test6;
245284285Sjkim    }
246284285Sjkim    if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
247284285Sjkim        printf("Error updating HMAC with data (sha256) (test 5)\n");
248284285Sjkim        err++;
249284285Sjkim        goto test6;
250284285Sjkim    }
251284285Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
252284285Sjkim        printf("Error finalising data (sha256) (test 5)\n");
253284285Sjkim        err++;
254284285Sjkim        goto test6;
255284285Sjkim    }
256284285Sjkim    p = pt(buf, len);
257284285Sjkim    if (strcmp(p, (char *)test[5].digest) != 0) {
258284285Sjkim        printf("Error calculating 2nd interim HMAC on test 5\n");
259284285Sjkim        printf("got %s instead of %s\n", p, test[5].digest);
260284285Sjkim        err++;
261284285Sjkim        goto test6;
262284285Sjkim    }
263284285Sjkim    if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
264284285Sjkim        printf("Failed to reinitialise HMAC with key (test 5)\n");
265284285Sjkim        err++;
266284285Sjkim        goto test6;
267284285Sjkim    }
268284285Sjkim    if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
269284285Sjkim        printf("Error updating HMAC with data (new key) (test 5)\n");
270284285Sjkim        err++;
271284285Sjkim        goto test6;
272284285Sjkim    }
273284285Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
274284285Sjkim        printf("Error finalising data (new key) (test 5)\n");
275284285Sjkim        err++;
276284285Sjkim        goto test6;
277284285Sjkim    }
278284285Sjkim    p = pt(buf, len);
279284285Sjkim    if (strcmp(p, (char *)test[6].digest) != 0) {
280284285Sjkim        printf("error calculating HMAC on test 5\n");
281284285Sjkim        printf("got %s instead of %s\n", p, test[6].digest);
282284285Sjkim        err++;
283284285Sjkim    } else {
284284285Sjkim        printf("test 5 ok\n");
285284285Sjkim    }
286284285Sjkimtest6:
287284285Sjkim    HMAC_CTX_init(&ctx);
288284285Sjkim    if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
289284285Sjkim        printf("Failed to initialise HMAC (test 6)\n");
290284285Sjkim        err++;
291284285Sjkim        goto end;
292284285Sjkim    }
293284285Sjkim    if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
294284285Sjkim        printf("Error updating HMAC with data (test 6)\n");
295284285Sjkim        err++;
296284285Sjkim        goto end;
297284285Sjkim    }
298284285Sjkim    if (!HMAC_CTX_copy(&ctx2, &ctx)) {
299284285Sjkim        printf("Failed to copy HMAC_CTX (test 6)\n");
300284285Sjkim        err++;
301284285Sjkim        goto end;
302284285Sjkim    }
303284285Sjkim    if (!HMAC_Final(&ctx2, buf, &len)) {
304284285Sjkim        printf("Error finalising data (test 6)\n");
305284285Sjkim        err++;
306284285Sjkim        goto end;
307284285Sjkim    }
308284285Sjkim    p = pt(buf, len);
309284285Sjkim    if (strcmp(p, (char *)test[7].digest) != 0) {
310284285Sjkim        printf("Error calculating HMAC on test 6\n");
311284285Sjkim        printf("got %s instead of %s\n", p, test[7].digest);
312284285Sjkim        err++;
313284285Sjkim    } else {
314284285Sjkim        printf("test 6 ok\n");
315284285Sjkim    }
316284285Sjkimend:
317280304Sjkim    EXIT(err);
318280304Sjkim    return (0);
319280304Sjkim}
32055714Skris
321280304Sjkim# ifndef OPENSSL_NO_MD5
322284285Sjkimstatic char *pt(unsigned char *md, unsigned int len)
323280304Sjkim{
324284285Sjkim    unsigned int i;
325280304Sjkim    static char buf[80];
32655714Skris
327284285Sjkim    for (i = 0; i < len; i++)
328280304Sjkim        sprintf(&(buf[i * 2]), "%02x", md[i]);
329280304Sjkim    return (buf);
330280304Sjkim}
331280304Sjkim# endif
33255714Skris#endif
333