From ba3ac04c505db3e0c56e95ef414ca297ca749313 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 18 Jun 2017 01:55:49 -0400 Subject: [PATCH] Implemented SHA1Hmac(). --- sha1.c | 38 ++++++++++++++++++++++++++++++++++++++ sha1.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/sha1.c b/sha1.c index b641529..190f789 100644 --- a/sha1.c +++ b/sha1.c @@ -177,3 +177,41 @@ SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) #endif #endif } + + +/* https://www.ietf.org/rfc/rfc2104.txt */ +void SHA1Hmac(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t digest[SHA1_DIGEST_LENGTH]) +{ + SHA1_CTX sha1; + uint8_t block[64]; // 512 bits. + uint8_t xori[sizeof (block)]; + uint8_t xoro[sizeof (block)]; + int i; + + memset(block, '\0', sizeof (block)); + if (keylen <= sizeof (block)) { + memcpy(block, key, keylen); + } else { + /* SHA-1 the key itself to shrink it down. */ + SHA1Init(&sha1); + SHA1Update(&sha1, key, keylen); + SHA1Final(block, &sha1); + } + + for (i = 0; i < sizeof (block); i++) { + const uint8_t b = block[i]; + xori[i] = b ^ 0x36; /* XOR block vs ipad value */ + xoro[i] = b ^ 0x5C; /* XOR block vs opad value */ + } + + SHA1Init(&sha1); + SHA1Update(&sha1, xori, sizeof (xori)); + SHA1Update(&sha1, msg, msglen); + SHA1Final(block, &sha1); + + SHA1Init(&sha1); + SHA1Update(&sha1, xoro, sizeof (xoro)); + SHA1Update(&sha1, block, SHA1_DIGEST_LENGTH); + SHA1Final(digest, &sha1); +} + diff --git a/sha1.h b/sha1.h index 608766b..6bbbebf 100644 --- a/sha1.h +++ b/sha1.h @@ -25,4 +25,6 @@ void SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH]); void SHA1Update(SHA1_CTX *context, const uint8_t *data, const uint32_t len); void SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context); +void SHA1Hmac(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t digest[SHA1_DIGEST_LENGTH]); + #endif /* _SHA1_H_ */