botan: Add support for ChaCha20/Poly1305 AEAD algorithm
This commit is contained in:
@@ -27,7 +27,7 @@ libstrongswan_botan_la_SOURCES = \
|
|||||||
botan_ed_private_key.h botan_ed_private_key.c \
|
botan_ed_private_key.h botan_ed_private_key.c \
|
||||||
botan_util.h botan_util.c \
|
botan_util.h botan_util.c \
|
||||||
botan_util_keys.h botan_util_keys.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
|
botan_x25519.h botan_x25519.c
|
||||||
|
|
||||||
libstrongswan_botan_la_LDFLAGS = -module -avoid-version
|
libstrongswan_botan_la_LDFLAGS = -module -avoid-version
|
||||||
|
|||||||
+106
-72
@@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 Tobias Brunner
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
* Copyright (C) 2018 Atanas Filyanov
|
* Copyright (C) 2018 Atanas Filyanov
|
||||||
* Rohde & Schwarz Cybersecurity GmbH
|
* Rohde & Schwarz Cybersecurity GmbH
|
||||||
*
|
*
|
||||||
@@ -21,23 +24,24 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "botan_gcm.h"
|
#include "botan_aead.h"
|
||||||
|
|
||||||
#include <botan/build.h>
|
#include <botan/build.h>
|
||||||
|
|
||||||
#ifdef BOTAN_HAS_AES
|
#if (defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM)) || \
|
||||||
#ifdef BOTAN_HAS_AEAD_GCM
|
defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
|
||||||
|
|
||||||
#include <crypto/iv/iv_gen_seq.h>
|
#include <crypto/iv/iv_gen_seq.h>
|
||||||
|
|
||||||
#include <botan/ffi.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 IV_LEN 8
|
||||||
#define SALT_LEN 4
|
#define SALT_LEN 4
|
||||||
#define NONCE_LEN (IV_LEN + SALT_LEN)
|
#define NONCE_LEN (IV_LEN + SALT_LEN)
|
||||||
|
#define CHAPOLY_KEY_LEN 32
|
||||||
|
|
||||||
typedef struct private_aead_t private_aead_t;
|
typedef struct private_aead_t private_aead_t;
|
||||||
|
|
||||||
@@ -77,8 +81,8 @@ struct private_aead_t {
|
|||||||
/**
|
/**
|
||||||
* Do the actual en/decryption
|
* Do the actual en/decryption
|
||||||
*/
|
*/
|
||||||
static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv,
|
static bool do_crypt(private_aead_t *this, chunk_t data, chunk_t assoc,
|
||||||
u_char *out, uint32_t init_flag)
|
chunk_t iv, u_char *out, uint32_t init_flag)
|
||||||
{
|
{
|
||||||
botan_cipher_t cipher;
|
botan_cipher_t cipher;
|
||||||
uint8_t nonce[NONCE_LEN];
|
uint8_t nonce[NONCE_LEN];
|
||||||
@@ -149,7 +153,8 @@ METHOD(aead_t, encrypt, bool,
|
|||||||
*encrypted = chunk_alloc(plain.len + this->icv_size);
|
*encrypted = chunk_alloc(plain.len + this->icv_size);
|
||||||
out = encrypted->ptr;
|
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,
|
METHOD(aead_t, decrypt, bool,
|
||||||
@@ -170,8 +175,8 @@ METHOD(aead_t, decrypt, bool,
|
|||||||
*plain = chunk_alloc(encrypted.len);
|
*plain = chunk_alloc(encrypted.len);
|
||||||
out = plain->ptr;
|
out = plain->ptr;
|
||||||
}
|
}
|
||||||
return crypt(this, encrypted, assoc, iv, out,
|
return do_crypt(this, encrypted, assoc, iv, out,
|
||||||
BOTAN_CIPHER_INIT_FLAG_DECRYPT);
|
BOTAN_CIPHER_INIT_FLAG_DECRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(aead_t, get_block_size, size_t,
|
METHOD(aead_t, get_block_size, size_t,
|
||||||
@@ -224,11 +229,78 @@ METHOD(aead_t, destroy, void,
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the cipher name and ICV size for the given algorithm and key size
|
||||||
|
*/
|
||||||
|
static bool determine_gcm_params(private_aead_t *this,
|
||||||
|
encryption_algorithm_t algo, size_t key_size)
|
||||||
|
{
|
||||||
|
switch (algo)
|
||||||
|
{
|
||||||
|
case ENCR_AES_GCM_ICV8:
|
||||||
|
switch (key_size)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->icv_size = 8;
|
||||||
|
return TRUE;
|
||||||
|
case ENCR_AES_GCM_ICV12:
|
||||||
|
switch (key_size)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->icv_size = 12;
|
||||||
|
return TRUE;
|
||||||
|
case ENCR_AES_GCM_ICV16:
|
||||||
|
switch (key_size)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->icv_size = 16;
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Described in header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
|
aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size,
|
||||||
size_t salt_size)
|
size_t salt_size)
|
||||||
{
|
{
|
||||||
private_aead_t *this;
|
private_aead_t *this;
|
||||||
|
|
||||||
@@ -248,76 +320,39 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
|
|||||||
|
|
||||||
if (salt_size && salt_size != SALT_LEN)
|
if (salt_size && salt_size != SALT_LEN)
|
||||||
{
|
{
|
||||||
/* currently not supported */
|
|
||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (algo)
|
switch (algo)
|
||||||
{
|
{
|
||||||
|
#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM)
|
||||||
case ENCR_AES_GCM_ICV8:
|
case ENCR_AES_GCM_ICV8:
|
||||||
switch (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;
|
|
||||||
}
|
|
||||||
this->icv_size = 8;
|
|
||||||
break;
|
|
||||||
case ENCR_AES_GCM_ICV12:
|
case ENCR_AES_GCM_ICV12:
|
||||||
switch (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;
|
|
||||||
}
|
|
||||||
this->icv_size = 12;
|
|
||||||
break;
|
|
||||||
case ENCR_AES_GCM_ICV16:
|
case ENCR_AES_GCM_ICV16:
|
||||||
switch (key_size)
|
if (!key_size)
|
||||||
{
|
{
|
||||||
case 0:
|
key_size = 16;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
this->icv_size = 16;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -330,4 +365,3 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
+10
-7
@@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 Tobias Brunner
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
* Copyright (C) 2018 Atanas Filyanov
|
* Copyright (C) 2018 Atanas Filyanov
|
||||||
* Rohde & Schwarz Cybersecurity GmbH
|
* 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
|
* @{ @ingroup botan_p
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BOTAN_GCM_H_
|
#ifndef BOTAN_AEAD_H_
|
||||||
#define BOTAN_GCM_H_
|
#define BOTAN_AEAD_H_
|
||||||
|
|
||||||
#include <crypto/aead.h>
|
#include <crypto/aead.h>
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@
|
|||||||
* @param salt_size size of implicit salt length
|
* @param salt_size size of implicit salt length
|
||||||
* @return aead_t object, NULL if not supported
|
* @return aead_t object, NULL if not supported
|
||||||
*/
|
*/
|
||||||
aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
|
aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size,
|
||||||
size_t salt_size);
|
size_t salt_size);
|
||||||
|
|
||||||
#endif /** BOTAN_GCM_H_ @}*/
|
#endif /** BOTAN_AEAD_H_ @}*/
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#include "botan_ec_private_key.h"
|
#include "botan_ec_private_key.h"
|
||||||
#include "botan_ed_public_key.h"
|
#include "botan_ed_public_key.h"
|
||||||
#include "botan_ed_private_key.h"
|
#include "botan_ed_private_key.h"
|
||||||
#include "botan_gcm.h"
|
#include "botan_aead.h"
|
||||||
#include "botan_util_keys.h"
|
#include "botan_util_keys.h"
|
||||||
#include "botan_x25519.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, 24),
|
||||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
|
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* AEAD */
|
||||||
|
PLUGIN_REGISTER(AEAD, botan_aead_create),
|
||||||
|
#ifdef BOTAN_HAS_AES
|
||||||
#ifdef BOTAN_HAS_AEAD_GCM
|
#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, 16),
|
||||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
|
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
|
||||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
|
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),
|
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305
|
||||||
|
PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
|
||||||
|
#endif
|
||||||
|
|
||||||
/* hashers */
|
/* hashers */
|
||||||
PLUGIN_REGISTER(HASHER, botan_hasher_create),
|
PLUGIN_REGISTER(HASHER, botan_hasher_create),
|
||||||
#ifdef BOTAN_HAS_MD5
|
#ifdef BOTAN_HAS_MD5
|
||||||
|
|||||||
Reference in New Issue
Block a user