1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00
putty-source/crypto/aes.h
Simon Tatham 840043f06e Add 'next_message' methods to cipher and MAC vtables.
This provides a convenient hook to be called between SSH messages, for
the crypto components to do any per-message processing like
incrementing a sequence number.
2022-08-16 18:27:06 +01:00

112 lines
4.8 KiB
C

/*
* 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;
};
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;
}
/*
* 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(impl_c) \
static struct aes_extra_mutable aes ## impl_c ## _extra_mut; \
static const struct aes_extra aes ## impl_c ## _extra = { \
.check_available = aes ## impl_c ## _available, \
.mut = &aes ## impl_c ## _extra_mut, \
}
#define AES_CBC_VTABLE(impl_c, impl_display, bits) \
const ssh_cipheralg ssh_aes ## bits ## _cbc ## impl_c = { \
.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, \
.next_message = nullcipher_next_message, \
.ssh2_id = "aes" #bits "-cbc", \
.blksize = 16, \
.real_keybits = bits, \
.padded_keybytes = bits/8, \
.flags = SSH_CIPHER_IS_CBC, \
.text_name = "AES-" #bits " CBC (" impl_display ")", \
.extra = &aes ## impl_c ## _extra, \
}
#define AES_SDCTR_VTABLE(impl_c, impl_display, bits) \
const ssh_cipheralg ssh_aes ## bits ## _sdctr ## impl_c = { \
.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, \
.next_message = nullcipher_next_message, \
.ssh2_id = "aes" #bits "-ctr", \
.blksize = 16, \
.real_keybits = bits, \
.padded_keybytes = bits/8, \
.flags = 0, \
.text_name = "AES-" #bits " SDCTR (" impl_display ")", \
.extra = &aes ## 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)
/*
* 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