From: rasky Date: Fri, 24 Sep 2010 13:56:42 +0000 (+0000) Subject: SEC: add HMAC implementation. X-Git-Tag: 2.6.0~99 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=ffcd73346399453a46d47c920545a10885ed42f9;p=bertos.git SEC: add HMAC implementation. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4302 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/sec/mac/hmac.c b/bertos/sec/mac/hmac.c new file mode 100644 index 00000000..1616ec44 --- /dev/null +++ b/bertos/sec/mac/hmac.c @@ -0,0 +1,105 @@ +/** + * \file + * + * + * \brief HMAC implementation + * \author Giovanni Bajo + * + */ + +#include "hmac.h" +#include +#include + + +static void HMAC_set_key(Mac *m, const uint8_t *key, size_t key_len) +{ + HMAC_Context *ctx = (HMAC_Context *)m; + + memset(ctx->key, 0, ctx->m.key_len); + if (key_len <= ctx->m.key_len) + memcpy(ctx->key, key, key_len); + else + { + hash_begin(ctx->h); + hash_update(ctx->h, key, key_len); + memcpy(ctx->key, hash_final(ctx->h), hash_digest_len(ctx->h)); + } + + xor_block_const(ctx->key, ctx->key, 0x5C, ctx->m.key_len); +} + +static void HMAC_begin(Mac *m) +{ + HMAC_Context *ctx = (HMAC_Context *)m; + int klen = ctx->m.key_len; + + xor_block_const(ctx->key, ctx->key, 0x36^0x5C, klen); + hash_begin(ctx->h); + hash_update(ctx->h, ctx->key, klen); +} + +static void HMAC_update(Mac *m, const uint8_t *data, size_t len) +{ + HMAC_Context *ctx = (HMAC_Context *)m; + hash_update(ctx->h, data, len); +} + +static uint8_t *HMAC_final(Mac *m) +{ + HMAC_Context *ctx = (HMAC_Context *)m; + int hlen = hash_digest_len(ctx->h); + + uint8_t temp[hlen]; + memcpy(temp, hash_final(ctx->h), hlen); + + xor_block_const(ctx->key, ctx->key, 0x5C^0x36, ctx->m.key_len); + hash_begin(ctx->h); + hash_update(ctx->h, ctx->key, ctx->m.key_len); + hash_update(ctx->h, temp, hlen); + + PURGE(temp); + return hash_final(ctx->h); +} + +/*********************************************************************/ + +void HMAC_init(HMAC_Context *ctx, Hash *h) +{ + ctx->h = h; + ctx->m.key_len = hash_block_len(h); + ctx->m.digest_len = hash_digest_len(h); + ctx->m.set_key = HMAC_set_key; + ctx->m.begin = HMAC_begin; + ctx->m.update = HMAC_update; + ctx->m.final = HMAC_final; + ASSERT(sizeof(ctx->key) >= ctx->m.key_len); +} diff --git a/bertos/sec/mac/hmac.h b/bertos/sec/mac/hmac.h new file mode 100644 index 00000000..c22a695b --- /dev/null +++ b/bertos/sec/mac/hmac.h @@ -0,0 +1,57 @@ +/** + * \file + * + * + * \brief HMAC (RFC 2104) implementation + * \author Giovanni Bajo + * + */ + +#ifndef SEC_MAC_HMAC_H +#define SEC_MAC_HMAC_H + +#include +#include + +typedef struct HMAC_Context +{ + Mac m; + Hash *h; + uint8_t key[64]; +} HMAC_Context; + +void HMAC_init(HMAC_Context* hmac, Hash *h); + +int HMAC_testSetup(void); +int HMAC_testRun(void); +int HMAC_testTearDown(void); + +#endif /* SEC_MAC_HMAC_H */ diff --git a/bertos/sec/mac/hmac_test.c b/bertos/sec/mac/hmac_test.c new file mode 100644 index 00000000..8b160964 --- /dev/null +++ b/bertos/sec/mac/hmac_test.c @@ -0,0 +1,192 @@ + +#include +#include +#include +#include +#include +#include + +int HMAC_testSetup(void) +{ + kdbg_init(); + return 0; +} + +int HMAC_testTearDown(void) +{ + return 0; +} + +struct Test_HMAC +{ + const char *key; + size_t key_len; + const char *data; + size_t data_len; + const char *digest; +}; + +const struct Test_HMAC tests_hmac_md5[] = +{ + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 16, + "Hi There", 8, + "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d", + }, + { + "Jefe", 4, + "what do ya want for nothing?", 28, + "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 16, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50, + "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6", + }, + { + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50, + "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79", + }, + { + "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 16, + "Test With Truncation", 20, + "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, + "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", 73, + "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", + } +}; + +const struct Test_HMAC tests_hmac_sha1[] = +{ + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20, + "Hi There", 8, + "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00", + }, + { + "Jefe", 4, + "what do ya want for nothing?", 28, + "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50, + "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3", + }, + { + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50, + "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda", + }, + { + "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20, + "Test With Truncation", 20, + "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12", + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80, + "Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data", 73, + "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91", + }, +}; + +static void algo_run_tests(HMAC_Context *hmac, const struct Test_HMAC *t, int count) +{ + for (int i=0; im, (const uint8_t*)t->key, t->key_len); + mac_begin(&hmac->m); + mac_update(&hmac->m, (const uint8_t*)t->data, t->data_len); + ASSERT(memcmp(mac_final(&hmac->m), t->digest, mac_digest_len(&hmac->m)) == 0); + } +} + +int HMAC_testRun(void) +{ + if (1) + { + MD5_Context md5; + MD5_init(&md5); + + HMAC_Context hmac; + HMAC_init(&hmac, &md5.h); + + algo_run_tests(&hmac, tests_hmac_md5, countof(tests_hmac_md5)); + } + + if (1) + { + SHA1_Context sha1; + SHA1_init(&sha1); + + HMAC_Context hmac; + HMAC_init(&hmac, &sha1.h); + + algo_run_tests(&hmac, tests_hmac_sha1, countof(tests_hmac_sha1)); + } + + return 0; +} + +TEST_MAIN(HMAC);