wolfssl: Fixes, code style changes and some refactorings

The main fixes are

 * the generation of fingerprints for RSA, ECDSA, and EdDSA
 * the encoding of ECDSA private keys
 * calculating p and q for RSA private keys
 * deriving the public key for raw Ed25519 private keys

Also, instead of numeric literals for buffer lengths ASN.1 related
constants are used.
This commit is contained in:
Tobias Brunner 2019-04-05 12:03:18 +02:00
parent 59be02519a
commit d3329ee540
24 changed files with 646 additions and 798 deletions

View File

@ -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

2
conf/plugins/wolfssl.opt Normal file
View File

@ -0,0 +1,2 @@
charon.plugins.wolfssl.fips_mode = no
Enable to prevent loading the plugin if wolfSSL is not in FIPS mode.

View File

@ -1,6 +1,5 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-DFIPS_MODE=${fips_mode}
-I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = \
$(PLUGIN_CFLAGS)

View File

@ -40,17 +40,6 @@
#define CCM_SALT_LEN 3
#define CCM_NONCE_LEN (CCM_SALT_LEN + IV_LEN)
#if !defined(NO_AES) && defined(HAVE_AESGCM)
#define MAX_NONCE_LEN GCM_NONCE_LEN
#define MAX_SALT_LEN GCM_SALT_LEN
#elif defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
#define MAX_NONCE_LEN 12
#define MAX_SALT_LEN 4
#elif !defined(NO_AES) && defined(HAVE_AESCCM)
#define MAX_NONCE_LEN CCM_NONCE_LEN
#define MAX_SALT_LEN GCM_SALT_LEN
#endif
typedef struct private_aead_t private_aead_t;
/**
@ -71,23 +60,13 @@ struct private_aead_t {
/**
* Salt value
*/
char salt[MAX_SALT_LEN];
/**
* Length of the salt
*/
size_t salt_len;
chunk_t salt;
/**
* Size of the integrity check value
*/
size_t icv_size;
/**
* Size of the IV
*/
size_t iv_size;
/**
* IV generator
*/
@ -96,8 +75,7 @@ struct private_aead_t {
/**
* The cipher to use
*/
union
{
union {
#if !defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))
Aes aes;
#endif
@ -109,15 +87,14 @@ struct private_aead_t {
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)
{
bool success = FALSE;
int ret = 0;
chunk_t nonce;
u_char *out;
u_char nonce[MAX_NONCE_LEN];
bool success = FALSE;
int ret;
out = plain.ptr;
if (encrypted)
@ -126,8 +103,7 @@ METHOD(aead_t, encrypt, bool,
out = encrypted->ptr;
}
memcpy(nonce, this->salt, this->salt_len);
memcpy(nonce + this->salt_len, iv.ptr, IV_LEN);
nonce = chunk_cata("cc", this->salt, iv);
switch (this->alg)
{
@ -140,8 +116,8 @@ METHOD(aead_t, encrypt, bool,
if (ret == 0)
{
ret = wc_AesGcmEncrypt(&this->cipher.aes, out, plain.ptr,
plain.len, nonce, GCM_NONCE_LEN, out + plain.len,
this->icv_size, assoc.ptr, assoc.len);
plain.len, nonce.ptr, GCM_NONCE_LEN, out + plain.len,
this->icv_size, assoc.ptr, assoc.len);
}
success = (ret == 0);
break;
@ -150,23 +126,27 @@ METHOD(aead_t, encrypt, bool,
case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16:
if (plain.ptr == NULL && plain.len == 0)
plain.ptr = nonce;
/* 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, CCM_NONCE_LEN, out + plain.len,
this->icv_size, assoc.ptr, assoc.len);
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, assoc.ptr,
assoc.len, plain.ptr, plain.len, out, out + plain.len);
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
@ -174,6 +154,7 @@ METHOD(aead_t, encrypt, bool,
break;
}
memwipe(nonce.ptr, nonce.len);
return success;
}
@ -181,10 +162,10 @@ 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;
u_char *out;
u_char nonce[MAX_NONCE_LEN];
if (encrypted.len < this->icv_size)
{
@ -199,8 +180,7 @@ METHOD(aead_t, decrypt, bool,
out = plain->ptr;
}
memcpy(nonce, this->salt, this->salt_len);
memcpy(nonce + this->salt_len, iv.ptr, IV_LEN);
nonce = chunk_cata("cc", this->salt, iv);
switch (this->alg)
{
@ -209,13 +189,13 @@ METHOD(aead_t, decrypt, bool,
case ENCR_AES_GCM_ICV12:
case ENCR_AES_GCM_ICV16:
ret = wc_AesGcmSetKey(&this->cipher.aes, this->key.ptr,
this->key.len);
this->key.len);
if (ret == 0)
{
ret = wc_AesGcmDecrypt(&this->cipher.aes, out, encrypted.ptr,
encrypted.len, nonce, GCM_NONCE_LEN,
encrypted.ptr + encrypted.len, this->icv_size, assoc.ptr,
assoc.len);
encrypted.len, nonce.ptr, GCM_NONCE_LEN,
encrypted.ptr + encrypted.len, this->icv_size,
assoc.ptr, assoc.len);
}
success = (ret == 0);
break;
@ -224,27 +204,32 @@ METHOD(aead_t, decrypt, bool,
case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16:
if (encrypted.ptr == NULL && encrypted.len == 0)
encrypted.ptr = nonce;
if (out == NULL && encrypted.len == 0)
out = nonce;
/* 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);
this->key.len);
if (ret == 0)
{
ret = wc_AesCcmDecrypt(&this->cipher.aes, out, encrypted.ptr,
encrypted.len, nonce, CCM_NONCE_LEN,
encrypted.ptr + encrypted.len, this->icv_size, assoc.ptr,
assoc.len);
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, assoc.ptr,
assoc.len, encrypted.ptr, encrypted.len,
encrypted.ptr + encrypted.len, out);
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
@ -252,13 +237,14 @@ METHOD(aead_t, decrypt, bool,
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. */
/* all AEAD algorithms are streaming */
return 1;
}
@ -283,7 +269,7 @@ METHOD(aead_t, get_iv_gen, iv_gen_t*,
METHOD(aead_t, get_key_size, size_t,
private_aead_t *this)
{
return this->key.len + this->salt_len;
return this->key.len + this->salt.len;
}
METHOD(aead_t, set_key, bool,
@ -293,7 +279,7 @@ METHOD(aead_t, set_key, bool,
{
return FALSE;
}
memcpy(this->salt, key.ptr + key.len - this->salt_len, this->salt_len);
memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
memcpy(this->key.ptr, key.ptr, this->key.len);
return TRUE;
}
@ -302,6 +288,7 @@ 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)
@ -317,10 +304,6 @@ METHOD(aead_t, destroy, void,
case ENCR_AES_CCM_ICV16:
wc_AesFree(&this->cipher.aes);
break;
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
case ENCR_CHACHA20_POLY1305:
break;
#endif
default:
break;
@ -336,6 +319,7 @@ 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 = {
@ -404,8 +388,7 @@ aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
case 16:
case 24:
case 32:
this->iv_size = GCM_NONCE_LEN;
this->salt_len = GCM_SALT_LEN;
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");
@ -431,8 +414,7 @@ aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
case 16:
case 24:
case 32:
this->iv_size = CCM_NONCE_LEN;
this->salt_len = CCM_SALT_LEN;
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");
@ -454,8 +436,7 @@ aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
key_size = 32;
/* FALL */
case 32:
this->iv_size = CHACHA_IV_BYTES;
this->salt_len = 4;
expected_salt_size = 4;
break;
default:
free(this);
@ -468,7 +449,7 @@ aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
return NULL;
}
if (salt_size && salt_size != this->salt_len)
if (salt_size && salt_size != expected_salt_size)
{
/* currently not supported */
free(this);
@ -476,6 +457,7 @@ aead_t *wolfssl_aead_create(encryption_algorithm_t algo,
}
this->key = chunk_alloc(key_size);
this->salt = chunk_alloc(expected_salt_size);
this->iv_gen = iv_gen_seq_create();
return &this->public;

View File

@ -46,8 +46,7 @@ struct private_wolfssl_crypter_t {
/**
* wolfSSL cipher
*/
union
{
union {
#if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
Aes aes;
#endif
@ -65,7 +64,7 @@ struct private_wolfssl_crypter_t {
*/
encryption_algorithm_t alg;
/**
/**
* Private key
*/
chunk_t key;
@ -73,17 +72,7 @@ struct private_wolfssl_crypter_t {
/**
* Salt value
*/
char salt[CTR_SALT_LEN];
/**
* Length of the salt
*/
size_t salt_len;
/**
* Size of key
*/
size_t key_size;
chunk_t salt;
/**
* Size of block
@ -114,10 +103,10 @@ METHOD(crypter_t, decrypt, bool,
out = dst->ptr;
}
if (this->salt_len > 0)
if (this->salt.len > 0)
{
memcpy(nonce, this->salt, this->salt_len);
memcpy(nonce + this->salt_len, iv.ptr, this->iv_size);
memcpy(nonce, this->salt.ptr, this->salt.len);
memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
nonce[AES_BLOCK_SIZE - 1] = 1;
}
@ -212,6 +201,7 @@ METHOD(crypter_t, decrypt, bool,
break;
}
memwipe(nonce, sizeof(nonce));
return success;
}
@ -233,10 +223,10 @@ METHOD(crypter_t, encrypt, bool,
out = dst->ptr;
}
if (this->salt_len > 0)
if (this->salt.len > 0)
{
memcpy(nonce, this->salt, this->salt_len);
memcpy(nonce + this->salt_len, iv.ptr, this->iv_size);
memcpy(nonce, this->salt.ptr, this->salt.len);
memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
nonce[AES_BLOCK_SIZE - 1] = 1;
}
@ -348,7 +338,7 @@ METHOD(crypter_t, get_iv_size, size_t,
METHOD(crypter_t, get_key_size, size_t,
private_wolfssl_crypter_t *this)
{
return this->key.len + this->salt_len;
return this->key.len + this->salt.len;
}
METHOD(crypter_t, set_key, bool,
@ -358,7 +348,7 @@ METHOD(crypter_t, set_key, bool,
{
return FALSE;
}
memcpy(this->salt, key.ptr + key.len - this->salt_len, this->salt_len);
memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
memcpy(this->key.ptr, key.ptr, this->key.len);
return TRUE;
}
@ -367,6 +357,7 @@ 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)
@ -379,19 +370,10 @@ METHOD(crypter_t, destroy, void,
wc_AesFree(&this->cipher.aes);
break;
#endif
#ifdef HAVE_CAMELLIA
case ENCR_CAMELLIA_CBC:
break;
#endif
#ifndef NO_DES3
case ENCR_3DES:
wc_Des3Free(&this->cipher.des3);
break;
case ENCR_DES:
#ifdef WOLFSSL_DES_ECB
case ENCR_DES_ECB:
#endif
break;
#endif
default:
break;
@ -424,6 +406,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
{
case 0:
key_size = 16;
/* fall-through */
case 16:
case 24:
case 32:
@ -441,6 +424,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
{
case 0:
key_size = 16;
/* fall-through */
case 16:
case 24:
case 32:
@ -459,6 +443,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
{
case 0:
key_size = 16;
/* fall-through */
case 16:
case 24:
case 32:
@ -480,24 +465,16 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
iv_size = DES_BLOCK_SIZE;
break;
case ENCR_DES:
if (key_size != 8)
{
return NULL;
}
block_size = DES_BLOCK_SIZE;
iv_size = DES_BLOCK_SIZE;
break;
#ifdef WOLFSSL_DES_ECB
case ENCR_DES_ECB:
#endif
if (key_size != 8)
{
return NULL;
}
key_size = DES_BLOCK_SIZE;
block_size = DES_BLOCK_SIZE;
iv_size = DES_BLOCK_SIZE;
break;
#endif
#endif
default:
return NULL;
@ -516,10 +493,8 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
},
},
.alg = algo,
.key_size = key_size,
.block_size = block_size,
.iv_size = iv_size,
.salt_len = salt_len,
);
switch (algo)
@ -534,19 +509,10 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
break;
#endif
#ifdef HAVE_CAMELLIA
case ENCR_CAMELLIA_CBC:
break;
#endif
#ifndef NO_DES3
case ENCR_3DES:
ret = wc_Des3Init(&this->cipher.des3, NULL, INVALID_DEVID);
break;
case ENCR_DES:
#ifdef WOLFSSL_DES_ECB
case ENCR_DES_ECB:
#endif
break;
#endif
default:
break;
@ -558,7 +524,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
}
this->key = chunk_alloc(key_size);
this->salt = chunk_alloc(salt_len);
return &this->public;
}

View File

@ -33,7 +33,7 @@ typedef struct wolfssl_crypter_t wolfssl_crypter_t;
#include <crypto/crypters/crypter.h>
/**
* Implementation of crypters using wolfssl.
* Implementation of crypters using wolfSSL.
*/
struct wolfssl_crypter_t {
@ -51,6 +51,6 @@ struct wolfssl_crypter_t {
* @return wolfssl_crypter_t, NULL if not supported
*/
wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
size_t key_size);
size_t key_size);
#endif /** WOLFSSL_CRYPTER_H_ @}*/

View File

@ -37,6 +37,7 @@ 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.
*/
@ -52,11 +53,6 @@ struct private_wolfssl_diffie_hellman_t {
*/
DhKey dh;
/**
* Random number generator to use with RSA operations.
*/
WC_RNG rng;
/**
* Length of public values
*/
@ -76,41 +72,26 @@ struct private_wolfssl_diffie_hellman_t {
* Shared secret
*/
chunk_t shared_secret;
/**
* True if shared secret is computed
*/
bool computed;
};
METHOD(diffie_hellman_t, get_my_public_value, bool,
private_wolfssl_diffie_hellman_t *this, chunk_t *value)
{
/* Front pad the value with zeros to length of prime */
*value = chunk_alloc(this->len);
memset(value->ptr, 0, value->len - this->pub.len);
memcpy(value->ptr + value->len - this->pub.len, this->pub.ptr,
this->pub.len);
*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->computed)
if (!this->shared_secret.len)
{
return FALSE;
}
/* Front pad with zeros to length of prime */
*secret = chunk_alloc(this->len);
memset(secret->ptr, 0, secret->len);
memcpy(secret->ptr + secret->len - this->shared_secret.len,
this->shared_secret.ptr, this->shared_secret.len);
*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)
{
@ -122,17 +103,15 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
}
chunk_clear(&this->shared_secret);
this->shared_secret.ptr = malloc(this->len);
memset(this->shared_secret.ptr, 0xFF, this->shared_secret.len);
len = this->shared_secret.len;
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;
this->computed = TRUE;
return TRUE;
}
@ -142,18 +121,17 @@ METHOD(diffie_hellman_t, set_private_value, bool,
bool success = FALSE;
chunk_t g;
word32 len;
int ret;
chunk_clear(&this->priv);
this->priv = chunk_clone(value);
/* Calculate public value - g^priv mod p */
/* calculate public value - g^priv mod p */
if (wolfssl_mp2chunk(&this->dh.g, &g))
{
len = this->pub.len;
ret = wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
this->priv.len, g.ptr, g.len);
if (ret == 0) {
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;
}
@ -169,31 +147,9 @@ METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
return this->group;
}
/**
* Lookup the modulus in modulo table
*/
static status_t set_modulus(private_wolfssl_diffie_hellman_t *this)
{
diffie_hellman_params_t *params = diffie_hellman_get_params(this->group);
if (!params)
{
return NOT_FOUND;
}
this->len = params->prime.len;
if (wc_DhSetKey(&this->dh, params->prime.ptr, params->prime.len,
params->generator.ptr, params->generator.len) != 0)
{
return FAILED;
}
return SUCCESS;
}
METHOD(diffie_hellman_t, destroy, void,
private_wolfssl_diffie_hellman_t *this)
{
wc_FreeRng(&this->rng);
wc_FreeDhKey(&this->dh);
chunk_clear(&this->pub);
chunk_clear(&this->priv);
@ -241,14 +197,15 @@ static int wolfssl_priv_key_size(int len)
return len / 20;
}
/*
* Described in header.
/**
* Generic internal constructor
*/
wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
diffie_hellman_group_t group, ...)
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 = {
@ -261,47 +218,26 @@ wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
.destroy = _destroy,
},
},
.group = group,
.len = p.len,
);
if (wc_InitRng(&this->rng) != 0)
{
free(this);
return NULL;
}
if (wc_InitDhKey(&this->dh) != 0)
{
wc_FreeRng(&this->rng);
free(this);
return NULL;
}
this->group = group;
this->computed = FALSE;
this->priv = chunk_empty;
this->pub = chunk_empty;
this->shared_secret = chunk_empty;
if (group == MODP_CUSTOM)
if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
{
chunk_t g, p;
VA_ARGS_GET(group, g, p);
this->len = p.len;
if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
{
destroy(this);
return NULL;
}
destroy(this);
return NULL;
}
else
if (wc_InitRng(&rng) != 0)
{
/* find a modulus according to group */
if (set_modulus(this) != SUCCESS)
{
destroy(this);
return NULL;
}
destroy(this);
return NULL;
}
this->priv = chunk_alloc(wolfssl_priv_key_size(this->len));
@ -309,16 +245,41 @@ wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
privLen = this->priv.len;
pubLen = this->pub.len;
/* generate my public and private values */
if (wc_DhGenerateKeyPair(&this->dh, &this->rng, this->priv.ptr, &privLen,
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 */

View File

@ -62,25 +62,10 @@ struct private_wolfssl_ec_diffie_hellman_t {
*/
ecc_key key;
/**
* Other public key
*/
ecc_point *pub_key;
/**
* Shared secret
*/
chunk_t shared_secret;
/**
* Random number generator
*/
WC_RNG rng;
/**
* True if shared secret is computed
*/
bool computed;
};
/**
@ -90,9 +75,13 @@ struct private_wolfssl_ec_diffie_hellman_t {
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;
}
@ -113,23 +102,20 @@ static bool ecp2chunk(int keysize, ecc_point *point, chunk_t *chunk,
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)
ecc_point *point, ecc_point *r)
{
int ret;
mp_int a, prime;
int ret;
ret = mp_init(&a);
if (ret != 0)
if (mp_init(&a) != 0)
{
return FALSE;
}
ret = mp_init(&prime);
if (ret != 0)
if (mp_init(&prime) != 0)
{
mp_free(&a);
return FALSE;
@ -142,7 +128,7 @@ static bool wolfssl_ecc_multiply(const ecc_set_type *ecc_set, mp_int *scalar,
}
if (ret == 0)
{
/* Multiply the point by our secret */
/* multiply the point by our secret */
ret = wc_ecc_mulmod(scalar, point, r, &a, &prime, 1);
}
@ -164,24 +150,24 @@ static bool wolfssl_ecc_multiply(const ecc_set_type *ecc_set, mp_int *scalar,
* Diffie-Hellman public value."
*/
static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this,
chunk_t *shared_secret)
ecc_point *pub_key, chunk_t *shared_secret)
{
bool success = FALSE;
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, this->pub_key, secret))
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
*/
* 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,
@ -195,26 +181,35 @@ static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this,
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 (!chunk2ecp(value, this->pub_key))
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, &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;
}
this->computed = TRUE;
wc_ecc_del_point(pub_key);
return TRUE;
}
@ -237,7 +232,7 @@ METHOD(diffie_hellman_t, set_private_value, bool,
}
ret = mp_read_unsigned_bin(&this->key.k, value.ptr, value.len);
/* Get base point */
/* get base point */
if (ret == 0)
{
ret = mp_read_radix(base->x, this->key.dp->Gx, MP_RADIX_HEX);
@ -252,7 +247,7 @@ METHOD(diffie_hellman_t, set_private_value, bool,
}
if (ret == 0)
{
/* Calculate public key */
/* calculate public key */
success = wolfssl_ecc_multiply(this->key.dp, &this->key.k, base,
&this->key.pubkey);
}
@ -265,7 +260,7 @@ METHOD(diffie_hellman_t, set_private_value, bool,
METHOD(diffie_hellman_t, get_shared_secret, bool,
private_wolfssl_ec_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
if (!this->shared_secret.len)
{
return FALSE;
}
@ -282,19 +277,18 @@ METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
METHOD(diffie_hellman_t, destroy, void,
private_wolfssl_ec_diffie_hellman_t *this)
{
wc_FreeRng(&this->rng);
wc_ecc_del_point(this->pub_key);
wc_ecc_free(&this->key);
chunk_clear(&this->shared_secret);
free(this);
}
/*
* Described in header.
* 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 = {
@ -316,21 +310,6 @@ wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(diffie_hellman_gro
free(this);
return NULL;
}
if ((this->pub_key = wc_ecc_new_point()) == NULL)
{
wc_ecc_free(&this->key);
DBG1(DBG_LIB, "pub_key init failed, ecdh create failed");
free(this);
return NULL;
}
if (wc_InitRng(&this->rng) != 0)
{
wc_ecc_del_point(this->pub_key);
wc_ecc_free(&this->key);
DBG1(DBG_LIB, "RNG init failed, ecdh create failed");
free(this);
return NULL;
}
switch (group)
{
@ -373,20 +352,27 @@ wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(diffie_hellman_gro
break;
#endif
default:
DBG1(DBG_LIB, "EC group not supported");
destroy(this);
return NULL;
}
/* generate an EC private (public) key */
if (wc_ecc_make_key_ex(&this->rng, this->keysize, &this->key,
this->curve_id) != 0)
if (wc_InitRng(&rng) != 0)
{
DBG1(DBG_LIB, "Make key failed, wolfssl ECDH create failed");
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 */

View File

@ -47,9 +47,10 @@ struct wolfssl_ec_diffie_hellman_t {
* 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
* @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);
wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(
diffie_hellman_group_t group);
#endif /** WOLFSSL_EC_DIFFIE_HELLMAN_H_ @}*/

View File

@ -34,7 +34,7 @@
#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;
@ -42,8 +42,9 @@ 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 for this signer.
* Public interface
*/
wolfssl_ec_private_key_t public;
@ -63,7 +64,7 @@ struct private_wolfssl_ec_private_key_t {
WC_RNG rng;
/**
* reference count
* Reference count
*/
refcount_t ref;
};
@ -97,7 +98,6 @@ static bool build_signature(private_wolfssl_ec_private_key_t *this,
mp_free(&s);
mp_free(&r);
return success;
}
@ -105,16 +105,17 @@ static bool build_signature(private_wolfssl_ec_private_key_t *this,
* 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)
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 = 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);
signature_scheme_names, scheme);
return FALSE;
}
if (wolfssl_hash_chunk(hash, data, &dgst))
@ -129,20 +130,19 @@ static bool build_curve_signature(private_wolfssl_ec_private_key_t *this,
* 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)
enum wc_HashType hash, chunk_t data,
chunk_t *signature)
{
bool success = FALSE;
chunk_t dgst = chunk_empty;
int ret;
bool success = FALSE;
word32 len;
if (wolfssl_hash_chunk(hash, data, &dgst))
{
*signature = chunk_alloc(this->ec.dp->size * 2 + 10);
*signature = chunk_alloc(wc_ecc_sig_size(&this->ec));
len = signature->len;
ret = wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len,
&this->rng, &this->ec);
if (ret == 0)
if (wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len,
&this->rng, &this->ec) == 0)
{
signature->len = len;
success = TRUE;
@ -152,7 +152,6 @@ static bool build_der_signature(private_wolfssl_ec_private_key_t *this,
chunk_free(signature);
}
}
chunk_free(&dgst);
return success;
}
@ -165,40 +164,40 @@ METHOD(private_key_t, sign, bool,
{
case SIGN_ECDSA_WITH_NULL:
return build_signature(this, data, signature);
#ifndef NO_SHA
#ifndef NO_SHA
case SIGN_ECDSA_WITH_SHA1_DER:
return build_der_signature(this, WC_HASH_TYPE_SHA, data, signature);
#endif
#ifndef NO_SHA256
#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
#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
#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
#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
#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
#endif
#ifdef WOLFSSL_SHA512
case SIGN_ECDSA_521:
return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
ECC_SECP521R1, data, signature);
#endif
#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported",
signature_scheme_names, scheme);
@ -231,16 +230,18 @@ METHOD(private_key_t, get_public_key, public_key_t*,
{
public_key_t *public;
chunk_t key;
int ret;
int len;
key = chunk_alloc((this->keysize + 7) / 8 * 5);
ret = wc_EccPublicKeyToDer(&this->ec, key.ptr, key.len, 1);
if (ret < 0)
/* 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 = ret;
key.len = len;
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
BUILD_BLOB_ASN1_DER, key, BUILD_END);
@ -259,20 +260,23 @@ 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:
{
bool success = TRUE;
*encoding = chunk_alloc(this->keysize * 4 + 30);
if (wc_EccPrivateKeyToDer(&this->ec, encoding->ptr,
encoding->len) < 0)
/* 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)
{
@ -284,7 +288,6 @@ METHOD(private_key_t, get_encoding, bool,
chunk_clear(&asn1_encoding);
}
return success;
}
default:
return FALSE;
}
@ -338,16 +341,15 @@ static private_wolfssl_ec_private_key_t *create_empty(void)
if (wc_InitRng(&this->rng) < 0)
{
DBG1(DBG_LIB, "Random number generation init failed");
DBG1(DBG_LIB, "RNG init failed");
free(this);
return NULL;
}
return this;
}
/*
* See header.
* Described in header
*/
wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
va_list args)
@ -375,6 +377,11 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
return NULL;
}
this = create_empty();
if (!this)
{
return NULL;
}
this->keysize = key_size;
switch (key_size)
{
@ -396,25 +403,23 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
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", key_size);
DBG1(DBG_LIB, "EC private key generation failed");
destroy(this);
return NULL;
}
return &this->public;
}
/**
* See header.
/*
* 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;
chunk_t key = chunk_empty;
chunk_t alg_id = chunk_empty;
chunk_t params = chunk_empty, key = chunk_empty;
word32 idx;
int oid;
int oid = OID_UNKNOWN;
while (TRUE)
{
@ -433,12 +438,15 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
}
break;
}
if (key.ptr == NULL)
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)
@ -463,9 +471,7 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
if (params.ptr)
{
/* if ECParameters is passed, check we guessed correct */
alg_id = asn1_algorithmIdentifier_params(OID_EC_PUBLICKEY,
chunk_clone(params));
/* if ECParameters is passed, ensure we guessed correctly */
if (asn1_unwrap(&params, &params) == ASN1_OID)
{
oid = asn1_known_oid(params);
@ -494,7 +500,6 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
break;
}
}
chunk_free(&alg_id);
if (oid == OID_UNKNOWN)
{
DBG1(DBG_LIB, "parameters do not match private key data");
@ -502,7 +507,7 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
return NULL;
}
}
return &this->public;
}
#endif /* HAVE_ECC_SIGN */

View File

@ -31,7 +31,7 @@
#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;
@ -39,8 +39,9 @@ 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 for this signer.
* Public interface
*/
wolfssl_ec_public_key_t public;
@ -55,7 +56,7 @@ struct private_wolfssl_ec_public_key_t {
ecc_key ec;
/**
* reference counter
* Reference count
*/
refcount_t ref;
};
@ -66,8 +67,7 @@ struct private_wolfssl_ec_public_key_t {
static bool verify_signature(private_wolfssl_ec_public_key_t *this,
chunk_t hash, chunk_t signature)
{
int stat = 1;
int ret = -1;
int stat = 1, ret = -1;
mp_int r, s;
if (mp_init(&r) < 0)
@ -85,10 +85,8 @@ static bool verify_signature(private_wolfssl_ec_public_key_t *this,
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;
}
@ -96,8 +94,9 @@ static bool verify_signature(private_wolfssl_ec_public_key_t *this,
* 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)
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;
@ -122,30 +121,20 @@ static bool verify_curve_signature(private_wolfssl_ec_public_key_t *this,
* 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)
enum wc_HashType hash, chunk_t data,
chunk_t signature)
{
bool success = FALSE;
chunk_t dgst;
int stat = 1;
int ret;
int stat = 1, ret = -1;
/* remove any preceding 0-bytes from signature */
while (signature.len && signature.ptr[0] == 0x00)
{
signature = chunk_skip(signature, 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);
if (ret == 0 && stat == 1)
{
success = TRUE;
}
}
chunk_free(&dgst);
return success;
return ret == 0 && stat == 1;
}
METHOD(public_key_t, get_type, key_type_t,
@ -160,45 +149,45 @@ METHOD(public_key_t, verify, bool,
{
switch (scheme)
{
#ifndef NO_SHA
#ifndef NO_SHA
case SIGN_ECDSA_WITH_SHA1_DER:
return verify_der_signature(this, WC_HASH_TYPE_SHA, data,
signature);
#endif
#ifndef NO_SHA256
#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
#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
#endif
#ifdef WOLFSSL_SHA512
case SIGN_ECDSA_WITH_SHA512_DER:
return verify_der_signature(this, WC_HASH_TYPE_SHA512, data,
signature);
#endif
#endif
case SIGN_ECDSA_WITH_NULL:
return verify_signature(this, data, signature);
#ifndef NO_SHA256
#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
#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
#endif
#ifdef WOLFSSL_SHA512
case SIGN_ECDSA_521:
return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
ECC_SECP521R1, data, signature);
#endif
#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in EC",
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
signature_scheme_names, scheme);
return FALSE;
}
@ -219,51 +208,51 @@ METHOD(public_key_t, get_keysize, int,
}
/**
* Calculate fingerprint from a EC_KEY, also used in ec private key.
* 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 ret;
bool success;
int len;
if (lib->encoding->get_cache(lib->encoding, type, ec, fp))
{
return TRUE;
}
key = chunk_alloc(ec->dp->size * 4 + 30);
ret = wc_EccPublicKeyToDer(ec, key.ptr, key.len, 1);
if (ret < 0)
{
free(key.ptr);
return FALSE;
}
key.len = ret;
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:
success = lib->encoding->encode(lib->encoding, type, ec, fp,
CRED_PART_ECDSA_PUB_ASN1_DER, key,
CRED_PART_END);
chunk_free(&key);
return success;
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 hash algorithm not supported, fingerprinting failed");
DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
DESTROY_IF(hasher);
free(key.ptr);
return FALSE;
}
hasher->destroy(hasher);
free(key.ptr);
lib->encoding->cache(lib->encoding, type, ec, *fp);
return TRUE;
}
@ -280,18 +269,20 @@ METHOD(public_key_t, get_encoding, bool,
chunk_t *encoding)
{
bool success = TRUE;
int ret;
int len;
*encoding = chunk_alloc(this->ec.dp->size * 2 + 30);
ret = wc_EccPublicKeyToDer(&this->ec, encoding->ptr, encoding->len, 1);
if (ret < 0)
/* 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 = ret;
encoding->len = len;
if (type != PUBKEY_ASN1_DER)
if (type != PUBKEY_SPKI_ASN1_DER)
{
chunk_t asn1_encoding = *encoding;
@ -351,12 +342,11 @@ static private_wolfssl_ec_public_key_t *create_empty()
free(this);
return NULL;
}
return this;
}
/**
* See header.
/*
* Described in header
*/
wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
va_list args)
@ -366,11 +356,6 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
word32 idx;
int ret;
if (type != KEY_ECDSA)
{
return NULL;
}
while (TRUE)
{
switch (va_arg(args, builder_part_t))
@ -386,6 +371,11 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
break;
}
this = create_empty();
if (!this)
{
return NULL;
}
idx = 0;
ret = wc_EccPublicKeyDecode(blob.ptr, &idx, &this->ec, blob.len);
if (ret < 0)
@ -409,5 +399,5 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
}
return &this->public;
}
#endif /* HAVE_ECC_VERIFY */
#endif /* HAVE_ECC_VERIFY */

View File

@ -29,6 +29,7 @@
#include <utils/debug.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/asn.h>
typedef struct private_private_key_t private_private_key_t;
@ -48,17 +49,11 @@ struct private_private_key_t {
ed25519_key key;
/**
* Key type
*/
key_type_t type;
/**
* reference count
* Reference count
*/
refcount_t ref;
};
/* from ed public key */
bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
chunk_t *fp);
@ -68,17 +63,17 @@ METHOD(private_key_t, sign, bool,
void *params, chunk_t data, chunk_t *signature)
{
word32 len;
int ret;
byte dummy[1];
int ret;
if (this->type == KEY_ED25519 && scheme != SIGN_ED25519)
if (scheme != SIGN_ED25519)
{
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
signature_scheme_names, scheme, key_type_names, this->type);
signature_scheme_names, scheme, key_type_names, KEY_ED25519);
return FALSE;
}
if (data.ptr == NULL && data.len == 0)
if (!data.ptr && !data.len)
{
data.ptr = dummy;
}
@ -86,7 +81,7 @@ METHOD(private_key_t, sign, bool,
len = ED25519_SIG_SIZE;
*signature = chunk_alloc(len);
ret = wc_ed25519_sign_msg(data.ptr, data.len, signature->ptr, &len,
&this->key);
&this->key);
return ret == 0;
}
@ -107,7 +102,7 @@ METHOD(private_key_t, get_keysize, int,
METHOD(private_key_t, get_type, key_type_t,
private_private_key_t *this)
{
return this->type;
return KEY_ED25519;
}
METHOD(private_key_t, get_public_key, public_key_t*,
@ -117,14 +112,12 @@ METHOD(private_key_t, get_public_key, public_key_t*,
chunk_t key;
word32 len = ED25519_PUB_KEY_SIZE;
/* Allocate on stack */
key = chunk_alloca(len);
if (wc_ed25519_export_public(&this->key, key.ptr, &len) != 0)
{
chunk_free(&key);
return NULL;
}
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type,
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
BUILD_EDDSA_PUB, key, BUILD_END);
return public;
}
@ -148,7 +141,9 @@ METHOD(private_key_t, get_encoding, bool,
{
bool success = TRUE;
*encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 20);
/* +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)
@ -195,7 +190,7 @@ METHOD(private_key_t, destroy, void,
/**
* Internal generic constructor
*/
static private_private_key_t *create_internal(key_type_t type)
static private_private_key_t *create_internal()
{
private_private_key_t *this;
@ -214,7 +209,6 @@ static private_private_key_t *create_internal(key_type_t type)
.get_ref = _get_ref,
.destroy = _destroy,
},
.type = type,
.ref = 1,
);
@ -235,12 +229,6 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args)
WC_RNG rng;
int ret;
if (wc_InitRng(&rng) != 0)
{
DBG1(DBG_LIB, "initializing random failed");
return NULL;
}
while (TRUE)
{
switch (va_arg(args, builder_part_t))
@ -257,31 +245,52 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args)
break;
}
switch (type)
{
case KEY_ED25519:
break;
default:
return NULL;
}
this = create_internal(type);
if (this == NULL)
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
*/
@ -309,40 +318,31 @@ private_key_t *wolfssl_ed_private_key_load(key_type_t type, va_list args)
}
break;
}
this = create_internal(type);
if (this == NULL)
this = create_internal();
if (!this)
{
return NULL;
}
if (priv.len)
{
/* Check for ASN.1 wrapped key (Octet String == 0x04) */
/* 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);
if (ret == 0)
{
ret = wc_ed25519_make_public(&this->key, this->key.p,
ED25519_PUB_KEY_SIZE);
}
if (ret == 0)
{
/* Fix internal state now public key set */
memmove(this->key.k + ED25519_KEY_SIZE, this->key.p,
ED25519_PUB_KEY_SIZE);
this->key.pubKeySet = 1;
}
}
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);

View File

@ -27,8 +27,10 @@
#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;
@ -48,39 +50,32 @@ struct private_public_key_t {
ed25519_key key;
/**
* Key type
*/
key_type_t type;
/**
* Reference counter
* Reference count
*/
refcount_t ref;
};
METHOD(public_key_t, get_type, key_type_t,
private_public_key_t *this)
{
return this->type;
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)
{
int ret;
int res;
byte dummy[1];
int ret, res;
if (this->type == KEY_ED25519 && scheme != SIGN_ED25519)
if (scheme != SIGN_ED25519)
{
DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
signature_scheme_names, scheme, key_type_names, this->type);
signature_scheme_names, scheme, key_type_names, KEY_ED25519);
return FALSE;
}
if (data.ptr == NULL && data.len == 0)
if (!data.ptr && !data.len)
{
data.ptr = dummy;
}
@ -105,6 +100,25 @@ METHOD(public_key_t, get_keysize, int,
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.
*/
@ -114,7 +128,7 @@ bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
hasher_t *hasher;
chunk_t blob;
word32 len;
int ret;
bool success = FALSE;
if (lib->encoding->get_cache(lib->encoding, type, key, fp))
{
@ -124,21 +138,17 @@ bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
{
case KEYID_PUBKEY_SHA1:
len = ED25519_PUB_KEY_SIZE;
blob = chunk_alloca(len);
blob = chunk_alloc(len);
if (wc_ed25519_export_public(key, blob.ptr, &len) != 0)
{
return FALSE;
}
break;
case KEYID_PUBKEY_INFO_SHA1:
len = ED25519_PUB_KEY_SIZE + 40;
blob = chunk_alloca(len);
ret = wc_Ed25519PublicKeyToDer(key, blob.ptr, blob.len, 1);
if (ret < 0)
if (!encode_pubkey(key, &blob))
{
return FALSE;
}
blob.len = ret;
break;
default:
return FALSE;
@ -147,12 +157,15 @@ bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
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;
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,
@ -165,15 +178,11 @@ METHOD(public_key_t, get_encoding, bool,
private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
bool success = TRUE;
int ret;
*encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 32);
ret = wc_Ed25519PublicKeyToDer(&this->key, encoding->ptr, encoding->len, 1);
if (ret < 0)
if (!encode_pubkey(&this->key, encoding))
{
return FALSE;
}
encoding->len = ret;
if (type != PUBKEY_SPKI_ASN1_DER)
{
@ -182,7 +191,7 @@ METHOD(public_key_t, get_encoding, bool,
success = lib->encoding->encode(lib->encoding, type,
NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER,
asn1_encoding, CRED_PART_END);
chunk_clear(&asn1_encoding);
chunk_free(&asn1_encoding);
}
return success;
}
@ -208,7 +217,7 @@ METHOD(public_key_t, destroy, void,
/**
* Generic private constructor
*/
static private_public_key_t *create_empty(key_type_t type)
static private_public_key_t *create_empty()
{
private_public_key_t *this;
@ -225,15 +234,14 @@ static private_public_key_t *create_empty(key_type_t type)
.get_ref = _get_ref,
.destroy = _destroy,
},
.type = type,
.ref = 1,
);
if (wc_ed25519_init(&this->key) != 0)
{
free(this);
return NULL;
}
return this;
}
@ -265,8 +273,8 @@ public_key_t *wolfssl_ed_public_key_load(key_type_t type, va_list args)
break;
}
this = create_empty(type);
if (this == NULL)
this = create_empty();
if (!this)
{
return NULL;
}

View File

@ -34,17 +34,17 @@ typedef struct private_wolfssl_hasher_t private_wolfssl_hasher_t;
struct private_wolfssl_hasher_t {
/**
* Public part of this class.
* Public interface
*/
wolfssl_hasher_t public;
/**
* the hasher to use
* The hasher to use
*/
wc_HashAlg hasher;
/**
* the hash algiorithm
* The hash algorithm
*/
enum wc_HashType type;
};
@ -128,6 +128,5 @@ wolfssl_hasher_t *wolfssl_hasher_create(hash_algorithm_t algo)
destroy(this);
return NULL;
}
return &this->public;
}

View File

@ -77,10 +77,10 @@ METHOD(mac_t, get_mac, bool,
if (this->key_set)
{
ret = wc_HmacUpdate(&this->hmac, data.ptr, data.len);
}
if (ret == 0 && out != NULL)
{
ret = wc_HmacFinal(&this->hmac, out);
if (ret == 0 && out)
{
ret = wc_HmacFinal(&this->hmac, out);
}
}
return ret == 0;
}
@ -121,14 +121,12 @@ static mac_t *hmac_create(hash_algorithm_t algo)
.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;
}

View File

@ -45,21 +45,19 @@
#define FIPS_MODE 0
#endif
typedef struct private_wolfssl_plugin_t private_wolfssl_plugin_t;
/**
* private data of wolfssl_plugin
* Private data of wolfssl_plugin
*/
struct private_wolfssl_plugin_t {
/**
* public functions
* Public interface
*/
wolfssl_plugin_t public;
};
METHOD(plugin_t, get_name, char*,
private_wolfssl_plugin_t *this)
{
@ -424,30 +422,29 @@ METHOD(plugin_t, destroy, void,
}
/*
* see header file
* Described in header
*/
plugin_t *wolfssl_plugin_create()
{
private_wolfssl_plugin_t *this;
int fips_mode;
bool fips_mode;
fips_mode = lib->settings->get_int(lib->settings,
"%s.plugins.wolfssl.fips_mode", FIPS_MODE, lib->ns);
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();
int ret = wolfCrypt_GetStatus_fips();
if (ret != 0)
{
DBG1(DBG_LIB, "wolfssl FIPS mode(%d) unavailable (%d)", fips_mode,
ret);
DBG1(DBG_LIB, "wolfssl FIPS mode unavailable (%d)", ret);
return NULL;
}
}
#else
if (fips_mode)
{
DBG1(DBG_LIB, "wolfssl FIPS mode(%d) unavailable", fips_mode);
DBG1(DBG_LIB, "wolfssl FIPS mode unavailable");
return NULL;
}
#endif

View File

@ -37,7 +37,7 @@ typedef struct private_wolfssl_rng_t private_wolfssl_rng_t;
wolfSSL_Mutex globalRngMutex;
#endif
static WC_RNG globalRng;
static int globalRngInit = 0;
static bool globalRngInit;
/**
* Private data of wolfssl_rng_t
@ -67,7 +67,7 @@ METHOD(rng_t, get_bytes, bool,
ret = wc_LockMutex(&globalRngMutex);
if (ret != 0)
{
DBG1(DBG_LIB, "Locking failed, get bytes failed");
DBG1(DBG_LIB, "locking failed, get bytes failed");
return FALSE;
}
}
@ -107,7 +107,7 @@ METHOD(rng_t, destroy, void,
}
/*
* Described in header.
* Described in header
*/
wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
{
@ -129,7 +129,7 @@ wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
this->rng = malloc(sizeof(*this->rng));
if (wc_InitRng(this->rng) != 0)
{
DBG1(DBG_LIB, "Init RNG failed, rng create failed");
DBG1(DBG_LIB, "init RNG failed, rng create failed");
free(this->rng);
free(this);
return NULL;
@ -139,7 +139,7 @@ wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
}
/*
* Described in header.
* Described in header
*/
int wolfssl_rng_global_init()
{
@ -150,25 +150,24 @@ int wolfssl_rng_global_init()
ret = wc_InitRng(&globalRng);
if (ret != 0)
{
DBG1(DBG_LIB, "Init RNG failed, rng global init failed");
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");
DBG1(DBG_LIB, "init Mutex failed, rng global init failed");
}
#endif
else
{
globalRngInit = 1;
globalRngInit = TRUE;
}
}
return ret == 0;
}
/*
* Described in header.
* Described in header
*/
void wolfssl_rng_global_final()
{
@ -178,7 +177,7 @@ void wolfssl_rng_global_final()
wc_FreeMutex(&globalRngMutex);
#endif
wc_FreeRng(&globalRng);
globalRngInit = 0;
globalRngInit = FALSE;
}
}

View File

@ -28,20 +28,22 @@
#include "wolfssl_rsa_public_key.h"
#include "wolfssl_util.h"
#include <crypto/hashers/hasher.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.
* Private data of a wolfssl_rsa_private_key_t object
*/
struct private_wolfssl_rsa_private_key_t {
/**
* Public interface for this signer.
* Public interface
*/
wolfssl_rsa_private_key_t public;
@ -56,15 +58,15 @@ struct private_wolfssl_rsa_private_key_t {
WC_RNG rng;
/**
* reference count
* 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
*/
@ -88,8 +90,8 @@ static bool build_emsa_pkcs1_signature(private_wolfssl_rsa_private_key_t *this,
chunk_t *sig)
{
bool success = FALSE;
chunk_t dgst, encDgst;
int ret;
chunk_t dgst, digestInfo;
int len;
*sig = chunk_alloc(wc_RsaEncryptSize(&this->rsa));
@ -99,16 +101,15 @@ static bool build_emsa_pkcs1_signature(private_wolfssl_rsa_private_key_t *this,
}
else if (wolfssl_hash_chunk(hash, data, &dgst))
{
encDgst = chunk_alloc(dgst.len + 20);
ret = wc_EncodeSignature(encDgst.ptr, dgst.ptr, dgst.len,
digestInfo = chunk_alloc(MAX_DER_DIGEST_SZ);
len = wc_EncodeSignature(digestInfo.ptr, dgst.ptr, dgst.len,
wc_HashGetOID(hash));
if (ret > 0)
if (len > 0)
{
encDgst.len = ret;
success = build_signature(this, hash, encDgst, sig);
digestInfo.len = len;
success = build_signature(this, hash, digestInfo, sig);
}
chunk_free(&encDgst);
chunk_free(&digestInfo);
chunk_free(&dgst);
}
@ -130,8 +131,7 @@ static bool build_emsa_pss_signature(private_wolfssl_rsa_private_key_t *this,
bool success = FALSE;
chunk_t dgst = chunk_empty;
enum wc_HashType hash;
int mgf;
int ret;
int mgf, ret;
if (!wolfssl_hash2type(params->hash, &hash))
{
@ -215,7 +215,7 @@ METHOD(private_key_t, sign, bool,
return build_emsa_pss_signature(this, params, data, signature);
#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
signature_scheme_names, scheme);
return FALSE;
}
@ -227,7 +227,6 @@ METHOD(private_key_t, decrypt, bool,
{
int padding, mgf, len;
enum wc_HashType hash;
char *decrypted;
switch (scheme)
{
@ -279,16 +278,16 @@ METHOD(private_key_t, decrypt, bool,
return FALSE;
}
len = wc_RsaEncryptSize(&this->rsa);
decrypted = malloc(len);
len = wc_RsaPrivateDecrypt_ex(crypto.ptr, crypto.len, decrypted, len,
*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");
free(decrypted);
chunk_free(plain);
return FALSE;
}
*plain = chunk_create(decrypted, len);
plain->len = len;
return TRUE;
}
@ -301,15 +300,16 @@ METHOD(private_key_t, get_keysize, int,
METHOD(private_key_t, get_public_key, public_key_t*,
private_wolfssl_rsa_private_key_t *this)
{
chunk_t enc;
public_key_t *key;
int len = wc_RsaEncryptSize(&this->rsa) * 2 + 20;
chunk_t enc;
enc = chunk_alloc(len);
enc.len = wc_RsaKeyToPublicDer(&this->rsa, enc.ptr, len);
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);
free(enc.ptr);
chunk_free(&enc);
return key;
}
@ -330,8 +330,11 @@ METHOD(private_key_t, get_encoding, bool,
case PRIVKEY_PEM:
{
bool success = TRUE;
int len = wc_RsaEncryptSize(&this->rsa) * 5 + 20;
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)
@ -405,13 +408,13 @@ static private_wolfssl_rsa_private_key_t *create_empty()
if (wc_InitRng(&this->rng) != 0)
{
DBG1(DBG_LIB, "Init RNG failed, rsa private key create failed\n");
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\n");
DBG1(DBG_LIB, "init RSA failed, rsa private key create failed");
wc_FreeRng(&this->rng);
free(this);
return NULL;
@ -422,7 +425,7 @@ static private_wolfssl_rsa_private_key_t *create_empty()
}
/*
* See header.
* Described in header
*/
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
va_list args)
@ -450,7 +453,7 @@ wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
}
this = create_empty();
if (this == NULL)
if (!this)
{
return NULL;
}
@ -463,12 +466,14 @@ wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
return &this->public;
}
static bool wolfssl_mp_rand(mp_int* n, WC_RNG* rng, mp_int* r)
/**
* 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;
int ret;
int len, ret;
/* Ensure the number has enough memory. */
/* ensure the number has enough memory. */
ret = mp_set_bit(r, mp_count_bits(n));
if (ret == 0)
{
@ -479,7 +484,6 @@ static bool wolfssl_mp_rand(mp_int* n, WC_RNG* rng, mp_int* r)
{
ret = mp_mod(r, n, r);
}
return ret == 0;
}
@ -492,16 +496,15 @@ static bool calculate_pq(mp_int *n, mp_int *e, mp_int *d, mp_int *p, mp_int *q,
{
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;
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(k, d, e) != 0)
if (mp_mul(d, e, k) != 0)
{
goto error;
}
@ -515,7 +518,7 @@ static bool calculate_pq(mp_int *n, mp_int *e, mp_int *d, mp_int *p, mp_int *q,
goto error;
}
/* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
if (mp_copy(r, k) != 0)
if (mp_copy(k, r) != 0)
{
goto error;
}
@ -562,14 +565,14 @@ static bool calculate_pq(mp_int *n, mp_int *e, mp_int *d, mp_int *p, mp_int *q,
break;
}
/* y = x */
if (mp_copy(y, x) != 0)
if (mp_copy(x, y) != 0)
{
goto error;
}
}
}
goto error;
done:
/* p = gcd(y-1, n) */
if (mp_sub_d(y, 1, y) != 0)
@ -587,7 +590,7 @@ done:
}
success = TRUE;
error:
return success;
}
@ -596,20 +599,12 @@ error:
* Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder
* algorithm.
*/
static int dmodpq1(mp_int *d, mp_int *pq, mp_int *res)
static bool dmodpq1(mp_int *d, mp_int *pq, mp_int *res)
{
/* p|q - 1 */
if (mp_sub_d(pq, 1, res) != 0)
{
return FALSE;
}
/* d (mod p|q -1) */
if (mp_mod(d, res, res) != 0)
{
return FALSE;
}
return TRUE;
/* p|q - 1
* d (mod p|q -1) */
return mp_sub_d(pq, 1, res) == 0 &&
mp_mod(d, res, res) == 0;
}
/**
@ -622,7 +617,7 @@ static int qinv(mp_int *q, mp_int *p, mp_int *res)
}
/*
* See header
* Described in header
*/
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
va_list args)
@ -673,7 +668,7 @@ wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
}
this = create_empty();
if (this == NULL)
if (!this)
{
return NULL;
}
@ -716,7 +711,6 @@ wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
&this->rsa.p, &this->rsa.q, &this->rsa.dP,
&this->rsa.dQ, &this->rng))
{
DBG1(DBG_LIB, "calculate pq failed, rsa private key load failed\n");
goto error;
}
if (exp1.ptr)

View File

@ -27,21 +27,23 @@
#include "wolfssl_rsa_public_key.h"
#include "wolfssl_util.h"
#include <crypto/hashers/hasher.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 structure with signing context.
* Private data
*/
struct private_wolfssl_rsa_public_key_t {
/**
* Public interface for this signer.
* Public interface
*/
wolfssl_rsa_public_key_t public;
@ -56,12 +58,11 @@ struct private_wolfssl_rsa_public_key_t {
WC_RNG rng;
/**
* reference counter
* Reference counter
*/
refcount_t ref;
};
/**
* Verify RSA signature
*/
@ -70,7 +71,7 @@ static bool verify_signature(private_wolfssl_rsa_public_key_t *this,
{
bool success = FALSE;
int len = wc_RsaEncryptSize(&this->rsa);
u_char *buf;
chunk_t padded;
u_char *p;
if (signature.len > len)
@ -78,17 +79,13 @@ static bool verify_signature(private_wolfssl_rsa_public_key_t *this,
signature = chunk_skip(signature, signature.len - len);
}
buf = malloc(len);
memcpy(buf + len - signature.len, signature.ptr, signature.len);
memset(buf, 0, len - signature.len);
padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00);
len = wc_RsaSSL_VerifyInline(buf, len, &p, &this->rsa);
len = wc_RsaSSL_VerifyInline(padded.ptr, len, &p, &this->rsa);
if (len > 0)
{
success = chunk_equals_const(data, chunk_create(p, len));
}
free(buf);
return success;
}
@ -99,24 +96,23 @@ 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;
chunk_t dgst = chunk_empty, encDgst;
int len;
encDgst = chunk_alloc(wc_HashGetDigestSize(hash) + 20);
if (wolfssl_hash_chunk(hash, data, &dgst))
{
len = wc_EncodeSignature(encDgst.ptr, dgst.ptr, dgst.len,
digestInfo = chunk_alloc(MAX_DER_DIGEST_SZ);
len = wc_EncodeSignature(digestInfo.ptr, dgst.ptr, dgst.len,
wc_HashGetOID(hash));
if (len > 0)
{
encDgst.len = len;
success = verify_signature(this, encDgst, signature);
digestInfo.len = len;
success = verify_signature(this, digestInfo, signature);
}
chunk_free(&digestInfo);
chunk_free(&dgst);
}
chunk_free(&encDgst);
chunk_free(&dgst);
return success;
}
@ -128,13 +124,11 @@ 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 = chunk_empty;
chunk_t dgst, padded;
enum wc_HashType hash;
int mgf;
bool success = FALSE;
int len = 0;
u_char *buf = NULL;
u_char *p;
int mgf, len = 0;
bool success = FALSE;
if (!wolfssl_hash2type(params->hash, &hash))
{
@ -144,34 +138,25 @@ static bool verify_emsa_pss_signature(private_wolfssl_rsa_public_key_t *this,
{
return FALSE;
}
if (wolfssl_hash_chunk(hash, data, &dgst))
if (!wolfssl_hash_chunk(hash, data, &dgst))
{
len = wc_RsaEncryptSize(&this->rsa);
if (signature.len > len)
{
signature = chunk_skip(signature, signature.len - len);
}
buf = malloc(len);
memcpy(buf + len - signature.len, signature.ptr, signature.len);
memset(buf, 0, len - signature.len);
len = wc_RsaPSS_VerifyInline_ex(buf, 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;
}
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);
if (buf != NULL)
{
free(buf);
}
return success;
}
#endif
@ -213,7 +198,7 @@ METHOD(public_key_t, verify, bool,
return verify_emsa_pss_signature(this, params, data, signature);
#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
signature_scheme_names, scheme);
return FALSE;
}
@ -225,7 +210,6 @@ METHOD(public_key_t, encrypt, bool,
{
int padding, mgf, len;
enum wc_HashType hash;
char *encrypted;
switch (scheme)
{
@ -277,17 +261,17 @@ METHOD(public_key_t, encrypt, bool,
return FALSE;
}
len = wc_RsaEncryptSize(&this->rsa);
encrypted = malloc(len);
len = wc_RsaPublicEncrypt_ex(plain.ptr, plain.len, encrypted, len,
*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");
free(encrypted);
chunk_free(crypto);
return FALSE;
}
*crypto = chunk_create(encrypted, len);
crypto->len = len;
return TRUE;
}
@ -297,6 +281,25 @@ METHOD(public_key_t, get_keysize, int,
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.
*/
@ -305,7 +308,7 @@ bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type,
{
hasher_t *hasher;
chunk_t key;
int len;
bool success = FALSE;
if (lib->encoding->get_cache(lib->encoding, type, rsa, fp))
{
@ -314,45 +317,47 @@ bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type,
switch (type)
{
case KEYID_PUBKEY_SHA1:
len = wc_RsaEncryptSize(rsa) * 2 + 20;
key = chunk_alloc(len);
len = wc_RsaKeyToPublicDer(rsa, key.ptr, len);
break;
default:
{
chunk_t n = chunk_empty, e = chunk_empty;
bool success = FALSE;
if (wolfssl_mp2chunk(&rsa->n, &n) && wolfssl_mp2chunk(&rsa->e, &e))
if (wolfssl_mp2chunk(&rsa->n, &n) &&
wolfssl_mp2chunk(&rsa->e, &e))
{
success = lib->encoding->encode(lib->encoding, type, rsa, fp,
CRED_PART_RSA_MODULUS, n,
CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
key = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_integer("m", n),
asn1_integer("m", e));
}
chunk_free(&n);
chunk_free(&e);
return success;
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;
}
if (len < 0)
{
chunk_free(&key);
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 hash algorithm not supported, fingerprinting failed");
DESTROY_IF(hasher);
free(key.ptr);
return FALSE;
DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
}
free(key.ptr);
hasher->destroy(hasher);
lib->encoding->cache(lib->encoding, type, rsa, *fp);
return TRUE;
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,
@ -366,39 +371,24 @@ 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;
int len;
switch (type)
if (type == PUBKEY_SPKI_ASN1_DER)
{
case PUBKEY_ASN1_DER:
len = wc_RsaEncryptSize(&this->rsa) * 2 + 20;
*encoding = chunk_alloc(len);
len = wc_RsaKeyToPublicDer(&this->rsa, encoding->ptr, len);
if (len < 0)
{
DBG1(DBG_LIB, "Public Der failed, get encoding failed");
chunk_free(encoding);
return FALSE;
}
encoding->len = len;
return TRUE;
default:
{
chunk_t n = chunk_empty, e = chunk_empty;
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;
}
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*,
@ -447,13 +437,13 @@ static private_wolfssl_rsa_public_key_t *create_empty()
if (wc_InitRng(&this->rng) != 0)
{
DBG1(DBG_LIB, "Init RNG, rsa public key load failed");
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, rsa public key load failed");
DBG1(DBG_LIB, "init RSA failed, rsa public key load failed");
wc_FreeRng(&this->rng);
free(this);
return NULL;
@ -461,8 +451,8 @@ static private_wolfssl_rsa_public_key_t *create_empty()
return this;
}
/**
* See header.
/*
* Described in header
*/
wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
va_list args)
@ -494,7 +484,7 @@ wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
}
this = create_empty();
if (this == NULL)
if (!this)
{
return NULL;
}
@ -509,7 +499,6 @@ wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
if (wc_RsaPublicKeyDecode(blob.ptr, &idx, &this->rsa,
blob.len) != 0)
{
DBG1(DBG_LIB, "Public , rsa public key load failed");
destroy(this);
return NULL;
}

View File

@ -37,7 +37,7 @@ typedef struct private_wolfssl_sha1_prf_t private_wolfssl_sha1_prf_t;
struct private_wolfssl_sha1_prf_t {
/**
* Public wolfssl_sha1_prf_t interface.
* Public wolfssl_sha1_prf_t interface
*/
wolfssl_sha1_prf_t public;
@ -65,7 +65,6 @@ METHOD(prf_t, get_bytes, bool,
hash[3] = htonl(this->sha1.digest[3]);
hash[4] = htonl(this->sha1.digest[4]);
}
return TRUE;
}
@ -134,18 +133,13 @@ METHOD(prf_t, destroy, void,
free(this);
}
/**
* See header
/*
* Described in header
*/
wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
{
private_wolfssl_sha1_prf_t *this;
if (algo != PRF_KEYED_SHA1)
{
return NULL;
}
INIT(this,
.public = {
.prf = {
@ -164,7 +158,6 @@ wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
free(this);
return NULL;
}
return &this->public;
}

View File

@ -48,7 +48,7 @@ struct wolfssl_sha1_prf_t {
* Creates a new wolfssl_sha1_prf_t.
*
* @param algo algorithm, must be PRF_KEYED_SHA1
* @return sha1_keyed_prf_tobject
* @return wolfssl_sha1_prf_t object
*/
wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo);

View File

@ -28,8 +28,8 @@
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/rsa.h>
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
{
@ -45,8 +45,8 @@ bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
return TRUE;
}
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
{
@ -63,8 +63,8 @@ bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
return FALSE;
}
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
{
@ -82,12 +82,11 @@ bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
{
ret = mp_read_unsigned_bin(b, chunk.ptr + len, len);
}
return ret == 0;
}
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
{
@ -109,85 +108,84 @@ bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
memset(chunk->ptr + len, 0, len - sz);
ret = mp_to_unsigned_bin(b, chunk->ptr + 2 * len - sz);
}
return ret == 0;
}
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type)
{
switch (hash)
{
#ifndef NO_MD5
#ifndef NO_MD5
case HASH_MD5:
*type = WC_HASH_TYPE_MD5;
break;
#endif
#ifndef NO_SHA
#endif
#ifndef NO_SHA
case HASH_SHA1:
*type = WC_HASH_TYPE_SHA;
break;
#endif
#ifdef WOLFSSL_SHA224
#endif
#ifdef WOLFSSL_SHA224
case HASH_SHA224:
*type = WC_HASH_TYPE_SHA224;
break;
#endif
#ifndef NO_SHA256
#endif
#ifndef NO_SHA256
case HASH_SHA256:
*type = WC_HASH_TYPE_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
#endif
#ifdef WOLFSSL_SHA384
case HASH_SHA384:
*type = WC_HASH_TYPE_SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
#endif
#ifdef WOLFSSL_SHA512
case HASH_SHA512:
*type = WC_HASH_TYPE_SHA512;
break;
#endif
#endif
default:
return FALSE;
}
return TRUE;
}
/**
* Described in header.
/*
* Described in header
*/
bool wolfssl_hash2mgf1(hash_algorithm_t hash, int *mgf1)
{
switch (hash)
{
#ifndef NO_SHA
#ifndef NO_SHA
case HASH_SHA1:
*mgf1 = WC_MGF1SHA1;
break;
#endif
#ifdef WOLFSSL_SHA224
#endif
#ifdef WOLFSSL_SHA224
case HASH_SHA224:
*mgf1 = WC_MGF1SHA224;
break;
#endif
#ifndef NO_SHA256
#endif
#ifndef NO_SHA256
case HASH_SHA256:
*mgf1 = WC_MGF1SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
#endif
#ifdef WOLFSSL_SHA384
case HASH_SHA384:
*mgf1 = WC_MGF1SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
#endif
#ifdef WOLFSSL_SHA512
case HASH_SHA512:
*mgf1 = WC_MGF1SHA512;
break;
#endif
#endif
default:
return FALSE;
}

View File

@ -56,11 +56,6 @@ struct private_diffie_hellman_t {
* Shared secret
*/
chunk_t shared_secret;
/**
* True if shared secret is computed
*/
bool computed;
};
/**
@ -69,8 +64,8 @@ struct private_diffie_hellman_t {
static bool compute_shared_key(private_diffie_hellman_t *this,
curve25519_key *pub, chunk_t *shared_secret)
{
int ret;
word32 len = CURVE25519_KEYSIZE;
int ret;
*shared_secret = chunk_alloc(len);
ret = wc_curve25519_shared_secret_ex(&this->key, pub, shared_secret->ptr,
@ -81,8 +76,8 @@ static bool compute_shared_key(private_diffie_hellman_t *this,
METHOD(diffie_hellman_t, set_other_public_value, bool,
private_diffie_hellman_t *this, chunk_t value)
{
int ret;
curve25519_key pub;
int ret;
if (!diffie_hellman_verify_value(this->group, value))
{
@ -90,7 +85,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
}
ret = wc_curve25519_init(&pub);
if (ret < 0)
if (ret != 0)
{
DBG1(DBG_LIB, "%N public key initialization failed",
diffie_hellman_group_names, this->group);
@ -112,10 +107,10 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
{
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;
}
this->computed = TRUE;
wc_curve25519_free(&pub);
return TRUE;
}
@ -138,13 +133,13 @@ METHOD(diffie_hellman_t, get_my_public_value, bool,
METHOD(diffie_hellman_t, set_private_value, bool,
private_diffie_hellman_t *this, chunk_t value)
{
int ret;
unsigned char basepoint[CURVE25519_KEYSIZE] = {9};
curve25519_key pub;
int len;
u_char basepoint[CURVE25519_KEYSIZE] = {9};
word32 len = CURVE25519_KEYSIZE;
int ret;
ret = wc_curve25519_init(&pub);
/* Create base point for calculating public key */
/* create base point for calculating public key */
if (ret == 0)
{
ret = wc_curve25519_import_public_ex(basepoint, CURVE25519_KEYSIZE,
@ -157,22 +152,16 @@ METHOD(diffie_hellman_t, set_private_value, bool,
}
if (ret == 0)
{
len = CURVE25519_KEYSIZE;
ret = wc_curve25519_shared_secret_ex(&this->key, &pub,
this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
if (ret > 0)
{
ret = 0;
}
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->computed)
if (!this->shared_secret.len)
{
return FALSE;
}
@ -203,14 +192,6 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
WC_RNG rng;
int ret;
switch (group)
{
case CURVE_25519:
break;
default:
return NULL;
}
INIT(this,
.public = {
.get_shared_secret = _get_shared_secret,
@ -225,23 +206,23 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
if (wc_curve25519_init(&this->key) != 0)
{
DBG1(DBG_LIB, "Initializing key failed");
DBG1(DBG_LIB, "initializing key failed");
free(this);
return NULL;
}
if (wc_InitRng(&rng) != 0)
{
DBG1(DBG_LIB, "Initializing a random number generator failed");
free(this);
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");
free(this);
DBG1(DBG_LIB, "making a key failed");
destroy(this);
return NULL;
}
return &this->public;

View File

@ -41,4 +41,3 @@
diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group);
#endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/