/contrib/bearssl/src/symcipher/aes_ct_enc.c

https://bitbucket.org/freebsd/freebsd-base · C · 112 lines · 77 code · 11 blank · 24 comment · 2 complexity · 0233daa46124c558b56f4ee6f54d7fc9 MD5 · raw file

  1. /*
  2. * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. */
  24. #include "inner.h"
  25. static inline void
  26. add_round_key(uint32_t *q, const uint32_t *sk)
  27. {
  28. q[0] ^= sk[0];
  29. q[1] ^= sk[1];
  30. q[2] ^= sk[2];
  31. q[3] ^= sk[3];
  32. q[4] ^= sk[4];
  33. q[5] ^= sk[5];
  34. q[6] ^= sk[6];
  35. q[7] ^= sk[7];
  36. }
  37. static inline void
  38. shift_rows(uint32_t *q)
  39. {
  40. int i;
  41. for (i = 0; i < 8; i ++) {
  42. uint32_t x;
  43. x = q[i];
  44. q[i] = (x & 0x000000FF)
  45. | ((x & 0x0000FC00) >> 2) | ((x & 0x00000300) << 6)
  46. | ((x & 0x00F00000) >> 4) | ((x & 0x000F0000) << 4)
  47. | ((x & 0xC0000000) >> 6) | ((x & 0x3F000000) << 2);
  48. }
  49. }
  50. static inline uint32_t
  51. rotr16(uint32_t x)
  52. {
  53. return (x << 16) | (x >> 16);
  54. }
  55. static inline void
  56. mix_columns(uint32_t *q)
  57. {
  58. uint32_t q0, q1, q2, q3, q4, q5, q6, q7;
  59. uint32_t r0, r1, r2, r3, r4, r5, r6, r7;
  60. q0 = q[0];
  61. q1 = q[1];
  62. q2 = q[2];
  63. q3 = q[3];
  64. q4 = q[4];
  65. q5 = q[5];
  66. q6 = q[6];
  67. q7 = q[7];
  68. r0 = (q0 >> 8) | (q0 << 24);
  69. r1 = (q1 >> 8) | (q1 << 24);
  70. r2 = (q2 >> 8) | (q2 << 24);
  71. r3 = (q3 >> 8) | (q3 << 24);
  72. r4 = (q4 >> 8) | (q4 << 24);
  73. r5 = (q5 >> 8) | (q5 << 24);
  74. r6 = (q6 >> 8) | (q6 << 24);
  75. r7 = (q7 >> 8) | (q7 << 24);
  76. q[0] = q7 ^ r7 ^ r0 ^ rotr16(q0 ^ r0);
  77. q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr16(q1 ^ r1);
  78. q[2] = q1 ^ r1 ^ r2 ^ rotr16(q2 ^ r2);
  79. q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr16(q3 ^ r3);
  80. q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr16(q4 ^ r4);
  81. q[5] = q4 ^ r4 ^ r5 ^ rotr16(q5 ^ r5);
  82. q[6] = q5 ^ r5 ^ r6 ^ rotr16(q6 ^ r6);
  83. q[7] = q6 ^ r6 ^ r7 ^ rotr16(q7 ^ r7);
  84. }
  85. /* see inner.h */
  86. void
  87. br_aes_ct_bitslice_encrypt(unsigned num_rounds,
  88. const uint32_t *skey, uint32_t *q)
  89. {
  90. unsigned u;
  91. add_round_key(q, skey);
  92. for (u = 1; u < num_rounds; u ++) {
  93. br_aes_ct_bitslice_Sbox(q);
  94. shift_rows(q);
  95. mix_columns(q);
  96. add_round_key(q, skey + (u << 3));
  97. }
  98. br_aes_ct_bitslice_Sbox(q);
  99. shift_rows(q);
  100. add_round_key(q, skey + (num_rounds << 3));
  101. }