aes-select.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Top-level vtables to select an AES implementation.
  3. */
  4. #include <assert.h>
  5. #include <stdlib.h>
  6. #include "putty.h"
  7. #include "ssh.h"
  8. #include "aes.h"
  9. static ssh_cipher *aes_select(const ssh_cipheralg *alg)
  10. {
  11. const ssh_cipheralg *const *real_algs = (const ssh_cipheralg **)alg->extra;
  12. { // WINSCP
  13. size_t i;
  14. for (i = 0; real_algs[i]; i++) {
  15. const ssh_cipheralg *alg = real_algs[i];
  16. const struct aes_extra *alg_extra =
  17. (const struct aes_extra *)alg->extra;
  18. if (check_availability(alg_extra))
  19. return ssh_cipher_new(alg);
  20. }
  21. /* We should never reach the NULL at the end of the list, because
  22. * the last non-NULL entry should be software-only AES, which is
  23. * always available. */
  24. unreachable("aes_select ran off the end of its list");
  25. } // WINSCP
  26. }
  27. #if HAVE_AES_NI
  28. #define IF_NI(...) __VA_ARGS__
  29. #else
  30. #define IF_NI(...)
  31. #endif
  32. #if HAVE_NEON_CRYPTO
  33. #define IF_NEON(...) __VA_ARGS__
  34. #else
  35. #define IF_NEON(...)
  36. #endif
  37. #define AES_SELECTOR_VTABLE(mode_c, mode_protocol, mode_display, bits) \
  38. static const ssh_cipheralg * \
  39. ssh_aes ## bits ## _ ## mode_c ## _impls[] = { \
  40. IF_NI(&ssh_aes ## bits ## _ ## mode_c ## _ni,) \
  41. IF_NEON(&ssh_aes ## bits ## _ ## mode_c ## _neon,) \
  42. &ssh_aes ## bits ## _ ## mode_c ## _sw, \
  43. NULL, \
  44. }; \
  45. const ssh_cipheralg ssh_aes ## bits ## _ ## mode_c = { \
  46. /* WINSCP */ \
  47. /*.new =*/ aes_select, \
  48. NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
  49. /*.ssh2_id =*/ "aes" #bits "-" mode_protocol, \
  50. /*.blksize =*/ 16, \
  51. /*.real_keybits =*/ bits, \
  52. /*.padded_keybytes =*/ bits/8, \
  53. 0, \
  54. /*.text_name =*/ "AES-" #bits " " mode_display \
  55. " (dummy selector vtable)", \
  56. NULL, \
  57. /*.extra =*/ ssh_aes ## bits ## _ ## mode_c ## _impls, \
  58. }
  59. AES_SELECTOR_VTABLE(cbc, "cbc", "CBC", 128);
  60. AES_SELECTOR_VTABLE(cbc, "cbc", "CBC", 192);
  61. AES_SELECTOR_VTABLE(cbc, "cbc", "CBC", 256);
  62. AES_SELECTOR_VTABLE(sdctr, "ctr", "SDCTR", 128);
  63. AES_SELECTOR_VTABLE(sdctr, "ctr", "SDCTR", 192);
  64. AES_SELECTOR_VTABLE(sdctr, "ctr", "SDCTR", 256);
  65. static const ssh_cipheralg ssh_rijndael_lysator = {
  66. /* Same as aes256_cbc, but with a different protocol ID */
  67. /*.new =*/ aes_select,
  68. NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  69. /*.ssh2_id =*/ "[email protected]",
  70. /*.blksize =*/ 16,
  71. /*.real_keybits =*/ 256,
  72. /*.padded_keybytes =*/ 256/8,
  73. 0,
  74. /*.text_name =*/ "AES-256 CBC (dummy selector vtable)",
  75. NULL,
  76. /*.extra =*/ ssh_aes256_cbc_impls,
  77. };
  78. static const ssh_cipheralg *const aes_list[] = {
  79. &ssh_aes256_sdctr,
  80. &ssh_aes256_cbc,
  81. &ssh_rijndael_lysator,
  82. &ssh_aes192_sdctr,
  83. &ssh_aes192_cbc,
  84. &ssh_aes128_sdctr,
  85. &ssh_aes128_cbc,
  86. };
  87. const ssh2_ciphers ssh2_aes = { lenof(aes_list), aes_list };