You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

aes.c 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /*
  2. * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * AES algorithm
  27. *
  28. */
  29. #include <stdint.h>
  30. #include <string.h>
  31. #include <errno.h>
  32. #include <assert.h>
  33. #include <byteswap.h>
  34. #include <ipxe/rotate.h>
  35. #include <ipxe/crypto.h>
  36. #include <ipxe/ecb.h>
  37. #include <ipxe/cbc.h>
  38. #include <ipxe/aes.h>
  39. /** AES strides
  40. *
  41. * These are the strides (modulo 16) used to walk through the AES
  42. * input state bytes in order of byte position after [Inv]ShiftRows.
  43. */
  44. enum aes_stride {
  45. /** Input stride for ShiftRows
  46. *
  47. * 0 4 8 c
  48. * \ \ \
  49. * 1 5 9 d
  50. * \ \ \
  51. * 2 6 a e
  52. * \ \ \
  53. * 3 7 b f
  54. */
  55. AES_STRIDE_SHIFTROWS = +5,
  56. /** Input stride for InvShiftRows
  57. *
  58. * 0 4 8 c
  59. * / / /
  60. * 1 5 9 d
  61. * / / /
  62. * 2 6 a e
  63. * / / /
  64. * 3 7 b f
  65. */
  66. AES_STRIDE_INVSHIFTROWS = -3,
  67. };
  68. /** A single AES lookup table entry
  69. *
  70. * This represents the product (in the Galois field GF(2^8)) of an
  71. * eight-byte vector multiplier with a single scalar multiplicand.
  72. *
  73. * The vector multipliers used for AES will be {1,1,1,3,2,1,1,3} for
  74. * MixColumns and {1,9,13,11,14,9,13,11} for InvMixColumns. This
  75. * allows for the result of multiplying any single column of the
  76. * [Inv]MixColumns matrix by a scalar value to be obtained simply by
  77. * extracting the relevant four-byte subset from the lookup table
  78. * entry.
  79. *
  80. * For example, to find the result of multiplying the second column of
  81. * the MixColumns matrix by the scalar value 0x80:
  82. *
  83. * MixColumns column[0]: { 2, 1, 1, 3 }
  84. * MixColumns column[1]: { 3, 2, 1, 1 }
  85. * MixColumns column[2]: { 1, 3, 2, 1 }
  86. * MixColumns column[3]: { 1, 1, 3, 2 }
  87. * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
  88. * Scalar multiplicand: 0x80
  89. * Lookup table entry: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
  90. *
  91. * The second column of the MixColumns matrix is {3,2,1,1}. The
  92. * product of this column with the scalar value 0x80 can be obtained
  93. * by extracting the relevant four-byte subset of the lookup table
  94. * entry:
  95. *
  96. * MixColumns column[1]: { 3, 2, 1, 1 }
  97. * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
  98. * Lookup table entry: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
  99. * Product: { 0x9b, 0x1b, 0x80, 0x80 }
  100. *
  101. * The column lookups require only seven bytes of the eight-byte
  102. * entry: the remaining (first) byte is used to hold the scalar
  103. * multiplicand itself (i.e. the first byte of the vector multiplier
  104. * is always chosen to be 1).
  105. */
  106. union aes_table_entry {
  107. /** Viewed as an array of bytes */
  108. uint8_t byte[8];
  109. } __attribute__ (( packed ));
  110. /** An AES lookup table
  111. *
  112. * This represents the products (in the Galois field GF(2^8)) of a
  113. * constant eight-byte vector multiplier with all possible 256 scalar
  114. * multiplicands.
  115. *
  116. * The entries are indexed by the AES [Inv]SubBytes S-box output
  117. * values (denoted S(N)). This allows for the result of multiplying
  118. * any single column of the [Inv]MixColumns matrix by S(N) to be
  119. * obtained simply by extracting the relevant four-byte subset from
  120. * the Nth table entry. For example:
  121. *
  122. * Input byte (N): 0x3a
  123. * SubBytes output S(N): 0x80
  124. * MixColumns column[1]: { 3, 2, 1, 1 }
  125. * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
  126. * Table entry[0x3a]: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
  127. * Product: { 0x9b, 0x1b, 0x80, 0x80 }
  128. *
  129. * Since the first byte of the eight-byte vector multiplier is always
  130. * chosen to be 1, the value of S(N) may be lookup up by extracting
  131. * the first byte of the Nth table entry.
  132. */
  133. struct aes_table {
  134. /** Table entries, indexed by S(N) */
  135. union aes_table_entry entry[256];
  136. } __attribute__ (( aligned ( 8 ) ));
  137. /** AES MixColumns lookup table */
  138. static struct aes_table aes_mixcolumns;
  139. /** AES InvMixColumns lookup table */
  140. static struct aes_table aes_invmixcolumns;
  141. /**
  142. * Multiply [Inv]MixColumns matrix column by scalar multiplicand
  143. *
  144. * @v entry AES lookup table entry for scalar multiplicand
  145. * @v column [Inv]MixColumns matrix column index
  146. * @ret product Product of matrix column with scalar multiplicand
  147. */
  148. static inline __attribute__ (( always_inline )) uint32_t
  149. aes_entry_column ( const union aes_table_entry *entry, unsigned int column ) {
  150. const union {
  151. uint8_t byte;
  152. uint32_t column;
  153. } __attribute__ (( may_alias )) *product;
  154. /* Locate relevant four-byte subset */
  155. product = container_of ( &entry->byte[ 4 - column ],
  156. typeof ( *product ), byte );
  157. /* Extract this four-byte subset */
  158. return product->column;
  159. }
  160. /**
  161. * Multiply [Inv]MixColumns matrix column by S-boxed input byte
  162. *
  163. * @v table AES lookup table
  164. * @v stride AES row shift stride
  165. * @v in AES input state
  166. * @v offset Output byte offset (after [Inv]ShiftRows)
  167. * @ret product Product of matrix column with S(input byte)
  168. *
  169. * Note that the specified offset is not the offset of the input byte;
  170. * it is the offset of the output byte which corresponds to the input
  171. * byte. This output byte offset is used to calculate both the input
  172. * byte offset and to select the appropriate matric column.
  173. *
  174. * With a compile-time constant offset, this function will optimise
  175. * down to a single "movzbl" (to extract the input byte) and will
  176. * generate a single x86 memory reference expression which can then be
  177. * used directly within a single "xorl" instruction.
  178. */
  179. static inline __attribute__ (( always_inline )) uint32_t
  180. aes_column ( const struct aes_table *table, size_t stride,
  181. const union aes_matrix *in, size_t offset ) {
  182. const union aes_table_entry *entry;
  183. unsigned int byte;
  184. /* Extract input byte corresponding to this output byte offset
  185. * (i.e. perform [Inv]ShiftRows).
  186. */
  187. byte = in->byte[ ( stride * offset ) & 0xf ];
  188. /* Locate lookup table entry for this input byte (i.e. perform
  189. * [Inv]SubBytes).
  190. */
  191. entry = &table->entry[byte];
  192. /* Multiply appropriate matrix column by this input byte
  193. * (i.e. perform [Inv]MixColumns).
  194. */
  195. return aes_entry_column ( entry, ( offset & 0x3 ) );
  196. }
  197. /**
  198. * Calculate intermediate round output column
  199. *
  200. * @v table AES lookup table
  201. * @v stride AES row shift stride
  202. * @v in AES input state
  203. * @v key AES round key
  204. * @v column Column index
  205. * @ret output Output column value
  206. */
  207. static inline __attribute__ (( always_inline )) uint32_t
  208. aes_output ( const struct aes_table *table, size_t stride,
  209. const union aes_matrix *in, const union aes_matrix *key,
  210. unsigned int column ) {
  211. size_t offset = ( column * 4 );
  212. /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
  213. * AddRoundKey for this column. The loop is unrolled to allow
  214. * for the required compile-time constant optimisations.
  215. */
  216. return ( aes_column ( table, stride, in, ( offset + 0 ) ) ^
  217. aes_column ( table, stride, in, ( offset + 1 ) ) ^
  218. aes_column ( table, stride, in, ( offset + 2 ) ) ^
  219. aes_column ( table, stride, in, ( offset + 3 ) ) ^
  220. key->column[column] );
  221. }
  222. /**
  223. * Perform a single intermediate round
  224. *
  225. * @v table AES lookup table
  226. * @v stride AES row shift stride
  227. * @v in AES input state
  228. * @v out AES output state
  229. * @v key AES round key
  230. */
  231. static inline __attribute__ (( always_inline )) void
  232. aes_round ( const struct aes_table *table, size_t stride,
  233. const union aes_matrix *in, union aes_matrix *out,
  234. const union aes_matrix *key ) {
  235. /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
  236. * AddRoundKey for all columns. The loop is unrolled to allow
  237. * for the required compile-time constant optimisations.
  238. */
  239. out->column[0] = aes_output ( table, stride, in, key, 0 );
  240. out->column[1] = aes_output ( table, stride, in, key, 1 );
  241. out->column[2] = aes_output ( table, stride, in, key, 2 );
  242. out->column[3] = aes_output ( table, stride, in, key, 3 );
  243. }
  244. /**
  245. * Perform encryption intermediate rounds
  246. *
  247. * @v in AES input state
  248. * @v out AES output state
  249. * @v key Round keys
  250. * @v rounds Number of rounds (must be odd)
  251. *
  252. * This function is deliberately marked as non-inlinable to ensure
  253. * maximal availability of registers for GCC's register allocator,
  254. * which has a tendency to otherwise spill performance-critical
  255. * registers to the stack.
  256. */
  257. static __attribute__ (( noinline )) void
  258. aes_encrypt_rounds ( union aes_matrix *in, union aes_matrix *out,
  259. const union aes_matrix *key, unsigned int rounds ) {
  260. union aes_matrix *tmp;
  261. /* Perform intermediate rounds */
  262. do {
  263. /* Perform one intermediate round */
  264. aes_round ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS,
  265. in, out, key++ );
  266. /* Swap input and output states for next round */
  267. tmp = in;
  268. in = out;
  269. out = tmp;
  270. } while ( --rounds );
  271. }
  272. /**
  273. * Perform decryption intermediate rounds
  274. *
  275. * @v in AES input state
  276. * @v out AES output state
  277. * @v key Round keys
  278. * @v rounds Number of rounds (must be odd)
  279. *
  280. * As with aes_encrypt_rounds(), this function is deliberately marked
  281. * as non-inlinable.
  282. *
  283. * This function could potentially use the same binary code as is used
  284. * for encryption. To compensate for the difference between ShiftRows
  285. * and InvShiftRows, half of the input byte offsets would have to be
  286. * modifiable at runtime (half by an offset of +4/-4, half by an
  287. * offset of -4/+4 for ShiftRows/InvShiftRows). This can be
  288. * accomplished in x86 assembly within the number of available
  289. * registers, but GCC's register allocator struggles to do so,
  290. * resulting in a significant performance decrease due to registers
  291. * being spilled to the stack. We therefore use two separate but very
  292. * similar binary functions based on the same C source.
  293. */
  294. static __attribute__ (( noinline )) void
  295. aes_decrypt_rounds ( union aes_matrix *in, union aes_matrix *out,
  296. const union aes_matrix *key, unsigned int rounds ) {
  297. union aes_matrix *tmp;
  298. /* Perform intermediate rounds */
  299. do {
  300. /* Perform one intermediate round */
  301. aes_round ( &aes_invmixcolumns, AES_STRIDE_INVSHIFTROWS,
  302. in, out, key++ );
  303. /* Swap input and output states for next round */
  304. tmp = in;
  305. in = out;
  306. out = tmp;
  307. } while ( --rounds );
  308. }
  309. /**
  310. * Perform standalone AddRoundKey
  311. *
  312. * @v state AES state
  313. * @v key AES round key
  314. */
  315. static inline __attribute__ (( always_inline )) void
  316. aes_addroundkey ( union aes_matrix *state, const union aes_matrix *key ) {
  317. state->column[0] ^= key->column[0];
  318. state->column[1] ^= key->column[1];
  319. state->column[2] ^= key->column[2];
  320. state->column[3] ^= key->column[3];
  321. }
  322. /**
  323. * Perform final round
  324. *
  325. * @v table AES lookup table
  326. * @v stride AES row shift stride
  327. * @v in AES input state
  328. * @v out AES output state
  329. * @v key AES round key
  330. */
  331. static void aes_final ( const struct aes_table *table, size_t stride,
  332. const union aes_matrix *in, union aes_matrix *out,
  333. const union aes_matrix *key ) {
  334. const union aes_table_entry *entry;
  335. unsigned int byte;
  336. size_t out_offset;
  337. size_t in_offset;
  338. /* Perform [Inv]ShiftRows and [Inv]SubBytes */
  339. for ( out_offset = 0, in_offset = 0 ; out_offset < 16 ;
  340. out_offset++, in_offset = ( ( in_offset + stride ) & 0xf ) ) {
  341. /* Extract input byte (i.e. perform [Inv]ShiftRows) */
  342. byte = in->byte[in_offset];
  343. /* Locate lookup table entry for this input byte
  344. * (i.e. perform [Inv]SubBytes).
  345. */
  346. entry = &table->entry[byte];
  347. /* Store output byte */
  348. out->byte[out_offset] = entry->byte[0];
  349. }
  350. /* Perform AddRoundKey */
  351. aes_addroundkey ( out, key );
  352. }
  353. /**
  354. * Encrypt data
  355. *
  356. * @v ctx Context
  357. * @v src Data to encrypt
  358. * @v dst Buffer for encrypted data
  359. * @v len Length of data
  360. */
  361. static void aes_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
  362. struct aes_context *aes = ctx;
  363. union aes_matrix buffer[2];
  364. union aes_matrix *in = &buffer[0];
  365. union aes_matrix *out = &buffer[1];
  366. unsigned int rounds = aes->rounds;
  367. /* Sanity check */
  368. assert ( len == sizeof ( *in ) );
  369. /* Initialise input state */
  370. memcpy ( in, src, sizeof ( *in ) );
  371. /* Perform initial round (AddRoundKey) */
  372. aes_addroundkey ( in, &aes->encrypt.key[0] );
  373. /* Perform intermediate rounds (ShiftRows, SubBytes,
  374. * MixColumns, AddRoundKey).
  375. */
  376. aes_encrypt_rounds ( in, out, &aes->encrypt.key[1], ( rounds - 2 ) );
  377. in = out;
  378. /* Perform final round (ShiftRows, SubBytes, AddRoundKey) */
  379. out = dst;
  380. aes_final ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS, in, out,
  381. &aes->encrypt.key[ rounds - 1 ] );
  382. }
  383. /**
  384. * Decrypt data
  385. *
  386. * @v ctx Context
  387. * @v src Data to decrypt
  388. * @v dst Buffer for decrypted data
  389. * @v len Length of data
  390. */
  391. static void aes_decrypt ( void *ctx, const void *src, void *dst, size_t len ) {
  392. struct aes_context *aes = ctx;
  393. union aes_matrix buffer[2];
  394. union aes_matrix *in = &buffer[0];
  395. union aes_matrix *out = &buffer[1];
  396. unsigned int rounds = aes->rounds;
  397. /* Sanity check */
  398. assert ( len == sizeof ( *in ) );
  399. /* Initialise input state */
  400. memcpy ( in, src, sizeof ( *in ) );
  401. /* Perform initial round (AddRoundKey) */
  402. aes_addroundkey ( in, &aes->decrypt.key[0] );
  403. /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
  404. * InvMixColumns, AddRoundKey).
  405. */
  406. aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
  407. in = out;
  408. /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
  409. out = dst;
  410. aes_final ( &aes_invmixcolumns, AES_STRIDE_INVSHIFTROWS, in, out,
  411. &aes->decrypt.key[ rounds - 1 ] );
  412. }
  413. /**
  414. * Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
  415. *
  416. * @v poly Polynomial to be multiplied
  417. * @ret result Result
  418. */
  419. static __attribute__ (( const )) unsigned int aes_double ( unsigned int poly ) {
  420. /* Multiply polynomial by (x), placing the resulting x^8
  421. * coefficient in the LSB (i.e. rotate byte left by one).
  422. */
  423. poly = rol8 ( poly, 1 );
  424. /* If coefficient of x^8 (in LSB) is non-zero, then reduce by
  425. * subtracting (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8).
  426. */
  427. if ( poly & 0x01 ) {
  428. poly ^= 0x01; /* Subtract x^8 (currently in LSB) */
  429. poly ^= 0x1b; /* Subtract (x^4 + x^3 + x^2 + 1) */
  430. }
  431. return poly;
  432. }
  433. /**
  434. * Fill in MixColumns lookup table entry
  435. *
  436. * @v entry AES lookup table entry for scalar multiplicand
  437. *
  438. * The MixColumns lookup table vector multiplier is {1,1,1,3,2,1,1,3}.
  439. */
  440. static void aes_mixcolumns_entry ( union aes_table_entry *entry ) {
  441. unsigned int scalar_x_1;
  442. unsigned int scalar_x;
  443. unsigned int scalar;
  444. /* Retrieve scalar multiplicand */
  445. scalar = entry->byte[0];
  446. entry->byte[1] = scalar;
  447. entry->byte[2] = scalar;
  448. entry->byte[5] = scalar;
  449. entry->byte[6] = scalar;
  450. /* Calculate scalar multiplied by (x) */
  451. scalar_x = aes_double ( scalar );
  452. entry->byte[4] = scalar_x;
  453. /* Calculate scalar multiplied by (x + 1) */
  454. scalar_x_1 = ( scalar_x ^ scalar );
  455. entry->byte[3] = scalar_x_1;
  456. entry->byte[7] = scalar_x_1;
  457. }
  458. /**
  459. * Fill in InvMixColumns lookup table entry
  460. *
  461. * @v entry AES lookup table entry for scalar multiplicand
  462. *
  463. * The InvMixColumns lookup table vector multiplier is {1,9,13,11,14,9,13,11}.
  464. */
  465. static void aes_invmixcolumns_entry ( union aes_table_entry *entry ) {
  466. unsigned int scalar_x3_x2_x;
  467. unsigned int scalar_x3_x2_1;
  468. unsigned int scalar_x3_x2;
  469. unsigned int scalar_x3_x_1;
  470. unsigned int scalar_x3_1;
  471. unsigned int scalar_x3;
  472. unsigned int scalar_x2;
  473. unsigned int scalar_x;
  474. unsigned int scalar;
  475. /* Retrieve scalar multiplicand */
  476. scalar = entry->byte[0];
  477. /* Calculate scalar multiplied by (x) */
  478. scalar_x = aes_double ( scalar );
  479. /* Calculate scalar multiplied by (x^2) */
  480. scalar_x2 = aes_double ( scalar_x );
  481. /* Calculate scalar multiplied by (x^3) */
  482. scalar_x3 = aes_double ( scalar_x2 );
  483. /* Calculate scalar multiplied by (x^3 + 1) */
  484. scalar_x3_1 = ( scalar_x3 ^ scalar );
  485. entry->byte[1] = scalar_x3_1;
  486. entry->byte[5] = scalar_x3_1;
  487. /* Calculate scalar multiplied by (x^3 + x + 1) */
  488. scalar_x3_x_1 = ( scalar_x3_1 ^ scalar_x );
  489. entry->byte[3] = scalar_x3_x_1;
  490. entry->byte[7] = scalar_x3_x_1;
  491. /* Calculate scalar multiplied by (x^3 + x^2) */
  492. scalar_x3_x2 = ( scalar_x3 ^ scalar_x2 );
  493. /* Calculate scalar multiplied by (x^3 + x^2 + 1) */
  494. scalar_x3_x2_1 = ( scalar_x3_x2 ^ scalar );
  495. entry->byte[2] = scalar_x3_x2_1;
  496. entry->byte[6] = scalar_x3_x2_1;
  497. /* Calculate scalar multiplied by (x^3 + x^2 + x) */
  498. scalar_x3_x2_x = ( scalar_x3_x2 ^ scalar_x );
  499. entry->byte[4] = scalar_x3_x2_x;
  500. }
  501. /**
  502. * Generate AES lookup tables
  503. *
  504. */
  505. static void aes_generate ( void ) {
  506. union aes_table_entry *entry;
  507. union aes_table_entry *inventry;
  508. unsigned int poly = 0x01;
  509. unsigned int invpoly = 0x01;
  510. unsigned int transformed;
  511. unsigned int i;
  512. /* Iterate over non-zero values of GF(2^8) using generator (x + 1) */
  513. do {
  514. /* Multiply polynomial by (x + 1) */
  515. poly ^= aes_double ( poly );
  516. /* Divide inverse polynomial by (x + 1). This code
  517. * fragment is taken directly from the Wikipedia page
  518. * on the Rijndael S-box. An explanation of why it
  519. * works would be greatly appreciated.
  520. */
  521. invpoly ^= ( invpoly << 1 );
  522. invpoly ^= ( invpoly << 2 );
  523. invpoly ^= ( invpoly << 4 );
  524. if ( invpoly & 0x80 )
  525. invpoly ^= 0x09;
  526. invpoly &= 0xff;
  527. /* Apply affine transformation */
  528. transformed = ( 0x63 ^ invpoly ^ rol8 ( invpoly, 1 ) ^
  529. rol8 ( invpoly, 2 ) ^ rol8 ( invpoly, 3 ) ^
  530. rol8 ( invpoly, 4 ) );
  531. /* Populate S-box (within MixColumns lookup table) */
  532. aes_mixcolumns.entry[poly].byte[0] = transformed;
  533. } while ( poly != 0x01 );
  534. /* Populate zeroth S-box entry (which has no inverse) */
  535. aes_mixcolumns.entry[0].byte[0] = 0x63;
  536. /* Fill in MixColumns and InvMixColumns lookup tables */
  537. for ( i = 0 ; i < 256 ; i++ ) {
  538. /* Fill in MixColumns lookup table entry */
  539. entry = &aes_mixcolumns.entry[i];
  540. aes_mixcolumns_entry ( entry );
  541. /* Populate inverse S-box (within InvMixColumns lookup table) */
  542. inventry = &aes_invmixcolumns.entry[ entry->byte[0] ];
  543. inventry->byte[0] = i;
  544. /* Fill in InvMixColumns lookup table entry */
  545. aes_invmixcolumns_entry ( inventry );
  546. }
  547. }
  548. /**
  549. * Rotate key column
  550. *
  551. * @v column Key column
  552. * @ret column Updated key column
  553. */
  554. static inline __attribute__ (( always_inline )) uint32_t
  555. aes_key_rotate ( uint32_t column ) {
  556. return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
  557. ror32 ( column, 8 ) : rol32 ( column, 8 ) );
  558. }
  559. /**
  560. * Apply S-box to key column
  561. *
  562. * @v column Key column
  563. * @ret column Updated key column
  564. */
  565. static uint32_t aes_key_sbox ( uint32_t column ) {
  566. unsigned int i;
  567. uint8_t byte;
  568. for ( i = 0 ; i < 4 ; i++ ) {
  569. byte = ( column & 0xff );
  570. byte = aes_mixcolumns.entry[byte].byte[0];
  571. column = ( ( column & ~0xff ) | byte );
  572. column = rol32 ( column, 8 );
  573. }
  574. return column;
  575. }
  576. /**
  577. * Apply schedule round constant to key column
  578. *
  579. * @v column Key column
  580. * @v rcon Round constant
  581. * @ret column Updated key column
  582. */
  583. static inline __attribute__ (( always_inline )) uint32_t
  584. aes_key_rcon ( uint32_t column, unsigned int rcon ) {
  585. return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
  586. ( column ^ rcon ) : ( column ^ ( rcon << 24 ) ) );
  587. }
  588. /**
  589. * Set key
  590. *
  591. * @v ctx Context
  592. * @v key Key
  593. * @v keylen Key length
  594. * @ret rc Return status code
  595. */
  596. static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
  597. struct aes_context *aes = ctx;
  598. union aes_matrix *enc;
  599. union aes_matrix *dec;
  600. union aes_matrix temp;
  601. union aes_matrix zero;
  602. unsigned int rcon = 0x01;
  603. unsigned int rounds;
  604. size_t offset = 0;
  605. uint32_t *prev;
  606. uint32_t *next;
  607. uint32_t *end;
  608. uint32_t tmp;
  609. /* Generate lookup tables, if not already done */
  610. if ( ! aes_mixcolumns.entry[0].byte[0] )
  611. aes_generate();
  612. /* Validate key length and calculate number of intermediate rounds */
  613. switch ( keylen ) {
  614. case ( 128 / 8 ) :
  615. rounds = 11;
  616. break;
  617. case ( 192 / 8 ) :
  618. rounds = 13;
  619. break;
  620. case ( 256 / 8 ) :
  621. rounds = 15;
  622. break;
  623. default:
  624. DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
  625. aes, ( keylen * 8 ) );
  626. return -EINVAL;
  627. }
  628. aes->rounds = rounds;
  629. enc = aes->encrypt.key;
  630. end = enc[rounds].column;
  631. /* Copy raw key */
  632. memcpy ( enc, key, keylen );
  633. prev = enc->column;
  634. next = ( ( ( void * ) prev ) + keylen );
  635. tmp = next[-1];
  636. /* Construct expanded key */
  637. while ( next < end ) {
  638. /* If this is the first column of an expanded key
  639. * block, or the middle column of an AES-256 key
  640. * block, then apply the S-box.
  641. */
  642. if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
  643. tmp = aes_key_sbox ( tmp );
  644. /* If this is the first column of an expanded key
  645. * block then rotate and apply the round constant.
  646. */
  647. if ( offset == 0 ) {
  648. tmp = aes_key_rotate ( tmp );
  649. tmp = aes_key_rcon ( tmp, rcon );
  650. rcon = aes_double ( rcon );
  651. }
  652. /* XOR with previous key column */
  653. tmp ^= *prev;
  654. /* Store column */
  655. *next = tmp;
  656. /* Move to next column */
  657. offset += sizeof ( *next );
  658. if ( offset == keylen )
  659. offset = 0;
  660. next++;
  661. prev++;
  662. }
  663. DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
  664. DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
  665. /* Convert to decryption key */
  666. memset ( &zero, 0, sizeof ( zero ) );
  667. dec = &aes->decrypt.key[ rounds - 1 ];
  668. memcpy ( dec--, enc++, sizeof ( *dec ) );
  669. while ( dec > aes->decrypt.key ) {
  670. /* Perform InvMixColumns (by reusing the encryption
  671. * final-round code to perform ShiftRows+SubBytes and
  672. * reusing the decryption intermediate-round code to
  673. * perform InvShiftRows+InvSubBytes+InvMixColumns, all
  674. * with a zero encryption key).
  675. */
  676. aes_final ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS,
  677. enc++, &temp, &zero );
  678. aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
  679. }
  680. memcpy ( dec--, enc++, sizeof ( *dec ) );
  681. DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
  682. DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
  683. return 0;
  684. }
  685. /**
  686. * Set initialisation vector
  687. *
  688. * @v ctx Context
  689. * @v iv Initialisation vector
  690. */
  691. static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
  692. /* Nothing to do */
  693. }
  694. /** Basic AES algorithm */
  695. struct cipher_algorithm aes_algorithm = {
  696. .name = "aes",
  697. .ctxsize = sizeof ( struct aes_context ),
  698. .blocksize = AES_BLOCKSIZE,
  699. .setkey = aes_setkey,
  700. .setiv = aes_setiv,
  701. .encrypt = aes_encrypt,
  702. .decrypt = aes_decrypt,
  703. };
  704. /* AES in Electronic Codebook mode */
  705. ECB_CIPHER ( aes_ecb, aes_ecb_algorithm,
  706. aes_algorithm, struct aes_context, AES_BLOCKSIZE );
  707. /* AES in Cipher Block Chaining mode */
  708. CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
  709. aes_algorithm, struct aes_context, AES_BLOCKSIZE );