From cb7b83017d4ccc20e059f987012bcfa1d12b2615 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 23 Oct 2018 11:26:02 +0200 Subject: [PATCH] botan: Add support for ChaCha20/Poly1305 AEAD algorithm --- src/libstrongswan/plugins/botan/Makefile.am | 2 +- .../botan/{botan_gcm.c => botan_aead.c} | 148 +++++++++++------- .../botan/{botan_gcm.h => botan_aead.h} | 17 +- .../plugins/botan/botan_plugin.c | 13 +- 4 files changed, 112 insertions(+), 68 deletions(-) rename src/libstrongswan/plugins/botan/{botan_gcm.c => botan_aead.c} (77%) rename src/libstrongswan/plugins/botan/{botan_gcm.h => botan_aead.h} (81%) diff --git a/src/libstrongswan/plugins/botan/Makefile.am b/src/libstrongswan/plugins/botan/Makefile.am index 6e5af362e1..30d3e601c5 100644 --- a/src/libstrongswan/plugins/botan/Makefile.am +++ b/src/libstrongswan/plugins/botan/Makefile.am @@ -27,7 +27,7 @@ libstrongswan_botan_la_SOURCES = \ botan_ed_private_key.h botan_ed_private_key.c \ botan_util.h botan_util.c \ botan_util_keys.h botan_util_keys.c \ - botan_gcm.h botan_gcm.c \ + botan_aead.h botan_aead.c \ botan_x25519.h botan_x25519.c libstrongswan_botan_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/botan/botan_gcm.c b/src/libstrongswan/plugins/botan/botan_aead.c similarity index 77% rename from src/libstrongswan/plugins/botan/botan_gcm.c rename to src/libstrongswan/plugins/botan/botan_aead.c index 7e0fc1468a..16676bde5b 100644 --- a/src/libstrongswan/plugins/botan/botan_gcm.c +++ b/src/libstrongswan/plugins/botan/botan_aead.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2018 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2018 Atanas Filyanov * Rohde & Schwarz Cybersecurity GmbH * @@ -21,23 +24,24 @@ * THE SOFTWARE. */ -#include "botan_gcm.h" +#include "botan_aead.h" #include -#ifdef BOTAN_HAS_AES -#ifdef BOTAN_HAS_AEAD_GCM +#if (defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM)) || \ + defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) #include #include /** - * as defined in RFC 4106 + * As defined in RFC 4106 (GCM) and RFC 7634 (ChaPoly) */ -#define IV_LEN 8 -#define SALT_LEN 4 -#define NONCE_LEN (IV_LEN + SALT_LEN) +#define IV_LEN 8 +#define SALT_LEN 4 +#define NONCE_LEN (IV_LEN + SALT_LEN) +#define CHAPOLY_KEY_LEN 32 typedef struct private_aead_t private_aead_t; @@ -77,8 +81,8 @@ struct private_aead_t { /** * Do the actual en/decryption */ -static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv, - u_char *out, uint32_t init_flag) +static bool do_crypt(private_aead_t *this, chunk_t data, chunk_t assoc, + chunk_t iv, u_char *out, uint32_t init_flag) { botan_cipher_t cipher; uint8_t nonce[NONCE_LEN]; @@ -149,7 +153,8 @@ METHOD(aead_t, encrypt, bool, *encrypted = chunk_alloc(plain.len + this->icv_size); out = encrypted->ptr; } - return crypt(this, plain, assoc, iv, out, BOTAN_CIPHER_INIT_FLAG_ENCRYPT); + return do_crypt(this, plain, assoc, iv, out, + BOTAN_CIPHER_INIT_FLAG_ENCRYPT); } METHOD(aead_t, decrypt, bool, @@ -170,8 +175,8 @@ METHOD(aead_t, decrypt, bool, *plain = chunk_alloc(encrypted.len); out = plain->ptr; } - return crypt(this, encrypted, assoc, iv, out, - BOTAN_CIPHER_INIT_FLAG_DECRYPT); + return do_crypt(this, encrypted, assoc, iv, out, + BOTAN_CIPHER_INIT_FLAG_DECRYPT); } METHOD(aead_t, get_block_size, size_t, @@ -224,43 +229,19 @@ METHOD(aead_t, destroy, void, free(this); } -/* - * Described in header +#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM) + +/** + * Determine the cipher name and ICV size for the given algorithm and key size */ -aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, - size_t salt_size) +static bool determine_gcm_params(private_aead_t *this, + encryption_algorithm_t algo, size_t key_size) { - private_aead_t *this; - - INIT(this, - .public = { - .encrypt = _encrypt, - .decrypt = _decrypt, - .get_block_size = _get_block_size, - .get_icv_size = _get_icv_size, - .get_iv_size = _get_iv_size, - .get_iv_gen = _get_iv_gen, - .get_key_size = _get_key_size, - .set_key = _set_key, - .destroy = _destroy, - }, - ); - - if (salt_size && salt_size != SALT_LEN) - { - /* currently not supported */ - free(this); - return NULL; - } - switch (algo) { case ENCR_AES_GCM_ICV8: switch (key_size) { - case 0: - key_size = 16; - /* FALL */ case 16: this->cipher_name = "AES-128/GCM(8)"; break; @@ -271,17 +252,13 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, this->cipher_name = "AES-256/GCM(8)"; break; default: - free(this); - return NULL; + return FALSE; } this->icv_size = 8; - break; + return TRUE; case ENCR_AES_GCM_ICV12: switch (key_size) { - case 0: - key_size = 16; - /* FALL */ case 16: this->cipher_name = "AES-128/GCM(12)"; break; @@ -292,17 +269,13 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, this->cipher_name = "AES-256/GCM(12)"; break; default: - free(this); - return NULL; + return FALSE; } this->icv_size = 12; - break; + return TRUE; case ENCR_AES_GCM_ICV16: switch (key_size) { - case 0: - key_size = 16; - /* FALL */ case 16: this->cipher_name = "AES-128/GCM"; break; @@ -313,11 +286,73 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, this->cipher_name = "AES-256/GCM"; break; default: - free(this); - return NULL; + return FALSE; } this->icv_size = 16; + return TRUE; + default: + return FALSE; + } +} +#endif + +/* + * Described in header + */ +aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size, + size_t salt_size) +{ + private_aead_t *this; + + INIT(this, + .public = { + .encrypt = _encrypt, + .decrypt = _decrypt, + .get_block_size = _get_block_size, + .get_icv_size = _get_icv_size, + .get_iv_size = _get_iv_size, + .get_iv_gen = _get_iv_gen, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + ); + + if (salt_size && salt_size != SALT_LEN) + { + free(this); + return NULL; + } + + switch (algo) + { +#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM) + case ENCR_AES_GCM_ICV8: + case ENCR_AES_GCM_ICV12: + case ENCR_AES_GCM_ICV16: + if (!key_size) + { + key_size = 16; + } + if (!determine_gcm_params(this, algo, key_size)) + { + free(this); + return NULL; + } break; +#endif +#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305 + case ENCR_CHACHA20_POLY1305: + if (key_size && key_size != CHAPOLY_KEY_LEN) + { + free(this); + return NULL; + } + key_size = CHAPOLY_KEY_LEN; + this->cipher_name = "ChaCha20Poly1305"; + this->icv_size = 16; + break; +#endif default: free(this); return NULL; @@ -330,4 +365,3 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, } #endif -#endif diff --git a/src/libstrongswan/plugins/botan/botan_gcm.h b/src/libstrongswan/plugins/botan/botan_aead.h similarity index 81% rename from src/libstrongswan/plugins/botan/botan_gcm.h rename to src/libstrongswan/plugins/botan/botan_aead.h index b2053cb4d9..00a2ba4bce 100644 --- a/src/libstrongswan/plugins/botan/botan_gcm.h +++ b/src/libstrongswan/plugins/botan/botan_aead.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2018 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2018 Atanas Filyanov * Rohde & Schwarz Cybersecurity GmbH * @@ -22,14 +25,14 @@ */ /** - * Implements the aead_t interface using Botan in GCM mode. + * Implements the aead_t interface using Botan. * - * @defgroup botan_gcm botan_gcm + * @defgroup botan_aead botan_aead * @{ @ingroup botan_p */ -#ifndef BOTAN_GCM_H_ -#define BOTAN_GCM_H_ +#ifndef BOTAN_AEAD_H_ +#define BOTAN_AEAD_H_ #include @@ -41,7 +44,7 @@ * @param salt_size size of implicit salt length * @return aead_t object, NULL if not supported */ -aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size, - size_t salt_size); +aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size, + size_t salt_size); -#endif /** BOTAN_GCM_H_ @}*/ +#endif /** BOTAN_AEAD_H_ @}*/ diff --git a/src/libstrongswan/plugins/botan/botan_plugin.c b/src/libstrongswan/plugins/botan/botan_plugin.c index e21cf06b73..9a2d8e6c2c 100644 --- a/src/libstrongswan/plugins/botan/botan_plugin.c +++ b/src/libstrongswan/plugins/botan/botan_plugin.c @@ -38,7 +38,7 @@ #include "botan_ec_private_key.h" #include "botan_ed_public_key.h" #include "botan_ed_private_key.h" -#include "botan_gcm.h" +#include "botan_aead.h" #include "botan_util_keys.h" #include "botan_x25519.h" @@ -110,9 +110,12 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24), PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32), #endif +#endif + + /* AEAD */ + PLUGIN_REGISTER(AEAD, botan_aead_create), +#ifdef BOTAN_HAS_AES #ifdef BOTAN_HAS_AEAD_GCM - /* AES GCM */ - PLUGIN_REGISTER(AEAD, botan_gcm_create), PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16), PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24), PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32), @@ -121,6 +124,10 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32), #endif #endif +#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305 + PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32), +#endif + /* hashers */ PLUGIN_REGISTER(HASHER, botan_hasher_create), #ifdef BOTAN_HAS_MD5 -- 2.47.3