]> Cypherpunks repositories - gostls13.git/commitdiff
md5 Reset fix; preliminary hmac
authorRuss Cox <rsc@golang.org>
Fri, 22 May 2009 22:44:29 +0000 (15:44 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 22 May 2009 22:44:29 +0000 (15:44 -0700)
TBR=r
OCL=29279
CL=29279

src/lib/crypto/hmac/Makefile [new file with mode: 0644]
src/lib/crypto/hmac/hmac.go [new file with mode: 0644]
src/lib/crypto/hmac/hmac_test.go [new file with mode: 0644]
src/lib/crypto/md5/md5.go

diff --git a/src/lib/crypto/hmac/Makefile b/src/lib/crypto/hmac/Makefile
new file mode 100644 (file)
index 0000000..c7a430b
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# DO NOT EDIT.  Automatically generated by gobuild.
+# gobuild -m >Makefile
+
+D=/crypto/
+
+O_arm=5
+O_amd64=6
+O_386=8
+OS=568vq
+
+O=$(O_$(GOARCH))
+GC=$(O)g -I_obj
+CC=$(O)c -FVw
+AS=$(O)a
+AR=6ar
+
+default: packages
+
+clean:
+       rm -rf *.[$(OS)] *.a [$(OS)].out _obj
+
+test: packages
+       gotest
+
+coverage: packages
+       gotest
+       6cov -g `pwd` | grep -v '_test\.go:'
+
+%.$O: %.go
+       $(GC) $*.go
+
+%.$O: %.c
+       $(CC) $*.c
+
+%.$O: %.s
+       $(AS) $*.s
+
+O1=\
+       hmac.$O\
+
+
+phases: a1
+_obj$D/hmac.a: phases
+
+a1: $(O1)
+       $(AR) grc _obj$D/hmac.a hmac.$O
+       rm -f $(O1)
+
+
+newpkg: clean
+       mkdir -p _obj$D
+       $(AR) grc _obj$D/hmac.a
+
+$(O1): newpkg
+$(O2): a1
+
+nuke: clean
+       rm -f $(GOROOT)/pkg$D/hmac.a
+
+packages: _obj$D/hmac.a
+
+install: packages
+       test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D
+       cp _obj$D/hmac.a $(GOROOT)/pkg$D/hmac.a
diff --git a/src/lib/crypto/hmac/hmac.go b/src/lib/crypto/hmac/hmac.go
new file mode 100644 (file)
index 0000000..ccecc15
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): comments
+
+package hmac
+
+import (
+       "hash";
+       "os";
+)
+
+// k0 = key
+// ipad = 0x36 byte repeated to key len
+// opad = 0x5c byte repeated to key len
+// hmac = 
+//     H((k0 ^ opad) || H((k0 ^ ipad) || text))
+
+const (
+       padSize = 64;
+)
+
+type hmac struct {
+       size int;
+       key []byte;
+       tmp []byte;
+       inner hash.Hash;
+}
+
+func (h *hmac) tmpPad(xor byte) {
+       for i, k := range h.key {
+               h.tmp[i] = xor ^ k;
+       }
+       for i := len(h.key); i < padSize; i++ {
+               h.tmp[i] = xor;
+       }
+}
+
+func (h *hmac) init() {
+       h.tmpPad(0x36);
+       h.inner.Write(h.tmp[0:padSize]);
+}
+
+func (h *hmac) Sum() []byte {
+       h.tmpPad(0x5c);
+       sum := h.inner.Sum();
+       for i, b := range sum {
+               h.tmp[padSize + i] = b;
+       }
+       h.inner.Reset();
+       h.inner.Write(h.tmp);
+       return h.inner.Sum();
+}
+
+func (h *hmac) Write(p []byte) (n int, err os.Error) {
+       return h.inner.Write(p);
+}
+
+func (h *hmac) Size() int {
+       return h.size;
+}
+
+func (h *hmac) Reset() {
+       h.inner.Reset();
+       h.init();
+}
+
+func HMAC(h hash.Hash, key []byte) hash.Hash {
+       hm := new(hmac);
+       hm.inner = h;
+       hm.size = h.Size();
+       hm.key = make([]byte, len(key));
+       for i, k := range key {
+               hm.key[i] = k;
+       }
+       hm.tmp = make([]byte, padSize + hm.size);
+       hm.init();
+       return hm;
+}
diff --git a/src/lib/crypto/hmac/hmac_test.go b/src/lib/crypto/hmac/hmac_test.go
new file mode 100644 (file)
index 0000000..47bf6b6
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package hmac
+
+// TODO(rsc): better test
+
+import (
+       "crypto/hmac";
+       "crypto/md5";
+       "io";
+       "fmt";
+       "testing";
+)
+
+func TestHMAC_MD5(t *testing.T) {
+       // presotto's test
+       inner := md5.New();
+       h := HMAC(inner, io.StringBytes("Jefe"));
+       io.WriteString(h, "what do ya want for nothing?");
+       s := fmt.Sprintf("%x", h.Sum());
+       answer := "750c783e6ab0b503eaa86e310a5db738";
+       if s != answer {
+               t.Error("have", s, "\nwant", answer);
+       }
+}
index f8b8dda2fb973d145b5d8859443079026b66bf7d..cbc007f013f40cb07251b532d03014e48feb3f18 100644 (file)
@@ -35,6 +35,8 @@ func (d *digest) Reset() {
        d.s[1] = _Init1;
        d.s[2] = _Init2;
        d.s[3] = _Init3;
+       d.nx = 0;
+       d.len = 0;
 }
 
 // New returns a Hash computing the SHA1 checksum.