22* Byte-oriented AES-256 implementation.
33* All lookup tables replaced with 'on the fly' calculations.
44*
5- * Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com
5+ * Copyright (c) 2007-2011 Literatecode, http://www.literatecode.com
6+ * Copyright (c) 2022 Ilia Levin (ilia@levin.sg)
67* Other contributors: Hal Finney
78*
89* Permission to use, copy, modify, and distribute this software for any
1920*/
2021#include "aes256.h"
2122
22- #define FD (x ) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
23-
24- #define BACK_TO_TABLES
25-
26- static uint8_t rj_xtime (uint8_t );
27- static void aes_subBytes (uint8_t * );
28- static void aes_subBytes_inv (uint8_t * );
29- static void aes_addRoundKey (uint8_t * , uint8_t * );
30- static void aes_addRoundKey_cpy (uint8_t * , uint8_t * , uint8_t * );
31- static void aes_shiftRows (uint8_t * );
32- static void aes_shiftRows_inv (uint8_t * );
33- static void aes_mixColumns (uint8_t * );
34- static void aes_mixColumns_inv (uint8_t * );
35- static void aes_expandEncKey (uint8_t * , uint8_t * );
36- static void aes_expandDecKey (uint8_t * , uint8_t * );
37- #ifndef BACK_TO_TABLES
38- static uint8_t gf_alog (uint8_t );
39- static uint8_t gf_log (uint8_t );
40- static uint8_t gf_mulinv (uint8_t );
41- static uint8_t rj_sbox (uint8_t );
42- static uint8_t rj_sbox_inv (uint8_t );
43- #endif
44-
45- #ifdef BACK_TO_TABLES
23+ /*
24+ * We use the compact version with runtime calculations by default.
25+ * For a faster pre-calculated version, compile with defined BACK_TO_TABLES.
26+ */
27+ /* #define BACK_TO_TABLES */
28+
29+ /* -------------------------------------------------------------------------- */
30+ static uint8_t
31+ rj_xtime (uint8_t x )
32+ {
33+ uint8_t y = 0xff & (x << 1 );
34+ return (x & 0x80 ) ? (y ^ 0x1b ) : y ;
35+ } /* rj_xtime */
36+
37+ #ifdef BACK_TO_TABLES /* pre-calculated tables */
4638
4739static const uint8_t sbox [256 ] = {
4840 0x63 , 0x7c , 0x77 , 0x7b , 0xf2 , 0x6b , 0x6f , 0xc5 ,
@@ -118,13 +110,15 @@ static const uint8_t sboxinv[256] = {
118110
119111#else /* tableless subroutines */
120112
113+ #define SHL8 (x , n ) ((0xff & ((x) << (n))) | ((x) >> (8 - (n))))
114+
121115/* -------------------------------------------------------------------------- */
122116static uint8_t
123- gf_alog (uint8_t x ) // calculate anti-logarithm gen 3
117+ gf_alog (uint8_t x ) /* calculate anti-logarithm gen 3 */
124118{
125119 uint8_t y = 1 , i ;
126120
127- for (i = 0 ; i < x ; i ++ ) {
121+ for (i = 0 ; ( x < 0xff ) && ( i < x ) ; i ++ ) {
128122 y ^= rj_xtime (y );
129123 }
130124
@@ -133,11 +127,11 @@ gf_alog(uint8_t x) // calculate anti-logarithm gen 3
133127
134128/* -------------------------------------------------------------------------- */
135129static uint8_t
136- gf_log (uint8_t x ) // calculate logarithm gen 3
130+ gf_log (uint8_t x ) /* calculate logarithm gen 3 */
137131{
138132 uint8_t y , i = 0 ;
139133
140- if (x ) {
134+ if (0 != x ) {
141135 for (i = 1 , y = 1 ; i > 0 ; i ++ ) {
142136 y ^= rj_xtime (y );
143137 if (y == x ) {
@@ -149,66 +143,46 @@ gf_log(uint8_t x) // calculate logarithm gen 3
149143 return i ;
150144} /* gf_log */
151145
152-
153146/* -------------------------------------------------------------------------- */
154147static uint8_t
155- gf_mulinv (uint8_t x ) // calculate multiplicative inverse
148+ gf_mulinv (uint8_t x ) /* calculate multiplicative inverse */
156149{
157- return (x ) ? gf_alog (255 - gf_log (x )) : 0 ;
150+ return (( x ) ? gf_alog (255 - gf_log (x )) : 0 ) ;
158151} /* gf_mulinv */
159152
160153/* -------------------------------------------------------------------------- */
161154static uint8_t
162155rj_sbox (uint8_t x )
163156{
164- uint8_t y , sb ;
165-
166- sb = y = gf_mulinv (x );
167- y = (uint8_t )(y << 1 ) | (y >> 7 );
168- sb ^= y ;
169- y = (uint8_t )(y << 1 ) | (y >> 7 );
170- sb ^= y ;
171- y = (uint8_t )(y << 1 ) | (y >> 7 );
172- sb ^= y ;
173- y = (uint8_t )(y << 1 ) | (y >> 7 );
174- sb ^= y ;
175-
176- return (sb ^ 0x63 );
157+ uint8_t y = gf_mulinv (x ), sb = y ;
158+
159+ sb ^= y = SHL8 (y , 1 );
160+ sb ^= y = SHL8 (y , 1 );
161+ sb ^= y = SHL8 (y , 1 );
162+
163+ return (sb ^ SHL8 (y , 1 ) ^ 0x63 );
177164} /* rj_sbox */
178165
179166/* -------------------------------------------------------------------------- */
180167static uint8_t
181168rj_sbox_inv (uint8_t x )
182169{
183- uint8_t y , sb ;
170+ uint8_t y = ( x ^ 0x63 ) , sb = y = SHL8 ( y , 1 ) ;
184171
185- y = x ^ 0x63 ;
186- sb = y = (uint8_t )(y << 1 ) | (y >> 7 );
187- y = (uint8_t )(y << 2 ) | (y >> 6 );
188- sb ^= y ;
189- y = (uint8_t )(y << 3 ) | (y >> 5 );
190- sb ^= y ;
172+ sb ^= y = SHL8 (y , 2 );
191173
192- return gf_mulinv (sb );
174+ return gf_mulinv (sb ^ SHL8 ( y , 3 ) );
193175} /* rj_sbox_inv */
194176
195- #endif
196-
197- /* -------------------------------------------------------------------------- */
198- static uint8_t
199- rj_xtime (uint8_t x )
200- {
201- uint8_t y = (uint8_t )(x << 1 );
202- return (x & 0x80 ) ? (y ^ 0x1b ) : y ;
203- } /* rj_xtime */
177+ #endif /* BACK_TO_TABLES */
204178
205179/* -------------------------------------------------------------------------- */
206180static void
207181aes_subBytes (uint8_t * buf )
208182{
209- register uint8_t i = 16 ;
183+ register uint8_t i ;
210184
211- while (i -- ) {
185+ for (i = 0 ; i < 16 ; i ++ ) {
212186 buf [i ] = rj_sbox (buf [i ]);
213187 }
214188} /* aes_subBytes */
@@ -217,9 +191,9 @@ aes_subBytes(uint8_t *buf)
217191static void
218192aes_subBytes_inv (uint8_t * buf )
219193{
220- register uint8_t i = 16 ;
194+ register uint8_t i ;
221195
222- while (i -- ) {
196+ for (i = 0 ; i < 16 ; i ++ ) {
223197 buf [i ] = rj_sbox_inv (buf [i ]);
224198 }
225199} /* aes_subBytes_inv */
@@ -228,9 +202,9 @@ aes_subBytes_inv(uint8_t *buf)
228202static void
229203aes_addRoundKey (uint8_t * buf , uint8_t * key )
230204{
231- register uint8_t i = 16 ;
205+ register uint8_t i ;
232206
233- while (i -- ) {
207+ for (i = 0 ; i < 16 ; i ++ ) {
234208 buf [i ] ^= key [i ];
235209 }
236210} /* aes_addRoundKey */
@@ -239,15 +213,14 @@ aes_addRoundKey(uint8_t *buf, uint8_t *key)
239213static void
240214aes_addRoundKey_cpy (uint8_t * buf , uint8_t * key , uint8_t * cpk )
241215{
242- register uint8_t i = 16 ;
216+ register uint8_t i ;
243217
244- while (i -- ) {
218+ for (i = 0 ; i < 16 ; i ++ ) {
245219 buf [i ] ^= (cpk [i ] = key [i ]);
246220 cpk [16 + i ] = key [16 + i ];
247221 }
248222} /* aes_addRoundKey_cpy */
249223
250-
251224/* -------------------------------------------------------------------------- */
252225static void
253226aes_shiftRows (uint8_t * buf )
@@ -322,7 +295,7 @@ aes_mixColumns(uint8_t *buf)
322295} /* aes_mixColumns */
323296
324297/* -------------------------------------------------------------------------- */
325- void
298+ static void
326299aes_mixColumns_inv (uint8_t * buf )
327300{
328301 register uint8_t i , a , b , c , d , e , x , y , z ;
@@ -376,7 +349,7 @@ aes_expandEncKey(uint8_t *k, uint8_t *rc)
376349} /* aes_expandEncKey */
377350
378351/* -------------------------------------------------------------------------- */
379- void
352+ static void
380353aes_expandDecKey (uint8_t * k , uint8_t * rc )
381354{
382355 uint8_t i ;
@@ -400,14 +373,13 @@ aes_expandDecKey(uint8_t *k, uint8_t *rc)
400373 k [i + 3 ] ^= k [i - 1 ];
401374 }
402375
403- * rc = FD ( * rc );
376+ * rc = ((( * rc ) >> 1 ) ^ ((( * rc ) & 1 ) ? 0x8d : 0 ) );
404377 k [0 ] ^= rj_sbox (k [29 ]) ^ (* rc );
405378 k [1 ] ^= rj_sbox (k [30 ]);
406379 k [2 ] ^= rj_sbox (k [31 ]);
407380 k [3 ] ^= rj_sbox (k [28 ]);
408381} /* aes_expandDecKey */
409382
410-
411383/* -------------------------------------------------------------------------- */
412384void
413385aes256_init (aes256_context * ctx , uint8_t * k )
@@ -419,7 +391,7 @@ aes256_init(aes256_context *ctx, uint8_t *k)
419391 ctx -> enckey [i ] = ctx -> deckey [i ] = k [i ];
420392 }
421393
422- for (i = 8 ; -- i ; ) {
394+ for (i = 0 ; i < 7 ; i ++ ) {
423395 aes_expandEncKey (ctx -> deckey , & rcon );
424396 }
425397} /* aes256_init */
@@ -439,15 +411,15 @@ aes256_done(aes256_context *ctx)
439411void
440412aes256_encrypt_ecb (aes256_context * ctx , uint8_t * buf )
441413{
442- uint8_t i , rcon ;
414+ uint8_t i , rcon = 1 ;
443415
444416 aes_addRoundKey_cpy (buf , ctx -> enckey , ctx -> key );
445417
446- for (i = 1 , rcon = 1 ; i < 14 ; ++ i ) {
418+ for (i = 1 ; i < 14 ; ++ i ) {
447419 aes_subBytes (buf );
448420 aes_shiftRows (buf );
449421 aes_mixColumns (buf );
450- if (i & 1 ) {
422+ if (1 == ( i & 1 ) ) {
451423 aes_addRoundKey (buf , & ctx -> key [16 ]);
452424 } else {
453425 aes_expandEncKey (ctx -> key , & rcon );
@@ -465,14 +437,14 @@ aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
465437void
466438aes256_decrypt_ecb (aes256_context * ctx , uint8_t * buf )
467439{
468- uint8_t i , rcon ;
440+ uint8_t i , rcon = 0x80 ;
469441
470442 aes_addRoundKey_cpy (buf , ctx -> deckey , ctx -> key );
471443 aes_shiftRows_inv (buf );
472444 aes_subBytes_inv (buf );
473445
474- for (i = 14 , rcon = 0x80 ; -- i ;) {
475- if ((i & 1 )) {
446+ for (i = 14 ; -- i ;) {
447+ if (1 == (i & 1 )) {
476448 aes_expandDecKey (ctx -> key , & rcon );
477449 aes_addRoundKey (buf , & ctx -> key [16 ]);
478450 } else {
@@ -485,3 +457,4 @@ aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
485457
486458 aes_addRoundKey (buf , ctx -> key );
487459} /* aes256_decrypt */
460+
0 commit comments