From: Tobias Brunner Date: Fri, 5 Apr 2019 10:03:18 +0000 (+0200) Subject: wolfssl: Fixes, code style changes and some refactorings X-Git-Tag: 5.8.0rc1~28^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3329ee540c8f6137c9860a96fd7041ae9b57e66;p=thirdparty%2Fstrongswan.git 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. --- diff --git a/conf/Makefile.am b/conf/Makefile.am index 9d86740495..0080a559d3 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -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 diff --git a/conf/plugins/wolfssl.opt b/conf/plugins/wolfssl.opt new file mode 100644 index 0000000000..02d37e07fd --- /dev/null +++ b/conf/plugins/wolfssl.opt @@ -0,0 +1,2 @@ +charon.plugins.wolfssl.fips_mode = no + Enable to prevent loading the plugin if wolfSSL is not in FIPS mode. diff --git a/src/libstrongswan/plugins/wolfssl/Makefile.am b/src/libstrongswan/plugins/wolfssl/Makefile.am index cd0be7da26..5f3080a271 100644 --- a/src/libstrongswan/plugins/wolfssl/Makefile.am +++ b/src/libstrongswan/plugins/wolfssl/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ - -I$(top_srcdir)/src/libstrongswan \ - -DFIPS_MODE=${fips_mode} + -I$(top_srcdir)/src/libstrongswan AM_CFLAGS = \ $(PLUGIN_CFLAGS) diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_aead.c b/src/libstrongswan/plugins/wolfssl/wolfssl_aead.c index 1ed0c715ba..2ea7c94cd6 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_aead.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_aead.c @@ -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; diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c b/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c index cf4623ace9..a39c25b955 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c @@ -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; } - diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.h b/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.h index 31519c4954..108c9cc94f 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.h @@ -33,7 +33,7 @@ typedef struct wolfssl_crypter_t wolfssl_crypter_t; #include /** - * 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_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c index fc6815c9ad..6fefe523d5 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c @@ -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 */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c index 20f1031cd5..ceff4172c1 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c @@ -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,19 +352,26 @@ 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; } + if (wc_InitRng(&rng) != 0) + { + DBG1(DBG_LIB, "RNG init failed, ecdh create failed"); + destroy(this); + return NULL; + } + /* generate an EC private (public) key */ - if (wc_ecc_make_key_ex(&this->rng, this->keysize, &this->key, + if (wc_ecc_make_key_ex(&rng, this->keysize, &this->key, this->curve_id) != 0) { - DBG1(DBG_LIB, "Make key failed, wolfssl ECDH create failed"); + DBG1(DBG_LIB, "make key failed, wolfssl ECDH create failed"); destroy(this); return NULL; } + wc_FreeRng(&rng); return &this->public; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h index d9e37693dd..c0a3e84f24 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h @@ -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_ @}*/ - diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c index f127bd13b8..2a2b44e4c9 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c @@ -34,7 +34,7 @@ #include #include - +#include 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 */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_public_key.c index 1bca252139..abcddab79a 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_public_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_public_key.c @@ -31,7 +31,7 @@ #include #include - +#include 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 */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c index bee0a33949..ed61b4b79b 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c @@ -29,6 +29,7 @@ #include #include +#include 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) + this = create_internal(); + if (!this) { - case KEY_ED25519: - break; - default: - return NULL; + return NULL; } - this = create_internal(type); - if (this == NULL) + + if (wc_InitRng(&rng) != 0) { + DBG1(DBG_LIB, "initializing random failed"); + destroy(this); return NULL; } - ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &this->key); wc_FreeRng(&rng); + if (ret < 0) { DBG1(DBG_LIB, "generating %N key failed", key_type_names, type); destroy(this); return NULL; } - return &this->public; } +/** + * Fix the internal state if only the private key is set + */ +static int set_public_key(private_private_key_t *this) +{ + int ret = 0; + + if (!this->key.pubKeySet) + { + ret = wc_ed25519_make_public(&this->key, this->key.p, + ED25519_PUB_KEY_SIZE); + if (ret == 0) + { + /* put public key after private key in the same buffer */ + memmove(this->key.k + ED25519_KEY_SIZE, this->key.p, + ED25519_PUB_KEY_SIZE); + this->key.pubKeySet = 1; + } + } + return ret; +} + /* * Described in header */ @@ -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); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c index d09eb48529..879dfa73fb 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c @@ -27,8 +27,10 @@ #include "wolfssl_ed_public_key.h" #include +#include #include +#include 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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_hasher.c b/src/libstrongswan/plugins/wolfssl/wolfssl_hasher.c index d87364a96e..5e9d851c29 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_hasher.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_hasher.c @@ -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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_hmac.c b/src/libstrongswan/plugins/wolfssl/wolfssl_hmac.c index 27eb6a6bec..a28beb4444 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_hmac.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_hmac.c @@ -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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index b091a2084a..925f08ee37 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -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 diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_rng.c b/src/libstrongswan/plugins/wolfssl/wolfssl_rng.c index 86a8d8a22a..73b85840ba 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_rng.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_rng.c @@ -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; } } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c index c3ddd5c0c6..39d3e021bd 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c @@ -28,20 +28,22 @@ #include "wolfssl_rsa_public_key.h" #include "wolfssl_util.h" -#include #include +#include #include #include +#include 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) diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c index 669dc08f94..2824e9a170 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c @@ -27,21 +27,23 @@ #include "wolfssl_rsa_public_key.h" #include "wolfssl_util.h" -#include #include +#include +#include #include #include - +#include 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; } - - chunk_free(&dgst); - if (buf != NULL) + len = wc_RsaEncryptSize(&this->rsa); + if (signature.len > len) { - free(buf); + signature = chunk_skip(signature, signature.len - len); } + padded = chunk_copy_pad(chunk_alloca(len), signature, 0x00); + len = wc_RsaPSS_VerifyInline_ex(padded.ptr, len, &p, hash, mgf, + params->salt_len, &this->rsa); + if (len > 0) + { + success = wc_RsaPSS_CheckPadding_ex(dgst.ptr, dgst.len, p, len, hash, + params->salt_len, mp_count_bits(&this->rsa.n)) == 0; + } + chunk_free(&dgst); return success; } #endif @@ -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; + return wolfssl_rsa_encode_public(&this->rsa, encoding); + } - if (wolfssl_mp2chunk(&this->rsa.n, &n) && - wolfssl_mp2chunk(&this->rsa.e, &e)) - { - success = lib->encoding->encode(lib->encoding, type, NULL, - encoding, CRED_PART_RSA_MODULUS, n, + if (wolfssl_mp2chunk(&this->rsa.n, &n) && + wolfssl_mp2chunk(&this->rsa.e, &e)) + { + success = lib->encoding->encode(lib->encoding, type, NULL, encoding, + CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END); - } - chunk_free(&n); - chunk_free(&e); - return success; - } } + chunk_free(&n); + chunk_free(&e); + return success; } METHOD(public_key_t, get_ref, public_key_t*, @@ -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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.c b/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.c index fa08356c72..fa90288ed8 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.c @@ -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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.h b/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.h index 7f6a32e9cb..89e12c482f 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.h @@ -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); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_util.c b/src/libstrongswan/plugins/wolfssl/wolfssl_util.c index cc8054a486..c83c2982bd 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_util.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_util.c @@ -28,8 +28,8 @@ #include #include -/** - * 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; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c index b752ce0d47..5c21eb66c2 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c @@ -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; diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h index 5e0b7b189f..a66ddc1317 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h @@ -41,4 +41,3 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group); #endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/ -