wolfssl: Fixes, code style changes and some refactorings
authorTobias Brunner <tobias@strongswan.org>
Fri, 5 Apr 2019 10:03:18 +0000 (12:03 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 24 Apr 2019 10:26:08 +0000 (12:26 +0200)
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.

24 files changed:
conf/Makefile.am
conf/plugins/wolfssl.opt [new file with mode: 0644]
src/libstrongswan/plugins/wolfssl/Makefile.am
src/libstrongswan/plugins/wolfssl/wolfssl_aead.c
src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c
src/libstrongswan/plugins/wolfssl/wolfssl_crypter.h
src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c
src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c
src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h
src/libstrongswan/plugins/wolfssl/wolfssl_ec_private_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_ec_public_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_hasher.c
src/libstrongswan/plugins/wolfssl/wolfssl_hmac.c
src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c
src/libstrongswan/plugins/wolfssl/wolfssl_rng.c
src/libstrongswan/plugins/wolfssl/wolfssl_rsa_private_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_rsa_public_key.c
src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.c
src/libstrongswan/plugins/wolfssl/wolfssl_sha1_prf.h
src/libstrongswan/plugins/wolfssl/wolfssl_util.c
src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c
src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h

index 9d86740..0080a55 100644 (file)
@@ -101,6 +101,7 @@ plugins = \
        plugins/updown.opt \
        plugins/vici.opt \
        plugins/whitelist.opt \
+       plugins/wolfssl.opt \
        plugins/xauth-eap.opt \
        plugins/xauth-pam.opt
 
diff --git a/conf/plugins/wolfssl.opt b/conf/plugins/wolfssl.opt
new file mode 100644 (file)
index 0000000..02d37e0
--- /dev/null
@@ -0,0 +1,2 @@
+charon.plugins.wolfssl.fips_mode = no
+       Enable to prevent loading the plugin if wolfSSL is not in FIPS mode.
index cd0be7d..5f3080a 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
-       -I$(top_srcdir)/src/libstrongswan \
-       -DFIPS_MODE=${fips_mode}
+       -I$(top_srcdir)/src/libstrongswan
 
 AM_CFLAGS = \
        $(PLUGIN_CFLAGS)
index 1ed0c71..2ea7c94 100644 (file)
 #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,12 +60,7 @@ 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
@@ -84,11 +68,6 @@ struct private_aead_t {
        size_t icv_size;
 
        /**
-        * Size of the IV
-        */
-       size_t iv_size;
-
-       /**
         * IV generator
         */
        iv_gen_t *iv_gen;
@@ -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)
@@ -318,10 +305,6 @@ METHOD(aead_t, destroy, void,
                        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;
index cf4623a..a39c25b 100644 (file)
@@ -46,8 +46,7 @@ struct private_wolfssl_crypter_t {
        /**
         * wolfSSL cipher
         */
-       union
-       {
+       union {
 #if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
                Aes aes;
 #endif
@@ -65,7 +64,7 @@ struct private_wolfssl_crypter_t {
         */
        encryption_algorithm_t alg;
 
-       /** 
+       /**
         * Private key
         */
        chunk_t key;
@@ -73,17 +72,7 @@ struct private_wolfssl_crypter_t {
        /**
         * Salt value
         */
-       char salt[CTR_SALT_LEN];
-
-       /**
-        * Length of the salt
-        */
-       size_t salt_len;
-
-       /**
-        * Size of key
-        */
-       size_t key_size;
+       chunk_t salt;
 
        /**
         * Size of block
@@ -114,10 +103,10 @@ METHOD(crypter_t, decrypt, bool,
                out = dst->ptr;
        }
 
-       if (this->salt_len > 0)
+       if (this->salt.len > 0)
        {
-               memcpy(nonce, this->salt, this->salt_len);
-               memcpy(nonce + this->salt_len, iv.ptr, this->iv_size);
+               memcpy(nonce, this->salt.ptr, this->salt.len);
+               memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
                nonce[AES_BLOCK_SIZE - 1] = 1;
        }
 
@@ -212,6 +201,7 @@ METHOD(crypter_t, decrypt, bool,
                        break;
        }
 
+       memwipe(nonce, sizeof(nonce));
        return success;
 }
 
@@ -233,10 +223,10 @@ METHOD(crypter_t, encrypt, bool,
                out = dst->ptr;
        }
 
-       if (this->salt_len > 0)
+       if (this->salt.len > 0)
        {
-               memcpy(nonce, this->salt, this->salt_len);
-               memcpy(nonce + this->salt_len, iv.ptr, this->iv_size);
+               memcpy(nonce, this->salt.ptr, this->salt.len);
+               memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
                nonce[AES_BLOCK_SIZE - 1] = 1;
        }
 
@@ -348,7 +338,7 @@ METHOD(crypter_t, get_iv_size, size_t,
 METHOD(crypter_t, get_key_size, size_t,
        private_wolfssl_crypter_t *this)
 {
-       return this->key.len + this->salt_len;
+       return this->key.len + this->salt.len;
 }
 
 METHOD(crypter_t, set_key, bool,
@@ -358,7 +348,7 @@ METHOD(crypter_t, set_key, bool,
        {
                return FALSE;
        }
-       memcpy(this->salt, key.ptr + key.len - this->salt_len, this->salt_len);
+       memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
        memcpy(this->key.ptr, key.ptr, this->key.len);
        return TRUE;
 }
@@ -367,6 +357,7 @@ METHOD(crypter_t, destroy, void,
        private_wolfssl_crypter_t *this)
 {
        chunk_clear(&this->key);
+       chunk_clear(&this->salt);
        switch (this->alg)
        {
 #if !defined(NO_AES) && !defined(NO_AES_CBC)
@@ -379,19 +370,10 @@ METHOD(crypter_t, destroy, void,
                        wc_AesFree(&this->cipher.aes);
                        break;
 #endif
-#ifdef HAVE_CAMELLIA
-               case ENCR_CAMELLIA_CBC:
-                       break;
-#endif
 #ifndef NO_DES3
                case ENCR_3DES:
                        wc_Des3Free(&this->cipher.des3);
                        break;
-               case ENCR_DES:
-       #ifdef WOLFSSL_DES_ECB
-               case ENCR_DES_ECB:
-       #endif
-                       break;
 #endif
                default:
                        break;
@@ -424,6 +406,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        {
                                case 0:
                                        key_size = 16;
+                                       /* fall-through */
                                case 16:
                                case 24:
                                case 32:
@@ -441,6 +424,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        {
                                case 0:
                                        key_size = 16;
+                                       /* fall-through */
                                case 16:
                                case 24:
                                case 32:
@@ -459,6 +443,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        {
                                case 0:
                                        key_size = 16;
+                                       /* fall-through */
                                case 16:
                                case 24:
                                case 32:
@@ -480,24 +465,16 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        iv_size = DES_BLOCK_SIZE;
                        break;
                case ENCR_DES:
-                       if (key_size != 8)
-                       {
-                               return NULL;
-                       }
-                       block_size = DES_BLOCK_SIZE;
-                       iv_size = DES_BLOCK_SIZE;
-                       break;
        #ifdef WOLFSSL_DES_ECB
                case ENCR_DES_ECB:
+       #endif
                        if (key_size != 8)
                        {
                                return NULL;
                        }
-                       key_size = DES_BLOCK_SIZE;
                        block_size = DES_BLOCK_SIZE;
                        iv_size = DES_BLOCK_SIZE;
                        break;
-       #endif
 #endif
                default:
                        return NULL;
@@ -516,10 +493,8 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        },
                },
                .alg = algo,
-               .key_size = key_size,
                .block_size = block_size,
                .iv_size = iv_size,
-               .salt_len = salt_len,
        );
 
        switch (algo)
@@ -534,19 +509,10 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
                        ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
                        break;
 #endif
-#ifdef HAVE_CAMELLIA
-               case ENCR_CAMELLIA_CBC:
-                       break;
-#endif
 #ifndef NO_DES3
                case ENCR_3DES:
                        ret = wc_Des3Init(&this->cipher.des3, NULL, INVALID_DEVID);
                        break;
-               case ENCR_DES:
-       #ifdef WOLFSSL_DES_ECB
-               case ENCR_DES_ECB:
-       #endif
-                       break;
 #endif
                default:
                        break;
@@ -558,7 +524,7 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
        }
 
        this->key = chunk_alloc(key_size);
+       this->salt = chunk_alloc(salt_len);
 
        return &this->public;
 }
-
index 31519c4..108c9cc 100644 (file)
@@ -33,7 +33,7 @@ typedef struct wolfssl_crypter_t wolfssl_crypter_t;
 #include <crypto/crypters/crypter.h>
 
 /**
- * Implementation of crypters using wolfssl.
+ * Implementation of crypters using wolfSSL.
  */
 struct wolfssl_crypter_t {
 
@@ -51,6 +51,6 @@ struct wolfssl_crypter_t {
  * @return                             wolfssl_crypter_t, NULL if not supported
  */
 wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
-                                                                               size_t key_size);
+                                                                                 size_t key_size);
 
 #endif /** WOLFSSL_CRYPTER_H_ @}*/
index fc6815c..6fefe52 100644 (file)
@@ -37,6 +37,7 @@ typedef struct private_wolfssl_diffie_hellman_t private_wolfssl_diffie_hellman_t
  * Private data of an wolfssl_diffie_hellman_t object.
  */
 struct private_wolfssl_diffie_hellman_t {
+
        /**
         * Public wolfssl_diffie_hellman_t interface.
         */
@@ -53,11 +54,6 @@ struct private_wolfssl_diffie_hellman_t {
        DhKey dh;
 
        /**
-        * Random number generator to use with RSA operations.
-        */
-       WC_RNG rng;
-
-       /**
         * Length of public values
         */
        int len;
@@ -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 */
index 20f1031..ceff417 100644 (file)
@@ -63,24 +63,9 @@ 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;
 }
index d9e3769..c0a3e84 100644 (file)
@@ -47,9 +47,10 @@ struct wolfssl_ec_diffie_hellman_t {
  * Creates a new wolfssl_ec_diffie_hellman_t object.
  *
  * @param group                        EC Diffie Hellman group number to use
- * @return                             wolfssl_ec_diffie_hellman_t object, NULL if not supported
+ * @return                             wolfssl_ec_diffie_hellman_t object, NULL if not
+ *                                             supported
  */
-wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(diffie_hellman_group_t group);
+wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(
+                                                                                               diffie_hellman_group_t group);
 
 #endif /** WOLFSSL_EC_DIFFIE_HELLMAN_H_ @}*/
-
index f127bd1..2a2b44e 100644 (file)
@@ -34,7 +34,7 @@
 #include <utils/debug.h>
 
 #include <wolfssl/wolfcrypt/ecc.h>
-
+#include <wolfssl/wolfcrypt/asn.h>
 
 typedef struct private_wolfssl_ec_private_key_t private_wolfssl_ec_private_key_t;
 
@@ -42,8 +42,9 @@ typedef struct private_wolfssl_ec_private_key_t private_wolfssl_ec_private_key_t
  * Private data of a wolfssl_ec_private_key_t object.
  */
 struct private_wolfssl_ec_private_key_t {
+
        /**
-        * Public interface for this signer.
+        * Public interface
         */
        wolfssl_ec_private_key_t public;
 
@@ -63,7 +64,7 @@ struct private_wolfssl_ec_private_key_t {
        WC_RNG rng;
 
        /**
-        * reference count
+        * Reference count
         */
        refcount_t ref;
 };
@@ -97,7 +98,6 @@ static bool build_signature(private_wolfssl_ec_private_key_t *this,
 
        mp_free(&s);
        mp_free(&r);
-       
        return success;
 }
 
@@ -105,16 +105,17 @@ static bool build_signature(private_wolfssl_ec_private_key_t *this,
  * Build a RFC 4754 signature for a specified curve and hash algorithm
  */
 static bool build_curve_signature(private_wolfssl_ec_private_key_t *this,
-               signature_scheme_t scheme, enum wc_HashType hash, ecc_curve_id curve_id,
-               chunk_t data, chunk_t *signature)
+                                                                 signature_scheme_t scheme,
+                                                                 enum wc_HashType hash, ecc_curve_id curve_id,
+                                                                 chunk_t data, chunk_t *signature)
 {
-       bool success = FALSE;
        chunk_t dgst = chunk_empty;
+       bool success = FALSE;
 
        if (curve_id != this->ec.dp->id)
        {
                DBG1(DBG_LIB, "signature scheme %N not supported by private key",
-                       signature_scheme_names, scheme);
+                        signature_scheme_names, scheme);
                return FALSE;
        }
        if (wolfssl_hash_chunk(hash, data, &dgst))
@@ -129,20 +130,19 @@ static bool build_curve_signature(private_wolfssl_ec_private_key_t *this,
  * Build a DER encoded signature as in RFC 3279
  */
 static bool build_der_signature(private_wolfssl_ec_private_key_t *this,
-               enum wc_HashType hash, chunk_t data, chunk_t *signature)
+                                                               enum wc_HashType hash, chunk_t data,
+                                                               chunk_t *signature)
 {
-       bool success = FALSE;
        chunk_t dgst = chunk_empty;
-       int ret;
+       bool success = FALSE;
        word32 len;
 
        if (wolfssl_hash_chunk(hash, data, &dgst))
        {
-               *signature = chunk_alloc(this->ec.dp->size * 2 + 10);
+               *signature = chunk_alloc(wc_ecc_sig_size(&this->ec));
                len = signature->len;
-               ret = wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len,
-                                                          &this->rng, &this->ec);
-               if (ret == 0)
+               if (wc_ecc_sign_hash(dgst.ptr, dgst.len, signature->ptr, &len,
+                                                          &this->rng, &this->ec) == 0)
                {
                        signature->len = len;
                        success = TRUE;
@@ -152,7 +152,6 @@ static bool build_der_signature(private_wolfssl_ec_private_key_t *this,
                        chunk_free(signature);
                }
        }
-
        chunk_free(&dgst);
        return success;
 }
@@ -165,40 +164,40 @@ METHOD(private_key_t, sign, bool,
        {
                case SIGN_ECDSA_WITH_NULL:
                        return build_signature(this, data, signature);
-       #ifndef NO_SHA
+#ifndef NO_SHA
                case SIGN_ECDSA_WITH_SHA1_DER:
                        return build_der_signature(this, WC_HASH_TYPE_SHA, data, signature);
-       #endif
-       #ifndef NO_SHA256
+#endif
+#ifndef NO_SHA256
                case SIGN_ECDSA_WITH_SHA256_DER:
                        return build_der_signature(this, WC_HASH_TYPE_SHA256, data,
                                                                           signature);
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case SIGN_ECDSA_WITH_SHA384_DER:
                        return build_der_signature(this, WC_HASH_TYPE_SHA384, data,
                                                                           signature);
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case SIGN_ECDSA_WITH_SHA512_DER:
                        return build_der_signature(this, WC_HASH_TYPE_SHA512, data,
                                                                           signature);
-       #endif
-       #ifndef NO_SHA256
+#endif
+#ifndef NO_SHA256
                case SIGN_ECDSA_256:
                        return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA256,
                                                                                 ECC_SECP256R1, data, signature);
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case SIGN_ECDSA_384:
                        return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA384,
                                                                                 ECC_SECP384R1, data, signature);
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case SIGN_ECDSA_521:
                        return build_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
                                                                                 ECC_SECP521R1, data, signature);
-       #endif
+#endif
                default:
                        DBG1(DBG_LIB, "signature scheme %N not supported",
                                 signature_scheme_names, scheme);
@@ -231,16 +230,18 @@ METHOD(private_key_t, get_public_key, public_key_t*,
 {
        public_key_t *public;
        chunk_t key;
-       int ret;
+       int len;
 
-       key = chunk_alloc((this->keysize + 7) / 8 * 5);
-       ret = wc_EccPublicKeyToDer(&this->ec, key.ptr, key.len, 1);
-       if (ret < 0)
+       /* space for algorithmIdentifier/bitString + one byte for the point type */
+       key = chunk_alloc(2 * this->ec.dp->size + 2 * MAX_SEQ_SZ + 2 * MAX_ALGO_SZ +
+                                         TRAILING_ZERO + 1);
+       len = wc_EccPublicKeyToDer(&this->ec, key.ptr, key.len, 1);
+       if (len < 0)
        {
                chunk_free(&key);
                return NULL;
        }
-       key.len = ret;
+       key.len = len;
 
        public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
                                                                BUILD_BLOB_ASN1_DER, key, BUILD_END);
@@ -259,20 +260,23 @@ METHOD(private_key_t, get_encoding, bool,
        private_wolfssl_ec_private_key_t *this, cred_encoding_type_t type,
        chunk_t *encoding)
 {
+       bool success = TRUE;
+       int len;
+
        switch (type)
        {
                case PRIVKEY_ASN1_DER:
                case PRIVKEY_PEM:
-               {
-                       bool success = TRUE;
-
-                       *encoding = chunk_alloc(this->keysize * 4 + 30);
-                       if (wc_EccPrivateKeyToDer(&this->ec, encoding->ptr,
-                                                                         encoding->len) < 0)
+                       /* include space for parameters, public key and contexts */
+                       *encoding = chunk_alloc(3 * this->ec.dp->size + 4 * MAX_SEQ_SZ +
+                                                                       MAX_VERSION_SZ + MAX_ALGO_SZ);
+                       len = wc_EccKeyToDer(&this->ec, encoding->ptr, encoding->len);
+                       if (len < 0)
                        {
                                chunk_free(encoding);
                                return FALSE;
                        }
+                       encoding->len = len;
 
                        if (type == PRIVKEY_PEM)
                        {
@@ -284,7 +288,6 @@ METHOD(private_key_t, get_encoding, bool,
                                chunk_clear(&asn1_encoding);
                        }
                        return success;
-               }
                default:
                        return FALSE;
        }
@@ -338,16 +341,15 @@ static private_wolfssl_ec_private_key_t *create_empty(void)
 
        if (wc_InitRng(&this->rng) < 0)
        {
-               DBG1(DBG_LIB, "Random number generation init failed");
+               DBG1(DBG_LIB, "RNG init failed");
                free(this);
                return NULL;
        }
-
        return this;
 }
 
 /*
- * See header.
+ * Described in header
  */
 wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
                                                                                                         va_list args)
@@ -375,6 +377,11 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
                return NULL;
        }
        this = create_empty();
+       if (!this)
+       {
+               return NULL;
+       }
+
        this->keysize = key_size;
        switch (key_size)
        {
@@ -396,25 +403,23 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_gen(key_type_t type,
        if (wc_ecc_make_key_ex(&this->rng, (key_size + 7) / 8, &this->ec,
                                                   curve_id) < 0)
        {
-               DBG1(DBG_LIB, "EC private key generation failed", key_size);
+               DBG1(DBG_LIB, "EC private key generation failed");
                destroy(this);
                return NULL;
        }
        return &this->public;
 }
 
-/**
- * See header.
+/*
+ * Described in header
  */
 wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
                                                                                                          va_list args)
 {
        private_wolfssl_ec_private_key_t *this;
-       chunk_t params = chunk_empty;
-       chunk_t key = chunk_empty;
-       chunk_t alg_id = chunk_empty;
+       chunk_t params = chunk_empty, key = chunk_empty;
        word32 idx;
-       int oid;
+       int oid = OID_UNKNOWN;
 
        while (TRUE)
        {
@@ -433,12 +438,15 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
                }
                break;
        }
-       if (key.ptr == NULL)
+       if (!key.ptr)
        {
                return NULL;
        }
-
        this = create_empty();
+       if (!this)
+       {
+               return NULL;
+       }
 
        idx = 0;
        if (wc_EccPrivateKeyDecode(key.ptr, &idx, &this->ec, key.len) < 0)
@@ -463,9 +471,7 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
 
        if (params.ptr)
        {
-               /* if ECParameters is passed, check we guessed correct */
-               alg_id = asn1_algorithmIdentifier_params(OID_EC_PUBLICKEY,
-                                                                                                chunk_clone(params));
+               /* if ECParameters is passed, ensure we guessed correctly */
                if (asn1_unwrap(&params, &params) == ASN1_OID)
                {
                        oid = asn1_known_oid(params);
@@ -494,7 +500,6 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
                                        break;
                        }
                }
-               chunk_free(&alg_id);
                if (oid == OID_UNKNOWN)
                {
                        DBG1(DBG_LIB, "parameters do not match private key data");
@@ -502,7 +507,7 @@ wolfssl_ec_private_key_t *wolfssl_ec_private_key_load(key_type_t type,
                        return NULL;
                }
        }
-
        return &this->public;
 }
+
 #endif /* HAVE_ECC_SIGN */
index 1bca252..abcddab 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <wolfssl/wolfcrypt/ecc.h>
 #include <wolfssl/wolfcrypt/hash.h>
-
+#include <wolfssl/wolfcrypt/asn.h>
 
 typedef struct private_wolfssl_ec_public_key_t private_wolfssl_ec_public_key_t;
 
@@ -39,8 +39,9 @@ typedef struct private_wolfssl_ec_public_key_t private_wolfssl_ec_public_key_t;
  * Private data structure with signing context.
  */
 struct private_wolfssl_ec_public_key_t {
+
        /**
-        * Public interface for this signer.
+        * Public interface
         */
        wolfssl_ec_public_key_t public;
 
@@ -55,7 +56,7 @@ struct private_wolfssl_ec_public_key_t {
        ecc_key ec;
 
        /**
-        * reference counter
+        * Reference count
         */
        refcount_t ref;
 };
@@ -66,8 +67,7 @@ struct private_wolfssl_ec_public_key_t {
 static bool verify_signature(private_wolfssl_ec_public_key_t *this,
                                                         chunk_t hash, chunk_t signature)
 {
-       int stat = 1;
-       int ret = -1;
+       int stat = 1, ret = -1;
        mp_int r, s;
 
        if (mp_init(&r) < 0)
@@ -85,10 +85,8 @@ static bool verify_signature(private_wolfssl_ec_public_key_t *this,
                ret = wc_ecc_verify_hash_ex(&r, &s, hash.ptr, hash.len, &stat,
                                                                        &this->ec);
        }
-
        mp_free(&s);
        mp_free(&r);
-
        return ret == 0 && stat == 1;
 }
 
@@ -96,8 +94,9 @@ static bool verify_signature(private_wolfssl_ec_public_key_t *this,
  * Verify a RFC 4754 signature for a specified curve and hash algorithm
  */
 static bool verify_curve_signature(private_wolfssl_ec_public_key_t *this,
-               signature_scheme_t scheme, enum wc_HashType hash, ecc_curve_id curve_id,
-               chunk_t data, chunk_t signature)
+                                                                  signature_scheme_t scheme,
+                                                                  enum wc_HashType hash, ecc_curve_id curve_id,
+                                                                  chunk_t data, chunk_t signature)
 {
        bool success = FALSE;
        chunk_t dgst;
@@ -122,30 +121,20 @@ static bool verify_curve_signature(private_wolfssl_ec_public_key_t *this,
  * Verification of a DER encoded signature as in RFC 3279
  */
 static bool verify_der_signature(private_wolfssl_ec_public_key_t *this,
-               enum wc_HashType hash, chunk_t data, chunk_t signature)
+                                                                enum wc_HashType hash, chunk_t data,
+                                                                chunk_t signature)
 {
-       bool success = FALSE;
        chunk_t dgst;
-       int stat = 1;
-       int ret;
+       int stat = 1, ret = -1;
 
-       /* remove any preceding 0-bytes from signature */
-       while (signature.len && signature.ptr[0] == 0x00)
-       {
-               signature = chunk_skip(signature, 1);
-       }
+       signature = chunk_skip_zero(signature);
        if (wolfssl_hash_chunk(hash, data, &dgst))
        {
                ret = wc_ecc_verify_hash(signature.ptr, signature.len, dgst.ptr,
                                                                 dgst.len, &stat, &this->ec);
-               if (ret == 0 && stat == 1)
-               {
-                       success = TRUE;
-               }
        }
-
        chunk_free(&dgst);
-       return success;
+       return ret == 0 && stat == 1;
 }
 
 METHOD(public_key_t, get_type, key_type_t,
@@ -160,45 +149,45 @@ METHOD(public_key_t, verify, bool,
 {
        switch (scheme)
        {
-       #ifndef NO_SHA
+#ifndef NO_SHA
                case SIGN_ECDSA_WITH_SHA1_DER:
                        return verify_der_signature(this, WC_HASH_TYPE_SHA, data,
                                                                                signature);
-       #endif
-       #ifndef NO_SHA256
+#endif
+#ifndef NO_SHA256
                case SIGN_ECDSA_WITH_SHA256_DER:
                        return verify_der_signature(this, WC_HASH_TYPE_SHA256, data,
                                                                                signature);
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case SIGN_ECDSA_WITH_SHA384_DER:
                        return verify_der_signature(this, WC_HASH_TYPE_SHA384, data,
                                                                                signature);
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case SIGN_ECDSA_WITH_SHA512_DER:
                        return verify_der_signature(this, WC_HASH_TYPE_SHA512, data,
                                                                                signature);
-       #endif
+#endif
                case SIGN_ECDSA_WITH_NULL:
                        return verify_signature(this, data, signature);
-       #ifndef NO_SHA256
+#ifndef NO_SHA256
                case SIGN_ECDSA_256:
                        return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA256,
                                                                                  ECC_SECP256R1, data, signature);
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case SIGN_ECDSA_384:
                        return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA384,
                                                                                  ECC_SECP384R1, data, signature);
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case SIGN_ECDSA_521:
                        return verify_curve_signature(this, scheme, WC_HASH_TYPE_SHA512,
                                                                                  ECC_SECP521R1, data, signature);
-       #endif
+#endif
                default:
-                       DBG1(DBG_LIB, "signature scheme %N not supported in EC",
+                       DBG1(DBG_LIB, "signature scheme %N not supported via wolfssl",
                                 signature_scheme_names, scheme);
                        return FALSE;
        }
@@ -219,51 +208,51 @@ METHOD(public_key_t, get_keysize, int,
 }
 
 /**
- * Calculate fingerprint from a EC_KEY, also used in ec private key.
+ * Calculate fingerprint from an EC key, also used in ec private key.
  */
 bool wolfssl_ec_fingerprint(ecc_key *ec, cred_encoding_type_t type, chunk_t *fp)
 {
        hasher_t *hasher;
        chunk_t key;
-       int ret;
-       bool success;
+       int len;
 
        if (lib->encoding->get_cache(lib->encoding, type, ec, fp))
        {
                return TRUE;
        }
 
-       key = chunk_alloc(ec->dp->size * 4 + 30);
-       ret = wc_EccPublicKeyToDer(ec, key.ptr, key.len, 1);
-       if (ret < 0)
-       {
-               free(key.ptr);
-               return FALSE;
-       }
-       key.len = ret;
-
        switch (type)
        {
                case KEYID_PUBKEY_SHA1:
+               case KEYID_PUBKEY_INFO_SHA1:
+                       /* need an additional byte for the point type */
+                       len = ec->dp->size * 2 + 1;
+                       if (type == KEYID_PUBKEY_INFO_SHA1)
+                       {
+                               /* additional space for algorithmIdentifier/bitString */
+                               len += 2 * MAX_SEQ_SZ + 2 * MAX_ALGO_SZ + TRAILING_ZERO;
+                       }
+                       key = chunk_alloca(len);
+                       len = wc_EccPublicKeyToDer(ec, key.ptr, key.len,
+                                                                          type == KEYID_PUBKEY_INFO_SHA1);
                        break;
                default:
-                       success = lib->encoding->encode(lib->encoding, type, ec, fp,
-                                                                                       CRED_PART_ECDSA_PUB_ASN1_DER, key,
-                                                                                       CRED_PART_END);
-                       chunk_free(&key);
-                       return success;
+                       return FALSE;
        }
+       if (len < 0)
+       {
+               return FALSE;
+       }
+       key.len = len;
 
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        if (!hasher || !hasher->allocate_hash(hasher, key, fp))
        {
-               DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
+               DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
                DESTROY_IF(hasher);
-               free(key.ptr);
                return FALSE;
        }
        hasher->destroy(hasher);
-       free(key.ptr);
        lib->encoding->cache(lib->encoding, type, ec, *fp);
        return TRUE;
 }
@@ -280,18 +269,20 @@ METHOD(public_key_t, get_encoding, bool,
        chunk_t *encoding)
 {
        bool success = TRUE;
-       int ret;
+       int len;
 
-       *encoding = chunk_alloc(this->ec.dp->size * 2 + 30);
-       ret = wc_EccPublicKeyToDer(&this->ec, encoding->ptr, encoding->len, 1);
-       if (ret < 0)
+       /* space for algorithmIdentifier/bitString + one byte for the point type */
+       *encoding = chunk_alloc(2 * this->ec.dp->size + 2 * MAX_SEQ_SZ +
+                                                       2 * MAX_ALGO_SZ + TRAILING_ZERO + 1);
+       len = wc_EccPublicKeyToDer(&this->ec, encoding->ptr, encoding->len, 1);
+       if (len < 0)
        {
                chunk_free(encoding);
                return FALSE;
        }
-       encoding->len = ret;
+       encoding->len = len;
 
-       if (type != PUBKEY_ASN1_DER)
+       if (type != PUBKEY_SPKI_ASN1_DER)
        {
                chunk_t asn1_encoding = *encoding;
 
@@ -351,12 +342,11 @@ static private_wolfssl_ec_public_key_t *create_empty()
                free(this);
                return NULL;
        }
-
        return this;
 }
 
-/**
- * See header.
+/*
+ * Described in header
  */
 wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
                                                                                                        va_list args)
@@ -366,11 +356,6 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
        word32 idx;
        int ret;
 
-       if (type != KEY_ECDSA)
-       {
-               return NULL;
-       }
-
        while (TRUE)
        {
                switch (va_arg(args, builder_part_t))
@@ -386,6 +371,11 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
                break;
        }
        this = create_empty();
+       if (!this)
+       {
+               return NULL;
+       }
+
        idx = 0;
        ret = wc_EccPublicKeyDecode(blob.ptr, &idx, &this->ec, blob.len);
        if (ret < 0)
@@ -409,5 +399,5 @@ wolfssl_ec_public_key_t *wolfssl_ec_public_key_load(key_type_t type,
        }
        return &this->public;
 }
-#endif /* HAVE_ECC_VERIFY */
 
+#endif /* HAVE_ECC_VERIFY */
index bee0a33..ed61b4b 100644 (file)
@@ -29,6 +29,7 @@
 #include <utils/debug.h>
 
 #include <wolfssl/wolfcrypt/ed25519.h>
+#include <wolfssl/wolfcrypt/asn.h>
 
 typedef struct private_private_key_t private_private_key_t;
 
@@ -48,17 +49,11 @@ struct private_private_key_t {
        ed25519_key key;
 
        /**
-        * Key type
-        */
-       key_type_t type;
-
-       /**
-        * reference count
+        * Reference count
         */
        refcount_t ref;
 };
 
-
 /* from ed public key */
 bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
                                                        chunk_t *fp);
@@ -68,17 +63,17 @@ METHOD(private_key_t, sign, bool,
        void *params, chunk_t data, chunk_t *signature)
 {
        word32 len;
-       int ret;
        byte dummy[1];
+       int ret;
 
-       if (this->type == KEY_ED25519 && scheme != SIGN_ED25519)
+       if (scheme != SIGN_ED25519)
        {
                DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
-                        signature_scheme_names, scheme, key_type_names, this->type);
+                        signature_scheme_names, scheme, key_type_names, KEY_ED25519);
                return FALSE;
        }
 
-       if (data.ptr == NULL && data.len == 0)
+       if (!data.ptr && !data.len)
        {
                data.ptr = dummy;
        }
@@ -86,7 +81,7 @@ METHOD(private_key_t, sign, bool,
        len = ED25519_SIG_SIZE;
        *signature = chunk_alloc(len);
        ret = wc_ed25519_sign_msg(data.ptr, data.len, signature->ptr, &len,
-                                                          &this->key);
+                                                         &this->key);
        return ret == 0;
 }
 
@@ -107,7 +102,7 @@ METHOD(private_key_t, get_keysize, int,
 METHOD(private_key_t, get_type, key_type_t,
        private_private_key_t *this)
 {
-       return this->type;
+       return KEY_ED25519;
 }
 
 METHOD(private_key_t, get_public_key, public_key_t*,
@@ -117,14 +112,12 @@ METHOD(private_key_t, get_public_key, public_key_t*,
        chunk_t key;
        word32 len = ED25519_PUB_KEY_SIZE;
 
-       /* Allocate on stack */
        key = chunk_alloca(len);
        if (wc_ed25519_export_public(&this->key, key.ptr, &len) != 0)
        {
-               chunk_free(&key);
                return NULL;
        }
-       public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type,
+       public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
                                                                BUILD_EDDSA_PUB, key, BUILD_END);
        return public;
 }
@@ -148,7 +141,9 @@ METHOD(private_key_t, get_encoding, bool,
                {
                        bool success = TRUE;
 
-                       *encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 20);
+                       /* +4 is for the two octet strings */
+                       *encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 2 * MAX_SEQ_SZ +
+                                                                       MAX_VERSION_SZ + MAX_ALGO_SZ + 4);
                        ret = wc_Ed25519PrivateKeyToDer(&this->key, encoding->ptr,
                                                                                        encoding->len);
                        if (ret < 0)
@@ -195,7 +190,7 @@ METHOD(private_key_t, destroy, void,
 /**
  * Internal generic constructor
  */
-static private_private_key_t *create_internal(key_type_t type)
+static private_private_key_t *create_internal()
 {
        private_private_key_t *this;
 
@@ -214,7 +209,6 @@ static private_private_key_t *create_internal(key_type_t type)
                        .get_ref = _get_ref,
                        .destroy = _destroy,
                },
-               .type = type,
                .ref = 1,
        );
 
@@ -235,12 +229,6 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args)
        WC_RNG rng;
        int ret;
 
-       if (wc_InitRng(&rng) != 0)
-       {
-               DBG1(DBG_LIB, "initializing random failed");
-               return NULL;
-       }
-
        while (TRUE)
        {
                switch (va_arg(args, builder_part_t))
@@ -257,31 +245,52 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args)
                break;
        }
 
-       switch (type)
+       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);
index d09eb48..879dfa7 100644 (file)
 #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;
        }
@@ -106,6 +101,25 @@ METHOD(public_key_t, get_keysize, int,
 }
 
 /**
+ * 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.
  */
 bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
@@ -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;
        }
index d87364a..5e9d851 100644 (file)
@@ -34,17 +34,17 @@ typedef struct private_wolfssl_hasher_t private_wolfssl_hasher_t;
 struct private_wolfssl_hasher_t {
 
        /**
-        * Public part of this class.
+        * Public interface
         */
        wolfssl_hasher_t public;
 
        /**
-        * the hasher to use
+        * The hasher to use
         */
        wc_HashAlg hasher;
 
        /**
-        * the hash algiorithm
+        * The hash algorithm
         */
        enum wc_HashType type;
 };
@@ -128,6 +128,5 @@ wolfssl_hasher_t *wolfssl_hasher_create(hash_algorithm_t algo)
                destroy(this);
                return NULL;
        }
-
        return &this->public;
 }
index 27eb6a6..a28beb4 100644 (file)
@@ -77,10 +77,10 @@ METHOD(mac_t, get_mac, bool,
        if (this->key_set)
        {
                ret = wc_HmacUpdate(&this->hmac, data.ptr, data.len);
-       }
-       if (ret == 0 && out != NULL)
-       {
-               ret = wc_HmacFinal(&this->hmac, out);
+               if (ret == 0 && out)
+               {
+                       ret = wc_HmacFinal(&this->hmac, out);
+               }
        }
        return ret == 0;
 }
@@ -121,14 +121,12 @@ static mac_t *hmac_create(hash_algorithm_t algo)
                .type = type,
        );
 
-       
        if (wc_HmacInit(&this->hmac, NULL, INVALID_DEVID) != 0)
        {
                DBG1(DBG_LIB, "HMAC init failed, hmac create failed\n");
                free(this);
                return NULL;
        }
-
        return &this->public;
 }
 
index b091a20..925f08e 100644 (file)
 #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
index 86a8d8a..73b8584 100644 (file)
@@ -37,7 +37,7 @@ typedef struct private_wolfssl_rng_t private_wolfssl_rng_t;
 wolfSSL_Mutex globalRngMutex;
 #endif
 static WC_RNG globalRng;
-static int globalRngInit = 0;
+static bool globalRngInit;
 
 /**
  * Private data of wolfssl_rng_t
@@ -67,7 +67,7 @@ METHOD(rng_t, get_bytes, bool,
                ret = wc_LockMutex(&globalRngMutex);
                if (ret != 0)
                {
-                       DBG1(DBG_LIB, "Locking failed, get bytes failed");
+                       DBG1(DBG_LIB, "locking failed, get bytes failed");
                        return FALSE;
                }
        }
@@ -107,7 +107,7 @@ METHOD(rng_t, destroy, void,
 }
 
 /*
- * Described in header.
+ * Described in header
  */
 wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
 {
@@ -129,7 +129,7 @@ wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
                this->rng = malloc(sizeof(*this->rng));
                if (wc_InitRng(this->rng) != 0)
                {
-                       DBG1(DBG_LIB, "Init RNG failed, rng create failed");
+                       DBG1(DBG_LIB, "init RNG failed, rng create failed");
                        free(this->rng);
                        free(this);
                        return NULL;
@@ -139,7 +139,7 @@ wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
 }
 
 /*
- * Described in header.
+ * Described in header
  */
 int wolfssl_rng_global_init()
 {
@@ -150,25 +150,24 @@ int wolfssl_rng_global_init()
                ret = wc_InitRng(&globalRng);
                if (ret != 0)
                {
-                       DBG1(DBG_LIB, "Init RNG failed, rng global init failed");
+                       DBG1(DBG_LIB, "init RNG failed, rng global init failed");
                }
 #ifndef SINGLE_THREADED
                else if ((ret = wc_InitMutex(&globalRngMutex)) != 0)
                {
-                       DBG1(DBG_LIB, "Init Mutex failed, rng global init failed");
+                       DBG1(DBG_LIB, "init Mutex failed, rng global init failed");
                }
 #endif
                else
                {
-                       globalRngInit = 1;
+                       globalRngInit = TRUE;
                }
        }
-
        return ret == 0;
 }
 
 /*
- * Described in header.
+ * Described in header
  */
 void wolfssl_rng_global_final()
 {
@@ -178,7 +177,7 @@ void wolfssl_rng_global_final()
                wc_FreeMutex(&globalRngMutex);
 #endif
                wc_FreeRng(&globalRng);
-               globalRngInit = 0;
+               globalRngInit = FALSE;
        }
 }
 
index c3ddd5c..39d3e02 100644 (file)
 #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)
index 669dc08..2824e9a 100644 (file)
 #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;
        }
-
-       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;
 }
 
@@ -298,6 +282,25 @@ METHOD(public_key_t, get_keysize, int,
 }
 
 /**
+ * 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.
  */
 bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type,
@@ -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;
                                }
index fa08356..fa90288 100644 (file)
@@ -37,7 +37,7 @@ typedef struct private_wolfssl_sha1_prf_t private_wolfssl_sha1_prf_t;
 struct private_wolfssl_sha1_prf_t {
 
        /**
-        * Public wolfssl_sha1_prf_t interface.
+        * Public wolfssl_sha1_prf_t interface
         */
        wolfssl_sha1_prf_t public;
 
@@ -65,7 +65,6 @@ METHOD(prf_t, get_bytes, bool,
                hash[3] = htonl(this->sha1.digest[3]);
                hash[4] = htonl(this->sha1.digest[4]);
        }
-
        return TRUE;
 }
 
@@ -134,18 +133,13 @@ METHOD(prf_t, destroy, void,
        free(this);
 }
 
-/**
- * See header
+/*
+ * Described in header
  */
 wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
 {
        private_wolfssl_sha1_prf_t *this;
 
-       if (algo != PRF_KEYED_SHA1)
-       {
-               return NULL;
-       }
-
        INIT(this,
                .public = {
                        .prf = {
@@ -164,7 +158,6 @@ wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
                free(this);
                return NULL;
        }
-
        return &this->public;
 }
 
index 7f6a32e..89e12c4 100644 (file)
@@ -48,7 +48,7 @@ struct wolfssl_sha1_prf_t {
  * Creates a new wolfssl_sha1_prf_t.
  *
  * @param algo         algorithm, must be PRF_KEYED_SHA1
- * @return                     sha1_keyed_prf_tobject
+ * @return                     wolfssl_sha1_prf_t object
  */
 wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo);
 
index cc8054a..c83c298 100644 (file)
@@ -28,8 +28,8 @@
 #include <wolfssl/wolfcrypt/hash.h>
 #include <wolfssl/wolfcrypt/rsa.h>
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
 {
@@ -45,8 +45,8 @@ bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
        return TRUE;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
 {
@@ -63,8 +63,8 @@ bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
        return FALSE;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
 {
@@ -82,12 +82,11 @@ bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
        {
                ret = mp_read_unsigned_bin(b, chunk.ptr + len, len);
        }
-
        return ret == 0;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
 {
@@ -109,85 +108,84 @@ bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
                memset(chunk->ptr + len, 0, len - sz);
                ret = mp_to_unsigned_bin(b, chunk->ptr + 2 * len - sz);
        }
-
        return ret == 0;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type)
 {
        switch (hash)
        {
-       #ifndef NO_MD5
+#ifndef NO_MD5
                case HASH_MD5:
                        *type = WC_HASH_TYPE_MD5;
                        break;
-       #endif
-       #ifndef NO_SHA
+#endif
+#ifndef NO_SHA
                case HASH_SHA1:
                        *type = WC_HASH_TYPE_SHA;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA224
+#endif
+#ifdef WOLFSSL_SHA224
                case HASH_SHA224:
                        *type = WC_HASH_TYPE_SHA224;
                        break;
-       #endif
-       #ifndef NO_SHA256
+#endif
+#ifndef NO_SHA256
                case HASH_SHA256:
                        *type = WC_HASH_TYPE_SHA256;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case HASH_SHA384:
                        *type = WC_HASH_TYPE_SHA384;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case HASH_SHA512:
                        *type = WC_HASH_TYPE_SHA512;
                        break;
-       #endif
+#endif
                default:
                        return FALSE;
        }
        return TRUE;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 bool wolfssl_hash2mgf1(hash_algorithm_t hash, int *mgf1)
 {
        switch (hash)
        {
-       #ifndef NO_SHA
+#ifndef NO_SHA
                case HASH_SHA1:
                        *mgf1 = WC_MGF1SHA1;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA224
+#endif
+#ifdef WOLFSSL_SHA224
                case HASH_SHA224:
                        *mgf1 = WC_MGF1SHA224;
                        break;
-       #endif
-       #ifndef NO_SHA256
+#endif
+#ifndef NO_SHA256
                case HASH_SHA256:
                        *mgf1 = WC_MGF1SHA256;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA384
+#endif
+#ifdef WOLFSSL_SHA384
                case HASH_SHA384:
                        *mgf1 = WC_MGF1SHA384;
                        break;
-       #endif
-       #ifdef WOLFSSL_SHA512
+#endif
+#ifdef WOLFSSL_SHA512
                case HASH_SHA512:
                        *mgf1 = WC_MGF1SHA512;
                        break;
-       #endif
+#endif
                default:
                        return FALSE;
        }
index b752ce0..5c21eb6 100644 (file)
@@ -56,11 +56,6 @@ struct private_diffie_hellman_t {
         * Shared secret
         */
        chunk_t shared_secret;
-
-       /**
-        * True if shared secret is computed
-        */
-       bool computed;
 };
 
 /**
@@ -69,8 +64,8 @@ struct private_diffie_hellman_t {
 static bool compute_shared_key(private_diffie_hellman_t *this,
                                                           curve25519_key *pub, chunk_t *shared_secret)
 {
-       int ret;
        word32 len = CURVE25519_KEYSIZE;
+       int ret;
 
        *shared_secret = chunk_alloc(len);
        ret = wc_curve25519_shared_secret_ex(&this->key, pub, shared_secret->ptr,
@@ -81,8 +76,8 @@ static bool compute_shared_key(private_diffie_hellman_t *this,
 METHOD(diffie_hellman_t, set_other_public_value, bool,
        private_diffie_hellman_t *this, chunk_t value)
 {
-       int ret;
        curve25519_key pub;
+       int ret;
 
        if (!diffie_hellman_verify_value(this->group, value))
        {
@@ -90,7 +85,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
        }
 
        ret = wc_curve25519_init(&pub);
-       if (ret < 0)
+       if (ret != 0)
        {
                DBG1(DBG_LIB, "%N public key initialization failed",
                         diffie_hellman_group_names, this->group);
@@ -112,10 +107,10 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
        {
                DBG1(DBG_LIB, "%N shared secret computation failed",
                         diffie_hellman_group_names, this->group);
+               chunk_clear(&this->shared_secret);
                wc_curve25519_free(&pub);
                return FALSE;
        }
-       this->computed = TRUE;
        wc_curve25519_free(&pub);
        return TRUE;
 }
@@ -138,13 +133,13 @@ METHOD(diffie_hellman_t, get_my_public_value, bool,
 METHOD(diffie_hellman_t, set_private_value, bool,
        private_diffie_hellman_t *this, chunk_t value)
 {
-       int ret;
-       unsigned char basepoint[CURVE25519_KEYSIZE] = {9};
        curve25519_key pub;
-       int len;
+       u_char basepoint[CURVE25519_KEYSIZE] = {9};
+       word32 len = CURVE25519_KEYSIZE;
+       int ret;
 
        ret = wc_curve25519_init(&pub);
-       /* Create base point for calculating public key */
+       /* create base point for calculating public key */
        if (ret == 0)
        {
                ret = wc_curve25519_import_public_ex(basepoint, CURVE25519_KEYSIZE,
@@ -157,22 +152,16 @@ METHOD(diffie_hellman_t, set_private_value, bool,
        }
        if (ret == 0)
        {
-               len = CURVE25519_KEYSIZE;
                ret = wc_curve25519_shared_secret_ex(&this->key, &pub,
-                               this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
-               if (ret > 0)
-               {
-                       ret = 0;
-               }
+                                                               this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
        }
-
        return ret == 0;
 }
 
 METHOD(diffie_hellman_t, get_shared_secret, bool,
        private_diffie_hellman_t *this, chunk_t *secret)
 {
-       if (!this->computed)
+       if (!this->shared_secret.len)
        {
                return FALSE;
        }
@@ -203,14 +192,6 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
        WC_RNG rng;
        int ret;
 
-       switch (group)
-       {
-               case CURVE_25519:
-                       break;
-               default:
-                       return NULL;
-       }
-
        INIT(this,
                .public = {
                        .get_shared_secret = _get_shared_secret,
@@ -225,23 +206,23 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
 
        if (wc_curve25519_init(&this->key) != 0)
        {
-               DBG1(DBG_LIB, "Initializing key failed");
+               DBG1(DBG_LIB, "initializing key failed");
                free(this);
                return NULL;
        }
 
        if (wc_InitRng(&rng) != 0)
        {
-               DBG1(DBG_LIB, "Initializing a random number generator failed");
-               free(this);
+               DBG1(DBG_LIB, "initializing a random number generator failed");
+               destroy(this);
                return NULL;
        }
        ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &this->key);
        wc_FreeRng(&rng);
        if (ret != 0)
        {
-               DBG1(DBG_LIB, "Making a key failed");
-               free(this);
+               DBG1(DBG_LIB, "making a key failed");
+               destroy(this);
                return NULL;
        }
        return &this->public;
index 5e0b7b1..a66ddc1 100644 (file)
@@ -41,4 +41,3 @@
 diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group);
 
 #endif /** WOLFSSL_X_DIFFIE_HELLMAN_H_ @}*/
-