diff --git a/src/lib/crypto/hmac/Makefile b/src/lib/crypto/hmac/Makefile new file mode 100644 index 00000000000..c7a430b1501 --- /dev/null +++ b/src/lib/crypto/hmac/Makefile @@ -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 index 00000000000..ccecc15d202 --- /dev/null +++ b/src/lib/crypto/hmac/hmac.go @@ -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 index 00000000000..47bf6b609d0 --- /dev/null +++ b/src/lib/crypto/hmac/hmac_test.go @@ -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); + } +} diff --git a/src/lib/crypto/md5/md5.go b/src/lib/crypto/md5/md5.go index f8b8dda2fb9..cbc007f013f 100644 --- a/src/lib/crypto/md5/md5.go +++ b/src/lib/crypto/md5/md5.go @@ -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.