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.
8280297Sjkim *
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).
15280297Sjkim *
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.
22280297Sjkim *
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 :-).
37280297Sjkim * 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)"
40280297Sjkim *
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.
52280297Sjkim *
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");
69280297Sjkim    return (0);
7055714Skris}
7155714Skris#else
72280297Sjkim# include <openssl/hmac.h>
73280297Sjkim# ifndef OPENSSL_NO_MD5
74280297Sjkim#  include <openssl/md5.h>
75280297Sjkim# endif
7655714Skris
77280297Sjkim# ifdef CHARSET_EBCDIC
78280297Sjkim#  include <openssl/ebcdic.h>
79280297Sjkim# endif
8055714Skris
81280297Sjkim# ifndef OPENSSL_NO_MD5
82280297Sjkimstatic struct test_st {
83280297Sjkim    unsigned char key[16];
84280297Sjkim    int key_len;
85280297Sjkim    unsigned char data[64];
86280297Sjkim    int data_len;
87280297Sjkim    unsigned char *digest;
88284283Sjkim} test[8] = {
89280297Sjkim    {
90280297Sjkim        "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
91280297Sjkim        (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
92280297Sjkim    },
93280297Sjkim    {
94280297Sjkim        {
95280297Sjkim            0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
96280297Sjkim            0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
97280297Sjkim        }, 16, "Hi There", 8,
98280297Sjkim        (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
99280297Sjkim    },
100280297Sjkim    {
101280297Sjkim        "Jefe", 4, "what do ya want for nothing?", 28,
102280297Sjkim        (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
103280297Sjkim    },
104280297Sjkim    {
105280297Sjkim        {
106280297Sjkim            0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
107280297Sjkim            0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
108280297Sjkim        }, 16, {
109280297Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
110280297Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
111280297Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
112280297Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
113280297Sjkim            0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
114280297Sjkim        }, 50, (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
115280297Sjkim    },
116284283Sjkim    {
117284283Sjkim        "", 0, "My test data", 12,
118284283Sjkim        (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
119284283Sjkim    },
120284283Sjkim    {
121284283Sjkim        "", 0, "My test data", 12,
122284283Sjkim        (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
123284283Sjkim    },
124284283Sjkim    {
125284283Sjkim        "123456", 6, "My test data", 12,
126284283Sjkim        (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
127284283Sjkim    },
128284283Sjkim    {
129284283Sjkim        "12345", 5, "My test data again", 12,
130284283Sjkim        (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131284283Sjkim    }
132280297Sjkim};
133280297Sjkim# endif
13455714Skris
135284283Sjkimstatic char *pt(unsigned char *md, unsigned int len);
136284283Sjkim
13755714Skrisint main(int argc, char *argv[])
138280297Sjkim{
139280297Sjkim# ifndef OPENSSL_NO_MD5
140280297Sjkim    int i;
141280297Sjkim    char *p;
142280297Sjkim# endif
143280297Sjkim    int err = 0;
144284283Sjkim    HMAC_CTX ctx, ctx2;
145284283Sjkim    unsigned char buf[EVP_MAX_MD_SIZE];
146284283Sjkim    unsigned int len;
14755714Skris
148280297Sjkim# ifdef OPENSSL_NO_MD5
149280297Sjkim    printf("test skipped: MD5 disabled\n");
150280297Sjkim# else
151109998Smarkm
152280297Sjkim#  ifdef CHARSET_EBCDIC
153280297Sjkim    ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
154280297Sjkim    ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
155280297Sjkim    ebcdic2ascii(test[2].key, test[2].key, test[2].key_len);
156280297Sjkim    ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
157280297Sjkim#  endif
15855714Skris
159280297Sjkim    for (i = 0; i < 4; i++) {
160280297Sjkim        p = pt(HMAC(EVP_md5(),
161280297Sjkim                    test[i].key, test[i].key_len,
162284283Sjkim                    test[i].data, test[i].data_len, NULL, NULL),
163284283Sjkim                    MD5_DIGEST_LENGTH);
16455714Skris
165280297Sjkim        if (strcmp(p, (char *)test[i].digest) != 0) {
166284283Sjkim            printf("Error calculating HMAC on %d entry'\n", i);
167280297Sjkim            printf("got %s instead of %s\n", p, test[i].digest);
168280297Sjkim            err++;
169280297Sjkim        } else
170280297Sjkim            printf("test %d ok\n", i);
171280297Sjkim    }
172280297Sjkim# endif                         /* OPENSSL_NO_MD5 */
173284283Sjkim
174284283Sjkim/* test4 */
175284283Sjkim    HMAC_CTX_init(&ctx);
176284283Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
177284283Sjkim        printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
178284283Sjkim        err++;
179284283Sjkim        goto test5;
180284283Sjkim    }
181284283Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
182284283Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
183284283Sjkim        err++;
184284283Sjkim        goto test5;
185284283Sjkim    }
186284283Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
187284283Sjkim        printf("Should fail to initialise HMAC with empty key (test 4)\n");
188284283Sjkim        err++;
189284283Sjkim        goto test5;
190284283Sjkim    }
191284283Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
192284283Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
193284283Sjkim        err++;
194284283Sjkim        goto test5;
195284283Sjkim    }
196284283Sjkim    printf("test 4 ok\n");
197284283Sjkimtest5:
198290207Sjkim    HMAC_CTX_cleanup(&ctx);
199284283Sjkim    HMAC_CTX_init(&ctx);
200284283Sjkim    if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
201284283Sjkim        printf("Should fail to initialise HMAC with empty MD (test 5)\n");
202284283Sjkim        err++;
203284283Sjkim        goto test6;
204284283Sjkim    }
205284283Sjkim    if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
206284283Sjkim        printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
207284283Sjkim        err++;
208284283Sjkim        goto test6;
209284283Sjkim    }
210284283Sjkim    if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
211284283Sjkim        printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
212284283Sjkim        err++;
213284283Sjkim        goto test6;
214284283Sjkim    }
215284283Sjkim    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
216284283Sjkim        printf("Failed to initialise HMAC (test 5)\n");
217284283Sjkim        err++;
218284283Sjkim        goto test6;
219284283Sjkim    }
220284283Sjkim    if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
221284283Sjkim        printf("Error updating HMAC with data (test 5)\n");
222284283Sjkim        err++;
223284283Sjkim        goto test6;
224284283Sjkim    }
225284283Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
226284283Sjkim        printf("Error finalising data (test 5)\n");
227284283Sjkim        err++;
228284283Sjkim        goto test6;
229284283Sjkim    }
230284283Sjkim    p = pt(buf, len);
231284283Sjkim    if (strcmp(p, (char *)test[4].digest) != 0) {
232284283Sjkim        printf("Error calculating interim HMAC on test 5\n");
233284283Sjkim        printf("got %s instead of %s\n", p, test[4].digest);
234284283Sjkim        err++;
235284283Sjkim        goto test6;
236284283Sjkim    }
237284329Sjkim    if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
238284329Sjkim        printf("Should disallow changing MD without a new key (test 5)\n");
239284329Sjkim        err++;
240284329Sjkim        goto test6;
241284329Sjkim    }
242284329Sjkim    if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
243284283Sjkim        printf("Failed to reinitialise HMAC (test 5)\n");
244284283Sjkim        err++;
245284283Sjkim        goto test6;
246284283Sjkim    }
247284283Sjkim    if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
248284283Sjkim        printf("Error updating HMAC with data (sha256) (test 5)\n");
249284283Sjkim        err++;
250284283Sjkim        goto test6;
251284283Sjkim    }
252284283Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
253284283Sjkim        printf("Error finalising data (sha256) (test 5)\n");
254284283Sjkim        err++;
255284283Sjkim        goto test6;
256284283Sjkim    }
257284283Sjkim    p = pt(buf, len);
258284283Sjkim    if (strcmp(p, (char *)test[5].digest) != 0) {
259284283Sjkim        printf("Error calculating 2nd interim HMAC on test 5\n");
260284283Sjkim        printf("got %s instead of %s\n", p, test[5].digest);
261284283Sjkim        err++;
262284283Sjkim        goto test6;
263284283Sjkim    }
264284283Sjkim    if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
265284283Sjkim        printf("Failed to reinitialise HMAC with key (test 5)\n");
266284283Sjkim        err++;
267284283Sjkim        goto test6;
268284283Sjkim    }
269284283Sjkim    if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
270284283Sjkim        printf("Error updating HMAC with data (new key) (test 5)\n");
271284283Sjkim        err++;
272284283Sjkim        goto test6;
273284283Sjkim    }
274284283Sjkim    if (!HMAC_Final(&ctx, buf, &len)) {
275284283Sjkim        printf("Error finalising data (new key) (test 5)\n");
276284283Sjkim        err++;
277284283Sjkim        goto test6;
278284283Sjkim    }
279284283Sjkim    p = pt(buf, len);
280284283Sjkim    if (strcmp(p, (char *)test[6].digest) != 0) {
281284283Sjkim        printf("error calculating HMAC on test 5\n");
282284283Sjkim        printf("got %s instead of %s\n", p, test[6].digest);
283284283Sjkim        err++;
284284283Sjkim    } else {
285284283Sjkim        printf("test 5 ok\n");
286284283Sjkim    }
287284283Sjkimtest6:
288290207Sjkim    HMAC_CTX_cleanup(&ctx);
289284283Sjkim    HMAC_CTX_init(&ctx);
290284283Sjkim    if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
291284283Sjkim        printf("Failed to initialise HMAC (test 6)\n");
292284283Sjkim        err++;
293284283Sjkim        goto end;
294284283Sjkim    }
295284283Sjkim    if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
296284283Sjkim        printf("Error updating HMAC with data (test 6)\n");
297284283Sjkim        err++;
298284283Sjkim        goto end;
299284283Sjkim    }
300284283Sjkim    if (!HMAC_CTX_copy(&ctx2, &ctx)) {
301284283Sjkim        printf("Failed to copy HMAC_CTX (test 6)\n");
302284283Sjkim        err++;
303284283Sjkim        goto end;
304284283Sjkim    }
305284283Sjkim    if (!HMAC_Final(&ctx2, buf, &len)) {
306284283Sjkim        printf("Error finalising data (test 6)\n");
307284283Sjkim        err++;
308284283Sjkim        goto end;
309284283Sjkim    }
310284283Sjkim    p = pt(buf, len);
311284283Sjkim    if (strcmp(p, (char *)test[7].digest) != 0) {
312284283Sjkim        printf("Error calculating HMAC on test 6\n");
313284283Sjkim        printf("got %s instead of %s\n", p, test[7].digest);
314284283Sjkim        err++;
315284283Sjkim    } else {
316284283Sjkim        printf("test 6 ok\n");
317284283Sjkim    }
318284283Sjkimend:
319290207Sjkim    HMAC_CTX_cleanup(&ctx);
320280297Sjkim    EXIT(err);
321280297Sjkim    return (0);
322280297Sjkim}
32355714Skris
324280297Sjkim# ifndef OPENSSL_NO_MD5
325284283Sjkimstatic char *pt(unsigned char *md, unsigned int len)
326280297Sjkim{
327284283Sjkim    unsigned int i;
328280297Sjkim    static char buf[80];
32955714Skris
330284283Sjkim    for (i = 0; i < len; i++)
331280297Sjkim        sprintf(&(buf[i * 2]), "%02x", md[i]);
332280297Sjkim    return (buf);
333280297Sjkim}
334280297Sjkim# endif
33555714Skris#endif
336