mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
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:
parent
59be02519a
commit
d3329ee540
@ -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
2
conf/plugins/wolfssl.opt
Normal file
@ -0,0 +1,2 @@
|
||||
charon.plugins.wolfssl.fips_mode = no
|
||||
Enable to prevent loading the plugin if wolfSSL is not in FIPS mode.
|
@ -1,6 +1,5 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-DFIPS_MODE=${fips_mode}
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_ @}*/
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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_ @}*/
|
||||
|
||||
|
@ -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(¶ms, ¶ms) == 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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -41,4 +41,3 @@
|
||||
diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group);
|
||||
|
||||
#endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user