1// Copyright 2012 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// +build ignore 6 7package aes 8 9import ( 10 "crypto/cipher" 11 "crypto/internal/cipherhw" 12) 13 14// defined in asm_amd64.s 15func encryptBlockAsm(nr int, xk *uint32, dst, src *byte) 16func decryptBlockAsm(nr int, xk *uint32, dst, src *byte) 17func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32) 18 19type aesCipherAsm struct { 20 aesCipher 21} 22 23var useAsm = cipherhw.AESGCMSupport() 24 25func newCipher(key []byte) (cipher.Block, error) { 26 if !useAsm { 27 return newCipherGeneric(key) 28 } 29 n := len(key) + 28 30 c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}} 31 rounds := 10 32 switch len(key) { 33 case 128 / 8: 34 rounds = 10 35 case 192 / 8: 36 rounds = 12 37 case 256 / 8: 38 rounds = 14 39 } 40 expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0]) 41 if hasGCMAsm() { 42 return &aesCipherGCM{c}, nil 43 } 44 45 return &c, nil 46} 47 48func (c *aesCipherAsm) BlockSize() int { return BlockSize } 49 50func (c *aesCipherAsm) Encrypt(dst, src []byte) { 51 if len(src) < BlockSize { 52 panic("crypto/aes: input not full block") 53 } 54 if len(dst) < BlockSize { 55 panic("crypto/aes: output not full block") 56 } 57 encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0]) 58} 59 60func (c *aesCipherAsm) Decrypt(dst, src []byte) { 61 if len(src) < BlockSize { 62 panic("crypto/aes: input not full block") 63 } 64 if len(dst) < BlockSize { 65 panic("crypto/aes: output not full block") 66 } 67 decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0]) 68} 69 70// expandKey is used by BenchmarkExpand to ensure that the asm implementation 71// of key expansion is used for the benchmark when it is available. 72func expandKey(key []byte, enc, dec []uint32) { 73 if useAsm { 74 rounds := 10 // rounds needed for AES128 75 switch len(key) { 76 case 192 / 8: 77 rounds = 12 78 case 256 / 8: 79 rounds = 14 80 } 81 expandKeyAsm(rounds, &key[0], &enc[0], &dec[0]) 82 } else { 83 expandKeyGo(key, enc, dec) 84 } 85} 86