comparison AES/rijndael.h @ 1:0b3630a29ad8

Initial version based on previous repository. Project was ported to QT6 and in now cmake based.
author Ideenmodellierer <tiefenrauscher@web.de>
date Thu, 27 Nov 2025 18:40:28 +0100
parents
children
comparison
equal deleted inserted replaced
0:76ccd6ce50c0 1:0b3630a29ad8
1 //////////////////////////////////////////////////////////////////////////////
2 /// \file rijndael.h
3 /// \brief Public Domain AES encryption/decryption
4 /// \author Philip J. Erdelsky <pje@efgh.com>, JD Gascuel, and others.
5 ///
6 /// \copyright (c) 2015 JD Gascuel. All rights reserved.
7 /// $Id$
8 //////////////////////////////////////////////////////////////////////////////
9 //
10 // BSD 2-Clause License:
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions
14 // are met:
15 //
16 // 1. Redistributions of source code must retain the above copyright notice,
17 // this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright notice,
20 // this list of conditions and the following disclaimer in the documentation
21 // and/or other materials provided with the distribution.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 // THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //////////////////////////////////////////////////////////////////////////////
36 // HISTORY
37 // 2002-09-03 PJE: original source http://www.efgh.com/software/rijndael.htm
38 // 2015-03-14 jDG: Import into OSTC_Companion, major C++ rewrites to insure
39 // key length is not messed up. Added ECb and CFB modes.
40
41 #ifndef RIJNDAEL_H
42 #define RIJNDAEL_H
43
44 namespace Rijndael {
45
46 #define KEYLENGTH(keybits) ((keybits)/8)
47 #define RKLENGTH(keybits) ((keybits)/8+28)
48 #define NROUNDS(keybits) ((keybits)/32+6)
49
50 typedef unsigned long Word32;
51 typedef unsigned char Byte;
52 typedef Byte Block[16];
53
54 //////////////////////////////////////////////////////////////////////////////
55 /// \brief Public Domain AES encryption/decryption rewritten.
56 ///
57 /// The Rijndael encryption algorithm has been designed to replace the aging
58 /// DES algorithm. Like DES, it is a block cipher. It uses 128-bit, 192-bit
59 /// or 256-bit keys. This implementation encrypts 128-bit blocks.
60 /// (DES used 56-bit keys and 64-bit blocks.)
61 ///
62 /// The code in this package is a modified version of an implementation
63 /// placed in the public domain by the following persons:
64 /// + Vincent Rijmen vincent.rijmen@esat.kuleuven.ac.be
65 /// + Antoon Bosselaers antoon.bosselaers@esat.kuleuven.ac.be
66 /// + Paulo Barreto paulo.barreto@terra.com.br
67 ///
68 /// See details in http://www.efgh.com/software/rijndael.htm
69 ///
70 struct AES
71 {
72 static void setupEncrypt(Word32* rk, const Byte *key, int keybits);
73 static void setupDecrypt(Word32* rk, const Byte *key, int keybits);
74 static void encrypt(Word32 *rk, int nrounds, const Block plaintext, Block ciphertext);
75 static void decrypt(Word32 *rk, int nrounds, const Block ciphertext, Block plaintext);
76 static Word32 get_random(Word32 *rk, int keybits);
77 };
78
79 //////////////////////////////////////////////////////////////////////////////
80 template<int keybits>
81 class ECB : private AES
82 {
83 /// \brief Internal state
84 ///
85 /// storage for encryption buffer, required space:
86 /// keybits 32-bit words required
87 /// 128 44
88 /// 192 52
89 /// 256 60
90 /// \sa RKLENGTH macro.
91 Word32 rk[RKLENGTH(keybits)];
92
93 public:
94 typedef Byte Key[KEYLENGTH(keybits)];
95
96 ECB();
97
98 //------------------------------------------------------------------------
99 /// \brief Initialize encryption state
100 ///
101 ///
102 /// \param[in] key: AES key, where length is:
103 /// keybits number of bytes
104 /// 128 16
105 /// 192 24
106 /// 256 32
107 /// \sa KEYLENGTH macro.
108 ///
109 /// \code
110 /// Rijndael::ECB<128>::Key key = "my big secret";
111 /// Rijndael::ECB<128> enc;
112 /// enc.setupEncrypt(key);
113 /// ...
114 /// Rijndael::Block plain = "Hello World!";
115 /// Rijndael::Block result;
116 /// enc.encrypt(plain, result);
117 /// \endcode
118 void setupEncrypt(const Key key);
119
120 //------------------------------------------------------------------------
121 /// \brief Encrypt a block of 16 bytes.
122 ///
123 /// \param[in] plaintext: The 16 bytes block to encrypt.
124 /// \param[out] ciphertext: Space to store the 16 bytes of encrypted data.
125 ///
126 void encrypt(const Block plaintext, Block ciphertext);
127
128 //------------------------------------------------------------------------
129 /// \brief Initialize decryption state.
130 ///
131 /// \param[in] key: AES key, where length is:
132 /// keybits number of bytes
133 /// 128 16
134 /// 192 24
135 /// 256 32
136 /// \sa KEYLENGTH macro.
137 ///
138 /// \code
139 /// Rijndael::ECB<128>::Key key = "my big secret";
140 /// Rijndael::ECB<128> dec;
141 /// dec.setupDecrypt(key);
142 /// ...
143 /// Rijndael::Block cipher = ...;
144 /// Rijndael::Block result;
145 /// Rijndael::decrypt(cipher, result);
146 /// \endcode
147 void setupDecrypt(const Key key);
148
149 //------------------------------------------------------------------------
150 /// \brief Decrypt a block of 16 bytes.
151 ///
152 /// \param[in] ciphertext: The 16 bytes block of data to decrypt.
153 /// \param[out] plaintext: Space to store the 16 bytes result block.
154 ///
155 void decrypt(const Block ciphertext, Block plaintext);
156
157 //----------------------------------------------------------------------------
158 /// \brief Crypto base PRNG
159 ///
160 /// Based on wall-clock value and current key, but should be a crypto-secure
161 /// generator.
162 Word32 get_random();
163 };
164
165 //////////////////////////////////////////////////////////////////////////////
166 template<int keybits>
167 class CFB : public ECB<keybits>
168 {
169 /// Initialization vector (salt), updated in CFB mode
170 /// for the next block of text.
171 Block iv;
172
173 public:
174 typedef Byte Key[KEYLENGTH(keybits)];
175 typedef Block IV;
176
177 //------------------------------------------------------------------------
178 /// \brief Initialize encryption/decription state
179 ///
180 ///
181 /// \param[in] key: AES key, where length is:
182 /// keybits number of bytes
183 /// 128 16
184 /// 192 24
185 /// 256 32
186 /// \sa KEYLENGTH macro.
187 /// \param[in] iv: initialization vector. Some randomness needed to
188 /// enforce the sequence is non replayable.
189 ///
190 /// \code
191 /// Rijndael::CFB<128>::Key key = "my big secret";
192 /// Rijndael::CFB<128> enc(key, iv);
193 /// ...
194 /// Rijndael::Block plain = "Hello World!";
195 /// Rijndael::Block cipher, again;
196 /// enc.encrypt(plain, cipher);
197 /// enc.decrypt(cipher, again);
198 /// \endcode
199 CFB(const Key key, const IV iv);
200
201 //------------------------------------------------------------------------
202 /// \brief Encrypt a block of 16 bytes, with IV (CFB mode)
203 ///
204 /// \param[in] plaintext: The 16 bytes block to encrypt.
205 /// \param[out] ciphertext: Space to store the 16 bytes of encrypted data.
206 ///
207 void encrypt(const Block plaintext, Block ciphertext);
208
209 //----------------------------------------------------------------------------
210 /// \brief Decrypt a block of 16 bytes, with IV (CFB mode)
211 ///
212 /// \param[in] ciphertext: The 16 bytes block of data to decrypt.
213 /// \param[out] plaintext: Space to store the 16 bytes result block.
214 ///
215 void decrypt(const Block ciphertext, Block plaintext);
216 };
217
218 //////////////////////////////////////////////////////////////////////////////
219
220 template<int keybits>
221 ECB<keybits>::ECB()
222 {
223 for(int i=0; i<RKLENGTH(keybits); ++i)
224 rk[i] = 0;
225 }
226
227 template<int keybits>
228 void ECB<keybits>::setupEncrypt(const Key key)
229 {
230 AES::setupEncrypt(rk, key, keybits);
231 }
232
233 template<int keybits>
234 void ECB<keybits>::encrypt(const Block plaintext, Block ciphertext)
235 {
236 AES::encrypt(rk, NROUNDS(keybits), plaintext, ciphertext);
237 }
238
239 //////////////////////////////////////////////////////////////////////////////
240
241 template<int keybits>
242 void ECB<keybits>::setupDecrypt(const Key key)
243 {
244 AES::setupDecrypt(rk, key, keybits);
245 }
246
247 template<int keybits>
248 void ECB<keybits>::decrypt(const Block ciphertext, Block plaintext)
249 {
250 AES::decrypt(rk, NROUNDS(keybits), ciphertext, plaintext);
251 }
252
253 //////////////////////////////////////////////////////////////////////////////
254
255 template<int keybits>
256 Word32 ECB<keybits>::get_random()
257 {
258 return AES::get_random(rk, keybits);
259 }
260
261 //////////////////////////////////////////////////////////////////////////////
262
263 template<int keybits>
264 CFB<keybits>::CFB(const Key key, const IV _iv)
265 {
266 ECB<keybits>::setupEncrypt(key);
267 for(int i=0; i<16; ++i)
268 iv[i] = _iv[i];
269 }
270
271 template<int keybits>
272 void CFB<keybits>::encrypt(const Block plaintext, Block ciphertext)
273 {
274 Block tmp;
275 ECB<keybits>::encrypt(iv, tmp);
276 for(int i=0; i<16; ++i)
277 {
278 ciphertext[i] = plaintext[i] ^ tmp[i];
279 iv[i] = ciphertext[i];
280 }
281 }
282
283 template<int keybits>
284 void CFB<keybits>::decrypt(const Block ciphertext, Block plaintext)
285 {
286 Block tmp;
287 ECB<keybits>::encrypt(iv, tmp);
288 for(int i=0; i<16; ++i)
289 {
290 plaintext[i] = ciphertext[i] ^ tmp[i];
291 iv[i] = ciphertext[i];
292 }
293 }
294
295 }
296 #endif // RIJNDAEL_H