| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | 
							- /*
 
-  * Definitions likely to be helpful to multiple AES implementations.
 
-  */
 
- /*
 
-  * The 'extra' structure used by AES implementations is used to
 
-  * include information about how to check if a given implementation is
 
-  * available at run time, and whether we've already checked.
 
-  */
 
- struct aes_extra_mutable;
 
- struct aes_extra {
 
-     /* Function to check availability. Might be expensive, so we don't
 
-      * want to call it more than once. */
 
-     bool (*check_available)(void);
 
-     /* Point to a writable substructure. */
 
-     struct aes_extra_mutable *mut;
 
-     /* Extra API function specific to AES, to encrypt a single block
 
-      * in ECB mode without touching the IV. Used by AES-GCM MAC
 
-      * setup. */
 
-     void (*encrypt_ecb_block)(ssh_cipher *, void *);
 
- };
 
- struct aes_extra_mutable {
 
-     bool checked_availability;
 
-     bool is_available;
 
- };
 
- static inline bool check_availability(const struct aes_extra *extra)
 
- {
 
-     if (!extra->mut->checked_availability) {
 
-         extra->mut->is_available = extra->check_available();
 
-         extra->mut->checked_availability = true;
 
-     }
 
-     return extra->mut->is_available;
 
- }
 
- /* Shared stub function for all the AES-GCM vtables. */
 
- void aesgcm_cipher_crypt_length(
 
-     ssh_cipher *cipher, void *blk, int len, unsigned long seq);
 
- /* External entry point for the encrypt_ecb_block function. */
 
- static inline void aes_encrypt_ecb_block(ssh_cipher *ciph, void *blk)
 
- {
 
-     const struct aes_extra *extra = ciph->vt->extra;
 
-     extra->encrypt_ecb_block(ciph, blk);
 
- }
 
- /*
 
-  * Macros to define vtables for AES variants. There are a lot of
 
-  * these, because of the cross product between cipher modes, key
 
-  * sizes, and assorted HW/SW implementations, so it's worth spending
 
-  * some effort here to reduce the boilerplate in the sub-files.
 
-  */
 
- #define AES_EXTRA_BITS(impl_c, bits)                                    \
 
-     static struct aes_extra_mutable aes ## impl_c ## _extra_mut;        \
 
-     static const struct aes_extra aes ## bits ## impl_c ## _extra = {   \
 
-         /* WINSCP */ \
 
-         /*.check_available =*/ aes ## impl_c ## _available,                 \
 
-         /*.mut =*/ &aes ## impl_c ## _extra_mut,                            \
 
-         /*.encrypt_ecb_block =*/ &aes ## bits ## impl_c ## _encrypt_ecb_block, \
 
-     }
 
- #define AES_EXTRA(impl_c)                       \
 
-     AES_EXTRA_BITS(impl_c, 128);                \
 
-     AES_EXTRA_BITS(impl_c, 192);                \
 
-     AES_EXTRA_BITS(impl_c, 256)
 
- // WINSCP string constants are for avoiding 
 
- // Warning 1060: Different alignments specified for same segment, %s. Using highest alignment.rdata
 
- // in objconv
 
- #define AES_CBC_VTABLE(impl_c, impl_display, bits)                      \
 
-     const char ssh_aes ## bits ## _cbc ## impl_c ## ssh2_id[] = "aes" #bits "-cbc"; /*WINSCP*/ \
 
-     const char ssh_aes ## bits ## _cbc ## impl_c ## text_name[] = "AES-" #bits " CBC (" impl_display ")"; /*WINSCP*/ \
 
-     const ssh_cipheralg ssh_aes ## bits ## _cbc ## impl_c = {           \
 
-         /*WINSCP*/ \
 
-         /*.new =*/ aes ## impl_c ## _new,                                   \
 
-         /*.free =*/ aes ## impl_c ## _free,                                 \
 
-         /*.setiv =*/ aes ## impl_c ## _setiv_cbc,                           \
 
-         /*.setkey =*/ aes ## impl_c ## _setkey,                             \
 
-         /*.encrypt =*/ aes ## bits ## impl_c ## _cbc_encrypt,               \
 
-         /*.decrypt =*/ aes ## bits ## impl_c ## _cbc_decrypt,               \
 
-         NULL, \
 
-         NULL, \
 
-         /*.next_message =*/ nullcipher_next_message,                        \
 
-         /*.ssh2_id =*/ ssh_aes ## bits ## _cbc ## impl_c ## ssh2_id, /*WINSCP*/ \
 
-         /*.blksize =*/ 16,                                                  \
 
-         /*.real_keybits =*/ bits,                                           \
 
-         /*.padded_keybytes =*/ bits/8,                                      \
 
-         /*.flags =*/ SSH_CIPHER_IS_CBC,                                     \
 
-         /*.text_name =*/ ssh_aes ## bits ## _cbc ## impl_c ## text_name, /*WINSCP*/ \
 
-         NULL, \
 
-         /*.extra =*/ &aes ## bits ## impl_c ## _extra,                              \
 
-     }
 
- #define AES_SDCTR_VTABLE(impl_c, impl_display, bits)                    \
 
-     const char ssh_aes ## bits ## _sdctr ## impl_c ## ssh2_id[] = "aes" #bits "-ctr"; /*WINSCP*/ \
 
-     const char ssh_aes ## bits ## _sdctr ## impl_c ## text_name[] = "AES-" #bits " SDCTR (" impl_display ")"; /*WINSCP*/ \
 
-     const ssh_cipheralg ssh_aes ## bits ## _sdctr ## impl_c = {         \
 
-         /*WINSCP*/ \
 
-         /*.new =*/ aes ## impl_c ## _new,                                   \
 
-         /*.free =*/ aes ## impl_c ## _free,                                 \
 
-         /*.setiv =*/ aes ## impl_c ## _setiv_sdctr,                         \
 
-         /*.setkey =*/ aes ## impl_c ## _setkey,                             \
 
-         /*.encrypt =*/ aes ## bits ## impl_c ## _sdctr,                     \
 
-         /*.decrypt =*/ aes ## bits ## impl_c ## _sdctr,                     \
 
-         NULL, \
 
-         NULL, \
 
-         /*.next_message =*/ nullcipher_next_message,                        \
 
-         /*.ssh2_id =*/ ssh_aes ## bits ## _sdctr ## impl_c ## ssh2_id, /*WINSCP*/ \
 
-         /*.blksize =*/ 16,                                                  \
 
-         /*.real_keybits =*/ bits,                                           \
 
-         /*.padded_keybytes =*/ bits/8,                                      \
 
-         /*.flags =*/ 0,                                                     \
 
-         /*.text_name =*/ ssh_aes ## bits ## _sdctr ## impl_c ## text_name, /*WINSCP*/ \
 
-         NULL, \
 
-         /*.extra =*/ &aes ## bits ## impl_c ## _extra,                      \
 
-     }
 
- #define AES_GCM_VTABLE(impl_c, impl_display, bits)                      \
 
-     const char ssh_aes ## bits ## _gcm ## impl_c ## ssh2_id[] = "aes" #bits "[email protected]"; /*WINSCP*/ \
 
-     const char ssh_aes ## bits ## _gcm ## impl_c ## text_name[] = "AES-" #bits " GCM (" impl_display ")"; /*WINSCP*/ \
 
-     const ssh_cipheralg ssh_aes ## bits ## _gcm ## impl_c = {           \
 
-         /*.new =*/ aes ## impl_c ## _new,                                   \
 
-         /*.free =*/ aes ## impl_c ## _free,                                 \
 
-         /*.setiv =*/ aes ## impl_c ## _setiv_gcm,                           \
 
-         /*.setkey =*/ aes ## impl_c ## _setkey,                             \
 
-         /*.encrypt =*/ aes ## bits ## impl_c ## _gcm,                       \
 
-         /*.decrypt =*/ aes ## bits ## impl_c ## _gcm,                       \
 
-         /*.encrypt_length =*/ aesgcm_cipher_crypt_length,                   \
 
-         /*.decrypt_length =*/ aesgcm_cipher_crypt_length,                   \
 
-         /*.next_message =*/ aes ## impl_c ## _next_message_gcm,             \
 
-         /* 192-bit AES-GCM is included only so that testcrypt can run   \
 
-          * standard test vectors against it. OpenSSH doesn't define a   \
 
-          * protocol id for it. So we set its ssh2_id to NULL. */        \
 
-         /*.ssh2_id =*/ bits==192 ? NULL : ssh_aes ## bits ## _gcm ## impl_c ## ssh2_id,   \
 
-         /*.blksize =*/ 16,                                                  \
 
-         /*.real_keybits =*/ bits,                                           \
 
-         /*.padded_keybytes =*/ bits/8,                                      \
 
-         /*.flags =*/ SSH_CIPHER_SEPARATE_LENGTH,                            \
 
-         /*.text_name =*/ ssh_aes ## bits ## _gcm ## impl_c ## text_name,            \
 
-         /*.required_mac =*/ &ssh2_aesgcm_mac,                               \
 
-         /*.extra =*/ &aes ## bits ## impl_c ## _extra,                      \
 
-     }
 
- #define AES_ALL_VTABLES(impl_c, impl_display)           \
 
-     AES_CBC_VTABLE(impl_c, impl_display, 128);          \
 
-     AES_CBC_VTABLE(impl_c, impl_display, 192);          \
 
-     AES_CBC_VTABLE(impl_c, impl_display, 256);          \
 
-     AES_SDCTR_VTABLE(impl_c, impl_display, 128);        \
 
-     AES_SDCTR_VTABLE(impl_c, impl_display, 192);        \
 
-     AES_SDCTR_VTABLE(impl_c, impl_display, 256);        \
 
-     AES_GCM_VTABLE(impl_c, impl_display, 128);          \
 
-     AES_GCM_VTABLE(impl_c, impl_display, 192);          \
 
-     AES_GCM_VTABLE(impl_c, impl_display, 256)
 
- /*
 
-  * Macros to repeat a piece of code particular numbers of times that
 
-  * correspond to 1 fewer than the number of AES rounds. (Because the
 
-  * last round is different.)
 
-  */
 
- #define REP2(x) x x
 
- #define REP4(x) REP2(REP2(x))
 
- #define REP8(x) REP2(REP4(x))
 
- #define REP9(x) REP8(x) x
 
- #define REP11(x) REP8(x) REP2(x) x
 
- #define REP13(x) REP8(x) REP4(x) x
 
- /*
 
-  * The round constants used in key schedule expansion.
 
-  */
 
- extern const uint8_t aes_key_setup_round_constants[10];
 
- /*
 
-  * The largest number of round keys ever needed.
 
-  */
 
- #define MAXROUNDKEYS 15
 
 
  |