cipher_amd64.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. package aes12
  5. // defined in asm_amd64.s
  6. func hasAsm() bool
  7. func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
  8. func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
  9. func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
  10. type aesCipherAsm struct {
  11. aesCipher
  12. }
  13. var useAsm = hasAsm()
  14. func newCipher(key []byte) (Block, error) {
  15. if !useAsm {
  16. return newCipherGeneric(key)
  17. }
  18. n := len(key) + 28
  19. c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
  20. rounds := 10
  21. switch len(key) {
  22. case 128 / 8:
  23. rounds = 10
  24. case 192 / 8:
  25. rounds = 12
  26. case 256 / 8:
  27. rounds = 14
  28. }
  29. expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
  30. if hasGCMAsm() {
  31. return &aesCipherGCM{c}, nil
  32. }
  33. return &c, nil
  34. }
  35. func (c *aesCipherAsm) BlockSize() int { return BlockSize }
  36. func (c *aesCipherAsm) Encrypt(dst, src []byte) {
  37. if len(src) < BlockSize {
  38. panic("crypto/aes: input not full block")
  39. }
  40. if len(dst) < BlockSize {
  41. panic("crypto/aes: output not full block")
  42. }
  43. encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
  44. }
  45. func (c *aesCipherAsm) Decrypt(dst, src []byte) {
  46. if len(src) < BlockSize {
  47. panic("crypto/aes: input not full block")
  48. }
  49. if len(dst) < BlockSize {
  50. panic("crypto/aes: output not full block")
  51. }
  52. decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
  53. }
  54. // expandKey is used by BenchmarkExpand to ensure that the asm implementation
  55. // of key expansion is used for the benchmark when it is available.
  56. func expandKey(key []byte, enc, dec []uint32) {
  57. if useAsm {
  58. rounds := 10 // rounds needed for AES128
  59. switch len(key) {
  60. case 192 / 8:
  61. rounds = 12
  62. case 256 / 8:
  63. rounds = 14
  64. }
  65. expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
  66. } else {
  67. expandKeyGo(key, enc, dec)
  68. }
  69. }