summaryrefslogtreecommitdiffstats
path: root/src/methods/composed_gmac/composed_gmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/methods/composed_gmac/composed_gmac.c')
-rw-r--r--src/methods/composed_gmac/composed_gmac.c50
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,