fixup hmacs

This commit is contained in:
Emery Hemingway 2021-09-07 12:01:28 +02:00
parent cd309ceb7d
commit 9a0b8caeb5
1 changed files with 81 additions and 19 deletions

View File

@ -3,28 +3,43 @@
import nimSHA2
proc hmacSha256*(key: openarray[byte]; msg: seq[byte]|string): seq[byte] =
proc fillPad(pad: var openarray[byte]; key: openarray[byte]; fillByte: byte) =
for i in 0..key.high: pad[i] = fillByte xor key[i].uint8
for i in key.len..pad.high: pad[i] = fillByte
proc hmacSha256*(key: openarray[byte]; msg: seq[byte]|string; outLength = 32): seq[byte] =
const blockSize = 64
assert(key.len <= blockSize)
assert(outLength <= 32)
var
inner, outer: SHA256
hash: SHA256
pad: array[blockSize, byte]
block:
const xorByte = 0x36'u8
for i in 0..key.high: pad[i] = xorByte xor key[i]
for i in key.len..pad.high: pad[i] = xorByte
initSHA(inner)
update(inner, pad)
update(inner, msg)
if key.len < blockSize:
fillPad(pad, key, xorByte)
else:
initSHA(hash)
update(hash, key)
var keyDigest = final(hash)
fillPad(pad, keyDigest, xorByte)
initSHA(hash)
update(hash, pad)
update(hash, msg)
var digest = final(hash)
block:
const xorByte = 0x5c'u8
for i in 0..key.high: pad[i] = xorByte xor key[i]
for i in key.len..pad.high: pad[i] = xorByte
initSHA(outer)
update(outer, pad)
update(outer, final(inner))
var digest = final(outer)
result.setLen(digest.len)
if key.len < blockSize:
fillPad(pad, key, xorByte)
else:
initSHA(hash)
update(hash, key)
var keyDigest = final(hash)
fillPad(pad, keyDigest, xorByte)
initSHA(hash)
update(hash, pad)
update(hash, digest)
digest = final(hash)
result.setLen(outLength)
copyMem(result[0].addr, digest[0].addr, result.len)
when isMainModule:
@ -34,7 +49,54 @@ when isMainModule:
var key: array[20,byte]
for b in key.mitems: b = 0x0b'u8
var data = "Hi There"
check(data.toHex == "4869205468657265")
let hmac = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let control = "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
check(hmac == control)
let a = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let b = "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
check(a == b)
test "2":
var key = "Jefe"
var data = "what do ya want for nothing?"
let a = cast[string](hmacSha256(cast[seq[byte]](key), data)).toHex.toLowerAscii
let b = "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
check(a == b)
test "3":
var
key: array[20,byte]
data = newSeq[byte](50)
for b in key.mitems: b = 0xaa'u8
for b in data.mitems: b = 0xdd'u8
let a = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let b = "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"
check(a == b)
test "4":
var
key: array[25,byte]
data = newSeq[byte](50)
for i in key.low..key.high: key[i] = i.uint8.succ
for b in data.mitems: b = 0xcd'u8
let a = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let b = "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
check(a == b)
test "5":
var
key: array[20,byte]
data = "Test With Truncation"
for b in key.mitems: b = 0x0c'u8
let a = cast[string](hmacSha256(key, data, 16)).toHex.toLowerAscii
let b = "a3b6167473100ee06e0c796c2955552b"
check(a == b)
test "6":
var
key: array[131,byte]
data = "Test Using Larger Than Block-Size Key - Hash Key First"
for b in key.mitems: b = 0xaa'u8
let a = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let b = "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"
check(a == b)
test "7":
var
key: array[131,byte]
data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."
for b in key.mitems: b = 0xaa'u8
let a = cast[string](hmacSha256(key, data)).toHex.toLowerAscii
let b = "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"
check(a == b)