...
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 n := len(key) + 28
48 c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
49 var rounds int
50 switch len(key) {
51 case 128 / 8:
52 rounds = 10
53 case 192 / 8:
54 rounds = 12
55 case 256 / 8:
56 rounds = 14
57 default:
58 return nil, KeySizeError(len(key))
59 }
60
61 expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
62 if supportsAES && supportsGFMUL {
63 return &aesCipherGCM{c}, nil
64 }
65 return &c, nil
66 }
67
68 func (c *aesCipherAsm) BlockSize() int { return BlockSize }
69
70 func (c *aesCipherAsm) Encrypt(dst, src []byte) {
71 boring.Unreachable()
72 if len(src) < BlockSize {
73 panic("crypto/aes: input not full block")
74 }
75 if len(dst) < BlockSize {
76 panic("crypto/aes: output not full block")
77 }
78 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
79 panic("crypto/aes: invalid buffer overlap")
80 }
81 encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
82 }
83
84 func (c *aesCipherAsm) Decrypt(dst, src []byte) {
85 boring.Unreachable()
86 if len(src) < BlockSize {
87 panic("crypto/aes: input not full block")
88 }
89 if len(dst) < BlockSize {
90 panic("crypto/aes: output not full block")
91 }
92 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
93 panic("crypto/aes: invalid buffer overlap")
94 }
95 decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
96 }
97
98
99
100 func expandKey(key []byte, enc, dec []uint32) {
101 if supportsAES {
102 rounds := 10
103 switch len(key) {
104 case 192 / 8:
105 rounds = 12
106 case 256 / 8:
107 rounds = 14
108 }
109 expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
110 } else {
111 expandKeyGo(key, enc, dec)
112 }
113 }
114
View as plain text