]> Cypherpunks.ru repositories - gostls13.git/blob - src/crypto/aes/cipher_amd64.go
[dev.boringcrypto] crypto/rsa: drop random source reading emulation
[gostls13.git] / src / crypto / aes / cipher_amd64.go
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
5 package aes
6
7 import (
8         "crypto/cipher"
9         "crypto/internal/boring"
10         "internal/cpu"
11 )
12
13 // defined in asm_amd64.s
14
15 func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
16 func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
17 func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
18
19 type aesCipherAsm struct {
20         aesCipher
21 }
22
23 func newCipher(key []byte) (cipher.Block, error) {
24         if !cpu.X86.HasAES {
25                 return newCipherGeneric(key)
26         }
27         n := len(key) + 28
28         c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
29         rounds := 10
30         switch len(key) {
31         case 128 / 8:
32                 rounds = 10
33         case 192 / 8:
34                 rounds = 12
35         case 256 / 8:
36                 rounds = 14
37         }
38
39         expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
40         if cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ {
41                 return &aesCipherGCM{c}, nil
42         }
43
44         return &c, nil
45 }
46
47 func (c *aesCipherAsm) BlockSize() int { return BlockSize }
48
49 func (c *aesCipherAsm) Encrypt(dst, src []byte) {
50         boring.Unreachable()
51         if len(src) < BlockSize {
52                 panic("crypto/aes: input not full block")
53         }
54         if len(dst) < BlockSize {
55                 panic("crypto/aes: output not full block")
56         }
57         encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
58 }
59
60 func (c *aesCipherAsm) Decrypt(dst, src []byte) {
61         boring.Unreachable()
62         if len(src) < BlockSize {
63                 panic("crypto/aes: input not full block")
64         }
65         if len(dst) < BlockSize {
66                 panic("crypto/aes: output not full block")
67         }
68         decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
69 }
70
71 // expandKey is used by BenchmarkExpand to ensure that the asm implementation
72 // of key expansion is used for the benchmark when it is available.
73 func expandKey(key []byte, enc, dec []uint32) {
74         if cpu.X86.HasAES {
75                 rounds := 10 // rounds needed for AES128
76                 switch len(key) {
77                 case 192 / 8:
78                         rounds = 12
79                 case 256 / 8:
80                         rounds = 14
81                 }
82                 expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
83         } else {
84                 expandKeyGo(key, enc, dec)
85         }
86 }