Files
mars-matrixssl/crypto/test/hmacTest.c
Janne Johansson d0a51a7e43 MatrixSSL 4.0.0
2018-09-13 12:17:26 +03:00

334 lines
9.7 KiB
C

/**
* @file hmacTest.c
* @version $Format:%h%d$
*
* HMAC test. (Only tests HMAC-SHA-1 currently.)
*/
#include <stdio.h>
#include <stdlib.h>
#include "crypto/cryptoApi.h"
#ifdef USE_HMAC_SHA1
/* A single basic test case. */
static int32 hmac_test_simple(void)
{
unsigned char res[20];
unsigned char res2[20];
psHmacSha1_t ctx;
int32_t rv;
const char *data1 = "Hi There";
unsigned char key1[] = {
0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b
};
const unsigned char res1[] = {
0xb6, 0x17, 0x31, 0x86,
0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6,
0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00
};
psSize_t keyLen = (uint16_t) sizeof(key1);
/* Try single-call */
rv = psHmacSha1(key1, keyLen, (unsigned char *) data1,
(uint32_t) Strlen(data1), res2,
key1, &keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Single-part HMAC KAT execution failure (rv=%d)\n",
(int) rv);
return PS_FAILURE;
}
if (Memcmp(res1, res2, 20) != 0)
{
printf("FAILED: Single-part HMAC KAT mismatch\n");
return PS_FAILURE;
}
/* Try init-update-finish */
rv = psHmacSha1Init(&ctx, key1, keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Init state of Init-Update-Finish HMAC\n");
return PS_FAILURE;
}
psHmacSha1Update(&ctx, (unsigned char *) data1, (uint32_t) Strlen(data1));
(void) psHmacSha1Final(&ctx, res);
if (Memcmp(res, res1, 20) != 0)
{
printf("FAILED: Init-Update-Finish HMAC KAT mismatch\n");
}
return PS_SUCCESS;
}
/* Get SHA-1 digest in hex. */
static void hexify(unsigned char (*res_p)[20], char (*res_hex_p)[43])
{
int i;
(*res_hex_p)[0] = '0';
(*res_hex_p)[1] = 'x';
for(i = 0; i < 20; i++)
{
sprintf((*res_hex_p) + i * 2 + 2, "%02x", (*res_p)[i]);
}
}
/* A single basic test case. */
static int32 hmac_test_vector(const unsigned char *key, size_t keylen,
const unsigned char *data, size_t datalen,
const char *mac)
{
unsigned char res[20];
unsigned char res2[20];
char res_hex[43];
char res2_hex[43];
psHmacSha1_t ctx;
int32_t rv;
unsigned char key1[64];
psSize_t keyLen = (uint16_t) keylen;
/* Try single-call */
rv = psHmacSha1(key, keylen, data, datalen, res, key1, &keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Single-part HMAC KAT execution failure (rv=%d)\n",
(int) rv);
return PS_FAILURE;
}
hexify(&res, &res_hex);
if (strcmp(mac, res_hex))
{
printf("FAILED: Single-part HMAC KAT mismatch\n");
printf("%s expected, got %s\n", mac, res_hex);
return PS_FAILURE;
}
/* Try init-update-finish */
rv = psHmacSha1Init(&ctx, key1, keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Init state of Init-Update-Finish HMAC\n");
return PS_FAILURE;
}
psHmacSha1Update(&ctx, data, datalen / 2);
psHmacSha1Update(&ctx, data + datalen / 2, datalen - (datalen / 2));
(void) psHmacSha1Final(&ctx, res2);
hexify(&res2, &res2_hex);
if (strcmp(mac, res2_hex))
{
printf("FAILED: Multipart HMAC KAT mismatch\n");
printf("%s expected, got %s\n", mac, res2_hex);
return PS_FAILURE;
}
return PS_SUCCESS;
}
/* A two vector test case with common prefix: use copying. */
static int32 hmac_test_vector2_copy(const unsigned char *key, size_t keylen,
const unsigned char *data_base, size_t data_baselen,
const unsigned char *data_post1, size_t data_post1len,
const unsigned char *data_post2, size_t data_post2len,
const char *mac1,
const char *mac2)
{
unsigned char res1[20];
unsigned char res2[20];
char res1_hex[43];
char res2_hex[43];
psHmacSha1_t ctx1;
psHmacSha1_t ctx2;
psRes_t rv;
rv = psHmacSha1Init(&ctx1, key, keylen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Init state of Init-Update-Finish HMAC\n");
return PS_FAILURE;
}
psHmacSha1Update(&ctx1, data_base, data_baselen);
/* Copy state. */
memcpy(&ctx2, &ctx1, sizeof(ctx2));
/* Update. */
psHmacSha1Update(&ctx1, data_post1, data_post1len);
psHmacSha1Update(&ctx2, data_post2, data_post2len);
/* Finish. */
(void) psHmacSha1Final(&ctx2, res2);
hexify(&res2, &res2_hex);
if (strcmp(mac2, res2_hex))
{
printf("FAILED: Multipart HMAC KAT mismatch (branch 1)\n");
printf("%s expected, got %s\n", mac2, res2_hex);
return PS_FAILURE;
}
(void) psHmacSha1Final(&ctx1, res1);
hexify(&res1, &res1_hex);
if (strcmp(mac1, res1_hex))
{
printf("FAILED: Multipart HMAC KAT mismatch (branch 2)\n");
printf("%s expected, got %s\n", mac1, res1_hex);
return PS_FAILURE;
}
return PS_SUCCESS;
}
/* A two vector test case with common prefix. */
static int32 hmac_test_vector2(const unsigned char *key, size_t keylen,
const unsigned char *data_base, size_t data_baselen,
const unsigned char *data_post1, size_t data_post1len,
const unsigned char *data_post2, size_t data_post2len,
const char *mac1,
const char *mac2)
{
unsigned char res[20];
unsigned char res2[20];
char res_hex[43];
char res2_hex[43];
int32_t rv;
unsigned char key1[64];
psSize_t keyLen = (uint16_t) keylen;
unsigned char data[2048];
psSize_t datalen;
if (data_baselen > 1024 || data_post1len > 1024 || data_post2len > 1024)
{
/* Possible buffer overflow. */
printf("FAILED: Multi-part HMAC KAT execution failure (invalid test vector).\n");
return PS_FAILURE;
}
/* Try single-call interfaces for concatenated vector. */
memcpy(data, data_base, data_baselen);
memcpy(data + data_baselen, data_post1, data_post1len);
datalen = data_baselen + data_post1len;
rv = psHmacSha1(key, keylen, data, datalen, res, key1, &keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Multi-part combined HMAC KAT execution failure (rv=%d)\n",
(int) rv);
return PS_FAILURE;
}
hexify(&res, &res_hex);
if (strcmp(mac1, res_hex))
{
printf("FAILED: Single-part HMAC KAT (1) mismatch\n");
printf("%s expected, got %s\n", mac1, res_hex);
return PS_FAILURE;
}
memcpy(data, data_base, data_baselen);
memcpy(data + data_baselen, data_post2, data_post2len);
datalen = data_baselen + data_post2len;
rv = psHmacSha1(key, keylen, data, datalen, res2, key1, &keyLen);
if (rv != PS_SUCCESS)
{
printf("FAILED: Multi-part combined HMAC KAT execution failure (rv=%d)\n",
(int) rv);
return PS_FAILURE;
}
hexify(&res2, &res2_hex);
if (strcmp(mac2, res2_hex))
{
printf("FAILED: Single-part HMAC KAT (2) mismatch\n");
printf("%s expected, got %s\n", mac2, res2_hex);
return PS_FAILURE;
}
/* Continue with tests involving Init-Update-Update-Finish and copy. */
/* Use truncated key here. */
return hmac_test_vector2_copy(key1, keyLen, data_base, data_baselen, data_post1, data_post1len, data_post2, data_post2len, mac1, mac2);
}
const static unsigned char HMACKEY[] =
"The quick brown fox jumps over a lazy dog. "
"The quick brown fox jumps over another dog. "
"The quick brown fox jumps over the lazy dog again.";
#define HMACKEY_LEN (sizeof(HMACKEY) - 1)
extern int psHmacDsaSignBlinding;
int main(void)
{
psRes_t res;
if (psCryptoOpen(PSCRYPTO_CONFIG) < PS_SUCCESS)
{
printf("Failed to initialize library: psCryptoOpen failed\n");
return 4;
}
res = hmac_test_simple();
if (res != 0)
{
printf("hmac test failed: %d!\n", res);
return 1;
}
res = hmac_test_vector(HMACKEY, HMACKEY_LEN, (unsigned char *)"abc", 3,
"0xee251a5cb1c09d8b0978aaac1885a4c5faf5b5f5");
if (res != 0)
{
printf("hmac test failed: %d!\n", res);
return 1;
}
res = hmac_test_vector(HMACKEY, HMACKEY_LEN, HMACKEY, HMACKEY_LEN,
"0xac11e301b5426191f7bf05fb5b9db144f9bcd8c8");
if (res != 0)
{
printf("hmac test failed: %d!\n", res);
return 1;
}
res = hmac_test_vector2(HMACKEY, HMACKEY_LEN,
HMACKEY, 124,
HMACKEY + 124, HMACKEY_LEN - 124,
(unsigned char *) "zy cog again.", HMACKEY_LEN - 124,
"0xac11e301b5426191f7bf05fb5b9db144f9bcd8c8",
"0x2c9ccb6518efee19472ca7cabf9f5b4a99817c41");
if (res != 0)
{
printf("hmac test failed: %d!\n", res);
return 1;
}
res = hmac_test_vector2(HMACKEY, HMACKEY_LEN,
HMACKEY, 124,
HMACKEY + 124, HMACKEY_LEN - 124,
(unsigned char *) "", 0,
"0xac11e301b5426191f7bf05fb5b9db144f9bcd8c8",
"0x5122e938ae8ac9fa15751b9e9829a8de40a5bbe6");
if (res != 0)
{
printf("hmac test failed: %d!\n", res);
return 1;
}
psCryptoClose();
printf("Test executed successfully.\n");
return 0;
}
#else
int main(void)
{
printf("Skipped HMAC test: USE_HMAC is not enabled.\n");
return 0;
}
#endif /* USE_HMAC_SHA1 */