Commit 6d3c17d5 authored by Pavel Tvrdík's avatar Pavel Tvrdík
Browse files

SHA1: Integrate sha1_hmac.c into sha1.c

parent 17a0035a
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -280,3 +280,61 @@ sha1_hash_buffer(byte *outbuf, const byte *buffer, uint length)
  sha1_update(&hd, buffer, length);
  memcpy(outbuf, sha1_final(&hd), SHA1_SIZE);
}

void
sha1_hmac_init(sha1_hmac_context *hd, const byte *key, uint keylen)
{
  byte keybuf[SHA1_BLOCK_SIZE], buf[SHA1_BLOCK_SIZE];

  // Hash the key if necessary
  if (keylen <= SHA1_BLOCK_SIZE)
  {
    memcpy(keybuf, key, keylen);
    bzero(keybuf + keylen, SHA1_BLOCK_SIZE - keylen);
  }
  else
  {
    sha1_hash_buffer(keybuf, key, keylen);
    bzero(keybuf + SHA1_SIZE, SHA1_BLOCK_SIZE - SHA1_SIZE);
  }

  // Initialize the inner digest
  sha1_init(&hd->ictx);
  int i;
  for (i = 0; i < SHA1_BLOCK_SIZE; i++)
    buf[i] = keybuf[i] ^ 0x36;
  sha1_update(&hd->ictx, buf, SHA1_BLOCK_SIZE);

  // Initialize the outer digest
  sha1_init(&hd->octx);
  for (i = 0; i < SHA1_BLOCK_SIZE; i++)
    buf[i] = keybuf[i] ^ 0x5c;
  sha1_update(&hd->octx, buf, SHA1_BLOCK_SIZE);
}

void
sha1_hmac_update(sha1_hmac_context *hd, const byte *data, uint datalen)
{
  // Just update the inner digest
  sha1_update(&hd->ictx, data, datalen);
}

byte *sha1_hmac_final(sha1_hmac_context *hd)
{
  // Finish the inner digest
  byte *isha = sha1_final(&hd->ictx);

  // Finish the outer digest
  sha1_update(&hd->octx, isha, SHA1_SIZE);
  return sha1_final(&hd->octx);
}

void
sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen)
{
  sha1_hmac_context hd;
  sha1_hmac_init(&hd, key, keylen);
  sha1_hmac_update(&hd, data, datalen);
  byte *osha = sha1_hmac_final(&hd);
  memcpy(outbuf, osha, SHA1_SIZE);
}

lib/sha1_hmac.c

deleted100644 → 0
+0 −76
Original line number Diff line number Diff line
/*
 *	BIRD -- HMAC-SHA1 Message Authentication (RFC 2202)
 *
 *	(c) 2015 CZ.NIC z.s.p.o.
 *
 *	Based on the code from libucw-6.4
 *	(c) 2008--2009 Martin Mares <mj@ucw.cz>
 *
 *	Based on the code from libgcrypt-1.2.3, which is
 *	(c) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <string.h>

#include "lib/sha1.h"
#include "lib/unaligned.h"

void
sha1_hmac_init(sha1_hmac_context *hd, const byte *key, uint keylen)
{
  byte keybuf[SHA1_BLOCK_SIZE], buf[SHA1_BLOCK_SIZE];

  // Hash the key if necessary
  if (keylen <= SHA1_BLOCK_SIZE)
  {
    memcpy(keybuf, key, keylen);
    bzero(keybuf + keylen, SHA1_BLOCK_SIZE - keylen);
  }
  else
  {
    sha1_hash_buffer(keybuf, key, keylen);
    bzero(keybuf + SHA1_SIZE, SHA1_BLOCK_SIZE - SHA1_SIZE);
  }

  // Initialize the inner digest
  sha1_init(&hd->ictx);
  int i;
  for (i = 0; i < SHA1_BLOCK_SIZE; i++)
    buf[i] = keybuf[i] ^ 0x36;
  sha1_update(&hd->ictx, buf, SHA1_BLOCK_SIZE);

  // Initialize the outer digest
  sha1_init(&hd->octx);
  for (i = 0; i < SHA1_BLOCK_SIZE; i++)
    buf[i] = keybuf[i] ^ 0x5c;
  sha1_update(&hd->octx, buf, SHA1_BLOCK_SIZE);
}

void
sha1_hmac_update(sha1_hmac_context *hd, const byte *data, uint datalen)
{
  // Just update the inner digest
  sha1_update(&hd->ictx, data, datalen);
}

byte *sha1_hmac_final(sha1_hmac_context *hd)
{
  // Finish the inner digest
  byte *isha = sha1_final(&hd->ictx);

  // Finish the outer digest
  sha1_update(&hd->octx, isha, SHA1_SIZE);
  return sha1_final(&hd->octx);
}

void
sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen)
{
  sha1_hmac_context hd;
  sha1_hmac_init(&hd, key, keylen);
  sha1_hmac_update(&hd, data, datalen);
  byte *osha = sha1_hmac_final(&hd);
  memcpy(outbuf, osha, SHA1_SIZE);
}

lib/sha1_hmac_test.c

deleted100644 → 0
+0 −202
Original line number Diff line number Diff line
/*
 *	BIRD Library -- HMAC-SHA1 Message Authentication Tests
 *
 *	(c) 2015 CZ.NIC z.s.p.o.
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <stdlib.h>

#include "test/birdtest.h"
#include "sysdep/config.h"
#include "lib/sha1.h"
#include "lib/sha1.c"		/* REMOVE ME */
#include "lib/sha1_hmac.c"	/* REMOVE ME */

#define HMAC_BUFFER_SIZE 80
struct hmac_data_in {
  byte key[HMAC_BUFFER_SIZE];
  uint key_len;
  byte data[HMAC_BUFFER_SIZE];
  uint data_len;
};

static void
get_sha1_hmac(const struct hmac_data_in in, char (*out_hash)[SHA1_HEX_SIZE])
{
  sha1_hmac_context ctx;
  sha1_hmac_init(&ctx, in.key, in.key_len);
  sha1_hmac_update(&ctx, in.data, in.data_len);
  byte *hash_byte = sha1_hmac_final(&ctx);

  int i;
  for (i = 0; i < SHA1_SIZE; i++)
    sprintf(*out_hash + i*2, "%02x", hash_byte[i]);
}

static int
t_sha1(void)
{
  struct in_out {
    struct hmac_data_in in;
    char out[SHA1_HEX_SIZE];
  } in_out[] = {
      {
	  .in  = {
	      .key = {
		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
	      },
	      .key_len = 20,
	      .data = "Hi There",
	      .data_len = 8,
	  },
	  .out = "b617318655057264e28bc0b6fb378c8ef146be00",
      },
      {
	  .in  = {
	      .key = "Jefe",
	      .key_len = 4,
	      .data = "what do ya want for nothing?",
	      .data_len = 28,
	  },
	  .out = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 20,
	      .data = {
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
	      },
	      .data_len = 50,
	  },
	  .out = "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
      },
      {
	  .in  = {
	      .key = {
		  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
		  0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
		  0x15, 0x16, 0x17, 0x18, 0x19,
	      },
	      .key_len = 25,
	      .data = {
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
	      },
	      .data_len = 50,
	  },
	  .out = "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
      },
      {
	  .in  = {
	      .key = {
		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
	      },
	      .key_len = 20,
	      .data = "Test With Truncation",
	      .data_len = 20,
	  },
	  .out = "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key - Hash Key First",
	      .data_len = 54,
	  },
	  .out = "aa4ae5e15272d00e95705637ce8a3b55ed402112",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
	      .data_len = 73,
	  },
	  .out = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key - Hash Key First",
	      .data_len = 54,
	  },
	  .out = "aa4ae5e15272d00e95705637ce8a3b55ed402112",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
	      .data_len = 73,
	  },
	  .out = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
      },
  };

  bt_assert_fn_in_out(get_sha1_hmac, in_out, NULL, "'%s'");

  return BT_SUCCESS;
}

int
main(int argc, char *argv[])
{
  bt_init(argc, argv);

  bt_test_suite(t_sha1, "Test Suite by RFC 2202");

  return bt_end();
}
+179 −1
Original line number Diff line number Diff line
@@ -68,12 +68,190 @@ t_sha1(void)
  return BT_SUCCESS;
}

#define HMAC_BUFFER_SIZE 80
struct hmac_data_in {
  byte key[HMAC_BUFFER_SIZE];
  uint key_len;
  byte data[HMAC_BUFFER_SIZE];
  uint data_len;
};

static void
get_sha1_hmac(const struct hmac_data_in in, char (*out_hash)[SHA1_HEX_SIZE])
{
  sha1_hmac_context ctx;
  sha1_hmac_init(&ctx, in.key, in.key_len);
  sha1_hmac_update(&ctx, in.data, in.data_len);
  byte *hash_byte = sha1_hmac_final(&ctx);

  int i;
  for (i = 0; i < SHA1_SIZE; i++)
    sprintf(*out_hash + i*2, "%02x", hash_byte[i]);
}

static int
t_sha1_hmac(void)
{
  struct in_out {
    struct hmac_data_in in;
    char out[SHA1_HEX_SIZE];
  } in_out[] = {
      {
	  .in  = {
	      .key = {
		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
		  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
	      },
	      .key_len = 20,
	      .data = "Hi There",
	      .data_len = 8,
	  },
	  .out = "b617318655057264e28bc0b6fb378c8ef146be00",
      },
      {
	  .in  = {
	      .key = "Jefe",
	      .key_len = 4,
	      .data = "what do ya want for nothing?",
	      .data_len = 28,
	  },
	  .out = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 20,
	      .data = {
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
		  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
	      },
	      .data_len = 50,
	  },
	  .out = "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
      },
      {
	  .in  = {
	      .key = {
		  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
		  0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
		  0x15, 0x16, 0x17, 0x18, 0x19,
	      },
	      .key_len = 25,
	      .data = {
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
		  0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
	      },
	      .data_len = 50,
	  },
	  .out = "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
      },
      {
	  .in  = {
	      .key = {
		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
		  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
	      },
	      .key_len = 20,
	      .data = "Test With Truncation",
	      .data_len = 20,
	  },
	  .out = "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key - Hash Key First",
	      .data_len = 54,
	  },
	  .out = "aa4ae5e15272d00e95705637ce8a3b55ed402112",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
	      .data_len = 73,
	  },
	  .out = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key - Hash Key First",
	      .data_len = 54,
	  },
	  .out = "aa4ae5e15272d00e95705637ce8a3b55ed402112",
      },
      {
	  .in  = {
	      .key = {
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
		  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	      },
	      .key_len = 80,
	      .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
	      .data_len = 73,
	  },
	  .out = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
      },
  };

  bt_assert_fn_in_out(get_sha1_hmac, in_out, NULL, "'%s'");

  return BT_SUCCESS;
}

int
main(int argc, char *argv[])
{
  bt_init(argc, argv);

  bt_test_suite(t_sha1, 	"Test Suite by RFC 1321 (it is for MD5)");
  bt_test_suite(t_sha1_hmac, 	"Test Suite by RFC 2202");

  return bt_end();
}