Merge branch 'openssl-25519/448'
Adds support for X25519/448 and Ed25519/448 via OpenSSL 1.1.1.
This commit is contained in:
+4
-13
@@ -38,7 +38,7 @@ env:
|
||||
matrix:
|
||||
include:
|
||||
- env: TEST=sonarcloud
|
||||
if: type = push
|
||||
if: type = push AND env(SONAR_TOKEN) IS present
|
||||
git:
|
||||
depth: false
|
||||
addons:
|
||||
@@ -78,22 +78,13 @@ matrix:
|
||||
- env: TEST=printf-builtin LEAK_DETECTIVE=yes
|
||||
- env: TEST=printf-builtin LEAK_DETECTIVE=yes
|
||||
compiler: clang
|
||||
# the crypto plugins are build-tested with clang via "all" above
|
||||
- env: TEST=botan
|
||||
- env: TEST=botan
|
||||
compiler: clang
|
||||
- env: TEST=botan LEAK_DETECTIVE=yes
|
||||
- env: TEST=botan LEAK_DETECTIVE=yes
|
||||
compiler: clang
|
||||
- env: TEST=openssl
|
||||
- env: TEST=openssl
|
||||
compiler: clang
|
||||
- env: TEST=openssl LEAK_DETECTIVE=yes
|
||||
- env: TEST=openssl LEAK_DETECTIVE=yes
|
||||
compiler: clang
|
||||
- env: TEST=openssl-1.0
|
||||
- env: TEST=openssl-1.0 LEAK_DETECTIVE=yes
|
||||
- env: TEST=gcrypt
|
||||
- env: TEST=gcrypt
|
||||
compiler: clang
|
||||
- env: TEST=gcrypt LEAK_DETECTIVE=yes
|
||||
- env: TEST=gcrypt LEAK_DETECTIVE=yes
|
||||
compiler: clang
|
||||
- env: TEST=apidoc
|
||||
|
||||
@@ -47,6 +47,7 @@ struct {
|
||||
{"ecp192", ECP_192_BIT},
|
||||
{"ecp224", ECP_224_BIT},
|
||||
{"curve25519", CURVE_25519},
|
||||
{"curve448", CURVE_448},
|
||||
};
|
||||
|
||||
static void start_timing(struct timespec *start)
|
||||
|
||||
+48
-3
@@ -11,6 +11,8 @@ build_botan()
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$ build_botan()"
|
||||
|
||||
# if the leak detective is enabled we have to disable threading support
|
||||
# (used for std::async) as that causes invalid frees somehow, the
|
||||
# locking allocator causes a static leak via the first function that
|
||||
@@ -43,7 +45,9 @@ build_tss2()
|
||||
return
|
||||
fi
|
||||
|
||||
# the default version of libgcrypt in Ubuntu 14.04 is too old
|
||||
echo "$ build_tss2()"
|
||||
|
||||
# the default version of libgcrypt in Ubuntu 16.04 is too old
|
||||
sudo apt-get update -qq && \
|
||||
sudo apt-get install -qq libgcrypt20-dev &&
|
||||
curl -L $TSS2_SRC | tar xz -C $TRAVIS_BUILD_DIR/.. &&
|
||||
@@ -55,6 +59,42 @@ build_tss2()
|
||||
cd -
|
||||
}
|
||||
|
||||
build_openssl()
|
||||
{
|
||||
SSL_REV=1.1.1a
|
||||
SSL_PKG=openssl-$SSL_REV
|
||||
SSL_DIR=$TRAVIS_BUILD_DIR/../$SSL_PKG
|
||||
SSL_SRC=https://www.openssl.org/source/$SSL_PKG.tar.gz
|
||||
SSL_INS=/usr/local/ssl
|
||||
SSL_OPT="shared no-tls no-dtls no-ssl3 no-zlib no-comp no-idea no-psk no-srp
|
||||
no-stdio no-tests enable-rfc3779 enable-ec_nistp_64_gcc_128"
|
||||
|
||||
if test -d "$SSL_DIR"; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$ build_openssl()"
|
||||
|
||||
curl -L $SSL_SRC | tar xz -C $TRAVIS_BUILD_DIR/.. &&
|
||||
cd $SSL_DIR &&
|
||||
./config --prefix=$SSL_INS --openssldir=$SSL_INS $SSL_OPT &&
|
||||
make -j4 >/dev/null &&
|
||||
sudo make install_sw >/dev/null &&
|
||||
echo $SSL_INS/lib | sudo tee /etc/ld.so.conf.d/openssl-$SSL_REV.conf >/dev/null &&
|
||||
sudo ldconfig || exit $?
|
||||
cd -
|
||||
}
|
||||
|
||||
use_custom_openssl()
|
||||
{
|
||||
CFLAGS="$CFLAGS -I/usr/local/ssl/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/ssl/lib"
|
||||
export LDFLAGS
|
||||
if test "$1" = "deps"; then
|
||||
build_openssl
|
||||
fi
|
||||
}
|
||||
|
||||
if test -z $TRAVIS_BUILD_DIR; then
|
||||
TRAVIS_BUILD_DIR=$PWD
|
||||
fi
|
||||
@@ -72,9 +112,13 @@ default)
|
||||
# should be the default, but lets make sure
|
||||
CONFIG="--with-printf-hooks=glibc"
|
||||
;;
|
||||
openssl)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-openssl"
|
||||
openssl*)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-openssl --enable-pem"
|
||||
DEPS="libssl-dev"
|
||||
if test "$TEST" != "openssl-1.0"; then
|
||||
DEPS=""
|
||||
use_custom_openssl $1
|
||||
fi
|
||||
;;
|
||||
gcrypt)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-gcrypt --enable-pkcs1"
|
||||
@@ -119,6 +163,7 @@ all|coverage|sonarcloud)
|
||||
build_botan
|
||||
build_tss2
|
||||
fi
|
||||
use_custom_openssl $1
|
||||
;;
|
||||
win*)
|
||||
CONFIG="--disable-defaults --enable-svc --enable-ikev2
|
||||
|
||||
@@ -49,6 +49,13 @@ METHOD(public_key_t, get_type, key_type_t,
|
||||
return KEY_ED25519;
|
||||
}
|
||||
|
||||
/* L = 2^252+27742317777372353535851937790883648493 in little-endian form */
|
||||
static chunk_t curve25519_order = chunk_from_chars(
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
|
||||
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10);
|
||||
|
||||
METHOD(public_key_t, verify, bool,
|
||||
private_curve25519_public_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t signature)
|
||||
@@ -94,6 +101,20 @@ METHOD(public_key_t, verify, bool,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* make sure 0 <= s < L, as per RFC 8032, section 5.1.7 to prevent signature
|
||||
* malleability. Due to the three-bit check above (forces s < 2^253) there
|
||||
* is not that much room, but adding L once works with most signatures */
|
||||
for (i = 31; ; i--)
|
||||
{
|
||||
if (sig[i+32] < curve25519_order.ptr[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (sig[i+32] > curve25519_order.ptr[i] || i == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
|
||||
if (!hasher)
|
||||
|
||||
@@ -29,7 +29,10 @@ libstrongswan_openssl_la_SOURCES = \
|
||||
openssl_pkcs12.c openssl_pkcs12.h \
|
||||
openssl_rng.c openssl_rng.h \
|
||||
openssl_hmac.c openssl_hmac.h \
|
||||
openssl_gcm.c openssl_gcm.h
|
||||
openssl_gcm.c openssl_gcm.h \
|
||||
openssl_x_diffie_hellman.c openssl_x_diffie_hellman.h \
|
||||
openssl_ed_private_key.c openssl_ed_private_key.h \
|
||||
openssl_ed_public_key.c openssl_ed_public_key.h
|
||||
|
||||
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
|
||||
libstrongswan_openssl_la_LIBADD = $(OPENSSL_LIB)
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
|
||||
|
||||
#include "openssl_ed_private_key.h"
|
||||
|
||||
#include <utils/debug.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
|
||||
*/
|
||||
EVP_PKEY *key;
|
||||
|
||||
/**
|
||||
* Key type
|
||||
*/
|
||||
key_type_t type;
|
||||
|
||||
/**
|
||||
* TRUE if the key is from an OpenSSL ENGINE and might not be readable
|
||||
*/
|
||||
bool engine;
|
||||
|
||||
/**
|
||||
* reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* We can't include asn1.h, declare function prototype directly
|
||||
*/
|
||||
int asn1_unwrap(chunk_t*, chunk_t*);
|
||||
|
||||
/* from ed public key */
|
||||
int openssl_ed_key_type(key_type_t type);
|
||||
int openssl_ed_keysize(key_type_t type);
|
||||
bool openssl_ed_fingerprint(EVP_PKEY *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)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
bool success = FALSE;
|
||||
|
||||
if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) ||
|
||||
(this->type == KEY_ED448 && scheme != SIGN_ED448))
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
|
||||
signature_scheme_names, scheme, key_type_names, this->type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (!ctx ||
|
||||
EVP_DigestSignInit(ctx, NULL, NULL, NULL, this->key) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (EVP_DigestSign(ctx, NULL, &signature->len, data.ptr, data.len) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
*signature = chunk_alloc(signature->len);
|
||||
|
||||
if (EVP_DigestSign(ctx, signature->ptr, &signature->len,
|
||||
data.ptr, data.len) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return success;
|
||||
}
|
||||
|
||||
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 openssl_ed_keysize(this->type);
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_type, key_type_t,
|
||||
private_private_key_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(private_key_t, get_public_key, public_key_t*,
|
||||
private_private_key_t *this)
|
||||
{
|
||||
public_key_t *public;
|
||||
chunk_t key;
|
||||
|
||||
if (!EVP_PKEY_get_raw_public_key(this->key, NULL, &key.len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
key = chunk_alloca(key.len);
|
||||
if (!EVP_PKEY_get_raw_public_key(this->key, key.ptr, &key.len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type,
|
||||
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 openssl_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)
|
||||
{
|
||||
u_char *p;
|
||||
|
||||
if (this->engine)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PRIVKEY_ASN1_DER:
|
||||
case PRIVKEY_PEM:
|
||||
{
|
||||
bool success = TRUE;
|
||||
|
||||
*encoding = chunk_alloc(i2d_PrivateKey(this->key, NULL));
|
||||
p = encoding->ptr;
|
||||
i2d_PrivateKey(this->key, &p);
|
||||
|
||||
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);
|
||||
EVP_PKEY_free(this->key);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal generic constructor
|
||||
*/
|
||||
static private_private_key_t *create_internal(key_type_t type, EVP_PKEY *key)
|
||||
{
|
||||
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,
|
||||
},
|
||||
.type = type,
|
||||
.key = key,
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_create(EVP_PKEY *key, bool engine)
|
||||
{
|
||||
private_private_key_t *this;
|
||||
key_type_t type;
|
||||
|
||||
switch (EVP_PKEY_base_id(key))
|
||||
{
|
||||
case EVP_PKEY_X25519:
|
||||
type = KEY_ED25519;
|
||||
break;
|
||||
case EVP_PKEY_X448:
|
||||
type = KEY_ED448;
|
||||
break;
|
||||
default:
|
||||
EVP_PKEY_free(key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = create_internal(type, key);
|
||||
this->engine = engine;
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_gen(key_type_t type, va_list args)
|
||||
{
|
||||
private_private_key_t *this;
|
||||
EVP_PKEY_CTX *ctx;
|
||||
EVP_PKEY *key = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ctx = EVP_PKEY_CTX_new_id(openssl_ed_key_type(type), NULL);
|
||||
if (!ctx ||
|
||||
EVP_PKEY_keygen_init(ctx) <= 0 ||
|
||||
EVP_PKEY_keygen(ctx, &key) <= 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "generating %N key failed", key_type_names, type);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
|
||||
this = create_internal(type, key);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_load(key_type_t type, va_list args)
|
||||
{
|
||||
private_private_key_t *this;
|
||||
chunk_t blob = chunk_empty, priv = chunk_empty;
|
||||
EVP_PKEY *key = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (priv.len)
|
||||
{
|
||||
/* unwrap octet string */
|
||||
if (asn1_unwrap(&priv, &priv) == 0x04 && priv.len)
|
||||
{
|
||||
key = EVP_PKEY_new_raw_private_key(openssl_ed_key_type(type), NULL,
|
||||
priv.ptr, priv.len);
|
||||
}
|
||||
}
|
||||
else if (blob.len)
|
||||
{
|
||||
key = d2i_PrivateKey(openssl_ed_key_type(type), NULL,
|
||||
(const u_char**)&blob.ptr, blob.len);
|
||||
}
|
||||
if (!key)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this = create_internal(type, key);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_NO_ECDSA */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup openssl_ed_private_key openssl_ed_private_key
|
||||
* @{ @ingroup openssl_p
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_ED_PRIVATE_KEY_H_
|
||||
#define OPENSSL_ED_PRIVATE_KEY_H_
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
|
||||
/**
|
||||
* Generate an EdDSA private key using OpenSSL.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ED25519 or KEY_ED448
|
||||
* @param args builder_part_t argument list
|
||||
* @return generated key, NULL on failure
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_gen(key_type_t type, va_list args);
|
||||
|
||||
/**
|
||||
* Load an EdDSA private key using OpenSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ED25519 or KEY_ED448
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_load(key_type_t type, va_list args);
|
||||
|
||||
/**
|
||||
* Wrap an EVP_PKEY object of type EVP_PKEY_ED25519/448
|
||||
*
|
||||
* @param key EVP_PKEY object (adopted)
|
||||
* @param engine whether the key was loaded via an engine
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
private_key_t *openssl_ed_private_key_create(EVP_PKEY *key, bool engine);
|
||||
|
||||
#endif /** OPENSSL_ED_PRIVATE_KEY_H_ @}*/
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
|
||||
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "openssl_ed_public_key.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_public_key_t private_public_key_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_public_key_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
public_key_t public;
|
||||
|
||||
/**
|
||||
* Key object
|
||||
*/
|
||||
EVP_PKEY *key;
|
||||
|
||||
/**
|
||||
* Key type
|
||||
*/
|
||||
key_type_t type;
|
||||
|
||||
/**
|
||||
* Reference counter
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* Map a key type to an EVP key type
|
||||
*/
|
||||
int openssl_ed_key_type(key_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KEY_ED25519:
|
||||
return EVP_PKEY_ED25519;
|
||||
case KEY_ED448:
|
||||
return EVP_PKEY_ED448;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a key type to a key size
|
||||
*/
|
||||
int openssl_ed_keysize(key_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case KEY_ED25519:
|
||||
return 32 * 8;
|
||||
case KEY_ED448:
|
||||
return 57 * 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_type, key_type_t,
|
||||
private_public_key_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, verify, bool,
|
||||
private_public_key_t *this, signature_scheme_t scheme,
|
||||
void *params, chunk_t data, chunk_t signature)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
|
||||
if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) ||
|
||||
(this->type == KEY_ED448 && scheme != SIGN_ED448))
|
||||
{
|
||||
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
|
||||
signature_scheme_names, scheme, key_type_names, this->type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (!ctx ||
|
||||
EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, this->key) <= 0 ||
|
||||
EVP_DigestVerify(ctx, signature.ptr, signature.len,
|
||||
data.ptr, data.len) <= 0)
|
||||
{
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return FALSE;
|
||||
}
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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 openssl_ed_keysize(this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate fingerprint from an EdDSA key, also used in ed private key.
|
||||
*/
|
||||
bool openssl_ed_fingerprint(EVP_PKEY *key, cred_encoding_type_t type,
|
||||
chunk_t *fp)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t blob;
|
||||
u_char *p;
|
||||
|
||||
if (lib->encoding->get_cache(lib->encoding, type, key, fp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case KEYID_PUBKEY_SHA1:
|
||||
if (!EVP_PKEY_get_raw_public_key(key, NULL, &blob.len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
blob = chunk_alloca(blob.len);
|
||||
if (!EVP_PKEY_get_raw_public_key(key, blob.ptr, &blob.len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case KEYID_PUBKEY_INFO_SHA1:
|
||||
blob = chunk_alloca(i2d_PUBKEY(key, NULL));
|
||||
p = blob.ptr;
|
||||
i2d_PUBKEY(key, &p);
|
||||
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");
|
||||
DESTROY_IF(hasher);
|
||||
return FALSE;
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
lib->encoding->cache(lib->encoding, type, key, *fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(public_key_t, get_fingerprint, bool,
|
||||
private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint)
|
||||
{
|
||||
return openssl_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;
|
||||
u_char *p;
|
||||
|
||||
*encoding = chunk_alloc(i2d_PUBKEY(this->key, NULL));
|
||||
p = encoding->ptr;
|
||||
i2d_PUBKEY(this->key, &p);
|
||||
|
||||
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_clear(&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);
|
||||
EVP_PKEY_free(this->key);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic private constructor
|
||||
*/
|
||||
static private_public_key_t *create_empty(key_type_t type)
|
||||
{
|
||||
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,
|
||||
},
|
||||
.type = type,
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
public_key_t *openssl_ed_public_key_load(key_type_t type, va_list args)
|
||||
{
|
||||
private_public_key_t *this;
|
||||
chunk_t blob = chunk_empty, pub = chunk_empty;
|
||||
EVP_PKEY *key = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (pub.len)
|
||||
{
|
||||
key = EVP_PKEY_new_raw_public_key(openssl_ed_key_type(type), NULL,
|
||||
pub.ptr, pub.len);
|
||||
}
|
||||
else if (blob.len)
|
||||
{
|
||||
key = d2i_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len);
|
||||
if (key && EVP_PKEY_base_id(key) != openssl_ed_key_type(type))
|
||||
{
|
||||
EVP_PKEY_free(key);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!key)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this = create_empty(type);
|
||||
this->key = key;
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup openssl_ed_public_key openssl_ed_public_key
|
||||
* @{ @ingroup openssl_p
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_ED_PUBLIC_KEY_H_
|
||||
#define OPENSSL_ED_PUBLIC_KEY_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* Load an EdDSA public key using OpenSSL.
|
||||
*
|
||||
* Accepts a BUILD_BLOB_ASN1_DER argument.
|
||||
*
|
||||
* @param type type of the key, must be KEY_ED25519 or KEY_ED448
|
||||
* @param args builder_part_t argument list
|
||||
* @return loaded key, NULL on failure
|
||||
*/
|
||||
public_key_t *openssl_ed_public_key_load(key_type_t type, va_list args);
|
||||
|
||||
#endif /** OPENSSL_ED_PUBLIC_KEY_H_ @}*/
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 Tobias Brunner
|
||||
* Copyright (C) 2008-2018 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -47,6 +47,9 @@
|
||||
#include "openssl_rng.h"
|
||||
#include "openssl_hmac.h"
|
||||
#include "openssl_gcm.h"
|
||||
#include "openssl_x_diffie_hellman.h"
|
||||
#include "openssl_ed_public_key.h"
|
||||
#include "openssl_ed_private_key.h"
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
#define FIPS_MODE 0
|
||||
@@ -307,6 +310,11 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
|
||||
case EVP_PKEY_EC:
|
||||
return openssl_ec_private_key_create(key, FALSE);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
|
||||
case EVP_PKEY_ED25519:
|
||||
case EVP_PKEY_ED448:
|
||||
return openssl_ed_private_key_create(key, FALSE);
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
default:
|
||||
EVP_PKEY_free(key);
|
||||
break;
|
||||
@@ -454,6 +462,11 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
|
||||
case EVP_PKEY_EC:
|
||||
return openssl_ec_private_key_create(key, TRUE);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
|
||||
case EVP_PKEY_ED25519:
|
||||
case EVP_PKEY_ED448:
|
||||
return openssl_ed_private_key_create(key, TRUE);
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
default:
|
||||
EVP_PKEY_free(key);
|
||||
break;
|
||||
@@ -594,7 +607,7 @@ METHOD(plugin_t, get_features, int,
|
||||
PLUGIN_PROVIDE(DH, ECP_384_BP),
|
||||
PLUGIN_PROVIDE(DH, ECP_512_BP),
|
||||
PLUGIN_PROVIDE(DH, ECP_224_BP),
|
||||
#endif
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
#ifndef OPENSSL_NO_DH
|
||||
/* MODP DH groups */
|
||||
PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
|
||||
@@ -699,6 +712,30 @@ METHOD(plugin_t, get_features, int,
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
|
||||
#endif
|
||||
#endif /* OPENSSL_NO_ECDSA */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
|
||||
PLUGIN_REGISTER(DH, openssl_x_diffie_hellman_create),
|
||||
/* available since 1.1.0a, but we require 1.1.1 features */
|
||||
PLUGIN_PROVIDE(DH, CURVE_25519),
|
||||
/* available since 1.1.1 */
|
||||
PLUGIN_PROVIDE(DH, CURVE_448),
|
||||
/* EdDSA private/public key loading */
|
||||
PLUGIN_REGISTER(PUBKEY, openssl_ed_public_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
|
||||
PLUGIN_PROVIDE(PUBKEY, KEY_ED448),
|
||||
PLUGIN_REGISTER(PRIVKEY, openssl_ed_private_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ED448),
|
||||
PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ed_private_key_gen, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
|
||||
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED448),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED448),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED448),
|
||||
/* register a pro forma identity hasher, never instantiated */
|
||||
PLUGIN_REGISTER(HASHER, return_null),
|
||||
PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
|
||||
#endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC */
|
||||
/* generic key loader */
|
||||
PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2012 Aleksandr Grinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,7 +27,6 @@
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "openssl_rng.h"
|
||||
|
||||
@@ -49,6 +51,13 @@ struct private_openssl_rng_t {
|
||||
METHOD(rng_t, get_bytes, bool,
|
||||
private_openssl_rng_t *this, size_t bytes, uint8_t *buffer)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
|
||||
if (this->quality > RNG_WEAK)
|
||||
{ /* use a separate DRBG for data we wan't to keep private, compared
|
||||
* to e.g. nonces */
|
||||
return RAND_priv_bytes((char*)buffer, bytes) == 1;
|
||||
}
|
||||
#endif
|
||||
return RAND_bytes((char*)buffer, bytes) == 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
/* basic support for X25519 was added with 1.1.0a, but we require features (e.g.
|
||||
* to load the keys) that were only added with 1.1.1 */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_ECDH)
|
||||
|
||||
#include "openssl_x_diffie_hellman.h"
|
||||
|
||||
#include <utils/debug.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
|
||||
*/
|
||||
EVP_PKEY *key;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
chunk_t shared_secret;
|
||||
|
||||
/**
|
||||
* True if shared secret is computed
|
||||
*/
|
||||
bool computed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Map a DH group to a key type
|
||||
*/
|
||||
static int map_key_type(diffie_hellman_group_t group)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case CURVE_25519:
|
||||
return EVP_PKEY_X25519;
|
||||
case CURVE_448:
|
||||
return EVP_PKEY_X448;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the shared secret
|
||||
*/
|
||||
static bool compute_shared_key(private_diffie_hellman_t *this, EVP_PKEY *pub,
|
||||
chunk_t *shared_secret)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx;
|
||||
bool success = FALSE;
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(this->key, NULL);
|
||||
if (!ctx)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_derive_init(ctx) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_derive(ctx, NULL, &shared_secret->len) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
*shared_secret = chunk_alloc(shared_secret->len);
|
||||
|
||||
if (EVP_PKEY_derive(ctx, shared_secret->ptr, &shared_secret->len) <= 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
EVP_PKEY *pub;
|
||||
|
||||
if (!diffie_hellman_verify_value(this->group, value))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pub = EVP_PKEY_new_raw_public_key(map_key_type(this->group), NULL,
|
||||
value.ptr, value.len);
|
||||
if (!pub)
|
||||
{
|
||||
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);
|
||||
EVP_PKEY_free(pub);
|
||||
return FALSE;
|
||||
}
|
||||
this->computed = TRUE;
|
||||
EVP_PKEY_free(pub);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_my_public_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *value)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (!EVP_PKEY_get_raw_public_key(this->key, NULL, &len))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*value = chunk_alloc(len);
|
||||
|
||||
if (!EVP_PKEY_get_raw_public_key(this->key, value->ptr, &value->len))
|
||||
{
|
||||
chunk_free(value);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, set_private_value, bool,
|
||||
private_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
EVP_PKEY_free(this->key);
|
||||
this->key = EVP_PKEY_new_raw_private_key(map_key_type(this->group), NULL,
|
||||
value.ptr, value.len);
|
||||
if (!this->key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_shared_secret, bool,
|
||||
private_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->computed)
|
||||
{
|
||||
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)
|
||||
{
|
||||
EVP_PKEY_free(this->key);
|
||||
chunk_clear(&this->shared_secret);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group)
|
||||
{
|
||||
private_diffie_hellman_t *this;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
EVP_PKEY *key = NULL;
|
||||
|
||||
switch (group)
|
||||
{
|
||||
case CURVE_25519:
|
||||
ctx = EVP_PKEY_CTX_new_id(NID_X25519, NULL);
|
||||
break;
|
||||
case CURVE_448:
|
||||
ctx = EVP_PKEY_CTX_new_id(NID_X448, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx ||
|
||||
EVP_PKEY_keygen_init(ctx) <= 0 ||
|
||||
EVP_PKEY_keygen(ctx, &key) <= 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "generating key for %N failed",
|
||||
diffie_hellman_group_names, group);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
|
||||
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,
|
||||
.key = key,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of the X25519/X448 Diffie-Hellman algorithm using OpenSSL.
|
||||
*
|
||||
* @defgroup openssl_x_diffie_hellman openssl_x_diffie_hellman
|
||||
* @{ @ingroup openssl_p
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_X_DIFFIE_HELLMAN_H_
|
||||
#define OPENSSL_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 *openssl_x_diffie_hellman_create(diffie_hellman_group_t group);
|
||||
|
||||
#endif /** OPENSSL_X_DIFFIE_HELLMAN_H_ @}*/
|
||||
|
||||
@@ -49,6 +49,7 @@ libstrongswan_test_vectors_la_SOURCES = \
|
||||
test_vectors/ecp.c \
|
||||
test_vectors/ecpbp.c \
|
||||
test_vectors/curve25519.c \
|
||||
test_vectors/curve448.c \
|
||||
test_vectors/rng.c
|
||||
|
||||
libstrongswan_test_vectors_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
@@ -306,3 +306,4 @@ TEST_VECTOR_DH(ecp384bp)
|
||||
TEST_VECTOR_DH(ecp512bp)
|
||||
TEST_VECTOR_DH(curve25519_1)
|
||||
TEST_VECTOR_DH(curve25519_2)
|
||||
TEST_VECTOR_DH(curve448_1)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <crypto/crypto_tester.h>
|
||||
|
||||
/**
|
||||
* From RFC 8037
|
||||
* From RFC 7748
|
||||
*/
|
||||
dh_test_vector_t curve25519_1 = {
|
||||
.group = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the Licenseor (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be usefulbut
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <crypto/crypto_tester.h>
|
||||
|
||||
/**
|
||||
* From RFC 7748
|
||||
*/
|
||||
dh_test_vector_t curve448_1 = {
|
||||
.group = CURVE_448, .priv_len = 56, .pub_len = 56, .shared_len = 56,
|
||||
.priv_a = "\x9a\x8f\x49\x25\xd1\x51\x9f\x57\x75\xcf\x46\xb0\x4b\x58\x00\xd4"
|
||||
"\xee\x9e\xe8\xba\xe8\xbc\x55\x65\xd4\x98\xc2\x8d\xd9\xc9\xba\xf5"
|
||||
"\x74\xa9\x41\x97\x44\x89\x73\x91\x00\x63\x82\xa6\xf1\x27\xab\x1d"
|
||||
"\x9a\xc2\xd8\xc0\xa5\x98\x72\x6b",
|
||||
.priv_b = "\x1c\x30\x6a\x7a\xc2\xa0\xe2\xe0\x99\x0b\x29\x44\x70\xcb\xa3\x39"
|
||||
"\xe6\x45\x37\x72\xb0\x75\x81\x1d\x8f\xad\x0d\x1d\x69\x27\xc1\x20"
|
||||
"\xbb\x5e\xe8\x97\x2b\x0d\x3e\x21\x37\x4c\x9c\x92\x1b\x09\xd1\xb0"
|
||||
"\x36\x6f\x10\xb6\x51\x73\x99\x2d",
|
||||
.pub_a = "\x9b\x08\xf7\xcc\x31\xb7\xe3\xe6\x7d\x22\xd5\xae\xa1\x21\x07\x4a"
|
||||
"\x27\x3b\xd2\xb8\x3d\xe0\x9c\x63\xfa\xa7\x3d\x2c\x22\xc5\xd9\xbb"
|
||||
"\xc8\x36\x64\x72\x41\xd9\x53\xd4\x0c\x5b\x12\xda\x88\x12\x0d\x53"
|
||||
"\x17\x7f\x80\xe5\x32\xc4\x1f\xa0",
|
||||
.pub_b = "\x3e\xb7\xa8\x29\xb0\xcd\x20\xf5\xbc\xfc\x0b\x59\x9b\x6f\xec\xcf"
|
||||
"\x6d\xa4\x62\x71\x07\xbd\xb0\xd4\xf3\x45\xb4\x30\x27\xd8\xb9\x72"
|
||||
"\xfc\x3e\x34\xfb\x42\x32\xa1\x3c\xa7\x06\xdc\xb5\x7a\xec\x3d\xae"
|
||||
"\x07\xbd\xc1\xc6\x7b\xf3\x36\x09",
|
||||
.shared = "\x07\xff\xf4\x18\x1a\xc6\xcc\x95\xec\x1c\x16\xa9\x4a\x0f\x74\xd1"
|
||||
"\x2d\xa2\x32\xce\x40\xa7\x75\x52\x28\x1d\x28\x2b\xb6\x0c\x0b\x56"
|
||||
"\xfd\x24\x64\xc3\x35\x54\x39\x36\x52\x1c\x24\x40\x30\x85\xd5\x9a"
|
||||
"\x44\x9a\x50\x37\x51\x4a\x87\x9d",
|
||||
};
|
||||
@@ -58,6 +58,7 @@ libstrongswan_tests_SOURCES = tests.h tests.c \
|
||||
suites/test_mgf1.c \
|
||||
suites/test_ntru.c \
|
||||
suites/test_ed25519.c \
|
||||
suites/test_ed448.c \
|
||||
suites/test_signature_params.c
|
||||
|
||||
libstrongswan_tests_CFLAGS = \
|
||||
|
||||
@@ -24,10 +24,12 @@ struct sig_test_t {
|
||||
chunk_t pubkey;
|
||||
chunk_t msg;
|
||||
chunk_t sig;
|
||||
chunk_t fp_pk;
|
||||
chunk_t fp_spki;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ed25519 Test Vectors from draft-irtf-cfrg-eddsa
|
||||
* Ed25519 Test Vectors from RFC 8032
|
||||
*/
|
||||
static sig_test_t sig_tests[] = {
|
||||
/* Test 1 */
|
||||
@@ -51,7 +53,13 @@ static sig_test_t sig_tests[] = {
|
||||
0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
|
||||
0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b,
|
||||
0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43,
|
||||
0x8e, 0x7a, 0x10, 0x0b)
|
||||
0x8e, 0x7a, 0x10, 0x0b),
|
||||
chunk_from_chars(
|
||||
0x5b, 0x27, 0xaa, 0x55, 0x89, 0x17, 0x97, 0x70, 0xe4, 0x75,
|
||||
0x75, 0xb1, 0x62, 0xa1, 0xde, 0xd9, 0x7b, 0x8b, 0xfc, 0x6d),
|
||||
chunk_from_chars(
|
||||
0xa5, 0x66, 0xbe, 0x19, 0x84, 0x01, 0x73, 0x41, 0x3a, 0x61,
|
||||
0x04, 0x83, 0x50, 0xef, 0xf2, 0x3e, 0x8f, 0xe2, 0x22, 0x66),
|
||||
},
|
||||
/* Test 2 */
|
||||
{ chunk_from_chars(
|
||||
@@ -75,7 +83,13 @@ static sig_test_t sig_tests[] = {
|
||||
0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
|
||||
0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 0x38, 0x7b,
|
||||
0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 0xb0, 0x0d, 0x29, 0x16,
|
||||
0x12, 0xbb, 0x0c, 0x00)
|
||||
0x12, 0xbb, 0x0c, 0x00),
|
||||
chunk_from_chars(
|
||||
0x13, 0xf7, 0x72, 0x66, 0x9e, 0x15, 0x2a, 0xe6, 0xa6, 0x2a,
|
||||
0x60, 0xa3, 0x48, 0x8a, 0x6f, 0x29, 0x7d, 0x06, 0x13, 0xdd),
|
||||
chunk_from_chars(
|
||||
0xbd, 0xae, 0x41, 0xeb, 0x5d, 0xbf, 0x88, 0xb9, 0xdf, 0x18,
|
||||
0xda, 0xbb, 0x2d, 0xee, 0xa9, 0x1a, 0x4e, 0x03, 0x38, 0xe4),
|
||||
},
|
||||
/* Test 3 */
|
||||
{ chunk_from_chars(
|
||||
@@ -99,7 +113,13 @@ static sig_test_t sig_tests[] = {
|
||||
0xc3, 0xac, 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90,
|
||||
0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59, 0x4a, 0x7c,
|
||||
0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d, 0xc0, 0x27, 0xbe, 0xce,
|
||||
0xea, 0x1e, 0xc4, 0x0a)
|
||||
0xea, 0x1e, 0xc4, 0x0a),
|
||||
chunk_from_chars(
|
||||
0x88, 0xc7, 0x64, 0xc8, 0xbe, 0x44, 0x37, 0x4a, 0x7d, 0x2f,
|
||||
0x5d, 0x84, 0x72, 0x1f, 0x8e, 0x32, 0x5e, 0x5b, 0xd6, 0x4c),
|
||||
chunk_from_chars(
|
||||
0xad, 0x01, 0x30, 0xb1, 0x2b, 0x48, 0x62, 0x9b, 0xb9, 0xad,
|
||||
0xea, 0x92, 0x1f, 0xfe, 0xd2, 0x9a, 0x42, 0xf0, 0xad, 0xe6),
|
||||
},
|
||||
/* Test 1024 */
|
||||
{ chunk_from_chars(
|
||||
@@ -235,7 +255,13 @@ static sig_test_t sig_tests[] = {
|
||||
0xc3, 0x50, 0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
|
||||
0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b, 0x5e, 0x8f,
|
||||
0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6, 0xac, 0x00, 0xa9, 0x70,
|
||||
0x4a, 0x18, 0x8a, 0x03)
|
||||
0x4a, 0x18, 0x8a, 0x03),
|
||||
chunk_from_chars(
|
||||
0x11, 0x2d, 0xb3, 0x08, 0x97, 0x6e, 0x38, 0x8f, 0x5f, 0x5e,
|
||||
0xb0, 0xae, 0x8f, 0x5f, 0x59, 0x1d, 0xff, 0x74, 0xf4, 0x44),
|
||||
chunk_from_chars(
|
||||
0xcb, 0x36, 0xcc, 0x6a, 0x82, 0x2c, 0x49, 0x40, 0xfb, 0x08,
|
||||
0x04, 0xf6, 0x3a, 0x4f, 0x20, 0x2b, 0xe5, 0x73, 0x43, 0x2f),
|
||||
},
|
||||
/* Test SHA(abc) */
|
||||
{ chunk_from_chars(
|
||||
@@ -265,7 +291,13 @@ static sig_test_t sig_tests[] = {
|
||||
0xb5, 0x89, 0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec,
|
||||
0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30, 0x3d, 0xca,
|
||||
0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a, 0xd9, 0xbe, 0xf1, 0x17,
|
||||
0x73, 0x31, 0xa7, 0x04)
|
||||
0x73, 0x31, 0xa7, 0x04),
|
||||
chunk_from_chars(
|
||||
0x26, 0x4c, 0xa5, 0x7f, 0x89, 0x6d, 0x64, 0x81, 0xd1, 0x87,
|
||||
0xe9, 0x89, 0x47, 0x29, 0x5a, 0xfe, 0xe3, 0x6d, 0x82, 0x44),
|
||||
chunk_from_chars(
|
||||
0x27, 0x88, 0xfc, 0x14, 0xb1, 0xcd, 0xd0, 0x24, 0xd5, 0x9d,
|
||||
0x31, 0x65, 0x59, 0x63, 0x69, 0xcf, 0xaf, 0x50, 0x10, 0xe7),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -273,24 +305,34 @@ START_TEST(test_ed25519_sign)
|
||||
{
|
||||
private_key_t *key;
|
||||
public_key_t *pubkey, *public;
|
||||
chunk_t sig, encoding;
|
||||
chunk_t sig, encoding, fp;
|
||||
|
||||
/* load private key */
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED25519,
|
||||
BUILD_BLOB_ASN1_DER, sig_tests[_i].key, BUILD_END);
|
||||
ck_assert(key != NULL);
|
||||
ck_assert(key->get_encoding(key, PRIVKEY_ASN1_DER, &encoding));
|
||||
ck_assert(chunk_equals(encoding, sig_tests[_i].key));
|
||||
ck_assert_chunk_eq(encoding, sig_tests[_i].key);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
|
||||
|
||||
/* load public key */
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
|
||||
BUILD_BLOB_ASN1_DER, sig_tests[_i].pubkey, BUILD_END);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
|
||||
ck_assert(chunk_equals(encoding, sig_tests[_i].pubkey));
|
||||
ck_assert_chunk_eq(encoding, sig_tests[_i].pubkey);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
|
||||
|
||||
/* compare public keys */
|
||||
public = key->get_public_key(key);
|
||||
ck_assert(public != NULL);
|
||||
@@ -299,7 +341,7 @@ START_TEST(test_ed25519_sign)
|
||||
/* sign */
|
||||
ck_assert(key->sign(key, SIGN_ED25519, NULL, sig_tests[_i].msg, &sig));
|
||||
ck_assert(sig.len == 64);
|
||||
ck_assert(chunk_equals(sig, sig_tests[_i].sig));
|
||||
ck_assert_chunk_eq(sig, sig_tests[_i].sig);
|
||||
|
||||
/* verify */
|
||||
ck_assert(pubkey->verify(pubkey, SIGN_ED25519, NULL, sig_tests[_i].msg,
|
||||
@@ -364,7 +406,7 @@ START_TEST(test_ed25519_gen)
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
|
||||
ck_assert(fp_pub.ptr != NULL);
|
||||
ck_assert(chunk_equals(fp_pub, fp_priv));
|
||||
ck_assert_chunk_eq(fp_pub, fp_priv);
|
||||
|
||||
/* clone public key */
|
||||
pubkey2 = pubkey->get_ref(pubkey);
|
||||
@@ -429,6 +471,16 @@ static chunk_t zero_pk = chunk_from_chars(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
/* sig_tests[0].sig with s+L */
|
||||
static chunk_t malleable_sig = chunk_from_chars(
|
||||
0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86,
|
||||
0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e,
|
||||
0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49,
|
||||
0x01, 0x55, 0x4c, 0x8c, 0x78, 0x72, 0xaa, 0x06, 0x4e, 0x04,
|
||||
0x9d, 0xbb, 0x30, 0x13, 0xfb, 0xf2, 0x93, 0x80, 0xd2, 0x5b,
|
||||
0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43,
|
||||
0x8e, 0x7a, 0x10, 0x1b);
|
||||
|
||||
START_TEST(test_ed25519_fail)
|
||||
{
|
||||
private_key_t *key;
|
||||
@@ -479,6 +531,16 @@ START_TEST(test_ed25519_fail)
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED25519, NULL, chunk_empty,
|
||||
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. */
|
||||
if (pubkey->verify(pubkey, SIGN_ED25519, NULL, sig_tests[0].msg,
|
||||
malleable_sig))
|
||||
{
|
||||
warn("Ed25519 signature verification is vulnerable to malleable "
|
||||
"signatures");
|
||||
}
|
||||
|
||||
/* malformed signature */
|
||||
sig = chunk_create(sig1, 64);
|
||||
memcpy(sig1, sig_tests[0].sig.ptr, 64);
|
||||
|
||||
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Tobias Brunner
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct sig_test_t sig_test_t;
|
||||
|
||||
struct sig_test_t {
|
||||
chunk_t key;
|
||||
chunk_t pubkey;
|
||||
chunk_t msg;
|
||||
chunk_t sig;
|
||||
chunk_t fp_pk;
|
||||
chunk_t fp_spki;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ed448 Test Vectors from RFC 8032
|
||||
*/
|
||||
static sig_test_t sig_tests[] = {
|
||||
/* Blank */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0x6c,0x82,0xa5,0x62,0xcb,0x80,0x8d,0x10,0xd6,0x32,0xbe,0x89,0xc8,0x51,0x3e,0xbf,
|
||||
0x6c,0x92,0x9f,0x34,0xdd,0xfa,0x8c,0x9f,0x63,0xc9,0x96,0x0e,0xf6,0xe3,0x48,0xa3,
|
||||
0x52,0x8c,0x8a,0x3f,0xcc,0x2f,0x04,0x4e,0x39,0xa3,0xfc,0x5b,0x94,0x49,0x2f,0x8f,
|
||||
0x03,0x2e,0x75,0x49,0xa2,0x00,0x98,0xf9,0x5b),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x5f,0xd7,0x44,0x9b,
|
||||
0x59,0xb4,0x61,0xfd,0x2c,0xe7,0x87,0xec,0x61,0x6a,0xd4,0x6a,0x1d,0xa1,0x34,0x24,
|
||||
0x85,0xa7,0x0e,0x1f,0x8a,0x0e,0xa7,0x5d,0x80,0xe9,0x67,0x78,0xed,0xf1,0x24,0x76,
|
||||
0x9b,0x46,0xc7,0x06,0x1b,0xd6,0x78,0x3d,0xf1,0xe5,0x0f,0x6c,0xd1,0xfa,0x1a,0xbe,
|
||||
0xaf,0xe8,0x25,0x61,0x80),
|
||||
{ NULL, 0 },
|
||||
chunk_from_chars(
|
||||
0x53,0x3a,0x37,0xf6,0xbb,0xe4,0x57,0x25,0x1f,0x02,0x3c,0x0d,0x88,0xf9,0x76,0xae,
|
||||
0x2d,0xfb,0x50,0x4a,0x84,0x3e,0x34,0xd2,0x07,0x4f,0xd8,0x23,0xd4,0x1a,0x59,0x1f,
|
||||
0x2b,0x23,0x3f,0x03,0x4f,0x62,0x82,0x81,0xf2,0xfd,0x7a,0x22,0xdd,0xd4,0x7d,0x78,
|
||||
0x28,0xc5,0x9b,0xd0,0xa2,0x1b,0xfd,0x39,0x80,0xff,0x0d,0x20,0x28,0xd4,0xb1,0x8a,
|
||||
0x9d,0xf6,0x3e,0x00,0x6c,0x5d,0x1c,0x2d,0x34,0x5b,0x92,0x5d,0x8d,0xc0,0x0b,0x41,
|
||||
0x04,0x85,0x2d,0xb9,0x9a,0xc5,0xc7,0xcd,0xda,0x85,0x30,0xa1,0x13,0xa0,0xf4,0xdb,
|
||||
0xb6,0x11,0x49,0xf0,0x5a,0x73,0x63,0x26,0x8c,0x71,0xd9,0x58,0x08,0xff,0x2e,0x65,
|
||||
0x26,0x00),
|
||||
chunk_from_chars(
|
||||
0x6d,0xe0,0x8a,0x72,0x35,0x1e,0xf1,0xad,0xeb,0xca,0x2c,0xd7,0xf1,0xfd,0xa6,0x91,
|
||||
0x54,0xad,0xfa,0x4f),
|
||||
chunk_from_chars(
|
||||
0x1b,0x7a,0x47,0x56,0x91,0xb8,0x41,0x33,0x0d,0x2e,0x4d,0xa5,0xe6,0x13,0xb9,0x89,
|
||||
0xda,0xce,0xc5,0x8e),
|
||||
},
|
||||
/* 1 octet */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0xc4,0xea,0xb0,0x5d,0x35,0x70,0x07,0xc6,0x32,0xf3,0xdb,0xb4,0x84,0x89,0x92,0x4d,
|
||||
0x55,0x2b,0x08,0xfe,0x0c,0x35,0x3a,0x0d,0x4a,0x1f,0x00,0xac,0xda,0x2c,0x46,0x3a,
|
||||
0xfb,0xea,0x67,0xc5,0xe8,0xd2,0x87,0x7c,0x5e,0x3b,0xc3,0x97,0xa6,0x59,0x94,0x9e,
|
||||
0xf8,0x02,0x1e,0x95,0x4e,0x0a,0x12,0x27,0x4e),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x43,0xba,0x28,0xf4,
|
||||
0x30,0xcd,0xff,0x45,0x6a,0xe5,0x31,0x54,0x5f,0x7e,0xcd,0x0a,0xc8,0x34,0xa5,0x5d,
|
||||
0x93,0x58,0xc0,0x37,0x2b,0xfa,0x0c,0x6c,0x67,0x98,0xc0,0x86,0x6a,0xea,0x01,0xeb,
|
||||
0x00,0x74,0x28,0x02,0xb8,0x43,0x8e,0xa4,0xcb,0x82,0x16,0x9c,0x23,0x51,0x60,0x62,
|
||||
0x7b,0x4c,0x3a,0x94,0x80),
|
||||
chunk_from_chars(
|
||||
0x03),
|
||||
chunk_from_chars(
|
||||
0x26,0xb8,0xf9,0x17,0x27,0xbd,0x62,0x89,0x7a,0xf1,0x5e,0x41,0xeb,0x43,0xc3,0x77,
|
||||
0xef,0xb9,0xc6,0x10,0xd4,0x8f,0x23,0x35,0xcb,0x0b,0xd0,0x08,0x78,0x10,0xf4,0x35,
|
||||
0x25,0x41,0xb1,0x43,0xc4,0xb9,0x81,0xb7,0xe1,0x8f,0x62,0xde,0x8c,0xcd,0xf6,0x33,
|
||||
0xfc,0x1b,0xf0,0x37,0xab,0x7c,0xd7,0x79,0x80,0x5e,0x0d,0xbc,0xc0,0xaa,0xe1,0xcb,
|
||||
0xce,0xe1,0xaf,0xb2,0xe0,0x27,0xdf,0x36,0xbc,0x04,0xdc,0xec,0xbf,0x15,0x43,0x36,
|
||||
0xc1,0x9f,0x0a,0xf7,0xe0,0xa6,0x47,0x29,0x05,0xe7,0x99,0xf1,0x95,0x3d,0x2a,0x0f,
|
||||
0xf3,0x34,0x8a,0xb2,0x1a,0xa4,0xad,0xaf,0xd1,0xd2,0x34,0x44,0x1c,0xf8,0x07,0xc0,
|
||||
0x3a,0x00),
|
||||
chunk_from_chars(
|
||||
0x74,0xa7,0x4b,0x23,0x69,0x98,0x17,0x46,0x1f,0xca,0xcf,0x84,0xf7,0xc6,0x3e,0x05,
|
||||
0x2a,0x1b,0xf9,0xb8),
|
||||
chunk_from_chars(
|
||||
0xf6,0x76,0xf7,0x63,0x82,0x2b,0x53,0x5c,0x61,0x9c,0xfa,0x4a,0x59,0x7d,0xdd,0xae,
|
||||
0x13,0x34,0xf0,0xb1),
|
||||
},
|
||||
/* 11 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0xcd,0x23,0xd2,0x4f,0x71,0x42,0x74,0xe7,0x44,0x34,0x32,0x37,0xb9,0x32,0x90,0xf5,
|
||||
0x11,0xf6,0x42,0x5f,0x98,0xe6,0x44,0x59,0xff,0x20,0x3e,0x89,0x85,0x08,0x3f,0xfd,
|
||||
0xf6,0x05,0x00,0x55,0x3a,0xbc,0x0e,0x05,0xcd,0x02,0x18,0x4b,0xdb,0x89,0xc4,0xcc,
|
||||
0xd6,0x7e,0x18,0x79,0x51,0x26,0x7e,0xb3,0x28),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xdc,0xea,0x9e,0x78,
|
||||
0xf3,0x5a,0x1b,0xf3,0x49,0x9a,0x83,0x1b,0x10,0xb8,0x6c,0x90,0xaa,0xc0,0x1c,0xd8,
|
||||
0x4b,0x67,0xa0,0x10,0x9b,0x55,0xa3,0x6e,0x93,0x28,0xb1,0xe3,0x65,0xfc,0xe1,0x61,
|
||||
0xd7,0x1c,0xe7,0x13,0x1a,0x54,0x3e,0xa4,0xcb,0x5f,0x7e,0x9f,0x1d,0x8b,0x00,0x69,
|
||||
0x64,0x47,0x00,0x14,0x00),
|
||||
chunk_from_chars(
|
||||
0x0c,0x3e,0x54,0x40,0x74,0xec,0x63,0xb0,0x26,0x5e,0x0c),
|
||||
chunk_from_chars(
|
||||
0x1f,0x0a,0x88,0x88,0xce,0x25,0xe8,0xd4,0x58,0xa2,0x11,0x30,0x87,0x9b,0x84,0x0a,
|
||||
0x90,0x89,0xd9,0x99,0xaa,0xba,0x03,0x9e,0xaf,0x3e,0x3a,0xfa,0x09,0x0a,0x09,0xd3,
|
||||
0x89,0xdb,0xa8,0x2c,0x4f,0xf2,0xae,0x8a,0xc5,0xcd,0xfb,0x7c,0x55,0xe9,0x4d,0x5d,
|
||||
0x96,0x1a,0x29,0xfe,0x01,0x09,0x94,0x1e,0x00,0xb8,0xdb,0xde,0xea,0x6d,0x3b,0x05,
|
||||
0x10,0x68,0xdf,0x72,0x54,0xc0,0xcd,0xc1,0x29,0xcb,0xe6,0x2d,0xb2,0xdc,0x95,0x7d,
|
||||
0xbb,0x47,0xb5,0x1f,0xd3,0xf2,0x13,0xfb,0x86,0x98,0xf0,0x64,0x77,0x42,0x50,0xa5,
|
||||
0x02,0x89,0x61,0xc9,0xbf,0x8f,0xfd,0x97,0x3f,0xe5,0xd5,0xc2,0x06,0x49,0x2b,0x14,
|
||||
0x0e,0x00),
|
||||
chunk_from_chars(
|
||||
0x3b,0x56,0x55,0xa4,0xce,0x4c,0xec,0x67,0x77,0x9c,0x9f,0xeb,0xfe,0x6f,0x38,0xba,
|
||||
0x88,0xc2,0x25,0x10),
|
||||
chunk_from_chars(
|
||||
0x71,0xcb,0xf2,0xb7,0x1b,0x3b,0x77,0xcb,0xd6,0x41,0x05,0x02,0x72,0x31,0xa6,0x91,
|
||||
0x27,0x3f,0xe5,0x51),
|
||||
},
|
||||
/* 12 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0x25,0x8c,0xdd,0x4a,0xda,0x32,0xed,0x9c,0x9f,0xf5,0x4e,0x63,0x75,0x6a,0xe5,0x82,
|
||||
0xfb,0x8f,0xab,0x2a,0xc7,0x21,0xf2,0xc8,0xe6,0x76,0xa7,0x27,0x68,0x51,0x3d,0x93,
|
||||
0x9f,0x63,0xdd,0xdb,0x55,0x60,0x91,0x33,0xf2,0x9a,0xdf,0x86,0xec,0x99,0x29,0xdc,
|
||||
0xcb,0x52,0xc1,0xc5,0xfd,0x2f,0xf7,0xe2,0x1b),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x3b,0xa1,0x6d,0xa0,
|
||||
0xc6,0xf2,0xcc,0x1f,0x30,0x18,0x77,0x40,0x75,0x6f,0x5e,0x79,0x8d,0x6b,0xc5,0xfc,
|
||||
0x01,0x5d,0x7c,0x63,0xcc,0x95,0x10,0xee,0x3f,0xd4,0x4a,0xdc,0x24,0xd8,0xe9,0x68,
|
||||
0xb6,0xe4,0x6e,0x6f,0x94,0xd1,0x9b,0x94,0x53,0x61,0x72,0x6b,0xd7,0x5e,0x14,0x9e,
|
||||
0xf0,0x98,0x17,0xf5,0x80),
|
||||
chunk_from_chars(
|
||||
0x64,0xa6,0x5f,0x3c,0xde,0xdc,0xdd,0x66,0x81,0x1e,0x29,0x15),
|
||||
chunk_from_chars(
|
||||
0x7e,0xee,0xab,0x7c,0x4e,0x50,0xfb,0x79,0x9b,0x41,0x8e,0xe5,0xe3,0x19,0x7f,0xf6,
|
||||
0xbf,0x15,0xd4,0x3a,0x14,0xc3,0x43,0x89,0xb5,0x9d,0xd1,0xa7,0xb1,0xb8,0x5b,0x4a,
|
||||
0xe9,0x04,0x38,0xac,0xa6,0x34,0xbe,0xa4,0x5e,0x3a,0x26,0x95,0xf1,0x27,0x0f,0x07,
|
||||
0xfd,0xcd,0xf7,0xc6,0x2b,0x8e,0xfe,0xaf,0x00,0xb4,0x5c,0x2c,0x96,0xba,0x45,0x7e,
|
||||
0xb1,0xa8,0xbf,0x07,0x5a,0x3d,0xb2,0x8e,0x5c,0x24,0xf6,0xb9,0x23,0xed,0x4a,0xd7,
|
||||
0x47,0xc3,0xc9,0xe0,0x3c,0x70,0x79,0xef,0xb8,0x7c,0xb1,0x10,0xd3,0xa9,0x98,0x61,
|
||||
0xe7,0x20,0x03,0xcb,0xae,0x6d,0x6b,0x8b,0x82,0x7e,0x4e,0x6c,0x14,0x30,0x64,0xff,
|
||||
0x3c,0x00),
|
||||
chunk_from_chars(
|
||||
0x56,0x8e,0xad,0x67,0xa7,0x83,0x78,0xfe,0x8f,0xaf,0xa7,0x87,0x2e,0xc8,0x95,0xa0,
|
||||
0xde,0x05,0x37,0x4c),
|
||||
chunk_from_chars(
|
||||
0xed,0x1b,0xe5,0xa1,0x97,0x23,0x59,0x4d,0x86,0x6b,0x6b,0xef,0xfb,0x81,0xe4,0x8e,
|
||||
0xf7,0x42,0xe0,0x81),
|
||||
},
|
||||
/* 13 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0x7e,0xf4,0xe8,0x45,0x44,0x23,0x67,0x52,0xfb,0xb5,0x6b,0x8f,0x31,0xa2,0x3a,0x10,
|
||||
0xe4,0x28,0x14,0xf5,0xf5,0x5c,0xa0,0x37,0xcd,0xcc,0x11,0xc6,0x4c,0x9a,0x3b,0x29,
|
||||
0x49,0xc1,0xbb,0x60,0x70,0x03,0x14,0x61,0x17,0x32,0xa6,0xc2,0xfe,0xa9,0x8e,0xeb,
|
||||
0xc0,0x26,0x6a,0x11,0xa9,0x39,0x70,0x10,0x0e),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xb3,0xda,0x07,0x9b,
|
||||
0x0a,0xa4,0x93,0xa5,0x77,0x20,0x29,0xf0,0x46,0x7b,0xae,0xbe,0xe5,0xa8,0x11,0x2d,
|
||||
0x9d,0x3a,0x22,0x53,0x23,0x61,0xda,0x29,0x4f,0x7b,0xb3,0x81,0x5c,0x5d,0xc5,0x9e,
|
||||
0x17,0x6b,0x4d,0x9f,0x38,0x1c,0xa0,0x93,0x8e,0x13,0xc6,0xc0,0x7b,0x17,0x4b,0xe6,
|
||||
0x5d,0xfa,0x57,0x8e,0x80),
|
||||
chunk_from_chars(
|
||||
0x64,0xa6,0x5f,0x3c,0xde,0xdc,0xdd,0x66,0x81,0x1e,0x29,0x15,0xe7),
|
||||
chunk_from_chars(
|
||||
0x6a,0x12,0x06,0x6f,0x55,0x33,0x1b,0x6c,0x22,0xac,0xd5,0xd5,0xbf,0xc5,0xd7,0x12,
|
||||
0x28,0xfb,0xda,0x80,0xae,0x8d,0xec,0x26,0xbd,0xd3,0x06,0x74,0x3c,0x50,0x27,0xcb,
|
||||
0x48,0x90,0x81,0x0c,0x16,0x2c,0x02,0x74,0x68,0x67,0x5e,0xcf,0x64,0x5a,0x83,0x17,
|
||||
0x6c,0x0d,0x73,0x23,0xa2,0xcc,0xde,0x2d,0x80,0xef,0xe5,0xa1,0x26,0x8e,0x8a,0xca,
|
||||
0x1d,0x6f,0xbc,0x19,0x4d,0x3f,0x77,0xc4,0x49,0x86,0xeb,0x4a,0xb4,0x17,0x79,0x19,
|
||||
0xad,0x8b,0xec,0x33,0xeb,0x47,0xbb,0xb5,0xfc,0x6e,0x28,0x19,0x6f,0xd1,0xca,0xf5,
|
||||
0x6b,0x4e,0x7e,0x0b,0xa5,0x51,0x92,0x34,0xd0,0x47,0x15,0x5a,0xc7,0x27,0xa1,0x05,
|
||||
0x31,0x00),
|
||||
chunk_from_chars(
|
||||
0x6e,0xb1,0xb6,0x33,0x76,0xa8,0x0f,0x84,0x26,0x23,0xfb,0xaa,0x9e,0xaa,0x1d,0x8d,
|
||||
0x6d,0xa5,0x75,0x4e),
|
||||
chunk_from_chars(
|
||||
0xfa,0x2f,0xeb,0xff,0x13,0xc0,0xee,0xd0,0x3b,0xc6,0xf2,0x7d,0xb8,0x61,0xe5,0x9d,
|
||||
0x16,0x53,0xb1,0x11),
|
||||
},
|
||||
/* 64 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0xd6,0x5d,0xf3,0x41,0xad,0x13,0xe0,0x08,0x56,0x76,0x88,0xba,0xed,0xda,0x8e,0x9d,
|
||||
0xcd,0xc1,0x7d,0xc0,0x24,0x97,0x4e,0xa5,0xb4,0x22,0x7b,0x65,0x30,0xe3,0x39,0xbf,
|
||||
0xf2,0x1f,0x99,0xe6,0x8c,0xa6,0x96,0x8f,0x3c,0xca,0x6d,0xfe,0x0f,0xb9,0xf4,0xfa,
|
||||
0xb4,0xfa,0x13,0x5d,0x55,0x42,0xea,0x3f,0x01),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xdf,0x97,0x05,0xf5,
|
||||
0x8e,0xdb,0xab,0x80,0x2c,0x7f,0x83,0x63,0xcf,0xe5,0x56,0x0a,0xb1,0xc6,0x13,0x2c,
|
||||
0x20,0xa9,0xf1,0xdd,0x16,0x34,0x83,0xa2,0x6f,0x8a,0xc5,0x3a,0x39,0xd6,0x80,0x8b,
|
||||
0xf4,0xa1,0xdf,0xbd,0x26,0x1b,0x09,0x9b,0xb0,0x3b,0x3f,0xb5,0x09,0x06,0xcb,0x28,
|
||||
0xbd,0x8a,0x08,0x1f,0x00),
|
||||
chunk_from_chars(
|
||||
0xbd,0x0f,0x6a,0x37,0x47,0xcd,0x56,0x1b,0xdd,0xdf,0x46,0x40,0xa3,0x32,0x46,0x1a,
|
||||
0x4a,0x30,0xa1,0x2a,0x43,0x4c,0xd0,0xbf,0x40,0xd7,0x66,0xd9,0xc6,0xd4,0x58,0xe5,
|
||||
0x51,0x22,0x04,0xa3,0x0c,0x17,0xd1,0xf5,0x0b,0x50,0x79,0x63,0x1f,0x64,0xeb,0x31,
|
||||
0x12,0x18,0x2d,0xa3,0x00,0x58,0x35,0x46,0x11,0x13,0x71,0x8d,0x1a,0x5e,0xf9,0x44),
|
||||
chunk_from_chars(
|
||||
0x55,0x4b,0xc2,0x48,0x08,0x60,0xb4,0x9e,0xab,0x85,0x32,0xd2,0xa5,0x33,0xb7,0xd5,
|
||||
0x78,0xef,0x47,0x3e,0xeb,0x58,0xc9,0x8b,0xb2,0xd0,0xe1,0xce,0x48,0x8a,0x98,0xb1,
|
||||
0x8d,0xfd,0xe9,0xb9,0xb9,0x07,0x75,0xe6,0x7f,0x47,0xd4,0xa1,0xc3,0x48,0x20,0x58,
|
||||
0xef,0xc9,0xf4,0x0d,0x2c,0xa0,0x33,0xa0,0x80,0x1b,0x63,0xd4,0x5b,0x3b,0x72,0x2e,
|
||||
0xf5,0x52,0xba,0xd3,0xb4,0xcc,0xb6,0x67,0xda,0x35,0x01,0x92,0xb6,0x1c,0x50,0x8c,
|
||||
0xf7,0xb6,0xb5,0xad,0xad,0xc2,0xc8,0xd9,0xa4,0x46,0xef,0x00,0x3f,0xb0,0x5c,0xba,
|
||||
0x5f,0x30,0xe8,0x8e,0x36,0xec,0x27,0x03,0xb3,0x49,0xca,0x22,0x9c,0x26,0x70,0x83,
|
||||
0x39,0x00),
|
||||
chunk_from_chars(
|
||||
0x2b,0xb0,0xd4,0x29,0xb8,0x51,0x3f,0xb5,0x9d,0x07,0xd0,0xb0,0x1f,0x4a,0x39,0x25,
|
||||
0x33,0xae,0x3e,0x64),
|
||||
chunk_from_chars(
|
||||
0x79,0xbb,0x37,0xe4,0x2a,0xf9,0x58,0xb7,0xa4,0x58,0x18,0x88,0x4b,0x82,0x8f,0xfb,
|
||||
0x9c,0x74,0xce,0x9d),
|
||||
},
|
||||
/* 256 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0x2e,0xc5,0xfe,0x3c,0x17,0x04,0x5a,0xbd,0xb1,0x36,0xa5,0xe6,0xa9,0x13,0xe3,0x2a,
|
||||
0xb7,0x5a,0xe6,0x8b,0x53,0xd2,0xfc,0x14,0x9b,0x77,0xe5,0x04,0x13,0x2d,0x37,0x56,
|
||||
0x9b,0x7e,0x76,0x6b,0xa7,0x4a,0x19,0xbd,0x61,0x62,0x34,0x3a,0x21,0xc8,0x59,0x0a,
|
||||
0xa9,0xce,0xbc,0xa9,0x01,0x4c,0x63,0x6d,0xf5),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x79,0x75,0x6f,0x01,
|
||||
0x4d,0xcf,0xe2,0x07,0x9f,0x5d,0xd9,0xe7,0x18,0xbe,0x41,0x71,0xe2,0xef,0x24,0x86,
|
||||
0xa0,0x8f,0x25,0x18,0x6f,0x6b,0xff,0x43,0xa9,0x93,0x6b,0x9b,0xfe,0x12,0x40,0x2b,
|
||||
0x08,0xae,0x65,0x79,0x8a,0x3d,0x81,0xe2,0x2e,0x9e,0xc8,0x0e,0x76,0x90,0x86,0x2e,
|
||||
0xf3,0xd4,0xed,0x3a,0x00),
|
||||
chunk_from_chars(
|
||||
0x15,0x77,0x75,0x32,0xb0,0xbd,0xd0,0xd1,0x38,0x9f,0x63,0x6c,0x5f,0x6b,0x9b,0xa7,
|
||||
0x34,0xc9,0x0a,0xf5,0x72,0x87,0x7e,0x2d,0x27,0x2d,0xd0,0x78,0xaa,0x1e,0x56,0x7c,
|
||||
0xfa,0x80,0xe1,0x29,0x28,0xbb,0x54,0x23,0x30,0xe8,0x40,0x9f,0x31,0x74,0x50,0x41,
|
||||
0x07,0xec,0xd5,0xef,0xac,0x61,0xae,0x75,0x04,0xda,0xbe,0x2a,0x60,0x2e,0xde,0x89,
|
||||
0xe5,0xcc,0xa6,0x25,0x7a,0x7c,0x77,0xe2,0x7a,0x70,0x2b,0x3a,0xe3,0x9f,0xc7,0x69,
|
||||
0xfc,0x54,0xf2,0x39,0x5a,0xe6,0xa1,0x17,0x8c,0xab,0x47,0x38,0xe5,0x43,0x07,0x2f,
|
||||
0xc1,0xc1,0x77,0xfe,0x71,0xe9,0x2e,0x25,0xbf,0x03,0xe4,0xec,0xb7,0x2f,0x47,0xb6,
|
||||
0x4d,0x04,0x65,0xaa,0xea,0x4c,0x7f,0xad,0x37,0x25,0x36,0xc8,0xba,0x51,0x6a,0x60,
|
||||
0x39,0xc3,0xc2,0xa3,0x9f,0x0e,0x4d,0x83,0x2b,0xe4,0x32,0xdf,0xa9,0xa7,0x06,0xa6,
|
||||
0xe5,0xc7,0xe1,0x9f,0x39,0x79,0x64,0xca,0x42,0x58,0x00,0x2f,0x7c,0x05,0x41,0xb5,
|
||||
0x90,0x31,0x6d,0xbc,0x56,0x22,0xb6,0xb2,0xa6,0xfe,0x7a,0x4a,0xbf,0xfd,0x96,0x10,
|
||||
0x5e,0xca,0x76,0xea,0x7b,0x98,0x81,0x6a,0xf0,0x74,0x8c,0x10,0xdf,0x04,0x8c,0xe0,
|
||||
0x12,0xd9,0x01,0x01,0x5a,0x51,0xf1,0x89,0xf3,0x88,0x81,0x45,0xc0,0x36,0x50,0xaa,
|
||||
0x23,0xce,0x89,0x4c,0x3b,0xd8,0x89,0xe0,0x30,0xd5,0x65,0x07,0x1c,0x59,0xf4,0x09,
|
||||
0xa9,0x98,0x1b,0x51,0x87,0x8f,0xd6,0xfc,0x11,0x06,0x24,0xdc,0xbc,0xde,0x0b,0xf7,
|
||||
0xa6,0x9c,0xcc,0xe3,0x8f,0xab,0xdf,0x86,0xf3,0xbe,0xf6,0x04,0x48,0x19,0xde,0x11),
|
||||
chunk_from_chars(
|
||||
0xc6,0x50,0xdd,0xbb,0x06,0x01,0xc1,0x9c,0xa1,0x14,0x39,0xe1,0x64,0x0d,0xd9,0x31,
|
||||
0xf4,0x3c,0x51,0x8e,0xa5,0xbe,0xa7,0x0d,0x3d,0xcd,0xe5,0xf4,0x19,0x1f,0xe5,0x3f,
|
||||
0x00,0xcf,0x96,0x65,0x46,0xb7,0x2b,0xcc,0x7d,0x58,0xbe,0x2b,0x9b,0xad,0xef,0x28,
|
||||
0x74,0x39,0x54,0xe3,0xa4,0x4a,0x23,0xf8,0x80,0xe8,0xd4,0xf1,0xcf,0xce,0x2d,0x7a,
|
||||
0x61,0x45,0x2d,0x26,0xda,0x05,0x89,0x6f,0x0a,0x50,0xda,0x66,0xa2,0x39,0xa8,0xa1,
|
||||
0x88,0xb6,0xd8,0x25,0xb3,0x30,0x5a,0xd7,0x7b,0x73,0xfb,0xac,0x08,0x36,0xec,0xc6,
|
||||
0x09,0x87,0xfd,0x08,0x52,0x7c,0x1a,0x8e,0x80,0xd5,0x82,0x3e,0x65,0xca,0xfe,0x2a,
|
||||
0x3d,0x00),
|
||||
chunk_from_chars(
|
||||
0xfc,0x02,0xc5,0x25,0x74,0x09,0x8f,0xbb,0xaf,0x8c,0xad,0x02,0x14,0x9d,0xef,0x0d,
|
||||
0x94,0xb7,0x96,0x5f),
|
||||
chunk_from_chars(
|
||||
0x63,0x03,0x8e,0x1f,0xcc,0x69,0x1e,0x2f,0x9d,0xb3,0x57,0x0f,0xad,0xbc,0x01,0x35,
|
||||
0x63,0xdb,0x06,0xba),
|
||||
},
|
||||
/* 1023 octets */
|
||||
{ chunk_from_chars(
|
||||
0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
|
||||
0x87,0x2d,0x09,0x37,0x80,0xf5,0xd3,0x73,0x0d,0xf7,0xc2,0x12,0x66,0x4b,0x37,0xb8,
|
||||
0xa0,0xf2,0x4f,0x56,0x81,0x0d,0xaa,0x83,0x82,0xcd,0x4f,0xa3,0xf7,0x76,0x34,0xec,
|
||||
0x44,0xdc,0x54,0xf1,0xc2,0xed,0x9b,0xea,0x86,0xfa,0xfb,0x76,0x32,0xd8,0xbe,0x19,
|
||||
0x9e,0xa1,0x65,0xf5,0xad,0x55,0xdd,0x9c,0xe8),
|
||||
chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xa8,0x1b,0x2e,0x8a,
|
||||
0x70,0xa5,0xac,0x94,0xff,0xdb,0xcc,0x9b,0xad,0xfc,0x3f,0xeb,0x08,0x01,0xf2,0x58,
|
||||
0x57,0x8b,0xb1,0x14,0xad,0x44,0xec,0xe1,0xec,0x0e,0x79,0x9d,0xa0,0x8e,0xff,0xb8,
|
||||
0x1c,0x5d,0x68,0x5c,0x0c,0x56,0xf6,0x4e,0xec,0xae,0xf8,0xcd,0xf1,0x1c,0xc3,0x87,
|
||||
0x37,0x83,0x8c,0xf4,0x00),
|
||||
chunk_from_chars(
|
||||
0x6d,0xdf,0x80,0x2e,0x1a,0xae,0x49,0x86,0x93,0x5f,0x7f,0x98,0x1b,0xa3,0xf0,0x35,
|
||||
0x1d,0x62,0x73,0xc0,0xa0,0xc2,0x2c,0x9c,0x0e,0x83,0x39,0x16,0x8e,0x67,0x54,0x12,
|
||||
0xa3,0xde,0xbf,0xaf,0x43,0x5e,0xd6,0x51,0x55,0x80,0x07,0xdb,0x43,0x84,0xb6,0x50,
|
||||
0xfc,0xc0,0x7e,0x3b,0x58,0x6a,0x27,0xa4,0xf7,0xa0,0x0a,0xc8,0xa6,0xfe,0xc2,0xcd,
|
||||
0x86,0xae,0x4b,0xf1,0x57,0x0c,0x41,0xe6,0xa4,0x0c,0x93,0x1d,0xb2,0x7b,0x2f,0xaa,
|
||||
0x15,0xa8,0xce,0xdd,0x52,0xcf,0xf7,0x36,0x2c,0x4e,0x6e,0x23,0xda,0xec,0x0f,0xbc,
|
||||
0x3a,0x79,0xb6,0x80,0x6e,0x31,0x6e,0xfc,0xc7,0xb6,0x81,0x19,0xbf,0x46,0xbc,0x76,
|
||||
0xa2,0x60,0x67,0xa5,0x3f,0x29,0x6d,0xaf,0xdb,0xdc,0x11,0xc7,0x7f,0x77,0x77,0xe9,
|
||||
0x72,0x66,0x0c,0xf4,0xb6,0xa9,0xb3,0x69,0xa6,0x66,0x5f,0x02,0xe0,0xcc,0x9b,0x6e,
|
||||
0xdf,0xad,0x13,0x6b,0x4f,0xab,0xe7,0x23,0xd2,0x81,0x3d,0xb3,0x13,0x6c,0xfd,0xe9,
|
||||
0xb6,0xd0,0x44,0x32,0x2f,0xee,0x29,0x47,0x95,0x2e,0x03,0x1b,0x73,0xab,0x5c,0x60,
|
||||
0x33,0x49,0xb3,0x07,0xbd,0xc2,0x7b,0xc6,0xcb,0x8b,0x8b,0xbd,0x7b,0xd3,0x23,0x21,
|
||||
0x9b,0x80,0x33,0xa5,0x81,0xb5,0x9e,0xad,0xeb,0xb0,0x9b,0x3c,0x4f,0x3d,0x22,0x77,
|
||||
0xd4,0xf0,0x34,0x36,0x24,0xac,0xc8,0x17,0x80,0x47,0x28,0xb2,0x5a,0xb7,0x97,0x17,
|
||||
0x2b,0x4c,0x5c,0x21,0xa2,0x2f,0x9c,0x78,0x39,0xd6,0x43,0x00,0x23,0x2e,0xb6,0x6e,
|
||||
0x53,0xf3,0x1c,0x72,0x3f,0xa3,0x7f,0xe3,0x87,0xc7,0xd3,0xe5,0x0b,0xdf,0x98,0x13,
|
||||
0xa3,0x0e,0x5b,0xb1,0x2c,0xf4,0xcd,0x93,0x0c,0x40,0xcf,0xb4,0xe1,0xfc,0x62,0x25,
|
||||
0x92,0xa4,0x95,0x88,0x79,0x44,0x94,0xd5,0x6d,0x24,0xea,0x4b,0x40,0xc8,0x9f,0xc0,
|
||||
0x59,0x6c,0xc9,0xeb,0xb9,0x61,0xc8,0xcb,0x10,0xad,0xde,0x97,0x6a,0x5d,0x60,0x2b,
|
||||
0x1c,0x3f,0x85,0xb9,0xb9,0xa0,0x01,0xed,0x3c,0x6a,0x4d,0x3b,0x14,0x37,0xf5,0x20,
|
||||
0x96,0xcd,0x19,0x56,0xd0,0x42,0xa5,0x97,0xd5,0x61,0xa5,0x96,0xec,0xd3,0xd1,0x73,
|
||||
0x5a,0x8d,0x57,0x0e,0xa0,0xec,0x27,0x22,0x5a,0x2c,0x4a,0xaf,0xf2,0x63,0x06,0xd1,
|
||||
0x52,0x6c,0x1a,0xf3,0xca,0x6d,0x9c,0xf5,0xa2,0xc9,0x8f,0x47,0xe1,0xc4,0x6d,0xb9,
|
||||
0xa3,0x32,0x34,0xcf,0xd4,0xd8,0x1f,0x2c,0x98,0x53,0x8a,0x09,0xeb,0xe7,0x69,0x98,
|
||||
0xd0,0xd8,0xfd,0x25,0x99,0x7c,0x7d,0x25,0x5c,0x6d,0x66,0xec,0xe6,0xfa,0x56,0xf1,
|
||||
0x11,0x44,0x95,0x0f,0x02,0x77,0x95,0xe6,0x53,0x00,0x8f,0x4b,0xd7,0xca,0x2d,0xee,
|
||||
0x85,0xd8,0xe9,0x0f,0x3d,0xc3,0x15,0x13,0x0c,0xe2,0xa0,0x03,0x75,0xa3,0x18,0xc7,
|
||||
0xc3,0xd9,0x7b,0xe2,0xc8,0xce,0x5b,0x6d,0xb4,0x1a,0x62,0x54,0xff,0x26,0x4f,0xa6,
|
||||
0x15,0x5b,0xae,0xe3,0xb0,0x77,0x3c,0x0f,0x49,0x7c,0x57,0x3f,0x19,0xbb,0x4f,0x42,
|
||||
0x40,0x28,0x1f,0x0b,0x1f,0x4f,0x7b,0xe8,0x57,0xa4,0xe5,0x9d,0x41,0x6c,0x06,0xb4,
|
||||
0xc5,0x0f,0xa0,0x9e,0x18,0x10,0xdd,0xc6,0xb1,0x46,0x7b,0xae,0xac,0x5a,0x36,0x68,
|
||||
0xd1,0x1b,0x6e,0xca,0xa9,0x01,0x44,0x00,0x16,0xf3,0x89,0xf8,0x0a,0xcc,0x4d,0xb9,
|
||||
0x77,0x02,0x5e,0x7f,0x59,0x24,0x38,0x8c,0x7e,0x34,0x0a,0x73,0x2e,0x55,0x44,0x40,
|
||||
0xe7,0x65,0x70,0xf8,0xdd,0x71,0xb7,0xd6,0x40,0xb3,0x45,0x0d,0x1f,0xd5,0xf0,0x41,
|
||||
0x0a,0x18,0xf9,0xa3,0x49,0x4f,0x70,0x7c,0x71,0x7b,0x79,0xb4,0xbf,0x75,0xc9,0x84,
|
||||
0x00,0xb0,0x96,0xb2,0x16,0x53,0xb5,0xd2,0x17,0xcf,0x35,0x65,0xc9,0x59,0x74,0x56,
|
||||
0xf7,0x07,0x03,0x49,0x7a,0x07,0x87,0x63,0x82,0x9b,0xc0,0x1b,0xb1,0xcb,0xc8,0xfa,
|
||||
0x04,0xea,0xdc,0x9a,0x6e,0x3f,0x66,0x99,0x58,0x7a,0x9e,0x75,0xc9,0x4e,0x5b,0xab,
|
||||
0x00,0x36,0xe0,0xb2,0xe7,0x11,0x39,0x2c,0xff,0x00,0x47,0xd0,0xd6,0xb0,0x5b,0xd2,
|
||||
0xa5,0x88,0xbc,0x10,0x97,0x18,0x95,0x42,0x59,0xf1,0xd8,0x66,0x78,0xa5,0x79,0xa3,
|
||||
0x12,0x0f,0x19,0xcf,0xb2,0x96,0x3f,0x17,0x7a,0xeb,0x70,0xf2,0xd4,0x84,0x48,0x26,
|
||||
0x26,0x2e,0x51,0xb8,0x02,0x71,0x27,0x20,0x68,0xef,0x5b,0x38,0x56,0xfa,0x85,0x35,
|
||||
0xaa,0x2a,0x88,0xb2,0xd4,0x1f,0x2a,0x0e,0x2f,0xda,0x76,0x24,0xc2,0x85,0x02,0x72,
|
||||
0xac,0x4a,0x2f,0x56,0x1f,0x8f,0x2f,0x7a,0x31,0x8b,0xfd,0x5c,0xaf,0x96,0x96,0x14,
|
||||
0x9e,0x4a,0xc8,0x24,0xad,0x34,0x60,0x53,0x8f,0xdc,0x25,0x42,0x1b,0xee,0xc2,0xcc,
|
||||
0x68,0x18,0x16,0x2d,0x06,0xbb,0xed,0x0c,0x40,0xa3,0x87,0x19,0x23,0x49,0xdb,0x67,
|
||||
0xa1,0x18,0xba,0xda,0x6c,0xd5,0xab,0x01,0x40,0xee,0x27,0x32,0x04,0xf6,0x28,0xaa,
|
||||
0xd1,0xc1,0x35,0xf7,0x70,0x27,0x9a,0x65,0x1e,0x24,0xd8,0xc1,0x4d,0x75,0xa6,0x05,
|
||||
0x9d,0x76,0xb9,0x6a,0x6f,0xd8,0x57,0xde,0xf5,0xe0,0xb3,0x54,0xb2,0x7a,0xb9,0x37,
|
||||
0xa5,0x81,0x5d,0x16,0xb5,0xfa,0xe4,0x07,0xff,0x18,0x22,0x2c,0x6d,0x1e,0xd2,0x63,
|
||||
0xbe,0x68,0xc9,0x5f,0x32,0xd9,0x08,0xbd,0x89,0x5c,0xd7,0x62,0x07,0xae,0x72,0x64,
|
||||
0x87,0x56,0x7f,0x9a,0x67,0xda,0xd7,0x9a,0xbe,0xc3,0x16,0xf6,0x83,0xb1,0x7f,0x2d,
|
||||
0x02,0xbf,0x07,0xe0,0xac,0x8b,0x5b,0xc6,0x16,0x2c,0xf9,0x46,0x97,0xb3,0xc2,0x7c,
|
||||
0xd1,0xfe,0xa4,0x9b,0x27,0xf2,0x3b,0xa2,0x90,0x18,0x71,0x96,0x25,0x06,0x52,0x0c,
|
||||
0x39,0x2d,0xa8,0xb6,0xad,0x0d,0x99,0xf7,0x01,0x3f,0xbc,0x06,0xc2,0xc1,0x7a,0x56,
|
||||
0x95,0x00,0xc8,0xa7,0x69,0x64,0x81,0xc1,0xcd,0x33,0xe9,0xb1,0x4e,0x40,0xb8,0x2e,
|
||||
0x79,0xa5,0xf5,0xdb,0x82,0x57,0x1b,0xa9,0x7b,0xae,0x3a,0xd3,0xe0,0x47,0x95,0x15,
|
||||
0xbb,0x0e,0x2b,0x0f,0x3b,0xfc,0xd1,0xfd,0x33,0x03,0x4e,0xfc,0x62,0x45,0xed,0xdd,
|
||||
0x7e,0xe2,0x08,0x6d,0xda,0xe2,0x60,0x0d,0x8c,0xa7,0x3e,0x21,0x4e,0x8c,0x2b,0x0b,
|
||||
0xdb,0x2b,0x04,0x7c,0x6a,0x46,0x4a,0x56,0x2e,0xd7,0x7b,0x73,0xd2,0xd8,0x41,0xc4,
|
||||
0xb3,0x49,0x73,0x55,0x12,0x57,0x71,0x3b,0x75,0x36,0x32,0xef,0xba,0x34,0x81,0x69,
|
||||
0xab,0xc9,0x0a,0x68,0xf4,0x26,0x11,0xa4,0x01,0x26,0xd7,0xcb,0x21,0xb5,0x86,0x95,
|
||||
0x56,0x81,0x86,0xf7,0xe5,0x69,0xd2,0xff,0x0f,0x9e,0x74,0x5d,0x04,0x87,0xdd,0x2e,
|
||||
0xb9,0x97,0xca,0xfc,0x5a,0xbf,0x9d,0xd1,0x02,0xe6,0x2f,0xf6,0x6c,0xba,0x87),
|
||||
chunk_from_chars(
|
||||
0xe3,0x01,0x34,0x5a,0x41,0xa3,0x9a,0x4d,0x72,0xff,0xf8,0xdf,0x69,0xc9,0x80,0x75,
|
||||
0xa0,0xcc,0x08,0x2b,0x80,0x2f,0xc9,0xb2,0xb6,0xbc,0x50,0x3f,0x92,0x6b,0x65,0xbd,
|
||||
0xdf,0x7f,0x4c,0x8f,0x1c,0xb4,0x9f,0x63,0x96,0xaf,0xc8,0xa7,0x0a,0xbe,0x6d,0x8a,
|
||||
0xef,0x0d,0xb4,0x78,0xd4,0xc6,0xb2,0x97,0x00,0x76,0xc6,0xa0,0x48,0x4f,0xe7,0x6d,
|
||||
0x76,0xb3,0xa9,0x76,0x25,0xd7,0x9f,0x1c,0xe2,0x40,0xe7,0xc5,0x76,0x75,0x0d,0x29,
|
||||
0x55,0x28,0x28,0x6f,0x71,0x9b,0x41,0x3d,0xe9,0xad,0xa3,0xe8,0xeb,0x78,0xed,0x57,
|
||||
0x36,0x03,0xce,0x30,0xd8,0xbb,0x76,0x17,0x85,0xdc,0x30,0xdb,0xc3,0x20,0x86,0x9e,
|
||||
0x1a,0x00),
|
||||
chunk_from_chars(
|
||||
0x89,0x30,0xb4,0x62,0xe0,0x28,0x45,0xf1,0x37,0xc0,0x0e,0x47,0xfe,0x64,0x3d,0x07,
|
||||
0x02,0x7b,0x66,0xec),
|
||||
chunk_from_chars(
|
||||
0xc1,0x6c,0x19,0x0e,0x3e,0xe9,0x2c,0x5e,0xd0,0x35,0x19,0x93,0x77,0x2c,0xd6,0x38,
|
||||
0xf0,0xbc,0xe1,0x62),
|
||||
},
|
||||
};
|
||||
|
||||
START_TEST(test_ed448_sign)
|
||||
{
|
||||
private_key_t *key;
|
||||
public_key_t *pubkey, *public;
|
||||
chunk_t sig, encoding, fp;
|
||||
|
||||
/* load private key */
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, sig_tests[_i].key, BUILD_END);
|
||||
ck_assert(key != NULL);
|
||||
ck_assert(key->get_encoding(key, PRIVKEY_ASN1_DER, &encoding));
|
||||
ck_assert_chunk_eq(encoding, sig_tests[_i].key);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
|
||||
|
||||
/* load public key */
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, sig_tests[_i].pubkey, BUILD_END);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
|
||||
ck_assert_chunk_eq(encoding, sig_tests[_i].pubkey);
|
||||
chunk_free(&encoding);
|
||||
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
|
||||
ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
|
||||
|
||||
/* compare public keys */
|
||||
public = key->get_public_key(key);
|
||||
ck_assert(public != NULL);
|
||||
ck_assert(public->equals(public, pubkey));
|
||||
|
||||
/* sign */
|
||||
ck_assert(key->sign(key, SIGN_ED448, NULL, sig_tests[_i].msg, &sig));
|
||||
ck_assert_chunk_eq(sig, sig_tests[_i].sig);
|
||||
|
||||
/* verify */
|
||||
ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[_i].msg,
|
||||
sig_tests[_i].sig));
|
||||
|
||||
/* cleanup */
|
||||
key->destroy(key);
|
||||
pubkey->destroy(pubkey);
|
||||
public->destroy(public);
|
||||
chunk_free(&sig);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ed448_gen)
|
||||
{
|
||||
private_key_t *key, *key2;
|
||||
public_key_t *pubkey, *pubkey2;
|
||||
chunk_t msg = chunk_from_str("Ed448"), sig, encoding, fp_priv, fp_pub;
|
||||
|
||||
/* generate private key */
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_KEY_SIZE, 456, BUILD_END);
|
||||
ck_assert(key != NULL);
|
||||
ck_assert(key->get_type(key) == KEY_ED448);
|
||||
ck_assert(key->get_keysize(key) == 456);
|
||||
ck_assert(!key->get_encoding(key, PRIVKEY_PGP, &encoding));
|
||||
ck_assert(key->get_encoding(key, PRIVKEY_PEM, &encoding));
|
||||
ck_assert(encoding.ptr != NULL);
|
||||
ck_assert(strstr(encoding.ptr, "PRIVATE KEY"));
|
||||
chunk_free(&encoding);
|
||||
|
||||
/* clone private key */
|
||||
key2 = key->get_ref(key);
|
||||
ck_assert(key2);
|
||||
key2->destroy(key2);
|
||||
|
||||
/* decryption not supported */
|
||||
ck_assert(!key->decrypt(key, ENCRYPT_UNKNOWN, msg, NULL));
|
||||
|
||||
/* wrong signature scheme */
|
||||
ck_assert(!key->sign(key, SIGN_ED25519, NULL, msg, &sig));
|
||||
|
||||
/* correct signature scheme*/
|
||||
ck_assert(key->sign(key, SIGN_ED448, NULL, msg, &sig));
|
||||
|
||||
/* export public key */
|
||||
pubkey = key->get_public_key(key);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->get_type(pubkey) == KEY_ED448);
|
||||
ck_assert(pubkey->get_keysize(pubkey) == 456);
|
||||
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_PEM, &encoding));
|
||||
ck_assert(encoding.ptr != NULL);
|
||||
ck_assert(strstr(encoding.ptr, "PUBLIC KEY"));
|
||||
chunk_free(&encoding);
|
||||
|
||||
/* generate and compare public and private key fingerprints */
|
||||
ck_assert(!key->get_fingerprint(key, KEYID_PGPV4, &fp_priv));
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp_priv));
|
||||
ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp_priv));
|
||||
ck_assert(fp_priv.ptr != NULL);
|
||||
ck_assert(!pubkey->get_fingerprint(pubkey, KEYID_PGPV4, &fp_pub));
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
|
||||
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
|
||||
ck_assert(fp_pub.ptr != NULL);
|
||||
ck_assert_chunk_eq(fp_pub, fp_priv);
|
||||
|
||||
/* clone public key */
|
||||
pubkey2 = pubkey->get_ref(pubkey);
|
||||
ck_assert(pubkey2 != NULL);
|
||||
pubkey2->destroy(pubkey2);
|
||||
|
||||
/* encryption not supported */
|
||||
ck_assert(!pubkey->encrypt(pubkey, ENCRYPT_UNKNOWN, msg, NULL));
|
||||
|
||||
/* verify with wrong signature scheme */
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED25519, NULL, msg, sig));
|
||||
|
||||
/* verify with correct signature scheme */
|
||||
ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, msg, sig));
|
||||
|
||||
/* cleanup */
|
||||
key->destroy(key);
|
||||
pubkey->destroy(pubkey);
|
||||
chunk_free(&sig);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_ed448_speed)
|
||||
{
|
||||
private_key_t *key;
|
||||
public_key_t *pubkey;
|
||||
chunk_t msg = chunk_from_str("Hello Ed448"), sig;
|
||||
int i, count = 500;
|
||||
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec start, stop;
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_KEY_SIZE, 456, BUILD_END);
|
||||
ck_assert(key != NULL);
|
||||
ck_assert(key->sign(key, SIGN_ED448, NULL, msg, &sig));
|
||||
pubkey = key->get_public_key(key);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, msg, sig));
|
||||
key->destroy(key);
|
||||
pubkey->destroy(pubkey);
|
||||
chunk_free(&sig);
|
||||
}
|
||||
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stop);
|
||||
DBG0(DBG_LIB, "%d Ed448 keys and signatures in %d ms\n", count,
|
||||
(stop.tv_nsec - start.tv_nsec) / 1000000 +
|
||||
(stop.tv_sec - start.tv_sec) * 1000);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static chunk_t zero_pk = chunk_from_chars(
|
||||
0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00);
|
||||
|
||||
/* sig_tests[0].sig with s+L, note that only the 9 most significant bits are 0 */
|
||||
static chunk_t malleable_sig = chunk_from_chars(
|
||||
0x53,0x3a,0x37,0xf6,0xbb,0xe4,0x57,0x25,0x1f,0x02,0x3c,0x0d,0x88,0xf9,0x76,0xae,
|
||||
0x2d,0xfb,0x50,0x4a,0x84,0x3e,0x34,0xd2,0x07,0x4f,0xd8,0x23,0xd4,0x1a,0x59,0x1f,
|
||||
0x2b,0x23,0x3f,0x03,0x4f,0x62,0x82,0x81,0xf2,0xfd,0x7a,0x22,0xdd,0xd4,0x7d,0x78,
|
||||
0x28,0xc5,0x9b,0xd0,0xa2,0x1b,0xfd,0x39,0x80,0xf2,0x52,0x78,0xd3,0x66,0x74,0x03,
|
||||
0xc1,0x4b,0xce,0xc5,0xf9,0xcf,0xde,0x99,0x55,0xeb,0xc8,0x33,0x3c,0x0a,0xe7,0x8f,
|
||||
0xc8,0x6e,0x51,0x83,0x17,0xc5,0xc7,0xcd,0xda,0x85,0x30,0xa1,0x13,0xa0,0xf4,0xdb,
|
||||
0xb6,0x11,0x49,0xf0,0x5a,0x73,0x63,0x26,0x8c,0x71,0xd9,0x58,0x08,0xff,0x2e,0x65,
|
||||
0x66,0x00);
|
||||
|
||||
START_TEST(test_ed448_fail)
|
||||
{
|
||||
private_key_t *key;
|
||||
public_key_t *pubkey;
|
||||
chunk_t blob, sig;
|
||||
uint8_t sig1[114];
|
||||
|
||||
/* Invalid private key format */
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, chunk_empty, BUILD_END);
|
||||
ck_assert(key == NULL);
|
||||
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_EDDSA_PRIV_ASN1_DER, chunk_empty, BUILD_END);
|
||||
ck_assert(key == NULL);
|
||||
|
||||
blob = chunk_from_chars(0x04, 0x01, 0x9d);
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
|
||||
BUILD_EDDSA_PRIV_ASN1_DER, blob, BUILD_END);
|
||||
ck_assert(key == NULL);
|
||||
|
||||
/* Invalid public key format */
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, chunk_empty, BUILD_END);
|
||||
ck_assert(pubkey == NULL);
|
||||
|
||||
blob = chunk_from_chars(0x30, 0x0b, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
|
||||
0x71, 0x03, 0x02, 0x00, 0xd7);
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, blob, BUILD_END);
|
||||
ck_assert(pubkey == NULL);
|
||||
|
||||
blob = chunk_from_chars(0x30, 0x0b, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x00,
|
||||
0x71, 0x03, 0x02, 0x00, 0xd7);
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, blob, BUILD_END);
|
||||
ck_assert(pubkey == NULL);
|
||||
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_KEY_SIZE, 456, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
|
||||
ck_assert(pubkey == NULL);
|
||||
|
||||
/* Invalid signature format */
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, sig_tests[0].pubkey, BUILD_END);
|
||||
ck_assert(pubkey != NULL);
|
||||
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, chunk_empty,
|
||||
chunk_empty));
|
||||
|
||||
/* RFC 8032, section 5.2.7 requires that 0 <= s < L to prevent signature
|
||||
* malleability. Only a warning because OpenSSL is vulnerable to this. */
|
||||
if (pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
|
||||
malleable_sig))
|
||||
{
|
||||
warn("Ed448 signature verification is vulnerable to malleable "
|
||||
"signatures");
|
||||
}
|
||||
|
||||
/* malformed signature */
|
||||
sig = chunk_from_thing(sig1);
|
||||
memcpy(sig1, sig_tests[0].sig.ptr, sig_tests[0].sig.len);
|
||||
sig1[113] |= 0xFF;
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
|
||||
sig));
|
||||
|
||||
/* wrong signature */
|
||||
memcpy(sig1, sig_tests[0].sig.ptr, sig_tests[0].sig.len);
|
||||
sig1[0] = 0xe4;
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
|
||||
sig));
|
||||
|
||||
/* detect all-zeroes public key */
|
||||
pubkey->destroy(pubkey);
|
||||
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
|
||||
BUILD_BLOB_ASN1_DER, zero_pk, BUILD_END);
|
||||
ck_assert(pubkey != NULL);
|
||||
ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
|
||||
sig));
|
||||
pubkey->destroy(pubkey);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *ed448_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("ed448");
|
||||
|
||||
tc = tcase_create("ed448_sign");
|
||||
tcase_add_loop_test(tc, test_ed448_sign, 0, countof(sig_tests));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ed448_gen");
|
||||
tcase_add_test(tc, test_ed448_gen);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ed448_fail");
|
||||
tcase_add_test(tc, test_ed448_fail);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("ed448_speed");
|
||||
test_case_set_timeout(tc, 10);
|
||||
tcase_add_test(tc, test_ed448_speed);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -52,5 +52,6 @@ TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256)
|
||||
TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
|
||||
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
|
||||
TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519)
|
||||
TEST_SUITE_DEPEND(ed448_suite_create, PRIVKEY_GEN, KEY_ED448)
|
||||
TEST_SUITE(signature_params_suite_create)
|
||||
|
||||
|
||||
@@ -587,6 +587,11 @@ static char *whitelist[] = {
|
||||
"OPENSSL_load_builtin_modules",
|
||||
"CONF_modules_load_file",
|
||||
"CONF_module_add",
|
||||
"RAND_DRBG_bytes",
|
||||
"RAND_DRBG_generate",
|
||||
"RAND_DRBG_get0_master",
|
||||
"RAND_DRBG_get0_private",
|
||||
"RAND_DRBG_get0_public",
|
||||
/* OpenSSL libssl */
|
||||
"SSL_COMP_get_compression_methods",
|
||||
/* NSPR */
|
||||
|
||||
Reference in New Issue
Block a user