crypto_aes.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. #include <assert.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <openssl/aes.h>
  6. #include "cpusupport.h"
  7. #include "crypto_aes_aesni.h"
  8. #include "crypto_aes_arm.h"
  9. #include "insecure_memzero.h"
  10. #include "warnp.h"
  11. #include "crypto_aes.h"
  12. #if defined(CPUSUPPORT_X86_AESNI) || defined(CPUSUPPORT_ARM_AES)
  13. #define HWACCEL
  14. static enum {
  15. HW_SOFTWARE = 0,
  16. #if defined(CPUSUPPORT_X86_AESNI)
  17. HW_X86_AESNI,
  18. #endif
  19. #if defined(CPUSUPPORT_ARM_AES)
  20. HW_ARM_AES,
  21. #endif
  22. HW_UNSET
  23. } hwaccel = HW_UNSET;
  24. #endif
  25. /**
  26. * This represents either an AES_KEY or a struct crypto_aes_key_aesni; we
  27. * know which it is based on whether we're using AESNI code or not. As such,
  28. * it's just an opaque pointer; but declaring it as a named structure type
  29. * prevents type-mismatch bugs in upstream code.
  30. */
  31. struct crypto_aes_key;
  32. #ifdef HWACCEL
  33. static struct aes_test {
  34. const uint8_t key[32];
  35. const size_t len;
  36. const uint8_t ptext[16];
  37. const uint8_t ctext[16];
  38. } testcases[] = { {
  39. /* NIST FIPS 179, Appendix C - Example Vectors, AES-128, p. 35. */
  40. .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  41. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
  42. .len = 16,
  43. .ptext = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
  44. 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
  45. .ctext = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
  46. 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
  47. }, {
  48. /* NIST FIPS 179, Appendix C - Example Vectors, AES-256, p. 42. */
  49. .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  50. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  51. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  52. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, },
  53. .len = 32,
  54. .ptext = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
  55. 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
  56. .ctext = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
  57. 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
  58. }
  59. };
  60. /* Test a function against test vectors. */
  61. static int
  62. functest(int (* func)(const uint8_t *, size_t, const uint8_t[16], uint8_t[16]))
  63. {
  64. struct aes_test * knowngood;
  65. uint8_t ctext[16];
  66. size_t i;
  67. for (i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++) {
  68. knowngood = &testcases[i];
  69. /* Sanity-check. */
  70. assert((knowngood->len == 16) || (knowngood->len == 32));
  71. /* Expand the key and encrypt with the provided function. */
  72. if (func(knowngood->key, knowngood->len, knowngood->ptext,
  73. ctext))
  74. goto err0;
  75. /* Does the output match the known good value? */
  76. if (memcmp(knowngood->ctext, ctext, 16))
  77. goto err0;
  78. }
  79. /* Success! */
  80. return (0);
  81. err0:
  82. /* Failure! */
  83. return (-1);
  84. }
  85. #if defined(CPUSUPPORT_X86_AESNI)
  86. static int
  87. x86_aesni_oneshot(const uint8_t * key_unexpanded, size_t len,
  88. const uint8_t ptext[16], uint8_t ctext[16])
  89. {
  90. void * kexp_hw;
  91. /* Expand the key and encrypt with hardware intrinsics. */
  92. if ((kexp_hw = crypto_aes_key_expand_aesni(key_unexpanded, len))
  93. == NULL)
  94. goto err0;
  95. crypto_aes_encrypt_block_aesni(ptext, ctext, kexp_hw);
  96. crypto_aes_key_free_aesni(kexp_hw);
  97. /* Success! */
  98. return (0);
  99. err0:
  100. /* Failure! */
  101. return (-1);
  102. }
  103. #endif
  104. #if defined(CPUSUPPORT_ARM_AES)
  105. static int
  106. arm_aes_oneshot(const uint8_t * key_unexpanded, size_t len,
  107. const uint8_t ptext[16], uint8_t * ctext)
  108. {
  109. void * kexp_hw;
  110. if ((kexp_hw = crypto_aes_key_expand_arm(key_unexpanded, len)) == NULL)
  111. goto err0;
  112. crypto_aes_encrypt_block_arm(ptext, ctext, kexp_hw);
  113. crypto_aes_key_free_arm(kexp_hw);
  114. /* Success! */
  115. return (0);
  116. err0:
  117. /* Failure! */
  118. return (-1);
  119. }
  120. #endif
  121. static int
  122. openssl_oneshot(const uint8_t * key_unexpanded, size_t len,
  123. const uint8_t ptext[16], uint8_t * ctext)
  124. {
  125. AES_KEY kexp_actual;
  126. AES_KEY * kexp = &kexp_actual;
  127. /* Expand the key, encrypt, and clean up. */
  128. if (AES_set_encrypt_key(key_unexpanded, (int)(len * 8), kexp) != 0)
  129. goto err0;
  130. AES_encrypt(ptext, ctext, kexp);
  131. insecure_memzero(kexp, sizeof(AES_KEY));
  132. /* Success! */
  133. return (0);
  134. err0:
  135. /* Failure! */
  136. return (-1);
  137. }
  138. /* Which type of hardware acceleration should we use, if any? */
  139. static void
  140. hwaccel_init(void)
  141. {
  142. /* If we've already set hwaccel, we're finished. */
  143. if (hwaccel != HW_UNSET)
  144. return;
  145. /* Default to software. */
  146. hwaccel = HW_SOFTWARE;
  147. #if defined(CPUSUPPORT_X86_AESNI)
  148. CPUSUPPORT_VALIDATE(hwaccel, HW_X86_AESNI, cpusupport_x86_aesni(),
  149. functest(x86_aesni_oneshot));
  150. #endif
  151. #if defined(CPUSUPPORT_ARM_AES)
  152. CPUSUPPORT_VALIDATE(hwaccel, HW_ARM_AES, cpusupport_arm_aes(),
  153. functest(arm_aes_oneshot));
  154. #endif
  155. /*
  156. * If we're here, we're not using any intrinsics. Test OpenSSL; if
  157. * there's an error, print a warning and abort.
  158. */
  159. if (functest(openssl_oneshot)) {
  160. warn0("OpenSSL gives incorrect AES values.");
  161. abort();
  162. }
  163. }
  164. #endif /* HWACCEL */
  165. /**
  166. * crypto_aes_can_use_intrinsics(void):
  167. * Test whether hardware intrinsics are safe to use. Return 1 if x86 AESNI
  168. * operations are available, 2 if ARM-AES operations are available, or 0 if
  169. * none are available.
  170. */
  171. int
  172. crypto_aes_can_use_intrinsics(void)
  173. {
  174. #ifdef HWACCEL
  175. /* Ensure that we've chosen the type of hardware acceleration. */
  176. hwaccel_init();
  177. #if defined(CPUSUPPORT_X86_AESNI)
  178. if (hwaccel == HW_X86_AESNI)
  179. return (1);
  180. #endif
  181. #if defined(CPUSUPPORT_ARM_AES)
  182. if (hwaccel == HW_ARM_AES)
  183. return (2);
  184. #endif
  185. #endif /* HWACCEL */
  186. /* Software only. */
  187. return (0);
  188. }
  189. /**
  190. * crypto_aes_key_expand(key_unexpanded, len):
  191. * Expand the ${len}-byte unexpanded AES key ${key_unexpanded} into a
  192. * structure which can be passed to crypto_aes_encrypt_block(). The length
  193. * must be 16 or 32.
  194. */
  195. struct crypto_aes_key *
  196. crypto_aes_key_expand(const uint8_t * key_unexpanded, size_t len)
  197. {
  198. AES_KEY * kexp;
  199. /* Sanity-check. */
  200. assert((len == 16) || (len == 32));
  201. #ifdef HWACCEL
  202. /* Ensure that we've chosen the type of hardware acceleration. */
  203. hwaccel_init();
  204. #ifdef CPUSUPPORT_X86_AESNI
  205. if (hwaccel == HW_X86_AESNI)
  206. return (crypto_aes_key_expand_aesni(key_unexpanded, len));
  207. #endif
  208. #ifdef CPUSUPPORT_ARM_AES
  209. if (hwaccel == HW_ARM_AES)
  210. return (crypto_aes_key_expand_arm(key_unexpanded, len));
  211. #endif
  212. #endif /* HWACCEL */
  213. /* Allocate structure. */
  214. if ((kexp = malloc(sizeof(AES_KEY))) == NULL)
  215. goto err0;
  216. /* Expand the key. */
  217. if (AES_set_encrypt_key(key_unexpanded, (int)(len * 8), kexp) != 0)
  218. goto err1;
  219. /* Success! */
  220. return ((void *)kexp);
  221. err1:
  222. free(kexp);
  223. err0:
  224. /* Failure! */
  225. return (NULL);
  226. }
  227. /**
  228. * crypto_aes_encrypt_block(in, out, key):
  229. * Using the expanded AES key ${key}, encrypt the block ${in} and write the
  230. * resulting ciphertext to ${out}. ${in} and ${out} can overlap.
  231. */
  232. void
  233. crypto_aes_encrypt_block(const uint8_t in[16], uint8_t out[16],
  234. const struct crypto_aes_key * key)
  235. {
  236. #ifdef HWACCEL
  237. #ifdef CPUSUPPORT_X86_AESNI
  238. if (hwaccel == HW_X86_AESNI) {
  239. crypto_aes_encrypt_block_aesni(in, out, (const void *)key);
  240. return;
  241. }
  242. #endif
  243. #ifdef CPUSUPPORT_ARM_AES
  244. if (hwaccel == HW_ARM_AES) {
  245. crypto_aes_encrypt_block_arm(in, out, (const void *)key);
  246. return;
  247. }
  248. #endif
  249. #endif /* HWACCEL */
  250. /* Get AES to do the work. */
  251. AES_encrypt(in, out, (const void *)key);
  252. }
  253. /**
  254. * crypto_aes_key_free(key):
  255. * Free the expanded AES key ${key}.
  256. */
  257. void
  258. crypto_aes_key_free(struct crypto_aes_key * key)
  259. {
  260. #ifdef HWACCEL
  261. #ifdef CPUSUPPORT_X86_AESNI
  262. if (hwaccel == HW_X86_AESNI) {
  263. crypto_aes_key_free_aesni((void *)key);
  264. return;
  265. }
  266. #endif
  267. #ifdef CPUSUPPORT_ARM_AES
  268. if (hwaccel == HW_ARM_AES) {
  269. crypto_aes_key_free_arm((void *)key);
  270. return;
  271. }
  272. #endif
  273. #endif /* HWACCEL */
  274. /* Behave consistently with free(NULL). */
  275. if (key == NULL)
  276. return;
  277. /* Attempt to zero the expanded key. */
  278. insecure_memzero(key, sizeof(AES_KEY));
  279. /* Free the key. */
  280. free(key);
  281. }