aes.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Definitions likely to be helpful to multiple AES implementations.
  3. */
  4. /*
  5. * The 'extra' structure used by AES implementations is used to
  6. * include information about how to check if a given implementation is
  7. * available at run time, and whether we've already checked.
  8. */
  9. struct aes_extra_mutable;
  10. struct aes_extra {
  11. /* Function to check availability. Might be expensive, so we don't
  12. * want to call it more than once. */
  13. bool (*check_available)(void);
  14. /* Point to a writable substructure. */
  15. struct aes_extra_mutable *mut;
  16. /* Extra API function specific to AES, to encrypt a single block
  17. * in ECB mode without touching the IV. Used by AES-GCM MAC
  18. * setup. */
  19. void (*encrypt_ecb_block)(ssh_cipher *, void *);
  20. };
  21. struct aes_extra_mutable {
  22. bool checked_availability;
  23. bool is_available;
  24. };
  25. static inline bool check_availability(const struct aes_extra *extra)
  26. {
  27. if (!extra->mut->checked_availability) {
  28. extra->mut->is_available = extra->check_available();
  29. extra->mut->checked_availability = true;
  30. }
  31. return extra->mut->is_available;
  32. }
  33. /* Shared stub function for all the AES-GCM vtables. */
  34. void aesgcm_cipher_crypt_length(
  35. ssh_cipher *cipher, void *blk, int len, unsigned long seq);
  36. /* External entry point for the encrypt_ecb_block function. */
  37. static inline void aes_encrypt_ecb_block(ssh_cipher *ciph, void *blk)
  38. {
  39. const struct aes_extra *extra = ciph->vt->extra;
  40. extra->encrypt_ecb_block(ciph, blk);
  41. }
  42. /*
  43. * Macros to define vtables for AES variants. There are a lot of
  44. * these, because of the cross product between cipher modes, key
  45. * sizes, and assorted HW/SW implementations, so it's worth spending
  46. * some effort here to reduce the boilerplate in the sub-files.
  47. */
  48. #define AES_EXTRA_BITS(impl_c, bits) \
  49. static struct aes_extra_mutable aes ## impl_c ## _extra_mut; \
  50. static const struct aes_extra aes ## bits ## impl_c ## _extra = { \
  51. /* WINSCP */ \
  52. /*.check_available =*/ aes ## impl_c ## _available, \
  53. /*.mut =*/ &aes ## impl_c ## _extra_mut, \
  54. /*.encrypt_ecb_block =*/ &aes ## bits ## impl_c ## _encrypt_ecb_block, \
  55. }
  56. #define AES_EXTRA(impl_c) \
  57. AES_EXTRA_BITS(impl_c, 128); \
  58. AES_EXTRA_BITS(impl_c, 192); \
  59. AES_EXTRA_BITS(impl_c, 256)
  60. // WINSCP string constants are for avoiding
  61. // Warning 1060: Different alignments specified for same segment, %s. Using highest alignment.rdata
  62. // in objconv
  63. #define AES_CBC_VTABLE(impl_c, impl_display, bits) \
  64. const char ssh_aes ## bits ## _cbc ## impl_c ## ssh2_id[] = "aes" #bits "-cbc"; /*WINSCP*/ \
  65. const char ssh_aes ## bits ## _cbc ## impl_c ## text_name[] = "AES-" #bits " CBC (" impl_display ")"; /*WINSCP*/ \
  66. const ssh_cipheralg ssh_aes ## bits ## _cbc ## impl_c = { \
  67. /*WINSCP*/ \
  68. /*.new =*/ aes ## impl_c ## _new, \
  69. /*.free =*/ aes ## impl_c ## _free, \
  70. /*.setiv =*/ aes ## impl_c ## _setiv_cbc, \
  71. /*.setkey =*/ aes ## impl_c ## _setkey, \
  72. /*.encrypt =*/ aes ## bits ## impl_c ## _cbc_encrypt, \
  73. /*.decrypt =*/ aes ## bits ## impl_c ## _cbc_decrypt, \
  74. NULL, \
  75. NULL, \
  76. /*.next_message =*/ nullcipher_next_message, \
  77. /*.ssh2_id =*/ ssh_aes ## bits ## _cbc ## impl_c ## ssh2_id, /*WINSCP*/ \
  78. /*.blksize =*/ 16, \
  79. /*.real_keybits =*/ bits, \
  80. /*.padded_keybytes =*/ bits/8, \
  81. /*.flags =*/ SSH_CIPHER_IS_CBC, \
  82. /*.text_name =*/ ssh_aes ## bits ## _cbc ## impl_c ## text_name, /*WINSCP*/ \
  83. NULL, \
  84. /*.extra =*/ &aes ## bits ## impl_c ## _extra, \
  85. }
  86. #define AES_SDCTR_VTABLE(impl_c, impl_display, bits) \
  87. const char ssh_aes ## bits ## _sdctr ## impl_c ## ssh2_id[] = "aes" #bits "-ctr"; /*WINSCP*/ \
  88. const char ssh_aes ## bits ## _sdctr ## impl_c ## text_name[] = "AES-" #bits " SDCTR (" impl_display ")"; /*WINSCP*/ \
  89. const ssh_cipheralg ssh_aes ## bits ## _sdctr ## impl_c = { \
  90. /*WINSCP*/ \
  91. /*.new =*/ aes ## impl_c ## _new, \
  92. /*.free =*/ aes ## impl_c ## _free, \
  93. /*.setiv =*/ aes ## impl_c ## _setiv_sdctr, \
  94. /*.setkey =*/ aes ## impl_c ## _setkey, \
  95. /*.encrypt =*/ aes ## bits ## impl_c ## _sdctr, \
  96. /*.decrypt =*/ aes ## bits ## impl_c ## _sdctr, \
  97. NULL, \
  98. NULL, \
  99. /*.next_message =*/ nullcipher_next_message, \
  100. /*.ssh2_id =*/ ssh_aes ## bits ## _sdctr ## impl_c ## ssh2_id, /*WINSCP*/ \
  101. /*.blksize =*/ 16, \
  102. /*.real_keybits =*/ bits, \
  103. /*.padded_keybytes =*/ bits/8, \
  104. /*.flags =*/ 0, \
  105. /*.text_name =*/ ssh_aes ## bits ## _sdctr ## impl_c ## text_name, /*WINSCP*/ \
  106. NULL, \
  107. /*.extra =*/ &aes ## bits ## impl_c ## _extra, \
  108. }
  109. #define AES_GCM_VTABLE(impl_c, impl_display, bits) \
  110. const char ssh_aes ## bits ## _gcm ## impl_c ## ssh2_id[] = "aes" #bits "[email protected]"; /*WINSCP*/ \
  111. const char ssh_aes ## bits ## _gcm ## impl_c ## text_name[] = "AES-" #bits " GCM (" impl_display ")"; /*WINSCP*/ \
  112. const ssh_cipheralg ssh_aes ## bits ## _gcm ## impl_c = { \
  113. /*.new =*/ aes ## impl_c ## _new, \
  114. /*.free =*/ aes ## impl_c ## _free, \
  115. /*.setiv =*/ aes ## impl_c ## _setiv_gcm, \
  116. /*.setkey =*/ aes ## impl_c ## _setkey, \
  117. /*.encrypt =*/ aes ## bits ## impl_c ## _gcm, \
  118. /*.decrypt =*/ aes ## bits ## impl_c ## _gcm, \
  119. /*.encrypt_length =*/ aesgcm_cipher_crypt_length, \
  120. /*.decrypt_length =*/ aesgcm_cipher_crypt_length, \
  121. /*.next_message =*/ aes ## impl_c ## _next_message_gcm, \
  122. /* 192-bit AES-GCM is included only so that testcrypt can run \
  123. * standard test vectors against it. OpenSSH doesn't define a \
  124. * protocol id for it. So we set its ssh2_id to NULL. */ \
  125. /*.ssh2_id =*/ bits==192 ? NULL : ssh_aes ## bits ## _gcm ## impl_c ## ssh2_id, \
  126. /*.blksize =*/ 16, \
  127. /*.real_keybits =*/ bits, \
  128. /*.padded_keybytes =*/ bits/8, \
  129. /*.flags =*/ SSH_CIPHER_SEPARATE_LENGTH, \
  130. /*.text_name =*/ ssh_aes ## bits ## _gcm ## impl_c ## text_name, \
  131. /*.required_mac =*/ &ssh2_aesgcm_mac, \
  132. /*.extra =*/ &aes ## bits ## impl_c ## _extra, \
  133. }
  134. #define AES_ALL_VTABLES(impl_c, impl_display) \
  135. AES_CBC_VTABLE(impl_c, impl_display, 128); \
  136. AES_CBC_VTABLE(impl_c, impl_display, 192); \
  137. AES_CBC_VTABLE(impl_c, impl_display, 256); \
  138. AES_SDCTR_VTABLE(impl_c, impl_display, 128); \
  139. AES_SDCTR_VTABLE(impl_c, impl_display, 192); \
  140. AES_SDCTR_VTABLE(impl_c, impl_display, 256); \
  141. AES_GCM_VTABLE(impl_c, impl_display, 128); \
  142. AES_GCM_VTABLE(impl_c, impl_display, 192); \
  143. AES_GCM_VTABLE(impl_c, impl_display, 256)
  144. /*
  145. * Macros to repeat a piece of code particular numbers of times that
  146. * correspond to 1 fewer than the number of AES rounds. (Because the
  147. * last round is different.)
  148. */
  149. #define REP2(x) x x
  150. #define REP4(x) REP2(REP2(x))
  151. #define REP8(x) REP2(REP4(x))
  152. #define REP9(x) REP8(x) x
  153. #define REP11(x) REP8(x) REP2(x) x
  154. #define REP13(x) REP8(x) REP4(x) x
  155. /*
  156. * The round constants used in key schedule expansion.
  157. */
  158. extern const uint8_t aes_key_setup_round_constants[10];
  159. /*
  160. * The largest number of round keys ever needed.
  161. */
  162. #define MAXROUNDKEYS 15