Merge branch 'wolfssl'
Adds a plugin that uses wolfSSL for cryptographic operations. Closes strongswan/strongswan#133.
This commit is contained in:
commit
20550480e1
|
@ -81,6 +81,8 @@ matrix:
|
|||
# the crypto plugins are build-tested with clang via "all" above
|
||||
- env: TEST=botan
|
||||
- env: TEST=botan LEAK_DETECTIVE=yes
|
||||
- env: TEST=wolfssl
|
||||
- env: TEST=wolfssl LEAK_DETECTIVE=yes
|
||||
- env: TEST=openssl
|
||||
- env: TEST=openssl LEAK_DETECTIVE=yes
|
||||
- env: TEST=openssl-1.0
|
||||
|
|
|
@ -101,6 +101,7 @@ plugins = \
|
|||
plugins/updown.opt \
|
||||
plugins/vici.opt \
|
||||
plugins/whitelist.opt \
|
||||
plugins/wolfssl.opt \
|
||||
plugins/xauth-eap.opt \
|
||||
plugins/xauth-pam.opt
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
charon.plugins.wolfssl.fips_mode = no
|
||||
Enable to prevent loading the plugin if wolfSSL is not in FIPS mode.
|
14
configure.ac
14
configure.ac
|
@ -145,6 +145,7 @@ ARG_ENABL_SET([newhope], [enable New Hope crypto plugin.])
|
|||
ARG_DISBL_SET([nonce], [disable nonce generation plugin.])
|
||||
ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.])
|
||||
ARG_ENABL_SET([openssl], [enables the OpenSSL crypto plugin.])
|
||||
ARG_ENABL_SET([wolfssl], [enables the wolfSSL crypto plugin.])
|
||||
ARG_ENABL_SET([padlock], [enables VIA Padlock crypto plugin.])
|
||||
ARG_DISBL_SET([random], [disable RNG implementation on top of /dev/(u)random.])
|
||||
ARG_DISBL_SET([rc2], [disable RC2 software implementation plugin.])
|
||||
|
@ -444,7 +445,7 @@ if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$i
|
|||
fi
|
||||
|
||||
if test x$fips_prf = xtrue; then
|
||||
if test x$openssl = xfalse; then
|
||||
if test x$openssl = xfalse -a x$wolfssl = xfalse; then
|
||||
sha1=true;
|
||||
fi
|
||||
fi
|
||||
|
@ -1136,6 +1137,14 @@ if test x$openssl = xtrue; then
|
|||
AC_CHECK_HEADER([openssl/evp.h],,[AC_MSG_ERROR([OpenSSL header openssl/evp.h not found!])])
|
||||
fi
|
||||
|
||||
if test x$wolfssl = xtrue; then
|
||||
wolfssl_lib=wolfssl
|
||||
AC_CHECK_LIB([$wolfssl_lib],[wolfSSL_Init],[LIBS="$LIBS"],
|
||||
[AC_MSG_ERROR([wolfSSL lib$wolfssl_lib not found])],[$DLLIB])
|
||||
AC_SUBST(WOLFSSL_LIB, [-l$wolfssl_lib])
|
||||
AC_CHECK_HEADER([wolfssl/options.h],,[AC_MSG_ERROR([wolfSSL header wolfssl/options.h not found!])])
|
||||
fi
|
||||
|
||||
if test x$gcrypt = xtrue; then
|
||||
AC_CHECK_LIB([gcrypt],[gcry_control],[LIBS="$LIBS"],[AC_MSG_ERROR([gcrypt library not found])],[-lgpg-error])
|
||||
AC_CHECK_HEADER([gcrypt.h],,[AC_MSG_ERROR([gcrypt header gcrypt.h not found!])])
|
||||
|
@ -1408,6 +1417,7 @@ ADD_PLUGIN([ipseckey], [c charon])
|
|||
ADD_PLUGIN([pem], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([padlock], [s charon])
|
||||
ADD_PLUGIN([openssl], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([wolfssl], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([gcrypt], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([botan], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([af-alg], [s charon scepclient pki scripts medsrv attest nm cmd aikgen])
|
||||
|
@ -1578,6 +1588,7 @@ AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
|
|||
AM_CONDITIONAL(USE_SQLITE, test x$sqlite = xtrue)
|
||||
AM_CONDITIONAL(USE_PADLOCK, test x$padlock = xtrue)
|
||||
AM_CONDITIONAL(USE_OPENSSL, test x$openssl = xtrue)
|
||||
AM_CONDITIONAL(USE_WOLFSSL, test x$wolfssl = xtrue)
|
||||
AM_CONDITIONAL(USE_GCRYPT, test x$gcrypt = xtrue)
|
||||
AM_CONDITIONAL(USE_BOTAN, test x$botan = xtrue)
|
||||
AM_CONDITIONAL(USE_AGENT, test x$agent = xtrue)
|
||||
|
@ -1857,6 +1868,7 @@ AC_CONFIG_FILES([
|
|||
src/libstrongswan/plugins/sqlite/Makefile
|
||||
src/libstrongswan/plugins/padlock/Makefile
|
||||
src/libstrongswan/plugins/openssl/Makefile
|
||||
src/libstrongswan/plugins/wolfssl/Makefile
|
||||
src/libstrongswan/plugins/gcrypt/Makefile
|
||||
src/libstrongswan/plugins/botan/Makefile
|
||||
src/libstrongswan/plugins/agent/Makefile
|
||||
|
|
|
@ -34,6 +34,33 @@ build_botan()
|
|||
cd -
|
||||
}
|
||||
|
||||
build_wolfssl()
|
||||
{
|
||||
WOLFSSL_REV=v4.0.0-stable
|
||||
WOLFSSL_DIR=$TRAVIS_BUILD_DIR/../wolfssl
|
||||
|
||||
if test -d "$WOLFSSL_DIR"; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$ build_wolfssl()"
|
||||
|
||||
WOLFSSL_CFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DES_ECB"
|
||||
WOLFSSL_CONFIG="--enable-keygen --enable-rsapss --enable-aesccm
|
||||
--enable-aesctr --enable-des3 --enable-camellia
|
||||
--enable-curve25519 --enable-ed25519"
|
||||
|
||||
git clone https://github.com/wolfSSL/wolfssl.git $WOLFSSL_DIR &&
|
||||
cd $WOLFSSL_DIR &&
|
||||
git checkout -qf $WOLFSSL_REV &&
|
||||
./autogen.sh &&
|
||||
./configure C_EXTRA_FLAGS="$WOLFSSL_CFLAGS" $WOLFSSL_CONFIG &&
|
||||
make -j4 >/dev/null &&
|
||||
sudo make install >/dev/null &&
|
||||
sudo ldconfig || exit $?
|
||||
cd -
|
||||
}
|
||||
|
||||
build_tss2()
|
||||
{
|
||||
TSS2_REV=2.1.0
|
||||
|
@ -135,6 +162,14 @@ botan)
|
|||
build_botan
|
||||
fi
|
||||
;;
|
||||
wolfssl)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-wolfssl --enable-pem"
|
||||
# build with custom options to enable all the features the plugin supports
|
||||
DEPS=""
|
||||
if test "$1" = "deps"; then
|
||||
build_wolfssl
|
||||
fi
|
||||
;;
|
||||
printf-builtin)
|
||||
CONFIG="--with-printf-hooks=builtin"
|
||||
;;
|
||||
|
@ -161,6 +196,7 @@ all|coverage|sonarcloud)
|
|||
PYDEPS="pytest"
|
||||
if test "$1" = "deps"; then
|
||||
build_botan
|
||||
build_wolfssl
|
||||
build_tss2
|
||||
fi
|
||||
use_custom_openssl $1
|
||||
|
|
|
@ -558,6 +558,13 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_WOLFSSL
|
||||
SUBDIRS += plugins/wolfssl
|
||||
if MONOLITHIC
|
||||
libstrongswan_la_LIBADD += plugins/wolfssl/libstrongswan-wolfssl.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_GCRYPT
|
||||
SUBDIRS += plugins/gcrypt
|
||||
if MONOLITHIC
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-wolfssl.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-wolfssl.la
|
||||
endif
|
||||
|
||||
libstrongswan_wolfssl_la_SOURCES = \
|
||||
wolfssl_common.h \
|
||||
wolfssl_plugin.h wolfssl_plugin.c \
|
||||
wolfssl_aead.h wolfssl_aead.c \
|
||||
wolfssl_crypter.h wolfssl_crypter.c \
|
||||
wolfssl_diffie_hellman.h wolfssl_diffie_hellman.c \
|
||||
wolfssl_ec_diffie_hellman.h wolfssl_ec_diffie_hellman.c \
|
||||
wolfssl_ec_private_key.h wolfssl_ec_private_key.c \
|
||||
wolfssl_ec_public_key.h wolfssl_ec_public_key.c \
|
||||
wolfssl_ed_private_key.h wolfssl_ed_private_key.c \
|
||||
wolfssl_ed_public_key.h wolfssl_ed_public_key.c \
|
||||
wolfssl_hasher.h wolfssl_hasher.c \
|
||||
wolfssl_hmac.h wolfssl_hmac.c \
|
||||
wolfssl_rsa_public_key.h wolfssl_rsa_public_key.c \
|
||||
wolfssl_rsa_private_key.h wolfssl_rsa_private_key.c \
|
||||
wolfssl_rng.h wolfssl_rng.c \
|
||||
wolfssl_sha1_prf.h wolfssl_sha1_prf.c \
|
||||
wolfssl_x_diffie_hellman.h wolfssl_x_diffie_hellman.c \
|
||||
wolfssl_util.h wolfssl_util.c
|
||||
|
||||
|
||||
libstrongswan_wolfssl_la_LDFLAGS = -module -avoid-version
|
||||
libstrongswan_wolfssl_la_LIBADD = $(WOLFSSL_LIB)
|
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))) || \
|
||||
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
|
||||
|
||||
#include "wolfssl_aead.h"
|
||||
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#include <wolfssl/wolfcrypt/chacha.h>
|
||||
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
|
||||
#include <crypto/iv/iv_gen_seq.h>
|
||||
|
||||
/** as defined in RFC 4106 */
|
||||
#define IV_LEN 8
|
||||
#define GCM_SALT_LEN 4
|
||||
#define GCM_NONCE_LEN (GCM_SALT_LEN + IV_LEN)
|
||||
|
||||
#define CCM_SALT_LEN 3
|
||||
#define CCM_NONCE_LEN (CCM_SALT_LEN + IV_LEN)
|
||||
|
||||
typedef struct private_aead_t private_aead_t;
|
||||
|
||||
/**
|
||||
* Private data of aead_t
|
||||
*/
|
||||
struct private_aead_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
aead_t public;
|
||||
|
||||
/**
|
||||
* The encryption key
|
||||
*/
|
||||
chunk_t key;
|
||||
|
||||
/**
|
||||
* Salt value
|
||||
*/
|
||||
chunk_t salt;
|
||||
|
||||
/**
|
||||
* Size of the integrity check value
|
||||
*/
|
||||
size_t icv_size;
|
||||
|
||||
/**
|
||||
* IV generator
|
||||
*/
|
||||
iv_gen_t *iv_gen;
|
||||
|
||||
/**
|
||||
* The cipher to use
|
||||
*/
|
||||
union {
|
||||
#if !defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))
|
||||
Aes aes;
|
||||
#endif
|
||||
} cipher;
|
||||
|
||||
/**
|
||||
* The cipher to use
|
||||
*/
|
||||
encryption_algorithm_t alg;
|
||||
};
|
||||
|
||||
METHOD(aead_t, encrypt, bool,
|
||||
private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
|
||||
chunk_t *encrypted)
|
||||
{
|
||||
chunk_t nonce;
|
||||
u_char *out;
|
||||
bool success = FALSE;
|
||||
int ret;
|
||||
|
||||
out = plain.ptr;
|
||||
if (encrypted)
|
||||
{
|
||||
*encrypted = chunk_alloc(plain.len + this->icv_size);
|
||||
out = encrypted->ptr;
|
||||
}
|
||||
|
||||
nonce = chunk_cata("cc", this->salt, iv);
|
||||
|
||||
switch (this->alg)
|
||||
{
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
ret = wc_AesGcmSetKey(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesGcmEncrypt(&this->cipher.aes, out, plain.ptr,
|
||||
plain.len, nonce.ptr, GCM_NONCE_LEN, out + plain.len,
|
||||
this->icv_size, assoc.ptr, assoc.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
/* wc_AesCcmEncrypt fails if the pointer is NULL */
|
||||
if (!plain.ptr && !plain.len)
|
||||
{
|
||||
plain.ptr = nonce.ptr;
|
||||
}
|
||||
ret = wc_AesCcmSetKey(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCcmEncrypt(&this->cipher.aes, out, plain.ptr,
|
||||
plain.len, nonce.ptr, CCM_NONCE_LEN, out + plain.len,
|
||||
this->icv_size, assoc.ptr, assoc.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
ret = wc_ChaCha20Poly1305_Encrypt(this->key.ptr, nonce.ptr,
|
||||
assoc.ptr, assoc.len, plain.ptr, plain.len, out,
|
||||
out + plain.len);
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memwipe(nonce.ptr, nonce.len);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(aead_t, decrypt, bool,
|
||||
private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
|
||||
chunk_t *plain)
|
||||
{
|
||||
chunk_t nonce;
|
||||
u_char *out;
|
||||
bool success = FALSE;
|
||||
int ret = 0;
|
||||
|
||||
if (encrypted.len < this->icv_size)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
encrypted.len -= this->icv_size;
|
||||
|
||||
out = encrypted.ptr;
|
||||
if (plain)
|
||||
{
|
||||
*plain = chunk_alloc(encrypted.len);
|
||||
out = plain->ptr;
|
||||
}
|
||||
|
||||
nonce = chunk_cata("cc", this->salt, iv);
|
||||
|
||||
switch (this->alg)
|
||||
{
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
ret = wc_AesGcmSetKey(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesGcmDecrypt(&this->cipher.aes, out, encrypted.ptr,
|
||||
encrypted.len, nonce.ptr, GCM_NONCE_LEN,
|
||||
encrypted.ptr + encrypted.len, this->icv_size,
|
||||
assoc.ptr, assoc.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
/* wc_AesCcmDecrypt() fails if the pointers are NULL */
|
||||
if (!encrypted.ptr && !encrypted.len)
|
||||
{
|
||||
encrypted.ptr = nonce.ptr;
|
||||
}
|
||||
if (!out && !encrypted.len)
|
||||
{
|
||||
out = nonce.ptr;
|
||||
}
|
||||
ret = wc_AesCcmSetKey(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCcmDecrypt(&this->cipher.aes, out, encrypted.ptr,
|
||||
encrypted.len, nonce.ptr, CCM_NONCE_LEN,
|
||||
encrypted.ptr + encrypted.len, this->icv_size,
|
||||
assoc.ptr, assoc.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
ret = wc_ChaCha20Poly1305_Decrypt(this->key.ptr, nonce.ptr,
|
||||
assoc.ptr, assoc.len, encrypted.ptr, encrypted.len,
|
||||
encrypted.ptr + encrypted.len, out);
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memwipe(nonce.ptr, nonce.len);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_block_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
/* all AEAD algorithms are streaming */
|
||||
return 1;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_icv_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->icv_size;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_iv_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return IV_LEN;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_iv_gen, iv_gen_t*,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->iv_gen;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_key_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->key.len + this->salt.len;
|
||||
}
|
||||
|
||||
METHOD(aead_t, set_key, bool,
|
||||
private_aead_t *this, chunk_t key)
|
||||
{
|
||||
if (key.len != get_key_size(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
METHOD(aead_t, destroy, void,
|
||||
private_aead_t *this)
|
||||
{
|
||||
chunk_clear(&this->key);
|
||||
chunk_clear(&this->salt);
|
||||
switch (this->alg)
|
||||
{
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->iv_gen->destroy(this->iv_gen);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
|
||||
size_t key_size, size_t salt_size)
|
||||
{
|
||||
private_aead_t *this;
|
||||
size_t expected_salt_size;
|
||||
|
||||
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,
|
||||
},
|
||||
.alg = algo,
|
||||
);
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
this->icv_size = 8;
|
||||
break;
|
||||
#endif
|
||||
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
this->icv_size = 12;
|
||||
break;
|
||||
#endif
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
this->icv_size = 16;
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
this->icv_size = 8;
|
||||
break;
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
this->icv_size = 12;
|
||||
break;
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
this->icv_size = 16;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
this->icv_size = 16;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* FALL */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
expected_salt_size = GCM_SALT_LEN;
|
||||
if (wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "AES Init failed, aead create failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* FALL */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
expected_salt_size = CCM_SALT_LEN;
|
||||
if (wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "AES Init failed, aead create failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 32;
|
||||
/* FALL */
|
||||
case 32:
|
||||
expected_salt_size = 4;
|
||||
break;
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (salt_size && salt_size != expected_salt_size)
|
||||
{
|
||||
/* currently not supported */
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->key = chunk_alloc(key_size);
|
||||
this->salt = chunk_alloc(expected_salt_size);
|
||||
this->iv_gen = iv_gen_seq_create();
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements the aead_t interface using wolfSSL.
|
||||
*
|
||||
* @defgroup wolfssl_aead wolfssl_aead
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_AEAD_H_
|
||||
#define WOLFSSL_AEAD_H_
|
||||
|
||||
#include <crypto/aead.h>
|
||||
|
||||
/**
|
||||
* Constructor to create aead_t implementation.
|
||||
*
|
||||
* @param algo algorithm to implement
|
||||
* @param key_size key size in bytes
|
||||
* @param salt_size size of implicit salt length
|
||||
* @return aead_t object, NULL if not supported
|
||||
*/
|
||||
aead_t *wolfssl_aead_create(encryption_algorithm_t algo, size_t key_size,
|
||||
size_t salt_size);
|
||||
|
||||
#endif /** WOLFSSL_AEAD_H_ @}*/
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 WOLFSSL_COMMON_H_
|
||||
#define WOLFSSL_COMMON_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/* Undefine these as they are enum entries in wolfSSL - same values */
|
||||
#ifdef AES_BLOCK_SIZE
|
||||
#undef AES_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef CAMELLIA_BLOCK_SIZE
|
||||
#undef CAMELLIA_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef DES_BLOCK_SIZE
|
||||
#undef DES_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
/* PARSE_ERROR is an enum entry in wolfSSL - not used in this plugin */
|
||||
#define PARSE_ERROR WOLFSSL_PARSE_EROR
|
||||
|
||||
#ifndef WOLFSSL_USER_SETTINGS
|
||||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#undef PARSE_ERROR
|
||||
|
||||
#endif /* WOLFSSL_COMMON_H_ */
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_crypter.h"
|
||||
|
||||
#include "wolfssl_common.h"
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#include <wolfssl/wolfcrypt/camellia.h>
|
||||
#include <wolfssl/wolfcrypt/des3.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_wolfssl_crypter_t private_wolfssl_crypter_t;
|
||||
|
||||
#define CTR_SALT_LEN 4
|
||||
|
||||
/**
|
||||
* Private data of wolfssl_crypter_t
|
||||
*/
|
||||
struct private_wolfssl_crypter_t {
|
||||
|
||||
/**
|
||||
* Public part of this class.
|
||||
*/
|
||||
wolfssl_crypter_t public;
|
||||
|
||||
/**
|
||||
* wolfSSL cipher
|
||||
*/
|
||||
union {
|
||||
#if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
|
||||
Aes aes;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
Camellia camellia;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
Des des;
|
||||
Des3 des3;
|
||||
#endif
|
||||
} cipher;
|
||||
|
||||
/**
|
||||
* Encryption algorithm identifier
|
||||
*/
|
||||
encryption_algorithm_t alg;
|
||||
|
||||
/**
|
||||
* Private key
|
||||
*/
|
||||
chunk_t key;
|
||||
|
||||
/**
|
||||
* Salt value
|
||||
*/
|
||||
chunk_t salt;
|
||||
|
||||
/**
|
||||
* Size of block
|
||||
*/
|
||||
size_t block_size;
|
||||
|
||||
/**
|
||||
* Size of IV
|
||||
*/
|
||||
size_t iv_size;
|
||||
};
|
||||
|
||||
METHOD(crypter_t, decrypt, bool,
|
||||
private_wolfssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
|
||||
{
|
||||
u_char *out;
|
||||
bool success = FALSE;
|
||||
int ret;
|
||||
u_char nonce[AES_BLOCK_SIZE] = {0};
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
chunk_t d = chunk_empty;
|
||||
#endif
|
||||
|
||||
out = data.ptr;
|
||||
if (dst)
|
||||
{
|
||||
*dst = chunk_alloc(data.len);
|
||||
out = dst->ptr;
|
||||
}
|
||||
|
||||
if (this->salt.len > 0)
|
||||
{
|
||||
memcpy(nonce, this->salt.ptr, this->salt.len);
|
||||
memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
|
||||
nonce[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
|
||||
switch (this->alg)
|
||||
{
|
||||
case ENCR_NULL:
|
||||
memcpy(out, data.ptr, data.len);
|
||||
success = TRUE;
|
||||
break;
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
case ENCR_AES_CBC:
|
||||
ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
|
||||
iv.ptr, AES_DECRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCbcDecrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
if (out == data.ptr)
|
||||
{
|
||||
d = chunk_alloc(data.len);
|
||||
out = d.ptr;
|
||||
}
|
||||
ret = wc_AesSetKeyDirect(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len, nonce, AES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCtrEncrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
if (ret == 0 && out == d.ptr)
|
||||
{
|
||||
memcpy(data.ptr, out, data.len);
|
||||
}
|
||||
chunk_free(&d);
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
case ENCR_CAMELLIA_CBC:
|
||||
ret = wc_CamelliaSetKey(&this->cipher.camellia, this->key.ptr,
|
||||
this->key.len, iv.ptr);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_CamelliaCbcDecrypt(&this->cipher.camellia, out,
|
||||
data.ptr, data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case ENCR_3DES:
|
||||
ret = wc_Des3_SetKey(&this->cipher.des3, this->key.ptr, iv.ptr,
|
||||
DES_DECRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des3_CbcDecrypt(&this->cipher.des3, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
case ENCR_DES:
|
||||
ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
|
||||
DES_DECRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des_CbcDecrypt(&this->cipher.des, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
if (ret == 0)
|
||||
success = TRUE;
|
||||
break;
|
||||
#ifdef WOLFSSL_DES_ECB
|
||||
case ENCR_DES_ECB:
|
||||
ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
|
||||
DES_DECRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des_EcbDecrypt(&this->cipher.des, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memwipe(nonce, sizeof(nonce));
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, encrypt, bool,
|
||||
private_wolfssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
|
||||
{
|
||||
u_char *out;
|
||||
bool success = FALSE;
|
||||
int ret;
|
||||
u_char nonce[AES_BLOCK_SIZE] = {0};
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
chunk_t d = chunk_empty;
|
||||
#endif
|
||||
|
||||
out = data.ptr;
|
||||
if (dst)
|
||||
{
|
||||
*dst = chunk_alloc(data.len);
|
||||
out = dst->ptr;
|
||||
}
|
||||
|
||||
if (this->salt.len > 0)
|
||||
{
|
||||
memcpy(nonce, this->salt.ptr, this->salt.len);
|
||||
memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
|
||||
nonce[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
|
||||
switch (this->alg)
|
||||
{
|
||||
case ENCR_NULL:
|
||||
memcpy(out, data.ptr, data.len);
|
||||
success = TRUE;
|
||||
break;
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
case ENCR_AES_CBC:
|
||||
ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
|
||||
iv.ptr, AES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCbcEncrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
if (out == data.ptr)
|
||||
{
|
||||
d = chunk_alloc(data.len);
|
||||
out = d.ptr;
|
||||
}
|
||||
ret = wc_AesSetKeyDirect(&this->cipher.aes, this->key.ptr,
|
||||
this->key.len, nonce, AES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesCtrEncrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
if (ret == 0 && out == d.ptr)
|
||||
{
|
||||
memcpy(data.ptr, out, data.len);
|
||||
}
|
||||
chunk_free(&d);
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
case ENCR_CAMELLIA_CBC:
|
||||
ret = wc_CamelliaSetKey(&this->cipher.camellia, this->key.ptr,
|
||||
this->key.len, iv.ptr);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_CamelliaCbcEncrypt(&this->cipher.camellia, out,
|
||||
data.ptr, data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case ENCR_3DES:
|
||||
ret = wc_Des3_SetKey(&this->cipher.des3, this->key.ptr, iv.ptr,
|
||||
DES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des3_CbcEncrypt(&this->cipher.des3, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
case ENCR_DES:
|
||||
ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
|
||||
DES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des_CbcEncrypt(&this->cipher.des, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#ifdef WOLFSSL_DES_ECB
|
||||
case ENCR_DES_ECB:
|
||||
ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
|
||||
DES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_Des_EcbEncrypt(&this->cipher.des, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, get_block_size, size_t,
|
||||
private_wolfssl_crypter_t *this)
|
||||
{
|
||||
return this->block_size;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, get_iv_size, size_t,
|
||||
private_wolfssl_crypter_t *this)
|
||||
{
|
||||
return this->iv_size;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, get_key_size, size_t,
|
||||
private_wolfssl_crypter_t *this)
|
||||
{
|
||||
return this->key.len + this->salt.len;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, set_key, bool,
|
||||
private_wolfssl_crypter_t *this, chunk_t key)
|
||||
{
|
||||
if (key.len != get_key_size(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
METHOD(crypter_t, destroy, void,
|
||||
private_wolfssl_crypter_t *this)
|
||||
{
|
||||
chunk_clear(&this->key);
|
||||
chunk_clear(&this->salt);
|
||||
switch (this->alg)
|
||||
{
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
case ENCR_AES_CBC:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case ENCR_3DES:
|
||||
wc_Des3Free(&this->cipher.des3);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
|
||||
size_t key_size)
|
||||
{
|
||||
private_wolfssl_crypter_t *this;
|
||||
size_t block_size;
|
||||
size_t iv_size;
|
||||
size_t salt_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case ENCR_NULL:
|
||||
key_size = 0;
|
||||
block_size = 1;
|
||||
iv_size = 0;
|
||||
break;
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
case ENCR_AES_CBC:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* fall-through */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
block_size = AES_BLOCK_SIZE;
|
||||
iv_size = AES_IV_SIZE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* fall-through */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
block_size = 1;
|
||||
iv_size = 8;
|
||||
salt_len = CTR_SALT_LEN;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
case ENCR_CAMELLIA_CBC:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* fall-through */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
block_size = CAMELLIA_BLOCK_SIZE;
|
||||
iv_size = CAMELLIA_BLOCK_SIZE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case ENCR_3DES:
|
||||
if (key_size != 24)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
block_size = DES_BLOCK_SIZE;
|
||||
iv_size = DES_BLOCK_SIZE;
|
||||
break;
|
||||
case ENCR_DES:
|
||||
#ifdef WOLFSSL_DES_ECB
|
||||
case ENCR_DES_ECB:
|
||||
#endif
|
||||
if (key_size != 8)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
block_size = DES_BLOCK_SIZE;
|
||||
iv_size = DES_BLOCK_SIZE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.crypter = {
|
||||
.encrypt = _encrypt,
|
||||
.decrypt = _decrypt,
|
||||
.get_block_size = _get_block_size,
|
||||
.get_iv_size = _get_iv_size,
|
||||
.get_key_size = _get_key_size,
|
||||
.set_key = _set_key,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.alg = algo,
|
||||
.block_size = block_size,
|
||||
.iv_size = iv_size,
|
||||
);
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
case ENCR_AES_CBC:
|
||||
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case ENCR_3DES:
|
||||
ret = wc_Des3Init(&this->cipher.des3, NULL, INVALID_DEVID);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ret != 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->key = chunk_alloc(key_size);
|
||||
this->salt = chunk_alloc(salt_len);
|
||||
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_crypter wolfssl_crypter
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_CRYPTER_H_
|
||||
#define WOLFSSL_CRYPTER_H_
|
||||
|
||||
typedef struct wolfssl_crypter_t wolfssl_crypter_t;
|
||||
|
||||
#include <crypto/crypters/crypter.h>
|
||||
|
||||
/**
|
||||
* Implementation of crypters using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_crypter_t {
|
||||
|
||||
/**
|
||||
* Implements crypter_t interface.
|
||||
*/
|
||||
crypter_t crypter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor to create wolfssl_crypter_t.
|
||||
*
|
||||
* @param algo algorithm to implement
|
||||
* @param key_size key size in bytes
|
||||
* @return wolfssl_crypter_t, NULL if not supported
|
||||
*/
|
||||
wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
|
||||
size_t key_size);
|
||||
|
||||
#endif /** WOLFSSL_CRYPTER_H_ @}*/
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifndef NO_DH
|
||||
|
||||
#include <wolfssl/wolfcrypt/dh.h>
|
||||
|
||||
#include "wolfssl_diffie_hellman.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_wolfssl_diffie_hellman_t private_wolfssl_diffie_hellman_t;
|
||||
|
||||
/**
|
||||
* Private data of an wolfssl_diffie_hellman_t object.
|
||||
*/
|
||||
struct private_wolfssl_diffie_hellman_t {
|
||||
|
||||
/**
|
||||
* Public wolfssl_diffie_hellman_t interface.
|
||||
*/
|
||||
wolfssl_diffie_hellman_t public;
|
||||
|
||||
/**
|
||||
* Diffie Hellman group number.
|
||||
*/
|
||||
diffie_hellman_group_t group;
|
||||
|
||||
/**
|
||||
* Diffie Hellman object
|
||||
*/
|
||||
DhKey dh;
|
||||
|
||||
/**
|
||||
* Length of public values
|
||||
*/
|
||||
int len;
|
||||
|
||||
/**
|
||||
* Private key
|
||||
*/
|
||||
chunk_t priv;
|
||||
|
||||
/**
|
||||
* Public key
|
||||
*/
|
||||
chunk_t pub;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
chunk_t shared_secret;
|
||||
};
|
||||
|
||||
METHOD(diffie_hellman_t, get_my_public_value, bool,
|
||||
private_wolfssl_diffie_hellman_t *this, chunk_t *value)
|
||||
{
|
||||
*value = chunk_copy_pad(chunk_alloc(this->len), this->pub, 0x00);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_shared_secret, bool,
|
||||
private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->shared_secret.len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*secret = chunk_copy_pad(chunk_alloc(this->len), this->shared_secret, 0x00);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||
private_wolfssl_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
word32 len;
|
||||
|
||||
if (!diffie_hellman_verify_value(this->group, value))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
chunk_clear(&this->shared_secret);
|
||||
this->shared_secret = chunk_alloc(this->len);
|
||||
if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
|
||||
this->priv.len, value.ptr, value.len) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "DH shared secret computation failed");
|
||||
chunk_free(&this->shared_secret);
|
||||
return FALSE;
|
||||
}
|
||||
this->shared_secret.len = len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_private_value, bool,
|
||||
private_wolfssl_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
bool success = FALSE;
|
||||
chunk_t g;
|
||||
word32 len;
|
||||
|
||||
chunk_clear(&this->priv);
|
||||
this->priv = chunk_clone(value);
|
||||
|
||||
/* calculate public value - g^priv mod p */
|
||||
if (wolfssl_mp2chunk(&this->dh.g, &g))
|
||||
{
|
||||
len = this->pub.len;
|
||||
if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
|
||||
this->priv.len, g.ptr, g.len) == 0)
|
||||
{
|
||||
this->pub.len = len;
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
free(g.ptr);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
|
||||
private_wolfssl_diffie_hellman_t *this)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, destroy, void,
|
||||
private_wolfssl_diffie_hellman_t *this)
|
||||
{
|
||||
wc_FreeDhKey(&this->dh);
|
||||
chunk_clear(&this->pub);
|
||||
chunk_clear(&this->priv);
|
||||
chunk_clear(&this->shared_secret);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum private key length when generating key
|
||||
*/
|
||||
static int wolfssl_priv_key_size(int len)
|
||||
{
|
||||
if (len <= 128)
|
||||
{
|
||||
return 21;
|
||||
}
|
||||
if (len <= 256)
|
||||
{
|
||||
return 29;
|
||||
}
|
||||
if (len <= 384)
|
||||
{
|
||||
return 34;
|
||||
}
|
||||
if (len <= 512)
|
||||
{
|
||||
return 39;
|
||||
}
|
||||
if (len <= 640)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
if (len <= 768)
|
||||
{
|
||||
return 46;
|
||||
}
|
||||
if (len <= 896)
|
||||
{
|
||||
return 49;
|
||||
}
|
||||
if (len <= 1024)
|
||||
{
|
||||
return 52;
|
||||
}
|
||||
return len / 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic internal constructor
|
||||
*/
|
||||
static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
|
||||
chunk_t g, chunk_t p)
|
||||
{
|
||||
private_wolfssl_diffie_hellman_t *this;
|
||||
word32 privLen, pubLen;
|
||||
WC_RNG rng;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.dh = {
|
||||
.get_shared_secret = _get_shared_secret,
|
||||
.set_other_public_value = _set_other_public_value,
|
||||
.get_my_public_value = _get_my_public_value,
|
||||
.set_private_value = _set_private_value,
|
||||
.get_dh_group = _get_dh_group,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.group = group,
|
||||
.len = p.len,
|
||||
);
|
||||
|
||||
if (wc_InitDhKey(&this->dh) != 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->priv = chunk_alloc(wolfssl_priv_key_size(this->len));
|
||||
this->pub = chunk_alloc(this->len);
|
||||
privLen = this->priv.len;
|
||||
pubLen = this->pub.len;
|
||||
/* generate my public and private values */
|
||||
if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
|
||||
this->pub.ptr, &pubLen) != 0)
|
||||
{
|
||||
wc_FreeRng(&rng);
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
this->pub.len = pubLen;
|
||||
this->priv.len = privLen;
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
|
||||
diffie_hellman_group_t group, ...)
|
||||
{
|
||||
diffie_hellman_params_t *params;
|
||||
chunk_t g, p;
|
||||
|
||||
if (group == MODP_CUSTOM)
|
||||
{
|
||||
VA_ARGS_GET(group, g, p);
|
||||
return create_generic(group, g, p);
|
||||
}
|
||||
params = diffie_hellman_get_params(group);
|
||||
if (!params)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* wolfSSL doesn't support optimized exponent sizes according to RFC 3526 */
|
||||
return create_generic(group, params->generator, params->prime);
|
||||
}
|
||||
|
||||
#endif /* NO_DH */
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_diffie_hellman wolfssl_diffie_hellman
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_DIFFIE_HELLMAN_H_
|
||||
#define WOLFSSL_DIFFIE_HELLMAN_H_
|
||||
|
||||
typedef struct wolfssl_diffie_hellman_t wolfssl_diffie_hellman_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Implementation of the Diffie-Hellman algorithm using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_diffie_hellman_t {
|
||||
|
||||
/**
|
||||
* Implements diffie_hellman_t interface.
|
||||
*/
|
||||
diffie_hellman_t dh;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new wolfssl_diffie_hellman_t object.
|
||||
*
|
||||
* @param group Diffie Hellman group number to use
|
||||
* @param ... expects generator and prime as chunk_t if MODP_CUSTOM
|
||||
* @return wolfssl_diffie_hellman_t object, NULL if not supported
|
||||
*/
|
||||
wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
|
||||
diffie_hellman_group_t group, ...);
|
||||
|
||||
#endif /** WOLFSSL_DIFFIE_HELLMAN_H_ @}*/
|
||||
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_ECC_DHE
|
||||
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
|
||||
#include "wolfssl_ec_diffie_hellman.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_wolfssl_ec_diffie_hellman_t private_wolfssl_ec_diffie_hellman_t;
|
||||
|
||||
/**
|
||||
* Private data of an wolfssl_ec_diffie_hellman_t object.
|
||||
*/
|
||||
struct private_wolfssl_ec_diffie_hellman_t {
|
||||
/**
|
||||
* Public wolfssl_ec_diffie_hellman_t interface.
|
||||
*/
|
||||
wolfssl_ec_diffie_hellman_t public;
|
||||
|
||||
/**
|
||||
* Diffie Hellman group number.
|
||||
*/
|
||||
diffie_hellman_group_t group;
|
||||
|
||||
/**
|
||||
* EC curve id for creating keys
|
||||
*/
|
||||
ecc_curve_id curve_id;
|
||||
|
||||
/**
|
||||
* Size of an ordinate in bytes
|
||||
*/
|
||||
int keysize;
|
||||
|
||||
/**
|
||||
* EC private (public) key
|
||||
*/
|
||||
ecc_key key;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
chunk_t shared_secret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a chunk to an ecc_point (which must already exist). The x and y
|
||||
* coordinates of the point have to be concatenated in the chunk.
|
||||
*/
|
||||
static bool chunk2ecp(chunk_t chunk, ecc_point *point)
|
||||
{
|
||||
if (!wolfssl_mp_split(chunk, point->x, point->y))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (mp_set(point->z, 1) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an ec_point to a chunk by concatenating the x and y coordinates of
|
||||
* the point. This function allocates memory for the chunk.
|
||||
*/
|
||||
static bool ecp2chunk(int keysize, ecc_point *point, chunk_t *chunk,
|
||||
bool x_coordinate_only)
|
||||
{
|
||||
mp_int *y = NULL;
|
||||
|
||||
if (!x_coordinate_only)
|
||||
{
|
||||
keysize *= 2;
|
||||
y = point->y;
|
||||
}
|
||||
return wolfssl_mp_cat(keysize, point->x, y, chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the elliptic curve scalar multiplication.
|
||||
*/
|
||||
static bool wolfssl_ecc_multiply(const ecc_set_type *ecc_set, mp_int *scalar,
|
||||
ecc_point *point, ecc_point *r)
|
||||
{
|
||||
mp_int a, prime;
|
||||
int ret;
|
||||
|
||||
if (mp_init(&a) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (mp_init(&prime) != 0)
|
||||
{
|
||||
mp_free(&a);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = mp_read_radix(&a, ecc_set->Af, MP_RADIX_HEX);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_read_radix(&prime, ecc_set->prime, MP_RADIX_HEX);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
/* multiply the point by our secret */
|
||||
ret = wc_ecc_mulmod(scalar, point, r, &a, &prime, 1);
|
||||
}
|
||||
|
||||
mp_free(&prime);
|
||||
mp_free(&a);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the shared secret.
|
||||
*
|
||||
* We cannot use the function wc_ecc_shared_secret() because that returns only
|
||||
* the x coordinate of the shared secret point (which is defined, for instance,
|
||||
* in 'NIST SP 800-56A').
|
||||
* However, we need both coordinates as RFC 4753 says: "The Diffie-Hellman
|
||||
* public value is obtained by concatenating the x and y values. The format
|
||||
* of the Diffie-Hellman shared secret value is the same as that of the
|
||||
* Diffie-Hellman public value."
|
||||
*/
|
||||
static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this,
|
||||
ecc_point *pub_key, chunk_t *shared_secret)
|
||||
{
|
||||
ecc_point* secret;
|
||||
bool x_coordinate_only;
|
||||
bool success = FALSE;
|
||||
|
||||
if ((secret = wc_ecc_new_point()) == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wolfssl_ecc_multiply(this->key.dp, &this->key.k, pub_key, secret))
|
||||
{
|
||||
/*
|
||||
* The default setting ecp_x_coordinate_only = TRUE
|
||||
* applies the following errata for RFC 4753:
|
||||
* http://www.rfc-editor.org/errata_search.php?eid=9
|
||||
*/
|
||||
x_coordinate_only = lib->settings->get_bool(lib->settings,
|
||||
"%s.ecp_x_coordinate_only", TRUE, lib->ns);
|
||||
success = ecp2chunk(this->keysize, secret, shared_secret,
|
||||
x_coordinate_only);
|
||||
}
|
||||
|
||||
wc_ecc_del_point(secret);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||
private_wolfssl_ec_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
ecc_point *pub_key;
|
||||
|
||||
if (!diffie_hellman_verify_value(this->group, value))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((pub_key = wc_ecc_new_point()) == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!chunk2ecp(value, pub_key))
|
||||
{
|
||||
DBG1(DBG_LIB, "ECDH public value is malformed");
|
||||
wc_ecc_del_point(pub_key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
chunk_clear(&this->shared_secret);
|
||||
|
||||
if (!compute_shared_key(this, pub_key, &this->shared_secret))
|
||||
{
|
||||
DBG1(DBG_LIB, "ECDH shared secret computation failed");
|
||||
chunk_clear(&this->shared_secret);
|
||||
wc_ecc_del_point(pub_key);
|
||||
return FALSE;
|
||||
}
|
||||
wc_ecc_del_point(pub_key);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_my_public_value, bool,
|
||||
private_wolfssl_ec_diffie_hellman_t *this,chunk_t *value)
|
||||
{
|
||||
return ecp2chunk(this->keysize, &this->key.pubkey, value, FALSE);
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_private_value, bool,
|
||||
private_wolfssl_ec_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
bool success = FALSE;
|
||||
ecc_point *base;
|
||||
int ret;
|
||||
|
||||
if ((base = wc_ecc_new_point()) == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = mp_read_unsigned_bin(&this->key.k, value.ptr, value.len);
|
||||
/* get base point */
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_read_radix(base->x, this->key.dp->Gx, MP_RADIX_HEX);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_read_radix(base->y, this->key.dp->Gy, MP_RADIX_HEX);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_set(base->z, 1);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
/* calculate public key */
|
||||
success = wolfssl_ecc_multiply(this->key.dp, &this->key.k, base,
|
||||
&this->key.pubkey);
|
||||
}
|
||||
|
||||
wc_ecc_del_point(base);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_shared_secret, bool,
|
||||
private_wolfssl_ec_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->shared_secret.len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*secret = chunk_clone(this->shared_secret);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
|
||||
private_wolfssl_ec_diffie_hellman_t *this)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, destroy, void,
|
||||
private_wolfssl_ec_diffie_hellman_t *this)
|
||||
{
|
||||
wc_ecc_free(&this->key);
|
||||
chunk_clear(&this->shared_secret);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
|
||||
{
|
||||
private_wolfssl_ec_diffie_hellman_t *this;
|
||||
WC_RNG rng;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.dh = {
|
||||
.get_shared_secret = _get_shared_secret,
|
||||
.set_other_public_value = _set_other_public_value,
|
||||
.get_my_public_value = _get_my_public_value,
|
||||
.set_private_value = _set_private_value,
|
||||
.get_dh_group = _get_dh_group,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.group = group,
|
||||
);
|
||||
|
||||
if (wc_ecc_init(&this->key) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "key init failed, ecdh create failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (group)
|
||||
{
|
||||
case ECP_192_BIT:
|
||||
this->curve_id = ECC_SECP192R1;
|
||||
this->keysize = 192 / 8;
|
||||
break;
|
||||
case ECP_224_BIT:
|
||||
this->curve_id = ECC_SECP224R1;
|
||||
this->keysize = 224 / 8;
|
||||
break;
|
||||
case ECP_256_BIT:
|
||||
this->curve_id = ECC_SECP256R1;
|
||||
this->keysize = 256 / 8;
|
||||
break;
|
||||
case ECP_384_BIT:
|
||||
this->curve_id = ECC_SECP384R1;
|
||||
this->keysize = 384 / 8;
|
||||
break;
|
||||
case ECP_521_BIT:
|
||||
this->curve_id = ECC_SECP521R1;
|
||||
this->keysize = (521 + 7) / 8;
|
||||
break;
|
||||
#ifdef HAVE_BRAINPOOL
|
||||
case ECP_224_BP:
|
||||
this->curve_id = ECC_BRAINPOOLP224R1;
|
||||
this->keysize = 224 / 8;
|
||||
break;
|
||||
case ECP_256_BP:
|
||||
this->curve_id = ECC_BRAINPOOLP256R1;
|
||||
this->keysize = 256 / 8;
|
||||
break;
|
||||
case ECP_384_BP:
|
||||
this->curve_id = ECC_BRAINPOOLP384R1;
|
||||
this->keysize = 384 / 8;
|
||||
break;
|
||||
case ECP_512_BP:
|
||||
this->curve_id = ECC_BRAINPOOLP512R1;
|
||||
this->keysize = 512 / 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "RNG init failed, ecdh create failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* generate an EC private (public) key */
|
||||
if (wc_ecc_make_key_ex(&rng, this->keysize, &this->key,
|
||||
this->curve_id) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "make key failed, wolfssl ECDH create failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
#endif /* HAVE_ECC_DHE */
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_ec_diffie_hellman wolfssl_ec_diffie_hellman
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_EC_DIFFIE_HELLMAN_H_
|
||||
#define WOLFSSL_EC_DIFFIE_HELLMAN_H_
|
||||
|
||||
typedef struct wolfssl_ec_diffie_hellman_t wolfssl_ec_diffie_hellman_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Implementation of the EC Diffie-Hellman algorithm using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_ec_diffie_hellman_t {
|
||||
|
||||
/**
|
||||
* Implements diffie_hellman_t interface.
|
||||
*/
|
||||
diffie_hellman_t dh;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new wolfssl_ec_diffie_hellman_t object.
|
||||
*
|
||||
* @param group EC Diffie Hellman group number to use
|
||||
* @return wolfssl_ec_diffie_hellman_t object, NULL if not
|
||||
* supported
|
||||
*/
|
||||
wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(
|
||||
diffie_hellman_group_t group);
|
||||
|
||||
#endif /** WOLFSSL_EC_DIFFIE_HELLMAN_H_ @}*/
|
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_ECC_SIGN
|
||||
|
||||
#include "wolfssl_ec_private_key.h"
|
||||
#include "wolfssl_ec_public_key.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/oid.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_wolfssl_ec_private_key_t private_wolfssl_ec_private_key_t;
|
||||
|
||||
/**
|
||||
* Private data of a wolfssl_ec_private_key_t object.
|
||||
*/
|
||||
struct private_wolfssl_ec_private_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_ec_private_key_t public;
|
||||
|
||||
/**
|
||||
* Key size
|
||||
*/
|
||||
int keysize;
|
||||
|
||||
/**
|
||||
* EC key object
|
||||
*/
|
||||
ecc_key ec;
|
||||
|
||||
/**
|
||||
* Random number generator
|
||||
*/
|
||||
WC_RNG rng;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/* from ec public key */
|
||||
bool wolfssl_ec_fingerprint(ecc_key *ec, cred_encoding_type_t type, chunk_t *fp);
|
||||
|
||||
/**
|
||||
* Build a signature as in RFC 4754
|
||||
*/
|
||||
static bool build_signature(private_wolfssl_ec_private_key_t *this,
|
||||
chunk_t hash, chunk_t *signature)
|
||||
{
|
||||
bool success = FALSE;
|
||||
mp_int r, s;
|
||||
|
||||
if (mp_init(&r) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (mp_init(&s) != 0)
|
||||
{
|
||||
mp_free(&r);
|
||||
return FALSE;
|
||||
}
|
||||
if (wc_ecc_sign_hash_ex(hash.ptr, hash.len, &this->rng, &this->ec, &r,
|
||||
&s) == 0)
|
||||
{
|
||||
success = wolfssl_mp_cat(this->ec.dp->size * 2, &r, &s, signature);
|
||||
}
|
||||
|
||||
mp_free(&s);
|
||||
mp_free(&r);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a RFC 4754 signature for a specified curve and hash algorithm
|
||||
*/
|
||||
static bool build_curve_signature(private_wolfssl_ec_private_key_t *this,
|
||||
signature_scheme_t scheme,
|
||||
enum wc_HashType hash, ecc_curve_id curve_id,
|
||||
chunk_t data, chunk_t *signature)
|
||||
{
|
||||
chunk_t dgst = chunk_empty;
|
||||
bool success = FALSE;
|
||||
|
||||
if (curve_id != this->ec.dp->id)
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by private key",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
success = build_signature(this, dgst, signature);
|
||||
}
|
||||
chunk_free(&dgst);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a DER encoded signature as in RFC 3279
|
||||
*/
|
||||
static bool build_der_signature(private_wolfssl_ec_private_key_t *this,
|
||||
enum wc_HashType hash, chunk_t data,
|
||||
chunk_t *signature)
|
||||
{
|
||||
chunk_t dgst = chunk_empty;
|
||||
bool success = FALSE;
|
||||
word32 len;
|
||||
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
*signature = chunk_alloc(wc_ecc_sig_size(&this->ec));
|
||||
len = signature->len;
|
||||
if (wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len,
|
||||
&this->rng, &this->ec) == 0)
|
||||
{
|
||||
signature->len = len;
|
||||
success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_free(signature);
|
||||
}
|
||||
}
|
||||
chunk_free(&dgst);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, sign, bool,
|
||||
private_wolfssl_ec_private_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t *signature)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_ECDSA_WITH_NULL:
|
||||
return build_signature(this, data, signature);
|
||||
#ifndef NO_SHA
|
||||
case SIGN_ECDSA_WITH_SHA1_DER:
|
||||
return build_der_signature(this, WC_HASH_TYPE_SHA, data, signature);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case SIGN_ECDSA_WITH_SHA256_DER:
|
||||
return build_der_signature(this, WC_HASH_TYPE_SHA256, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SIGN_ECDSA_WITH_SHA384_DER:
|
||||
return build_der_signature(this, WC_HASH_TYPE_SHA384, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SIGN_ECDSA_WITH_SHA512_DER:
|
||||
return build_der_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case SIGN_ECDSA_256:
|
||||
return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA256,
|
||||
ECC_SECP256R1, data, signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SIGN_ECDSA_384:
|
||||
return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA384,
|
||||
ECC_SECP384R1, data, signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SIGN_ECDSA_521:
|
||||
return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
|
||||
ECC_SECP521R1, data, signature);
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(private_key_t, decrypt, bool,
|
||||
private_wolfssl_ec_private_key_t *this, encryption_scheme_t scheme,
|
||||
chunk_t crypto, chunk_t *plain)
|
||||
{
|
||||
DBG1(DBG_LIB, "EC private key decryption not implemented");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_keysize, int,
|
||||
private_wolfssl_ec_private_key_t *this)
|
||||
{
|
||||
return this->keysize;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_type, key_type_t,
|
||||
private_wolfssl_ec_private_key_t *this)
|
||||
{
|
||||
return KEY_ECDSA;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_public_key, public_key_t*,
|
||||
private_wolfssl_ec_private_key_t *this)
|
||||
{
|
||||
public_key_t *public;
|
||||
chunk_t key;
|
||||
int len;
|
||||
|
||||
/* space for algorithmIdentifier/bitString + one byte for the point type */
|
||||
key = chunk_alloc(2 * this->ec.dp->size + 2 * MAX_SEQ_SZ + 2 * MAX_ALGO_SZ +
|
||||
TRAILING_ZERO + 1);
|
||||
len = wc_EccPublicKeyToDer(&this->ec, key.ptr, key.len, 1);
|
||||
if (len < 0)
|
||||
{
|
||||
chunk_free(&key);
|
||||
return NULL;
|
||||
}
|
||||
key.len = len;
|
||||
|
||||
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
|
||||
BUILD_BLOB_ASN1_DER, key, BUILD_END);
|
||||
free(key.ptr);
|
||||
return public;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_fingerprint, bool,
|
||||
private_wolfssl_ec_private_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_ec_fingerprint(&this->ec, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_encoding, bool,
|
||||
private_wolfssl_ec_private_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *encoding)
|
||||
{
|
||||
bool success = TRUE;
|
||||
int len;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PRIVKEY_ASN1_DER:
|
||||
case PRIVKEY_PEM:
|
||||
/* include space for parameters, public key and contexts */
|
||||
*encoding = chunk_alloc(3 * this->ec.dp->size + 4 * MAX_SEQ_SZ +
|
||||
MAX_VERSION_SZ + MAX_ALGO_SZ);
|
||||
len = wc_EccKeyToDer(&this->ec, encoding->ptr, encoding->len);
|
||||
if (len < 0)
|
||||
{
|
||||
chunk_free(encoding);
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = len;
|
||||
|
||||
if (type == PRIVKEY_PEM)
|
||||
{
|
||||
chunk_t asn1_encoding = *encoding;
|
||||
|
||||
success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
|
||||
NULL, encoding, CRED_PART_ECDSA_PRIV_ASN1_DER,
|
||||
asn1_encoding, CRED_PART_END);
|
||||
chunk_clear(&asn1_encoding);
|
||||
}
|
||||
return success;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_ref, private_key_t*,
|
||||
private_wolfssl_ec_private_key_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.key;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, destroy, void,
|
||||
private_wolfssl_ec_private_key_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
lib->encoding->clear_cache(lib->encoding, &this->ec);
|
||||
wc_FreeRng(&this->rng);
|
||||
wc_ecc_free(&this->ec);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal generic constructor
|
||||
*/
|
||||
static private_wolfssl_ec_private_key_t *create_empty(void)
|
||||
{
|
||||
private_wolfssl_ec_private_key_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.key = {
|
||||
.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,
|
||||
);
|
||||
|
||||
if (wc_InitRng(&this->rng) < 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "RNG init failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_ec_private_key_t *this;
|
||||
u_int key_size = 0;
|
||||
ecc_curve_id curve_id;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_KEY_SIZE:
|
||||
key_size = va_arg(args, u_int);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!key_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->keysize = key_size;
|
||||
switch (key_size)
|
||||
{
|
||||
case 256:
|
||||
curve_id = ECC_SECP256R1;
|
||||
break;
|
||||
case 384:
|
||||
curve_id = ECC_SECP384R1;
|
||||
break;
|
||||
case 521:
|
||||
curve_id = ECC_SECP521R1;
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_LIB, "EC private key size %d not supported", key_size);
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_ecc_make_key_ex(&this->rng, (key_size + 7) / 8, &this->ec,
|
||||
curve_id) < 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "EC private key generation failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_ec_private_key_t *this;
|
||||
chunk_t params = chunk_empty, key = chunk_empty;
|
||||
word32 idx;
|
||||
int oid = OID_UNKNOWN;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ALGID_PARAMS:
|
||||
params = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
key = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!key.ptr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
if (wc_EccPrivateKeyDecode(key.ptr, &idx, &this->ec, key.len) < 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
switch (this->ec.dp->id)
|
||||
{
|
||||
case ECC_SECP256R1:
|
||||
this->keysize = 256;
|
||||
break;
|
||||
case ECC_SECP384R1:
|
||||
this->keysize = 384;
|
||||
break;
|
||||
case ECC_SECP521R1:
|
||||
this->keysize = 521;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (params.ptr)
|
||||
{
|
||||
/* if ECParameters is passed, ensure we guessed correctly */
|
||||
if (asn1_unwrap(¶ms, ¶ms) == ASN1_OID)
|
||||
{
|
||||
oid = asn1_known_oid(params);
|
||||
switch (oid)
|
||||
{
|
||||
case OID_PRIME256V1:
|
||||
if (this->ec.dp->id != ECC_SECP256R1)
|
||||
{
|
||||
oid = OID_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
case OID_SECT384R1:
|
||||
if (this->ec.dp->id != ECC_SECP384R1)
|
||||
{
|
||||
oid = OID_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
case OID_SECT521R1:
|
||||
if (this->ec.dp->id != ECC_SECP521R1)
|
||||
{
|
||||
oid = OID_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
oid = OID_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oid == OID_UNKNOWN)
|
||||
{
|
||||
DBG1(DBG_LIB, "parameters do not match private key data");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC_SIGN */
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_ec_private_key wolfssl_ec_private_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_EC_PRIVATE_KEY_H_
|
||||
#define WOLFSSL_EC_PRIVATE_KEY_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
|
||||
typedef struct wolfssl_ec_private_key_t wolfssl_ec_private_key_t;
|
||||
|
||||
/**
|
||||
* private_key_t implementation of ECDSA using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_ec_private_key_t {
|
||||
|
||||
/**
|
||||
* Implements private_key_t interface
|
||||
*/
|
||||
private_key_t key;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a ECDSA private key using wolfSSL.
|
||||
*
|
||||
* Accepts the BUILD_KEY_SIZE argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ECDSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return generated key, NULL on failure
|
||||
*/
|
||||
wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
/**
|
||||
* Load a ECDSA private key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ECDSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
#endif /** WOLFSSL_EC_PRIVATE_KEY_H_ @}*/
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_ECC_VERIFY
|
||||
|
||||
#include "wolfssl_ec_public_key.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_wolfssl_ec_public_key_t private_wolfssl_ec_public_key_t;
|
||||
|
||||
/**
|
||||
* Private data structure with signing context.
|
||||
*/
|
||||
struct private_wolfssl_ec_public_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_ec_public_key_t public;
|
||||
|
||||
/**
|
||||
* Key size
|
||||
*/
|
||||
int keysize;
|
||||
|
||||
/**
|
||||
* EC key object
|
||||
*/
|
||||
ecc_key ec;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* Verification of a signature as in RFC 4754
|
||||
*/
|
||||
static bool verify_signature(private_wolfssl_ec_public_key_t *this,
|
||||
chunk_t hash, chunk_t signature)
|
||||
{
|
||||
int stat = 1, ret = -1;
|
||||
mp_int r, s;
|
||||
|
||||
if (mp_init(&r) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (mp_init(&s) < 0)
|
||||
{
|
||||
mp_free(&r);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wolfssl_mp_split(signature, &r, &s))
|
||||
{
|
||||
ret = wc_ecc_verify_hash_ex(&r, &s, hash.ptr, hash.len, &stat,
|
||||
&this->ec);
|
||||
}
|
||||
mp_free(&s);
|
||||
mp_free(&r);
|
||||
return ret == 0 && stat == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a RFC 4754 signature for a specified curve and hash algorithm
|
||||
*/
|
||||
static bool verify_curve_signature(private_wolfssl_ec_public_key_t *this,
|
||||
signature_scheme_t scheme,
|
||||
enum wc_HashType hash, ecc_curve_id curve_id,
|
||||
chunk_t data, chunk_t signature)
|
||||
{
|
||||
bool success = FALSE;
|
||||
chunk_t dgst;
|
||||
|
||||
if (curve_id != this->ec.dp->id)
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by private key",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
success = verify_signature(this, dgst, signature);
|
||||
}
|
||||
|
||||
chunk_free(&dgst);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verification of a DER encoded signature as in RFC 3279
|
||||
*/
|
||||
static bool verify_der_signature(private_wolfssl_ec_public_key_t *this,
|
||||
enum wc_HashType hash, chunk_t data,
|
||||
chunk_t signature)
|
||||
{
|
||||
chunk_t dgst;
|
||||
int stat = 1, ret = -1;
|
||||
|
||||
signature = chunk_skip_zero(signature);
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
ret = wc_ecc_verify_hash(signature.ptr, signature.len, dgst.ptr,
|
||||
dgst.len, &stat, &this->ec);
|
||||
}
|
||||
chunk_free(&dgst);
|
||||
return ret == 0 && stat == 1;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_type, key_type_t,
|
||||
private_wolfssl_ec_public_key_t *this)
|
||||
{
|
||||
return KEY_ECDSA;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, verify, bool,
|
||||
private_wolfssl_ec_public_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t signature)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
#ifndef NO_SHA
|
||||
case SIGN_ECDSA_WITH_SHA1_DER:
|
||||
return verify_der_signature(this, WC_HASH_TYPE_SHA, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case SIGN_ECDSA_WITH_SHA256_DER:
|
||||
return verify_der_signature(this, WC_HASH_TYPE_SHA256, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SIGN_ECDSA_WITH_SHA384_DER:
|
||||
return verify_der_signature(this, WC_HASH_TYPE_SHA384, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SIGN_ECDSA_WITH_SHA512_DER:
|
||||
return verify_der_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
#endif
|
||||
case SIGN_ECDSA_WITH_NULL:
|
||||
return verify_signature(this, data, signature);
|
||||
#ifndef NO_SHA256
|
||||
case SIGN_ECDSA_256:
|
||||
return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA256,
|
||||
ECC_SECP256R1, data, signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SIGN_ECDSA_384:
|
||||
return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA384,
|
||||
ECC_SECP384R1, data, signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SIGN_ECDSA_521:
|
||||
return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
|
||||
ECC_SECP521R1, data, signature);
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(public_key_t, encrypt, bool,
|
||||
private_wolfssl_ec_public_key_t *this, encryption_scheme_t scheme,
|
||||
chunk_t crypto, chunk_t *plain)
|
||||
{
|
||||
DBG1(DBG_LIB, "EC public key encryption not implemented");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_keysize, int,
|
||||
private_wolfssl_ec_public_key_t *this)
|
||||
{
|
||||
return this->keysize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fingerprint from an EC key, also used in ec private key.
|
||||
*/
|
||||
bool wolfssl_ec_fingerprint(ecc_key *ec, cred_encoding_type_t type, chunk_t *fp)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t key;
|
||||
int len;
|
||||
|
||||
if (lib->encoding->get_cache(lib->encoding, type, ec, fp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case KEYID_PUBKEY_SHA1:
|
||||
case KEYID_PUBKEY_INFO_SHA1:
|
||||
/* need an additional byte for the point type */
|
||||
len = ec->dp->size * 2 + 1;
|
||||
if (type == KEYID_PUBKEY_INFO_SHA1)
|
||||
{
|
||||
/* additional space for algorithmIdentifier/bitString */
|
||||
len += 2 * MAX_SEQ_SZ + 2 * MAX_ALGO_SZ + TRAILING_ZERO;
|
||||
}
|
||||
key = chunk_alloca(len);
|
||||
len = wc_EccPublicKeyToDer(ec, key.ptr, key.len,
|
||||
type == KEYID_PUBKEY_INFO_SHA1);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
if (len < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
key.len = len;
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (!hasher || !hasher->allocate_hash(hasher, key, fp))
|
||||
{
|
||||
DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
|
||||
DESTROY_IF(hasher);
|
||||
return FALSE;
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
lib->encoding->cache(lib->encoding, type, ec, *fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_fingerprint, bool,
|
||||
private_wolfssl_ec_public_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_ec_fingerprint(&this->ec, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_encoding, bool,
|
||||
private_wolfssl_ec_public_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *encoding)
|
||||
{
|
||||
bool success = TRUE;
|
||||
int len;
|
||||
|
||||
/* space for algorithmIdentifier/bitString + one byte for the point type */
|
||||
*encoding = chunk_alloc(2 * this->ec.dp->size + 2 * MAX_SEQ_SZ +
|
||||
2 * MAX_ALGO_SZ + TRAILING_ZERO + 1);
|
||||
len = wc_EccPublicKeyToDer(&this->ec, encoding->ptr, encoding->len, 1);
|
||||
if (len < 0)
|
||||
{
|
||||
chunk_free(encoding);
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = len;
|
||||
|
||||
if (type != PUBKEY_SPKI_ASN1_DER)
|
||||
{
|
||||
chunk_t asn1_encoding = *encoding;
|
||||
|
||||
success = lib->encoding->encode(lib->encoding, type,
|
||||
NULL, encoding, CRED_PART_ECDSA_PUB_ASN1_DER,
|
||||
asn1_encoding, CRED_PART_END);
|
||||
chunk_clear(&asn1_encoding);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_ref, public_key_t*,
|
||||
private_wolfssl_ec_public_key_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.key;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, destroy, void,
|
||||
private_wolfssl_ec_public_key_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
lib->encoding->clear_cache(lib->encoding, &this->ec);
|
||||
wc_ecc_free(&this->ec);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic private constructor
|
||||
*/
|
||||
static private_wolfssl_ec_public_key_t *create_empty()
|
||||
{
|
||||
private_wolfssl_ec_public_key_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.key = {
|
||||
.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,
|
||||
);
|
||||
|
||||
if (wc_ecc_init(&this->ec) < 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_ec_public_key_t *this;
|
||||
chunk_t blob = chunk_empty;
|
||||
word32 idx;
|
||||
int ret;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
ret = wc_EccPublicKeyDecode(blob.ptr, &idx, &this->ec, blob.len);
|
||||
if (ret < 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
switch (this->ec.dp->id)
|
||||
{
|
||||
case ECC_SECP256R1:
|
||||
this->keysize = 256;
|
||||
break;
|
||||
case ECC_SECP384R1:
|
||||
this->keysize = 384;
|
||||
break;
|
||||
case ECC_SECP521R1:
|
||||
this->keysize = 521;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC_VERIFY */
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_ec_public_key wolfssl_ec_public_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_EC_PUBLIC_KEY_H_
|
||||
#define WOLFSSL_EC_PUBLIC_KEY_H_
|
||||
|
||||
typedef struct wolfssl_ec_public_key_t wolfssl_ec_public_key_t;
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* public_key_t implementation of ECDSA using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_ec_public_key_t {
|
||||
|
||||
/**
|
||||
* Implements the public_key_t interface
|
||||
*/
|
||||
public_key_t key;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a ECDSA public key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ECDSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
#endif /** WOLFSSL_EC_PUBLIC_KEY_H_ @}*/
|
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_ED25519
|
||||
|
||||
#include "wolfssl_ed_private_key.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_private_key_t private_private_key_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_private_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
private_key_t public;
|
||||
|
||||
/**
|
||||
* Key object
|
||||
*/
|
||||
ed25519_key key;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/* from ed public key */
|
||||
bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
|
||||
chunk_t *fp);
|
||||
|
||||
METHOD(private_key_t, sign, bool,
|
||||
private_private_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t *signature)
|
||||
{
|
||||
word32 len;
|
||||
byte dummy[1];
|
||||
int ret;
|
||||
|
||||
if (scheme != SIGN_ED25519)
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
|
||||
signature_scheme_names, scheme, key_type_names, KEY_ED25519);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!data.ptr && !data.len)
|
||||
{
|
||||
data.ptr = dummy;
|
||||
}
|
||||
|
||||
len = ED25519_SIG_SIZE;
|
||||
*signature = chunk_alloc(len);
|
||||
ret = wc_ed25519_sign_msg(data.ptr, data.len, signature->ptr, &len,
|
||||
&this->key);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
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_SIZE * 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)
|
||||
{
|
||||
public_key_t *public;
|
||||
chunk_t key;
|
||||
word32 len = ED25519_PUB_KEY_SIZE;
|
||||
|
||||
key = chunk_alloca(len);
|
||||
if (wc_ed25519_export_public(&this->key, key.ptr, &len) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
|
||||
BUILD_EDDSA_PUB, key, BUILD_END);
|
||||
return public;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_fingerprint, bool,
|
||||
private_private_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_ed_fingerprint(&this->key, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_encoding, bool,
|
||||
private_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PRIVKEY_ASN1_DER:
|
||||
case PRIVKEY_PEM:
|
||||
{
|
||||
bool success = TRUE;
|
||||
|
||||
/* +4 is for the two octet strings */
|
||||
*encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 2 * MAX_SEQ_SZ +
|
||||
MAX_VERSION_SZ + MAX_ALGO_SZ + 4);
|
||||
ret = wc_Ed25519PrivateKeyToDer(&this->key, encoding->ptr,
|
||||
encoding->len);
|
||||
if (ret < 0)
|
||||
{
|
||||
chunk_free(encoding);
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = ret;
|
||||
|
||||
if (type == PRIVKEY_PEM)
|
||||
{
|
||||
chunk_t asn1_encoding = *encoding;
|
||||
|
||||
success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
|
||||
NULL, encoding, CRED_PART_EDDSA_PRIV_ASN1_DER,
|
||||
asn1_encoding, CRED_PART_END);
|
||||
chunk_clear(&asn1_encoding);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
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->key);
|
||||
wc_ed25519_free(&this->key);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal generic constructor
|
||||
*/
|
||||
static private_private_key_t *create_internal()
|
||||
{
|
||||
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,
|
||||
);
|
||||
|
||||
if (wc_ed25519_init(&this->key) != 0)
|
||||
{
|
||||
free(this);
|
||||
this = NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args)
|
||||
{
|
||||
private_private_key_t *this;
|
||||
WC_RNG rng;
|
||||
int ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
this = create_internal();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "initializing random failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &this->key);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "generating %N key failed", key_type_names, type);
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the internal state if only the private key is set
|
||||
*/
|
||||
static int set_public_key(private_private_key_t *this)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!this->key.pubKeySet)
|
||||
{
|
||||
ret = wc_ed25519_make_public(&this->key, this->key.p,
|
||||
ED25519_PUB_KEY_SIZE);
|
||||
if (ret == 0)
|
||||
{
|
||||
/* put public key after private key in the same buffer */
|
||||
memmove(this->key.k + ED25519_KEY_SIZE, this->key.p,
|
||||
ED25519_PUB_KEY_SIZE);
|
||||
this->key.pubKeySet = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
private_key_t *wolfssl_ed_private_key_load(key_type_t type, va_list args)
|
||||
{
|
||||
private_private_key_t *this;
|
||||
chunk_t blob = chunk_empty, priv = chunk_empty;
|
||||
int idx;
|
||||
int ret = -1;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_EDDSA_PRIV_ASN1_DER:
|
||||
priv = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this = create_internal();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (priv.len)
|
||||
{
|
||||
/* check for ASN.1 wrapped key (Octet String == 0x04) */
|
||||
if (priv.len == ED25519_KEY_SIZE + 2 && priv.ptr[0] == 0x04 &&
|
||||
priv.ptr[1] == ED25519_KEY_SIZE)
|
||||
{
|
||||
priv = chunk_skip(priv, 2);
|
||||
}
|
||||
ret = wc_ed25519_import_private_only(priv.ptr, priv.len, &this->key);
|
||||
}
|
||||
else if (blob.len)
|
||||
{
|
||||
idx = 0;
|
||||
ret = wc_Ed25519PrivateKeyDecode(blob.ptr, &idx, &this->key, blob.len);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = set_public_key(this);
|
||||
}
|
||||
if (ret != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ED25519 */
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_ed_private_key wolfssl_ed_private_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_ED_PRIVATE_KEY_H_
|
||||
#define WOLFSSL_ED_PRIVATE_KEY_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
|
||||
/**
|
||||
* Generate an EdDSA private key using wolfSSL.
|
||||
*
|
||||
* @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 *wolfssl_ed_private_key_gen(key_type_t type, va_list args);
|
||||
|
||||
/**
|
||||
* Load an EdDSA private key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @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 *wolfssl_ed_private_key_load(key_type_t type, va_list args);
|
||||
|
||||
#endif /** WOLFSSL_ED_PRIVATE_KEY_H_ @}*/
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_ED25519
|
||||
|
||||
#include "wolfssl_ed_public_key.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_public_key_t private_public_key_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_public_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
public_key_t public;
|
||||
|
||||
/**
|
||||
* Key object
|
||||
*/
|
||||
ed25519_key key;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(public_key_t, get_type, key_type_t,
|
||||
private_public_key_t *this)
|
||||
{
|
||||
return KEY_ED25519;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, verify, bool,
|
||||
private_public_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t signature)
|
||||
{
|
||||
byte dummy[1];
|
||||
int ret, res;
|
||||
|
||||
if (scheme != SIGN_ED25519)
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
|
||||
signature_scheme_names, scheme, key_type_names, KEY_ED25519);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!data.ptr && !data.len)
|
||||
{
|
||||
data.ptr = dummy;
|
||||
}
|
||||
|
||||
ret = wc_ed25519_verify_msg(signature.ptr, signature.len, data.ptr,
|
||||
data.len, &res, &this->key);
|
||||
return ret == 0 && res == 1;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, encrypt, bool,
|
||||
private_public_key_t *this, encryption_scheme_t scheme,
|
||||
chunk_t crypto, chunk_t *plain)
|
||||
{
|
||||
DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names,
|
||||
scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_keysize, int,
|
||||
private_public_key_t *this)
|
||||
{
|
||||
return ED25519_KEY_SIZE * 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given public key as ASN.1 DER with algorithm identifier
|
||||
*/
|
||||
static bool encode_pubkey(ed25519_key *key, chunk_t *encoding)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* account for algorithmIdentifier/bitString */
|
||||
*encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ +
|
||||
MAX_ALGO_SZ + TRAILING_ZERO);
|
||||
ret = wc_Ed25519PublicKeyToDer(key, encoding->ptr, encoding->len, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fingerprint from an EdDSA key, also used in ed private key.
|
||||
*/
|
||||
bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
|
||||
chunk_t *fp)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t blob;
|
||||
word32 len;
|
||||
bool success = FALSE;
|
||||
|
||||
if (lib->encoding->get_cache(lib->encoding, type, key, fp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case KEYID_PUBKEY_SHA1:
|
||||
len = ED25519_PUB_KEY_SIZE;
|
||||
blob = chunk_alloc(len);
|
||||
if (wc_ed25519_export_public(key, blob.ptr, &len) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case KEYID_PUBKEY_INFO_SHA1:
|
||||
if (!encode_pubkey(key, &blob))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (!hasher || !hasher->allocate_hash(hasher, blob, fp))
|
||||
{
|
||||
DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, key, *fp);
|
||||
success = TRUE;
|
||||
}
|
||||
DESTROY_IF(hasher);
|
||||
chunk_free(&blob);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_fingerprint, bool,
|
||||
private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_ed_fingerprint(&this->key, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_encoding, bool,
|
||||
private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
|
||||
{
|
||||
bool success = TRUE;
|
||||
|
||||
if (!encode_pubkey(&this->key, encoding))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (type != PUBKEY_SPKI_ASN1_DER)
|
||||
{
|
||||
chunk_t asn1_encoding = *encoding;
|
||||
|
||||
success = lib->encoding->encode(lib->encoding, type,
|
||||
NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER,
|
||||
asn1_encoding, CRED_PART_END);
|
||||
chunk_free(&asn1_encoding);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
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->key);
|
||||
wc_ed25519_free(&this->key);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic private 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,
|
||||
);
|
||||
|
||||
if (wc_ed25519_init(&this->key) != 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
public_key_t *wolfssl_ed_public_key_load(key_type_t type, va_list args)
|
||||
{
|
||||
private_public_key_t *this;
|
||||
chunk_t blob = chunk_empty, pub = chunk_empty;
|
||||
int idx;
|
||||
int ret = -1;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_EDDSA_PUB:
|
||||
pub = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pub.len)
|
||||
{
|
||||
ret = wc_ed25519_import_public(pub.ptr, pub.len, &this->key);
|
||||
}
|
||||
else if (blob.len)
|
||||
{
|
||||
idx = 0;
|
||||
ret = wc_Ed25519PublicKeyDecode(blob.ptr, &idx, &this->key, blob.len);
|
||||
}
|
||||
if (ret != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ED25519 */
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_ed_public_key wolfssl_ed_public_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_ED_PUBLIC_KEY_H_
|
||||
#define WOLFSSL_ED_PUBLIC_KEY_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* Load an EdDSA public key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @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 *wolfssl_ed_public_key_load(key_type_t type, va_list args);
|
||||
|
||||
#endif /** WOLFSSL_ED_PUBLIC_KEY_H_ @}*/
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
#include "wolfssl_hasher.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
|
||||
typedef struct private_wolfssl_hasher_t private_wolfssl_hasher_t;
|
||||
|
||||
/**
|
||||
* Private data of wolfssl_hasher_t
|
||||
*/
|
||||
struct private_wolfssl_hasher_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_hasher_t public;
|
||||
|
||||
/**
|
||||
* The hasher to use
|
||||
*/
|
||||
wc_HashAlg hasher;
|
||||
|
||||
/**
|
||||
* The hash algorithm
|
||||
*/
|
||||
enum wc_HashType type;
|
||||
};
|
||||
|
||||
METHOD(hasher_t, get_hash_size, size_t,
|
||||
private_wolfssl_hasher_t *this)
|
||||
{
|
||||
return wc_HashGetDigestSize(this->type);
|
||||
}
|
||||
|
||||
METHOD(hasher_t, reset, bool,
|
||||
private_wolfssl_hasher_t *this)
|
||||
{
|
||||
return wc_HashInit(&this->hasher, this->type) == 0;
|
||||
}
|
||||
|
||||
METHOD(hasher_t, get_hash, bool,
|
||||
private_wolfssl_hasher_t *this, chunk_t chunk, uint8_t *hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = wc_HashUpdate(&this->hasher, this->type, chunk.ptr, chunk.len);
|
||||
if (ret == 0 && hash)
|
||||
{
|
||||
ret = wc_HashFinal(&this->hasher, this->type, hash);
|
||||
if (ret == 0)
|
||||
{
|
||||
return reset(this);
|
||||
}
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(hasher_t, allocate_hash, bool,
|
||||
private_wolfssl_hasher_t *this, chunk_t chunk, chunk_t *hash)
|
||||
{
|
||||
if (hash)
|
||||
{
|
||||
*hash = chunk_alloc(get_hash_size(this));
|
||||
return get_hash(this, chunk, hash->ptr);
|
||||
}
|
||||
return get_hash(this, chunk, NULL);
|
||||
}
|
||||
|
||||
METHOD(hasher_t, destroy, void,
|
||||
private_wolfssl_hasher_t *this)
|
||||
{
|
||||
wc_HashFree(&this->hasher, this->type);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_hasher_t *wolfssl_hasher_create(hash_algorithm_t algo)
|
||||
{
|
||||
private_wolfssl_hasher_t *this;
|
||||
enum wc_HashType type;
|
||||
|
||||
if (!wolfssl_hash2type(algo, &type))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.hasher = {
|
||||
.get_hash = _get_hash,
|
||||
.allocate_hash = _allocate_hash,
|
||||
.get_hash_size = _get_hash_size,
|
||||
.reset = _reset,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.type = type,
|
||||
);
|
||||
|
||||
/* initialization */
|
||||
if (!reset(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_hasher wolfssl_hasher
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_HASHER_H_
|
||||
#define WOLFSSL_HASHER_H_
|
||||
|
||||
typedef struct wolfssl_hasher_t wolfssl_hasher_t;
|
||||
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
/**
|
||||
* Implementation of hashers using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_hasher_t {
|
||||
|
||||
/**
|
||||
* Implements hasher_t interface.
|
||||
*/
|
||||
hasher_t hasher;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor to create wolfssl_hasher_t.
|
||||
*
|
||||
* @param algo algorithm
|
||||
* @return wolfssl_hasher_t, NULL if not supported
|
||||
*/
|
||||
wolfssl_hasher_t *wolfssl_hasher_create(hash_algorithm_t algo);
|
||||
|
||||
#endif /** WOLFSSL_HASHER_H_ @}*/
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifndef NO_HMAC
|
||||
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
|
||||
#include "wolfssl_hmac.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <crypto/mac.h>
|
||||
#include <crypto/prfs/mac_prf.h>
|
||||
#include <crypto/signers/mac_signer.h>
|
||||
|
||||
typedef struct private_mac_t private_mac_t;
|
||||
|
||||
/**
|
||||
* Private data of a mac_t object.
|
||||
*/
|
||||
struct private_mac_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
mac_t public;
|
||||
|
||||
/**
|
||||
* Current HMAC
|
||||
*/
|
||||
Hmac hmac;
|
||||
|
||||
/**
|
||||
* Hasher to use
|
||||
*/
|
||||
enum wc_HashType type;
|
||||
|
||||
/**
|
||||
* Key set on Hmac?
|
||||
*/
|
||||
bool key_set;
|
||||
};
|
||||
|
||||
METHOD(mac_t, set_key, bool,
|
||||
private_mac_t *this, chunk_t key)
|
||||
{
|
||||
int ret = wc_HmacSetKey(&this->hmac, this->type, key.ptr, key.len);
|
||||
this->key_set = (ret == 0);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(mac_t, get_mac, bool,
|
||||
private_mac_t *this, chunk_t data, uint8_t *out)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (this->key_set)
|
||||
{
|
||||
ret = wc_HmacUpdate(&this->hmac, data.ptr, data.len);
|
||||
if (ret == 0 && out)
|
||||
{
|
||||
ret = wc_HmacFinal(&this->hmac, out);
|
||||
}
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(mac_t, get_mac_size, size_t,
|
||||
private_mac_t *this)
|
||||
{
|
||||
return wc_HmacSizeByType(this->type);
|
||||
}
|
||||
|
||||
METHOD(mac_t, destroy, void,
|
||||
private_mac_t *this)
|
||||
{
|
||||
wc_HmacFree(&this->hmac);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an wolfSSL-backed implementation of the mac_t interface
|
||||
*/
|
||||
static mac_t *hmac_create(hash_algorithm_t algo)
|
||||
{
|
||||
private_mac_t *this;
|
||||
enum wc_HashType type;
|
||||
|
||||
if (!wolfssl_hash2type(algo, &type))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_mac = _get_mac,
|
||||
.get_mac_size = _get_mac_size,
|
||||
.set_key = _set_key,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = type,
|
||||
);
|
||||
|
||||
if (wc_HmacInit(&this->hmac, NULL, INVALID_DEVID) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "HMAC init failed, hmac create failed\n");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
prf_t *wolfssl_hmac_prf_create(pseudo_random_function_t algo)
|
||||
{
|
||||
mac_t *hmac;
|
||||
|
||||
hmac = hmac_create(hasher_algorithm_from_prf(algo));
|
||||
if (hmac)
|
||||
{
|
||||
return mac_prf_create(hmac);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
signer_t *wolfssl_hmac_signer_create(integrity_algorithm_t algo)
|
||||
{
|
||||
mac_t *hmac;
|
||||
size_t trunc;
|
||||
|
||||
hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
|
||||
if (hmac)
|
||||
{
|
||||
return mac_signer_create(hmac, trunc);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* NO_HMAC */
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements HMAC based PRF and signer using wolfSSL's HMAC functions.
|
||||
*
|
||||
* @defgroup wolfssl_hmac wolfssl_hmac
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_HMAC_H_
|
||||
#define WOLFSSL_HMAC_H_
|
||||
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
|
||||
/**
|
||||
* Creates a new prf_t object based on an HMAC.
|
||||
*
|
||||
* @param algo algorithm to implement
|
||||
* @return prf_t object, NULL if not supported
|
||||
*/
|
||||
prf_t *wolfssl_hmac_prf_create(pseudo_random_function_t algo);
|
||||
|
||||
/**
|
||||
* Creates a new signer_t object based on an HMAC.
|
||||
*
|
||||
* @param algo algorithm to implement
|
||||
* @return signer_t, NULL if not supported
|
||||
*/
|
||||
signer_t *wolfssl_hmac_signer_create(integrity_algorithm_t algo);
|
||||
|
||||
#endif /** WOLFSSL_HMAC_H_ @}*/
|
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 <library.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "wolfssl_common.h"
|
||||
#include "wolfssl_plugin.h"
|
||||
#include "wolfssl_aead.h"
|
||||
#include "wolfssl_crypter.h"
|
||||
#include "wolfssl_diffie_hellman.h"
|
||||
#include "wolfssl_ec_diffie_hellman.h"
|
||||
#include "wolfssl_ec_private_key.h"
|
||||
#include "wolfssl_ec_public_key.h"
|
||||
#include "wolfssl_ed_private_key.h"
|
||||
#include "wolfssl_ed_public_key.h"
|
||||
#include "wolfssl_hasher.h"
|
||||
#include "wolfssl_hmac.h"
|
||||
#include "wolfssl_rsa_private_key.h"
|
||||
#include "wolfssl_rsa_public_key.h"
|
||||
#include "wolfssl_rng.h"
|
||||
#include "wolfssl_sha1_prf.h"
|
||||
#include "wolfssl_x_diffie_hellman.h"
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
#define FIPS_MODE 0
|
||||
#endif
|
||||
|
||||
typedef struct private_wolfssl_plugin_t private_wolfssl_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data of wolfssl_plugin
|
||||
*/
|
||||
struct private_wolfssl_plugin_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_wolfssl_plugin_t *this)
|
||||
{
|
||||
return "wolfssl";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_wolfssl_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
/* crypters */
|
||||
PLUGIN_REGISTER(CRYPTER, wolfssl_crypter_create),
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CTR)
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32),
|
||||
#endif
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
|
||||
#ifdef WOLFSSL_DES_ECB
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
|
||||
#endif
|
||||
#endif
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0),
|
||||
/* hashers */
|
||||
PLUGIN_REGISTER(HASHER, wolfssl_hasher_create),
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(HASHER, HASH_MD5),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA1),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA224),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA512),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
/* keyed sha1 hasher (aka prf) */
|
||||
PLUGIN_REGISTER(PRF, wolfssl_sha1_prf_create),
|
||||
PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
|
||||
#endif
|
||||
#ifndef NO_HMAC
|
||||
PLUGIN_REGISTER(PRF, wolfssl_hmac_prf_create),
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
|
||||
#endif
|
||||
PLUGIN_REGISTER(SIGNER, wolfssl_hmac_signer_create),
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
|
||||
PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512),
|
||||
#endif
|
||||
#endif /* NO_HMAC */
|
||||
#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))) || \
|
||||
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
|
||||
PLUGIN_REGISTER(AEAD, wolfssl_aead_create),
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
|
||||
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
|
||||
#endif
|
||||
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
|
||||
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
|
||||
#endif /* !NO_AES && HAVE_AESGCM */
|
||||
#if !defined(NO_AES) && defined(HAVE_AESCCM)
|
||||
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 /* !NO_AES && HAVE_AESCCM */
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
|
||||
#endif /* HAVE_CHACHA && HAVE_POLY1305 */
|
||||
#endif
|
||||
#ifdef HAVE_ECC_DHE
|
||||
/* EC DH groups */
|
||||
PLUGIN_REGISTER(DH, wolfssl_ec_diffie_hellman_create),
|
||||
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_256_BIT),
|
||||
#endif
|
||||
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_384_BIT),
|
||||
#endif
|
||||
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_521_BIT),
|
||||
#endif
|
||||
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_224_BIT),
|
||||
#endif
|
||||
#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_192_BIT),
|
||||
#endif
|
||||
#ifdef HAVE_BRAINPOOL
|
||||
#if !define(NO_ECC256) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_256_BP),
|
||||
#endif
|
||||
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_384_BP),
|
||||
#endif
|
||||
#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_512_BP),
|
||||
#endif
|
||||
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
|
||||
PLUGIN_PROVIDE(DH, ECP_224_BP),
|
||||
#endif
|
||||
#endif
|
||||
#endif /* HAVE_ECC_DHE */
|
||||
#ifndef NO_DH
|
||||
/* MODP DH groups */
|
||||
PLUGIN_REGISTER(DH, wolfssl_diffie_hellman_create),
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (3072 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_3072_BIT),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (4096 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_4096_BIT),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (6144 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_6144_BIT),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (8192 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_8192_BIT),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (2048 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_2048_BIT),
|
||||
PLUGIN_PROVIDE(DH, MODP_2048_224),
|
||||
PLUGIN_PROVIDE(DH, MODP_2048_256),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (1536 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_1536_BIT),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (1024 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_1024_BIT),
|
||||
PLUGIN_PROVIDE(DH, MODP_1024_160),
|
||||
#endif
|
||||
#if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (768 * 2)
|
||||
PLUGIN_PROVIDE(DH, MODP_768_BIT),
|
||||
#endif
|
||||
PLUGIN_PROVIDE(DH, MODP_CUSTOM),
|
||||
#endif /* NO_DH */
|
||||
#ifndef NO_RSA
|
||||
/* RSA private/public key loading */
|
||||
PLUGIN_REGISTER(PRIVKEY, wolfssl_rsa_private_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
|
||||
PLUGIN_REGISTER(PUBKEY, wolfssl_rsa_public_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_rsa_private_key_gen, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
|
||||
#endif
|
||||
/* signature/encryption schemes */
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
|
||||
#ifdef WC_RSA_PSS
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
#endif
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
|
||||
#ifndef WC_NO_RSA_OAEP
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA1),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA1),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA224),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA224),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA256),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA384),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA512),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA512),
|
||||
#endif
|
||||
#endif /* !WC_NO_RSA_OAEP */
|
||||
#endif /* !NO_RSA */
|
||||
#ifdef HAVE_ECC
|
||||
#ifdef HAVE_ECC_KEY_IMPORT
|
||||
/* EC private/public key loading */
|
||||
PLUGIN_REGISTER(PRIVKEY, wolfssl_ec_private_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
|
||||
#endif
|
||||
#ifdef HAVE_ECC_DHE
|
||||
PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_ec_private_key_gen, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
|
||||
#endif
|
||||
#ifdef HAVE_ECC_KEY_IMPORT
|
||||
PLUGIN_REGISTER(PUBKEY, wolfssl_ec_public_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
|
||||
#endif
|
||||
#ifdef HAVE_ECC_SIGN
|
||||
/* signature encryption schemes */
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
|
||||
#endif
|
||||
#endif /* HAVE_ECC_SIGN */
|
||||
#ifdef HAVE_ECC_VERIFY
|
||||
/* signature encryption schemes */
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
|
||||
#endif
|
||||
#endif /* HAVE_ECC_VERIFY */
|
||||
#endif /* HAVE_ECC */
|
||||
#ifdef HAVE_CURVE25519
|
||||
PLUGIN_REGISTER(DH, wolfssl_x_diffie_hellman_create),
|
||||
PLUGIN_PROVIDE(DH, CURVE_25519),
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
/* EdDSA private/public key loading */
|
||||
PLUGIN_REGISTER(PUBKEY, wolfssl_ed_public_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
|
||||
PLUGIN_REGISTER(PRIVKEY, wolfssl_ed_private_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
|
||||
PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_ed_private_key_gen, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
|
||||
#ifdef HAVE_ED25519_SIGN
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
|
||||
#endif
|
||||
#ifdef HAVE_ED25519_VERIFY
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
|
||||
#endif
|
||||
/* register a pro forma identity hasher, never instantiated */
|
||||
PLUGIN_REGISTER(HASHER, return_null),
|
||||
PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
|
||||
#endif /* HAVE_ED25519 */
|
||||
#ifndef WC_NO_RNG
|
||||
/* generic key loader */
|
||||
PLUGIN_REGISTER(RNG, wolfssl_rng_create),
|
||||
PLUGIN_PROVIDE(RNG, RNG_STRONG),
|
||||
PLUGIN_PROVIDE(RNG, RNG_WEAK),
|
||||
#endif
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_wolfssl_plugin_t *this)
|
||||
{
|
||||
#ifndef WC_NO_RNG
|
||||
wolfssl_rng_global_final();
|
||||
#endif
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
plugin_t *wolfssl_plugin_create()
|
||||
{
|
||||
private_wolfssl_plugin_t *this;
|
||||
bool fips_mode;
|
||||
|
||||
fips_mode = lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.wolfssl.fips_mode", FALSE, lib->ns);
|
||||
#ifdef HAVE_FIPS
|
||||
if (fips_mode)
|
||||
{
|
||||
int ret = wolfCrypt_GetStatus_fips();
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "wolfssl FIPS mode unavailable (%d)", ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (fips_mode)
|
||||
{
|
||||
DBG1(DBG_LIB, "wolfssl FIPS mode unavailable");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
wolfSSL_Init();
|
||||
#ifndef WC_NO_RNG
|
||||
if (!wolfssl_rng_global_init())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_p wolfssl
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup wolfssl_plugin wolfssl_plugin
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_PLUGIN_H_
|
||||
#define WOLFSSL_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct wolfssl_plugin_t wolfssl_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing crypto functions via the wolfSSL library
|
||||
*/
|
||||
struct wolfssl_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** WOLFSSL_PLUGIN_H_ @}*/
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 <wolfssl_common.h>
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
#include "wolfssl_rng.h"
|
||||
|
||||
typedef struct private_wolfssl_rng_t private_wolfssl_rng_t;
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
wolfSSL_Mutex globalRngMutex;
|
||||
#endif
|
||||
static WC_RNG globalRng;
|
||||
static bool globalRngInit;
|
||||
|
||||
/**
|
||||
* Private data of wolfssl_rng_t
|
||||
*/
|
||||
struct private_wolfssl_rng_t {
|
||||
|
||||
/**
|
||||
* Public part of this class.
|
||||
*/
|
||||
wolfssl_rng_t public;
|
||||
|
||||
/**
|
||||
* Random number generator to use
|
||||
* Either own instance or reference to global.
|
||||
*/
|
||||
WC_RNG *rng;
|
||||
};
|
||||
|
||||
METHOD(rng_t, get_bytes, bool,
|
||||
private_wolfssl_rng_t *this, size_t bytes, uint8_t *buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
if (this->rng == &globalRng)
|
||||
{
|
||||
ret = wc_LockMutex(&globalRngMutex);
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "locking failed, get bytes failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = wc_RNG_GenerateBlock(this->rng, buffer, bytes);
|
||||
#ifndef SINGLE_THREADED
|
||||
if (this->rng == &globalRng)
|
||||
{
|
||||
wc_UnLockMutex(&globalRngMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(rng_t, allocate_bytes, bool,
|
||||
private_wolfssl_rng_t *this, size_t bytes, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(bytes);
|
||||
if (!get_bytes(this, chunk->len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(rng_t, destroy, void,
|
||||
private_wolfssl_rng_t *this)
|
||||
{
|
||||
if (this->rng != &globalRng)
|
||||
{
|
||||
wc_FreeRng(this->rng);
|
||||
free(this->rng);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
|
||||
{
|
||||
private_wolfssl_rng_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.rng = {
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.rng = &globalRng,
|
||||
);
|
||||
|
||||
if (quality > RNG_WEAK)
|
||||
{
|
||||
this->rng = malloc(sizeof(*this->rng));
|
||||
if (wc_InitRng(this->rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RNG failed, rng create failed");
|
||||
free(this->rng);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
int wolfssl_rng_global_init()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!globalRngInit)
|
||||
{
|
||||
ret = wc_InitRng(&globalRng);
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RNG failed, rng global init failed");
|
||||
}
|
||||
#ifndef SINGLE_THREADED
|
||||
else if ((ret = wc_InitMutex(&globalRngMutex)) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init Mutex failed, rng global init failed");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
globalRngInit = TRUE;
|
||||
}
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
void wolfssl_rng_global_final()
|
||||
{
|
||||
if (globalRngInit)
|
||||
{
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_FreeMutex(&globalRngMutex);
|
||||
#endif
|
||||
wc_FreeRng(&globalRng);
|
||||
globalRngInit = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WC_NO_RNG */
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_rng wolfssl_rng
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_RNG_H_
|
||||
#define WOLFSSL_RNG_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct wolfssl_rng_t wolfssl_rng_t;
|
||||
|
||||
/**
|
||||
* Implementation of random number using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_rng_t {
|
||||
|
||||
/**
|
||||
* Implements rng_t interface.
|
||||
*/
|
||||
rng_t rng;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor to create wolfssl_rng_t.
|
||||
*
|
||||
* @param quality quality of randomness
|
||||
* @return wolfssl_rng_t
|
||||
*/
|
||||
wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality);
|
||||
|
||||
/**
|
||||
* Initializes the global random number generator.
|
||||
*
|
||||
* @return TRUE on success and FALSE on failure.
|
||||
*/
|
||||
int wolfssl_rng_global_init();
|
||||
|
||||
/**
|
||||
* Finalizes the global random number generator.
|
||||
*/
|
||||
void wolfssl_rng_global_final();
|
||||
|
||||
#endif /** WOLFSSL_RNG_H_ @}*/
|
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifndef NO_RSA
|
||||
|
||||
#include "wolfssl_rsa_private_key.h"
|
||||
#include "wolfssl_rsa_public_key.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <credentials/keys/signature_params.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_wolfssl_rsa_private_key_t private_wolfssl_rsa_private_key_t;
|
||||
|
||||
/**
|
||||
* Private data of a wolfssl_rsa_private_key_t object
|
||||
*/
|
||||
struct private_wolfssl_rsa_private_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_rsa_private_key_t public;
|
||||
|
||||
/**
|
||||
* RSA key object from wolfSSL
|
||||
*/
|
||||
RsaKey rsa;
|
||||
|
||||
/**
|
||||
* Random number generator to use with RSA operations.
|
||||
*/
|
||||
WC_RNG rng;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/* implemented in rsa public key */
|
||||
bool wolfssl_rsa_encode_public(RsaKey *rsa, chunk_t *encoding);
|
||||
bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type, chunk_t *fp);
|
||||
|
||||
/**
|
||||
* Build RSA signature
|
||||
*/
|
||||
static bool build_signature(private_wolfssl_rsa_private_key_t *this,
|
||||
enum wc_HashType hash, chunk_t data, chunk_t *sig)
|
||||
{
|
||||
int ret = wc_RsaSSL_Sign(data.ptr, data.len, sig->ptr, sig->len, &this->rsa,
|
||||
&this->rng);
|
||||
if (ret > 0)
|
||||
{
|
||||
sig->len = ret;
|
||||
}
|
||||
return ret > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an EMSA PKCS1 signature described in PKCS#1
|
||||
*/
|
||||
static bool build_emsa_pkcs1_signature(private_wolfssl_rsa_private_key_t *this,
|
||||
enum wc_HashType hash, chunk_t data,
|
||||
chunk_t *sig)
|
||||
{
|
||||
bool success = FALSE;
|
||||
chunk_t dgst, digestInfo;
|
||||
int len;
|
||||
|
||||
*sig = chunk_alloc(wc_RsaEncryptSize(&this->rsa));
|
||||
|
||||
if (hash == WC_HASH_TYPE_NONE)
|
||||
{
|
||||
success = build_signature(this, hash, data, sig);
|
||||
}
|
||||
else if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
digestInfo = chunk_alloc(MAX_DER_DIGEST_SZ);
|
||||
len = wc_EncodeSignature(digestInfo.ptr, dgst.ptr, dgst.len,
|
||||
wc_HashGetOID(hash));
|
||||
if (len > 0)
|
||||
{
|
||||
digestInfo.len = len;
|
||||
success = build_signature(this, hash, digestInfo, sig);
|
||||
}
|
||||
chunk_free(&digestInfo);
|
||||
chunk_free(&dgst);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
chunk_free(sig);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
/**
|
||||
* Build an EMSA PSS signature described in PKCS#1
|
||||
*/
|
||||
static bool build_emsa_pss_signature(private_wolfssl_rsa_private_key_t *this,
|
||||
rsa_pss_params_t *params, chunk_t data,
|
||||
chunk_t *sig)
|
||||
{
|
||||
bool success = FALSE;
|
||||
chunk_t dgst = chunk_empty;
|
||||
enum wc_HashType hash;
|
||||
int mgf, ret;
|
||||
|
||||
if (!wolfssl_hash2type(params->hash, &hash))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!wolfssl_hash2mgf1(params->mgf1_hash, &mgf))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*sig = chunk_alloc(wc_RsaEncryptSize(&this->rsa));
|
||||
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
ret = wc_RsaPSS_Sign_ex(dgst.ptr, dgst.len, sig->ptr, sig->len, hash,
|
||||
mgf, params->salt_len, &this->rsa, &this->rng);
|
||||
if (ret > 0)
|
||||
{
|
||||
sig->len = ret;
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
chunk_free(&dgst);
|
||||
if (!success)
|
||||
{
|
||||
chunk_free(sig);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
METHOD(private_key_t, get_type, key_type_t,
|
||||
private_wolfssl_rsa_private_key_t *this)
|
||||
{
|
||||
return KEY_RSA;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, sign, bool,
|
||||
private_wolfssl_rsa_private_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t *signature)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_NONE, data,
|
||||
signature);
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA224, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA256, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA384, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
case SIGN_RSA_EMSA_PKCS1_MD5:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_MD5, data,
|
||||
signature);
|
||||
#endif
|
||||
#ifdef WC_RSA_PSS
|
||||
case SIGN_RSA_EMSA_PSS:
|
||||
return build_emsa_pss_signature(this, params, data, signature);
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(private_key_t, decrypt, bool,
|
||||
private_wolfssl_rsa_private_key_t *this, encryption_scheme_t scheme,
|
||||
chunk_t crypto, chunk_t *plain)
|
||||
{
|
||||
int padding, mgf, len;
|
||||
enum wc_HashType hash;
|
||||
|
||||
switch (scheme)
|
||||
{
|
||||
case ENCRYPT_RSA_PKCS1:
|
||||
hash = WC_HASH_TYPE_NONE;
|
||||
padding = WC_RSA_PKCSV15_PAD;
|
||||
mgf = WC_MGF1NONE;
|
||||
break;
|
||||
#ifndef WC_NO_RSA_OAEP
|
||||
#ifndef NO_SHA
|
||||
case ENCRYPT_RSA_OAEP_SHA1:
|
||||
hash = WC_HASH_TYPE_SHA;
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
mgf = WC_MGF1SHA1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case ENCRYPT_RSA_OAEP_SHA224:
|
||||
hash = WC_HASH_TYPE_SHA224;
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
mgf = WC_MGF1SHA224;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case ENCRYPT_RSA_OAEP_SHA256:
|
||||
hash = WC_HASH_TYPE_SHA256;
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
mgf = WC_MGF1SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case ENCRYPT_RSA_OAEP_SHA384:
|
||||
hash = WC_HASH_TYPE_SHA384;
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
mgf = WC_MGF1SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case ENCRYPT_RSA_OAEP_SHA512:
|
||||
hash = WC_HASH_TYPE_SHA512;
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
mgf = WC_MGF1SHA512;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "encryption scheme %N not supported via wolfssl",
|
||||
encryption_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
len = wc_RsaEncryptSize(&this->rsa);
|
||||
*plain = chunk_alloc(len);
|
||||
len = wc_RsaPrivateDecrypt_ex(crypto.ptr, crypto.len, plain->ptr, len,
|
||||
&this->rsa, padding, hash, mgf, NULL, 0);
|
||||
if (len < 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "RSA decryption failed");
|
||||
chunk_free(plain);
|
||||
return FALSE;
|
||||
}
|
||||
plain->len = len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_keysize, int,
|
||||
private_wolfssl_rsa_private_key_t *this)
|
||||
{
|
||||
return wc_RsaEncryptSize(&this->rsa) * 8;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_public_key, public_key_t*,
|
||||
private_wolfssl_rsa_private_key_t *this)
|
||||
{
|
||||
public_key_t *key;
|
||||
chunk_t enc;
|
||||
|
||||
if (!wolfssl_rsa_encode_public(&this->rsa, &enc))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
|
||||
BUILD_BLOB_ASN1_DER, enc, BUILD_END);
|
||||
chunk_free(&enc);
|
||||
return key;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_fingerprint, bool,
|
||||
private_wolfssl_rsa_private_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_rsa_fingerprint(&this->rsa, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_encoding, bool,
|
||||
private_wolfssl_rsa_private_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *encoding)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PRIVKEY_ASN1_DER:
|
||||
case PRIVKEY_PEM:
|
||||
{
|
||||
bool success = TRUE;
|
||||
int len;
|
||||
|
||||
/* n and d are of keysize length, p and q plus the three CRT
|
||||
* params roughtly half that, the version and e are small */
|
||||
len = wc_RsaEncryptSize(&this->rsa) * 5 + MAX_SEQ_SZ;
|
||||
*encoding = chunk_alloc(len);
|
||||
len = wc_RsaKeyToDer(&this->rsa, encoding->ptr, len);
|
||||
if (len < 0)
|
||||
{
|
||||
chunk_free(encoding);
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = len;
|
||||
|
||||
if (type == PRIVKEY_PEM)
|
||||
{
|
||||
chunk_t asn1_encoding = *encoding;
|
||||
|
||||
success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
|
||||
NULL, encoding, CRED_PART_RSA_PRIV_ASN1_DER,
|
||||
asn1_encoding, CRED_PART_END);
|
||||
chunk_clear(&asn1_encoding);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_ref, private_key_t*,
|
||||
private_wolfssl_rsa_private_key_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.key;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, destroy, void,
|
||||
private_wolfssl_rsa_private_key_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
lib->encoding->clear_cache(lib->encoding, &this->rsa);
|
||||
wc_FreeRsaKey(&this->rsa);
|
||||
wc_FreeRng(&this->rng);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal generic constructor
|
||||
*/
|
||||
static private_wolfssl_rsa_private_key_t *create_empty()
|
||||
{
|
||||
private_wolfssl_rsa_private_key_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.key = {
|
||||
.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,
|
||||
);
|
||||
|
||||
if (wc_InitRng(&this->rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RNG failed, rsa private key create failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
if (wc_InitRsaKey(&this->rsa, NULL) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RSA failed, rsa private key create failed");
|
||||
wc_FreeRng(&this->rng);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->rsa.rng = &this->rng;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_rsa_private_key_t *this;
|
||||
u_int key_size = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_KEY_SIZE:
|
||||
key_size = va_arg(args, u_int);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!key_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_MakeRsaKey(&this->rsa, key_size, WC_RSA_EXPONENT, &this->rng) < 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a random number in the range [0, n-1]
|
||||
*/
|
||||
static bool wolfssl_mp_rand(mp_int *n, WC_RNG *rng, mp_int *r)
|
||||
{
|
||||
int len, ret;
|
||||
|
||||
/* ensure the number has enough memory. */
|
||||
ret = mp_set_bit(r, mp_count_bits(n));
|
||||
if (ret == 0)
|
||||
{
|
||||
len = sizeof(*r->dp) * n->used;
|
||||
ret = wc_RNG_GenerateBlock(rng, (byte *)r->dp, len);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_mod(r, n, r);
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover the primes from n, e and d using the algorithm described in
|
||||
* Appendix C of NIST SP 800-56B.
|
||||
*/
|
||||
static bool calculate_pq(mp_int *n, mp_int *e, mp_int *d, mp_int *p, mp_int *q,
|
||||
mp_int *t1, mp_int *t2, WC_RNG* rng)
|
||||
{
|
||||
int i, t, j;
|
||||
bool success = FALSE;
|
||||
mp_int *k = p;
|
||||
mp_int *r = p;
|
||||
mp_int *n1 = q;
|
||||
mp_int *g = t2;
|
||||
mp_int *y = t2;
|
||||
mp_int *x = t1;
|
||||
|
||||
/* k = (d * e) - 1 */
|
||||
if (mp_mul(d, e, k) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (mp_sub_d(k, 1, k) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* k must be even */
|
||||
if (mp_isodd(k))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
|
||||
if (mp_copy(k, r) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
for (t = 0; !mp_isodd(r); t++)
|
||||
{ /* r = r/2 */
|
||||
if (mp_div_2(r, r) != 0)
|
||||
goto error;
|
||||
}
|
||||
/* we need n-1 below */
|
||||
if (mp_sub_d(n, 1, n1) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
for (i = 0; i < 100; i++)
|
||||
{ /* generate random integer g in [0, n-1] */
|
||||
if (!wolfssl_mp_rand(n, rng, g))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* y = g^r mod n */
|
||||
if (mp_exptmod(g, r, n, y) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* try again if y == 1 or y == n-1 */
|
||||
if (mp_isone(y) || mp_cmp(y, n1) == MP_EQ)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < t; j++)
|
||||
{ /* x = y^2 mod n */
|
||||
if (mp_sqrmod(y, n, x) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* stop if x == 1 */
|
||||
if (mp_isone(x))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
/* retry with new g if x = n-1 */
|
||||
if (mp_cmp(x, n1) == MP_EQ)
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* y = x */
|
||||
if (mp_copy(x, y) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto error;
|
||||
|
||||
done:
|
||||
/* p = gcd(y-1, n) */
|
||||
if (mp_sub_d(y, 1, y) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (mp_gcd(y, n, p) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* q = n/p */
|
||||
if (mp_div(n, p, q, NULL) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder
|
||||
* algorithm.
|
||||
*/
|
||||
static bool dmodpq1(mp_int *d, mp_int *pq, mp_int *res)
|
||||
{
|
||||
/* p|q - 1
|
||||
* d (mod p|q -1) */
|
||||
return mp_sub_d(pq, 1, res) == 0 &&
|
||||
mp_mod(d, res, res) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates qinv = q^-1 (mod p) for the Chinese remainder algorithm.
|
||||
*/
|
||||
static int qinv(mp_int *q, mp_int *p, mp_int *res)
|
||||
{
|
||||
/* q^-1 (mod p) */
|
||||
return mp_invmod(q, p, res) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_rsa_private_key_t *this;
|
||||
chunk_t blob, n, e, d, p, q, exp1, exp2, coeff;
|
||||
word32 idx;
|
||||
int ret;
|
||||
|
||||
blob = n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty;
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_MODULUS:
|
||||
n = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_PUB_EXP:
|
||||
e = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_PRIV_EXP:
|
||||
d = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_PRIME1:
|
||||
p = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_PRIME2:
|
||||
q = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_EXP1:
|
||||
exp1 = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_EXP2:
|
||||
exp2 = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_COEFF:
|
||||
coeff = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (blob.ptr)
|
||||
{
|
||||
idx = 0;
|
||||
ret = wc_RsaPrivateKeyDecode(blob.ptr, &idx, &this->rsa, blob.len);
|
||||
if (ret == 0)
|
||||
{
|
||||
return &this->public;
|
||||
}
|
||||
}
|
||||
else if (n.ptr && e.ptr && d.ptr)
|
||||
{
|
||||
if (mp_read_unsigned_bin(&this->rsa.n, n.ptr, n.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (mp_read_unsigned_bin(&this->rsa.e, e.ptr, e.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (mp_read_unsigned_bin(&this->rsa.d, d.ptr, d.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (p.ptr && q.ptr)
|
||||
{
|
||||
if (mp_read_unsigned_bin(&this->rsa.p, p.ptr, p.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (mp_read_unsigned_bin(&this->rsa.q, q.ptr, q.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (!calculate_pq(&this->rsa.n, &this->rsa.e, &this->rsa.d,
|
||||
&this->rsa.p, &this->rsa.q, &this->rsa.dP,
|
||||
&this->rsa.dQ, &this->rng))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (exp1.ptr)
|
||||
{
|
||||
if (mp_read_unsigned_bin(&this->rsa.dP, exp1.ptr, exp1.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (!dmodpq1(&this->rsa.d, &this->rsa.p, &this->rsa.dP))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (exp2.ptr)
|
||||
{
|
||||
if (mp_read_unsigned_bin(&this->rsa.dQ, exp2.ptr, exp2.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (!dmodpq1(&this->rsa.d, &this->rsa.q, &this->rsa.dQ))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
if (coeff.ptr)
|
||||
{
|
||||
if (mp_read_unsigned_bin(&this->rsa.u, coeff.ptr, coeff.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (!qinv(&this->rsa.q, &this->rsa.p, &this->rsa.u))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
error:
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* NO_RSA */
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_rsa_private_key wolfssl_rsa_private_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_RSA_PRIVATE_KEY_H_
|
||||
#define WOLFSSL_RSA_PRIVATE_KEY_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
|
||||
typedef struct wolfssl_rsa_private_key_t wolfssl_rsa_private_key_t;
|
||||
|
||||
/**
|
||||
* private_key_t implementation of RSA algorithm using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_rsa_private_key_t {
|
||||
|
||||
/**
|
||||
* Implements private_key_t interface
|
||||
*/
|
||||
private_key_t key;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate an RSA private key using wolfSSL.
|
||||
*
|
||||
* Accepts the BUILD_KEY_SIZE argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_RSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return generated key, NULL on failure
|
||||
*/
|
||||
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
/**
|
||||
* Load an RSA private key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_RSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
#endif /** WOLFSSL_RSA_PRIVATE_KEY_H_ @}*/
|
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifndef NO_RSA
|
||||
|
||||
#include "wolfssl_rsa_public_key.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <credentials/keys/signature_params.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
|
||||
typedef struct private_wolfssl_rsa_public_key_t private_wolfssl_rsa_public_key_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_wolfssl_rsa_public_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
wolfssl_rsa_public_key_t public;
|
||||
|
||||
/**
|
||||
* RSA key object from wolfSSL.
|
||||
*/
|
||||
RsaKey rsa;
|
||||
|
||||
/**
|
||||
* Random number generator to use with RSA operations.
|
||||
*/
|
||||
WC_RNG rng;
|
||||
|
||||
/**
|
||||
* Reference counter
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify RSA signature
|
||||
*/
|
||||
static bool verify_signature(private_wolfssl_rsa_public_key_t *this,
|
||||
chunk_t data, chunk_t signature)
|
||||
{
|
||||
bool success = FALSE;
|
||||
int len = wc_RsaEncryptSize(&this->rsa);
|
||||
chunk_t padded;
|
||||
u_char *p;
|
||||
|
||||
if (signature.len > len)
|
||||
{
|
||||
signature = chunk_skip(signature, signature.len - len);
|
||||
}
|
||||
|
||||
padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00);
|
||||
|
||||
len = wc_RsaSSL_VerifyInline(padded.ptr, len, &p, &this->rsa);
|
||||
if (len > 0)
|
||||
{
|
||||
success = chunk_equals_const(data, chunk_create(p, len));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verification of an EMSA PKCS1 signature described in PKCS#1
|
||||
*/
|
||||
static bool verify_emsa_pkcs1_signature(private_wolfssl_rsa_public_key_t *this,
|
||||
enum wc_HashType hash, chunk_t data,
|
||||
chunk_t signature)
|
||||
{
|
||||
chunk_t dgst, digestInfo;
|
||||
bool success = FALSE;
|
||||
int len;
|
||||
|
||||
if (wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
digestInfo = chunk_alloc(MAX_DER_DIGEST_SZ);
|
||||
len = wc_EncodeSignature(digestInfo.ptr, dgst.ptr, dgst.len,
|
||||
wc_HashGetOID(hash));
|
||||
if (len > 0)
|
||||
{
|
||||
digestInfo.len = len;
|
||||
success = verify_signature(this, digestInfo, signature);
|
||||
}
|
||||
chunk_free(&digestInfo);
|
||||
chunk_free(&dgst);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
/**
|
||||
* Verification of an EMSA PSS signature described in PKCS#1
|
||||
*/
|
||||
static bool verify_emsa_pss_signature(private_wolfssl_rsa_public_key_t *this,
|
||||
rsa_pss_params_t *params, chunk_t data,
|
||||
chunk_t signature)
|
||||
{
|
||||
chunk_t dgst, padded;
|
||||
enum wc_HashType hash;
|
||||
u_char *p;
|
||||
int mgf, len = 0;
|
||||
bool success = FALSE;
|
||||
|
||||
if (!wolfssl_hash2type(params->hash, &hash))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!wolfssl_hash2mgf1(params->mgf1_hash, &mgf))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!wolfssl_hash_chunk(hash, data, &dgst))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
len = wc_RsaEncryptSize(&this->rsa);
|
||||
if (signature.len > len)
|
||||
{
|
||||
signature = chunk_skip(signature, signature.len - len);
|
||||
}
|
||||
padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00);
|
||||
|
||||
len = wc_RsaPSS_VerifyInline_ex(padded.ptr, len, &p, hash, mgf,
|
||||
params->salt_len, &this->rsa);
|
||||
if (len > 0)
|
||||
{
|
||||
success = wc_RsaPSS_CheckPadding_ex(dgst.ptr, dgst.len, p, len, hash,
|
||||
params->salt_len, mp_count_bits(&this->rsa.n)) == 0;
|
||||
}
|
||||
chunk_free(&dgst);
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
METHOD(public_key_t, get_type, key_type_t,
|
||||
private_wolfssl_rsa_public_key_t *this)
|
||||
{
|
||||
return KEY_RSA;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, verify, bool,
|
||||
private_wolfssl_rsa_public_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t signature)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case SIGN_RSA_EMSA_PKCS1_NULL:
|
||||
return verify_signature(this, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA224, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA256, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA384, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_MD5:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_MD5, data,
|
||||
signature);
|
||||
#ifdef WC_RSA_PSS
|
||||
case SIGN_RSA_EMSA_PSS:
|
||||
return verify_emsa_pss_signature(this, params, data, signature);
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
|
||||
signature_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(public_key_t, encrypt, bool,
|
||||
private_wolfssl_rsa_public_key_t *this, encryption_scheme_t scheme,
|
||||
chunk_t plain, chunk_t *crypto)
|
||||
{
|
||||
int padding, mgf, len;
|
||||
enum wc_HashType hash;
|
||||
|
||||
switch (scheme)
|
||||
{
|
||||
case ENCRYPT_RSA_PKCS1:
|
||||
padding = WC_RSA_PKCSV15_PAD;
|
||||
hash = WC_HASH_TYPE_NONE;
|
||||
mgf = WC_MGF1NONE;
|
||||
break;
|
||||
#ifndef WC_NO_RSA_OAEP
|
||||
#ifndef NO_SHA
|
||||
case ENCRYPT_RSA_OAEP_SHA1:
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
hash = WC_HASH_TYPE_SHA;
|
||||
mgf = WC_MGF1SHA1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case ENCRYPT_RSA_OAEP_SHA224:
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
hash = WC_HASH_TYPE_SHA224;
|
||||
mgf = WC_MGF1SHA224;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case ENCRYPT_RSA_OAEP_SHA256:
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
hash = WC_HASH_TYPE_SHA256;
|
||||
mgf = WC_MGF1SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case ENCRYPT_RSA_OAEP_SHA384:
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
hash = WC_HASH_TYPE_SHA384;
|
||||
mgf = WC_MGF1SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case ENCRYPT_RSA_OAEP_SHA512:
|
||||
padding = WC_RSA_OAEP_PAD;
|
||||
hash = WC_HASH_TYPE_SHA512;
|
||||
mgf = WC_MGF1SHA512;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
DBG1(DBG_LIB, "decryption scheme %N not supported via wolfssl",
|
||||
encryption_scheme_names, scheme);
|
||||
return FALSE;
|
||||
}
|
||||
len = wc_RsaEncryptSize(&this->rsa);
|
||||
*crypto = chunk_alloc(len);
|
||||
len = wc_RsaPublicEncrypt_ex(plain.ptr, plain.len, crypto->ptr, len,
|
||||
&this->rsa, &this->rng, padding, hash, mgf,
|
||||
NULL, 0);
|
||||
if (len < 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "RSA encryption failed");
|
||||
chunk_free(crypto);
|
||||
return FALSE;
|
||||
}
|
||||
crypto->len = len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_keysize, int,
|
||||
private_wolfssl_rsa_public_key_t *this)
|
||||
{
|
||||
return wc_RsaEncryptSize(&this->rsa) * 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given public key as ASN.1 DER with algorithm identifier
|
||||
*/
|
||||
bool wolfssl_rsa_encode_public(RsaKey *rsa, chunk_t *encoding)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = wc_RsaEncryptSize(rsa) * 2 + 4 * MAX_SEQ_SZ + MAX_ALGO_SZ;
|
||||
*encoding = chunk_alloc(len);
|
||||
len = wc_RsaKeyToPublicDer(rsa, encoding->ptr, len);
|
||||
if (len < 0)
|
||||
{
|
||||
chunk_free(encoding);
|
||||
return FALSE;
|
||||
}
|
||||
encoding->len = len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fingerprint from a RSA key, also used in rsa private key.
|
||||
*/
|
||||
bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type,
|
||||
chunk_t *fp)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t key;
|
||||
bool success = FALSE;
|
||||
|
||||
if (lib->encoding->get_cache(lib->encoding, type, rsa, fp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case KEYID_PUBKEY_SHA1:
|
||||
{
|
||||
chunk_t n = chunk_empty, e = chunk_empty;
|
||||
|
||||
if (wolfssl_mp2chunk(&rsa->n, &n) &&
|
||||
wolfssl_mp2chunk(&rsa->e, &e))
|
||||
{
|
||||
key = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_integer("m", n),
|
||||
asn1_integer("m", e));
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_free(&n);
|
||||
chunk_free(&e);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEYID_PUBKEY_INFO_SHA1:
|
||||
if (!wolfssl_rsa_encode_public(rsa, &key))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (!hasher || !hasher->allocate_hash(hasher, key, fp))
|
||||
{
|
||||
DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, rsa, *fp);
|
||||
success = TRUE;
|
||||
}
|
||||
DESTROY_IF(hasher);
|
||||
chunk_free(&key);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_fingerprint, bool,
|
||||
private_wolfssl_rsa_public_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *fingerprint)
|
||||
{
|
||||
return wolfssl_rsa_fingerprint(&this->rsa, type, fingerprint);
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_encoding, bool,
|
||||
private_wolfssl_rsa_public_key_t *this, cred_encoding_type_t type,
|
||||
chunk_t *encoding)
|
||||
{
|
||||
chunk_t n = chunk_empty, e = chunk_empty;
|
||||
bool success = FALSE;
|
||||
|
||||
if (type == PUBKEY_SPKI_ASN1_DER)
|
||||
{
|
||||
return wolfssl_rsa_encode_public(&this->rsa, encoding);
|
||||
}
|
||||
|
||||
if (wolfssl_mp2chunk(&this->rsa.n, &n) &&
|
||||
wolfssl_mp2chunk(&this->rsa.e, &e))
|
||||
{
|
||||
success = lib->encoding->encode(lib->encoding, type, NULL, encoding,
|
||||
CRED_PART_RSA_MODULUS, n,
|
||||
CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
|
||||
}
|
||||
chunk_free(&n);
|
||||
chunk_free(&e);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_ref, public_key_t*,
|
||||
private_wolfssl_rsa_public_key_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.key;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, destroy, void,
|
||||
private_wolfssl_rsa_public_key_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
lib->encoding->clear_cache(lib->encoding, &this->rsa);
|
||||
wc_FreeRsaKey(&this->rsa);
|
||||
wc_FreeRng(&this->rng);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic private constructor
|
||||
*/
|
||||
static private_wolfssl_rsa_public_key_t *create_empty()
|
||||
{
|
||||
private_wolfssl_rsa_public_key_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.key = {
|
||||
.get_type = _get_type,
|
||||
.verify = _verify,
|
||||
.encrypt = _encrypt,
|
||||
.equals = public_key_equals,
|
||||
.get_keysize = _get_keysize,
|
||||
.get_fingerprint = _get_fingerprint,
|
||||
.has_fingerprint = public_key_has_fingerprint,
|
||||
.get_encoding = _get_encoding,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
if (wc_InitRng(&this->rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RNG failed, rsa public key load failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
if (wc_InitRsaKey(&this->rsa, NULL) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "init RSA failed, rsa public key load failed");
|
||||
wc_FreeRng(&this->rng);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
private_wolfssl_rsa_public_key_t *this;
|
||||
chunk_t blob, n, e;
|
||||
word32 idx;
|
||||
|
||||
n = e = blob = chunk_empty;
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_MODULUS:
|
||||
n = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_RSA_PUB_EXP:
|
||||
e = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this = create_empty();
|
||||
if (!this)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (blob.ptr)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KEY_ANY:
|
||||
case KEY_RSA:
|
||||
idx = 0;
|
||||
if (wc_RsaPublicKeyDecode(blob.ptr, &idx, &this->rsa,
|
||||
blob.len) != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
else if (n.ptr && e.ptr && type == KEY_RSA)
|
||||
{
|
||||
if (wc_RsaPublicKeyDecodeRaw(n.ptr, n.len, e.ptr, e.len,
|
||||
&this->rsa) != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* NO_RSA */
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_rsa_public_key wolfssl_rsa_public_key
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_RSA_PUBLIC_KEY_H_
|
||||
#define WOLFSSL_RSA_PUBLIC_KEY_H_
|
||||
|
||||
typedef struct wolfssl_rsa_public_key_t wolfssl_rsa_public_key_t;
|
||||
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* public_key_t implementation of RSA algorithm using wolfSSL.
|
||||
*/
|
||||
struct wolfssl_rsa_public_key_t {
|
||||
|
||||
/**
|
||||
* Implements the public_key_t interface
|
||||
*/
|
||||
public_key_t key;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a RSA public key using wolfSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_RSA
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
|
||||
va_list args);
|
||||
|
||||
#endif /** WOLFSSL_RSA_PUBLIC_KEY_H_ @}*/
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifndef NO_SHA
|
||||
|
||||
#include "wolfssl_sha1_prf.h"
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
typedef struct private_wolfssl_sha1_prf_t private_wolfssl_sha1_prf_t;
|
||||
|
||||
/**
|
||||
* Private data of an wolfssl_sha1_prf_t object.
|
||||
*/
|
||||
struct private_wolfssl_sha1_prf_t {
|
||||
|
||||
/**
|
||||
* Public wolfssl_sha1_prf_t interface
|
||||
*/
|
||||
wolfssl_sha1_prf_t public;
|
||||
|
||||
/**
|
||||
* SHA1 context
|
||||
*/
|
||||
wc_Sha sha1;
|
||||
};
|
||||
|
||||
METHOD(prf_t, get_bytes, bool,
|
||||
private_wolfssl_sha1_prf_t *this, chunk_t seed, uint8_t *bytes)
|
||||
{
|
||||
if (wc_ShaUpdate(&this->sha1, seed.ptr, seed.len) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
uint32_t *hash = (uint32_t*)bytes;
|
||||
|
||||
hash[0] = htonl(this->sha1.digest[0]);
|
||||
hash[1] = htonl(this->sha1.digest[1]);
|
||||
hash[2] = htonl(this->sha1.digest[2]);
|
||||
hash[3] = htonl(this->sha1.digest[3]);
|
||||
hash[4] = htonl(this->sha1.digest[4]);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(prf_t, get_block_size, size_t,
|
||||
private_wolfssl_sha1_prf_t *this)
|
||||
{
|
||||
return HASH_SIZE_SHA1;
|
||||
}
|
||||
|
||||
METHOD(prf_t, allocate_bytes, bool,
|
||||
private_wolfssl_sha1_prf_t *this, chunk_t seed, chunk_t *chunk)
|
||||
{
|
||||
if (chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(HASH_SIZE_SHA1);
|
||||
return get_bytes(this, seed, chunk->ptr);
|
||||
}
|
||||
return get_bytes(this, seed, NULL);
|
||||
}
|
||||
|
||||
METHOD(prf_t, get_key_size, size_t,
|
||||
private_wolfssl_sha1_prf_t *this)
|
||||
{
|
||||
return HASH_SIZE_SHA1;
|
||||
}
|
||||
|
||||
METHOD(prf_t, set_key, bool,
|
||||
private_wolfssl_sha1_prf_t *this, chunk_t key)
|
||||
{
|
||||
if (wc_InitSha(&this->sha1) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (key.len % 4)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (key.len >= 4)
|
||||
{
|
||||
this->sha1.digest[0] ^= untoh32(key.ptr);
|
||||
}
|
||||
if (key.len >= 8)
|
||||
{
|
||||
this->sha1.digest[1] ^= untoh32(key.ptr + 4);
|
||||
}
|
||||
if (key.len >= 12)
|
||||
{
|
||||
this->sha1.digest[2] ^= untoh32(key.ptr + 8);
|
||||
}
|
||||
if (key.len >= 16)
|
||||
{
|
||||
this->sha1.digest[3] ^= untoh32(key.ptr + 12);
|
||||
}
|
||||
if (key.len >= 20)
|
||||
{
|
||||
this->sha1.digest[4] ^= untoh32(key.ptr + 16);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(prf_t, destroy, void,
|
||||
private_wolfssl_sha1_prf_t *this)
|
||||
{
|
||||
wc_ShaFree(&this->sha1);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
|
||||
{
|
||||
private_wolfssl_sha1_prf_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.prf = {
|
||||
.get_block_size = _get_block_size,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.get_key_size = _get_key_size,
|
||||
.set_key = _set_key,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (wc_InitSha(&this->sha1) != 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* NO_SHA */
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_sha1_prf wolfssl_sha1_prf
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_SHA1_PRF_H_
|
||||
#define WOLFSSL_SHA1_PRF_H_
|
||||
|
||||
typedef struct wolfssl_sha1_prf_t wolfssl_sha1_prf_t;
|
||||
|
||||
#include <crypto/prfs/prf.h>
|
||||
|
||||
/**
|
||||
* Implementation of prf_t interface using keyed SHA1 algorithm as used
|
||||
* in EAP-AKA/FIPS_PRF.
|
||||
*/
|
||||
struct wolfssl_sha1_prf_t {
|
||||
|
||||
/**
|
||||
* Implements prf_t interface.
|
||||
*/
|
||||
prf_t prf;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new wolfssl_sha1_prf_t.
|
||||
*
|
||||
* @param algo algorithm, must be PRF_KEYED_SHA1
|
||||
* @return wolfssl_sha1_prf_t object
|
||||
*/
|
||||
wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo);
|
||||
|
||||
#endif /** WOLFSSL_SHA1_PRF_H_ @}*/
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
#include "wolfssl_util.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*hash = chunk_alloc(wc_HashGetDigestSize(hash_type));
|
||||
ret = wc_Hash(hash_type, data.ptr, data.len, hash->ptr, hash->len);
|
||||
if (ret < 0)
|
||||
{
|
||||
chunk_free(hash);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(mp_unsigned_bin_size(mp));
|
||||
if (mp_to_unsigned_bin(mp, chunk->ptr) == 0)
|
||||
{
|
||||
if (chunk->len && chunk->ptr[0] & 0x80)
|
||||
{ /* if MSB is set, prepend a zero to make it non-negative */
|
||||
*chunk = chunk_cat("cm", chunk_from_chars(0x00), *chunk);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
|
||||
{
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
if ((chunk.len % 2) == 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
len = chunk.len / 2;
|
||||
ret = mp_read_unsigned_bin(a, chunk.ptr, len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = mp_read_unsigned_bin(b, chunk.ptr + len, len);
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
|
||||
{
|
||||
int ret;
|
||||
int sz;
|
||||
|
||||
*chunk = chunk_alloc(len);
|
||||
if (b != NULL)
|
||||
{
|
||||
len /= 2;
|
||||
}
|
||||
|
||||
sz = mp_unsigned_bin_size(a);
|
||||
memset(chunk->ptr, 0, len - sz);
|
||||
ret = mp_to_unsigned_bin(a, chunk->ptr + len - sz);
|
||||
if (ret == 0 && b != NULL)
|
||||
{
|
||||
sz = mp_unsigned_bin_size(b);
|
||||
memset(chunk->ptr + len, 0, len - sz);
|
||||
ret = mp_to_unsigned_bin(b, chunk->ptr + 2 * len - sz);
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type)
|
||||
{
|
||||
switch (hash)
|
||||
{
|
||||
#ifndef NO_MD5
|
||||
case HASH_MD5:
|
||||
*type = WC_HASH_TYPE_MD5;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
case HASH_SHA1:
|
||||
*type = WC_HASH_TYPE_SHA;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case HASH_SHA224:
|
||||
*type = WC_HASH_TYPE_SHA224;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case HASH_SHA256:
|
||||
*type = WC_HASH_TYPE_SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case HASH_SHA384:
|
||||
*type = WC_HASH_TYPE_SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case HASH_SHA512:
|
||||
*type = WC_HASH_TYPE_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool wolfssl_hash2mgf1(hash_algorithm_t hash, int *mgf1)
|
||||
{
|
||||
switch (hash)
|
||||
{
|
||||
#ifndef NO_SHA
|
||||
case HASH_SHA1:
|
||||
*mgf1 = WC_MGF1SHA1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case HASH_SHA224:
|
||||
*mgf1 = WC_MGF1SHA224;
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case HASH_SHA256:
|
||||
*mgf1 = WC_MGF1SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case HASH_SHA384:
|
||||
*mgf1 = WC_MGF1SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case HASH_SHA512:
|
||||
*mgf1 = WC_MGF1SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 wolfssl_util wolfssl_util
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_UTIL_H_
|
||||
#define WOLFSSL_UTIL_H_
|
||||
|
||||
#include <wolfssl/wolfcrypt/integer.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
|
||||
/**
|
||||
* Creates a hash of a given type of a chunk of data.
|
||||
*
|
||||
* Note: this function allocates memory for the hash
|
||||
*
|
||||
* @param hash_type Hash enumeration
|
||||
* @param data the chunk of data to hash
|
||||
* @param hash chunk that contains the hash
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash);
|
||||
|
||||
/**
|
||||
* Exports the given integer (assumed to be a positive number) to a chunk in
|
||||
* two's complement format (i.e. a zero byte is added if the MSB is set).
|
||||
*
|
||||
* @param mp the integer to export
|
||||
* @param chunk the chunk (data gets allocated)
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* Splits a chunk into two mp_ints of equal binary length.
|
||||
*
|
||||
* @param chunk a chunk that contains the two integers
|
||||
* @param a first mp_int
|
||||
* @param b second mp_int
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b);
|
||||
|
||||
/**
|
||||
* Concatenates two integers into a chunk, thereby enfocing the length of
|
||||
* a single integer, if necessary, by pre-pending it with zeros.
|
||||
*
|
||||
* Note: this function allocates memory for the chunk
|
||||
*
|
||||
* @param len the length of a single integer
|
||||
* @param a first integer
|
||||
* @param b second integer
|
||||
* @param chunk resulting chunk
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* Convert the hash algorithm to a wolfSSL hash type.
|
||||
*
|
||||
* @param hash hash algorithm
|
||||
* @param type Hash enumeration from wolfSSL
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type);
|
||||
|
||||
/**
|
||||
* Convert the mgf1 hash algorithm to a wolfSSL mgf1 type.
|
||||
*
|
||||
* @param hash hash algorithm
|
||||
* @param mgf1 MGF1 algorithm from wolfSSL
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
bool wolfssl_hash2mgf1(hash_algorithm_t hash, int *mgf1);
|
||||
|
||||
#endif /** WOLFSSL_UTIL_H_ @}*/
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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 "wolfssl_common.h"
|
||||
|
||||
#ifdef HAVE_CURVE25519
|
||||
|
||||
#include "wolfssl_x_diffie_hellman.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/curve25519.h>
|
||||
#include <wolfssl/wolfcrypt/fe_operations.h>
|
||||
|
||||
typedef struct private_diffie_hellman_t private_diffie_hellman_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_diffie_hellman_t {
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
diffie_hellman_t public;
|
||||
|
||||
/**
|
||||
* Diffie Hellman group number.
|
||||
*/
|
||||
diffie_hellman_group_t group;
|
||||
|
||||
/**
|
||||
* Private (public) key
|
||||
*/
|
||||
curve25519_key key;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
chunk_t shared_secret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the shared secret
|
||||
*/
|
||||
static bool compute_shared_key(private_diffie_hellman_t *this,
|
||||
curve25519_key *pub, chunk_t *shared_secret)
|
||||
{
|
||||
word32 len = CURVE25519_KEYSIZE;
|
||||
int ret;
|
||||
|
||||
*shared_secret = chunk_alloc(len);
|
||||
ret = wc_curve25519_shared_secret_ex(&this->key, pub, shared_secret->ptr,
|
||||
&len, EC25519_LITTLE_ENDIAN);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
curve25519_key pub;
|
||||
int ret;
|
||||
|
||||
if (!diffie_hellman_verify_value(this->group, value))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = wc_curve25519_init(&pub);
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "%N public key initialization failed",
|
||||
diffie_hellman_group_names, this->group);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = wc_curve25519_import_public_ex(value.ptr, value.len, &pub,
|
||||
EC25519_LITTLE_ENDIAN);
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "%N public value is malformed",
|
||||
diffie_hellman_group_names, this->group);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
chunk_clear(&this->shared_secret);
|
||||
|
||||
if (!compute_shared_key(this, &pub, &this->shared_secret))
|
||||
{
|
||||
DBG1(DBG_LIB, "%N shared secret computation failed",
|
||||
diffie_hellman_group_names, this->group);
|
||||
chunk_clear(&this->shared_secret);
|
||||
wc_curve25519_free(&pub);
|
||||
return FALSE;
|
||||
}
|
||||
wc_curve25519_free(&pub);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_my_public_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *value)
|
||||
{
|
||||
word32 len = CURVE25519_KEYSIZE;
|
||||
|
||||
*value = chunk_alloc(len);
|
||||
if (wc_curve25519_export_public_ex(&this->key, value->ptr, &len,
|
||||
EC25519_LITTLE_ENDIAN) != 0)
|
||||
{
|
||||
chunk_free(value);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_private_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
curve25519_key pub;
|
||||
u_char basepoint[CURVE25519_KEYSIZE] = {9};
|
||||
word32 len = CURVE25519_KEYSIZE;
|
||||
int ret;
|
||||
|
||||
ret = wc_curve25519_init(&pub);
|
||||
/* create base point for calculating public key */
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_curve25519_import_public_ex(basepoint, CURVE25519_KEYSIZE,
|
||||
&pub, EC25519_LITTLE_ENDIAN);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_curve25519_import_private_ex(value.ptr, value.len, &this->key,
|
||||
EC25519_LITTLE_ENDIAN);
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_curve25519_shared_secret_ex(&this->key, &pub,
|
||||
this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_shared_secret, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->shared_secret.len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*secret = chunk_clone(this->shared_secret);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
|
||||
private_diffie_hellman_t *this)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, destroy, void,
|
||||
private_diffie_hellman_t *this)
|
||||
{
|
||||
wc_curve25519_free(&this->key);
|
||||
chunk_clear(&this->shared_secret);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
|
||||
{
|
||||
private_diffie_hellman_t *this;
|
||||
WC_RNG rng;
|
||||
int ret;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_shared_secret = _get_shared_secret,
|
||||
.set_other_public_value = _set_other_public_value,
|
||||
.get_my_public_value = _get_my_public_value,
|
||||
.set_private_value = _set_private_value,
|
||||
.get_dh_group = _get_dh_group,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.group = group,
|
||||
);
|
||||
|
||||
if (wc_curve25519_init(&this->key) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "initializing key failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "initializing a random number generator failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &this->key);
|
||||
wc_FreeRng(&rng);
|
||||
if (ret != 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "making a key failed");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CURVE25519 */
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of the X25519 Diffie-Hellman algorithm using wolfSSL.
|
||||
*
|
||||
* @defgroup wolfssl_x_diffie_hellman wolfssl_x_diffie_hellman
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_X_DIFFIE_HELLMAN_H_
|
||||
#define WOLFSSL_X_DIFFIE_HELLMAN_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Creates a new diffie_hellman_t object.
|
||||
*
|
||||
* @param group Diffie Hellman group number to use
|
||||
* @return object, NULL if not supported
|
||||
*/
|
||||
diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group);
|
||||
|
||||
#endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/
|
|
@ -573,6 +573,40 @@ START_TEST(test_increment)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_copy_pad tests
|
||||
*/
|
||||
|
||||
static struct {
|
||||
size_t len;
|
||||
u_char chr;
|
||||
chunk_t src;
|
||||
chunk_t exp;
|
||||
} copy_pad_data[] = {
|
||||
{0, 0x00, { NULL, 0 }, { NULL, 0 }},
|
||||
{4, 0x00, { NULL, 0 }, chunk_from_chars(0x00,0x00,0x00,0x00)},
|
||||
{0, 0x00, chunk_from_chars(0x01), { NULL, 0 }},
|
||||
{1, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x01)},
|
||||
{2, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x01)},
|
||||
{3, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x01)},
|
||||
{4, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x00,0x01)},
|
||||
{4, 0x02, chunk_from_chars(0x01), chunk_from_chars(0x02,0x02,0x02,0x01)},
|
||||
{1, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x04)},
|
||||
{2, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x03,0x04)},
|
||||
{3, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x02,0x03,0x04)},
|
||||
{4, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x01,0x02,0x03,0x04)},
|
||||
};
|
||||
|
||||
START_TEST(test_copy_pad)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
chunk = chunk_copy_pad(chunk_alloca(copy_pad_data[_i].len),
|
||||
copy_pad_data[_i].src, copy_pad_data[_i].chr);
|
||||
ck_assert_chunk_eq(chunk, copy_pad_data[_i].exp);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* chunk_printable tests
|
||||
*/
|
||||
|
@ -1076,6 +1110,10 @@ Suite *chunk_suite_create()
|
|||
tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_copy_pad");
|
||||
tcase_add_loop_test(tc, test_copy_pad, 0, countof(copy_pad_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("chunk_printable");
|
||||
tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
|
||||
tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
|
||||
|
|
|
@ -160,8 +160,14 @@ END_TEST
|
|||
/**
|
||||
* Private keys to load
|
||||
*/
|
||||
static chunk_t keys[] = {
|
||||
chunk_from_chars( /* ECDSA-256 */
|
||||
static struct {
|
||||
chunk_t key;
|
||||
chunk_t pkcs8;
|
||||
chunk_t pub;
|
||||
chunk_t fp_pk;
|
||||
chunk_t fp_spki;
|
||||
} keys[] = {
|
||||
{ chunk_from_chars( /* ECDSA-256 */
|
||||
0x30,0x77,0x02,0x01,0x01,0x04,0x20,0x42,0xc6,0x8c,0xff,0x2b,0x8b,0x87,0xa1,0xfb,
|
||||
0x50,0xf6,0xfe,0xd6,0x88,0xb3,0x0a,0x48,0xb2,0xc5,0x8f,0x50,0xe0,0xcf,0x40,0xfa,
|
||||
0x57,0xd1,0xc6,0x6c,0x20,0x64,0xc5,0xa0,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,
|
||||
|
@ -170,7 +176,31 @@ static chunk_t keys[] = {
|
|||
0xe8,0x5e,0x3f,0x8e,0x64,0x33,0xb4,0x15,0xbb,0x1b,0xa5,0xed,0xf9,0x4b,0xa7,0xe8,
|
||||
0x5e,0x6f,0x49,0x24,0xf7,0x32,0xf4,0x9b,0x4c,0x47,0xdc,0xf1,0x28,0x44,0x1c,0x37,
|
||||
0xdb,0xee,0xfb,0xd8,0xbd,0x4e,0x5c,0xeb,0x07),
|
||||
chunk_from_chars( /* ECDSA-384 */
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0x87,0x02,0x01,0x00,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,
|
||||
0x01,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x04,0x6d,0x30,0x6b,0x02,
|
||||
0x01,0x01,0x04,0x20,0x42,0xc6,0x8c,0xff,0x2b,0x8b,0x87,0xa1,0xfb,0x50,0xf6,0xfe,
|
||||
0xd6,0x88,0xb3,0x0a,0x48,0xb2,0xc5,0x8f,0x50,0xe0,0xcf,0x40,0xfa,0x57,0xd1,0xc6,
|
||||
0x6c,0x20,0x64,0xc5,0xa1,0x44,0x03,0x42,0x00,0x04,0x9c,0xb2,0x52,0xcb,0xc0,0x5c,
|
||||
0xcf,0x97,0xdd,0xd6,0xe7,0x49,0x32,0x47,0x0c,0x8e,0xdb,0x6d,0xbf,0xc8,0x1a,0x0a,
|
||||
0x01,0xe8,0x5e,0x3f,0x8e,0x64,0x33,0xb4,0x15,0xbb,0x1b,0xa5,0xed,0xf9,0x4b,0xa7,
|
||||
0xe8,0x5e,0x6f,0x49,0x24,0xf7,0x32,0xf4,0x9b,0x4c,0x47,0xdc,0xf1,0x28,0x44,0x1c,
|
||||
0x37,0xdb,0xee,0xfb,0xd8,0xbd,0x4e,0x5c,0xeb,0x07),
|
||||
chunk_from_chars(
|
||||
0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,
|
||||
0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x9c,0xb2,0x52,0xcb,0xc0,
|
||||
0x5c,0xcf,0x97,0xdd,0xd6,0xe7,0x49,0x32,0x47,0x0c,0x8e,0xdb,0x6d,0xbf,0xc8,0x1a,
|
||||
0x0a,0x01,0xe8,0x5e,0x3f,0x8e,0x64,0x33,0xb4,0x15,0xbb,0x1b,0xa5,0xed,0xf9,0x4b,
|
||||
0xa7,0xe8,0x5e,0x6f,0x49,0x24,0xf7,0x32,0xf4,0x9b,0x4c,0x47,0xdc,0xf1,0x28,0x44,
|
||||
0x1c,0x37,0xdb,0xee,0xfb,0xd8,0xbd,0x4e,0x5c,0xeb,0x07),
|
||||
chunk_from_chars(
|
||||
0x07,0x64,0x50,0x1c,0x33,0x37,0x20,0x9b,0xe2,0x0e,0xe9,0x27,0xf0,0x29,0x5b,0x97,
|
||||
0x11,0x5f,0x7c,0xd1),
|
||||
chunk_from_chars(
|
||||
0x1a,0x97,0x25,0x7a,0x48,0xae,0x8a,0x40,0x1a,0x4b,0xa0,0x0f,0x82,0x3c,0xa3,0x1f,
|
||||
0x61,0x91,0xd3,0x91),
|
||||
},
|
||||
{ chunk_from_chars( /* ECDSA-384 */
|
||||
0x30,0x81,0xa4,0x02,0x01,0x01,0x04,0x30,0x4b,0xbf,0x6c,0xf5,0x24,0x78,0x53,0x4b,
|
||||
0x1a,0x91,0x23,0xae,0x30,0xc8,0xb3,0xc9,0xc2,0x9b,0x23,0x07,0x10,0x6f,0x1b,0x47,
|
||||
0x7c,0xa0,0xd4,0x79,0x3c,0xc4,0x83,0x10,0xd1,0x44,0x07,0xc2,0x1b,0x66,0xff,0xae,
|
||||
|
@ -182,7 +212,36 @@ static chunk_t keys[] = {
|
|||
0xda,0xea,0xaf,0xfc,0x7a,0xaf,0x59,0x5f,0xbc,0x91,0x65,0xd3,0x21,0x19,0x61,0xbb,
|
||||
0xfe,0x3c,0xdb,0x47,0xcb,0x7a,0xe7,0x5d,0xbd,0x28,0xde,0x25,0x64,0x9e,0x3a,0xa9,
|
||||
0x18,0xed,0x24,0xe1,0x1f,0x73,0xcc),
|
||||
chunk_from_chars( /* ECDSA-521 */
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0xb6,0x02,0x01,0x00,0x30,0x10,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,
|
||||
0x01,0x06,0x05,0x2b,0x81,0x04,0x00,0x22,0x04,0x81,0x9e,0x30,0x81,0x9b,0x02,0x01,
|
||||
0x01,0x04,0x30,0x4b,0xbf,0x6c,0xf5,0x24,0x78,0x53,0x4b,0x1a,0x91,0x23,0xae,0x30,
|
||||
0xc8,0xb3,0xc9,0xc2,0x9b,0x23,0x07,0x10,0x6f,0x1b,0x47,0x7c,0xa0,0xd4,0x79,0x3c,
|
||||
0xc4,0x83,0x10,0xd1,0x44,0x07,0xc2,0x1b,0x66,0xff,0xae,0x76,0x57,0x72,0x90,0x53,
|
||||
0xc2,0xf5,0x29,0xa1,0x64,0x03,0x62,0x00,0x04,0x1e,0xcf,0x1c,0x85,0x9d,0x06,0xa0,
|
||||
0x54,0xa2,0x24,0x2f,0xd8,0x63,0x56,0x7b,0x70,0x0b,0x7f,0x81,0x96,0xce,0xb9,0x2e,
|
||||
0x35,0x03,0x9c,0xf9,0x0a,0x5d,0x3b,0x10,0xf7,0x13,0x7a,0x0d,0xca,0x56,0xda,0x1d,
|
||||
0x44,0x84,0x07,0x6f,0x58,0xdc,0x34,0x7b,0x1d,0x4c,0xdd,0x28,0x10,0xc0,0xe2,0xae,
|
||||
0xf4,0xd6,0xda,0xea,0xaf,0xfc,0x7a,0xaf,0x59,0x5f,0xbc,0x91,0x65,0xd3,0x21,0x19,
|
||||
0x61,0xbb,0xfe,0x3c,0xdb,0x47,0xcb,0x7a,0xe7,0x5d,0xbd,0x28,0xde,0x25,0x64,0x9e,
|
||||
0x3a,0xa9,0x18,0xed,0x24,0xe1,0x1f,0x73,0xcc),
|
||||
chunk_from_chars(
|
||||
0x30,0x76,0x30,0x10,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x05,0x2b,
|
||||
0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x1e,0xcf,0x1c,0x85,0x9d,0x06,0xa0,0x54,
|
||||
0xa2,0x24,0x2f,0xd8,0x63,0x56,0x7b,0x70,0x0b,0x7f,0x81,0x96,0xce,0xb9,0x2e,0x35,
|
||||
0x03,0x9c,0xf9,0x0a,0x5d,0x3b,0x10,0xf7,0x13,0x7a,0x0d,0xca,0x56,0xda,0x1d,0x44,
|
||||
0x84,0x07,0x6f,0x58,0xdc,0x34,0x7b,0x1d,0x4c,0xdd,0x28,0x10,0xc0,0xe2,0xae,0xf4,
|
||||
0xd6,0xda,0xea,0xaf,0xfc,0x7a,0xaf,0x59,0x5f,0xbc,0x91,0x65,0xd3,0x21,0x19,0x61,
|
||||
0xbb,0xfe,0x3c,0xdb,0x47,0xcb,0x7a,0xe7,0x5d,0xbd,0x28,0xde,0x25,0x64,0x9e,0x3a,
|
||||
0xa9,0x18,0xed,0x24,0xe1,0x1f,0x73,0xcc),
|
||||
chunk_from_chars(
|
||||
0x33,0xe5,0x8b,0x39,0xb7,0x88,0xa1,0xbe,0x86,0x2f,0x5f,0xdf,0x8c,0x48,0xe2,0x4a,
|
||||
0x51,0x4e,0xe8,0xea),
|
||||
chunk_from_chars(
|
||||
0x57,0x5b,0xdb,0x2e,0xa4,0xa9,0xd5,0x53,0x26,0x91,0x76,0x21,0xce,0x68,0x90,0xb2,
|
||||
0xa7,0x09,0x74,0xb4),
|
||||
},
|
||||
{ chunk_from_chars( /* ECDSA-521 */
|
||||
0x30,0x81,0xdc,0x02,0x01,0x01,0x04,0x42,0x01,0xcf,0x38,0xaa,0xa7,0x7a,0x79,0x48,
|
||||
0xa9,0x60,0x55,0x24,0xa8,0x7e,0xe1,0xbc,0x45,0x35,0x16,0xff,0x18,0xce,0x44,0xa2,
|
||||
0x0b,0x72,0x6b,0xca,0x0a,0x40,0xb4,0x97,0x13,0x17,0x90,0x50,0x15,0xb9,0xba,0xfc,
|
||||
|
@ -197,18 +256,78 @@ static chunk_t keys[] = {
|
|||
0x69,0x3d,0x0f,0x2b,0xf3,0xb4,0x03,0x19,0x89,0xcf,0xfa,0x77,0x04,0x15,0xaf,0xdd,
|
||||
0xf7,0x32,0x76,0x25,0x25,0x05,0x8d,0xfd,0x18,0x8a,0xda,0xd6,0xbc,0x71,0xb8,0x9f,
|
||||
0x39,0xb0,0xaf,0xcc,0x54,0xb0,0x9c,0x4d,0x54,0xfb,0x46,0x53,0x5f,0xf8,0x45),
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0xee,0x02,0x01,0x00,0x30,0x10,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,
|
||||
0x01,0x06,0x05,0x2b,0x81,0x04,0x00,0x23,0x04,0x81,0xd6,0x30,0x81,0xd3,0x02,0x01,
|
||||
0x01,0x04,0x42,0x01,0xcf,0x38,0xaa,0xa7,0x7a,0x79,0x48,0xa9,0x60,0x55,0x24,0xa8,
|
||||
0x7e,0xe1,0xbc,0x45,0x35,0x16,0xff,0x18,0xce,0x44,0xa2,0x0b,0x72,0x6b,0xca,0x0a,
|
||||
0x40,0xb4,0x97,0x13,0x17,0x90,0x50,0x15,0xb9,0xba,0xfc,0x08,0x0e,0xdb,0xf8,0xfc,
|
||||
0x06,0x35,0x37,0xbf,0xfb,0x25,0x74,0xfe,0x0f,0xe1,0x3c,0x3a,0xf0,0x0d,0xe0,0x52,
|
||||
0x15,0xa8,0x07,0x6f,0x3e,0xa1,0x81,0x89,0x03,0x81,0x86,0x00,0x04,0x00,0x56,0x81,
|
||||
0x28,0xd6,0xac,0xe9,0xc8,0x82,0x2c,0xac,0x61,0x6d,0xdd,0x88,0x79,0x00,0xe3,0x7a,
|
||||
0x4d,0x25,0xc4,0xea,0x05,0x80,0x75,0x48,0xbc,0x75,0x73,0xc4,0xe9,0x76,0x68,0xba,
|
||||
0x51,0xc3,0x29,0xce,0x7d,0x1b,0xb0,0x8b,0xac,0xc1,0xcc,0x23,0xa7,0x2d,0xa7,0x2c,
|
||||
0x95,0xf6,0x01,0x40,0x26,0x01,0x1c,0x1c,0x9c,0xe7,0xa7,0xb4,0x0f,0x8e,0xba,0x01,
|
||||
0x07,0xb3,0xf7,0xbe,0x45,0x20,0xa9,0x9e,0x70,0xf0,0xcf,0x9b,0xa0,0x91,0xe3,0x88,
|
||||
0x8f,0x04,0x69,0x3d,0x0f,0x2b,0xf3,0xb4,0x03,0x19,0x89,0xcf,0xfa,0x77,0x04,0x15,
|
||||
0xaf,0xdd,0xf7,0x32,0x76,0x25,0x25,0x05,0x8d,0xfd,0x18,0x8a,0xda,0xd6,0xbc,0x71,
|
||||
0xb8,0x9f,0x39,0xb0,0xaf,0xcc,0x54,0xb0,0x9c,0x4d,0x54,0xfb,0x46,0x53,0x5f,0xf8,
|
||||
0x45),
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0x9b,0x30,0x10,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x05,
|
||||
0x2b,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0x56,0x81,0x28,0xd6,0xac,
|
||||
0xe9,0xc8,0x82,0x2c,0xac,0x61,0x6d,0xdd,0x88,0x79,0x00,0xe3,0x7a,0x4d,0x25,0xc4,
|
||||
0xea,0x05,0x80,0x75,0x48,0xbc,0x75,0x73,0xc4,0xe9,0x76,0x68,0xba,0x51,0xc3,0x29,
|
||||
0xce,0x7d,0x1b,0xb0,0x8b,0xac,0xc1,0xcc,0x23,0xa7,0x2d,0xa7,0x2c,0x95,0xf6,0x01,
|
||||
0x40,0x26,0x01,0x1c,0x1c,0x9c,0xe7,0xa7,0xb4,0x0f,0x8e,0xba,0x01,0x07,0xb3,0xf7,
|
||||
0xbe,0x45,0x20,0xa9,0x9e,0x70,0xf0,0xcf,0x9b,0xa0,0x91,0xe3,0x88,0x8f,0x04,0x69,
|
||||
0x3d,0x0f,0x2b,0xf3,0xb4,0x03,0x19,0x89,0xcf,0xfa,0x77,0x04,0x15,0xaf,0xdd,0xf7,
|
||||
0x32,0x76,0x25,0x25,0x05,0x8d,0xfd,0x18,0x8a,0xda,0xd6,0xbc,0x71,0xb8,0x9f,0x39,
|
||||
0xb0,0xaf,0xcc,0x54,0xb0,0x9c,0x4d,0x54,0xfb,0x46,0x53,0x5f,0xf8,0x45),
|
||||
chunk_from_chars(
|
||||
0x1d,0x3b,0x1b,0x05,0xd7,0xcb,0x87,0x17,0x49,0x2c,0x6a,0xed,0x3b,0x82,0xa8,0xc3,
|
||||
0xaa,0x76,0x72,0x91),
|
||||
chunk_from_chars(
|
||||
0xd4,0x6d,0x34,0x22,0xd4,0xdd,0xca,0x63,0x26,0x95,0xb5,0x47,0x9b,0x8b,0x4a,0x30,
|
||||
0x67,0x27,0x3e,0xcd),
|
||||
},
|
||||
};
|
||||
|
||||
START_TEST(test_load)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
chunk_t encoding, fp;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
|
||||
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
|
||||
BUILD_BLOB_ASN1_DER, keys[_i].key, BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
ck_assert(privkey->get_encoding(privkey, PRIVKEY_ASN1_DER, &encoding));
|
||||
if (encoding.len == keys[_i].pkcs8.len)
|
||||
{
|
||||
ck_assert_chunk_eq(keys[_i].pkcs8, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_chunk_eq(keys[_i].key, encoding);
|
||||
}
|
||||
chunk_clear(&encoding);
|
||||
|
||||
ck_assert(privkey->get_fingerprint(privkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_pk, fp);
|
||||
ck_assert(privkey->get_fingerprint(privkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_spki, fp);
|
||||
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
|
||||
ck_assert_chunk_eq(keys[_i].pub, encoding);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_pk, fp);
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_spki, fp);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
|
|
|
@ -532,8 +532,8 @@ START_TEST(test_ed25519_fail)
|
|||
chunk_empty));
|
||||
|
||||
/* RFC 8032, section 5.1.7 requires that 0 <= s < L to prevent signature
|
||||
* malleability. Only a warning because Botan and OpenSSL are both
|
||||
* vulnerable to this. */
|
||||
* malleability. Only a warning because Botan, OpenSSL and wolfSSL are
|
||||
* all vulnerable to this. */
|
||||
if (pubkey->verify(pubkey, SIGN_ED25519, NULL, sig_tests[0].msg,
|
||||
malleable_sig))
|
||||
{
|
||||
|
|
|
@ -172,8 +172,14 @@ END_TEST
|
|||
/**
|
||||
* Private keys to load
|
||||
*/
|
||||
static chunk_t keys[] = {
|
||||
chunk_from_chars( /* RSA-768 */
|
||||
static struct {
|
||||
chunk_t key;
|
||||
chunk_t pkcs8;
|
||||
chunk_t pub;
|
||||
chunk_t fp_pk;
|
||||
chunk_t fp_spki;
|
||||
} keys[] = {
|
||||
{ chunk_from_chars( /* RSA-768 */
|
||||
0x30,0x82,0x01,0xcb,0x02,0x01,0x00,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,
|
||||
0x19,0x87,0x20,0x3f,0x10,0xb0,0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,
|
||||
0xed,0x84,0xb0,0x3e,0x96,0xd3,0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,
|
||||
|
@ -202,9 +208,56 @@ static chunk_t keys[] = {
|
|||
0xfb,0x1e,0x82,0xe4,0x32,0x7a,0x4d,0x17,0x02,0x46,0x82,0x30,0x0b,0x02,0x30,0x09,
|
||||
0xf3,0xce,0x9b,0x02,0xc5,0x53,0xe9,0xa2,0x89,0xe2,0x3b,0x8c,0x8b,0xe9,0xc2,0xba,
|
||||
0x94,0x76,0x60,0x27,0x2b,0xe9,0x92,0xc1,0x5e,0x3c,0xc3,0x77,0x9b,0xc7,0xce,0xc6,
|
||||
0x67,0xd5,0x20,0x2c,0x54,0xa1,0x5d,0x2a,0x17,0x16,0x66,0xdf,0x5a,0xe9,0x87,
|
||||
),
|
||||
chunk_from_chars( /* RSA-1024 */
|
||||
0x67,0xd5,0x20,0x2c,0x54,0xa1,0x5d,0x2a,0x17,0x16,0x66,0xdf,0x5a,0xe9,0x87),
|
||||
chunk_from_chars(
|
||||
0x30,0x82,0x01,0xe5,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
|
||||
0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x01,0xcf,0x30,0x82,0x01,0xcb,0x02,0x01,
|
||||
0x00,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,0x19,0x87,0x20,0x3f,0x10,0xb0,
|
||||
0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,0xed,0x84,0xb0,0x3e,0x96,0xd3,
|
||||
0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,0x08,0xd6,0x44,0xd5,0x01,0x2b,
|
||||
0x3e,0x5d,0xc0,0x37,0xae,0x4f,0xe0,0xea,0x8d,0x2c,0x42,0x4c,0xa9,0xa2,0x42,0xbe,
|
||||
0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,0xb2,0x4f,0xb5,0x9d,0x47,0x9b,
|
||||
0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,0xce,0x7a,0xed,0xa2,0x3e,0xd5,
|
||||
0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01,0x02,0x60,0x2d,0x83,0x82,0x53,0x99,
|
||||
0xb2,0xaa,0x02,0x05,0x11,0x90,0xa8,0x23,0x49,0xe3,0x7b,0xb9,0xdd,0x9b,0xa5,0xa4,
|
||||
0xb0,0x60,0xa7,0x12,0xc5,0x58,0x76,0x92,0x6e,0x9c,0x37,0x6b,0xa8,0x80,0x3f,0x91,
|
||||
0xa2,0x91,0xee,0x3a,0xa2,0x6f,0x91,0x9e,0x0a,0x35,0x69,0xc0,0xa7,0xdc,0xd8,0x46,
|
||||
0xe4,0x29,0x1c,0x3d,0x34,0x30,0xa2,0xb9,0x0d,0x34,0x94,0xa1,0x12,0xa7,0x85,0xd3,
|
||||
0x2c,0x47,0x1b,0xf0,0x78,0xd5,0x22,0xfc,0xa5,0xe0,0x75,0xac,0x71,0x21,0xe8,0xe8,
|
||||
0x19,0x9f,0xbb,0x98,0x5c,0xa6,0x9d,0x42,0xd7,0x9c,0x89,0x02,0x31,0x00,0xee,0xaa,
|
||||
0x9e,0x82,0xe1,0xb2,0xdd,0x05,0xbc,0x2e,0x53,0xe9,0x64,0x4b,0x48,0x06,0x3a,0xfd,
|
||||
0x9e,0x91,0xce,0x1b,0x7f,0x66,0xbc,0xd2,0xc4,0xab,0xbf,0xc5,0x5d,0x1a,0xbd,0xd6,
|
||||
0xb5,0x9c,0x5c,0x18,0x01,0xe6,0x79,0x19,0xf2,0xc3,0x1d,0x66,0x88,0x2d,0x02,0x31,
|
||||
0x00,0xe0,0x92,0x34,0x1e,0x09,0xf2,0x1b,0xf9,0xbf,0x11,0x65,0x3f,0xc8,0x85,0x5a,
|
||||
0xe6,0xc0,0xcf,0x93,0x44,0xb0,0x50,0xe4,0x8b,0x6f,0x30,0xde,0x42,0x0c,0x8a,0x77,
|
||||
0x0d,0x98,0x7f,0x52,0x59,0x9e,0x87,0xb8,0x6e,0xdc,0xed,0x15,0x80,0xbd,0xbb,0xf2,
|
||||
0xeb,0x02,0x31,0x00,0xb0,0x6b,0x36,0x98,0x90,0xb5,0x62,0x63,0xa6,0xe2,0xa7,0xec,
|
||||
0x51,0xd2,0xc3,0xfe,0xb7,0x04,0x5a,0x7e,0x74,0xd8,0x26,0xa8,0x8e,0xd3,0x4d,0xc5,
|
||||
0x97,0x10,0x10,0xee,0x7f,0x7d,0x82,0xe9,0x7d,0xb9,0xd1,0x4d,0xc8,0x1e,0xc2,0x30,
|
||||
0x30,0x3f,0x66,0x51,0x02,0x31,0x00,0xaa,0x75,0x2f,0x4c,0x11,0xbe,0x8d,0x0f,0x8f,
|
||||
0xc1,0x13,0x7a,0x4b,0xa9,0x35,0x6b,0x6b,0xb4,0xe3,0x92,0xc2,0xc6,0x54,0x03,0xa6,
|
||||
0x5d,0x90,0x86,0xcf,0xe0,0x16,0x27,0xe2,0xb5,0xd9,0xfb,0x1e,0x82,0xe4,0x32,0x7a,
|
||||
0x4d,0x17,0x02,0x46,0x82,0x30,0x0b,0x02,0x30,0x09,0xf3,0xce,0x9b,0x02,0xc5,0x53,
|
||||
0xe9,0xa2,0x89,0xe2,0x3b,0x8c,0x8b,0xe9,0xc2,0xba,0x94,0x76,0x60,0x27,0x2b,0xe9,
|
||||
0x92,0xc1,0x5e,0x3c,0xc3,0x77,0x9b,0xc7,0xce,0xc6,0x67,0xd5,0x20,0x2c,0x54,0xa1,
|
||||
0x5d,0x2a,0x17,0x16,0x66,0xdf,0x5a,0xe9,0x87),
|
||||
chunk_from_chars(
|
||||
0x30,0x7c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
|
||||
0x00,0x03,0x6b,0x00,0x30,0x68,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,0x19,
|
||||
0x87,0x20,0x3f,0x10,0xb0,0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,0xed,
|
||||
0x84,0xb0,0x3e,0x96,0xd3,0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,0x08,
|
||||
0xd6,0x44,0xd5,0x01,0x2b,0x3e,0x5d,0xc0,0x37,0xae,0x4f,0xe0,0xea,0x8d,0x2c,0x42,
|
||||
0x4c,0xa9,0xa2,0x42,0xbe,0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,0xb2,
|
||||
0x4f,0xb5,0x9d,0x47,0x9b,0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,0xce,
|
||||
0x7a,0xed,0xa2,0x3e,0xd5,0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01),
|
||||
chunk_from_chars(
|
||||
0x06,0xad,0x82,0xc3,0x58,0x22,0xbb,0x79,0xb5,0xfc,0x48,0xdb,0xa0,0x3c,0x39,0x60,
|
||||
0x00,0x85,0x06,0xca),
|
||||
chunk_from_chars(
|
||||
0x60,0xa2,0x6d,0x32,0x97,0xc5,0x91,0x44,0xa6,0xa6,0xfe,0xe2,0x15,0xb7,0xa5,0xdc,
|
||||
0x79,0x60,0xfd,0x3b),
|
||||
},
|
||||
{ chunk_from_chars( /* RSA-1024 */
|
||||
0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,0x83,0xbc,
|
||||
0xea,0x0b,0x32,0x06,0x4b,0xf5,0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,0x47,0xec,
|
||||
0x0e,0xf9,0xb4,0xcf,0x9a,0x02,0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,0xbc,0x37,
|
||||
|
@ -242,9 +295,68 @@ static chunk_t keys[] = {
|
|||
0x42,0xee,0x12,0x91,0xf9,0x80,0x1e,0x60,0x0b,0xaa,0xbe,0xfd,0x09,0x84,0x93,0x0d,
|
||||
0x09,0xd3,0x1e,0x37,0x52,0xb0,0xe8,0x51,0x4f,0xd3,0x9e,0xda,0x32,0x38,0x22,0x35,
|
||||
0xdb,0x25,0x8b,0x9f,0x1a,0xb5,0xf1,0x75,0xfa,0x4d,0x09,0x42,0x01,0x64,0xe6,0xc4,
|
||||
0x6e,0xba,0x2d,0x88,0x92,0xbe,0xa9,0x1f,0x85,0x38,0x10,0xa3,0x0e,0x1a,0x92,0x54,
|
||||
),
|
||||
chunk_from_chars( /* RSA-1536 */
|
||||
0x6e,0xba,0x2d,0x88,0x92,0xbe,0xa9,0x1f,0x85,0x38,0x10,0xa3,0x0e,0x1a,0x92,0x54),
|
||||
chunk_from_chars(
|
||||
0x30,0x82,0x02,0x76,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
|
||||
0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x02,0x60,0x30,0x82,0x02,0x5c,0x02,0x01,
|
||||
0x00,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,0x83,0xbc,0xea,0x0b,0x32,0x06,0x4b,0xf5,
|
||||
0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,0x47,0xec,0x0e,0xf9,0xb4,0xcf,0x9a,0x02,
|
||||
0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,0xbc,0x37,0x1a,0x25,0x7a,0x37,0x24,0x73,
|
||||
0x53,0x9a,0xf0,0x44,0x64,0x5b,0x6b,0x64,0x4c,0xfa,0x83,0x3a,0x0f,0x77,0x5d,0x7b,
|
||||
0x21,0xa2,0x25,0x00,0x11,0xae,0x72,0x36,0x35,0xd9,0x0d,0xef,0x5a,0xdd,0x98,0x35,
|
||||
0x49,0xaf,0x44,0xa0,0x33,0x29,0xc0,0xca,0xf5,0x6f,0xfe,0xc1,0x06,0x4c,0x80,0x9a,
|
||||
0x54,0xbe,0x46,0x1a,0x96,0xb1,0xf3,0x29,0xb8,0x9d,0x07,0x84,0x03,0x68,0x6b,0x9f,
|
||||
0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd,0x1a,0x61,0x0d,0x3a,0xc8,0x67,0xcd,0x99,
|
||||
0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x13,0xd2,0xa3,
|
||||
0xe5,0xa0,0xb0,0x0a,0xe2,0x0f,0x3c,0x65,0x57,0xa8,0xe9,0x87,0xd5,0x79,0xcc,0xc9,
|
||||
0xca,0xc8,0x8a,0xd5,0xc0,0x74,0x90,0x3e,0x1e,0xda,0x40,0xcd,0x42,0xf7,0x01,0x09,
|
||||
0x9c,0x37,0xfd,0x41,0x6e,0x2b,0x6e,0x5d,0x4a,0x1e,0x52,0x53,0x1b,0xbb,0x3c,0x9f,
|
||||
0xfe,0x91,0x79,0x48,0xfc,0x69,0x90,0xbc,0xbc,0x3d,0xcf,0xee,0x62,0x0a,0xbd,0x57,
|
||||
0x6b,0xa9,0x51,0x3e,0xc2,0x7f,0x26,0xb1,0xaa,0x38,0xeb,0x40,0x91,0x3a,0x3c,0x80,
|
||||
0x1e,0x4e,0xe2,0xff,0xa2,0x8e,0x56,0xbb,0xb3,0xeb,0x24,0x81,0x4c,0x19,0x2c,0x8f,
|
||||
0x51,0x4c,0x04,0x81,0xaf,0x5e,0xc2,0xa6,0xf9,0xd3,0x48,0xee,0xe9,0x6d,0x9b,0xe1,
|
||||
0xe5,0x17,0x4f,0x07,0x18,0xea,0x96,0xd3,0x2c,0xce,0x44,0x71,0x51,0x02,0x41,0x00,
|
||||
0xe9,0xe9,0x46,0x7e,0xe1,0xc2,0x86,0x94,0x65,0x77,0x9c,0xc7,0x76,0x5d,0xa0,0xd3,
|
||||
0xcc,0x1f,0xa3,0xc7,0xfe,0xbb,0x4e,0x27,0xd6,0x43,0x6b,0xbd,0x0d,0x05,0x7a,0x10,
|
||||
0xe8,0x48,0x97,0x30,0xaa,0x53,0x61,0x57,0x1f,0x8a,0xf7,0x39,0x5e,0xa6,0xfe,0xe9,
|
||||
0x2c,0x19,0x5e,0x53,0xea,0xc2,0xb2,0xc2,0x11,0x3c,0x18,0xab,0xcf,0xc4,0x91,0x1b,
|
||||
0x02,0x41,0x00,0xd2,0xf0,0xb1,0x49,0xa1,0x6f,0xf1,0x83,0xa3,0xd2,0xa1,0x0e,0xb3,
|
||||
0xb3,0x33,0x01,0xed,0xd0,0x28,0xc1,0x2f,0x88,0x80,0x9f,0x43,0x7c,0x7e,0x5d,0x4c,
|
||||
0x15,0x05,0x86,0xff,0x75,0x9b,0xf1,0x64,0xde,0x06,0xbf,0xdd,0x98,0x50,0xd9,0x4a,
|
||||
0x3a,0xd6,0x25,0x1c,0xdd,0xc8,0x56,0x12,0x11,0xb9,0x02,0x42,0xc7,0x1d,0x86,0xeb,
|
||||
0xd9,0xc2,0xb9,0x02,0x41,0x00,0x80,0x25,0x8c,0xb9,0x76,0x75,0x5b,0xc5,0x70,0xd1,
|
||||
0x56,0xd2,0xef,0xc5,0xdb,0x96,0x2c,0xfe,0x28,0x7c,0x28,0xd1,0xf4,0xbf,0x5e,0x63,
|
||||
0x11,0x63,0x40,0xfe,0xff,0x20,0xc4,0x21,0x00,0xb3,0x68,0x9c,0xc5,0x77,0x35,0x90,
|
||||
0xac,0x60,0x81,0xba,0x7b,0x6c,0xc2,0xfc,0x22,0xf1,0x56,0x6b,0xd4,0x02,0xfd,0xee,
|
||||
0x2e,0x95,0xf1,0xfd,0x7e,0x81,0x02,0x40,0x47,0xaf,0x84,0x90,0x81,0x4c,0x89,0xc7,
|
||||
0x32,0xe5,0x61,0xd6,0x9d,0x3b,0x49,0x1a,0x5e,0xb7,0x5f,0x22,0x48,0x05,0x1b,0xb1,
|
||||
0x04,0x3e,0x4a,0xb3,0x6a,0x27,0xba,0xb9,0x26,0x17,0xd1,0xe7,0x37,0x60,0x3c,0xea,
|
||||
0xf7,0x63,0xcc,0x16,0x0c,0x23,0xf2,0xa2,0xaa,0x2c,0xb4,0xe8,0x8b,0x3b,0x7a,0xa4,
|
||||
0x4a,0x0d,0x60,0xfb,0x79,0x2b,0x88,0x01,0x02,0x40,0x42,0xee,0x12,0x91,0xf9,0x80,
|
||||
0x1e,0x60,0x0b,0xaa,0xbe,0xfd,0x09,0x84,0x93,0x0d,0x09,0xd3,0x1e,0x37,0x52,0xb0,
|
||||
0xe8,0x51,0x4f,0xd3,0x9e,0xda,0x32,0x38,0x22,0x35,0xdb,0x25,0x8b,0x9f,0x1a,0xb5,
|
||||
0xf1,0x75,0xfa,0x4d,0x09,0x42,0x01,0x64,0xe6,0xc4,0x6e,0xba,0x2d,0x88,0x92,0xbe,
|
||||
0xa9,0x1f,0x85,0x38,0x10,0xa3,0x0e,0x1a,0x92,0x54),
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
|
||||
0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,
|
||||
0x83,0xbc,0xea,0x0b,0x32,0x06,0x4b,0xf5,0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,
|
||||
0x47,0xec,0x0e,0xf9,0xb4,0xcf,0x9a,0x02,0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,
|
||||
0xbc,0x37,0x1a,0x25,0x7a,0x37,0x24,0x73,0x53,0x9a,0xf0,0x44,0x64,0x5b,0x6b,0x64,
|
||||
0x4c,0xfa,0x83,0x3a,0x0f,0x77,0x5d,0x7b,0x21,0xa2,0x25,0x00,0x11,0xae,0x72,0x36,
|
||||
0x35,0xd9,0x0d,0xef,0x5a,0xdd,0x98,0x35,0x49,0xaf,0x44,0xa0,0x33,0x29,0xc0,0xca,
|
||||
0xf5,0x6f,0xfe,0xc1,0x06,0x4c,0x80,0x9a,0x54,0xbe,0x46,0x1a,0x96,0xb1,0xf3,0x29,
|
||||
0xb8,0x9d,0x07,0x84,0x03,0x68,0x6b,0x9f,0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd,
|
||||
0x1a,0x61,0x0d,0x3a,0xc8,0x67,0xcd,0x99,0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01,
|
||||
0x00,0x01),
|
||||
chunk_from_chars(
|
||||
0xda,0xab,0x50,0x22,0x4b,0x4f,0x3b,0xd0,0x82,0xc4,0xa4,0x14,0x06,0x64,0x0b,0x6f,
|
||||
0xad,0xbc,0x69,0xc0),
|
||||
chunk_from_chars(
|
||||
0x92,0xf4,0x02,0x8a,0x3c,0x8f,0x05,0xad,0x3a,0x55,0x1f,0xcf,0x13,0xd8,0xff,0xf2,
|
||||
0x65,0x35,0x75,0xa0),
|
||||
},
|
||||
{ chunk_from_chars( /* RSA-1536 */
|
||||
0x30,0x82,0x03,0x7d,0x02,0x01,0x00,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,0x93,0x7e,
|
||||
0x42,0x13,0x3c,0xba,0x41,0xc1,0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,0x77,0x01,
|
||||
0x70,0x2f,0x6e,0x4a,0xcf,0x2d,0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,0xb3,0xd4,
|
||||
|
@ -301,9 +413,90 @@ static chunk_t keys[] = {
|
|||
0xf0,0x9b,0xba,0xf0,0x90,0xaf,0xa1,0xe8,0xa8,0x70,0xef,0x60,0x6a,0x68,0xed,0x5a,
|
||||
0x21,0x77,0x69,0x7a,0xf2,0xee,0x3e,0xe5,0x90,0xd2,0x33,0x71,0x3b,0x82,0x88,0x75,
|
||||
0xdd,0x8e,0x6e,0xbc,0x17,0x83,0xef,0x37,0x82,0x4e,0x83,0x30,0xcb,0x8a,0xbc,0x6c,
|
||||
0x41,
|
||||
),
|
||||
chunk_from_chars( /* RSA-2048 */
|
||||
0x41),
|
||||
chunk_from_chars(
|
||||
0x30,0x82,0x03,0x97,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
|
||||
0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x03,0x81,0x30,0x82,0x03,0x7d,0x02,0x01,
|
||||
0x00,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,0x93,0x7e,0x42,0x13,0x3c,0xba,0x41,0xc1,
|
||||
0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,0x77,0x01,0x70,0x2f,0x6e,0x4a,0xcf,0x2d,
|
||||
0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,0xb3,0xd4,0xeb,0xe3,0x90,0xf6,0x01,0x03,
|
||||
0x75,0x03,0x1d,0xe8,0x06,0x40,0x15,0xfa,0x96,0x0b,0xd5,0x26,0x64,0xea,0x55,0x82,
|
||||
0x16,0x7b,0xd5,0x1e,0xaa,0x08,0xc7,0x30,0x1a,0x59,0xf8,0xd9,0xe3,0x9e,0x89,0xd9,
|
||||
0x92,0x2c,0x32,0x79,0x0e,0xb3,0x25,0xbc,0x1d,0x7c,0x59,0xde,0x05,0x47,0x8f,0x61,
|
||||
0x77,0xf5,0x4f,0xed,0x82,0x2c,0xf8,0x2a,0x3e,0x02,0xf3,0xc0,0x15,0x51,0xde,0x05,
|
||||
0xc4,0xfc,0x80,0x91,0xae,0x06,0x1b,0xd7,0x39,0x8e,0x9a,0x6d,0xb3,0x2f,0xb0,0xd0,
|
||||
0xc8,0x96,0xa6,0x88,0xb3,0x17,0xca,0x58,0xbe,0x38,0x2c,0x64,0x35,0x5a,0x29,0xb7,
|
||||
0xf8,0x74,0x3d,0xbb,0xec,0x90,0x01,0x04,0x64,0x3d,0x38,0x0f,0x87,0xce,0xd7,0xfc,
|
||||
0xd2,0x96,0x93,0x31,0x85,0x0d,0x2d,0xa5,0x91,0xe2,0xfc,0x7b,0xea,0xb0,0x89,0x24,
|
||||
0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54,0x74,0xe4,0x11,0xa8,0x04,0x6f,0x40,0xeb,
|
||||
0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01,0x00,0x01,0x02,0x81,0xc0,0x0a,0x96,0xec,
|
||||
0x63,0xc1,0xa0,0x39,0xd9,0xd3,0x8d,0xfd,0x4a,0x2a,0x13,0x54,0x0c,0x48,0x96,0xae,
|
||||
0x43,0x3c,0x04,0x20,0xd3,0xe5,0x8e,0x46,0xb5,0x6c,0x05,0xad,0xe0,0xc7,0xbc,0x39,
|
||||
0x05,0x44,0x17,0xd7,0xad,0xb3,0x9a,0xcc,0x18,0xd9,0xc3,0xdc,0x8d,0x5a,0x1d,0x44,
|
||||
0xb5,0x32,0xd7,0x71,0x94,0xff,0x48,0x38,0x16,0x51,0x0e,0xfa,0xed,0x54,0x91,0x00,
|
||||
0xd3,0x45,0x6c,0xd9,0xdf,0xd1,0x70,0x6b,0x31,0x22,0xaa,0xfb,0x7c,0x0f,0x3f,0xa0,
|
||||
0xa0,0xa5,0x16,0xac,0x83,0x6d,0x12,0x1d,0x4a,0x40,0x4e,0xb6,0x9c,0xf4,0x67,0xaa,
|
||||
0xa9,0xb0,0xc8,0xb4,0x0a,0xd5,0x3b,0x5c,0x19,0xed,0x86,0x83,0x5a,0x75,0xbc,0xeb,
|
||||
0x17,0xc8,0x16,0xa0,0x60,0x2e,0xb6,0x25,0xc5,0x4d,0x59,0xba,0x62,0xcb,0x3d,0x91,
|
||||
0x7c,0x79,0x6a,0x4b,0x4a,0x54,0xbd,0xb7,0xa3,0x89,0x7f,0xbf,0x0e,0x77,0xe1,0x54,
|
||||
0x29,0x0d,0x45,0x6d,0xa8,0x15,0xa5,0x17,0x8c,0xcf,0x27,0x9e,0x47,0x4e,0x2a,0x91,
|
||||
0x7e,0x4e,0x14,0x59,0x8c,0x62,0x91,0xa3,0x40,0xa5,0x9e,0x67,0xbb,0x02,0x97,0xb4,
|
||||
0xe7,0x06,0x04,0xbc,0x16,0x24,0x3d,0x49,0xb1,0xf0,0xae,0xfc,0x1d,0x02,0x61,0x00,
|
||||
0xde,0x86,0x5d,0x49,0x88,0xeb,0x5c,0xd3,0xe5,0x11,0x48,0x0b,0x1e,0x52,0x95,0xa9,
|
||||
0x65,0x99,0x89,0xcf,0x51,0xb0,0x08,0xdd,0xb5,0x5b,0x64,0x1a,0x34,0xd2,0xee,0x4b,
|
||||
0x2d,0x8b,0xc1,0xd5,0xd6,0x1d,0x6c,0x0c,0x7e,0xa5,0x66,0x12,0xec,0xaf,0x5d,0xe9,
|
||||
0x33,0xd4,0xba,0x18,0x71,0x84,0x97,0xbe,0xc0,0x75,0x63,0x19,0xae,0xc6,0xc7,0x65,
|
||||
0xf3,0xf6,0xda,0x3f,0x91,0xfa,0x5e,0x87,0xf3,0xbc,0xd2,0x64,0x8d,0xcf,0xfb,0xdd,
|
||||
0x7f,0x9b,0x6c,0x81,0xba,0x9b,0x4e,0x94,0x5e,0x83,0xd1,0xcb,0xb9,0xf4,0x39,0x7f,
|
||||
0x02,0x61,0x00,0xd7,0x00,0x6d,0x8e,0x1b,0xa1,0x44,0xd9,0xff,0xe6,0x42,0x72,0x18,
|
||||
0x55,0x26,0x3e,0x87,0x40,0x71,0xb2,0x67,0x37,0x16,0xe9,0xbd,0x51,0x7f,0x0e,0x79,
|
||||
0x0e,0x75,0xa9,0x1f,0x0f,0x6b,0xa5,0x7c,0x5f,0xc8,0xdc,0x17,0xde,0x53,0x88,0x97,
|
||||
0x90,0x88,0xf2,0x4d,0x66,0x5e,0x0e,0x11,0x16,0x92,0x1e,0x61,0x56,0xe6,0xf0,0x74,
|
||||
0x81,0x58,0x95,0x05,0x29,0x71,0x9b,0xa0,0x69,0xed,0x14,0x23,0xf6,0x36,0x9b,0x8f,
|
||||
0x06,0x3a,0x76,0xab,0xeb,0xce,0xe8,0xdc,0x79,0xc1,0x29,0xb9,0xfc,0x49,0x7a,0x26,
|
||||
0x59,0xd6,0x4d,0x02,0x61,0x00,0xaf,0x3c,0xac,0xd6,0x2d,0xe6,0xfb,0x91,0x3a,0xc1,
|
||||
0x23,0x34,0xee,0x4a,0x26,0xe5,0xe1,0xc6,0xc9,0xc9,0xe4,0x10,0x76,0xca,0xf1,0xf8,
|
||||
0xe8,0x99,0xe2,0xa3,0x81,0x58,0xde,0xa3,0x42,0xa0,0x3d,0x1f,0xaa,0x69,0x24,0x8a,
|
||||
0xe8,0x19,0x5b,0x1e,0xb7,0x1b,0xe0,0xdf,0x53,0x35,0xd0,0x9f,0x94,0x48,0x79,0x93,
|
||||
0x77,0xd9,0x4f,0xd3,0xe6,0x4f,0x19,0x92,0x7a,0x48,0xb9,0x92,0xab,0x42,0xf0,0xe4,
|
||||
0xef,0xe2,0x93,0xf3,0x07,0xeb,0x64,0x84,0x67,0x2c,0xba,0x61,0x77,0xbe,0x4b,0xb8,
|
||||
0x0f,0x4d,0x1a,0x41,0x83,0xcd,0x02,0x60,0x56,0xec,0x55,0x5e,0x9e,0xcd,0x14,0x89,
|
||||
0x0e,0x6c,0x89,0x70,0x97,0x65,0xd5,0x90,0x72,0x1e,0x1b,0xd9,0x84,0xe1,0x40,0xe2,
|
||||
0x3f,0x28,0x33,0xb6,0x26,0x3b,0x32,0x56,0xad,0xb8,0x0e,0x4d,0x59,0x7b,0x60,0x39,
|
||||
0x9b,0x6c,0xc7,0x58,0xf1,0xed,0xfd,0x6f,0xf8,0xda,0xea,0x2b,0xc5,0xbc,0xda,0x56,
|
||||
0x6e,0x04,0x34,0x5a,0x02,0xc0,0x48,0x8f,0xf7,0x06,0x4a,0x68,0x20,0xf2,0xb2,0x66,
|
||||
0xf2,0x23,0x18,0xf0,0xcb,0x62,0x39,0x40,0xc1,0x41,0x14,0xe6,0x10,0x3d,0x29,0x5b,
|
||||
0x35,0x56,0x4a,0x5e,0x98,0x22,0xba,0x01,0x02,0x61,0x00,0xcc,0x80,0xb7,0xb9,0xb9,
|
||||
0x4a,0xaf,0x47,0x00,0x3e,0x21,0x0f,0xb8,0x4e,0x7c,0xb1,0xe4,0x25,0xd6,0x19,0x26,
|
||||
0x54,0xc6,0x8c,0x30,0x88,0x54,0x70,0xcf,0x1f,0x62,0x75,0xcb,0x18,0x58,0x6c,0x14,
|
||||
0xb0,0x9b,0x13,0x90,0xa2,0x1a,0x5a,0x79,0xa3,0x82,0xf0,0x9b,0xba,0xf0,0x90,0xaf,
|
||||
0xa1,0xe8,0xa8,0x70,0xef,0x60,0x6a,0x68,0xed,0x5a,0x21,0x77,0x69,0x7a,0xf2,0xee,
|
||||
0x3e,0xe5,0x90,0xd2,0x33,0x71,0x3b,0x82,0x88,0x75,0xdd,0x8e,0x6e,0xbc,0x17,0x83,
|
||||
0xef,0x37,0x82,0x4e,0x83,0x30,0xcb,0x8a,0xbc,0x6c,0x41),
|
||||
chunk_from_chars(
|
||||
0x30,0x81,0xdf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
|
||||
0x05,0x00,0x03,0x81,0xcd,0x00,0x30,0x81,0xc9,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,
|
||||
0x93,0x7e,0x42,0x13,0x3c,0xba,0x41,0xc1,0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,
|
||||
0x77,0x01,0x70,0x2f,0x6e,0x4a,0xcf,0x2d,0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,
|
||||
0xb3,0xd4,0xeb,0xe3,0x90,0xf6,0x01,0x03,0x75,0x03,0x1d,0xe8,0x06,0x40,0x15,0xfa,
|
||||
0x96,0x0b,0xd5,0x26,0x64,0xea,0x55,0x82,0x16,0x7b,0xd5,0x1e,0xaa,0x08,0xc7,0x30,
|
||||
0x1a,0x59,0xf8,0xd9,0xe3,0x9e,0x89,0xd9,0x92,0x2c,0x32,0x79,0x0e,0xb3,0x25,0xbc,
|
||||
0x1d,0x7c,0x59,0xde,0x05,0x47,0x8f,0x61,0x77,0xf5,0x4f,0xed,0x82,0x2c,0xf8,0x2a,
|
||||
0x3e,0x02,0xf3,0xc0,0x15,0x51,0xde,0x05,0xc4,0xfc,0x80,0x91,0xae,0x06,0x1b,0xd7,
|
||||
0x39,0x8e,0x9a,0x6d,0xb3,0x2f,0xb0,0xd0,0xc8,0x96,0xa6,0x88,0xb3,0x17,0xca,0x58,
|
||||
0xbe,0x38,0x2c,0x64,0x35,0x5a,0x29,0xb7,0xf8,0x74,0x3d,0xbb,0xec,0x90,0x01,0x04,
|
||||
0x64,0x3d,0x38,0x0f,0x87,0xce,0xd7,0xfc,0xd2,0x96,0x93,0x31,0x85,0x0d,0x2d,0xa5,
|
||||
0x91,0xe2,0xfc,0x7b,0xea,0xb0,0x89,0x24,0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54,
|
||||
0x74,0xe4,0x11,0xa8,0x04,0x6f,0x40,0xeb,0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01,
|
||||
0x00,0x01),
|
||||
chunk_from_chars(
|
||||
0x21,0x00,0x8c,0xe1,0x78,0x25,0x67,0x19,0xb7,0xd0,0xcb,0x13,0x01,0x7a,0xa3,0x71,
|
||||
0x67,0x46,0x96,0xf1),
|
||||
chunk_from_chars(
|
||||
0x58,0x4d,0x4c,0x27,0x98,0x15,0x76,0xab,0x29,0xc9,0xf3,0xd1,0xa0,0xc4,0x50,0x0d,
|
||||
0x42,0x30,0x43,0x19),
|
||||
},
|
||||
{ chunk_from_chars( /* RSA-2048 */
|
||||
0x30,0x82,0x04,0xa2,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,0xba,0xbf,0x27,0x0b,
|
||||
0x22,0x59,0xd8,0x6f,0xff,0x26,0x5d,0x41,0x3d,0xb0,0x94,0x58,0x5d,0xc0,0x46,0xb6,
|
||||
0x77,0xa9,0x78,0x10,0x6d,0xe9,0xbf,0xca,0x6f,0x04,0xe1,0xda,0x85,0x12,0x1e,0xe0,
|
||||
|
@ -378,20 +571,148 @@ static chunk_t keys[] = {
|
|||
0x78,0x30,0x5f,0xdf,0x46,0xa6,0xb0,0x28,0x37,0x2b,0x55,0x08,0x4c,0xb6,0x6b,0xb8,
|
||||
0xa9,0x11,0x7d,0x0b,0xab,0x97,0x4d,0x8c,0xc3,0xbf,0x3b,0xcd,0x3e,0xad,0x80,0xce,
|
||||
0xe8,0xc6,0x01,0x35,0xd2,0x3e,0x31,0xdc,0x96,0xd7,0xc3,0xab,0x65,0xd1,0xc4,0xa3,
|
||||
0x47,0x14,0xa9,0xba,0xd0,0x30,
|
||||
),
|
||||
0x47,0x14,0xa9,0xba,0xd0,0x30),
|
||||
chunk_from_chars(
|
||||
0x30,0x82,0x04,0xbc,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
|
||||
0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x04,0xa6,0x30,0x82,0x04,0xa2,0x02,0x01,
|
||||
0x00,0x02,0x82,0x01,0x01,0x00,0xba,0xbf,0x27,0x0b,0x22,0x59,0xd8,0x6f,0xff,0x26,
|
||||
0x5d,0x41,0x3d,0xb0,0x94,0x58,0x5d,0xc0,0x46,0xb6,0x77,0xa9,0x78,0x10,0x6d,0xe9,
|
||||
0xbf,0xca,0x6f,0x04,0xe1,0xda,0x85,0x12,0x1e,0xe0,0xa6,0xc7,0xa2,0x71,0x04,0x8b,
|
||||
0x6e,0x84,0xf9,0x86,0x2b,0xeb,0x72,0x01,0x72,0xc8,0x0a,0x83,0xa6,0xf7,0xc0,0xd6,
|
||||
0x76,0x1d,0x28,0x38,0xb5,0x7e,0x6c,0x8c,0x6a,0x13,0xf4,0xf1,0x7f,0xf2,0x79,0xae,
|
||||
0x73,0xba,0x1a,0x3f,0x30,0x65,0xb6,0x23,0xa7,0x94,0x34,0x29,0x87,0xce,0x06,0x99,
|
||||
0xee,0x85,0x10,0xce,0x08,0xe2,0x8d,0xd5,0x47,0xf3,0xc8,0xf0,0x18,0x41,0xc0,0x59,
|
||||
0x66,0x06,0xda,0xb6,0x18,0xd2,0xa3,0xa0,0xbd,0x3a,0x90,0x7f,0x37,0x39,0xdf,0x98,
|
||||
0x55,0xa2,0x19,0x5e,0x37,0xbc,0x86,0xf3,0x02,0xf8,0x68,0x49,0x53,0xf2,0x4b,0x3d,
|
||||
0x7a,0xe3,0x1d,0xa4,0x15,0x10,0xa6,0xce,0x8c,0xb8,0xfd,0x95,0x54,0xa2,0x50,0xa2,
|
||||
0xd9,0x35,0x12,0x56,0xae,0xbc,0x51,0x33,0x6d,0xb8,0x63,0x7c,0x26,0xab,0x19,0x01,
|
||||
0xa5,0xda,0xfa,0x4b,0xb6,0x57,0xd3,0x4b,0xdd,0xc0,0x62,0xc5,0x05,0xb7,0xc3,0x2e,
|
||||
0x1f,0x17,0xc8,0x09,0x87,0x12,0x37,0x21,0xd7,0x7a,0x53,0xb0,0x47,0x60,0xa2,0xb5,
|
||||
0x23,0x3b,0x99,0xdf,0xea,0x8b,0x94,0xea,0x9d,0x53,0x5d,0x02,0x52,0xf7,0x29,0xfb,
|
||||
0x63,0xb0,0xff,0x27,0x5e,0xde,0x54,0x7d,0x95,0xd6,0x4e,0x58,0x12,0x06,0x60,0x22,
|
||||
0x33,0xf2,0x19,0x67,0x65,0xdd,0xf3,0x42,0xb5,0x00,0x51,0x35,0xe5,0x62,0x4d,0x90,
|
||||
0x44,0xfb,0x7f,0x5b,0xb5,0xe5,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x1c,
|
||||
0xf5,0x66,0xf5,0xce,0x4c,0x1d,0xe8,0xd2,0x29,0x6e,0x15,0x1f,0x9e,0x9a,0x06,0x70,
|
||||
0xf5,0x4f,0xd1,0xdc,0x51,0x02,0x8e,0x13,0xa9,0x47,0x85,0x39,0xfd,0x89,0x13,0x74,
|
||||
0x86,0xb8,0x94,0x90,0x30,0x4d,0x73,0x96,0xa7,0x93,0x8a,0x19,0xd2,0x91,0x4d,0x77,
|
||||
0xb6,0x9b,0x48,0xc3,0x7e,0xa2,0x5d,0xf1,0x80,0xa0,0x3c,0xc9,0xbf,0xaf,0x7f,0x4d,
|
||||
0x10,0x62,0x23,0xb9,0x9c,0x58,0x81,0xae,0x96,0x5b,0x9a,0x4c,0x97,0x27,0x67,0x62,
|
||||
0x5c,0xf9,0x8f,0xdd,0x1d,0xe2,0x92,0x13,0x8a,0x7b,0xc7,0x15,0x31,0xca,0x05,0x6d,
|
||||
0xc6,0x98,0xdb,0x88,0x39,0x99,0x1d,0x5b,0x19,0x51,0xdd,0xb6,0xbd,0x3d,0xb0,0xae,
|
||||
0x50,0x8e,0xff,0x7d,0xa8,0x48,0x95,0x58,0x23,0xbc,0x85,0xc0,0x46,0xd0,0xc0,0x0e,
|
||||
0xda,0xdd,0xa4,0x8e,0x8d,0x31,0x8b,0x89,0x0f,0x8b,0x76,0x9a,0xb5,0x99,0x56,0x5e,
|
||||
0xd3,0x0c,0x88,0x0b,0x03,0xf1,0xc9,0xe3,0x05,0x05,0x08,0x75,0xce,0x35,0x52,0xa0,
|
||||
0xc0,0xf2,0xf4,0xb9,0x87,0x22,0x21,0x3f,0x61,0xd6,0x99,0xae,0x0e,0x76,0x5d,0x9c,
|
||||
0x16,0xa3,0xe9,0xde,0x2d,0x2a,0x46,0xf7,0x89,0xbf,0x0d,0xb1,0x60,0xad,0xbc,0x24,
|
||||
0xe2,0xe5,0xb1,0xc1,0x1c,0x00,0x40,0x1c,0xbd,0xfa,0x6e,0xc7,0x0d,0xc1,0xda,0x4d,
|
||||
0x54,0x45,0x96,0xac,0xf7,0xfe,0x1b,0xf2,0x47,0x1e,0xf7,0x8b,0xcf,0x27,0xcc,0xe7,
|
||||
0x08,0xd6,0x43,0x60,0xea,0xda,0x19,0xd7,0x98,0x17,0x7c,0xab,0x0c,0x90,0x60,0x75,
|
||||
0x9f,0x8b,0xaa,0x13,0x63,0x98,0x9e,0xc6,0x41,0x9f,0xd4,0x85,0xa3,0xb2,0xb9,0x02,
|
||||
0x81,0x81,0x00,0xe1,0x20,0xf6,0xac,0xa9,0x01,0xbd,0x31,0xe6,0xb2,0x4e,0xcf,0x66,
|
||||
0xc3,0x11,0x0e,0x5b,0xfe,0x58,0x6b,0xc6,0x2d,0x7a,0x05,0x30,0x9a,0x6f,0xcc,0xcc,
|
||||
0xdf,0xd2,0x2c,0xe1,0x47,0x39,0x9e,0xf3,0x0c,0x81,0xd9,0x76,0x00,0xe2,0xb1,0x08,
|
||||
0x91,0xfb,0x12,0x04,0xf6,0x1f,0xea,0xff,0x82,0xe5,0x64,0x64,0x6f,0x14,0xbe,0x33,
|
||||
0x5f,0x41,0x5f,0x73,0x1f,0xa2,0x32,0xec,0x75,0xb3,0x98,0x4b,0x88,0x4d,0x1e,0xec,
|
||||
0x78,0xda,0x4c,0x2d,0xf8,0xbb,0xcf,0x0e,0x8f,0x2f,0x23,0xae,0xcd,0xe0,0x4c,0x13,
|
||||
0x1c,0x1c,0x16,0x8e,0xb9,0x9f,0x02,0x12,0x12,0xa5,0xf4,0x21,0xfe,0x57,0x08,0x7a,
|
||||
0xe8,0xbe,0x15,0xe9,0xdd,0x2a,0xd1,0x7b,0x39,0xd6,0x4f,0x70,0x74,0x7d,0xfd,0x39,
|
||||
0x97,0x80,0x8d,0x02,0x81,0x81,0x00,0xd4,0x5a,0xce,0x05,0x93,0x51,0x15,0x44,0xdd,
|
||||
0x4d,0x79,0x92,0x04,0xe6,0x64,0x7e,0x6c,0xb5,0x61,0x6b,0xc3,0xb3,0xae,0x4f,0x0a,
|
||||
0x75,0xbf,0x6c,0xec,0x47,0xf2,0xbc,0xea,0x76,0xc4,0xc2,0xe7,0xd2,0x50,0xc4,0xe0,
|
||||
0xaf,0x56,0x05,0x72,0x3c,0x34,0x8c,0x5b,0xae,0xb8,0x0e,0xfb,0x83,0x27,0xcf,0x61,
|
||||
0x05,0x44,0x97,0x3f,0x66,0x6d,0x26,0x7d,0xed,0xcd,0x5a,0x87,0x04,0xbc,0xb3,0x70,
|
||||
0x75,0x15,0x51,0xe9,0x18,0x85,0xf7,0x2a,0x45,0xd5,0xc7,0x93,0x32,0x07,0x2e,0x26,
|
||||
0x34,0x2d,0x18,0x63,0x45,0x06,0x6f,0xa9,0x75,0x5d,0x20,0x6b,0x0b,0x13,0x45,0x81,
|
||||
0x7e,0x5c,0xc5,0x48,0x16,0x4b,0x82,0x7c,0xad,0xbe,0xfd,0xa5,0x0a,0xd6,0xc2,0x21,
|
||||
0xfc,0xa5,0x84,0xaf,0xf3,0x10,0xb9,0x02,0x81,0x80,0x29,0x20,0x20,0x6f,0xc2,0x1f,
|
||||
0xf3,0x33,0xde,0x74,0xcc,0x38,0xcf,0x08,0xeb,0x60,0xb8,0x25,0x6a,0x79,0xa5,0xa6,
|
||||
0x41,0x18,0x19,0x9c,0xdc,0xb7,0x88,0xe5,0x8a,0x3b,0x70,0x9b,0xd6,0x46,0xd7,0x17,
|
||||
0x7d,0xd0,0xff,0xe1,0x81,0x87,0xdd,0x8c,0xed,0x54,0x89,0x5b,0x7c,0xd1,0x2d,0x03,
|
||||
0xf8,0x6b,0xb2,0x7d,0x28,0x48,0xe6,0x91,0x8c,0x1b,0xa7,0xa8,0x2b,0xb5,0x29,0xc5,
|
||||
0x06,0x9d,0xd7,0x8e,0x7a,0xa8,0x1f,0x82,0xa4,0x3e,0x2e,0x57,0xb5,0xd7,0x49,0x4d,
|
||||
0x96,0xca,0xe9,0xef,0xe9,0xfd,0x7b,0xb0,0x32,0xe1,0x5c,0x09,0x44,0xa6,0xd8,0x2e,
|
||||
0x57,0xea,0x95,0x1b,0x25,0x43,0x03,0x50,0xe9,0x08,0x8f,0xc4,0x3b,0x42,0x31,0x44,
|
||||
0x8b,0x85,0xcf,0x81,0x38,0x52,0xbd,0xe6,0x93,0x31,0x02,0x81,0x80,0x18,0x3d,0x79,
|
||||
0x51,0x07,0x9c,0xf4,0xd9,0x94,0x8d,0x78,0x78,0x23,0x99,0x0d,0x15,0xa5,0x61,0x1b,
|
||||
0x0a,0xcb,0x1f,0x22,0xa1,0xa1,0x27,0x09,0xbf,0xec,0x44,0xd6,0x3f,0x9c,0x60,0x0c,
|
||||
0x5b,0xd7,0x4c,0x99,0xad,0xaf,0x9c,0x34,0x2c,0x90,0xfa,0xb0,0x60,0xe9,0x42,0x4b,
|
||||
0x7e,0x62,0x55,0x79,0x60,0xe1,0xc9,0x51,0x28,0x16,0xb3,0xa1,0x78,0x08,0x5d,0xf1,
|
||||
0xd8,0x08,0x9b,0x90,0xd2,0xc6,0xde,0x86,0x9d,0x80,0x07,0x2d,0x9b,0xa6,0x36,0xac,
|
||||
0x8d,0x88,0x8e,0xe8,0x64,0xeb,0x35,0x7f,0x84,0x4e,0x28,0x9d,0xf0,0x77,0x1e,0x8f,
|
||||
0x8f,0xd8,0xc8,0x3d,0xdd,0xec,0x47,0x39,0x5d,0xc7,0xb9,0xcb,0xca,0xcc,0x62,0xa4,
|
||||
0xef,0x9d,0x3c,0x5c,0x81,0x72,0x91,0xbd,0x6f,0x25,0x0a,0x90,0xf9,0x02,0x81,0x80,
|
||||
0x51,0x42,0x23,0x64,0x3d,0xbc,0xcb,0xcb,0x77,0xd4,0x5c,0x6b,0xf4,0x16,0x3a,0x6b,
|
||||
0x05,0x5f,0xd4,0xf8,0x59,0xe6,0x98,0x0c,0x43,0x7e,0x6b,0x17,0x0d,0x01,0x23,0x6e,
|
||||
0x4c,0xff,0x35,0xe4,0xc5,0xba,0xe8,0x9e,0x12,0x94,0x34,0x78,0xe4,0x3d,0x35,0xa1,
|
||||
0xd4,0xa9,0xa3,0x7e,0xe4,0x57,0xef,0xa4,0x9a,0x6a,0x32,0xb3,0x9f,0xf8,0x3a,0xcf,
|
||||
0xea,0xf4,0xc7,0x59,0x92,0xd4,0x2a,0x5b,0x26,0x83,0x78,0x30,0x5f,0xdf,0x46,0xa6,
|
||||
0xb0,0x28,0x37,0x2b,0x55,0x08,0x4c,0xb6,0x6b,0xb8,0xa9,0x11,0x7d,0x0b,0xab,0x97,
|
||||
0x4d,0x8c,0xc3,0xbf,0x3b,0xcd,0x3e,0xad,0x80,0xce,0xe8,0xc6,0x01,0x35,0xd2,0x3e,
|
||||
0x31,0xdc,0x96,0xd7,0xc3,0xab,0x65,0xd1,0xc4,0xa3,0x47,0x14,0xa9,0xba,0xd0,0x30),
|
||||
chunk_from_chars(
|
||||
0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
|
||||
0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
|
||||
0x00,0xba,0xbf,0x27,0x0b,0x22,0x59,0xd8,0x6f,0xff,0x26,0x5d,0x41,0x3d,0xb0,0x94,
|
||||
0x58,0x5d,0xc0,0x46,0xb6,0x77,0xa9,0x78,0x10,0x6d,0xe9,0xbf,0xca,0x6f,0x04,0xe1,
|
||||
0xda,0x85,0x12,0x1e,0xe0,0xa6,0xc7,0xa2,0x71,0x04,0x8b,0x6e,0x84,0xf9,0x86,0x2b,
|
||||
0xeb,0x72,0x01,0x72,0xc8,0x0a,0x83,0xa6,0xf7,0xc0,0xd6,0x76,0x1d,0x28,0x38,0xb5,
|
||||
0x7e,0x6c,0x8c,0x6a,0x13,0xf4,0xf1,0x7f,0xf2,0x79,0xae,0x73,0xba,0x1a,0x3f,0x30,
|
||||
0x65,0xb6,0x23,0xa7,0x94,0x34,0x29,0x87,0xce,0x06,0x99,0xee,0x85,0x10,0xce,0x08,
|
||||
0xe2,0x8d,0xd5,0x47,0xf3,0xc8,0xf0,0x18,0x41,0xc0,0x59,0x66,0x06,0xda,0xb6,0x18,
|
||||
0xd2,0xa3,0xa0,0xbd,0x3a,0x90,0x7f,0x37,0x39,0xdf,0x98,0x55,0xa2,0x19,0x5e,0x37,
|
||||
0xbc,0x86,0xf3,0x02,0xf8,0x68,0x49,0x53,0xf2,0x4b,0x3d,0x7a,0xe3,0x1d,0xa4,0x15,
|
||||
0x10,0xa6,0xce,0x8c,0xb8,0xfd,0x95,0x54,0xa2,0x50,0xa2,0xd9,0x35,0x12,0x56,0xae,
|
||||
0xbc,0x51,0x33,0x6d,0xb8,0x63,0x7c,0x26,0xab,0x19,0x01,0xa5,0xda,0xfa,0x4b,0xb6,
|
||||
0x57,0xd3,0x4b,0xdd,0xc0,0x62,0xc5,0x05,0xb7,0xc3,0x2e,0x1f,0x17,0xc8,0x09,0x87,
|
||||
0x12,0x37,0x21,0xd7,0x7a,0x53,0xb0,0x47,0x60,0xa2,0xb5,0x23,0x3b,0x99,0xdf,0xea,
|
||||
0x8b,0x94,0xea,0x9d,0x53,0x5d,0x02,0x52,0xf7,0x29,0xfb,0x63,0xb0,0xff,0x27,0x5e,
|
||||
0xde,0x54,0x7d,0x95,0xd6,0x4e,0x58,0x12,0x06,0x60,0x22,0x33,0xf2,0x19,0x67,0x65,
|
||||
0xdd,0xf3,0x42,0xb5,0x00,0x51,0x35,0xe5,0x62,0x4d,0x90,0x44,0xfb,0x7f,0x5b,0xb5,
|
||||
0xe5,0x02,0x03,0x01,0x00,0x01),
|
||||
chunk_from_chars(
|
||||
0x4f,0xe8,0x82,0xee,0xaa,0x2c,0x7b,0x3f,0x3a,0xf1,0xb4,0xe1,0xe3,0x85,0xd4,0xb1,
|
||||
0xb4,0x34,0x5c,0x2d),
|
||||
chunk_from_chars(
|
||||
0x29,0xe3,0x4b,0x6c,0x41,0x08,0xf2,0x6d,0xe5,0x1a,0x99,0x02,0xdf,0x9c,0x02,0xe3,
|
||||
0x67,0xdf,0xfd,0xb3),
|
||||
},
|
||||
};
|
||||
|
||||
START_TEST(test_load)
|
||||
{
|
||||
private_key_t *privkey;
|
||||
public_key_t *pubkey;
|
||||
chunk_t encoding, fp;
|
||||
|
||||
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
|
||||
BUILD_BLOB_ASN1_DER, keys[_i].key, BUILD_END);
|
||||
ck_assert(privkey != NULL);
|
||||
ck_assert(privkey->get_encoding(privkey, PRIVKEY_ASN1_DER, &encoding));
|
||||
if (encoding.len == keys[_i].pkcs8.len)
|
||||
{
|
||||
ck_assert_chunk_eq(keys[_i].pkcs8, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
ck_assert_chunk_eq(keys[_i].key, encoding);
|
||||
}
|
||||
chunk_clear(&encoding);
|
||||
|
||||
ck_assert(privkey->get_fingerprint(privkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_pk, fp);
|
||||
ck_assert(privkey->get_fingerprint(privkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_spki, fp);
|
||||
|
||||
pubkey = privkey->get_public_key(privkey);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
|
||||
ck_assert_chunk_eq(keys[_i].pub, encoding);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_pk, fp);
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(keys[_i].fp_spki, fp);
|
||||
|
||||
test_good_sig(privkey, pubkey);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008-2019 Tobias Brunner
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -752,6 +752,26 @@ bool chunk_increment(chunk_t chunk)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr)
|
||||
{
|
||||
if (dst.ptr)
|
||||
{
|
||||
if (dst.len > src.len)
|
||||
{
|
||||
memcpy(dst.ptr + dst.len - src.len, src.ptr, src.len);
|
||||
memset(dst.ptr, chr, dst.len - src.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dst.ptr, src.ptr + src.len - dst.len, dst.len);
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove non-printable characters from a chunk.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008-2019 Tobias Brunner
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -292,6 +292,16 @@ static inline chunk_t chunk_skip_zero(chunk_t chunk)
|
|||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the data from src to dst, left-padded with chr if dst is longer,
|
||||
* otherwise data is copied truncated on the left.
|
||||
*
|
||||
* @param dst data is copied here
|
||||
* @param src data is copied from here
|
||||
* @param chr value to use for padding if necessary
|
||||
* @return the destination chunk
|
||||
*/
|
||||
chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr);
|
||||
|
||||
/**
|
||||
* Compare two chunks, returns zero if a equals b
|
||||
|
|
|
@ -11,7 +11,7 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs \
|
||||
-DIPSEC_CONFDIR=\"${sysconfdir}\" \
|
||||
-DPLUGINS="\"x509 pem pkcs1 pubkey openssl nonce tnc-tnccs tnc-imc tnccs-20\""
|
||||
-DPLUGINS="\"x509 pem pkcs1 pubkey openssl wolfssl nonce tnc-tnccs tnc-imc tnccs-20\""
|
||||
|
||||
pt_tls_client_LDADD = \
|
||||
$(top_builddir)/src/libstrongswan/libstrongswan.la \
|
||||
|
|
|
@ -13,7 +13,7 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libimcv \
|
||||
-DPLUGINS=\""random openssl sqlite curl"\"
|
||||
-DPLUGINS=\""random openssl wolfssl sqlite curl"\"
|
||||
|
||||
AM_CFLAGS = $(json_CFLAGS)
|
||||
|
||||
|
|
Loading…
Reference in New Issue