summaryrefslogtreecommitdiffstats
path: root/src/methods
diff options
context:
space:
mode:
Diffstat (limited to 'src/methods')
-rw-r--r--src/methods/cipher_test/cipher_test.c35
-rw-r--r--src/methods/composed_gmac/composed_gmac.c50
-rw-r--r--src/methods/generic_gmac/generic_gmac.c41
-rw-r--r--src/methods/generic_poly1305/generic_poly1305.c38
-rw-r--r--src/methods/methods.c.in8
-rw-r--r--src/methods/null/null.c28
-rw-r--r--src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c39
7 files changed, 204 insertions, 35 deletions
diff --git a/src/methods/cipher_test/cipher_test.c b/src/methods/cipher_test/cipher_test.c
index 52bca0f..7e064ba 100644
--- a/src/methods/cipher_test/cipher_test.c
+++ b/src/methods/cipher_test/cipher_test.c
@@ -23,25 +23,37 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ cipher-test method provider (testing and benchmarking only)
+
+ The cipher-test method provider performs encryption only and can be used to test
+ and benchmark cipher implementations.
+*/
+
#include "../../crypto.h"
#include "../../method.h"
#include "../common.h"
+/** A specific method provided by this provider */
struct fastd_method {
- const fastd_cipher_info_t *cipher_info;
+ const fastd_cipher_info_t *cipher_info; /**< The cipher used */
};
+/** 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_cipher_t *cipher;
- fastd_cipher_state_t *cipher_state;
+ const fastd_method_t *method; /**< The specific method used */
+ const fastd_cipher_t *cipher; /**< The cipher implementation used */
+ fastd_cipher_state_t *cipher_state; /**< The cipher state */
};
+/** Instanciates a method using a name of the pattern "<cipher>+cipher-test" */
static bool method_create_by_name(const char *name, fastd_method_t **method) {
fastd_method_t m;
@@ -66,14 +78,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;
}
+/** 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));
@@ -87,22 +102,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);
@@ -110,6 +130,8 @@ static void method_session_free(fastd_method_session_state_t *session) {
}
}
+
+/** Encrypts a packet and adds the common method header */
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(in.len, alignto(COMMON_HEADBYTES, 16), sizeof(fastd_block128_t)+tail_len);
@@ -140,6 +162,7 @@ static bool method_encrypt(fastd_peer_t *peer UNUSED, fastd_method_session_state
return true;
}
+/** 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)
return false;
@@ -184,6 +207,8 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
return true;
}
+
+/** The cipher-test method provider */
const fastd_method_provider_t fastd_method_cipher_test = {
.max_overhead = COMMON_HEADBYTES,
.min_encrypt_head_space = 0,
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,
diff --git a/src/methods/generic_gmac/generic_gmac.c b/src/methods/generic_gmac/generic_gmac.c
index 6b84a95..546cd50 100644
--- a/src/methods/generic_gmac/generic_gmac.c
+++ b/src/methods/generic_gmac/generic_gmac.c
@@ -23,30 +23,41 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ generic-gmac method provider
+
+ generic-gmac can combine any stream cipher with the GMAC authentication.
+*/
+
#include "../../crypto.h"
#include "../../method.h"
#include "../common.h"
+/** A specific method provided by this provider */
struct fastd_method {
- const fastd_cipher_info_t *cipher_info;
- const fastd_mac_info_t *ghash_info;
+ const fastd_cipher_info_t *cipher_info; /**< The cipher used */
+ 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 */
+ fastd_cipher_state_t *cipher_state; /**< The cipher state */
- 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>+gmac" (or "<cipher>-gcm" for block ciphers in counter mode, e.g. aes128-gcm instead of aes128-ctr+gmac) */
static bool method_create_by_name(const char *name, fastd_method_t **method) {
fastd_method_t m;
@@ -85,14 +96,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;
}
+/** 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));
@@ -121,22 +135,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);
@@ -146,6 +165,7 @@ static void method_session_free(fastd_method_session_state_t *session) {
}
}
+/** Writes the size of the input in bits to a block */
static inline void put_size(fastd_block128_t *out, size_t len) {
memset(out, 0, sizeof(fastd_block128_t));
out->b[11] = len >> 29;
@@ -155,6 +175,8 @@ static inline void put_size(fastd_block128_t *out, size_t len) {
out->b[15] = 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) {
fastd_buffer_pull_head_zero(&in, sizeof(fastd_block128_t));
@@ -199,6 +221,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;
@@ -255,6 +278,8 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
return true;
}
+
+/** The generic-gmac method provider */
const fastd_method_provider_t fastd_method_generic_gmac = {
.max_overhead = COMMON_HEADBYTES + sizeof(fastd_block128_t),
.min_encrypt_head_space = sizeof(fastd_block128_t),
diff --git a/src/methods/generic_poly1305/generic_poly1305.c b/src/methods/generic_poly1305/generic_poly1305.c
index 0e2641c..142b50e 100644
--- a/src/methods/generic_poly1305/generic_poly1305.c
+++ b/src/methods/generic_poly1305/generic_poly1305.c
@@ -23,6 +23,15 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ generic-poly1305 method provider
+
+ The Poly1305 authenticator is very secure, but for performance reasons
+ not really recommendable on embedded systems.
+*/
+
#include "../../crypto.h"
#include "../../method.h"
@@ -31,23 +40,29 @@
#include <crypto_onetimeauth_poly1305.h>
+/** The length of the key used by Poly1305 */
#define KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
+
+/** The length of the authentication tag */
#define TAGBYTES crypto_onetimeauth_poly1305_BYTES
+/** A specific method provided by this provider */
struct fastd_method {
- const fastd_cipher_info_t *cipher_info;
+ const fastd_cipher_info_t *cipher_info; /**< The cipher used */
};
+/** 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_cipher_t *cipher;
- fastd_cipher_state_t *cipher_state;
+ const fastd_method_t *method; /**< The specific method used */
+ const fastd_cipher_t *cipher; /**< The cipher implementation used */
+ fastd_cipher_state_t *cipher_state; /**< The cipher state */
};
+/** Instanciates a method using a name of the pattern "<cipher>+poly1305" */
static bool method_create_by_name(const char *name, fastd_method_t **method) {
fastd_method_t m;
@@ -75,14 +90,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;
}
+/** 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));
@@ -94,22 +112,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);
@@ -117,6 +140,8 @@ static void method_session_free(fastd_method_session_state_t *session) {
}
}
+
+/** 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) {
fastd_buffer_pull_head_zero(&in, KEYBYTES);
@@ -155,6 +180,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+TAGBYTES)
return false;
@@ -217,6 +243,8 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
return true;
}
+
+/** The generic-poly1305 method provider */
const fastd_method_provider_t fastd_method_generic_poly1305 = {
.max_overhead = COMMON_HEADBYTES + TAGBYTES,
.min_encrypt_head_space = KEYBYTES,
diff --git a/src/methods/methods.c.in b/src/methods/methods.c.in
index 914d929..672ef70 100644
--- a/src/methods/methods.c.in
+++ b/src/methods/methods.c.in
@@ -23,16 +23,24 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Generated list of supported method providers
+*/
+
#include <src/method.h>
@METHOD_DEFINITIONS@
+/** The list of method providers */
static const fastd_method_provider_t *const providers[] = { @METHOD_LIST@
};
+/** Searches for a provider providing a method and instanciates it */
bool fastd_method_create_by_name(const char *name, const fastd_method_provider_t **provider, fastd_method_t **method) {
size_t i;
for (i = 0; i < array_size(providers); i++) {
diff --git a/src/methods/null/null.c b/src/methods/null/null.c
index 76fd961..3062fcf 100644
--- a/src/methods/null/null.c
+++ b/src/methods/null/null.c
@@ -23,27 +23,37 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ The null method not providing any encryption or authenticaton
+*/
#include "../../method.h"
+/** The session state */
struct fastd_method_session_state {
- bool valid;
- bool initiator;
+ bool valid; /**< true if the session has not been invalidated */
+ bool initiator; /**< true if this side is the initiator of the session */
};
+/** Returns true if the name is "null" */
static bool method_create_by_name(const char *name, fastd_method_t **method UNUSED) {
return !strcmp(name, "null");
}
+/** Does nothing as the null provider provides only a single method */
static void method_destroy(fastd_method_t *method UNUSED) {
}
+/** Returns 0 */
static size_t method_key_length(const fastd_method_t *method UNUSED) {
return 0;
}
+/** Initiates a new null session */
static fastd_method_session_state_t* method_session_init(const fastd_method_t *method UNUSED, const uint8_t *secret UNUSED, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
@@ -53,35 +63,49 @@ static fastd_method_session_state_t* method_session_init(const fastd_method_t *m
return session;
}
+/** Initiates a new null session (pre-v11 compat handshake) */
static fastd_method_session_state_t* method_session_init_compat(const fastd_method_t *method, const uint8_t *secret, size_t length UNUSED, bool initiator) {
return method_session_init(method, secret, initiator);
}
+/** Checks if the session is valid */
static bool method_session_is_valid(fastd_method_session_state_t *session) {
return (session && session->valid);
}
+/** Checks if this side is the initiator of the session */
static bool method_session_is_initiator(fastd_method_session_state_t *session) {
return (session->initiator);
}
+/** Returns false */
static bool method_session_want_refresh(fastd_method_session_state_t *session UNUSED) {
return false;
}
+/**
+ Marks the session as invalid
+
+ The session in invalidated without any delay to prevent packets of the new session being
+ mistaken to be valid for the old session
+*/
static void method_session_superseded(fastd_method_session_state_t *session) {
session->valid = false;
}
+/** Frees the session state */
static void method_session_free(fastd_method_session_state_t *session) {
free(session);
}
+/** Just returns the input buffer as the output */
static bool method_passthrough(fastd_peer_t *peer UNUSED, fastd_method_session_state_t *session UNUSED, fastd_buffer_t *out, fastd_buffer_t in) {
*out = in;
return true;
}
+
+/** The null method provider */
const fastd_method_provider_t fastd_method_null = {
.max_overhead = 0,
.min_encrypt_head_space = 0,
diff --git a/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c b/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
index f06e0f8..9f2d61c 100644
--- a/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
+++ b/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
@@ -23,6 +23,16 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ The xsalsa20-poly1305 method provider (deprecated)
+
+ This provider is included for compatiblity reasons as pre-v11
+ xsalsa20-poly1305 was the recommended method. In new setups salsa20+poly1305
+ provided by the generic-poly1305 provider should be used as a replacement.
+*/
+
#include "../../crypto.h"
#include "../../method.h"
@@ -31,24 +41,29 @@
#include <crypto_secretbox_xsalsa20poly1305.h>
+/** The session state */
struct fastd_method_session_state {
- fastd_method_common_t common;
+ fastd_method_common_t common; /**< The common method state */
- uint8_t key[crypto_secretbox_xsalsa20poly1305_KEYBYTES] __attribute__((aligned(8)));
+ uint8_t key[crypto_secretbox_xsalsa20poly1305_KEYBYTES] __attribute__((aligned(8))); /**< The encryption key */
};
+/** Matches the method name "xsalsa20-poly1305" */
static bool method_create_by_name(const char *name, fastd_method_t **method UNUSED) {
return !strcmp(name, "xsalsa20-poly1305");
}
+/** Does nothing as this provider has only a single method */
static void method_destroy(fastd_method_t *method UNUSED) {
}
+/** Returns the key length used by xsalsa20-poly1305 */
static size_t method_key_length(const fastd_method_t *method UNUSED) {
return crypto_secretbox_xsalsa20poly1305_KEYBYTES;
}
+/** Initializes the session state */
static fastd_method_session_state_t* method_session_init(const fastd_method_t *method UNUSED, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
@@ -59,6 +74,7 @@ static fastd_method_session_state_t* method_session_init(const fastd_method_t *m
return session;
}
+/** Initializes the session state (pre-v11 compat handshake) */
static fastd_method_session_state_t* method_session_init_compat(const fastd_method_t *method, const uint8_t *secret, size_t length, bool initiator) {
if (length < crypto_secretbox_xsalsa20poly1305_KEYBYTES)
exit_bug("xsalsa20-poly1305: tried to init with short secret");
@@ -66,22 +82,27 @@ static fastd_method_session_state_t* method_session_init_compat(const fastd_meth
return method_session_init(method, secret, initiator);
}
+/** Checks if a 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 initiator 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) {
secure_memzero(session, sizeof(fastd_method_session_state_t));
@@ -90,12 +111,19 @@ static void method_session_free(fastd_method_session_state_t *session) {
}
+/**
+ Copies a nonce of length COMMON_NONCEBYTES to a buffer, reversing its byte order
+
+ To maintain compability with pre-v11 versions, which used a little-endian nonce,
+ the xsalsa20-poly1305 keeps using the old nonce format.
+*/
static inline void memcpy_nonce(uint8_t *dst, const uint8_t *src) {
size_t i;
for (i = 0; i < COMMON_NONCEBYTES; i++)
dst[i] = src[COMMON_NONCEBYTES-i-1];
}
+/** Adds the xsalsa20-poly1305 header to the head of a packet */
static inline void put_header(fastd_buffer_t *buffer, const uint8_t nonce[COMMON_NONCEBYTES], uint8_t flags) {
fastd_buffer_pull_head_from(buffer, &flags, 1);
@@ -103,19 +131,22 @@ static inline void put_header(fastd_buffer_t *buffer, const uint8_t nonce[COMMON
memcpy_nonce(buffer->data, nonce);
}
+/** Removes the xsalsa20-poly1305 header from the head of a packet */
static inline void take_header(fastd_buffer_t *buffer, uint8_t nonce[COMMON_NONCEBYTES], uint8_t *flags) {
- memcpy_nonce(nonce, buffer->data );
+ memcpy_nonce(nonce, buffer->data);
fastd_buffer_push_head(buffer, COMMON_NONCEBYTES);
fastd_buffer_push_head_to(buffer, flags, 1);
}
+/** Removes and handles the xsalsa20-poly1305 header from the head of a packet */
static inline bool handle_header(const fastd_method_common_t *session, fastd_buffer_t *buffer, uint8_t nonce[COMMON_NONCEBYTES], uint8_t *flags, int64_t *age) {
take_header(buffer, nonce, flags);
return fastd_method_is_nonce_valid(session, nonce, age);
}
+/** Performs encryption and authentication of 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) {
fastd_buffer_pull_head_zero(&in, crypto_secretbox_xsalsa20poly1305_ZEROBYTES);
@@ -135,6 +166,7 @@ static bool method_encrypt(fastd_peer_t *peer UNUSED, fastd_method_session_state
return true;
}
+/** Performs validation and decryption of 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)
return false;
@@ -180,6 +212,7 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
}
+/** The xsalsa20-poly1305 method provider */
const fastd_method_provider_t fastd_method_xsalsa20_poly1305 = {
.max_overhead = COMMON_HEADBYTES + crypto_secretbox_xsalsa20poly1305_ZEROBYTES - crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES,