1 // Copyright 2009 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.
5 // This Go implementation is derived in part from the reference
6 // ANSI C implementation, which carries the following notice:
10 // @version 3.0 (December 2000)
12 // Optimised ANSI C code for the Rijndael cipher (now AES)
14 // @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
15 // @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
16 // @author Paulo Barreto <paulo.barreto@terra.com.br>
18 // This code is hereby placed in the public domain.
20 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
21 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
24 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // See FIPS 197 for specification, and see Daemen and Rijmen's Rijndael submission
33 // for implementation details.
34 // http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
35 // http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf
39 // Encrypt one block from src into dst, using the expanded key xk.
40 func encryptBlockGo(xk
[]uint32, dst
, src
[]byte) {
41 var s0
, s1
, s2
, s3
, t0
, t1
, t2
, t3
uint32
43 s0
= uint32(src
[0])<<24 |
uint32(src
[1])<<16 |
uint32(src
[2])<<8 |
uint32(src
[3])
44 s1
= uint32(src
[4])<<24 |
uint32(src
[5])<<16 |
uint32(src
[6])<<8 |
uint32(src
[7])
45 s2
= uint32(src
[8])<<24 |
uint32(src
[9])<<16 |
uint32(src
[10])<<8 |
uint32(src
[11])
46 s3
= uint32(src
[12])<<24 |
uint32(src
[13])<<16 |
uint32(src
[14])<<8 |
uint32(src
[15])
48 // First round just XORs input with key.
54 // Middle rounds shuffle using tables.
55 // Number of rounds is set by length of expanded key.
56 nr
:= len(xk
)/4 - 2 // - 2: one above, one more below
58 for r
:= 0; r
< nr
; r
++ {
59 t0
= xk
[k
+0] ^ te0
[uint8(s0
>>24)] ^ te1
[uint8(s1
>>16)] ^ te2
[uint8(s2
>>8)] ^ te3
[uint8(s3
)]
60 t1
= xk
[k
+1] ^ te0
[uint8(s1
>>24)] ^ te1
[uint8(s2
>>16)] ^ te2
[uint8(s3
>>8)] ^ te3
[uint8(s0
)]
61 t2
= xk
[k
+2] ^ te0
[uint8(s2
>>24)] ^ te1
[uint8(s3
>>16)] ^ te2
[uint8(s0
>>8)] ^ te3
[uint8(s1
)]
62 t3
= xk
[k
+3] ^ te0
[uint8(s3
>>24)] ^ te1
[uint8(s0
>>16)] ^ te2
[uint8(s1
>>8)] ^ te3
[uint8(s2
)]
64 s0
, s1
, s2
, s3
= t0
, t1
, t2
, t3
67 // Last round uses s-box directly and XORs to produce output.
68 s0
= uint32(sbox0
[t0
>>24])<<24 |
uint32(sbox0
[t1
>>16&0xff])<<16 |
uint32(sbox0
[t2
>>8&0xff])<<8 |
uint32(sbox0
[t3
&0xff])
69 s1
= uint32(sbox0
[t1
>>24])<<24 |
uint32(sbox0
[t2
>>16&0xff])<<16 |
uint32(sbox0
[t3
>>8&0xff])<<8 |
uint32(sbox0
[t0
&0xff])
70 s2
= uint32(sbox0
[t2
>>24])<<24 |
uint32(sbox0
[t3
>>16&0xff])<<16 |
uint32(sbox0
[t0
>>8&0xff])<<8 |
uint32(sbox0
[t1
&0xff])
71 s3
= uint32(sbox0
[t3
>>24])<<24 |
uint32(sbox0
[t0
>>16&0xff])<<16 |
uint32(sbox0
[t1
>>8&0xff])<<8 |
uint32(sbox0
[t2
&0xff])
78 dst
[0], dst
[1], dst
[2], dst
[3] = byte(s0
>>24), byte(s0
>>16), byte(s0
>>8), byte(s0
)
79 dst
[4], dst
[5], dst
[6], dst
[7] = byte(s1
>>24), byte(s1
>>16), byte(s1
>>8), byte(s1
)
80 dst
[8], dst
[9], dst
[10], dst
[11] = byte(s2
>>24), byte(s2
>>16), byte(s2
>>8), byte(s2
)
81 dst
[12], dst
[13], dst
[14], dst
[15] = byte(s3
>>24), byte(s3
>>16), byte(s3
>>8), byte(s3
)
84 // Decrypt one block from src into dst, using the expanded key xk.
85 func decryptBlockGo(xk
[]uint32, dst
, src
[]byte) {
86 var s0
, s1
, s2
, s3
, t0
, t1
, t2
, t3
uint32
88 s0
= uint32(src
[0])<<24 |
uint32(src
[1])<<16 |
uint32(src
[2])<<8 |
uint32(src
[3])
89 s1
= uint32(src
[4])<<24 |
uint32(src
[5])<<16 |
uint32(src
[6])<<8 |
uint32(src
[7])
90 s2
= uint32(src
[8])<<24 |
uint32(src
[9])<<16 |
uint32(src
[10])<<8 |
uint32(src
[11])
91 s3
= uint32(src
[12])<<24 |
uint32(src
[13])<<16 |
uint32(src
[14])<<8 |
uint32(src
[15])
93 // First round just XORs input with key.
99 // Middle rounds shuffle using tables.
100 // Number of rounds is set by length of expanded key.
101 nr
:= len(xk
)/4 - 2 // - 2: one above, one more below
103 for r
:= 0; r
< nr
; r
++ {
104 t0
= xk
[k
+0] ^ td0
[uint8(s0
>>24)] ^ td1
[uint8(s3
>>16)] ^ td2
[uint8(s2
>>8)] ^ td3
[uint8(s1
)]
105 t1
= xk
[k
+1] ^ td0
[uint8(s1
>>24)] ^ td1
[uint8(s0
>>16)] ^ td2
[uint8(s3
>>8)] ^ td3
[uint8(s2
)]
106 t2
= xk
[k
+2] ^ td0
[uint8(s2
>>24)] ^ td1
[uint8(s1
>>16)] ^ td2
[uint8(s0
>>8)] ^ td3
[uint8(s3
)]
107 t3
= xk
[k
+3] ^ td0
[uint8(s3
>>24)] ^ td1
[uint8(s2
>>16)] ^ td2
[uint8(s1
>>8)] ^ td3
[uint8(s0
)]
109 s0
, s1
, s2
, s3
= t0
, t1
, t2
, t3
112 // Last round uses s-box directly and XORs to produce output.
113 s0
= uint32(sbox1
[t0
>>24])<<24 |
uint32(sbox1
[t3
>>16&0xff])<<16 |
uint32(sbox1
[t2
>>8&0xff])<<8 |
uint32(sbox1
[t1
&0xff])
114 s1
= uint32(sbox1
[t1
>>24])<<24 |
uint32(sbox1
[t0
>>16&0xff])<<16 |
uint32(sbox1
[t3
>>8&0xff])<<8 |
uint32(sbox1
[t2
&0xff])
115 s2
= uint32(sbox1
[t2
>>24])<<24 |
uint32(sbox1
[t1
>>16&0xff])<<16 |
uint32(sbox1
[t0
>>8&0xff])<<8 |
uint32(sbox1
[t3
&0xff])
116 s3
= uint32(sbox1
[t3
>>24])<<24 |
uint32(sbox1
[t2
>>16&0xff])<<16 |
uint32(sbox1
[t1
>>8&0xff])<<8 |
uint32(sbox1
[t0
&0xff])
123 dst
[0], dst
[1], dst
[2], dst
[3] = byte(s0
>>24), byte(s0
>>16), byte(s0
>>8), byte(s0
)
124 dst
[4], dst
[5], dst
[6], dst
[7] = byte(s1
>>24), byte(s1
>>16), byte(s1
>>8), byte(s1
)
125 dst
[8], dst
[9], dst
[10], dst
[11] = byte(s2
>>24), byte(s2
>>16), byte(s2
>>8), byte(s2
)
126 dst
[12], dst
[13], dst
[14], dst
[15] = byte(s3
>>24), byte(s3
>>16), byte(s3
>>8), byte(s3
)
129 // Apply sbox0 to each byte in w.
130 func subw(w
uint32) uint32 {
131 return uint32(sbox0
[w
>>24])<<24 |
132 uint32(sbox0
[w
>>16&0xff])<<16 |
133 uint32(sbox0
[w
>>8&0xff])<<8 |
134 uint32(sbox0
[w
&0xff])
138 func rotw(w
uint32) uint32 { return w
<<8 | w
>>24 }
140 // Key expansion algorithm. See FIPS-197, Figure 11.
141 // Their rcon[i] is our powx[i-1] << 24.
142 func expandKeyGo(key
[]byte, enc
, dec
[]uint32) {
143 // Encryption key setup.
146 for i
= 0; i
< nk
; i
++ {
147 enc
[i
] = uint32(key
[4*i
])<<24 |
uint32(key
[4*i
+1])<<16 |
uint32(key
[4*i
+2])<<8 |
uint32(key
[4*i
+3])
149 for ; i
< len(enc
); i
++ {
152 t
= subw(rotw(t
)) ^ (uint32(powx
[i
/nk
-1]) << 24)
153 } else if nk
> 6 && i%nk
== 4 {
156 enc
[i
] = enc
[i
-nk
] ^ t
159 // Derive decryption key from encryption key.
160 // Reverse the 4-word round key sets from enc to produce dec.
161 // All sets but the first and last get the MixColumn transform applied.
166 for i
:= 0; i
< n
; i
+= 4 {
168 for j
:= 0; j
< 4; j
++ {
170 if i
> 0 && i
+4 < n
{
171 x
= td0
[sbox0
[x
>>24]] ^ td1
[sbox0
[x
>>16&0xff]] ^ td2
[sbox0
[x
>>8&0xff]] ^ td3
[sbox0
[x
&0xff]]