mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-09 18:41:55 +00:00
Add HMAC-MD5 library and tests
This commit is contained in:
parent
aa75e6dfe1
commit
40d323e150
61
lib/md5.c
61
lib/md5.c
@ -247,3 +247,64 @@ void md5_transform(u32 buf[4], u32 const in[16])
|
|||||||
buf[2] += c;
|
buf[2] += c;
|
||||||
buf[3] += d;
|
buf[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5-HMAC
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
md5_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
|
||||||
|
{
|
||||||
|
md5_context hd_tmp;
|
||||||
|
|
||||||
|
md5_init(&hd_tmp);
|
||||||
|
md5_update(&hd_tmp, buffer, length);
|
||||||
|
memcpy(outbuf, md5_final(&hd_tmp), MD5_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_hmac_init(md5_hmac_context *ctx, const byte *key, size_t keylen)
|
||||||
|
{
|
||||||
|
byte keybuf[MD5_BLOCK_SIZE], buf[MD5_BLOCK_SIZE];
|
||||||
|
|
||||||
|
// Hash the key if necessary
|
||||||
|
if (keylen <= MD5_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
memcpy(keybuf, key, keylen);
|
||||||
|
bzero(keybuf + keylen, MD5_BLOCK_SIZE - keylen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
md5_hash_buffer(keybuf, key, keylen);
|
||||||
|
bzero(keybuf + MD5_SIZE, MD5_BLOCK_SIZE - MD5_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the inner digest
|
||||||
|
md5_init(&ctx->ictx);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MD5_BLOCK_SIZE; i++)
|
||||||
|
buf[i] = keybuf[i] ^ 0x36;
|
||||||
|
md5_update(&ctx->ictx, buf, MD5_BLOCK_SIZE);
|
||||||
|
|
||||||
|
// Initialize the outer digest
|
||||||
|
md5_init(&ctx->octx);
|
||||||
|
for (i = 0; i < MD5_BLOCK_SIZE; i++)
|
||||||
|
buf[i] = keybuf[i] ^ 0x5c;
|
||||||
|
md5_update(&ctx->octx, buf, MD5_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void md5_hmac_update(md5_hmac_context *ctx, const byte *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
// Just update the inner digest
|
||||||
|
md5_update(&ctx->ictx, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *md5_hmac_final(md5_hmac_context *ctx)
|
||||||
|
{
|
||||||
|
// Finish the inner digest
|
||||||
|
byte *isha = md5_final(&ctx->ictx);
|
||||||
|
|
||||||
|
// Finish the outer digest
|
||||||
|
md5_update(&ctx->octx, isha, MD5_SIZE);
|
||||||
|
return md5_final(&ctx->octx);
|
||||||
|
}
|
||||||
|
12
lib/md5.h
12
lib/md5.h
@ -28,5 +28,17 @@ byte *md5_final(md5_context *context);
|
|||||||
|
|
||||||
void md5_transform(u32 buf[4], u32 const in[16]);
|
void md5_transform(u32 buf[4], u32 const in[16]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMAC-MD5
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
md5_context ictx;
|
||||||
|
md5_context octx;
|
||||||
|
} md5_hmac_context;
|
||||||
|
|
||||||
|
void md5_hmac_init(md5_hmac_context *ctx, const byte *key, size_t keylen);
|
||||||
|
void md5_hmac_update(md5_hmac_context *ctx, const byte *buf, size_t buflen);
|
||||||
|
byte *md5_hmac_final(md5_hmac_context *ctx);
|
||||||
|
|
||||||
#endif /* _BIRD_MD5_H_ */
|
#endif /* _BIRD_MD5_H_ */
|
||||||
|
144
lib/md5_test.c
144
lib/md5_test.c
@ -69,12 +69,154 @@ t_md5(void)
|
|||||||
return BT_SUCCESS;
|
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_md5_hmac(const struct hmac_data_in in, char (*out_hash)[MD5_HEX_SIZE])
|
||||||
|
{
|
||||||
|
md5_hmac_context ctx;
|
||||||
|
md5_hmac_init(&ctx, in.key, in.key_len);
|
||||||
|
md5_hmac_update(&ctx, in.data, in.data_len);
|
||||||
|
byte *hash_byte = md5_hmac_final(&ctx);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MD5_SIZE; i++)
|
||||||
|
sprintf(*out_hash + i*2, "%02x", hash_byte[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
t_md5_hmac(void)
|
||||||
|
{
|
||||||
|
struct in_out {
|
||||||
|
struct hmac_data_in in;
|
||||||
|
char out[MD5_HEX_SIZE];
|
||||||
|
} in_out[] = {
|
||||||
|
{
|
||||||
|
.in = {
|
||||||
|
.key = {
|
||||||
|
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||||
|
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||||
|
},
|
||||||
|
.key_len = 16,
|
||||||
|
.data = "Hi There",
|
||||||
|
.data_len = 8,
|
||||||
|
},
|
||||||
|
.out = "9294727a3638bb1c13f48ef8158bfc9d",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.in = {
|
||||||
|
.key = "Jefe",
|
||||||
|
.key_len = 4,
|
||||||
|
.data = "what do ya want for nothing?",
|
||||||
|
.data_len = 28,
|
||||||
|
},
|
||||||
|
.out = "750c783e6ab0b503eaa86e310a5db738",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.in = {
|
||||||
|
.key = {
|
||||||
|
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||||
|
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||||
|
},
|
||||||
|
.key_len = 16,
|
||||||
|
.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 = "56be34521d144c88dbb8c733f0e8b3f6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.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 = "697eaf0aca3a3aea3a75164746ffaa79",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.in = {
|
||||||
|
.key = {
|
||||||
|
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||||
|
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||||
|
},
|
||||||
|
.key_len = 16,
|
||||||
|
.data = "Test With Truncation",
|
||||||
|
.data_len = 20,
|
||||||
|
},
|
||||||
|
.out = "56461ef2342edc00f9bab995690efd4c",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.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 = "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.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 = "6f630fad67cda0ee1fb1f562db3aa53e",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
bt_assert_fn_in_out(get_md5_hmac, in_out, NULL, "'%s'");
|
||||||
|
|
||||||
|
return BT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
bt_init(argc, argv);
|
bt_init(argc, argv);
|
||||||
|
|
||||||
bt_test_suite(t_md5, "Test Suite by RFC 1321");
|
bt_test_suite(t_md5, "Test Suite by RFC 1321");
|
||||||
|
bt_test_suite(t_md5_hmac, "Test Suite by RFC 2202");
|
||||||
|
|
||||||
return bt_end();
|
return bt_end();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user