plugins/updown.opt \
plugins/vici.opt \
plugins/whitelist.opt \
+ plugins/wolfssl.opt \
plugins/xauth-eap.opt \
plugins/xauth-pam.opt
--- /dev/null
+charon.plugins.wolfssl.fips_mode = no
+ Enable to prevent loading the plugin if wolfSSL is not in FIPS mode.
AM_CPPFLAGS = \
- -I$(top_srcdir)/src/libstrongswan \
- -DFIPS_MODE=${fips_mode}
+ -I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
#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;
/**
/**
* 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
*/
/**
* The cipher to use
*/
- union
- {
+ union {
#if !defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))
Aes aes;
#endif
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)
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)
{
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;
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
break;
}
+ memwipe(nonce.ptr, nonce.len);
return success;
}
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)
{
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)
{
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;
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
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;
}
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,
{
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;
}
private_aead_t *this)
{
chunk_clear(&this->key);
+ chunk_clear(&this->salt);
switch (this->alg)
{
#if !defined(NO_AES) && defined(HAVE_AESGCM)
case ENCR_AES_CCM_ICV16:
wc_AesFree(&this->cipher.aes);
break;
-#endif
-#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
- case ENCR_CHACHA20_POLY1305:
- break;
#endif
default:
break;
size_t key_size, size_t salt_size)
{
private_aead_t *this;
+ size_t expected_salt_size;
INIT(this,
.public = {
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");
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");
key_size = 32;
/* FALL */
case 32:
- this->iv_size = CHACHA_IV_BYTES;
- this->salt_len = 4;
+ expected_salt_size = 4;
break;
default:
free(this);
return NULL;
}
- if (salt_size && salt_size != this->salt_len)
+ if (salt_size && salt_size != expected_salt_size)
{
/* currently not supported */
free(this);
}
this->key = chunk_alloc(key_size);
+ this->salt = chunk_alloc(expected_salt_size);
this->iv_gen = iv_gen_seq_create();
return &this->public;
/**
* wolfSSL cipher
*/
- union
- {
+ union {
#if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
Aes aes;
#endif
*/
encryption_algorithm_t alg;
- /**
+ /**
* Private key
*/
chunk_t key;
/**
* 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
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;
}
break;
}
+ memwipe(nonce, sizeof(nonce));
return success;
}
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;
}
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,
{
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;
}
private_wolfssl_crypter_t *this)
{
chunk_clear(&this->key);
+ chunk_clear(&this->salt);
switch (this->alg)
{
#if !defined(NO_AES) && !defined(NO_AES_CBC)
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;
{
case 0:
key_size = 16;
+ /* fall-through */
case 16:
case 24:
case 32:
{
case 0:
key_size = 16;
+ /* fall-through */
case 16:
case 24:
case 32:
{
case 0:
key_size = 16;
+ /* fall-through */
case 16:
case 24:
case 32:
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;
},
},
.alg = algo,
- .key_size = key_size,
.block_size = block_size,
.iv_size = iv_size,
- .salt_len = salt_len,
);
switch (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;
}
this->key = chunk_alloc(key_size);
+ this->salt = chunk_alloc(salt_len);
return &this->public;
}
-
#include <crypto/crypters/crypter.h>
/**
- * Implementation of crypters using wolfssl.
+ * Implementation of crypters using wolfSSL.
*/
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_ @}*/
* Private data of an wolfssl_diffie_hellman_t object.
*/
struct private_wolfssl_diffie_hellman_t {
+
/**
* Public wolfssl_diffie_hellman_t interface.
*/
*/
DhKey dh;
- /**
- * Random number generator to use with RSA operations.
- */
- WC_RNG rng;
-
/**
* Length of public values
*/
* 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)
{
}
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;
}
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;
}
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);
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 = {
.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));
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 */
*/
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;
};
/**
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;
}
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;
}
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);
}
* 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,
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;
}
}
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);
}
if (ret == 0)
{
- /* Calculate public key */
+ /* calculate public key */
success = wolfssl_ecc_multiply(this->key.dp, &this->key.k, base,
&this->key.pubkey);
}
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;
}
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 = {
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)
{
break;
#endif
default:
- DBG1(DBG_LIB, "EC group not supported");
destroy(this);
return NULL;
}
+ if (wc_InitRng(&rng) != 0)
+ {
+ DBG1(DBG_LIB, "RNG init failed, ecdh create failed");
+ destroy(this);
+ return NULL;
+ }
+
/* generate an EC private (public) key */
- if (wc_ecc_make_key_ex(&this->rng, this->keysize, &this->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");
+ DBG1(DBG_LIB, "make key failed, wolfssl ECDH create failed");
destroy(this);
return NULL;
}
+ wc_FreeRng(&rng);
return &this->public;
}
* 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_ @}*/
-
#include <utils/debug.h>
#include <wolfssl/wolfcrypt/ecc.h>
-
+#include <wolfssl/wolfcrypt/asn.h>
typedef struct private_wolfssl_ec_private_key_t private_wolfssl_ec_private_key_t;
* Private data of a wolfssl_ec_private_key_t object.
*/
struct private_wolfssl_ec_private_key_t {
+
/**
- * Public interface for this signer.
+ * Public interface
*/
wolfssl_ec_private_key_t public;
WC_RNG rng;
/**
- * reference count
+ * Reference count
*/
refcount_t ref;
};
mp_free(&s);
mp_free(&r);
-
return success;
}
* Build a RFC 4754 signature for a specified curve and hash algorithm
*/
static bool build_curve_signature(private_wolfssl_ec_private_key_t *this,
- signature_scheme_t scheme, enum wc_HashType hash, ecc_curve_id curve_id,
- chunk_t data, chunk_t *signature)
+ 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))
* 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;
chunk_free(signature);
}
}
-
chunk_free(&dgst);
return success;
}
{
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);
{
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);
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)
{
chunk_clear(&asn1_encoding);
}
return success;
- }
default:
return FALSE;
}
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)
return NULL;
}
this = create_empty();
+ if (!this)
+ {
+ return NULL;
+ }
+
this->keysize = key_size;
switch (key_size)
{
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)
{
}
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)
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(¶ms, ¶ms) == ASN1_OID)
{
oid = asn1_known_oid(params);
break;
}
}
- chunk_free(&alg_id);
if (oid == OID_UNKNOWN)
{
DBG1(DBG_LIB, "parameters do not match private key data");
return NULL;
}
}
-
return &this->public;
}
+
#endif /* HAVE_ECC_SIGN */
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/hash.h>
-
+#include <wolfssl/wolfcrypt/asn.h>
typedef struct private_wolfssl_ec_public_key_t private_wolfssl_ec_public_key_t;
* Private data structure with signing context.
*/
struct private_wolfssl_ec_public_key_t {
+
/**
- * Public interface for this signer.
+ * Public interface
*/
wolfssl_ec_public_key_t public;
ecc_key ec;
/**
- * reference counter
+ * Reference count
*/
refcount_t ref;
};
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)
ret = wc_ecc_verify_hash_ex(&r, &s, hash.ptr, hash.len, &stat,
&this->ec);
}
-
mp_free(&s);
mp_free(&r);
-
return ret == 0 && stat == 1;
}
* Verify a RFC 4754 signature for a specified curve and hash algorithm
*/
static bool verify_curve_signature(private_wolfssl_ec_public_key_t *this,
- signature_scheme_t scheme, enum wc_HashType hash, ecc_curve_id curve_id,
- chunk_t data, chunk_t signature)
+ 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;
* 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,
{
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;
}
}
/**
- * 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;
}
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;
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)
word32 idx;
int ret;
- if (type != KEY_ECDSA)
- {
- return NULL;
- }
-
while (TRUE)
{
switch (va_arg(args, builder_part_t))
break;
}
this = create_empty();
+ if (!this)
+ {
+ return NULL;
+ }
+
idx = 0;
ret = wc_EccPublicKeyDecode(blob.ptr, &idx, &this->ec, blob.len);
if (ret < 0)
}
return &this->public;
}
-#endif /* HAVE_ECC_VERIFY */
+#endif /* HAVE_ECC_VERIFY */
#include <utils/debug.h>
#include <wolfssl/wolfcrypt/ed25519.h>
+#include <wolfssl/wolfcrypt/asn.h>
typedef struct private_private_key_t 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);
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;
}
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;
}
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*,
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;
}
{
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)
/**
* 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;
.get_ref = _get_ref,
.destroy = _destroy,
},
- .type = type,
.ref = 1,
);
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))
break;
}
- switch (type)
+ this = create_internal();
+ if (!this)
{
- case KEY_ED25519:
- break;
- default:
- return NULL;
+ return NULL;
}
- this = create_internal(type);
- if (this == 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
*/
}
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);
#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;
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;
}
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.
*/
hasher_t *hasher;
chunk_t blob;
word32 len;
- int ret;
+ bool success = FALSE;
if (lib->encoding->get_cache(lib->encoding, type, key, fp))
{
{
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;
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,
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)
{
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;
}
/**
* 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;
.get_ref = _get_ref,
.destroy = _destroy,
},
- .type = type,
.ref = 1,
);
+
if (wc_ed25519_init(&this->key) != 0)
{
free(this);
return NULL;
}
-
return this;
}
break;
}
- this = create_empty(type);
- if (this == NULL)
+ this = create_empty();
+ if (!this)
{
return NULL;
}
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;
};
destroy(this);
return NULL;
}
-
return &this->public;
}
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;
}
.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;
}
#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)
{
}
/*
- * 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
wolfSSL_Mutex globalRngMutex;
#endif
static WC_RNG globalRng;
-static int globalRngInit = 0;
+static bool globalRngInit;
/**
* Private data of wolfssl_rng_t
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;
}
}
}
/*
- * Described in header.
+ * Described in header
*/
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;
}
/*
- * Described in header.
+ * Described in header
*/
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()
{
wc_FreeMutex(&globalRngMutex);
#endif
wc_FreeRng(&globalRng);
- globalRngInit = 0;
+ globalRngInit = FALSE;
}
}
#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;
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
*/
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));
}
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);
}
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))
{
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;
}
{
int padding, mgf, len;
enum wc_HashType hash;
- char *decrypted;
switch (scheme)
{
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;
}
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;
}
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)
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;
}
/*
- * See header.
+ * Described in header
*/
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
va_list args)
}
this = create_empty();
- if (this == NULL)
+ if (!this)
{
return NULL;
}
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)
{
{
ret = mp_mod(r, n, r);
}
-
return ret == 0;
}
{
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;
}
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;
}
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)
}
success = TRUE;
-
+
error:
return success;
}
* 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;
}
/**
}
/*
- * See header
+ * Described in header
*/
wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
va_list args)
}
this = create_empty();
- if (this == NULL)
+ if (!this)
{
return NULL;
}
&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)
#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;
WC_RNG rng;
/**
- * reference counter
+ * Reference counter
*/
refcount_t ref;
};
-
/**
* Verify RSA signature
*/
{
bool success = FALSE;
int len = wc_RsaEncryptSize(&this->rsa);
- u_char *buf;
+ chunk_t padded;
u_char *p;
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);
+ 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;
}
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;
}
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))
{
{
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;
}
-
- chunk_free(&dgst);
- if (buf != NULL)
+ len = wc_RsaEncryptSize(&this->rsa);
+ if (signature.len > len)
{
- free(buf);
+ signature = chunk_skip(signature, signature.len - len);
}
+ padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00);
+ len = wc_RsaPSS_VerifyInline_ex(padded.ptr, len, &p, hash, mgf,
+ params->salt_len, &this->rsa);
+ if (len > 0)
+ {
+ success = wc_RsaPSS_CheckPadding_ex(dgst.ptr, dgst.len, p, len, hash,
+ params->salt_len, mp_count_bits(&this->rsa.n)) == 0;
+ }
+ chunk_free(&dgst);
return success;
}
#endif
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;
}
{
int padding, mgf, len;
enum wc_HashType hash;
- char *encrypted;
switch (scheme)
{
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;
}
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.
*/
{
hasher_t *hasher;
chunk_t key;
- int len;
+ bool success = FALSE;
if (lib->encoding->get_cache(lib->encoding, type, rsa, fp))
{
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,
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;
+ 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,
+ 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;
- }
}
+ chunk_free(&n);
+ chunk_free(&e);
+ return success;
}
METHOD(public_key_t, get_ref, public_key_t*,
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;
return this;
}
-/**
- * See header.
+/*
+ * Described in header
*/
wolfssl_rsa_public_key_t *wolfssl_rsa_public_key_load(key_type_t type,
va_list args)
}
this = create_empty();
- if (this == NULL)
+ if (!this)
{
return NULL;
}
if (wc_RsaPublicKeyDecode(blob.ptr, &idx, &this->rsa,
blob.len) != 0)
{
- DBG1(DBG_LIB, "Public , rsa public key load failed");
destroy(this);
return NULL;
}
struct private_wolfssl_sha1_prf_t {
/**
- * Public wolfssl_sha1_prf_t interface.
+ * Public wolfssl_sha1_prf_t interface
*/
wolfssl_sha1_prf_t public;
hash[3] = htonl(this->sha1.digest[3]);
hash[4] = htonl(this->sha1.digest[4]);
}
-
return TRUE;
}
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 = {
free(this);
return NULL;
}
-
return &this->public;
}
* 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);
#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)
{
return TRUE;
}
-/**
- * Described in header.
+/*
+ * Described in header
*/
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)
{
{
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)
{
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;
}
* Shared secret
*/
chunk_t shared_secret;
-
- /**
- * True if shared secret is computed
- */
- bool computed;
};
/**
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,
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))
{
}
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);
{
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;
}
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,
}
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;
}
WC_RNG rng;
int ret;
- switch (group)
- {
- case CURVE_25519:
- break;
- default:
- return NULL;
- }
-
INIT(this,
.public = {
.get_shared_secret = _get_shared_secret,
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;
diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group);
#endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/
-