aez_amd64.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // aez_amd64.go - AMD64 specific routines.
  2. //
  3. // To the extent possible under law, Yawning Angel has waived all copyright
  4. // and related or neighboring rights to aez, using the Creative
  5. // Commons "CC0" public domain dedication. See LICENSE or
  6. // <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
  7. // +build amd64,!gccgo,!appengine,!noasm
  8. package aez
  9. var useAESNI = false
  10. //go:noescape
  11. func cpuidAMD64(cpuidParams *uint32)
  12. //go:noescape
  13. func resetAMD64SSE2()
  14. //go:noescape
  15. func xorBytes1x16AMD64SSE2(a, b, dst *byte)
  16. //go:noescape
  17. func xorBytes4x16AMD64SSE2(a, b, c, d, dst *byte)
  18. //go:noescape
  19. func aezAES4AMD64AESNI(j, i, l, k, src, dst *byte)
  20. //go:noescape
  21. func aezAES10AMD64AESNI(l, k, src, dst *byte)
  22. //go:noescape
  23. func aezCorePass1AMD64AESNI(src, dst, x, i, l, k, consts *byte, sz int)
  24. //go:noescape
  25. func aezCorePass2AMD64AESNI(dst, y, s, j, i, l, k, consts *byte, sz int)
  26. func xorBytes1x16(a, b, dst []byte) {
  27. xorBytes1x16AMD64SSE2(&a[0], &b[0], &dst[0])
  28. }
  29. func xorBytes4x16(a, b, c, d, dst []byte) {
  30. xorBytes4x16AMD64SSE2(&a[0], &b[0], &c[0], &d[0], &dst[0])
  31. }
  32. type roundAESNI struct {
  33. keys [extractedKeySize]byte
  34. }
  35. func (r *roundAESNI) Reset() {
  36. memwipe(r.keys[:])
  37. resetAMD64SSE2()
  38. }
  39. func (r *roundAESNI) AES4(j, i, l *[blockSize]byte, src []byte, dst *[blockSize]byte) {
  40. aezAES4AMD64AESNI(&j[0], &i[0], &l[0], &r.keys[0], &src[0], &dst[0])
  41. }
  42. func (r *roundAESNI) AES10(l *[blockSize]byte, src []byte, dst *[blockSize]byte) {
  43. aezAES10AMD64AESNI(&l[0], &r.keys[0], &src[0], &dst[0])
  44. }
  45. func newRoundAESNI(extractedKey *[extractedKeySize]byte) aesImpl {
  46. r := new(roundAESNI)
  47. copy(r.keys[:], extractedKey[:])
  48. return r
  49. }
  50. var dblConsts = [32]byte{
  51. // PSHUFB constant
  52. 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
  53. 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
  54. // Mask constant
  55. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  56. 0x01, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
  57. }
  58. func (e *eState) aezCorePass1(in, out []byte, X *[blockSize]byte, sz int) {
  59. // Call the "slow" implementation if hardware/OS doesn't allow AES-NI.
  60. if !useAESNI {
  61. e.aezCorePass1Slow(in, out, X, sz)
  62. return
  63. }
  64. // Call the AES-NI implementation.
  65. a := e.aes.(*roundAESNI)
  66. aezCorePass1AMD64AESNI(&in[0], &out[0], &X[0], &e.I[1][0], &e.L[0][0], &a.keys[0], &dblConsts[0], sz)
  67. }
  68. func (e *eState) aezCorePass2(in, out []byte, Y, S *[blockSize]byte, sz int) {
  69. // Call the "slow" implementation if hardware/OS doesn't allow AES-NI.
  70. if !useAESNI {
  71. e.aezCorePass2Slow(in, out, Y, S, sz)
  72. return
  73. }
  74. // Call the AES-NI implementation.
  75. a := e.aes.(*roundAESNI)
  76. aezCorePass2AMD64AESNI(&out[0], &Y[0], &S[0], &e.J[0][0], &e.I[1][0], &e.L[0][0], &a.keys[0], &dblConsts[0], sz)
  77. }
  78. func supportsAESNI() bool {
  79. const aesniBit = 1 << 25
  80. // Check for AES-NI support.
  81. // CPUID.(EAX=01H, ECX=0H):ECX.AESNI[bit 25]==1
  82. regs := [4]uint32{0x01}
  83. cpuidAMD64(&regs[0])
  84. return regs[2]&aesniBit != 0
  85. }
  86. func platformInit() {
  87. useAESNI = supportsAESNI()
  88. if useAESNI {
  89. newAes = newRoundAESNI
  90. isHardwareAccelerated = true
  91. }
  92. }