diff --git a/src/ssl.c b/src/ssl.c index 24591613b..58cc6fe94 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1575,6 +1575,20 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +static const char *EVP_AES_128_CBC = "AES-128-CBC"; +static const char *EVP_AES_192_CBC = "AES-192-CBC"; +static const char *EVP_AES_256_CBC = "AES-256-CBC"; +static const char *EVP_AES_128_CTR = "AES-128-CTR"; +static const char *EVP_AES_192_CTR = "AES-192-CTR"; +static const char *EVP_AES_256_CTR = "AES-256-CTR"; +static const int EVP_AES_SIZE = 11; + +static const char *EVP_DES_CBC = "DES-CBC"; +static const int EVP_DES_SIZE = 7; + +static const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC"; +static const int EVP_DES_EDE3_SIZE = 12; + /* our KeyPemToDer password callback, password in userData */ static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata) { @@ -1663,7 +1677,6 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, } XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY); - return ret; } @@ -2191,6 +2204,7 @@ int wolfSSL_Init(void) #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +/* SSL_SUCCESS if ok, <= 0 else */ static int wolfssl_decrypt_buffer_key(buffer* der, byte* password, int passwordSz, EncryptedInfo* info) { @@ -2198,63 +2212,60 @@ static int wolfssl_decrypt_buffer_key(buffer* der, byte* password, #ifdef WOLFSSL_SMALL_STACK byte* key = NULL; - byte* iv = NULL; #else byte key[AES_256_KEY_SIZE]; -#ifndef NO_MD5 - byte iv[AES_IV_SIZE]; -#endif #endif - if (der == NULL || password == NULL || info == NULL) + WOLFSSL_ENTER("wolfssl_decrypt_buffer_key"); + + if (der == NULL || password == NULL || info == NULL) { + WOLFSSL_MSG("bad arguments"); return SSL_FATAL_ERROR; + } /* use file's salt for key derivation, hex decode first */ - if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) - return ASN_INPUT_E; + if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) { + WOLFSSL_MSG("base16 decode failed"); + return SSL_FATAL_ERROR; + } #ifndef NO_MD5 #ifdef WOLFSSL_SMALL_STACK - iv = (byte*)XMALLOC(AES_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (iv == NULL) - return MEMORY_E; - key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { - XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; + WOLFSSL_MSG("memory failure"); + return SSL_FATAL_ERROR; } #endif /* WOLFSSL_SMALL_STACK */ - if ((ret = EVP_BytesToKey(info->name, "MD5", info->iv, - password, passwordSz, 1, key, iv)) <= 0) { - + if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv, + password, passwordSz, 1, key, NULL)) <= 0) { + WOLFSSL_MSG("bytes to key failure"); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ASN_INPUT_E; + return SSL_FATAL_ERROR; } #endif /* NO_MD5 */ #ifndef NO_DES3 - if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) + if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0) ret = wc_Des_CbcDecryptWithKey(der->buffer, der->buffer, der->length, key, info->iv); - else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 12) == 0) + else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) ret = wc_Des3_CbcDecryptWithKey(der->buffer, der->buffer, der->length, key, info->iv); #endif /* NO_DES3 */ #ifndef NO_AES - else if (XSTRNCMP(info->name, "AES-128-CBC", 11) == 0) + else if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length, key, AES_128_KEY_SIZE, info->iv); - else if (XSTRNCMP(info->name, "AES-192-CBC", 11) == 0) + else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length, key, AES_192_KEY_SIZE, info->iv); - else if (XSTRNCMP(info->name, "AES-256-CBC", 11) == 0) + else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length, key, AES_256_KEY_SIZE, info->iv); #endif /* NO_AES */ @@ -2263,34 +2274,93 @@ static int wolfssl_decrypt_buffer_key(buffer* der, byte* password, #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ret; + if (ret == MP_OKAY) + return SSL_SUCCESS; + else if (ret == SSL_BAD_FILE) + return SSL_BAD_FILE; + + return SSL_FATAL_ERROR; } #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */ -#ifndef NO_CERTS +#if defined(WOLFSSL_KEY_GEN) +static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password, + int passwordSz, EncryptedInfo* info) +{ + int ret; -static const char* BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; -static const char* END_CERT = "-----END CERTIFICATE-----"; -static const char* BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----"; -static const char* END_CERT_REQ = "-----END CERTIFICATE REQUEST-----"; -static const char* BEGIN_DH_PARAM = "-----BEGIN DH PARAMETERS-----"; -static const char* END_DH_PARAM = "-----END DH PARAMETERS-----"; -static const char* BEGIN_X509_CRL = "-----BEGIN X509 CRL-----"; -static const char* END_X509_CRL = "-----END X509 CRL-----"; -static const char* BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----"; -static const char* END_RSA_PRIV = "-----END RSA PRIVATE KEY-----"; -static const char* BEGIN_PRIV_KEY = "-----BEGIN PRIVATE KEY-----"; -static const char* END_PRIV_KEY = "-----END PRIVATE KEY-----"; -static const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; -static const char* END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----"; -static const char* BEGIN_EC_PRIV = "-----BEGIN EC PRIVATE KEY-----"; -static const char* END_EC_PRIV = "-----END EC PRIVATE KEY-----"; -static const char* BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----"; -static const char* END_DSA_PRIV = "-----END DSA PRIVATE KEY-----"; +#ifdef WOLFSSL_SMALL_STACK + byte* key = NULL; +#else + byte key[AES_256_KEY_SIZE]; +#endif + + WOLFSSL_ENTER("wolfssl_encrypt_buffer_key"); + + if (der == NULL || password == NULL || info == NULL || info->ivSz == 0) { + WOLFSSL_MSG("bad arguments"); + return SSL_FATAL_ERROR; + } + +#ifndef NO_MD5 + +#ifdef WOLFSSL_SMALL_STACK + key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (key == NULL) { + WOLFSSL_MSG("memory failure"); + return SSL_FATAL_ERROR; + } +#endif /* WOLFSSL_SMALL_STACK */ + + if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv, + password, passwordSz, 1, key, NULL)) <= 0) { + WOLFSSL_MSG("bytes to key failure"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return SSL_FATAL_ERROR; + } + +#endif /* NO_MD5 */ + +#ifndef NO_DES3 + if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0) + ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv); + else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) + ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv); +#endif /* NO_DES3 */ +#ifndef NO_AES + else if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) + ret = wc_AesCbcEncryptWithKey(der, der, derSz, + key, AES_128_KEY_SIZE, info->iv); + else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) + ret = wc_AesCbcEncryptWithKey(der, der, derSz, + key, AES_192_KEY_SIZE, info->iv); + else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) + ret = wc_AesCbcEncryptWithKey(der, der, derSz, + key, AES_256_KEY_SIZE, info->iv); +#endif /* NO_AES */ + else + ret = SSL_BAD_FILE; + +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + if (ret == MP_OKAY) + return SSL_SUCCESS; + else if (ret == SSL_BAD_FILE) + return SSL_BAD_FILE; + + return SSL_FATAL_ERROR; +} +#endif /* defined(WOLFSSL_KEY_GEN) */ + + +#ifndef NO_CERTS /* Remove PEM header/footer, convert to ASN1, store any encrypted data info->consumed tracks of PEM bytes consumed in case multiple parts */ @@ -2309,6 +2379,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type, int sz = (int)longSz; int encrypted_key = 0; + WOLFSSL_ENTER("PemToDer"); + switch (type) { case CA_TYPE: /* same as below */ case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT; break; @@ -2390,9 +2462,11 @@ int PemToDer(const unsigned char* buff, long longSz, int type, if (start && finish && (start < finish)) { newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN); - XMEMCPY(info->name, start, finish - start); + if (XMEMCPY(info->name, start, finish - start) == NULL) + return SSL_FATAL_ERROR; info->name[finish - start] = 0; - XMEMCPY(info->iv, finish + 1, sizeof(info->iv)); + if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL) + return SSL_FATAL_ERROR; if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN); if (newline && (newline > finish)) { @@ -2499,7 +2573,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, #ifdef WOLFSSL_SMALL_STACK XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - if (ret != 0) { + if (ret != SSL_SUCCESS) { XFREE(der->buffer, heap, dynamicType); return ret; } @@ -2731,7 +2805,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - if (ret != 0) { + if (ret != SSL_SUCCESS) { #ifdef WOLFSSL_SMALL_STACK XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -7497,30 +7571,30 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return 0; #endif - WOLFSSL_ENTER("EVP_BytesToKey"); + WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey"); wc_InitMd5(md5); /* only support MD5 for now */ if (XSTRNCMP(md, "MD5", 3) != 0) return 0; /* only support CBC DES and AES for now */ - if (XSTRNCMP(type, "DES-CBC", 7) == 0) { + if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) { keyLen = DES_KEY_SIZE; ivLen = DES_IV_SIZE; } - else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) { + else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) { keyLen = DES3_KEY_SIZE; ivLen = DES_IV_SIZE; } - else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) { + else if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) { keyLen = AES_128_KEY_SIZE; ivLen = AES_IV_SIZE; } - else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) { + else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) { keyLen = AES_192_KEY_SIZE; ivLen = AES_IV_SIZE; } - else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) { + else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) { keyLen = AES_256_KEY_SIZE; ivLen = AES_IV_SIZE; } @@ -7562,8 +7636,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (ivLeft && digestLeft) { int store = min(ivLeft, digestLeft); - XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE - - digestLeft], store); + if (iv != NULL) + XMEMCPY(&iv[ivLen - ivLeft], + &digest[MD5_DIGEST_SIZE - digestLeft], store); keyOutput += store; ivLeft -= store; } @@ -7821,68 +7896,59 @@ int wolfSSL_set_compression(WOLFSSL* ssl) /* do nothing */ } - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void) { - static const char* type = "AES128-CBC"; WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc"); - return type; + return EVP_AES_128_CBC; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void) { - static const char* type = "AES192-CBC"; WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc"); - return type; + return EVP_AES_192_CBC; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void) { - static const char* type = "AES256-CBC"; WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc"); - return type; + return EVP_AES_256_CBC; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void) { - static const char* type = "AES128-CTR"; WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr"); - return type; + return EVP_AES_128_CTR; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void) { - static const char* type = "AES192-CTR"; WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr"); - return type; + return EVP_AES_192_CTR; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void) { - static const char* type = "AES256-CTR"; WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr"); - return type; + return EVP_AES_256_CTR; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void) { - static const char* type = "DES-CBC"; WOLFSSL_ENTER("wolfSSL_EVP_des_cbc"); - return type; + return EVP_DES_CBC; } const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void) { - static const char* type = "DES-EDE3-CBC"; WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc"); - return type; + return EVP_DES_EDE3_CBC; } @@ -7959,9 +8025,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } #ifndef NO_AES - if (ctx->cipherType == AES_128_CBC_TYPE || (type && - XSTRNCMP(type, "AES128-CBC", 10) == 0)) { - WOLFSSL_MSG("AES-128-CBC"); + if (ctx->cipherType == AES_128_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_128_CBC); ctx->cipherType = AES_128_CBC_TYPE; ctx->keyLen = 16; if (enc == 0 || enc == 1) @@ -7978,9 +8044,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ret; } } - else if (ctx->cipherType == AES_192_CBC_TYPE || (type && - XSTRNCMP(type, "AES192-CBC", 10) == 0)) { - WOLFSSL_MSG("AES-192-CBC"); + else if (ctx->cipherType == AES_192_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_192_CBC); ctx->cipherType = AES_192_CBC_TYPE; ctx->keyLen = 24; if (enc == 0 || enc == 1) @@ -7997,9 +8063,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ret; } } - else if (ctx->cipherType == AES_256_CBC_TYPE || (type && - XSTRNCMP(type, "AES256-CBC", 10) == 0)) { - WOLFSSL_MSG("AES-256-CBC"); + else if (ctx->cipherType == AES_256_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_256_CBC); ctx->cipherType = AES_256_CBC_TYPE; ctx->keyLen = 32; if (enc == 0 || enc == 1) @@ -8017,9 +8083,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } #ifdef WOLFSSL_AES_COUNTER - else if (ctx->cipherType == AES_128_CTR_TYPE || (type && - XSTRNCMP(type, "AES128-CTR", 10) == 0)) { - WOLFSSL_MSG("AES-128-CTR"); + else if (ctx->cipherType == AES_128_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_128_CTR); ctx->cipherType = AES_128_CTR_TYPE; ctx->keyLen = 16; if (enc == 0 || enc == 1) @@ -8036,9 +8102,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ret; } } - else if (ctx->cipherType == AES_192_CTR_TYPE || (type && - XSTRNCMP(type, "AES192-CTR", 10) == 0)) { - WOLFSSL_MSG("AES-192-CTR"); + else if (ctx->cipherType == AES_192_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_192_CTR); ctx->cipherType = AES_192_CTR_TYPE; ctx->keyLen = 24; if (enc == 0 || enc == 1) @@ -8055,9 +8121,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ret; } } - else if (ctx->cipherType == AES_256_CTR_TYPE || (type && - XSTRNCMP(type, "AES256-CTR", 10) == 0)) { - WOLFSSL_MSG("AES-256-CTR"); + else if (ctx->cipherType == AES_256_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_256_CTR); ctx->cipherType = AES_256_CTR_TYPE; ctx->keyLen = 32; if (enc == 0 || enc == 1) @@ -8078,9 +8144,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif /* NO_AES */ #ifndef NO_DES3 - else if (ctx->cipherType == DES_CBC_TYPE || (type && - XSTRNCMP(type, "DES-CBC", 7) == 0)) { - WOLFSSL_MSG("DES-CBC"); + else if (ctx->cipherType == DES_CBC_TYPE || + (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_CBC); ctx->cipherType = DES_CBC_TYPE; ctx->keyLen = 8; if (enc == 0 || enc == 1) @@ -8095,9 +8161,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (iv && key == NULL) wc_Des_SetIV(&ctx->cipher.des, iv); } - else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type && - XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) { - WOLFSSL_MSG("DES-EDE3-CBC"); + else if (ctx->cipherType == DES_EDE3_CBC_TYPE || + (type && + XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_EDE3_CBC); ctx->cipherType = DES_EDE3_CBC_TYPE; ctx->keyLen = 24; if (enc == 0 || enc == 1) @@ -10875,7 +10942,7 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num) RNG tmpRNG[1]; #endif - WOLFSSL_ENTER("RAND_bytes"); + WOLFSSL_ENTER("wolfSSL_RAND_bytes"); #ifdef WOLFSSL_SMALL_STACK tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -10984,6 +11051,7 @@ void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn) bn->internal = NULL; } XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT); + bn = NULL; } } @@ -11286,7 +11354,7 @@ int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n) return SSL_FAILURE; } - if (mp_set_int((mp_int*)bn->internal, n) != MP_OKAY) { + if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) { WOLFSSL_MSG("mp_set_int error"); return SSL_FAILURE; } @@ -11412,6 +11480,38 @@ int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str) } +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) +char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn) +{ + int len = 0; + char *buf; + + WOLFSSL_MSG("wolfSSL_BN_bn2dec"); + + if (bn == NULL || bn->internal == NULL) { + WOLFSSL_MSG("bn NULL error"); + return NULL; + } + + if (mp_radix_size((mp_int*)bn->internal, 10, &len) != MP_OKAY) { + WOLFSSL_MSG("mp_radix_size failure"); + return NULL; + } + + buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC); + if (buf == NULL) { + WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure"); + return NULL; + } + + if (mp_toradix((mp_int*)bn->internal, buf, 10) != MP_OKAY) { + XFREE(buf, NULL, DYNAMIC_TYPE_ECC); + return NULL; + } + + return buf; +} +#else char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn) { (void)bn; @@ -11420,6 +11520,7 @@ char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn) return NULL; } +#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ /* return code compliant with OpenSSL : * 1 if success, 0 else @@ -11536,7 +11637,6 @@ int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks, return SSL_SUCCESS; } -#endif /* #ifdef WOLFSSL_KEY_GEN */ /* return code compliant with OpenSSL : * (bn mod w) if success, -1 if error @@ -11544,7 +11644,6 @@ int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks, WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) { - mp_int mod, res; WOLFSSL_BN_ULONG ret = 0; WOLFSSL_MSG("wolfSSL_BN_mod_word"); @@ -11554,32 +11653,16 @@ WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn, return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR; } - if (mp_init_multi(&mod, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { - WOLFSSL_MSG("mp_init error"); - return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR; - } - - if (mp_set_int(&mod, w) != MP_OKAY) { - WOLFSSL_MSG("mp_set_int error"); - mp_clear(&mod); - return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR; - } - - if (mp_mod((mp_int*)bn->internal, &mod, &res) != MP_OKAY) { + if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) { WOLFSSL_MSG("mp_add_d error"); - mp_clear(&mod); - mp_clear(&res); return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR; } - ret = res.dp[0]; - - mp_clear(&mod); - mp_clear(&res); return ret; } +#endif /* #ifdef WOLFSSL_KEY_GEN */ -#if (defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)) && defined(HAVE_ECC) +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn) { int len = 0; @@ -11639,7 +11722,7 @@ int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn) } #endif /* !defined(NO_FILESYSTEM) */ -#else /* defined(HAVE_ECC) */ +#else /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn) { @@ -11665,7 +11748,7 @@ int wolfSSL_BN_print_fp(FILE *fp, const WOLFSSL_BIGNUM *bn) } #endif /* !defined(NO_FILESYSTEM) */ -#endif /*(defined(WOLFSSL_KEY_GEN)||defined(HAVE_COMP_KEY))&&defined(HAVE_ECC)*/ +#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx) { @@ -12042,36 +12125,9 @@ void wolfSSL_DSA_free(WOLFSSL_DSA* dsa) InitwolfSSL_DSA(dsa); /* set back to NULLs for safety */ XFREE(dsa, NULL, DYNAMIC_TYPE_DSA); + dsa = NULL; } } - - -int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) -{ - (void)dsa; - - WOLFSSL_MSG("wolfSSL_DSA_generate_key"); - - return 0; /* key gen not needed by server */ -} - - -int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, - unsigned char* seed, int seedLen, int* counterRet, - unsigned long* hRet, void* cb) -{ - (void)dsa; - (void)bits; - (void)seed; - (void)seedLen; - (void)counterRet; - (void)hRet; - (void)cb; - - WOLFSSL_MSG("wolfSSL_DSA_generate_parameters_ex"); - - return 0; /* key gen not needed by server */ -} #endif /* NO_DSA */ #ifndef NO_RSA @@ -12148,6 +12204,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); + rsa = NULL; } } #endif /* NO_RSA */ @@ -12183,7 +12240,7 @@ static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi) { WOLFSSL_MSG("Entering SetIndividualInternal"); - if (bn == NULL) { + if (bn == NULL || bn->internal == NULL) { WOLFSSL_MSG("bn NULL error"); return SSL_FATAL_ERROR; } @@ -12278,16 +12335,24 @@ static int SetDsaInternal(WOLFSSL_DSA* dsa) return SSL_FATAL_ERROR; } - if (dsa->pub_key != NULL && - SetIndividualInternal(dsa->pub_key, &key->y) != SSL_SUCCESS) { - WOLFSSL_MSG("rsa pub_key error"); - return SSL_FATAL_ERROR; + if (dsa->pub_key != NULL) { + if (SetIndividualInternal(dsa->pub_key, &key->y) != SSL_SUCCESS) { + WOLFSSL_MSG("rsa pub_key error"); + return SSL_FATAL_ERROR; + } + + /* public key */ + key->type = DSA_PUBLIC; } - if (dsa->priv_key != NULL && - SetIndividualInternal(dsa->priv_key, &key->x) != SSL_SUCCESS) { - WOLFSSL_MSG("rsa priv_key error"); - return SSL_FATAL_ERROR; + if (dsa->priv_key != NULL) { + if (SetIndividualInternal(dsa->priv_key, &key->x) != SSL_SUCCESS) { + WOLFSSL_MSG("rsa priv_key error"); + return SSL_FATAL_ERROR; + } + + /* private key */ + key->type = DSA_PRIVATE; } dsa->inSet = 1; @@ -12379,10 +12444,17 @@ static int SetRsaInternal(WOLFSSL_RSA* rsa) return SSL_FATAL_ERROR; } - if (rsa->d != NULL && - SetIndividualInternal(rsa->d, &key->d) != SSL_SUCCESS) { - WOLFSSL_MSG("rsa d key error"); - return SSL_FATAL_ERROR; + /* public key */ + key->type = RSA_PUBLIC; + + if (rsa->d != NULL) { + if (SetIndividualInternal(rsa->d, &key->d) != SSL_SUCCESS) { + WOLFSSL_MSG("rsa d key error"); + return SSL_FATAL_ERROR; + } + + /* private key */ + key->type = RSA_PRIVATE; } if (rsa->p != NULL && @@ -12421,19 +12493,25 @@ static int SetRsaInternal(WOLFSSL_RSA* rsa) } -/* SSL_SUCCESS on ok */ +/* return compliant with OpenSSL + * 1 if success, 0 if error + */ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, void* cb) { - int ret = SSL_FATAL_ERROR; + int ret = SSL_FAILURE; - WOLFSSL_MSG("wolfSSL_RSA_generate_key_ex"); - - (void)rsa; - (void)bits; (void)cb; (void)bn; + WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex"); + + if (rsa == NULL || rsa->internal == NULL || + bits < RSA_MIN_SIZE || bits > RSA_MAX_SIZE) { + WOLFSSL_MSG("bad arguments"); + return SSL_FAILURE; + } + #ifdef WOLFSSL_KEY_GEN { #ifdef WOLFSSL_SMALL_STACK @@ -12445,12 +12523,13 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, #ifdef WOLFSSL_SMALL_STACK rng = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (rng == NULL) - return SSL_FATAL_ERROR; + return SSL_FAILURE; #endif if (wc_InitRng(rng) < 0) WOLFSSL_MSG("RNG init failed"); - else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, rng) < 0) + else if (wc_MakeRsaKey((RsaKey*)rsa->internal, + bits, 65537, rng) != MP_OKAY) WOLFSSL_MSG("wc_MakeRsaKey failed"); else if (SetRsaExternal(rsa) != SSL_SUCCESS) WOLFSSL_MSG("SetRsaExternal failed"); @@ -12530,8 +12609,154 @@ int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa) } #endif /* NO_RSA */ - #ifndef NO_DSA +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) +{ + int ret = SSL_FAILURE; + + WOLFSSL_ENTER("wolfSSL_DSA_generate_key"); + + if (dsa == NULL || dsa->internal == NULL) { + WOLFSSL_MSG("Bad arguments"); + return SSL_FAILURE; + } + + if (dsa->inSet == 0) + { + WOLFSSL_MSG("No DSA internal set, do it"); + + if (SetDsaInternal(dsa) != SSL_SUCCESS) { + WOLFSSL_MSG("SetDsaInternal failed"); + return ret; + } + } + +#ifdef WOLFSSL_KEY_GEN + { + int initTmpRng = 0; + RNG *rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + RNG *tmpRNG = NULL; +#else + RNG tmpRNG[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmpRNG == NULL) + return SSL_FATAL_ERROR; +#endif + if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else { + WOLFSSL_MSG("Bad RNG Init, trying global"); + if (initGlobalRNG == 0) + WOLFSSL_MSG("Global RNG no Init"); + else + rng = &globalRNG; + } + + if (rng) { + if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY) + WOLFSSL_MSG("wc_MakeDsaKey failed"); + else if (SetDsaExternal(dsa) != SSL_SUCCESS) + WOLFSSL_MSG("SetDsaExternal failed"); + else + ret = SSL_SUCCESS; + } + + if (initTmpRng) + wc_FreeRng(tmpRNG); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + } +#else /* WOLFSSL_KEY_GEN */ + WOLFSSL_MSG("No Key Gen built in"); +#endif + return ret; +} + +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, + unsigned char* seed, int seedLen, + int* counterRet, + unsigned long* hRet, void* cb) +{ + int ret = SSL_FAILURE; + + (void)seed; + (void)seedLen; + (void)counterRet; + (void)hRet; + (void)cb; + + WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex"); + + if (dsa == NULL || dsa->internal == NULL) { + WOLFSSL_MSG("Bad arguments"); + return SSL_FAILURE; + } + +#ifdef WOLFSSL_KEY_GEN + { + int initTmpRng = 0; + RNG *rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + RNG *tmpRNG = NULL; +#else + RNG tmpRNG[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmpRNG == NULL) + return SSL_FATAL_ERROR; +#endif + if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else { + WOLFSSL_MSG("Bad RNG Init, trying global"); + if (initGlobalRNG == 0) + WOLFSSL_MSG("Global RNG no Init"); + else + rng = &globalRNG; + } + + if (rng) { + if (wc_MakeDsaParameters(rng, bits, + (DsaKey*)dsa->internal) != MP_OKAY) + WOLFSSL_MSG("wc_MakeDsaParameters failed"); + else if (SetDsaExternal(dsa) != SSL_SUCCESS) + WOLFSSL_MSG("SetDsaExternal failed"); + else + ret = SSL_SUCCESS; + } + + if (initTmpRng) + wc_FreeRng(tmpRNG); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + } +#else /* WOLFSSL_KEY_GEN */ + WOLFSSL_MSG("No Key Gen built in"); +#endif + + return ret; +} + /* return SSL_SUCCESS on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA* dsa) @@ -12561,6 +12786,7 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, return ret; } } + #ifdef WOLFSSL_SMALL_STACK tmpRNG = (RNG*)XMALLOC(sizeof(RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmpRNG == NULL) @@ -13147,20 +13373,123 @@ void wolfSSL_OPENSSL_free(void* p) XFREE(p, NULL, 0); } +#if defined(WOLFSSL_KEY_GEN) + +static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, + unsigned char* passwd, int passwdSz, byte **cipherInfo) +{ + int ret, paddingSz; + word32 idx, cipherInfoSz; +#ifdef WOLFSSL_SMALL_STACK + EncryptedInfo* info = NULL; +#else + EncryptedInfo info[1]; +#endif + + WOLFSSL_ENTER("EncryptDerKey"); + + if (der == NULL || derSz == NULL || cipher == NULL || + passwd == NULL || cipherInfo == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_SMALL_STACK + info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) { + WOLFSSL_MSG("malloc failed"); + return SSL_FAILURE; + } +#endif + info->set = 0; + info->ctx = NULL; + info->consumed = 0; + + /* set iv size */ + if (XSTRNCMP(cipher, "DES", 3) == 0) + info->ivSz = DES_IV_SIZE; + else if (XSTRNCMP(cipher, "AES", 3) == 0) + info->ivSz = AES_IV_SIZE; + else { + WOLFSSL_MSG("unsupported cipher"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return SSL_FAILURE; + } + + /* set the cipher name on info */ + XSTRNCPY(info->name, cipher, NAME_SZ); + + /* Generate a random salt */ + if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != SSL_SUCCESS) { + WOLFSSL_MSG("generate iv failed"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return SSL_FAILURE; + } + + /* add the padding before encryption */ + paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz); + if (paddingSz == 0) + paddingSz = info->ivSz; + XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz); + (*derSz) += paddingSz; + + /* encrypt buffer */ + if (wolfssl_encrypt_buffer_key(der, *derSz, + passwd, passwdSz, info) != SSL_SUCCESS) { + WOLFSSL_MSG("encrypt key failed"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return SSL_FAILURE; + } + + /* create cipher info : 'cipher_name,Salt(hex)' */ + cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2); + *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (*cipherInfo == NULL) { + WOLFSSL_MSG("malloc failed"); +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return SSL_FAILURE; + } + XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz); + XSTRNCAT((char*)*cipherInfo, ",", 1); + + idx = (word32)XSTRLEN((char*)*cipherInfo); + cipherInfoSz -= idx; + ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (ret != 0) { + WOLFSSL_MSG("Base16_Encode failed"); + XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + + return SSL_SUCCESS; +} +#endif /* defined(WOLFSSL_KEY_GEN) */ + #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) -int wolfSSL_PEM_write_buf_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, - unsigned char* passwd, int len, +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, + unsigned char* passwd, int passwdSz, byte **pem, int *plen) { - byte *der, *tmp; - int der_max_len = 0, derSz = 0; + byte *der, *tmp, *cipherInfo = NULL; + int der_max_len = 0, derSz = 0; - (void)cipher; - (void)passwd; - (void)len; - - WOLFSSL_MSG("wolfSSL_PEM_write_buf_RSAPrivateKey"); + WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey"); if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); @@ -13176,8 +13505,10 @@ int wolfSSL_PEM_write_buf_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, } } - der_max_len = 5 * wolfSSL_RSA_size(rsa); - printf("der_max_len = %d\n", der_max_len); + /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additionnal + * informations + */ + der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { @@ -13193,23 +13524,47 @@ int wolfSSL_PEM_write_buf_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, return SSL_FAILURE; } - /* tmp buffer with a max size */ - *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + sizeof(END_RSA_PRIV); + /* encrypt DER buffer if required */ + if (passwd != NULL && passwdSz > 0 && cipher != NULL) { + int ret; + + ret = EncryptDerKey(der, &derSz, cipher, + passwd, passwdSz, &cipherInfo); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("EncryptDerKey failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + + sizeof(END_RSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + } + else /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + sizeof(END_RSA_PRIV); + tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { WOLFSSL_MSG("malloc failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } /* DER to PEM */ - *plen = wc_DerToPem(der, derSz, tmp, *plen, PRIVATEKEY_TYPE); + *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, PRIVATEKEY_TYPE); if (*plen <= 0) { - WOLFSSL_MSG("wc_DerToPem failed"); + WOLFSSL_MSG("wc_DerToPemEx failed"); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER); if (*pem == NULL) { @@ -13220,26 +13575,27 @@ int wolfSSL_PEM_write_buf_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, XMEMSET(*pem, 0, (*plen)+1); if (XMEMCPY(*pem, tmp, *plen) == NULL) { - WOLFSSL_MSG("malloc failed"); + WOLFSSL_MSG("memcpy failed"); XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_SUCCESS; } +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { - byte* pem; - int plen, ret; + byte *pem; + int plen, ret; - (void)enc; - (void)kstr; - (void)klen; (void)cb; (void)u; @@ -13250,9 +13606,9 @@ int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, return SSL_FAILURE; } - ret = wolfSSL_PEM_write_buf_RSAPrivateKey(rsa, enc, NULL, 0, &pem, &plen); - if (ret != 1) { - WOLFSSL_MSG("wolfSSL_PEM_write_buf_RSAPrivateKey failed"); + ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed"); return SSL_FAILURE; } @@ -13285,24 +13641,6 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa, } #endif /* defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) */ -int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, - const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - pem_password_cb cb, void* arg) -{ - (void)bio; - (void)ec; - (void)cipher; - (void)passwd; - (void)len; - (void)cb; - (void)arg; - - WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented"); - - return SSL_FAILURE; -} - #ifdef HAVE_ECC /* EC_POINT Openssl -> WolfSSL */ @@ -13392,7 +13730,7 @@ static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey) if (eckey->pub_key->internal != NULL) { /* set the internal public key */ - if (ecc_copy_point(&key->pubkey, eckey->pub_key->internal) != MP_OKAY) { + if (wc_ecc_copy_point(&key->pubkey, eckey->pub_key->internal) != MP_OKAY) { WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed"); return SSL_FATAL_ERROR; } @@ -13431,29 +13769,38 @@ static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) key = (ecc_key*)eckey->internal; + /* validate group */ + if ((eckey->group->curve_idx < 0) || + (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) { + WOLFSSL_MSG("invalid curve idx"); + return SSL_FATAL_ERROR; + } + /* set group (idx of curve and corresponding domain parameters) */ key->idx = eckey->group->curve_idx; key->dp = &ecc_sets[key->idx]; /* set pubkey (point) */ - if (eckey->pub_key != NULL && eckey->pub_key->internal != NULL) { + if (eckey->pub_key != NULL) { if (SetECPointInternal(eckey->pub_key) != SSL_SUCCESS) { - WOLFSSL_MSG("SetECPointInternal failure"); + WOLFSSL_MSG("ec key pub error"); return SSL_FATAL_ERROR; } + + /* public key */ + key->type = ECC_PUBLICKEY; } /* set privkey */ - if (eckey->priv_key != NULL && eckey->priv_key->internal != NULL) { - key->type = ECC_PRIVATEKEY; - + if (eckey->priv_key != NULL) { if (SetIndividualInternal(eckey->priv_key, &key->k) != SSL_SUCCESS) { - WOLFSSL_MSG("rsa p key error"); + WOLFSSL_MSG("ec key priv error"); return SSL_FATAL_ERROR; } + + /* private key */ + key->type = ECC_PRIVATEKEY; } - else - key->type = ECC_PUBLICKEY; eckey->inSet = 1; @@ -13484,21 +13831,40 @@ const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key) return key->group; } + /* return code compliant with OpenSSL : * 1 if success, 0 if error */ int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key, const WOLFSSL_BIGNUM *priv_key) { - (void)key; - (void)priv_key; - WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key"); - WOLFSSL_MSG("wolfSSL_EC_KEY_set_private_key TBD"); - return SSL_FAILURE; + if (key == NULL || priv_key == NULL) { + WOLFSSL_MSG("Bad arguments"); + return SSL_FAILURE; + } + + /* free key if previously set */ + if (key->priv_key != NULL) + wolfSSL_BN_free(key->priv_key); + + key->priv_key = wolfSSL_BN_dup(priv_key); + if (key->priv_key == NULL) { + WOLFSSL_MSG("key ecc priv key NULL"); + return SSL_FAILURE; + } + + if (SetECKeyInternal(key) != SSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyInternal failed"); + wolfSSL_BN_free(key->priv_key); + return SSL_FAILURE; + } + + return SSL_SUCCESS; } + WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key) { WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key"); @@ -13752,14 +14118,14 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, /* create new point if required */ if (key_p == NULL) - key_p = ecc_new_point(); + key_p = wc_ecc_new_point(); if (key_p == NULL) { WOLFSSL_MSG("key ecc point NULL"); return SSL_FAILURE; } - if (ecc_copy_point(pub_p, key_p) != MP_OKAY) { + if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) { WOLFSSL_MSG("ecc_copy_point failure"); return SSL_FAILURE; } @@ -13774,7 +14140,6 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, wolfssl_EC_POINT_dump("key->pub_key", key->pub_key); #endif return SSL_SUCCESS; - } /* End EC_KEY */ @@ -13830,6 +14195,7 @@ void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) WOLFSSL_ENTER("wolfSSL_EC_GROUP_free"); XFREE(group, NULL, DYNAMIC_TYPE_ECC); + group = NULL; } void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag) @@ -14035,7 +14401,7 @@ WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) } XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT)); - p->internal = ecc_new_point(); + p->internal = wc_ecc_new_point(); if (p->internal == NULL) { WOLFSSL_MSG("ecc_new_point failure"); return NULL; @@ -14119,8 +14485,8 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, } /* r = q * m % prime */ - if (ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal, - (ecc_point*)r->internal, &prime, 1) != MP_OKAY) { + if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal, + (ecc_point*)r->internal, &prime, 1) != MP_OKAY) { WOLFSSL_MSG("ecc_mulmod failure"); mp_clear(&prime); return SSL_FAILURE; @@ -14163,7 +14529,7 @@ int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, return SSL_FATAL_ERROR; } - ret = ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal); + ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal); if (ret == MP_EQ) return 0; else if (ret == MP_LT || ret == MP_GT) @@ -14178,7 +14544,7 @@ void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p) if (p != NULL) { if (p->internal == NULL) { - ecc_del_point((ecc_point*)p->internal); + wc_ecc_del_point((ecc_point*)p->internal); XFREE(p->internal, NULL, DYNAMIC_TYPE_ECC); p->internal = NULL; } @@ -14219,7 +14585,7 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, } } - ret = ecc_point_is_at_infinity(point->internal); + ret = wc_ecc_point_is_at_infinity(point->internal); if (ret <= 0) { WOLFSSL_MSG("ecc_point_is_at_infinity failure"); return SSL_FAILURE; @@ -14411,6 +14777,7 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, void *out, size_t *outlen)) { word32 len; + (void)KDF; (void)KDF; @@ -14444,8 +14811,8 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, return len; } - /* End ECDH */ + /* return code compliant with OpenSSL : * 1 if success, 0 if error */ @@ -14459,19 +14826,188 @@ int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x) return SSL_FAILURE; } +#if defined(WOLFSSL_KEY_GEN) + +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg) +{ + (void)bio; + (void)ecc; + (void)cipher; + (void)passwd; + (void)len; + (void)cb; + (void)arg; + + WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented"); + + return SSL_FAILURE; +} + +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, + const EVP_CIPHER* cipher, + unsigned char* passwd, int passwdSz, + byte **pem, int *plen) +{ + byte *der, *tmp, *cipherInfo = NULL; + int der_max_len = 0, derSz = 0; + + WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey"); + + if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return SSL_FAILURE; + } + + if (ecc->inSet == 0) { + WOLFSSL_MSG("No ECC internal set, do it"); + + if (SetECKeyInternal(ecc) != SSL_SUCCESS) { + WOLFSSL_MSG("SetDsaInternal failed"); + return SSL_FAILURE; + } + } + + /* 4 > size of pub, priv + ASN.1 additionnal informations + */ + der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE; + + der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (der == NULL) { + WOLFSSL_MSG("malloc failed"); + return SSL_FAILURE; + } + + /* Key to DER */ + derSz = wc_EccKeyToDer(ecc->internal, der, der_max_len); + if (derSz < 0) { + WOLFSSL_MSG("wc_DsaKeyToDer failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + + /* encrypt DER buffer if required */ + if (passwd != NULL && passwdSz > 0 && cipher != NULL) { + int ret; + + ret = EncryptDerKey(der, &derSz, cipher, + passwd, passwdSz, &cipherInfo); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("EncryptDerKey failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + + sizeof(END_EC_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + } + else /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + sizeof(END_EC_PRIV); + + tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + WOLFSSL_MSG("malloc failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + + /* DER to PEM */ + *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, ECC_PRIVATEKEY_TYPE); + if (*plen <= 0) { + WOLFSSL_MSG("wc_DerToPemEx failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER); + if (*pem == NULL) { + WOLFSSL_MSG("malloc failed"); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + XMEMSET(*pem, 0, (*plen)+1); + + if (XMEMCPY(*pem, tmp, *plen) == NULL) { + WOLFSSL_MSG("memcpy failed"); + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return SSL_SUCCESS; +} + +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + byte *pem; + int plen, ret; + + (void)cb; + (void)u; + + WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey"); + + if (fp == NULL || ecc == NULL || ecc->internal == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return SSL_FAILURE; + } + + ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed"); + return SSL_FAILURE; + } + + ret = (int)XFWRITE(pem, plen, 1, fp); + if (ret != 1) { + WOLFSSL_MSG("ECC private key file write failed"); + return SSL_FAILURE; + } + + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); + return SSL_SUCCESS; +} + +#endif /* defined(WOLFSSL_KEY_GEN) */ #endif /* HAVE_ECC */ #ifndef NO_DSA +#if defined(WOLFSSL_KEY_GEN) + /* return code compliant with OpenSSL : * 1 if success, 0 if error */ -int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, DSA* dsa, - const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - pem_password_cb cb, void* arg) +int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg) { (void)bio; (void)dsa; @@ -14489,30 +15025,23 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, DSA* dsa, /* return code compliant with OpenSSL : * 1 if success, 0 if error */ -int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, - const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) +int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int passwdSz, + byte **pem, int *plen) { - byte *der, *pem; - int derSz = 0, pemSz = 0; + byte *der, *tmp, *cipherInfo = NULL; + int der_max_len = 0, derSz = 0; - (void)enc; - (void)kstr; - (void)klen; - (void)cb; - (void)u; + WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey"); - WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey"); - - if (fp == NULL || dsa == NULL || dsa->internal == NULL || - kstr == NULL || klen <= 0) { + if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); return SSL_FAILURE; } if (dsa->inSet == 0) { - WOLFSSL_MSG("No RSA internal set, do it"); + WOLFSSL_MSG("No DSA internal set, do it"); if (SetDsaInternal(dsa) != SSL_SUCCESS) { WOLFSSL_MSG("SetDsaInternal failed"); @@ -14520,40 +15049,124 @@ int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, } } - der = (byte*)XMALLOC(klen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + /* 4 > size of pub, priv, p, q, g + ASN.1 additionnal informations + */ + der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE; + + der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { WOLFSSL_MSG("malloc failed"); return SSL_FAILURE; } /* Key to DER */ - derSz = wc_DsaKeyToDer(dsa->internal, der, klen); + derSz = wc_DsaKeyToDer(dsa->internal, der, der_max_len); if (derSz < 0) { + WOLFSSL_MSG("wc_DsaKeyToDer failed"); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } - pemSz = (derSz * 4)/3 + 8; - pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (der == NULL) { + /* encrypt DER buffer if required */ + if (passwd != NULL && passwdSz > 0 && cipher != NULL) { + int ret; + + ret = EncryptDerKey(der, &derSz, cipher, + passwd, passwdSz, &cipherInfo); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("EncryptDerKey failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + + sizeof(END_DSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + } + else /* tmp buffer with a max size */ + *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + sizeof(END_DSA_PRIV); + + tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { WOLFSSL_MSG("malloc failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } /* DER to PEM */ - pemSz = wc_DerToPem(der, derSz, pem, pemSz, PRIVATEKEY_TYPE); - if (pemSz <= 0) { + *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, DSA_PRIVATEKEY_TYPE); + if (*plen <= 0) { + WOLFSSL_MSG("wc_DerToPemEx failed"); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_FAILURE; } XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipherInfo != NULL) + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); - fwrite(pem, 1, pemSz, fp); + *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER); + if (*pem == NULL) { + WOLFSSL_MSG("malloc failed"); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + XMEMSET(*pem, 0, (*plen)+1); + + if (XMEMCPY(*pem, tmp, *plen) == NULL) { + WOLFSSL_MSG("memcpy failed"); + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); return SSL_SUCCESS; } +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + byte *pem; + int plen, ret; + + (void)cb; + (void)u; + + WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey"); + + if (fp == NULL || dsa == NULL || dsa->internal == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return SSL_FAILURE; + } + + ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen); + if (ret != SSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed"); + return SSL_FAILURE; + } + + ret = (int)XFWRITE(pem, plen, 1, fp); + if (ret != 1) { + WOLFSSL_MSG("DSA private key file write failed"); + return SSL_FAILURE; + } + + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); + return SSL_SUCCESS; +} + +#endif /* defined(WOLFSSL_KEY_GEN) */ + /* return code compliant with OpenSSL : * 1 if success, 0 if error */ @@ -14606,27 +15219,6 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, return NULL; } -/* return code compliant with OpenSSL : - * 1 if success, 0 if error - */ -int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *key, - const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - (void)fp; - (void)key; - (void)enc; - (void)kstr; - (void)klen; - (void)cb; - (void)u; - - WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey not implemented"); - - return SSL_FAILURE; -} - #ifndef NO_RSA WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x, @@ -14887,7 +15479,9 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, return BAD_FUNC_ARG; /* header */ - XMEMCPY(buf, header, headerLen); + if (XMEMCPY(buf, header, headerLen) == NULL) + return SSL_FATAL_ERROR; + i = headerLen; /* body */ @@ -14900,7 +15494,8 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, /* footer */ if ( (i + footerLen) > inLen) return BAD_FUNC_ARG; - XMEMCPY(buf + i, footer, footerLen); + if (XMEMCPY(buf + i, footer, footerLen) == NULL) + return SSL_FATAL_ERROR; *outLen += headerLen + footerLen; return SSL_SUCCESS; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 85f01a0d1..c9f8c74ad 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -55,6 +55,12 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) } +int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, const byte* iv) +{ + return AesCbcDecryptWithKey(out, in, inSz, key, keySz, iv); +} + int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, const byte* key, word32 keySz, const byte* iv) { @@ -1748,6 +1754,33 @@ int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, return ret; } +int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, const byte* iv) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + Aes* aes = NULL; +#else + Aes aes[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (aes == NULL) + return MEMORY_E; +#endif + + ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION); + if (ret == 0) + ret = wc_AesCbcEncrypt(aes, out, in, inSz); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + /* AES-DIRECT */ #if defined(WOLFSSL_AES_DIRECT) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 78a849ab1..daed24e9d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1386,7 +1386,8 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || GetInt(&key->q, input, inOutIdx, inSz) < 0 || GetInt(&key->g, input, inOutIdx, inSz) < 0 || - GetInt(&key->y, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; + GetInt(&key->y, input, inOutIdx, inSz) < 0 ) + return ASN_DH_KEY_E; key->type = DSA_PUBLIC; return 0; @@ -1408,7 +1409,8 @@ int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, GetInt(&key->q, input, inOutIdx, inSz) < 0 || GetInt(&key->g, input, inOutIdx, inSz) < 0 || GetInt(&key->y, input, inOutIdx, inSz) < 0 || - GetInt(&key->x, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; + GetInt(&key->x, input, inOutIdx, inSz) < 0 ) + return ASN_DH_KEY_E; key->type = DSA_PRIVATE; return 0; @@ -1423,9 +1425,9 @@ static mp_int* GetDsaInt(DsaKey* key, int idx) if (idx == 2) return &key->g; if (idx == 3) - return &key->x; - if (idx == 4) return &key->y; + if (idx == 4) + return &key->x; return NULL; } @@ -1445,7 +1447,7 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen) { word32 seqSz, verSz, rawLen, intTotalLen = 0; word32 sizes[DSA_INTS]; - int i, j, outLen, ret = 0; + int i, j, outLen, ret = 0, lbit; byte seq[MAX_SEQ_SZ]; byte ver[MAX_VERSION_SZ]; @@ -1463,7 +1465,15 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen) /* write all big ints from key to DER tmps */ for (i = 0; i < DSA_INTS; i++) { mp_int* keyInt = GetDsaInt(key, i); - rawLen = mp_unsigned_bin_size(keyInt); + + /* leading zero */ + if ((mp_count_bits(keyInt) & 7) == 0 || mp_iszero(keyInt) == MP_YES) + lbit = 1; + else + lbit = 0; + + rawLen = mp_unsigned_bin_size(keyInt) + lbit; + tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, NULL, DYNAMIC_TYPE_DSA); if (tmps[i] == NULL) { ret = MEMORY_E; @@ -1471,12 +1481,16 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen) } tmps[i][0] = ASN_INTEGER; - sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ + sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */ if (sizes[i] <= MAX_SEQ_SZ) { + /* leading zero */ + if (lbit) + tmps[i][sizes[i]-1] = 0x00; + int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); if (err == MP_OKAY) { - sizes[i] += rawLen; + sizes[i] += (rawLen-lbit); /* lbit included in rawLen */ intTotalLen += sizes[i]; } else { @@ -4641,24 +4655,49 @@ WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output) +const char* BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; +const char* END_CERT = "-----END CERTIFICATE-----"; +const char* BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----"; +const char* END_CERT_REQ = "-----END CERTIFICATE REQUEST-----"; +const char* BEGIN_DH_PARAM = "-----BEGIN DH PARAMETERS-----"; +const char* END_DH_PARAM = "-----END DH PARAMETERS-----"; +const char* BEGIN_X509_CRL = "-----BEGIN X509 CRL-----"; +const char* END_X509_CRL = "-----END X509 CRL-----"; +const char* BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----"; +const char* END_RSA_PRIV = "-----END RSA PRIVATE KEY-----"; +const char* BEGIN_PRIV_KEY = "-----BEGIN PRIVATE KEY-----"; +const char* END_PRIV_KEY = "-----END PRIVATE KEY-----"; +const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; +const char* END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----"; +const char* BEGIN_EC_PRIV = "-----BEGIN EC PRIVATE KEY-----"; +const char* END_EC_PRIV = "-----END EC PRIVATE KEY-----"; +const char* BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----"; +const char* END_DSA_PRIV = "-----END DSA PRIVATE KEY-----"; -#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA) +#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) + +/* Used for compatibility API */ +int wc_DerToPem(const byte* der, word32 derSz, + byte* output, word32 outSz, int type) +{ + return wc_DerToPemEx(der, derSz, output, outSz, NULL, type); +} /* convert der buffer to pem into output, can't do inplace, der and output need to be different */ -int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, - int type) +int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, + byte *cipher_info, int type) { #ifdef WOLFSSL_SMALL_STACK char* header = NULL; char* footer = NULL; #else - char header[80]; - char footer[80]; + char header[40 + HEADER_ENCRYPTED_KEY_SIZE]; + char footer[40]; #endif - int headerLen = 80; - int footerLen = 80; + int headerLen = 40 + HEADER_ENCRYPTED_KEY_SIZE; + int footerLen = 40; int i; int err; int outLen; /* return length or error */ @@ -4670,36 +4709,55 @@ int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (header == NULL) return MEMORY_E; - + footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (footer == NULL) { XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif - if (type == CERT_TYPE) { - XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", headerLen); - XSTRNCPY(footer, "-----END CERTIFICATE-----\n", footerLen); + XSTRNCPY(header, BEGIN_CERT, headerLen); + XSTRNCAT(header, "\n", 1); + + XSTRNCPY(footer, END_CERT, footerLen); + XSTRNCAT(footer, "\n", 1); } else if (type == PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", headerLen); - XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", footerLen); + XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen); + XSTRNCAT(header, "\n", 1); + + XSTRNCPY(footer, END_RSA_PRIV, footerLen); + XSTRNCAT(footer, "\n", 1); } - #ifdef HAVE_ECC +#ifndef NO_DSA + else if (type == DSA_PRIVATEKEY_TYPE) { + XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen); + XSTRNCAT(header, "\n", 1); + + XSTRNCPY(footer, END_DSA_PRIV, footerLen); + XSTRNCAT(footer, "\n", 1); + } +#endif +#ifdef HAVE_ECC else if (type == ECC_PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", headerLen); - XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", footerLen); + XSTRNCPY(header, BEGIN_EC_PRIV, headerLen); + XSTRNCAT(header, "\n", 1); + + XSTRNCPY(footer, END_EC_PRIV, footerLen); + XSTRNCAT(footer, "\n", 1); } - #endif - #ifdef WOLFSSL_CERT_REQ +#endif +#ifdef WOLFSSL_CERT_REQ else if (type == CERTREQ_TYPE) { - XSTRNCPY(header, - "-----BEGIN CERTIFICATE REQUEST-----\n", headerLen); - XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", footerLen); + XSTRNCPY(header, BEGIN_CERT_REQ, headerLen); + XSTRNCAT(header, "\n", 1); + + XSTRNCPY(footer, END_CERT_REQ, footerLen); + XSTRNCAT(footer, "\n", 1); } - #endif +#endif else { #ifdef WOLFSSL_SMALL_STACK XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -4708,6 +4766,14 @@ int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, return BAD_FUNC_ARG; } + /* extra header information for encrypted key */ + if (cipher_info != NULL) { + XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23); + XSTRNCAT(header, "DEK-Info: ", 10); + XSTRNCAT(header, (char*)cipher_info, XSTRLEN((char*)cipher_info)); + XSTRNCAT(header, "\n\n", 2); + } + headerLen = (int)XSTRLEN(header); footerLen = (int)XSTRLEN(footer); @@ -4762,7 +4828,6 @@ int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, return outLen + headerLen + footerLen; } - #endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */ @@ -4810,7 +4875,7 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) { word32 seqSz, verSz, rawLen, intTotalLen = 0; word32 sizes[RSA_INTS]; - int i, j, outLen, ret = 0; + int i, j, outLen, ret = 0, lbit; byte seq[MAX_SEQ_SZ]; byte ver[MAX_VERSION_SZ]; @@ -4828,7 +4893,15 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) /* write all big ints from key to DER tmps */ for (i = 0; i < RSA_INTS; i++) { mp_int* keyInt = GetRsaInt(key, i); - rawLen = mp_unsigned_bin_size(keyInt); + + /* leading zero */ + if ((mp_count_bits(keyInt) & 7) == 0 || mp_iszero(keyInt) == MP_YES) + lbit = 1; + else + lbit = 0; + + rawLen = mp_unsigned_bin_size(keyInt) + lbit; + tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap, DYNAMIC_TYPE_RSA); if (tmps[i] == NULL) { @@ -4837,12 +4910,16 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) } tmps[i][0] = ASN_INTEGER; - sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ + sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */ if (sizes[i] <= MAX_SEQ_SZ) { + /* leading zero */ + if (lbit) + tmps[i][sizes[i]-1] = 0x00; + int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); if (err == MP_OKAY) { - sizes[i] += rawLen; + sizes[i] += (rawLen-lbit); /* lbit included in rawLen */ intTotalLen += sizes[i]; } else { @@ -6846,84 +6923,109 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, /* Write a Private ecc key to DER format, length on success else < 0 */ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen) { - byte curve[MAX_ALGO_SZ]; + byte curve[MAX_ALGO_SZ+2]; byte ver[MAX_VERSION_SZ]; byte seq[MAX_SEQ_SZ]; - int ret; - int curveSz; - int verSz; + byte *prv, *pub; + int ret, totalSz, curveSz, verSz; int privHdrSz = ASN_ECC_HEADER_SZ; int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ; - int curveHdrSz = ASN_ECC_CONTEXT_SZ; - word32 seqSz; - word32 idx = 0; - word32 pubSz = ECC_BUFSIZE; - word32 privSz; - word32 totalSz; + + word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0; + word32 seqSz, privSz, pubSz = ECC_BUFSIZE; if (key == NULL || output == NULL || inLen == 0) return BAD_FUNC_ARG; - ret = wc_ecc_export_x963(key, NULL, &pubSz); - if (ret != LENGTH_ONLY_E) { + /* curve */ + curve[curveidx++] = ECC_PREFIX_0; + curveidx++ /* to put the size after computation */; + curveSz = SetCurve(key, curve+curveidx); + if (curveSz < 0) + return curveSz; + /* set computed size */ + curve[1] = (byte)curveSz; + curveidx += curveSz; + + /* private */ + privSz = key->dp->size; + prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (prv == NULL) { + return MEMORY_E; + } + prv[prvidx++] = ASN_OCTET_STRING; + prv[prvidx++] = (byte)key->dp->size; + ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz); + if (ret < 0) { + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; } - curveSz = SetCurve(key, curve); - if (curveSz < 0) { - return curveSz; + prvidx += privSz; + + /* public */ + ret = wc_ecc_export_x963(key, NULL, &pubSz); + if (ret != LENGTH_ONLY_E) { + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; } - privSz = key->dp->size; + pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) { + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + pub[pubidx++] = ECC_PREFIX_1; + if (pubSz > 128) /* leading zero + extra size byte */ + pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx); + else /* leading zero */ + pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx); + pub[pubidx++] = ASN_BIT_STRING; + pubidx += SetLength(pubSz + 1, pub+pubidx); + pub[pubidx++] = (byte)0; /* leading zero */ + ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz); + if (ret != 0) { + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + pubidx += pubSz; + + /* make headers */ verSz = SetMyVersion(1, ver, FALSE); - if (verSz < 0) { - return verSz; + seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq); + + totalSz = prvidx + pubidx + curveidx + verSz + seqSz; + if (totalSz > (int)inLen) { + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return BAD_FUNC_ARG; } - totalSz = verSz + privSz + privHdrSz + curveSz + curveHdrSz + - pubSz + pubHdrSz + 1; /* plus null byte b4 public */ - seqSz = SetSequence(totalSz, seq); - totalSz += seqSz; - - if (totalSz > inLen) { - return BUFFER_E; - } - - /* write it out */ + /* write out */ /* seq */ XMEMCPY(output + idx, seq, seqSz); - idx += seqSz; + idx = seqSz; - /* ver */ + /* ver */ XMEMCPY(output + idx, ver, verSz); idx += verSz; /* private */ - output[idx++] = ASN_OCTET_STRING; - output[idx++] = (byte)privSz; - ret = wc_ecc_export_private_only(key, output + idx, &privSz); - if (ret < 0) { - return ret; - } - idx += privSz; + XMEMCPY(output + idx, prv, prvidx); + idx += prvidx; + XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER); /* curve */ - output[idx++] = ECC_PREFIX_0; - output[idx++] = (byte)curveSz; - XMEMCPY(output + idx, curve, curveSz); - idx += curveSz; + XMEMCPY(output + idx, curve, curveidx); + idx += curveidx; /* public */ - output[idx++] = ECC_PREFIX_1; - output[idx++] = (byte)pubSz + ASN_ECC_CONTEXT_SZ + 1; /* plus null byte */ - output[idx++] = ASN_BIT_STRING; - output[idx++] = (byte)pubSz + 1; /* plus null byte */ - output[idx++] = (byte)0; /* null byte */ - ret = wc_ecc_export_x963(key, output + idx, &pubSz); - if (ret != 0) { - return ret; - } - /* idx += pubSz if do more later */ + XMEMCPY(output + idx, pub, pubidx); + idx += pubidx; + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); return totalSz; } diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index f4d919255..0dff4c94d 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -400,6 +400,39 @@ int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) return 0; } +int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) +{ + word32 outIdx = 0; + word32 i; + byte hb, lb; + + if (*outLen < (2 * inLen + 1)) + return BAD_FUNC_ARG; + + for (i = 0; i < inLen; i++) { + hb = in[i] >> 4; + lb = in[i] & 0x0f; + + /* ASCII value */ + hb += '0'; + if (hb > '9') + hb += 7; + + /* ASCII value */ + lb += '0'; + if (lb>'9') + lb += 7; + + out[outIdx++] = hb; + out[outIdx++] = lb; + } + + /* force 0 at this end */ + out[outIdx++] = 0; + + *outLen = outIdx; + return 0; +} #endif /* (OPENSSL_EXTRA) || (HAVE_WEBSERVER) || (HAVE_FIPS) */ diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index f886ecdc7..ee068a0bc 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -91,8 +91,14 @@ void wc_Des_SetIV(Des* des, const byte* iv) } -int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, +int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, const byte* key, const byte* iv) +{ + return Des_CbcEncryptWithKey(out, in, sz, key, iv); +} + +int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) { return Des_CbcDecryptWithKey(out, in, sz, key, iv); } @@ -104,13 +110,18 @@ int wc_Des3_SetIV(Des3* des, const byte* iv) } +int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) +{ + return Des3_CbcEncryptWithKey(out, in, sz, key, iv); +} + int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, - const byte* key, const byte* iv) + const byte* key, const byte* iv) { return Des3_CbcDecryptWithKey(out, in, sz, key, iv); } - #ifdef HAVE_CAVIUM /* Initiliaze Des3 for use with Nitrox device */ @@ -1490,8 +1501,35 @@ void wc_Des_SetIV(Des* des, const byte* iv) } +int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + Des* des = NULL; +#else + Des des[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (des == NULL) + return MEMORY_E; +#endif + + ret = wc_Des_SetKey(des, key, iv, DES_ENCRYPTION); + if (ret == 0) + ret = wc_Des_CbcEncrypt(des, out, in, sz); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, - const byte* key, const byte* iv) + const byte* key, const byte* iv) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1508,7 +1546,7 @@ int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION); if (ret == 0) - ret = wc_Des_CbcDecrypt(des, out, in, sz); + ret = wc_Des_CbcDecrypt(des, out, in, sz); #ifdef WOLFSSL_SMALL_STACK XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1529,8 +1567,35 @@ int wc_Des3_SetIV(Des3* des, const byte* iv) } +int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + Des3* des3 = NULL; +#else + Des3 des3[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (des3 == NULL) + return MEMORY_E; +#endif + + ret = wc_Des3_SetKey(des3, key, iv, DES_ENCRYPTION); + if (ret == 0) + ret = wc_Des3_CbcEncrypt(des3, out, in, sz); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, - const byte* key, const byte* iv) + const byte* key, const byte* iv) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1547,7 +1612,7 @@ int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION); if (ret == 0) - ret = wc_Des3_CbcDecrypt(des3, out, in, sz); + ret = wc_Des3_CbcDecrypt(des3, out, in, sz); #ifdef WOLFSSL_SMALL_STACK XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index f2124b197..dc0e20e4b 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #ifdef HAVE_CONFIG_H #include @@ -27,10 +28,12 @@ #ifndef NO_DSA -#include -#include #include +#include #include +#include +#include +#include enum { @@ -80,6 +83,263 @@ void wc_FreeDsaKey(DsaKey* key) #endif } +#ifdef WOLFSSL_KEY_GEN + +int wc_MakeDsaKey(RNG *rng, DsaKey *dsa) +{ + unsigned char *buf; + int qsize, err; + + if (rng == NULL || dsa == NULL) + return BAD_FUNC_ARG; + + qsize = mp_unsigned_bin_size(&dsa->q); + if (qsize == 0) + return BAD_FUNC_ARG; + + /* allocate ram */ + buf = (unsigned char *)XMALLOC(qsize, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) + return MEMORY_E; + + if (mp_init(&dsa->x) != MP_OKAY) { + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MP_INIT_E; + } + + do { + /* make a random exponent mod q */ + err = wc_RNG_GenerateBlock(rng, buf, qsize); + if (err != MP_OKAY) { + mp_clear(&dsa->x); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return err; + } + + err = mp_read_unsigned_bin(&dsa->x, buf, qsize); + if (err != MP_OKAY) { + mp_clear(&dsa->x); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return err; + } + } while (mp_cmp_d(&dsa->x, 1) != MP_GT); + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (mp_init(&dsa->y) != MP_OKAY) { + mp_clear(&dsa->x); + return MP_INIT_E; + } + + /* public key : y = g^x mod p */ + err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y); + if (err != MP_OKAY) { + mp_clear(&dsa->x); + mp_clear(&dsa->y); + return err; + } + + dsa->type = DSA_PRIVATE; + + return MP_OKAY; +} + +/* modulus_size in bits */ +int wc_MakeDsaParameters(RNG *rng, int modulus_size, DsaKey *dsa) +{ + mp_int tmp, tmp2; + int err, msize, qsize, + loop_check_prime = 0, + check_prime = MP_NO; + unsigned char *buf; + + if (rng == NULL || dsa == NULL) + return BAD_FUNC_ARG; + + /* set group size in bytes from modulus size + * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256) + */ + switch (modulus_size) { + case 1024: + qsize = 20; + break; + case 2048: + case 3072: + qsize = 32; + break; + default: + return BAD_FUNC_ARG; + break; + } + + /* modulus size in bytes */ + msize = modulus_size / 8; + + /* allocate ram */ + buf = (unsigned char *)XMALLOC(msize - qsize, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) { + return MEMORY_E; + } + + /* make a random string that will be multplied against q */ + err = wc_RNG_GenerateBlock(rng, buf, msize - qsize); + if (err != MP_OKAY) { + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return err; + } + + /* force magnitude */ + buf[0] |= 0xC0; + + /* force even */ + buf[msize - qsize - 1] &= ~1; + + if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) { + mp_clear(&dsa->q); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MP_INIT_E; + } + + err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp2); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return err; + } + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + /* make our prime q */ + err = mp_rand_prime(&dsa->q, qsize, rng, NULL); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp2); + return err; + } + + /* p = random * q */ + err = mp_mul(&dsa->q, &tmp2, &dsa->p); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp2); + return err; + } + + /* p = random * q + 1, so q is a prime divisor of p-1 */ + err = mp_add_d(&dsa->p, 1, &dsa->p); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp2); + return err; + } + + if (mp_init(&tmp) != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp2); + return MP_INIT_E; + } + + /* tmp = 2q */ + err = mp_add(&dsa->q, &dsa->q, &tmp); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + + /* loop until p is prime */ + while (check_prime == MP_NO) { + err = mp_prime_is_prime(&dsa->p, 8, &check_prime); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + + if (check_prime != MP_YES) { + /* p += 2q */ + err = mp_add(&tmp, &dsa->p, &dsa->p); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + + loop_check_prime++; + } + } + + /* tmp2 += (2*loop_check_prime) + * to have p = (q * tmp2) + 1 prime + */ + if (loop_check_prime) { + err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + } + + if (mp_init(&dsa->g) != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&tmp); + mp_clear(&tmp2); + return MP_INIT_E; + } + + /* find a value g for which g^tmp2 != 1 */ + mp_set(&dsa->g, 1); + + do { + err = mp_add_d(&dsa->g, 1, &dsa->g); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&dsa->g); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + + err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp); + if (err != MP_OKAY) { + mp_clear(&dsa->q); + mp_clear(&dsa->p); + mp_clear(&dsa->g); + mp_clear(&tmp); + mp_clear(&tmp2); + return err; + } + + } while (mp_cmp_d(&tmp, 1) == MP_EQ); + + /* at this point tmp generates a group of order q mod p */ + mp_exch(&tmp, &dsa->g); + + mp_clear(&tmp); + mp_clear(&tmp2); + + return MP_OKAY; +} +#endif /* WOLFSSL_KEY_GEN */ + int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) { diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9d1d0dae0..a14a9e08d 100755 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1014,7 +1014,7 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp) static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, int map) #else -int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, +int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, int map) #endif { @@ -1043,10 +1043,10 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, /* alloc ram for window temps */ for (i = 0; i < 8; i++) { - M[i] = ecc_new_point(); + M[i] = wc_ecc_new_point(); if (M[i] == NULL) { for (j = 0; j < i; j++) { - ecc_del_point(M[j]); + wc_ecc_del_point(M[j]); } mp_clear(&mu); return MEMORY_E; @@ -1054,7 +1054,7 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, } /* make a copy of G incase R==G */ - tG = ecc_new_point(); + tG = wc_ecc_new_point(); if (tG == NULL) err = MEMORY_E; @@ -1204,9 +1204,9 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, err = ecc_map(R, modulus, &mp); mp_clear(&mu); - ecc_del_point(tG); + wc_ecc_del_point(tG); for (i = 0; i < 8; i++) { - ecc_del_point(M[i]); + wc_ecc_del_point(M[i]); } return err; } @@ -1229,7 +1229,7 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, int map) #else -int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, +int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, int map) #endif { @@ -1257,10 +1257,10 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, /* alloc ram for window temps */ for (i = 0; i < 3; i++) { - M[i] = ecc_new_point(); + M[i] = wc_ecc_new_point(); if (M[i] == NULL) { for (j = 0; j < i; j++) { - ecc_del_point(M[j]); + wc_ecc_del_point(M[j]); } mp_clear(&mu); return MEMORY_E; @@ -1268,7 +1268,7 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, } /* make a copy of G incase R==G */ - tG = ecc_new_point(); + tG = wc_ecc_new_point(); if (tG == NULL) err = MEMORY_E; @@ -1364,9 +1364,9 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, /* done */ mp_clear(&mu); - ecc_del_point(tG); + wc_ecc_del_point(tG); for (i = 0; i < 3; i++) { - ecc_del_point(M[i]); + wc_ecc_del_point(M[i]); } return err; } @@ -1389,7 +1389,7 @@ static void alt_fp_init(fp_int* a) Allocate a new ECC point return A newly allocated point or NULL on error */ -ecc_point* ecc_new_point(void) +ecc_point* wc_ecc_new_point(void) { ecc_point* p; @@ -1425,7 +1425,7 @@ ecc_point* ecc_new_point(void) /** Free an ECC point from memory p The point to free */ -void ecc_del_point(ecc_point* p) +void wc_ecc_del_point(ecc_point* p) { /* prevents free'ing null arguments */ if (p != NULL) { @@ -1440,7 +1440,7 @@ void ecc_del_point(ecc_point* p) p The point to copy r The created point */ -int ecc_copy_point(ecc_point* p, ecc_point *r) +int wc_ecc_copy_point(ecc_point* p, ecc_point *r) { int ret; @@ -1467,7 +1467,7 @@ int ecc_copy_point(ecc_point* p, ecc_point *r) return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error */ -int ecc_cmp_point(ecc_point* a, ecc_point *b) +int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) { int ret; @@ -1492,7 +1492,7 @@ int ecc_cmp_point(ecc_point* a, ecc_point *b) n The idx number to check return 1 if valid, 0 if not */ -static int ecc_is_valid_idx(int n) +int wc_ecc_is_valid_idx(int n) { int x; @@ -1533,28 +1533,28 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, return ECC_BAD_ARG_E; } - if (ecc_is_valid_idx(private_key->idx) == 0 || - ecc_is_valid_idx(public_key->idx) == 0) + if (wc_ecc_is_valid_idx(private_key->idx) == 0 || + wc_ecc_is_valid_idx(public_key->idx) == 0) return ECC_BAD_ARG_E; if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) return ECC_BAD_ARG_E; /* make new point */ - result = ecc_new_point(); + result = wc_ecc_new_point(); if (result == NULL) { return MEMORY_E; } if ((err = mp_init(&prime)) != MP_OKAY) { - ecc_del_point(result); + wc_ecc_del_point(result); return err; } err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); if (err == MP_OKAY) - err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); + err = wc_ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); if (err == MP_OKAY) { x = mp_unsigned_bin_size(&prime); @@ -1570,7 +1570,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, } mp_clear(&prime); - ecc_del_point(result); + wc_ecc_del_point(result); return err; } @@ -1600,24 +1600,24 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, return ECC_BAD_ARG_E; } - if (ecc_is_valid_idx(private_key->idx) == 0) + if (wc_ecc_is_valid_idx(private_key->idx) == 0) return ECC_BAD_ARG_E; /* make new point */ - result = ecc_new_point(); + result = wc_ecc_new_point(); if (result == NULL) { return MEMORY_E; } if ((err = mp_init(&prime)) != MP_OKAY) { - ecc_del_point(result); + wc_ecc_del_point(result); return err; } err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); if (err == MP_OKAY) - err = ecc_mulmod(&private_key->k, point, result, &prime, 1); + err = wc_ecc_mulmod(&private_key->k, point, result, &prime, 1); if (err == MP_OKAY) { x = mp_unsigned_bin_size(&prime); @@ -1633,14 +1633,14 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, } mp_clear(&prime); - ecc_del_point(result); + wc_ecc_del_point(result); return err; } /* return 1 if point is at infinity, 0 if not, < 0 on error */ -int ecc_point_is_at_infinity(ecc_point* p) +int wc_ecc_point_is_at_infinity(ecc_point* p) { if (p == NULL) return BAD_FUNC_ARG; @@ -1708,7 +1708,7 @@ static int wc_ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) } if (err == MP_OKAY) { - base = ecc_new_point(); + base = wc_ecc_new_point(); if (base == NULL) err = MEMORY_E; } @@ -1735,7 +1735,7 @@ static int wc_ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) } /* make the public key */ if (err == MP_OKAY) - err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); + err = wc_ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN /* validate the public key, order * pubkey = point at infinity */ @@ -1753,7 +1753,7 @@ static int wc_ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) mp_clear(key->pubkey.z); mp_clear(&key->k); } - ecc_del_point(base); + wc_ecc_del_point(base); if (po_init) { mp_clear(&prime); mp_clear(&order); @@ -1886,7 +1886,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, RNG* rng, } /* is the IDX valid ? */ - if (ecc_is_valid_idx(key->idx) != 1) { + if (wc_ecc_is_valid_idx(key->idx) != 1) { return ECC_BAD_ARG_E; } @@ -2059,10 +2059,10 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, /* allocate the table */ if (err == MP_OKAY) { for (x = 0; x < 16; x++) { - precomp[x] = ecc_new_point(); + precomp[x] = wc_ecc_new_point(); if (precomp[x] == NULL) { for (y = 0; y < x; ++y) { - ecc_del_point(precomp[y]); + wc_ecc_del_point(precomp[y]); } err = GEN_MEM_ERR; break; @@ -2203,7 +2203,7 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, if (tableInit) { for (x = 0; x < 16; x++) { - ecc_del_point(precomp[x]); + wc_ecc_del_point(precomp[x]); } } ForceZero(tA, ECC_BUFSIZE); @@ -2300,7 +2300,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, *stat = 0; /* is the IDX valid ? */ - if (ecc_is_valid_idx(key->idx) != 1) { + if (wc_ecc_is_valid_idx(key->idx) != 1) { return ECC_BAD_ARG_E; } @@ -2320,8 +2320,8 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } /* allocate points */ - mG = ecc_new_point(); - mQ = ecc_new_point(); + mG = wc_ecc_new_point(); + mQ = wc_ecc_new_point(); if (mQ == NULL || mG == NULL) err = MEMORY_E; @@ -2388,9 +2388,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, /* compute u1*mG + u2*mQ = mG */ if (err == MP_OKAY) - err = ecc_mulmod(&u1, mG, mG, &m, 0); + err = wc_ecc_mulmod(&u1, mG, mG, &m, 0); if (err == MP_OKAY) - err = ecc_mulmod(&u2, mQ, mQ, &m, 0); + err = wc_ecc_mulmod(&u2, mQ, mQ, &m, 0); /* find the montgomery mp */ if (err == MP_OKAY) @@ -2420,8 +2420,8 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, *stat = 1; } - ecc_del_point(mG); - ecc_del_point(mQ); + wc_ecc_del_point(mG); + wc_ecc_del_point(mQ); mp_clear(&v); mp_clear(&w); @@ -2442,7 +2442,7 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, int compressed = 0; if (in == NULL || point == NULL || (curve_idx < 0) || - (ecc_is_valid_idx(curve_idx) == 0)) + (wc_ecc_is_valid_idx(curve_idx) == 0)) return ECC_BAD_ARG_E; /* must be odd */ @@ -2568,7 +2568,7 @@ int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, word32 numlen; int ret = MP_OKAY; - if ((curve_idx < 0) || (ecc_is_valid_idx(curve_idx) == 0)) + if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) return ECC_BAD_ARG_E; /* return length needed only */ @@ -2645,7 +2645,7 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) if (key == NULL || out == NULL || outLen == NULL) return ECC_BAD_ARG_E; - if (ecc_is_valid_idx(key->idx) == 0) { + if (wc_ecc_is_valid_idx(key->idx) == 0) { return ECC_BAD_ARG_E; } numlen = key->dp->size; @@ -2780,7 +2780,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime) if (key == NULL) return BAD_FUNC_ARG; - base = ecc_new_point(); + base = wc_ecc_new_point(); if (base == NULL) return MEMORY_E; @@ -2792,11 +2792,11 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime) mp_set(base->z, 1); if (err == MP_OKAY) { - res = ecc_new_point(); + res = wc_ecc_new_point(); if (res == NULL) err = MEMORY_E; else { - err = ecc_mulmod(&key->k, base, res, prime, 1); + err = wc_ecc_mulmod(&key->k, base, res, prime, 1); if (err == MP_OKAY) { /* compare result to public key */ if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || @@ -2809,8 +2809,8 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime) } } - ecc_del_point(res); - ecc_del_point(base); + wc_ecc_del_point(res); + wc_ecc_del_point(base); return err; } @@ -2853,16 +2853,16 @@ static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order) if (key == NULL) return BAD_FUNC_ARG; - inf = ecc_new_point(); + inf = wc_ecc_new_point(); if (inf == NULL) err = MEMORY_E; else { - err = ecc_mulmod(order, &key->pubkey, inf, prime, 1); - if (err == MP_OKAY && !ecc_point_is_at_infinity(inf)) + err = wc_ecc_mulmod(order, &key->pubkey, inf, prime, 1); + if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) err = ECC_INF_E; } - ecc_del_point(inf); + wc_ecc_del_point(inf); return err; } @@ -2879,7 +2879,7 @@ int wc_ecc_check_key(ecc_key* key) return BAD_FUNC_ARG; /* pubkey point cannot be at inifinity */ - if (ecc_point_is_at_infinity(&key->pubkey)) + if (wc_ecc_point_is_at_infinity(&key->pubkey)) return ECC_INF_E; err = mp_init_multi(&prime, &order, NULL, NULL, NULL, NULL); @@ -3069,7 +3069,7 @@ int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) if (key == NULL || out == NULL || outLen == NULL) return ECC_BAD_ARG_E; - if (ecc_is_valid_idx(key->idx) == 0) { + if (wc_ecc_is_valid_idx(key->idx) == 0) { return ECC_BAD_ARG_E; } numlen = key->dp->size; @@ -3846,10 +3846,10 @@ static int find_hole(void) /* free entry z */ if (z >= 0 && fp_cache[z].g) { mp_clear(&fp_cache[z].mu); - ecc_del_point(fp_cache[z].g); + wc_ecc_del_point(fp_cache[z].g); fp_cache[z].g = NULL; for (x = 0; x < (1U<x, fp_cache[idx].g->x) != MP_OKAY) || (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { - ecc_del_point(fp_cache[idx].g); + wc_ecc_del_point(fp_cache[idx].g); fp_cache[idx].g = NULL; return GEN_MEM_ERR; } for (x = 0; x < (1U<idx) == 0) { + if (wc_ecc_is_valid_idx(key->idx) == 0) { return ECC_BAD_ARG_E; } numlen = key->dp->size; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 3fb8054fe..383f7dab8 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -45,6 +45,14 @@ #endif #endif +#ifdef SHOW_GEN + #ifdef FREESCALE_MQX + #include + #else + #include + #endif +#endif + /* reverse an array, used for radix code */ static void bn_reverse (unsigned char *s, int len) @@ -2493,46 +2501,21 @@ int mp_reduce_2k_setup(mp_int *a, mp_digit *d) } -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} - /* set the b bit of a */ int mp_set_bit (mp_int * a, int b) { int i = b / DIGIT_BIT, res; - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, i + 1)) != MP_OKAY) { - return res; - } + if (a->used < (int)(i + 1)) { + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, i + 1)) != MP_OKAY) { + return res; + } - /* set the used count of where the bit will go */ - a->used = i + 1; + /* set the used count of where the bit will go */ + a->used = (int)(i + 1); + } /* put the single bit in its place */ a->dp[i] |= ((mp_digit)1) << (b % DIGIT_BIT); @@ -2540,6 +2523,19 @@ mp_set_bit (mp_int * a, int b) return MP_OKAY; } +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, set the required bit + */ +int +mp_2expt (mp_int * a, int b) +{ + /* zero a as per default */ + mp_zero (a); + + return mp_set_bit(a, b); +} + /* multiply by a digit */ int mp_mul_d (mp_int * a, mp_digit b, mp_int * c) @@ -4086,12 +4082,15 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) #endif /* no easy answer [c'est la vie]. Just division */ - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; + if (c != NULL) { + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; } - q.used = a->used; - q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); @@ -4102,7 +4101,8 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) } else { t = 0; } - q.dp[ix] = (mp_digit)t; + if (c != NULL) + q.dp[ix] = (mp_digit)t; } if (d != NULL) { @@ -4112,8 +4112,8 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) if (c != NULL) { mp_clamp(&q); mp_exch(&q, c); + mp_clear(&q); } - mp_clear(&q); return res; } @@ -4282,6 +4282,70 @@ static int mp_prime_is_divisible (mp_int * a, int *result) return MP_OKAY; } +static const int USE_BBS = 1; + +int mp_rand_prime(mp_int* N, int len, RNG* rng, void* heap) +{ + int err, res, type; + byte* buf; + + if (N == NULL || rng == NULL) + return MP_VAL; + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return MP_VAL; + } + + /* allocate buffer to work with */ + buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); + if (buf == NULL) { + return MP_MEM; + } + XMEMSET(buf, 0, len); + + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + err = wc_RNG_GenerateBlock(rng, buf, len); + if (err != 0) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + + /* test */ + if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + } while (res == MP_NO); + + XMEMSET(buf, 0, len); + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + + return MP_OKAY; +} /* * Sets result to 1 if probably prime, 0 otherwise @@ -4468,8 +4532,6 @@ LBL_U:mp_clear (&v); return res; } - - #endif /* WOLFSSL_KEY_GEN */ @@ -4542,6 +4604,9 @@ int mp_read_radix (mp_int * a, const char *str, int radix) } return MP_OKAY; } +#endif /* HAVE_ECC */ + +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) /* returns size of ASCII representation */ int mp_radix_size (mp_int *a, int radix, int *size) @@ -4652,7 +4717,7 @@ int mp_toradix (mp_int *a, char *str, int radix) return MP_OKAY; } -#endif /* HAVE_ECC */ +#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ #endif /* USE_FAST_MATH */ diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 1a5021783..bc85a949e 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -131,14 +131,6 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, #include #endif -#ifdef SHOW_GEN - #ifdef FREESCALE_MQX - #include - #else - #include - #endif -#endif - #ifdef HAVE_CAVIUM static int InitCaviumRsaKey(RsaKey* key, void* heap); static int FreeCaviumRsaKey(RsaKey* key); @@ -152,22 +144,6 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, word32 outLen, RsaKey* key); #endif -enum { - RSA_PUBLIC_ENCRYPT = 0, - RSA_PUBLIC_DECRYPT = 1, - RSA_PRIVATE_ENCRYPT = 2, - RSA_PRIVATE_DECRYPT = 3, - - RSA_BLOCK_TYPE_1 = 1, - RSA_BLOCK_TYPE_2 = 2, - - RSA_MIN_SIZE = 512, - RSA_MAX_SIZE = 4096, - - RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */ -}; - - int wc_InitRsaKey(RsaKey* key, void* heap) { #ifdef HAVE_CAVIUM @@ -610,76 +586,7 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, return 0; } - #ifdef WOLFSSL_KEY_GEN - -static const int USE_BBS = 1; - -static int rand_prime(mp_int* N, int len, RNG* rng, void* heap) -{ - int err, res, type; - byte* buf; - - (void)heap; - if (N == NULL || rng == NULL) - return BAD_FUNC_ARG; - - /* get type */ - if (len < 0) { - type = USE_BBS; - len = -len; - } else { - type = 0; - } - - /* allow sizes between 2 and 512 bytes for a prime size */ - if (len < 2 || len > 512) { - return BAD_FUNC_ARG; - } - - /* allocate buffer to work with */ - buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); - if (buf == NULL) { - return MEMORY_E; - } - XMEMSET(buf, 0, len); - - do { -#ifdef SHOW_GEN - printf("."); - fflush(stdout); -#endif - /* generate value */ - err = wc_RNG_GenerateBlock(rng, buf, len); - if (err != 0) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - - /* munge bits */ - buf[0] |= 0x80 | 0x40; - buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); - - /* load value */ - if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - - /* test */ - if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - } while (res == MP_NO); - - ForceZero(buf, len); - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - - return 0; -} - - /* Make an RSA key for size bits, with e specified, 65537 is a good e */ int wc_MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) { @@ -703,7 +610,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) /* make p */ if (err == MP_OKAY) { do { - err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */ + err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */ if (err == MP_OKAY) err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */ @@ -716,7 +623,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) /* make q */ if (err == MP_OKAY) { do { - err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */ + err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */ if (err == MP_OKAY) err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */ diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 5c089edde..5c5f60bda 100755 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -39,6 +39,7 @@ #ifdef USE_FAST_MATH +#include #include #include /* will define asm MACROS or C ones */ @@ -1815,10 +1816,37 @@ void fp_set(fp_int *a, fp_digit b) /* chek if a bit is set */ int fp_is_bit_set (fp_int *a, fp_digit b) { - if ((fp_digit)a->used < b/DIGIT_BIT) + fp_digit i; + + if (b > FP_MAX_BITS) + return 0; + else + i = b/DIGIT_BIT; + + if ((fp_digit)a->used < i) return 0; - return (int)((a->dp[b/DIGIT_BIT] >> b%DIGIT_BIT) & (fp_digit)1); + return (int)((a->dp[i] >> b%DIGIT_BIT) & (fp_digit)1); +} + +/* set the b bit of a */ +int fp_set_bit (fp_int * a, fp_digit b) +{ + fp_digit i; + + if (b > FP_MAX_BITS) + return 0; + else + i = b/DIGIT_BIT; + + /* set the used count of where the bit will go if required */ + if (a->used < (int)(i+1)) + a->used = (int)(i+1); + + /* put the single bit in its place */ + a->dp[i] |= ((fp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; } int fp_count_bits (fp_int * a) @@ -1840,6 +1868,7 @@ int fp_count_bits (fp_int * a) ++r; q >>= ((fp_digit) 1); } + return r; } @@ -2186,17 +2215,22 @@ void mp_rshb (mp_int* a, int x) /* fast math wrappers */ -int mp_set_int(fp_int *a, fp_digit b) +int mp_set_int(mp_int *a, mp_digit b) { fp_set(a, b); return MP_OKAY; } -int mp_is_bit_set (fp_int *a, fp_digit b) +int mp_is_bit_set (mp_int *a, mp_digit b) { return fp_is_bit_set(a, b); } +int mp_set_bit(mp_int *a, mp_digit b) +{ + return fp_set_bit(a, b); +} + #if defined(WOLFSSL_KEY_GEN) || defined (HAVE_ECC) /* c = a * a (mod b) */ @@ -2230,6 +2264,18 @@ static const int lnz[16] = { 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +static void fp_exch (fp_int * a, fp_int * b) +{ + fp_int t; + + t = *a; + *a = *b; + *b = t; +} + /* Counts the number of lsbs which are zero before the first zero bit */ int fp_cnt_lsb(fp_int *a) { @@ -2258,8 +2304,6 @@ int fp_cnt_lsb(fp_int *a) } - - static int s_is_power_of_two(fp_digit b, int *p) { int x; @@ -2313,11 +2357,14 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) return FP_OKAY; } - /* no easy answer [c'est la vie]. Just division */ - fp_init(&q); + if (c != NULL) { + /* no easy answer [c'est la vie]. Just division */ + fp_init(&q); + + q.used = a->used; + q.sign = a->sign; + } - q.used = a->used; - q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]); @@ -2328,7 +2375,8 @@ static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) } else { t = 0; } - q.dp[ix] = (fp_digit)t; + if (c != NULL) + q.dp[ix] = (fp_digit)t; } if (d != NULL) { @@ -2362,6 +2410,7 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c) void fp_gcd(fp_int *a, fp_int *b, fp_int *c); void fp_lcm(fp_int *a, fp_int *b, fp_int *c); int fp_isprime(fp_int *a); +int fp_randprime(fp_int* N, int len, RNG* rng, void* heap); int mp_gcd(fp_int *a, fp_int *b, fp_int *c) { @@ -2384,6 +2433,31 @@ int mp_prime_is_prime(mp_int* a, int t, int* result) return MP_OKAY; } +int mp_rand_prime(mp_int* N, int len, RNG* rng, void* heap) +{ + int err; + + err = fp_randprime(N, len, rng, heap); + switch(err) { + case FP_VAL: + return MP_VAL; + break; + case FP_MEM: + return MP_MEM; + break; + default: + break; + } + + return MP_OKAY; +} + +int mp_exch (mp_int * a, mp_int * b) +{ + fp_exch(a, b); + return MP_OKAY; +} + /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 * @@ -2513,6 +2587,59 @@ int fp_isprime(fp_int *a) return FP_YES; } +int fp_randprime(fp_int* N, int len, RNG* rng, void* heap) +{ + static const int USE_BBS = 1; + int err, type; + byte* buf; + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return FP_VAL; + } + + /* allocate buffer to work with */ + buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) { + return FP_MEM; + } + XMEMSET(buf, 0, len); + + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + err = wc_RNG_GenerateBlock(rng, buf, len); + if (err != 0) { + XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER); + return FP_VAL; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + fp_read_unsigned_bin(N, buf, len); + + /* test */ + } while (fp_isprime(N) == FP_NO); + + XMEMSET(buf, 0, len); + XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER); + + return FP_OKAY; +} /* c = [a, b] */ void fp_lcm(fp_int *a, fp_int *b, fp_int *c) @@ -2740,7 +2867,7 @@ int mp_radix_size (mp_int *a, int radix, int *size) if (fp_iszero(a) == MP_YES) { *size = 2; - return FP_YES; + return FP_OKAY; } /* digs is the digit count */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c96d836a6..26ee84d4c 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -210,7 +210,7 @@ int pbkdf2_test(void); #endif -/* General big buffer size for many tests. */ +/* General big buffer size for many tests. */ #define FOURK_BUF 4096 @@ -3385,6 +3385,7 @@ int rsa_test(void) #ifdef HAVE_CAVIUM wc_RsaInitCavium(&key, CAVIUM_DEV_ID); #endif + ret = wc_InitRsaKey(&key, 0); if (ret != 0) { free(tmp); @@ -3465,7 +3466,6 @@ int rsa_test(void) (void)bytes; #endif - #ifdef WOLFSSL_KEY_GEN { byte* der; @@ -3575,7 +3575,6 @@ int rsa_test(void) } #endif /* WOLFSSL_KEY_GEN */ - #ifdef WOLFSSL_CERT_GEN /* self signed */ { @@ -4428,8 +4427,111 @@ int dsa_test(void) if (answer != 1) return -65; wc_FreeDsaKey(&key); - wc_FreeRng(&rng); +#ifdef WOLFSSL_KEY_GEN + { + byte* der; + byte* pem; + int derSz = 0; + int pemSz = 0; + DsaKey derIn; + DsaKey genKey; + FILE* keyFile; + FILE* pemFile; + + wc_InitDsaKey(&genKey); + ret = wc_MakeDsaParameters(&rng, 1024, &genKey); + if (ret != 0) return -362; + + ret = wc_MakeDsaKey(&rng, &genKey); + if (ret != 0) return -363; + + der = (byte*)malloc(FOURK_BUF); + if (der == NULL) { + wc_FreeDsaKey(&genKey); + return -364; + } + pem = (byte*)malloc(FOURK_BUF); + if (pem == NULL) { + free(der); + wc_FreeDsaKey(&genKey); + return -365; + } + + derSz = wc_DsaKeyToDer(&genKey, der, FOURK_BUF); + if (derSz < 0) { + free(der); + free(pem); + return -366; + } + +#ifdef FREESCALE_MQX + keyFile = fopen("a:\\certs\\key.der", "wb"); +#else + keyFile = fopen("./key.der", "wb"); +#endif + if (!keyFile) { + free(der); + free(pem); + wc_FreeDsaKey(&genKey); + return -367; + } + ret = (int)fwrite(der, 1, derSz, keyFile); + fclose(keyFile); + if (ret != derSz) { + free(der); + free(pem); + wc_FreeDsaKey(&genKey); + return -368; + } + + pemSz = wc_DerToPem(der, derSz, pem, FOURK_BUF, DSA_PRIVATEKEY_TYPE); + if (pemSz < 0) { + free(der); + free(pem); + wc_FreeDsaKey(&genKey); + return -369; + } + +#ifdef FREESCALE_MQX + pemFile = fopen("a:\\certs\\key.pem", "wb"); +#else + pemFile = fopen("./key.pem", "wb"); +#endif + if (!pemFile) { + free(der); + free(pem); + wc_FreeDsaKey(&genKey); + return -370; + } + ret = (int)fwrite(pem, 1, pemSz, pemFile); + fclose(pemFile); + if (ret != pemSz) { + free(der); + free(pem); + wc_FreeDsaKey(&genKey); + return -371; + } + + wc_InitDsaKey(&derIn); + idx = 0; + ret = wc_DsaPrivateKeyDecode(der, &idx, &derIn, derSz); + if (ret != 0) { + free(der); + free(pem); + wc_FreeDsaKey(&derIn); + wc_FreeDsaKey(&genKey); + return -373; + } + + wc_FreeDsaKey(&derIn); + wc_FreeDsaKey(&genKey); + free(pem); + free(der); + } +#endif /* WOLFSSL_KEY_GEN */ + + wc_FreeRng(&rng); return 0; } diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h index aedcab452..98048bd9c 100644 --- a/wolfssl/openssl/dsa.h +++ b/wolfssl/openssl/dsa.h @@ -24,7 +24,7 @@ struct WOLFSSL_DSA { WOLFSSL_API WOLFSSL_DSA* wolfSSL_DSA_new(void); -WOLFSSL_API void wolfSSL_DSA_free(WOLFSSL_DSA*); +WOLFSSL_API void wolfSSL_DSA_free(WOLFSSL_DSA*); WOLFSSL_API int wolfSSL_DSA_generate_key(WOLFSSL_DSA*); WOLFSSL_API int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA*, int bits, diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 56b85baec..7da6074a9 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -14,75 +14,104 @@ #endif -WOLFSSL_API int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, - const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - pem_password_cb cb, void* arg); +/* RSA */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + byte **pem, int *plen); +WOLFSSL_API +WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_RSAPublicKey(FILE *fp, WOLFSSL_RSA *x); -WOLFSSL_API int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, - const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - pem_password_cb cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x); -WOLFSSL_API int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u); +/* DSA */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + byte **pem, int *plen); +WOLFSSL_API +int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x); -WOLFSSL_API int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, - const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - pem_password_cb cb, void* arg); +/* ECC */ +WOLFSSL_API +int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg); +WOLFSSL_API +int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *key, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); +WOLFSSL_API +int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* key, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + byte **pem, int *plen); +WOLFSSL_API +int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *key); -WOLFSSL_API int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u); +/* EVP_KEY */ +WOLFSSL_API +WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY**, + pem_password_cb cb, + void* arg); +WOLFSSL_API +int wolfSSL_EVP_PKEY_type(int type); -WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, - WOLFSSL_EVP_PKEY**, pem_password_cb cb, void* arg); +WOLFSSL_API +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u); -WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); - -WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, - pem_password_cb *cb, void *u); - -WOLFSSL_API WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(FILE *fp, WOLFSSL_RSA **x, - pem_password_cb *cb, void *u); - -WOLFSSL_API int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x); - -WOLFSSL_API int wolfSSL_PEM_write_RSAPublicKey(FILE *fp, WOLFSSL_RSA *x); - -WOLFSSL_API int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x); - -WOLFSSL_API int wolfSSL_PEM_write_buf_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, - unsigned char* passwd, int len, - byte **pem, int *plen); - -WOLFSSL_API int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *key); -WOLFSSL_API int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *key, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u); - -#define PEM_write_bio_ECPrivateKey wolfSSL_PEM_write_bio_ECPrivateKey +/* RSA */ #define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey -#define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey +#define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey +#define PEM_write_RSA_PUBKEY wolfSSL_PEM_write_RSA_PUBKEY +#define PEM_write_RSAPublicKey wolfSSL_PEM_write_RSAPublicKey +#define PEM_read_RSAPublicKey wolfSSL_PEM_read_RSAPublicKey +/* DSA */ #define PEM_write_bio_DSAPrivateKey wolfSSL_PEM_write_bio_DSAPrivateKey -#define PEM_write_DSAPrivateKey wolfSSL_PEM_write_DSAPrivateKey -#define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey -#define PEM_write_RSA_PUBKEY wolfSSL_PEM_write_RSA_PUBKEY -#define PEM_write_RSAPublicKey wolfSSL_PEM_write_RSAPublicKey -#define PEM_write_DSA_PUBKEY wolfSSL_PEM_write_DSA_PUBKEY -#define PEM_read_RSAPublicKey wolfSSL_PEM_read_RSAPublicKey -#define PEM_read_RSAPublicKey wolfSSL_PEM_read_RSAPublicKey -#define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY -#define PEM_write_EC_PUBKEY wolfSSL_PEM_write_EC_PUBKEY -#define PEM_write_ECPrivateKey wolfSSL_PEM_write_ECPrivateKey -#define EVP_PKEY_type wolfSSL_EVP_PKEY_type +#define PEM_write_DSAPrivateKey wolfSSL_PEM_write_DSAPrivateKey +#define PEM_write_DSA_PUBKEY wolfSSL_PEM_write_DSA_PUBKEY +/* ECC */ +#define PEM_write_bio_ECPrivateKey wolfSSL_PEM_write_bio_ECPrivateKey +#define PEM_write_EC_PUBKEY wolfSSL_PEM_write_EC_PUBKEY +#define PEM_write_ECPrivateKey wolfSSL_PEM_write_ECPrivateKey +/* EVP_KEY */ +#define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey +#define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY +#define EVP_PKEY_type wolfSSL_EVP_PKEY_type #ifdef __cplusplus } /* extern "C" */ #endif - #endif /* WOLFSSL_PEM_H_ */ diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index a94ad0801..d99558cbb 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -126,17 +126,24 @@ typedef struct Gmac { #endif /* HAVE_AESGCM */ #endif /* HAVE_FIPS */ - WOLFSSL_API int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, - int dir); - WOLFSSL_API int wc_AesSetIV(Aes* aes, const byte* iv); - WOLFSSL_API int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); - WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); - WOLFSSL_API int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, - const byte* key, word32 keySz, const byte* iv); +WOLFSSL_API int wc_AesSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir); +WOLFSSL_API int wc_AesSetIV(Aes* aes, const byte* iv); +WOLFSSL_API int wc_AesCbcEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, + const byte* iv); +WOLFSSL_API int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, + const byte* iv); /* AES-CTR */ #ifdef WOLFSSL_AES_COUNTER - WOLFSSL_API void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); + WOLFSSL_API void wc_AesCtrEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); #endif /* AES-DIRECT */ #if defined(WOLFSSL_AES_DIRECT) @@ -147,30 +154,34 @@ typedef struct Gmac { #endif #ifdef HAVE_AESGCM WOLFSSL_API int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len); - WOLFSSL_API int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, - const byte* iv, word32 ivSz, - byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); - WOLFSSL_API int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, - const byte* iv, word32 ivSz, - const byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesGcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesGcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len); WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, - const byte* authIn, word32 authInSz, - byte* authTag, word32 authTagSz); + const byte* authIn, word32 authInSz, + byte* authTag, word32 authTagSz); #endif /* HAVE_AESGCM */ #ifdef HAVE_AESCCM WOLFSSL_API void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz); - WOLFSSL_API void wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, - const byte* nonce, word32 nonceSz, - byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); - WOLFSSL_API int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, - const byte* nonce, word32 nonceSz, - const byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); + WOLFSSL_API void wc_AesCcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + WOLFSSL_API int wc_AesCcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); #endif /* HAVE_AESCCM */ #ifdef HAVE_CAVIUM diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 824ea019b..311cad852 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -182,8 +182,9 @@ enum Misc_ASN { MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */ MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */ EIGHTK_BUF = 8192, /* Tmp buffer size */ - MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2 + MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, /* use bigger NTRU size */ + HEADER_ENCRYPTED_KEY_SIZE = 88 /* Extra header size for encrypted key */ }; @@ -476,6 +477,24 @@ struct DecodedCert { #endif /* WOLFSSL_SEP */ }; +extern const char* BEGIN_CERT; +extern const char* END_CERT; +extern const char* BEGIN_CERT_REQ; +extern const char* END_CERT_REQ; +extern const char* BEGIN_DH_PARAM; +extern const char* END_DH_PARAM; +extern const char* BEGIN_X509_CRL; +extern const char* END_X509_CRL; +extern const char* BEGIN_RSA_PRIV; +extern const char* END_RSA_PRIV; +extern const char* BEGIN_PRIV_KEY; +extern const char* END_PRIV_KEY; +extern const char* BEGIN_ENC_PRIV_KEY; +extern const char* END_ENC_PRIV_KEY; +extern const char* BEGIN_EC_PRIV; +extern const char* END_EC_PRIV; +extern const char* BEGIN_DSA_PRIV; +extern const char* END_DSA_PRIV; #ifdef NO_SHA #define SIGNER_DIGEST_SIZE SHA256_DIGEST_SIZE diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 223cea9be..04f77851a 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -43,6 +43,7 @@ enum CertType { CRL_TYPE, CA_TYPE, ECC_PRIVATEKEY_TYPE, + DSA_PRIVATEKEY_TYPE, CERTREQ_TYPE, DSA_TYPE, ECC_TYPE, @@ -177,7 +178,9 @@ WOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int); #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA) WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output, - word32 outputSz, int type); + word32 outputSz, int type); + WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, + word32 outputSz, byte *cipherIno, int type); #endif #ifdef HAVE_ECC diff --git a/wolfssl/wolfcrypt/coding.h b/wolfssl/wolfcrypt/coding.h index cb9bde0b8..6c203e964 100644 --- a/wolfssl/wolfcrypt/coding.h +++ b/wolfssl/wolfcrypt/coding.h @@ -62,6 +62,8 @@ WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out, #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) WOLFSSL_API int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen); + WOLFSSL_API + int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen); #endif diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index c17884968..c0d9394a2 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -83,21 +83,35 @@ typedef struct Des3 { } Des3; #endif /* HAVE_FIPS */ -WOLFSSL_API int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir); +WOLFSSL_API int wc_Des_SetKey(Des* des, const byte* key, + const byte* iv, int dir); WOLFSSL_API void wc_Des_SetIV(Des* des, const byte* iv); -WOLFSSL_API int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz); -WOLFSSL_API int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); -WOLFSSL_API int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz); -WOLFSSL_API int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, - const byte* key, const byte* iv); +WOLFSSL_API int wc_Des_CbcEncrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des_CbcDecrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des_EcbEncrypt(Des* des, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_Des_CbcDecryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +WOLFSSL_API int wc_Des_CbcEncryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); -WOLFSSL_API int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir); +WOLFSSL_API int wc_Des3_SetKey(Des3* des, const byte* key, + const byte* iv,int dir); WOLFSSL_API int wc_Des3_SetIV(Des3* des, const byte* iv); -WOLFSSL_API int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in,word32 sz); -WOLFSSL_API int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in,word32 sz); -WOLFSSL_API int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, - const byte* key, const byte* iv); - +WOLFSSL_API int wc_Des3_CbcEncrypt(Des3* des, byte* out, + const byte* in,word32 sz); +WOLFSSL_API int wc_Des3_CbcDecrypt(Des3* des, byte* out, + const byte* in,word32 sz); +WOLFSSL_API int wc_Des3_CbcEncryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); +WOLFSSL_API int wc_Des3_CbcDecryptWithKey(byte* out, + const byte* in, word32 sz, + const byte* key, const byte* iv); #ifdef HAVE_CAVIUM WOLFSSL_API int wc_Des3_InitCavium(Des3*, int); diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index 8da15cf31..115c18c6e 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -66,6 +66,11 @@ WOLFSSL_API int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey*, word32); WOLFSSL_API int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen); +#ifdef WOLFSSL_KEY_GEN +WOLFSSL_API int wc_MakeDsaKey(RNG *rng, DsaKey *dsa); +WOLFSSL_API int wc_MakeDsaParameters(RNG *rng, int modulus_size, DsaKey *dsa); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 3da99ec64..6630a1ae8 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -73,18 +73,18 @@ typedef struct { * mp_ints for the components of the point. With ALT_ECC_SIZE, the components * of the point are pointers that are set to each of a three item array of * alt_fp_ints. While an mp_int will have 4096 bits of digit inside the - * structure, the alt_fp_int will only have 512 bits. A size value was added + * structure, the alt_fp_int will only have 528 bits. A size value was added * in the ALT case, as well, and is set by mp_init() and alt_fp_init(). The * functions fp_zero() and fp_copy() use the size parameter. An int needs to * be initialized before using it instead of just fp_zeroing it, the init will - * call zero. FP_MAX_BITS_ECC defaults to 512, but can be set to change the + * call zero. FP_MAX_BITS_ECC defaults to 528, but can be set to change the * number of bits used in the alternate FP_INT. * * Do not enable ALT_ECC_SIZE and disable fast math in the configuration. */ #ifndef FP_MAX_BITS_ECC - #define FP_MAX_BITS_ECC 512 + #define FP_MAX_BITS_ECC 528 #endif #define FP_MAX_SIZE_ECC (FP_MAX_BITS_ECC+(8*DIGIT_BIT)) #if FP_MAX_BITS_ECC % CHAR_BIT @@ -163,17 +163,20 @@ WOLFSSL_API void wc_ecc_fp_free(void); WOLFSSL_API -ecc_point* ecc_new_point(void); +ecc_point* wc_ecc_new_point(void); WOLFSSL_API -void ecc_del_point(ecc_point* p); +void wc_ecc_del_point(ecc_point* p); WOLFSSL_API -int ecc_copy_point(ecc_point* p, ecc_point *r); +int wc_ecc_copy_point(ecc_point* p, ecc_point *r); WOLFSSL_API -int ecc_cmp_point(ecc_point* a, ecc_point *b); +int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); WOLFSSL_API -int ecc_point_is_at_infinity(ecc_point *p); +int wc_ecc_point_is_at_infinity(ecc_point *p); WOLFSSL_API -int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, int map); +int wc_ecc_is_valid_idx(int n); +WOLFSSL_API +int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, + mp_int* modulus, int map); /* ASN key helpers */ WOLFSSL_API diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index bd7da60d9..8e43a395b 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -36,6 +36,8 @@ #include #else +#include + #ifndef CHAR_BIT #include #endif @@ -313,6 +315,7 @@ int mp_radix_size (mp_int * a, int radix, int *size); int mp_prime_is_prime (mp_int * a, int t, int *result); int mp_gcd (mp_int * a, mp_int * b, mp_int * c); int mp_lcm (mp_int * a, mp_int * b, mp_int * c); + int mp_rand_prime(mp_int* N, int len, RNG* rng, void* heap); #endif int mp_cnt_lsb(mp_int *a); diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 5441535eb..1f12df941 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -46,9 +46,23 @@ enum { RSA_PUBLIC = 0, - RSA_PRIVATE = 1 + RSA_PRIVATE = 1, + + RSA_PUBLIC_ENCRYPT = 0, + RSA_PUBLIC_DECRYPT = 1, + RSA_PRIVATE_ENCRYPT = 2, + RSA_PRIVATE_DECRYPT = 3, + + RSA_BLOCK_TYPE_1 = 1, + RSA_BLOCK_TYPE_2 = 2, + + RSA_MIN_SIZE = 512, + RSA_MAX_SIZE = 4096, + + RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */ }; + /* RSA */ typedef struct RsaKey { mp_int n, e, d, p, q, dP, dQ, u; diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 2467069b3..157d58da4 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -40,6 +40,7 @@ #include #endif +#include #ifdef __cplusplus extern "C" { @@ -377,6 +378,8 @@ void fp_set(fp_int *a, fp_digit b); /* check if a bit is set */ int fp_is_bit_set(fp_int *a, fp_digit b); +/* set the b bit to 1 */ +int fp_set_bit (fp_int * a, fp_digit b); /* copy from a to b */ #ifndef ALT_ECC_SIZE @@ -651,6 +654,7 @@ void fp_sqr_comba64(fp_int *a, fp_int *b); #define MP_EQ FP_EQ /* equal to */ #define MP_GT FP_GT /* greater than */ #define MP_VAL FP_VAL /* invalid */ + #define MP_MEM FP_MEM /* memory error */ #define MP_NOT_INF FP_NOT_INF /* point not at infinity */ #define MP_OKAY FP_OKAY /* ok result */ #define MP_NO FP_NO /* yes/no result */ @@ -688,8 +692,9 @@ int mp_isodd(mp_int* a); int mp_iszero(mp_int* a); int mp_count_bits(mp_int *a); int mp_leading_bit(mp_int *a); -int mp_set_int(fp_int *a, fp_digit b); -int mp_is_bit_set (fp_int * a, fp_digit b); +int mp_set_int(mp_int *a, mp_digit b); +int mp_is_bit_set (mp_int * a, mp_digit b); +int mp_set_bit (mp_int * a, mp_digit b); void mp_rshb(mp_int *a, int x); int mp_toradix (mp_int *a, char *str, int radix); int mp_radix_size (mp_int * a, int radix, int *size); @@ -713,6 +718,8 @@ int mp_radix_size (mp_int * a, int radix, int *size); int mp_gcd(fp_int *a, fp_int *b, fp_int *c); int mp_lcm(fp_int *a, fp_int *b, fp_int *c); int mp_prime_is_prime(mp_int* a, int t, int* result); +int mp_rand_prime(mp_int* N, int len, RNG* rng, void* heap); +int mp_exch(mp_int *a, mp_int *b); #endif /* WOLFSSL_KEY_GEN */ int mp_cnt_lsb(fp_int *a);