summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/sha1.go25
-rw-r--r--lib/sha1_test.go91
2 files changed, 116 insertions, 0 deletions
diff --git a/lib/sha1.go b/lib/sha1.go
index 891ba83..fb81b92 100644
--- a/lib/sha1.go
+++ b/lib/sha1.go
@@ -236,3 +236,28 @@ func (s *Sha1) MacVerify(secret, msg, mac []byte) bool {
}
return false
}
+
+// HMAC-SHA1.
+func HmacSha1(key, msg []byte) []byte {
+ // Initialize SHA-1 object.
+ sha1 := Sha1{}
+ sha1.Init([]uint32{})
+
+ // Modify key based on it's size.
+ if len(key) > 64 { // > blocksize (64 bytes)
+ sha1.Message(key)
+ key = sha1.Hash()
+ }
+ if len(key) < 64 { // < blocksize (64 bytes)
+ // Pad with zeroes up to 64 bytes.
+ key = append(key, make([]byte, 64-len(key))...)
+ }
+
+ // Outer padded key.
+ opk := FixedXORBytes(key, FillBytes(0x5c, 64))
+
+ // Inner padded key.
+ ipk := FixedXORBytes(key, FillBytes(0x36, 64))
+
+ return sha1.Mac(opk, sha1.Mac(ipk, msg))
+}
diff --git a/lib/sha1_test.go b/lib/sha1_test.go
index 71b1296..58c6e61 100644
--- a/lib/sha1_test.go
+++ b/lib/sha1_test.go
@@ -42,3 +42,94 @@ func TestSha1Hash(t *testing.T) {
t.Errorf("sha1 test 3 failed: %x != %s\n", h, e)
}
}
+
+// Test cases from RFC 2202
+func TestHmacSha1(t *testing.T) {
+ // Test 1
+ k := FillBytes(0x0b, 20)
+ m := StrToBytes("Hi There")
+ h := HmacSha1(k, m)
+ e := "b617318655057264e28bc0b6fb378c8ef146be00" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 1 failed: %x != %s\n", h, e)
+ }
+
+ // Test 2
+ k = StrToBytes("Jefe")
+ m = StrToBytes("what do ya want for nothing?")
+ h = HmacSha1(k, m)
+ e = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 2 failed: %x != %s\n", h, e)
+ }
+
+ // Test 3
+ k = FillBytes(0xaa, 20)
+ m = FillBytes(0xdd, 50)
+ h = HmacSha1(k, m)
+ e = "125d7342b9ac11cd91a39af48aa17b4f63f175d3" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 3 failed: %x != %s\n", h, e)
+ }
+
+ // Test 4
+ k = []byte{
+ 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,
+ }
+ m = FillBytes(0xcd, 50)
+ h = HmacSha1(k, m)
+ e = "4c9007f4026250c6bc8414f9bf50c86c2d7235da" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 4 failed: %x != %s\n", h, e)
+ }
+
+ // Test 5
+ k = FillBytes(0x0c, 20)
+ m = StrToBytes("Test With Truncation")
+ h = HmacSha1(k, m)
+ e = "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 5 failed: %x != %s\n", h, e)
+ }
+
+ // Test 6
+ k = FillBytes(0xaa, 80)
+ m = StrToBytes("Test Using Larger Than Block-Size Key - Hash Key First")
+ h = HmacSha1(k, m)
+ e = "aa4ae5e15272d00e95705637ce8a3b55ed402112" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 6 failed: %x != %s\n", h, e)
+ }
+
+ // Test 7
+ k = FillBytes(0xaa, 80)
+ m = StrToBytes("Test Using Larger Than Block-Size Key and")
+ m = append(m, StrToBytes(" Larger Than One Block-Size Data")...)
+ h = HmacSha1(k, m)
+ e = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 7 failed: %x != %s\n", h, e)
+ }
+
+ // Test 8
+ k = FillBytes(0xaa, 80)
+ m = StrToBytes("Test Using Larger Than Block-Size Key - Hash Key First")
+ h = HmacSha1(k, m)
+ e = "aa4ae5e15272d00e95705637ce8a3b55ed402112" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 8 failed: %x != %s\n", h, e)
+ }
+
+ // Test 9
+ k = FillBytes(0xaa, 80)
+ m = StrToBytes("Test Using Larger Than Block-Size Key and Larger")
+ m = append(m, StrToBytes(" Than One Block-Size Data")...)
+ h = HmacSha1(k, m)
+ e = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91" // Expected HMAC-SHA1
+ if BytesToHexStr(h) != e {
+ t.Errorf("hmac-sha1 test 9 failed: %x != %s\n", h, e)
+ }
+}