/* * Common parts of the state structure for AESGCM MAC implementations. */ #define AESGCM_COMMON_FIELDS \ ssh_cipher *cipher; \ unsigned char partblk[16]; \ size_t skiplen, aadlen, ciphertextlen; \ size_t skipgot, aadgot, partlen; \ BinarySink_IMPLEMENTATION; \ ssh2_mac mac /* * The 'extra' structure 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 aesgcm_extra_mutable; struct aesgcm_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 aesgcm_extra_mutable *mut; /* * Extra API function specific to this MAC type that allows * testcrypt to set more general lengths for skiplen and aadlen. */ void (*set_prefix_lengths)(ssh2_mac *mac, size_t skip, size_t aad); }; struct aesgcm_extra_mutable { bool checked_availability; bool is_available; }; static inline bool check_aesgcm_availability(const struct aesgcm_extra *extra) { if (!extra->mut->checked_availability) { extra->mut->is_available = extra->check_available(); extra->mut->checked_availability = true; } return extra->mut->is_available; }