summaryrefslogtreecommitdiff
path: root/libgo/go/crypto/aes/cipher_amd64.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/aes/cipher_amd64.go')
-rw-r--r--libgo/go/crypto/aes/cipher_amd64.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/libgo/go/crypto/aes/cipher_amd64.go b/libgo/go/crypto/aes/cipher_amd64.go
new file mode 100644
index 0000000000..fbd157e49e
--- /dev/null
+++ b/libgo/go/crypto/aes/cipher_amd64.go
@@ -0,0 +1,85 @@
+// Copyright 2012 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.
+
+// +build ignore
+
+package aes
+
+import (
+ "crypto/cipher"
+ "crypto/internal/cipherhw"
+)
+
+// defined in asm_amd64.s
+func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
+
+type aesCipherAsm struct {
+ aesCipher
+}
+
+var useAsm = cipherhw.AESGCMSupport()
+
+func newCipher(key []byte) (cipher.Block, error) {
+ if !useAsm {
+ return newCipherGeneric(key)
+ }
+ n := len(key) + 28
+ c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
+ rounds := 10
+ switch len(key) {
+ case 128 / 8:
+ rounds = 10
+ case 192 / 8:
+ rounds = 12
+ case 256 / 8:
+ rounds = 14
+ }
+ expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
+ if hasGCMAsm() {
+ return &aesCipherGCM{c}, nil
+ }
+
+ return &c, nil
+}
+
+func (c *aesCipherAsm) BlockSize() int { return BlockSize }
+
+func (c *aesCipherAsm) Encrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
+}
+
+func (c *aesCipherAsm) Decrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
+}
+
+// expandKey is used by BenchmarkExpand to ensure that the asm implementation
+// of key expansion is used for the benchmark when it is available.
+func expandKey(key []byte, enc, dec []uint32) {
+ if useAsm {
+ rounds := 10 // rounds needed for AES128
+ switch len(key) {
+ case 192 / 8:
+ rounds = 12
+ case 256 / 8:
+ rounds = 14
+ }
+ expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
+ } else {
+ expandKeyGo(key, enc, dec)
+ }
+}