Skip to content

Commit

Permalink
Added generic HMAC.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Sep 28, 2024
1 parent cc130e0 commit 3b009e0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
55 changes: 55 additions & 0 deletions lib/std/hash/hmac.c3
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module std::hash::hmac(<HashAlg, HASH_BYTES, BLOCK_BYTES>);

struct Hmac
{
HashAlg a, b;
}

fn char[HASH_BYTES] hash(char[] key, char[] message)
{
Hmac hmac @noinit;
hmac.init(key);
hmac.update(message);
return hmac.final();
}

fn void Hmac.init(&self, char[] key)
{
char[BLOCK_BYTES] buffer;
if (key.len > BLOCK_BYTES)
{
self.a.init();
self.a.update(key);
buffer[:HASH_BYTES] = self.a.final()[..];
}
else
{
buffer[:key.len] = key[..];
}

foreach (&b : buffer) *b ^= IPAD;

self.a.init();
self.a.update(&buffer);

foreach (&b : buffer) *b ^= IPAD ^ OPAD;

self.b.init();
self.b.update(&buffer);

buffer = {};
}

fn void Hmac.update(&self, char[] data)
{
self.a.update(data);
}

fn char[HASH_BYTES] Hmac.final(&self)
{
self.b.update(&&self.a.final());
return self.b.final();
}

const IPAD @private = 0x36;
const OPAD @private = 0x5C;
11 changes: 9 additions & 2 deletions lib/std/hash/md5.c3
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module std::hash::md5;
import std::hash::hmac;
import std::bits;

const BLOCK_BYTES = 64;
const HASH_BYTES = 16;

struct Md5
{
uint lo, hi;
Expand All @@ -9,7 +13,10 @@ struct Md5
uint[16] block;
}

fn char[16] hash(char[] data)
def HmacMd5 = Hmac(<Md5, HASH_BYTES, BLOCK_BYTES>);
def hmac = hmac::hash(<Md5, HASH_BYTES, BLOCK_BYTES>);

fn char[HASH_BYTES] hash(char[] data)
{
Md5 md5;
md5.init();
Expand Down Expand Up @@ -58,7 +65,7 @@ fn void Md5.update(&ctx, char[] data)
ctx.buffer[:data.len] = data[..];
}

fn char[16] Md5.final(&ctx)
fn char[HASH_BYTES] Md5.final(&ctx)
{
usz used = (usz)ctx.lo & 0x3f;
ctx.buffer[used++] = 0x80;
Expand Down
27 changes: 21 additions & 6 deletions lib/std/hash/sha1.c3
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,28 @@
// Implementation was off Steve Reid's SHA-1 C implementation

module std::hash::sha1;
import std::hash::hmac;
import std::bits;

const BLOCK_BYTES = 64;
const HASH_BYTES = 20;

struct Sha1
{
uint[5] state;
uint[2] count;
char[64] buffer;
char[BLOCK_BYTES] buffer;
}

def HmacSha1 = Hmac(<Sha1, HASH_BYTES, BLOCK_BYTES>);
def hmac = hmac::hash(<Sha1, HASH_BYTES, BLOCK_BYTES>);

fn char[HASH_BYTES] hash(char[] data)
{
Sha1 sha1 @noinit;
sha1.init();
sha1.update(data);
return sha1.final();
}

fn void Sha1.init(&self)
Expand Down Expand Up @@ -55,7 +70,7 @@ fn void Sha1.update(&self, char[] data)
}


fn char[20] Sha1.final(&self)
fn char[HASH_BYTES] Sha1.final(&self)
{
char[8] finalcount;
for (uint i = 0; i < 8; i++)
Expand All @@ -69,21 +84,21 @@ fn char[20] Sha1.final(&self)
}

self.update(&finalcount);
char[20] digest;
for (uint i = 0; i < 20; i++)
char[HASH_BYTES] digest;
for (uint i = 0; i < HASH_BYTES; i++)
{
digest[i] = (char)((self.state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF);
}

// Clear mem
mem::clear(self, Sha1.sizeof);
*self = {};
finalcount = {};
return digest;
}

union Long16 @local
{
char[64] c;
char[BLOCK_BYTES] c;
uint[16] l;
}

Expand Down
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
- Add `rnd` and `rand_in_range` default random functions.
- Additional timezone related functions for `datetime`.
- Added MD5 and crypto::safe_compare.
- Added generic HMAC.

## 0.6.2 Change list

Expand Down

0 comments on commit 3b009e0

Please sign in to comment.