summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/botan
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2019-01-02 10:45:36 +0100
committerYves-Alexis Perez <corsac@debian.org>2019-01-02 11:07:05 +0100
commit918094fde55fa0dbfd59a5f88d576efb513a88db (patch)
tree61e31656c60a6cc928c50cd633568043673e2cbd /src/libstrongswan/plugins/botan
parent69bc96f6b0b388d35e983f8d27224fa49d92918c (diff)
downloadvyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.tar.gz
vyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.zip
New upstream version 5.7.2
Diffstat (limited to 'src/libstrongswan/plugins/botan')
-rw-r--r--src/libstrongswan/plugins/botan/Makefile.am4
-rw-r--r--src/libstrongswan/plugins/botan/Makefile.in13
-rw-r--r--src/libstrongswan/plugins/botan/botan_aead.c (renamed from src/libstrongswan/plugins/botan/botan_gcm.c)219
-rw-r--r--src/libstrongswan/plugins/botan/botan_aead.h (renamed from src/libstrongswan/plugins/botan/botan_gcm.h)17
-rw-r--r--src/libstrongswan/plugins/botan/botan_crypter.c6
-rw-r--r--src/libstrongswan/plugins/botan/botan_ec_public_key.c19
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_private_key.c279
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_private_key.h63
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_public_key.c202
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_public_key.h51
-rw-r--r--src/libstrongswan/plugins/botan/botan_plugin.c77
-rw-r--r--src/libstrongswan/plugins/botan/botan_rsa_private_key.c24
-rw-r--r--src/libstrongswan/plugins/botan/botan_rsa_public_key.c66
-rw-r--r--src/libstrongswan/plugins/botan/botan_util.c35
-rw-r--r--src/libstrongswan/plugins/botan/botan_util.h12
-rw-r--r--src/libstrongswan/plugins/botan/botan_util_keys.c38
16 files changed, 957 insertions, 168 deletions
diff --git a/src/libstrongswan/plugins/botan/Makefile.am b/src/libstrongswan/plugins/botan/Makefile.am
index c1160145a..30d3e601c 100644
--- a/src/libstrongswan/plugins/botan/Makefile.am
+++ b/src/libstrongswan/plugins/botan/Makefile.am
@@ -23,9 +23,11 @@ libstrongswan_botan_la_SOURCES = \
botan_ec_diffie_hellman.h botan_ec_diffie_hellman.c \
botan_ec_public_key.h botan_ec_public_key.c \
botan_ec_private_key.h botan_ec_private_key.c \
+ botan_ed_public_key.h botan_ed_public_key.c \
+ 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/Makefile.in b/src/libstrongswan/plugins/botan/Makefile.in
index ef9f88610..3bb3e22f4 100644
--- a/src/libstrongswan/plugins/botan/Makefile.in
+++ b/src/libstrongswan/plugins/botan/Makefile.in
@@ -142,8 +142,9 @@ am_libstrongswan_botan_la_OBJECTS = botan_plugin.lo botan_rng.lo \
botan_hasher.lo botan_hmac.lo botan_crypter.lo \
botan_rsa_public_key.lo botan_rsa_private_key.lo \
botan_diffie_hellman.lo botan_ec_diffie_hellman.lo \
- botan_ec_public_key.lo botan_ec_private_key.lo botan_util.lo \
- botan_util_keys.lo botan_gcm.lo botan_x25519.lo
+ botan_ec_public_key.lo botan_ec_private_key.lo \
+ botan_ed_public_key.lo botan_ed_private_key.lo botan_util.lo \
+ botan_util_keys.lo botan_aead.lo botan_x25519.lo
libstrongswan_botan_la_OBJECTS = $(am_libstrongswan_botan_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -478,9 +479,11 @@ libstrongswan_botan_la_SOURCES = \
botan_ec_diffie_hellman.h botan_ec_diffie_hellman.c \
botan_ec_public_key.h botan_ec_public_key.c \
botan_ec_private_key.h botan_ec_private_key.c \
+ botan_ed_public_key.h botan_ed_public_key.c \
+ 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
@@ -574,12 +577,14 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_aead.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_public_key.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_gcm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ed_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ed_public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_hasher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_hmac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_plugin.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/botan/botan_gcm.c b/src/libstrongswan/plugins/botan/botan_aead.c
index 7e0fc1468..40006ae77 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,28 @@
* 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_CCM))) || \
+ 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 CHAPOLY_KEY_LEN 32
+/**
+ * As defined in RFC 4309
+ */
+#define CCM_SALT_LEN 3
typedef struct private_aead_t private_aead_t;
@@ -56,7 +64,7 @@ struct private_aead_t {
/**
* Salt value
*/
- char salt[SALT_LEN];
+ chunk_t salt;
/**
* Size of the integrity check value
@@ -77,15 +85,12 @@ 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];
size_t output_written = 0, input_consumed = 0;
-
- memcpy(nonce, this->salt, SALT_LEN);
- memcpy(nonce + SALT_LEN, iv.ptr, IV_LEN);
+ chunk_t nonce;
if (botan_cipher_init(&cipher, this->cipher_name, init_flag))
{
@@ -105,7 +110,9 @@ static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv,
return FALSE;
}
- if (botan_cipher_start(cipher, nonce, NONCE_LEN))
+ nonce = chunk_cata("cc", this->salt, iv);
+
+ if (botan_cipher_start(cipher, nonce.ptr, nonce.len))
{
botan_cipher_destroy(cipher);
return FALSE;
@@ -149,7 +156,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 +178,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,
@@ -201,7 +209,7 @@ METHOD(aead_t, get_iv_gen, iv_gen_t*,
METHOD(aead_t, get_key_size, size_t,
private_aead_t *this)
{
- return this->key.len + SALT_LEN;
+ return this->key.len + this->salt.len;
}
METHOD(aead_t, set_key, bool,
@@ -211,7 +219,7 @@ METHOD(aead_t, set_key, bool,
{
return FALSE;
}
- memcpy(this->salt, key.ptr + key.len - SALT_LEN, SALT_LEN);
+ memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
memcpy(this->key.ptr, key.ptr, this->key.len);
return TRUE;
}
@@ -220,15 +228,82 @@ METHOD(aead_t, destroy, void,
private_aead_t *this)
{
chunk_clear(&this->key);
+ chunk_clear(&this->salt);
this->iv_gen->destroy(this->iv_gen);
free(this);
}
+#ifdef BOTAN_HAS_AES
+#if defined(BOTAN_HAS_AEAD_GCM) || defined(BOTAN_HAS_AEAD_GCM)
+
+static struct {
+ encryption_algorithm_t algo;
+ size_t key_size;
+ char *name;
+ size_t icv_size;
+} aes_modes[] = {
+ { ENCR_AES_GCM_ICV8, 16, "AES-128/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV8, 24, "AES-192/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV8, 32, "AES-256/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV12, 16, "AES-128/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV12, 24, "AES-192/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV12, 32, "AES-256/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV16, 16, "AES-128/GCM(16)", 16 },
+ { ENCR_AES_GCM_ICV16, 24, "AES-192/GCM(16)", 16 },
+ { ENCR_AES_GCM_ICV16, 32, "AES-256/GCM(16)", 16 },
+ { ENCR_AES_CCM_ICV8, 16, "AES-128/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV8, 24, "AES-192/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV8, 32, "AES-256/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV12, 16, "AES-128/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV12, 24, "AES-192/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV12, 32, "AES-256/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV16, 16, "AES-128/CCM(16,4)", 16 },
+ { ENCR_AES_CCM_ICV16, 24, "AES-192/CCM(16,4)", 16 },
+ { ENCR_AES_CCM_ICV16, 32, "AES-256/CCM(16,4)", 16 },
+};
+
+/**
+ * Determine the cipher name and ICV size for the given algorithm and key size
+ */
+static bool determine_aes_params(private_aead_t *this,
+ encryption_algorithm_t algo, size_t key_size)
+{
+ int i;
+
+ for (i = 0; i < countof(aes_modes); i++)
+ {
+ if (aes_modes[i].algo == algo &&
+ aes_modes[i].key_size == key_size)
+ {
+ this->cipher_name = aes_modes[i].name;
+ this->icv_size = aes_modes[i].icv_size;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#endif
+#endif
+
+/**
+ * Check the given salt size, set it if not set
+ */
+static bool check_salt_size(size_t expected, size_t *salt_size)
+{
+ if (*salt_size)
+ {
+ return *salt_size == expected;
+ }
+ *salt_size = expected;
+ return TRUE;
+}
+
/*
* Described in header
*/
-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)
{
private_aead_t *this;
@@ -246,88 +321,68 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
},
);
- if (salt_size && salt_size != SALT_LEN)
- {
- /* currently not supported */
- free(this);
- return NULL;
- }
-
switch (algo)
{
+#ifdef BOTAN_HAS_AES
+#ifdef BOTAN_HAS_AEAD_GCM
case ENCR_AES_GCM_ICV8:
- switch (key_size)
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ if (!key_size)
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM(8)";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM(8)";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM(8)";
- break;
- default:
- free(this);
- return NULL;
+ key_size = 16;
+ }
+ if (!check_salt_size(SALT_LEN, &salt_size) ||
+ !determine_aes_params(this, algo, key_size))
+ {
+ free(this);
+ return NULL;
}
- this->icv_size = 8;
break;
- case ENCR_AES_GCM_ICV12:
- switch (key_size)
+#endif
+#ifdef BOTAN_HAS_AEAD_CCM
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ if (!key_size)
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM(12)";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM(12)";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM(12)";
- break;
- default:
- free(this);
- return NULL;
+ key_size = 16;
+ }
+ if (!check_salt_size(CCM_SALT_LEN, &salt_size) ||
+ !determine_aes_params(this, algo, key_size))
+ {
+ free(this);
+ return NULL;
}
- this->icv_size = 12;
break;
- case ENCR_AES_GCM_ICV16:
- switch (key_size)
+#endif
+#endif
+#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305
+ case ENCR_CHACHA20_POLY1305:
+ if (!key_size)
+ {
+ key_size = CHAPOLY_KEY_LEN;
+ }
+ if (key_size != CHAPOLY_KEY_LEN ||
+ !check_salt_size(SALT_LEN, &salt_size))
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM";
- break;
- default:
- free(this);
- return NULL;
+ free(this);
+ return NULL;
}
+ this->cipher_name = "ChaCha20Poly1305";
this->icv_size = 16;
break;
+#endif
default:
free(this);
return NULL;
}
this->key = chunk_alloc(key_size);
+ this->salt = chunk_alloc(salt_size);
this->iv_gen = iv_gen_seq_create();
return &this->public;
}
#endif
-#endif
diff --git a/src/libstrongswan/plugins/botan/botan_gcm.h b/src/libstrongswan/plugins/botan/botan_aead.h
index b2053cb4d..00a2ba4bc 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 <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_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_crypter.c b/src/libstrongswan/plugins/botan/botan_crypter.c
index 002be6ea8..3ec5c4d5e 100644
--- a/src/libstrongswan/plugins/botan/botan_crypter.c
+++ b/src/libstrongswan/plugins/botan/botan_crypter.c
@@ -25,6 +25,10 @@
#include "botan_crypter.h"
+#include <botan/build.h>
+
+#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
+
#include <botan/ffi.h>
typedef struct private_botan_crypter_t private_botan_crypter_t;
@@ -189,3 +193,5 @@ botan_crypter_t *botan_crypter_create(encryption_algorithm_t algo,
this->key = chunk_alloc(key_size);
return &this->public;
}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ec_public_key.c b/src/libstrongswan/plugins/botan/botan_ec_public_key.c
index 4c85dbcec..095ae3f20 100644
--- a/src/libstrongswan/plugins/botan/botan_ec_public_key.c
+++ b/src/libstrongswan/plugins/botan/botan_ec_public_key.c
@@ -69,9 +69,7 @@ static bool verify_signature(private_botan_ec_public_key_t *this,
const char* hash_and_padding, int signature_format, size_t keylen,
chunk_t data, chunk_t signature)
{
- botan_pk_op_verify_t verify_op;
chunk_t sig = signature;
- bool valid = FALSE;
if (signature_format == SIG_FORMAT_DER_SEQUENCE)
{
@@ -104,22 +102,7 @@ static bool verify_signature(private_botan_ec_public_key_t *this,
memcpy(sig.ptr + (keylen - r.len), r.ptr, r.len);
memcpy(sig.ptr + keylen + (keylen - s.len), s.ptr, s.len);
}
-
- if (botan_pk_op_verify_create(&verify_op, this->key, hash_and_padding, 0))
- {
- return FALSE;
- }
-
- if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
- {
- botan_pk_op_verify_destroy(verify_op);
- return FALSE;
- }
-
- valid = !(botan_pk_op_verify_finish(verify_op, sig.ptr, sig.len));
-
- botan_pk_op_verify_destroy(verify_op);
- return valid;
+ return botan_verify_signature(this->key, hash_and_padding, data, sig);
}
METHOD(public_key_t, get_type, key_type_t,
diff --git a/src/libstrongswan/plugins/botan/botan_ed_private_key.c b/src/libstrongswan/plugins/botan/botan_ed_private_key.c
new file mode 100644
index 000000000..3f0f54222
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_private_key.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "botan_ed_private_key.h"
+#include "botan_ed_public_key.h"
+#include "botan_util.h"
+
+#include <botan/build.h>
+
+#ifdef BOTAN_HAS_ED25519
+
+#include <asn1/asn1.h>
+#include <utils/debug.h>
+
+typedef struct private_private_key_t private_private_key_t;
+
+#define ED25519_KEY_LEN 32
+
+/**
+ * Private data
+ */
+struct private_private_key_t {
+
+ /**
+ * Public interface
+ */
+ private_key_t public;
+
+ /**
+ * Botan private key object
+ */
+ botan_privkey_t key;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(private_key_t, sign, bool,
+ private_private_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ED25519:
+ return botan_get_signature(this->key, "Pure", data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported via botan",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(private_key_t, decrypt, bool,
+ private_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "EdDSA private key decryption not implemented");
+ return FALSE;
+}
+
+METHOD(private_key_t, get_keysize, int,
+ private_private_key_t *this)
+{
+ return ED25519_KEY_LEN * 8;
+}
+
+METHOD(private_key_t, get_type, key_type_t,
+ private_private_key_t *this)
+{
+ return KEY_ED25519;
+}
+
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_private_key_t *this)
+{
+ botan_pubkey_t pubkey;
+
+ if (botan_privkey_export_pubkey(&pubkey, this->key))
+ {
+ return NULL;
+ }
+ return botan_ed_public_key_adopt(pubkey);
+}
+
+METHOD(private_key_t, get_fingerprint, bool,
+ private_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
+{
+ botan_pubkey_t pubkey;
+ bool success = FALSE;
+
+ /* check the cache before doing the export */
+ if (lib->encoding->get_cache(lib->encoding, type, this, fingerprint))
+ {
+ return TRUE;
+ }
+
+ if (botan_privkey_export_pubkey(&pubkey, this->key))
+ {
+ return FALSE;
+ }
+ success = botan_get_fingerprint(pubkey, this, type, fingerprint);
+ botan_pubkey_destroy(pubkey);
+ return success;
+}
+
+METHOD(private_key_t, get_encoding, bool,
+ private_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ return botan_get_privkey_encoding(this->key, type, encoding);
+}
+
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(private_key_t, destroy, void,
+ private_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ botan_privkey_destroy(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_private_key_t *create_empty()
+{
+ private_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_adopt(botan_privkey_t key)
+{
+ private_private_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_gen(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ botan_rng_t rng;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ /* just ignore the key size */
+ va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (botan_rng_init(&rng, "system"))
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_privkey_create(&this->key, "Ed25519", NULL, rng))
+ {
+ DBG1(DBG_LIB, "EdDSA private key generation failed");
+ botan_rng_destroy(rng);
+ free(this);
+ return NULL;
+ }
+
+ botan_rng_destroy(rng);
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_load(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ chunk_t key = chunk_empty;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_EDDSA_PRIV_ASN1_DER:
+ key = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ /* PKCS#8-encoded keys are handled generically, so we only handle the
+ * explicit case */
+ if (asn1_unwrap(&key, &key) != ASN1_OCTET_STRING ||
+ key.len != ED25519_KEY_LEN)
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_privkey_load_ed25519(&this->key, key.ptr))
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ed_private_key.h b/src/libstrongswan/plugins/botan/botan_ed_private_key.h
new file mode 100644
index 000000000..f7f32e8f3
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_private_key.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @defgroup botan_ed_private_key botan_ed_private_key
+ * @{ @ingroup botan_p
+ */
+
+#ifndef BOTAN_ED_PRIVATE_KEY_H_
+#define BOTAN_ED_PRIVATE_KEY_H_
+
+#include <botan/ffi.h>
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * Generate an EdDSA private key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_gen(key_type_t type, va_list args);
+
+/**
+ * Load an EdDSA private key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_load(key_type_t type, va_list args);
+
+/**
+ * Load an EdDSA private key by adopting a botan_privkey_t object.
+ *
+ * @param key private key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_adopt(botan_privkey_t key);
+
+#endif /** BOTAN_ED_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_ed_public_key.c b/src/libstrongswan/plugins/botan/botan_ed_public_key.c
new file mode 100644
index 000000000..41d2baae8
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_public_key.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "botan_ed_public_key.h"
+#include "botan_util.h"
+
+#include <botan/build.h>
+
+#ifdef BOTAN_HAS_ED25519
+
+#include <utils/debug.h>
+
+typedef struct private_public_key_t private_public_key_t;
+
+/**
+ * Private data
+ */
+struct private_public_key_t {
+
+ /**
+ * Public interface
+ */
+ public_key_t public;
+
+ /**
+ * Botan public key object
+ */
+ botan_pubkey_t key;
+
+ /**
+ * Reference counter
+ */
+ refcount_t ref;
+};
+
+METHOD(public_key_t, get_type, key_type_t,
+ private_public_key_t *this)
+{
+ return KEY_ED25519;
+}
+
+METHOD(public_key_t, get_keysize, int,
+ private_public_key_t *this)
+{
+ return ED25519_KEY_LEN * 8;
+}
+
+METHOD(public_key_t, verify, bool,
+ private_public_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ED25519:
+ return botan_verify_signature(this->key, "Pure", data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported via botan",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(public_key_t, encrypt, bool,
+ private_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "EdDSA public key encryption not implemented");
+ return FALSE;
+}
+
+METHOD(public_key_t, get_fingerprint, bool,
+ private_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
+{
+ return botan_get_fingerprint(this->key, this, type, fingerprint);
+}
+
+METHOD(public_key_t, get_encoding, bool,
+ private_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ return botan_get_encoding(this->key, type, encoding);
+}
+
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(public_key_t, destroy, void,
+ private_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ botan_pubkey_destroy(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_public_key_t *create_empty()
+{
+ private_public_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt,
+ .get_keysize = _get_keysize,
+ .equals = public_key_equals,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *botan_ed_public_key_adopt(botan_pubkey_t key)
+{
+ private_public_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *botan_ed_public_key_load(key_type_t type, va_list args)
+{
+ private_public_key_t *this;
+ chunk_t key = chunk_empty;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_EDDSA_PUB:
+ key = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ /* ASN.1-encoded keys are handled generically, so we only handle the
+ * explicit case */
+ if (key.len != ED25519_KEY_LEN)
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_pubkey_load_ed25519(&this->key, key.ptr))
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ed_public_key.h b/src/libstrongswan/plugins/botan/botan_ed_public_key.h
new file mode 100644
index 000000000..0f44b1afb
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_public_key.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef BOTAN_ED_PUBLIC_KEY_H_
+#define BOTAN_ED_PUBLIC_KEY_H_
+
+#include <botan/ffi.h>
+
+#include <credentials/builder.h>
+#include <credentials/keys/public_key.h>
+
+#define ED25519_KEY_LEN 32
+
+/**
+ * Load an EdDSA public key by adopting a botan_pubkey_t object.
+ *
+ * @param key public key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+public_key_t *botan_ed_public_key_adopt(botan_pubkey_t key);
+
+/**
+ * Load an EdDSA public key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+public_key_t *botan_ed_public_key_load(key_type_t type, va_list args);
+
+#endif /** BOTAN_ED_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_plugin.c b/src/libstrongswan/plugins/botan/botan_plugin.c
index fd8e5f5a6..f045ba074 100644
--- a/src/libstrongswan/plugins/botan/botan_plugin.c
+++ b/src/libstrongswan/plugins/botan/botan_plugin.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -36,7 +37,9 @@
#include "botan_ec_diffie_hellman.h"
#include "botan_ec_public_key.h"
#include "botan_ec_private_key.h"
-#include "botan_gcm.h"
+#include "botan_ed_public_key.h"
+#include "botan_ed_private_key.h"
+#include "botan_aead.h"
#include "botan_util_keys.h"
#include "botan_x25519.h"
@@ -101,6 +104,7 @@ METHOD(plugin_t, get_features, int,
#endif
/* crypters */
+#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
PLUGIN_REGISTER(CRYPTER, botan_crypter_create),
#ifdef BOTAN_HAS_AES
#ifdef BOTAN_HAS_MODE_CBC
@@ -108,17 +112,43 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
#endif
+#endif
+#endif
+
+ /* AEAD */
+#if (defined(BOTAN_HAS_AES) && \
+ (defined(BOTAN_HAS_AEAD_GCM) || defined(BOTAN_HAS_AEAD_CCM))) || \
+ defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
+ 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),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
#endif
+ #ifdef BOTAN_HAS_AEAD_CCM
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 32),
+ #endif
+#endif
+#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305
+ PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
#endif
+#endif
+
/* hashers */
PLUGIN_REGISTER(HASHER, botan_hasher_create),
#ifdef BOTAN_HAS_MD5
@@ -135,6 +165,13 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(HASHER, HASH_SHA384),
PLUGIN_PROVIDE(HASHER, HASH_SHA512),
#endif
+#ifdef BOTAN_HAS_SHA3
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_224),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_256),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
+#endif
+
/* prfs */
#ifdef BOTAN_HAS_HMAC
PLUGIN_REGISTER(PRF, botan_hmac_prf_create),
@@ -168,7 +205,8 @@ METHOD(plugin_t, get_features, int,
#endif /* BOTAN_HAS_HMAC */
/* generic key loaders */
-#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA)
+#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA) || \
+ defined(BOTAN_HAS_ED25519)
PLUGIN_REGISTER(PUBKEY, botan_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
#ifdef BOTAN_HAS_RSA
@@ -177,6 +215,9 @@ METHOD(plugin_t, get_features, int,
#ifdef BOTAN_HAS_ECDSA
PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
#endif
+#ifdef BOTAN_HAS_ED25519
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
+#endif
PLUGIN_REGISTER(PRIVKEY, botan_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
#ifdef BOTAN_HAS_RSA
@@ -185,6 +226,9 @@ METHOD(plugin_t, get_features, int,
#ifdef BOTAN_HAS_ECDSA
PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
#endif
+#ifdef BOTAN_HAS_ED25519
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
+#endif
#endif
/* RSA */
#ifdef BOTAN_HAS_RSA
@@ -218,6 +262,16 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
#endif
+#ifdef BOTAN_HAS_SHA3
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_224),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_256),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_512),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_224),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_512),
+#endif
#endif
#ifdef BOTAN_HAS_EMSA_PSSR
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
@@ -272,6 +326,21 @@ METHOD(plugin_t, get_features, int,
#endif /* BOTAN_HAS_EMSA1 */
#endif /* BOTAN_HAS_ECDSA */
+#ifdef BOTAN_HAS_ED25519
+ /* EdDSA private/public key loading */
+ PLUGIN_REGISTER(PUBKEY, botan_ed_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
+ PLUGIN_REGISTER(PRIVKEY, botan_ed_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
+ PLUGIN_REGISTER(PRIVKEY_GEN, botan_ed_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
+ /* register a pro forma identity hasher, never instantiated */
+ PLUGIN_REGISTER(HASHER, return_null),
+ PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
+#endif
+
/* random numbers */
#if BOTAN_HAS_SYSTEM_RNG
#if BOTAN_HAS_HMAC_DRBG
diff --git a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
index bb723ff95..02820b297 100644
--- a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
+++ b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -84,13 +85,8 @@ bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len)
{
return FALSE;
}
-
- if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- return snprintf(id, len, "EMSA-PSS(%s,MGF1,%zd)", hash,
- params->salt_len) < len;
- }
- return snprintf(id, len, "EMSA-PSS(%s,MGF1)", hash) < len;
+ return snprintf(id, len, "EMSA-PSS(%s,MGF1,%zd)", hash,
+ params->salt_len) < len;
}
/**
@@ -140,6 +136,18 @@ METHOD(private_key_t, sign, bool,
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
return botan_get_signature(this->key, "EMSA_PKCS1(SHA-512)", data,
signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_224:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(224))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_256:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(256))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_384:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(384))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_512:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(512))", data,
+ signature);
case SIGN_RSA_EMSA_PSS:
return build_emsa_pss_signature(this, params, data, signature);
default:
@@ -617,7 +625,7 @@ botan_rsa_private_key_t *botan_rsa_private_key_load(key_type_t type,
if (n.ptr && e.ptr && d.ptr)
{
- botan_mp_t n_mp, e_mp, d_mp, p_mp, q_mp;
+ botan_mp_t n_mp, e_mp, d_mp, p_mp = NULL, q_mp = NULL;
if (!chunk_to_botan_mp(n, &n_mp))
{
diff --git a/src/libstrongswan/plugins/botan/botan_rsa_public_key.c b/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
index c6e2e8861..244caa585 100644
--- a/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
+++ b/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -69,33 +70,6 @@ struct private_botan_rsa_public_key_t {
bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len);
/**
- * Verify RSA signature
- */
-static bool verify_rsa_signature(private_botan_rsa_public_key_t *this,
- const char* hash_and_padding, chunk_t data,
- chunk_t signature)
-{
- botan_pk_op_verify_t verify_op;
- bool valid = FALSE;
-
- if (botan_pk_op_verify_create(&verify_op, this->key, hash_and_padding, 0))
- {
- return FALSE;
- }
-
- if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
- {
- botan_pk_op_verify_destroy(verify_op);
- return FALSE;
- }
-
- valid = !botan_pk_op_verify_finish(verify_op, signature.ptr, signature.len);
-
- botan_pk_op_verify_destroy(verify_op);
- return valid;
-}
-
-/**
* Verification of an EMSA PSS signature described in PKCS#1
*/
static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
@@ -109,7 +83,7 @@ static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
{
return FALSE;
}
- return verify_rsa_signature(this, hash_and_padding, data, signature);
+ return botan_verify_signature(this->key, hash_and_padding, data, signature);
}
METHOD(public_key_t, get_type, key_type_t,
@@ -125,23 +99,35 @@ METHOD(public_key_t, verify, bool,
switch (scheme)
{
case SIGN_RSA_EMSA_PKCS1_NULL:
- return verify_rsa_signature(this, "EMSA_PKCS1(Raw)", data,
- signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(Raw)", data,
+ signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-1)", data,
- signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-1)", data,
+ signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-224)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-224)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-256)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-256)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-384)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-384)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-512)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-512)",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_224:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(224)",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_256:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(256))",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_384:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(384))",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_512:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(512))",
+ data, signature);
case SIGN_RSA_EMSA_PSS:
return verify_emsa_pss_signature(this, params, data, signature);
default:
diff --git a/src/libstrongswan/plugins/botan/botan_util.c b/src/libstrongswan/plugins/botan/botan_util.c
index 5e18405d7..f5728e43e 100644
--- a/src/libstrongswan/plugins/botan/botan_util.c
+++ b/src/libstrongswan/plugins/botan/botan_util.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -67,6 +68,14 @@ const char *botan_get_hash(hash_algorithm_t hash)
return "SHA-384";
case HASH_SHA512:
return "SHA-512";
+ case HASH_SHA3_224:
+ return "SHA-3(224)";
+ case HASH_SHA3_256:
+ return "SHA-3(256)";
+ case HASH_SHA3_384:
+ return "SHA-3(384)";
+ case HASH_SHA3_512:
+ return "SHA-3(512)";
default:
return NULL;
}
@@ -252,6 +261,32 @@ bool botan_get_signature(botan_privkey_t key, const char *scheme,
/*
* Described in header
*/
+bool botan_verify_signature(botan_pubkey_t key, const char *scheme,
+ chunk_t data, chunk_t signature)
+{
+ botan_pk_op_verify_t verify_op;
+ bool valid = FALSE;
+
+ if (botan_pk_op_verify_create(&verify_op, key, scheme, 0))
+ {
+ return FALSE;
+ }
+
+ if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
+ {
+ botan_pk_op_verify_destroy(verify_op);
+ return FALSE;
+ }
+
+ valid = !botan_pk_op_verify_finish(verify_op, signature.ptr, signature.len);
+
+ botan_pk_op_verify_destroy(verify_op);
+ return valid;
+}
+
+/*
+ * Described in header
+ */
bool botan_dh_key_derivation(botan_privkey_t key, chunk_t pub, chunk_t *secret)
{
botan_pk_op_ka_t ka;
diff --git a/src/libstrongswan/plugins/botan/botan_util.h b/src/libstrongswan/plugins/botan/botan_util.h
index 08830356e..7fb74ec5d 100644
--- a/src/libstrongswan/plugins/botan/botan_util.h
+++ b/src/libstrongswan/plugins/botan/botan_util.h
@@ -101,6 +101,18 @@ bool botan_get_signature(botan_privkey_t key, const char *scheme,
chunk_t data, chunk_t *signature);
/**
+ * Verify the given signature using the provided data and key with the specified
+ * signature scheme (hash/padding).
+ *
+ * @param key private key object
+ * @param scheme hash/padding algorithm
+ * @param data signed data
+ * @param signature signature to verify
+ */
+bool botan_verify_signature(botan_pubkey_t key, const char* scheme,
+ chunk_t data, chunk_t signature);
+
+/**
* Do the Diffie-Hellman key derivation using the given private key and public
* value.
*
diff --git a/src/libstrongswan/plugins/botan/botan_util_keys.c b/src/libstrongswan/plugins/botan/botan_util_keys.c
index 176c2caf9..dc4031491 100644
--- a/src/libstrongswan/plugins/botan/botan_util_keys.c
+++ b/src/libstrongswan/plugins/botan/botan_util_keys.c
@@ -24,6 +24,8 @@
#include "botan_util_keys.h"
#include "botan_ec_public_key.h"
#include "botan_ec_private_key.h"
+#include "botan_ed_public_key.h"
+#include "botan_ed_private_key.h"
#include "botan_rsa_public_key.h"
#include "botan_rsa_private_key.h"
@@ -104,15 +106,27 @@ public_key_t *botan_public_key_load(key_type_t type, va_list args)
return NULL;
}
+#ifdef BOTAN_HAS_RSA
if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
{
this = (public_key_t*)botan_rsa_public_key_adopt(pubkey);
}
- else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ else
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
{
this = (public_key_t*)botan_ec_public_key_adopt(pubkey);
}
else
+#endif
+#ifdef BOTAN_HAS_ED25519
+ if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
+ {
+ this = botan_ed_public_key_adopt(pubkey);
+ }
+ else
+#endif
{
botan_pubkey_destroy(pubkey);
}
@@ -120,6 +134,7 @@ public_key_t *botan_public_key_load(key_type_t type, va_list args)
return this;
}
+#ifdef BOTAN_HAS_ECDSA
/**
* Determine the curve OID from a PKCS#8 structure
*/
@@ -139,6 +154,7 @@ static int determine_ec_oid(chunk_t pkcs8)
}
return oid;
}
+#endif
/*
* Described in header
@@ -151,7 +167,6 @@ private_key_t *botan_private_key_load(key_type_t type, va_list args)
chunk_t blob = chunk_empty;
botan_rng_t rng;
char *name;
- int oid;
while (TRUE)
{
@@ -188,20 +203,35 @@ private_key_t *botan_private_key_load(key_type_t type, va_list args)
botan_pubkey_destroy(pubkey);
if (!name)
{
+ botan_privkey_destroy(key);
return NULL;
}
+
+#ifdef BOTAN_HAS_RSA
if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
{
this = (private_key_t*)botan_rsa_private_key_adopt(key);
}
- else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ else
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
{
- oid = determine_ec_oid(blob);
+ int oid = determine_ec_oid(blob);
if (oid != OID_UNKNOWN)
{
this = (private_key_t*)botan_ec_private_key_adopt(key, oid);
}
}
+ else
+#endif
+#ifdef BOTAN_HAS_ED25519
+ if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
+ {
+ this = botan_ed_private_key_adopt(key);
+ }
+#endif
+
if (!this)
{
botan_privkey_destroy(key);