diff options
Diffstat (limited to 'src/methods/composed_gmac/composed_gmac.c')
-rw-r--r-- | src/methods/composed_gmac/composed_gmac.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/src/methods/composed_gmac/composed_gmac.c b/src/methods/composed_gmac/composed_gmac.c index 887fb5c..6636e49 100644 --- a/src/methods/composed_gmac/composed_gmac.c +++ b/src/methods/composed_gmac/composed_gmac.c @@ -23,37 +23,51 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + \file + + composed-gmac method provider + + composed-gmac combines any cipher (or null) with GMAC, while another cipher is + used to generate the GHASH keys. Combining the null cipher with GMAC allows creating + unencrypted, authenticated-only methods. +*/ + #include "../../crypto.h" #include "../../method.h" #include "../common.h" +/** A block of zeros */ static const fastd_block128_t ZERO_BLOCK = {}; +/** A specific method provided by this provider */ struct fastd_method { - const fastd_cipher_info_t *cipher_info; - const fastd_cipher_info_t *gmac_cipher_info; - const fastd_mac_info_t *ghash_info; + const fastd_cipher_info_t *cipher_info; /**< The cipher used for encryption */ + const fastd_cipher_info_t *gmac_cipher_info; /**< The cipher used for authenticaton */ + const fastd_mac_info_t *ghash_info; /**< GHASH */ }; +/** The method-specific session state */ struct fastd_method_session_state { - fastd_method_common_t common; + fastd_method_common_t common; /**< The common method state */ - const fastd_method_t *method; + const fastd_method_t *method; /**< The specific method used */ - const fastd_cipher_t *cipher; - fastd_cipher_state_t *cipher_state; + const fastd_cipher_t *cipher; /**< The cipher implementation used for encryption */ + fastd_cipher_state_t *cipher_state; /**< The cipher state for encryption */ - const fastd_cipher_t *gmac_cipher; - fastd_cipher_state_t *gmac_cipher_state; + const fastd_cipher_t *gmac_cipher; /**< The cipher implementation used for authentication */ + fastd_cipher_state_t *gmac_cipher_state; /**< The cipher state for authentication */ - const fastd_mac_t *ghash; - fastd_mac_state_t *ghash_state; + const fastd_mac_t *ghash; /**< The GHASH implementation */ + fastd_mac_state_t *ghash_state; /**< The GHASH state */ }; +/** Instanciates a method using a name of the pattern "<cipher>+<cipher>+gmac" (or "<cipher>+<cipher>-gmac" for block ciphers in counter mode, e.g. null+aes128-gmac instead of null+aes128-ctr+gmac) */ static bool method_create_by_name(const char *name, fastd_method_t **method) { fastd_method_t m; @@ -107,15 +121,17 @@ static bool method_create_by_name(const char *name, fastd_method_t **method) { return true; } +/** Frees a method */ static void method_destroy(fastd_method_t *method) { free(method); } - +/** Returns the key length used by a method */ static size_t method_key_length(const fastd_method_t *method) { return method->cipher_info->key_length + method->gmac_cipher_info->key_length; } +/** Initializes a session */ static fastd_method_session_state_t* method_session_init(const fastd_method_t *method, const uint8_t *secret, bool initiator) { fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t)); @@ -148,22 +164,27 @@ static fastd_method_session_state_t* method_session_init(const fastd_method_t *m return session; } +/** Checks if the session is currently valid */ static bool method_session_is_valid(fastd_method_session_state_t *session) { return (session && fastd_method_session_common_is_valid(&session->common)); } +/** Checks if this side is the initator of the session */ static bool method_session_is_initiator(fastd_method_session_state_t *session) { return fastd_method_session_common_is_initiator(&session->common); } +/** Checks if the session should be refreshed */ static bool method_session_want_refresh(fastd_method_session_state_t *session) { return fastd_method_session_common_want_refresh(&session->common); } +/** Marks the session as superseded */ static void method_session_superseded(fastd_method_session_state_t *session) { fastd_method_session_common_superseded(&session->common); } +/** Frees the session state */ static void method_session_free(fastd_method_session_state_t *session) { if (session) { session->cipher->free(session->cipher_state); @@ -174,6 +195,7 @@ static void method_session_free(fastd_method_session_state_t *session) { } } +/** Writes the size of the input in bits to a block (in a way different from the generic-gmac methods) */ static inline void put_size(fastd_block128_t *out, size_t len) { memset(out, 0, sizeof(fastd_block128_t)); out->b[3] = len >> 29; @@ -183,6 +205,7 @@ static inline void put_size(fastd_block128_t *out, size_t len) { out->b[7] = len << 3; } +/** Encrypts and authenticates a packet */ static bool method_encrypt(fastd_peer_t *peer UNUSED, fastd_method_session_state_t *session, fastd_buffer_t *out, fastd_buffer_t in) { size_t tail_len = alignto(in.len, sizeof(fastd_block128_t))-in.len; *out = fastd_buffer_alloc(sizeof(fastd_block128_t)+in.len, alignto(COMMON_HEADBYTES, 16), sizeof(fastd_block128_t)+tail_len); @@ -232,6 +255,7 @@ static bool method_encrypt(fastd_peer_t *peer UNUSED, fastd_method_session_state return true; } +/** Verifies and decrypts a packet */ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *session, fastd_buffer_t *out, fastd_buffer_t in) { if (in.len < COMMON_HEADBYTES+sizeof(fastd_block128_t)) return false; @@ -294,6 +318,8 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses return true; } + +/** The composed-gmac method provider */ const fastd_method_provider_t fastd_method_composed_gmac = { .max_overhead = COMMON_HEADBYTES + sizeof(fastd_block128_t), .min_encrypt_head_space = 0, |