aes-internal-enc.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * AES (Rijndael) cipher - encrypt
  3. *
  4. * Modifications to public domain implementation:
  5. * - cleanup
  6. * - use C pre-processor to make it easier to change S table access
  7. * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
  8. * cost of reduced throughput (quite small difference on Pentium 4,
  9. * 10-25% when using -O1 or -O2 optimization)
  10. *
  11. * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
  12. *
  13. * This software may be distributed under the terms of the BSD license.
  14. * See README for more details.
  15. */
  16. #include "includes.h"
  17. #include "common.h"
  18. #include "crypto.h"
  19. #include "aes_i.h"
  20. static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16])
  21. {
  22. u32 s0, s1, s2, s3, t0, t1, t2, t3;
  23. #ifndef FULL_UNROLL
  24. int r;
  25. #endif /* ?FULL_UNROLL */
  26. /*
  27. * map byte array block to cipher state
  28. * and add initial round key:
  29. */
  30. s0 = GETU32(pt ) ^ rk[0];
  31. s1 = GETU32(pt + 4) ^ rk[1];
  32. s2 = GETU32(pt + 8) ^ rk[2];
  33. s3 = GETU32(pt + 12) ^ rk[3];
  34. #define ROUND(i,d,s) \
  35. d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
  36. d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
  37. d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
  38. d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
  39. #ifdef FULL_UNROLL
  40. ROUND(1,t,s);
  41. ROUND(2,s,t);
  42. ROUND(3,t,s);
  43. ROUND(4,s,t);
  44. ROUND(5,t,s);
  45. ROUND(6,s,t);
  46. ROUND(7,t,s);
  47. ROUND(8,s,t);
  48. ROUND(9,t,s);
  49. if (Nr > 10) {
  50. ROUND(10,s,t);
  51. ROUND(11,t,s);
  52. if (Nr > 12) {
  53. ROUND(12,s,t);
  54. ROUND(13,t,s);
  55. }
  56. }
  57. rk += Nr << 2;
  58. #else /* !FULL_UNROLL */
  59. /* Nr - 1 full rounds: */
  60. r = Nr >> 1;
  61. for (;;) {
  62. ROUND(1,t,s);
  63. rk += 8;
  64. if (--r == 0)
  65. break;
  66. ROUND(0,s,t);
  67. }
  68. #endif /* ?FULL_UNROLL */
  69. #undef ROUND
  70. /*
  71. * apply last round and
  72. * map cipher state to byte array block:
  73. */
  74. s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
  75. PUTU32(ct , s0);
  76. s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
  77. PUTU32(ct + 4, s1);
  78. s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
  79. PUTU32(ct + 8, s2);
  80. s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
  81. PUTU32(ct + 12, s3);
  82. }
  83. void * aes_encrypt_init(const u8 *key, size_t len)
  84. {
  85. u32 *rk;
  86. int res;
  87. rk = os_malloc(AES_PRIV_SIZE);
  88. if (rk == NULL)
  89. return NULL;
  90. res = rijndaelKeySetupEnc(rk, key, len * 8);
  91. if (res < 0) {
  92. os_free(rk);
  93. return NULL;
  94. }
  95. rk[AES_PRIV_NR_POS] = res;
  96. return rk;
  97. }
  98. void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
  99. {
  100. u32 *rk = ctx;
  101. rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt);
  102. }
  103. void aes_encrypt_deinit(void *ctx)
  104. {
  105. os_memset(ctx, 0, AES_PRIV_SIZE);
  106. os_free(ctx);
  107. }