aes.mx raw
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.
4
5 package aes
6
7 import (
8 "crypto/internal/fips140"
9 "crypto/internal/fips140/alias"
10 "strconv"
11 )
12
13 // BlockSize is the AES block size in bytes.
14 const BlockSize = 16
15
16 // A Block is an instance of AES using a particular key.
17 // It is safe for concurrent use.
18 type Block struct {
19 block
20 }
21
22 // blockExpanded is the block type used for all architectures except s390x,
23 // which feeds the raw key directly to its instructions.
24 type blockExpanded struct {
25 rounds int
26 // Round keys, where only the first (rounds + 1) × (128 ÷ 32) words are used.
27 enc [60]uint32
28 dec [60]uint32
29 }
30
31 const (
32 // AES-128 has 128-bit keys, 10 rounds, and uses 11 128-bit round keys
33 // (11×128÷32 = 44 32-bit words).
34
35 // AES-192 has 192-bit keys, 12 rounds, and uses 13 128-bit round keys
36 // (13×128÷32 = 52 32-bit words).
37
38 // AES-256 has 256-bit keys, 14 rounds, and uses 15 128-bit round keys
39 // (15×128÷32 = 60 32-bit words).
40
41 aes128KeySize = 16
42 aes192KeySize = 24
43 aes256KeySize = 32
44
45 aes128Rounds = 10
46 aes192Rounds = 12
47 aes256Rounds = 14
48 )
49
50 // roundKeysSize returns the number of uint32 of c.end or c.dec that are used.
51 func (b *blockExpanded) roundKeysSize() int {
52 return (b.rounds + 1) * (128 / 32)
53 }
54
55 type KeySizeError int
56
57 func (k KeySizeError) Error() string {
58 var buf []byte
59 buf = append(buf, "crypto/aes: invalid key size "...)
60 buf = append(buf, strconv.Itoa(int(k))...)
61 return string(buf)
62 }
63
64 // New creates and returns a new [cipher.Block] implementation.
65 // The key argument should be the AES key, either 16, 24, or 32 bytes to select
66 // AES-128, AES-192, or AES-256.
67 func New(key []byte) (*Block, error) {
68 // This call is outline to let the allocation happen on the parent stack.
69 return newOutlined(&Block{}, key)
70 }
71
72 // newOutlined is marked go:noinline to avoid it inlining into New, and making New
73 // too complex to inline itself.
74 //
75 //go:noinline
76 func newOutlined(b *Block, key []byte) (*Block, error) {
77 switch len(key) {
78 case aes128KeySize, aes192KeySize, aes256KeySize:
79 default:
80 return nil, KeySizeError(len(key))
81 }
82 return newBlock(b, key), nil
83 }
84
85 func newBlockExpanded(c *blockExpanded, key []byte) {
86 switch len(key) {
87 case aes128KeySize:
88 c.rounds = aes128Rounds
89 case aes192KeySize:
90 c.rounds = aes192Rounds
91 case aes256KeySize:
92 c.rounds = aes256Rounds
93 }
94 expandKeyGeneric(c, key)
95 }
96
97 func (c *Block) BlockSize() int { return BlockSize }
98
99 func (c *Block) Encrypt(dst, src []byte) {
100 // AES-ECB is not approved in FIPS 140-3 mode.
101 fips140.RecordNonApproved()
102 if len(src) < BlockSize {
103 panic("crypto/aes: input not full block")
104 }
105 if len(dst) < BlockSize {
106 panic("crypto/aes: output not full block")
107 }
108 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
109 panic("crypto/aes: invalid buffer overlap")
110 }
111 encryptBlock(c, dst, src)
112 }
113
114 func (c *Block) Decrypt(dst, src []byte) {
115 // AES-ECB is not approved in FIPS 140-3 mode.
116 fips140.RecordNonApproved()
117 if len(src) < BlockSize {
118 panic("crypto/aes: input not full block")
119 }
120 if len(dst) < BlockSize {
121 panic("crypto/aes: output not full block")
122 }
123 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
124 panic("crypto/aes: invalid buffer overlap")
125 }
126 decryptBlock(c, dst, src)
127 }
128
129 // EncryptBlockInternal applies the AES encryption function to one block.
130 //
131 // It is an internal function meant only for the gcm package.
132 func EncryptBlockInternal(c *Block, dst, src []byte) {
133 encryptBlock(c, dst, src)
134 }
135