Arduino Cryptography Library
AES.h
1 /*
2  * Copyright (C) 2015,2018 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef CRYPTO_AES_h
24 #define CRYPTO_AES_h
25 
26 #include "BlockCipher.h"
27 
28 // Determine which AES implementation to export to applications.
29 #if defined(ESP32)
30 #define CRYPTO_AES_ESP32 1
31 #else
32 #define CRYPTO_AES_DEFAULT 1
33 #endif
34 
35 #if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC)
36 
37 class AESTiny128;
38 class AESTiny256;
39 class AESSmall128;
40 class AESSmall256;
41 
42 class AESCommon : public BlockCipher
43 {
44 public:
45  virtual ~AESCommon();
46 
47  size_t blockSize() const;
48 
49  void encryptBlock(uint8_t *output, const uint8_t *input);
50  void decryptBlock(uint8_t *output, const uint8_t *input);
51 
52  void clear();
53 
54 protected:
55  AESCommon();
56 
58  uint8_t rounds;
59  uint8_t *schedule;
60 
61  static void subBytesAndShiftRows(uint8_t *output, const uint8_t *input);
62  static void inverseShiftRowsAndSubBytes(uint8_t *output, const uint8_t *input);
63  static void mixColumn(uint8_t *output, uint8_t *input);
64  static void inverseMixColumn(uint8_t *output, const uint8_t *input);
65  static void keyScheduleCore(uint8_t *output, const uint8_t *input, uint8_t iteration);
66  static void applySbox(uint8_t *output, const uint8_t *input);
69  friend class AESTiny128;
70  friend class AESTiny256;
71  friend class AESSmall128;
72  friend class AESSmall256;
73 };
74 
75 class AES128 : public AESCommon
76 {
77 public:
78  AES128();
79  virtual ~AES128();
80 
81  size_t keySize() const;
82 
83  bool setKey(const uint8_t *key, size_t len);
84 
85 private:
86  uint8_t sched[176];
87 };
88 
89 class AES192 : public AESCommon
90 {
91 public:
92  AES192();
93  virtual ~AES192();
94 
95  size_t keySize() const;
96 
97  bool setKey(const uint8_t *key, size_t len);
98 
99 private:
100  uint8_t sched[208];
101 };
102 
103 class AES256 : public AESCommon
104 {
105 public:
106  AES256();
107  virtual ~AES256();
108 
109  size_t keySize() const;
110 
111  bool setKey(const uint8_t *key, size_t len);
112 
113 private:
114  uint8_t sched[240];
115 };
116 
117 class AESTiny256 : public BlockCipher
118 {
119 public:
120  AESTiny256();
121  virtual ~AESTiny256();
122 
123  size_t blockSize() const;
124  size_t keySize() const;
125 
126  bool setKey(const uint8_t *key, size_t len);
127 
128  void encryptBlock(uint8_t *output, const uint8_t *input);
129  void decryptBlock(uint8_t *output, const uint8_t *input);
130 
131  void clear();
132 
133 private:
134  uint8_t schedule[32];
135 };
136 
137 class AESSmall256 : public AESTiny256
138 {
139 public:
140  AESSmall256();
141  virtual ~AESSmall256();
142 
143  bool setKey(const uint8_t *key, size_t len);
144 
145  void decryptBlock(uint8_t *output, const uint8_t *input);
146 
147  void clear();
148 
149 private:
150  uint8_t reverse[32];
151 };
152 
153 class AESTiny128 : public BlockCipher
154 {
155 public:
156  AESTiny128();
157  virtual ~AESTiny128();
158 
159  size_t blockSize() const;
160  size_t keySize() const;
161 
162  bool setKey(const uint8_t *key, size_t len);
163 
164  void encryptBlock(uint8_t *output, const uint8_t *input);
165  void decryptBlock(uint8_t *output, const uint8_t *input);
166 
167  void clear();
168 
169 private:
170  uint8_t schedule[16];
171 };
172 
173 class AESSmall128 : public AESTiny128
174 {
175 public:
176  AESSmall128();
177  virtual ~AESSmall128();
178 
179  bool setKey(const uint8_t *key, size_t len);
180 
181  void decryptBlock(uint8_t *output, const uint8_t *input);
182 
183  void clear();
184 
185 private:
186  uint8_t reverse[16];
187 };
188 
189 #endif // CRYPTO_AES_DEFAULT
190 
191 #if defined(CRYPTO_AES_ESP32)
192 
195 // The esp32 SDK keeps moving where aes.h is located, so we have to
196 // declare the API functions ourselves and make the context opaque.
197 //
198 // About the only thing the various SDK versions agree on is that the
199 // first byte is the length of the key in bytes.
200 //
201 // Some versions of esp-idf have a 33 byte AES context, and others 34.
202 // Allocate up to 40 to make space for future expansion.
203 #define CRYPTO_ESP32_CONTEXT_SIZE 40
204 
205 // Some of the esp-idf system headers define enumerations for AES128,
206 // AES192, and AES256 to identify the hardware-accelerated algorithms.
207 // These can cause conflicts with the names we use in our library.
208 // Define our class names to something else to work around esp-idf.
209 #undef AES128
210 #undef AES192
211 #undef AES256
212 #define AES128 AES128_ESP
213 #define AES192 AES192_ESP
214 #define AES256 AES256_ESP
215 
218 class AESCommon : public BlockCipher
219 {
220 public:
221  virtual ~AESCommon();
222 
223  size_t blockSize() const;
224  size_t keySize() const;
225 
226  bool setKey(const uint8_t *key, size_t len);
227 
228  void encryptBlock(uint8_t *output, const uint8_t *input);
229  void decryptBlock(uint8_t *output, const uint8_t *input);
230 
231  void clear();
232 
233 protected:
234  AESCommon(uint8_t keySize);
235 
236 private:
237  uint8_t ctx[CRYPTO_ESP32_CONTEXT_SIZE];
238 };
239 
240 class AES128 : public AESCommon
241 {
242 public:
243  AES128() : AESCommon(16) {}
244  virtual ~AES128();
245 };
246 
247 class AES192 : public AESCommon
248 {
249 public:
250  AES192() : AESCommon(24) {}
251  virtual ~AES192();
252 };
253 
254 class AES256 : public AESCommon
255 {
256 public:
257  AES256() : AESCommon(32) {}
258  virtual ~AES256();
259 };
260 
261 // The ESP32 AES context is so small that it already qualifies as "tiny".
262 typedef AES128 AESTiny128;
263 typedef AES256 AESTiny256;
264 typedef AES128 AESSmall128;
265 typedef AES256 AESSmall256;
266 
267 #endif // CRYPTO_AES_ESP32
268 
269 #endif
AES block cipher with 128-bit keys.
Definition: AES.h:76
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES128.cpp:62
size_t keySize() const
Size of a 128-bit AES key in bytes.
Definition: AES128.cpp:57
AES128()
Constructs an AES 128-bit block cipher with no initial key.
Definition: AES128.cpp:42
AES block cipher with 192-bit keys.
Definition: AES.h:90
size_t keySize() const
Size of a 192-bit AES key in bytes.
Definition: AES192.cpp:57
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES192.cpp:62
AES192()
Constructs an AES 192-bit block cipher with no initial key.
Definition: AES192.cpp:42
AES block cipher with 256-bit keys.
Definition: AES.h:104
AES256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:42
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:62
size_t keySize() const
Size of a 256-bit AES key in bytes.
Definition: AES256.cpp:57
Abstract base class for AES block ciphers.
Definition: AES.h:43
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.
Definition: AESCommon.cpp:270
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AESCommon.cpp:332
virtual ~AESCommon()
Destroys this AES block cipher object after clearing sensitive information.
Definition: AESCommon.cpp:136
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AESCommon.cpp:301
size_t blockSize() const
Size of an AES block in bytes.
Definition: AESCommon.cpp:144
AESCommon()
Constructs an AES block cipher object.
Definition: AESCommon.cpp:127
AES block cipher with 128-bit keys and reduced memory usage.
Definition: AES.h:174
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES128.cpp:350
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES128.cpp:280
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES128.cpp:306
AESSmall128()
Constructs an AES 128-bit block cipher with no initial key.
Definition: AES128.cpp:271
AES block cipher with 256-bit keys and reduced memory usage.
Definition: AES.h:138
AESSmall256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:308
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES256.cpp:351
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES256.cpp:395
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:317
AES block cipher with 128-bit keys and tiny memory usage.
Definition: AES.h:154
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES128.cpp:240
AESTiny128()
Constructs an AES 128-bit block cipher with no initial key.
Definition: AES128.cpp:152
size_t blockSize() const
Size of an AES block in bytes.
Definition: AES128.cpp:165
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES128.cpp:179
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES128.cpp:235
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.
Definition: AES128.cpp:189
size_t keySize() const
Size of a 128-bit AES key in bytes.
Definition: AES128.cpp:174
AES block cipher with 256-bit keys and tiny memory usage.
Definition: AES.h:118
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.
Definition: AES256.cpp:226
size_t keySize() const
Size of a 256-bit AES key in bytes.
Definition: AES256.cpp:211
AESTiny256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:189
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:216
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES256.cpp:272
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES256.cpp:277
size_t blockSize() const
Size of an AES block in bytes.
Definition: AES256.cpp:202
Abstract base class for block ciphers.
Definition: BlockCipher.h:30
virtual bool setKey(const uint8_t *key, size_t len)=0
Sets the key to use for future encryption and decryption operations.
virtual size_t keySize() const =0
Default size of the key for this block cipher, in bytes.