Source file
src/crypto/aes/cipher_asm.go
1
2
3
4
5
6
7 package aes
8
9 import (
10 "crypto/cipher"
11 "crypto/internal/alias"
12 "crypto/internal/boring"
13 "internal/cpu"
14 "internal/goarch"
15 )
16
17
18
19
20 func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
21
22
23 func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
24
25
26 func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
27
28 type aesCipherAsm struct {
29 aesCipher
30 }
31
32
33
34
35
36 type aesCipherGCM struct {
37 aesCipherAsm
38 }
39
40 var supportsAES = cpu.X86.HasAES || cpu.ARM64.HasAES || goarch.IsPpc64 == 1 || goarch.IsPpc64le == 1
41 var supportsGFMUL = cpu.X86.HasPCLMULQDQ || cpu.ARM64.HasPMULL
42
43 func newCipher(key []byte) (cipher.Block, error) {
44 if !supportsAES {
45 return newCipherGeneric(key)
46 }
47
48
49 c := aesCipherGCM{aesCipherAsm{aesCipher{l: uint8(len(key) + 28)}}}
50 var rounds int
51 switch len(key) {
52 case 128 / 8:
53 rounds = 10
54 case 192 / 8:
55 rounds = 12
56 case 256 / 8:
57 rounds = 14
58 default:
59 return nil, KeySizeError(len(key))
60 }
61
62 expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
63 if supportsAES && supportsGFMUL {
64 return &c, nil
65 }
66 return &c.aesCipherAsm, nil
67 }
68
69 func (c *aesCipherAsm) BlockSize() int { return BlockSize }
70
71 func (c *aesCipherAsm) Encrypt(dst, src []byte) {
72 boring.Unreachable()
73 if len(src) < BlockSize {
74 panic("crypto/aes: input not full block")
75 }
76 if len(dst) < BlockSize {
77 panic("crypto/aes: output not full block")
78 }
79 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
80 panic("crypto/aes: invalid buffer overlap")
81 }
82 encryptBlockAsm(int(c.l)/4-1, &c.enc[0], &dst[0], &src[0])
83 }
84
85 func (c *aesCipherAsm) Decrypt(dst, src []byte) {
86 boring.Unreachable()
87 if len(src) < BlockSize {
88 panic("crypto/aes: input not full block")
89 }
90 if len(dst) < BlockSize {
91 panic("crypto/aes: output not full block")
92 }
93 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
94 panic("crypto/aes: invalid buffer overlap")
95 }
96 decryptBlockAsm(int(c.l)/4-1, &c.dec[0], &dst[0], &src[0])
97 }
98
99
100
101 func expandKey(key []byte, enc, dec []uint32) {
102 if supportsAES {
103 rounds := 10
104 switch len(key) {
105 case 192 / 8:
106 rounds = 12
107 case 256 / 8:
108 rounds = 14
109 }
110 expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
111 } else {
112 expandKeyGo(key, enc, dec)
113 }
114 }
115
View as plain text