]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
botan: Add support for ChaCha20/Poly1305 AEAD algorithm
authorTobias Brunner <tobias@strongswan.org>
Tue, 23 Oct 2018 09:26:02 +0000 (11:26 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 26 Oct 2018 09:06:45 +0000 (11:06 +0200)
src/libstrongswan/plugins/botan/Makefile.am
src/libstrongswan/plugins/botan/botan_aead.c [moved from src/libstrongswan/plugins/botan/botan_gcm.c with 77% similarity]
src/libstrongswan/plugins/botan/botan_aead.h [moved from src/libstrongswan/plugins/botan/botan_gcm.h with 81% similarity]
src/libstrongswan/plugins/botan/botan_plugin.c

index 6e5af362e1ead192c96cd530f20da4f001619326..30d3e601c50eb0050b59072764c9c0b86f62a994 100644 (file)
@@ -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
similarity index 77%
rename from src/libstrongswan/plugins/botan/botan_gcm.c
rename to src/libstrongswan/plugins/botan/botan_aead.c
index 7e0fc1468a7dece509fe1244b4ce419d1223fc8e..16676bde5baa90e7f09bb15c28871406339bbf70 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2018 Atanas Filyanov
  * Rohde & Schwarz Cybersecurity GmbH
  *
  * THE SOFTWARE.
  */
 
-#include "botan_gcm.h"
+#include "botan_aead.h"
 
 #include <botan/build.h>
 
-#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 <crypto/iv/iv_gen_seq.h>
 
 #include <botan/ffi.h>
 
 /**
- * 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
similarity index 81%
rename from src/libstrongswan/plugins/botan/botan_gcm.h
rename to src/libstrongswan/plugins/botan/botan_aead.h
index b2053cb4d917aafd2a4c55fcf008bd5db8bd8b29..00a2ba4bce473029ff46333b5d3e1e0f422666a1 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2018 Atanas Filyanov
  * Rohde & Schwarz Cybersecurity GmbH
  *
  */
 
 /**
- * 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 <crypto/aead.h>
 
@@ -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_ @}*/
index e21cf06b732f7b821b7fc452fa8816e731fbe95f..9a2d8e6c2c2cf6e8aaddd9dc564b2f2ea38445b3 100644 (file)
@@ -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