blob: 82c00219c46dca6c0a1331c5a241accd3fde8408 [file] [log] [blame] [edit]
/*
* hmac_test.c
*
* Version 1.0.0
*
* Written by Aaron D. Gifford <me@aarongifford.com>
*
* Copyright 1998, 2000 Aaron D. Gifford. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* This program is just a test program for making sure that the HMAC-SHA1
* library code correctly meets RFC 2202's test vectors. Here's how I
* compile it on my FreeBSD 4.0 system:
*
* cc -o hmac_test hmac_test.c hmac_sha1.c sha1.c
*
* OR when using the version of SHA1 in FreeBSD's libmd(Eric A. Young's
* implementation):
*
* cc -o hmac_test hmac_test.c hmac_sha1.c -lmd
*
* Then run the test from the command line:
*
* ./hmac_test
*/
#include <stdio.h>
#include <stdlib.h>
#include "hmac_sha1.h"
typedef struct _test_vector {
int caseno;
int keylen;
unsigned char *key;
int datalen;
unsigned char *data;
unsigned char *digest;
} test_vector;
unsigned char tolower(unsigned char c) {
if (c >= (unsigned char)'A' && c <= (unsigned char)'A')
return c + ((unsigned char)'a' - (unsigned char)'A');
return c;
}
unsigned char hexdigit(unsigned char c) {
c = tolower(c);
if (c >= (unsigned char)'a' && c <= (unsigned char)'f')
c += (10 - (unsigned char)'a');
else
c += (0 - (unsigned char)'0');
return c;
}
unsigned char *hex2data(unsigned char *hex, int len) {
unsigned char *data;
int dl;
unsigned int c;
/* Assume the hex data ALWAYS begins with "0x" */
hex += 2;
/* Allocate space... */
data = (unsigned char *)malloc(sizeof(unsigned char) * len);
for (dl = 0; dl < len; dl++) {
c = (unsigned int)hexdigit(*hex++) << 4;
c |= (unsigned int)hexdigit(*hex++);
data[dl] = (unsigned char)c;
}
return data;
}
int main(void) {
int i, p;
HMAC_SHA1_CTX c;
unsigned char md[HMAC_SHA1_DIGEST_LENGTH];
test_vector tests[7];
/* Set up the test vectors from RFC 2202 */
tests[0].caseno = 1;
tests[0].key = hex2data((unsigned char*)"0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", 20);
tests[0].keylen = 20;
tests[0].data = (unsigned char*)"Hi There";
tests[0].datalen = 8;
tests[0].digest = hex2data((unsigned char*)"0xb617318655057264e28bc0b6fb378c8ef146be00", 20);
tests[1].caseno = 2;
tests[1].keylen = 4;
tests[1].key = (unsigned char*)"Jefe";
tests[1].datalen = 28;
tests[1].data = (unsigned char*)"what do ya want for nothing?";
tests[1].digest = hex2data((unsigned char*)"0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79", 20);
tests[2].caseno = 3;
tests[2].keylen = 20;
tests[2].key = hex2data((unsigned char*)"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 20);
tests[2].datalen = 50;
tests[2].data = hex2data((unsigned char*)"0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", 50);
tests[2].digest = hex2data((unsigned char*)"0x125d7342b9ac11cd91a39af48aa17b4f63f175d3", 20);
tests[3].caseno = 4;
tests[3].keylen = 25;
tests[3].key = hex2data((unsigned char*)"0x0102030405060708090a0b0c0d0e0f10111213141516171819", 25);
tests[3].datalen = 50;
tests[3].data = hex2data((unsigned char*)"0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", 50);
tests[3].digest = hex2data((unsigned char*)"0x4c9007f4026250c6bc8414f9bf50c86c2d7235da", 20);
tests[4].caseno = 5;
tests[4].keylen = 20;
tests[4].key = hex2data((unsigned char*)"0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", 20);
tests[4].datalen = 20;
tests[4].data = (unsigned char*)"Test With Truncation";
tests[4].digest = hex2data((unsigned char*)"0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", 20);
tests[5].caseno = 6;
tests[5].keylen = 80;
tests[5].key = hex2data((unsigned char*)"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 80);
tests[5].datalen = 54;
tests[5].data = (unsigned char*)"Test Using Larger Than Block-Size Key - Hash Key First";
tests[5].digest = hex2data((unsigned char*)"0xaa4ae5e15272d00e95705637ce8a3b55ed402112", 20);
tests[6].caseno = 7;
tests[6].keylen = 80;
tests[6].key = hex2data((unsigned char*)"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 80);
tests[6].datalen = 73;
tests[6].data = (unsigned char*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";
tests[6].digest = hex2data((unsigned char*)"0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91", 20);
/* Now do the tests */
for (i = 0; i < 7; i++) {
printf("Test vector #%d:\n", tests[i].caseno);
HMAC_SHA1_Init(&c);
/* Send the first 3 bytes of key */
HMAC_SHA1_UpdateKey(&c, tests[i].key, 3);
HMAC_SHA1_UpdateKey(&c, &(tests[i].key[3]), tests[i].keylen - 3);
HMAC_SHA1_EndKey(&c);
HMAC_SHA1_StartMessage(&c);
/* Send the first 7 bytes of data */
HMAC_SHA1_UpdateMessage(&c, tests[i].data, 7);
HMAC_SHA1_UpdateMessage(&c, &(tests[i].data[7]), tests[i].datalen - 7);
HMAC_SHA1_EndMessage(&(md[0]),&c);
printf("Message Digest Was: \"0x");
for (p = 0; p < HMAC_SHA1_DIGEST_LENGTH; p++)
printf("%02x", (unsigned char)md[p]);
printf("\"\nExpected: \"0x");
for (p = 0; p < HMAC_SHA1_DIGEST_LENGTH; p++)
printf("%02x", (unsigned char)tests[i].digest[p]);
printf("\"\n");
for (p = 0; p < HMAC_SHA1_DIGEST_LENGTH; p++) {
if (tests[i].digest[p] != md[p]) {
printf("TEST FAILED (at byte %d)!!!\n", p);
printf("'0x%02x' != '0x%02x' apparently...\n", (unsigned char)tests[i].digest[p], (unsigned char)md[p]);
break;
}
}
if (p == HMAC_SHA1_DIGEST_LENGTH)
printf("TEST SUCCEEDED!!!\n\n");
}
HMAC_SHA1_Done(&c);
}