diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 4663838f9..a512be754 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -7227,7 +7227,6 @@ WOLFSSL_API int wolfSSL_SetVersion(WOLFSSL* ssl, int version); \endcode \sa PemToDer - \sa wolfssl_decrypt_buffer_key */ WOLFSSL_API int wolfSSL_KeyPemToDer(const unsigned char*, int, unsigned char*, int, const char*); @@ -11338,7 +11337,7 @@ WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl, _Example_ \code WOLFSSL_CTX* ctx; - Pem_password_cb cb; + pem_password_cb cb; // setup ctx cb = wolfSSL_CTX_get_default_passwd_cb(ctx); //use cb diff --git a/src/crl.c b/src/crl.c index fd7a2e99b..338ac1a40 100644 --- a/src/crl.c +++ b/src/crl.c @@ -442,11 +442,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, return BAD_FUNC_ARG; if (type == WOLFSSL_FILETYPE_PEM) { - int eccKey = 0; /* not used */ - EncryptedInfo info; - info.ctx = NULL; - - ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey); + ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, NULL, NULL); if (ret == 0) { myBuffer = der->buffer; sz = der->length; diff --git a/src/ssl.c b/src/ssl.c index 3cc1da5c0..c16c5f936 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3067,11 +3067,6 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, int eccKey = 0; int ret; DerBuffer* der = NULL; -#ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; -#else - EncryptedInfo info[1]; -#endif WOLFSSL_ENTER("wolfSSL_CertPemToDer"); @@ -3085,23 +3080,8 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, return BAD_FUNC_ARG; } -#ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_ENCRYPTEDINFO); - if (info == NULL) - return MEMORY_E; -#endif - - info->set = 0; - info->ctx = NULL; - info->consumed = 0; - - ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey); - -#ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); -#endif + ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey); if (ret < 0) { WOLFSSL_MSG("Bad Pem To Der"); } @@ -3125,7 +3105,7 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ defined(HAVE_WEBSERVER) -static struct cipher{ +static const struct cipher{ unsigned char type; const char *name; } cipher_tbl[] = { @@ -3492,33 +3472,12 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, return MEMORY_E; #endif - info->set = 0; - info->ctx = NULL; - info->consumed = 0; - -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(HAVE_WEBSERVER) - if (pass) { - info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); - if (info->ctx == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif - return MEMORY_E; - } - - wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb); - wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass); - } -#else - (void)pass; -#endif + XMEMSET(info, 0, sizeof(EncryptedInfo)); + info->passwd_cb = OurPasswordCb; + info->passwd_userdata = (void*)pass; ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey); - if (info->ctx) - wolfSSL_CTX_free(info->ctx); - #ifdef WOLFSSL_SMALL_STACK XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif @@ -4404,191 +4363,6 @@ int wolfSSL_Init(void) } -#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(HAVE_WEBSERVER)) && !defined(NO_CERTS) - -/* WOLFSSL_SUCCESS if ok, <= 0 else */ -static int wolfssl_decrypt_buffer_key(DerBuffer* der, byte* password, - int passwordSz, EncryptedInfo* info) -{ - int ret = WOLFSSL_BAD_FILE; - -#ifdef WOLFSSL_SMALL_STACK - byte* key = NULL; -#else - byte key[AES_256_KEY_SIZE]; -#endif - - (void)passwordSz; - (void)key; - - WOLFSSL_ENTER("wolfssl_decrypt_buffer_key"); - - if (der == NULL || password == NULL || info == NULL) { - WOLFSSL_MSG("bad arguments"); - return WOLFSSL_FATAL_ERROR; - } - - /* use file's salt for key derivation, hex decode first */ - if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) { - WOLFSSL_MSG("base16 decode failed"); - return WOLFSSL_FATAL_ERROR; - } - -#ifndef NO_MD5 - -#ifdef WOLFSSL_SMALL_STACK - key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); - if (key == NULL) { - WOLFSSL_MSG("memory failure"); - return WOLFSSL_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_SYMETRIC_KEY); -#endif - return WOLFSSL_FATAL_ERROR; - } - -#endif /* NO_MD5 */ - -#ifndef NO_DES3 - 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, 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 */ -#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) - #ifdef WOLFSSL_AES_128 - 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 - #endif /* WOLFSSL_AES_128 */ - #ifdef WOLFSSL_AES_192 - 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 - #endif /* WOLFSSL_AES_192 */ - #ifdef WOLFSSL_AES_256 - 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 /* WOLFSSL_AES_256 */ -#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */ - -#ifdef WOLFSSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); -#endif - - if (ret == MP_OKAY) - return WOLFSSL_SUCCESS; - else if (ret == WOLFSSL_BAD_FILE) - return WOLFSSL_BAD_FILE; - - return WOLFSSL_FATAL_ERROR; -} -#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || - defined(HAVE_WEBSERVER) */ - - -#if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA) -static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password, - int passwordSz, EncryptedInfo* info) -{ - int ret = WOLFSSL_BAD_FILE; - -#ifdef WOLFSSL_SMALL_STACK - byte* key = NULL; -#else - byte key[AES_256_KEY_SIZE]; -#endif - - (void)derSz; - (void)passwordSz; - (void)key; - - WOLFSSL_ENTER("wolfssl_encrypt_buffer_key"); - - if (der == NULL || password == NULL || info == NULL || info->ivSz == 0) { - WOLFSSL_MSG("bad arguments"); - return WOLFSSL_FATAL_ERROR; - } - -#ifndef NO_MD5 - -#ifdef WOLFSSL_SMALL_STACK - key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); - if (key == NULL) { - WOLFSSL_MSG("memory failure"); - return WOLFSSL_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_SYMETRIC_KEY); -#endif - return WOLFSSL_FATAL_ERROR; - } - -#endif /* NO_MD5 */ - - if (ret > 0) { -#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); - else -#endif /* NO_DES3 */ -#ifndef NO_AES - #ifdef WOLFSSL_AES_128 - 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 - #endif - #ifdef WOLFSSL_AES_192 - 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 - #endif - #ifdef WOLFSSL_AES_256 - 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); - else - #endif -#endif /* NO_AES */ - { - ret = WOLFSSL_BAD_FILE; /* Reset error return */ - } - } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); -#endif - - if (ret == MP_OKAY) - return WOLFSSL_SUCCESS; - else if (ret == WOLFSSL_BAD_FILE) - return WOLFSSL_BAD_FILE; - - return WOLFSSL_FATAL_ERROR; -} -#endif /* defined(WOLFSSL_KEY_GEN) */ - #ifndef NO_CERTS @@ -4769,9 +4543,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif XMEMSET(info, 0, sizeof(EncryptedInfo)); - info->set = 0; - info->ctx = ctx; - info->consumed = 0; + if (ctx) { + info->passwd_cb = ctx->passwd_cb; + info->passwd_userdata = ctx->passwd_userdata; + } if (format == WOLFSSL_FILETYPE_PEM) { ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey); @@ -4806,21 +4581,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } } - /* check for error */ - if (ret < 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif - FreeDer(&der); - return ret; - } - -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(HAVE_WEBSERVER) +#ifdef WOLFSSL_ENCRYPTED_KEYS /* for WOLFSSL_FILETYPE_PEM, PemToDer manage the decryption if required */ - if (info->set && (format != WOLFSSL_FILETYPE_PEM)) { + if (ret >= 0 && info->set && format != WOLFSSL_FILETYPE_PEM) { /* decrypt */ - int passwordSz; + int passwordSz = NAME_SZ; #ifdef WOLFSSL_SMALL_STACK char* password = NULL; #else @@ -4828,41 +4593,40 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif #ifdef WOLFSSL_SMALL_STACK - password = (char*)XMALLOC(NAME_SZ, heap, DYNAMIC_TYPE_STRING); + password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING); if (password == NULL) ret = MEMORY_E; else #endif - if (!ctx || !ctx->passwd_cb) { + if (info->passwd_cb == NULL) { + WOLFSSL_MSG("No password callback set"); ret = NO_PASSWORD; } else { - passwordSz = ctx->passwd_cb(password, NAME_SZ, - 0, ctx->userdata); + passwordSz = info->passwd_cb(password, passwordSz, PEM_PASS_READ, + info->passwd_userdata); /* decrypt the key */ - ret = wolfssl_decrypt_buffer_key(der, (byte*)password, - passwordSz, info); + ret = wc_BufferKeyDecrypt(info, der->buffer, der->length, + (byte*)password, passwordSz); } #ifdef WOLFSSL_SMALL_STACK XFREE(password, heap, DYNAMIC_TYPE_STRING); #endif - - if (ret != WOLFSSL_SUCCESS) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif - FreeDer(&der); - return ret; - } } -#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */ +#endif /* WOLFSSL_ENCRYPTED_KEYS */ #ifdef WOLFSSL_SMALL_STACK XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif + /* check for error */ + if (ret < 0) { + FreeDer(&der); + return ret; + } + /* Handle DER owner */ if (type == CA_TYPE) { if (ctx == NULL) { @@ -4889,18 +4653,18 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, /* Make sure previous is free'd */ if (ssl->buffers.weOwnCert) { FreeDer(&ssl->buffers.certificate); - #ifdef KEEP_OUR_CERT - FreeX509(ssl->ourCert); - if (ssl->ourCert) { - XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509); - ssl->ourCert = NULL; - } - #endif + #ifdef KEEP_OUR_CERT + FreeX509(ssl->ourCert); + if (ssl->ourCert) { + XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509); + ssl->ourCert = NULL; + } + #endif } ssl->buffers.certificate = der; - #ifdef KEEP_OUR_CERT - ssl->keepCert = 1; /* hold cert for ssl lifetime */ - #endif + #ifdef KEEP_OUR_CERT + ssl->keepCert = 1; /* hold cert for ssl lifetime */ + #endif ssl->buffers.weOwnCert = 1; } else if (ctx) { @@ -5338,11 +5102,10 @@ static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #ifdef HAVE_CRL if (ret < 0) { DerBuffer* der = NULL; - EncryptedInfo info; WOLFSSL_MSG("Trying a CRL"); - if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info, - NULL) == 0) { + if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, NULL, + NULL) == 0) { WOLFSSL_MSG(" Proccessed a CRL"); wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer, der->length, WOLFSSL_FILETYPE_ASN1); @@ -5552,40 +5315,15 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff, #endif if (format == WOLFSSL_FILETYPE_PEM) { - int eccKey = 0; /* not used */ - #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; - #else - EncryptedInfo info[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), cm->heap, - DYNAMIC_TYPE_ENCRYPTEDINFO); - if (info == NULL) { - XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); - return MEMORY_E; - } - #endif - - info->set = 0; - info->ctx = NULL; - info->consumed = 0; - - ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey); + ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL); if (ret != 0) { FreeDer(&der); #ifdef WOLFSSL_SMALL_STACK XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); - XFREE(info, cm->heap, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif return ret; } InitDecodedCert(cert, der->buffer, der->length, cm->heap); - - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, cm->heap, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif } else InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap); @@ -7281,13 +7019,11 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, } -/* this function makes the assumption that out buffer is big enough for digest*/ -static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, - unsigned int* outSz, const WOLFSSL_EVP_MD* evp, - WOLFSSL_ENGINE* eng) +static int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, + int* pHash, int* pHashSz) { enum wc_HashType hash = WC_HASH_TYPE_NONE; - int hashSz; + int hashSz; if (XSTRLEN(evp) < 3) { /* do not try comparing strings if size is too small */ @@ -7296,24 +7032,24 @@ static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, if (XSTRNCMP("SHA", evp, 3) == 0) { if (XSTRLEN(evp) > 3) { - #ifndef NO_SHA256 + #ifndef NO_SHA256 if (XSTRNCMP("SHA256", evp, 6) == 0) { hash = WC_HASH_TYPE_SHA256; } else - #endif - #ifdef WOLFSSL_SHA384 + #endif + #ifdef WOLFSSL_SHA384 if (XSTRNCMP("SHA384", evp, 6) == 0) { hash = WC_HASH_TYPE_SHA384; } else - #endif - #ifdef WOLFSSL_SHA512 + #endif + #ifdef WOLFSSL_SHA512 if (XSTRNCMP("SHA512", evp, 6) == 0) { hash = WC_HASH_TYPE_SHA512; } else - #endif + #endif { WOLFSSL_MSG("Unknown SHA hash"); } @@ -7338,20 +7074,43 @@ static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, } #endif + if (pHash) + *pHash = hash; + hashSz = wc_HashGetDigestSize(hash); + if (pHashSz) + *pHashSz = hashSz; + if (hashSz < 0) { - WOLFSSL_LEAVE("wolfSSL_EVP_Digest", hashSz); return WOLFSSL_FAILURE; } - *outSz = hashSz; + + return WOLFSSL_SUCCESS; +} + + +/* this function makes the assumption that out buffer is big enough for digest*/ +static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, + unsigned int* outSz, const WOLFSSL_EVP_MD* evp, + WOLFSSL_ENGINE* eng) +{ + int err; + int hashType = WC_HASH_TYPE_NONE; + int hashSz; (void)eng; - if (wc_Hash(hash, in, inSz, out, *outSz) == 0) { - return WOLFSSL_SUCCESS; - } - else { + + err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz); + if (err != WOLFSSL_SUCCESS) + return err; + + *outSz = hashSz; + + if (wc_Hash((enum wc_HashType)hashType, in, inSz, out, *outSz) != 0) { return WOLFSSL_FAILURE; } + + return WOLFSSL_SUCCESS; } @@ -12025,7 +11784,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) void* userdata) { WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata"); - ctx->userdata = userdata; + ctx->passwd_userdata = userdata; } @@ -12037,141 +11796,66 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } -#ifndef NO_MD5 + pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx) + { + if (ctx == NULL || ctx->passwd_cb == NULL) { + return NULL; + } + + return ctx->passwd_cb; + } + + + void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx) + { + if (ctx == NULL) { + return NULL; + } + + return ctx->passwd_userdata; + } + int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type, const WOLFSSL_EVP_MD* md, const byte* salt, const byte* data, int sz, int count, byte* key, byte* iv) { - int keyLen = 0; - int ivLen = 0; - int j; - int keyLeft; - int ivLeft; - int keyOutput = 0; - byte digest[WC_MD5_DIGEST_SIZE]; + int ret; + int hashType; #ifdef WOLFSSL_SMALL_STACK - wc_Md5* md5 = NULL; + EncryptedInfo* info = NULL; #else - wc_Md5 md5[1]; + EncryptedInfo info[1]; #endif #ifdef WOLFSSL_SMALL_STACK - md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), NULL, DYNAMIC_TYPE_HASHCTX); - if (md5 == NULL) - return 0; + info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, + DYNAMIC_TYPE_ENCRYPTEDINFO); + if (info == NULL) { + WOLFSSL_MSG("malloc failed"); + return WOLFSSL_FAILURE; + } #endif - (void)type; + XMEMSET(info, 0, sizeof(EncryptedInfo)); - WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey"); - - if (wc_InitMd5(md5) != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_HASHCTX); - #endif - return 0; - } - - /* only support MD5 for now */ - if (XSTRNCMP(md, "MD5", 3) != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_HASHCTX); - #endif - return 0; - } - - /* only support CBC DES and AES for now */ - #ifndef NO_DES3 - if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) { - keyLen = DES_KEY_SIZE; - ivLen = DES_IV_SIZE; - } - else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) { - keyLen = DES3_KEY_SIZE; - ivLen = DES_IV_SIZE; - } - else - #endif /* NO_DES3 */ - #ifndef NO_AES - #ifdef HAVE_AES_CBC - #ifdef WOLFSSL_AES_128 - if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_128_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else - #endif - #ifdef WOLFSSL_AES_192 - if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_192_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else - #endif - #ifdef WOLFSSL_AES_256 - if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_256_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else - #endif - #endif /* HAVE_AES_CBC */ - #endif /* NO_AES */ - { - #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_HASHCTX); - #endif - return 0; - } - - keyLeft = keyLen; - ivLeft = ivLen; - - while (keyOutput < (keyLen + ivLen)) { - int digestLeft = WC_MD5_DIGEST_SIZE; - /* D_(i - 1) */ - if (keyOutput) /* first time D_0 is empty */ - wc_Md5Update(md5, digest, WC_MD5_DIGEST_SIZE); - /* data */ - wc_Md5Update(md5, data, sz); - /* salt */ - if (salt) - wc_Md5Update(md5, salt, EVP_SALT_SIZE); - wc_Md5Final(md5, digest); - /* count */ - for (j = 1; j < count; j++) { - wc_Md5Update(md5, digest, WC_MD5_DIGEST_SIZE); - wc_Md5Final(md5, digest); - } - - if (keyLeft) { - int store = min(keyLeft, WC_MD5_DIGEST_SIZE); - XMEMCPY(&key[keyLen - keyLeft], digest, store); - - keyOutput += store; - keyLeft -= store; - digestLeft -= store; - } - - if (ivLeft && digestLeft) { - int store = min(ivLeft, digestLeft); - if (iv != NULL) - XMEMCPY(&iv[ivLen - ivLeft], - &digest[WC_MD5_DIGEST_SIZE - digestLeft], store); - keyOutput += store; - ivLeft -= store; - } - } + ret = wolfSSL_EVP_get_hashinfo(md, &hashType, NULL); + if (ret == 0) + ret = wc_EncryptedInfoGet(info, type); + if (ret == 0) + ret = wc_PBKDF1_ex(key, info->keySz, iv, info->ivSz, data, sz, salt, + EVP_SALT_SIZE, count, hashType, NULL); #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_HASHCTX); + XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif - return keyOutput == (keyLen + ivLen) ? keyOutput : 0; + if (ret <= 0) + return 0; /* failure - for compatibility */ + + return ret; } -#endif /* NO_MD5 */ #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */ @@ -14538,28 +14222,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return (unsigned long)ret; } - - WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb( - WOLFSSL_CTX *ctx) - { - if (ctx == NULL || ctx->passwd_cb == NULL) { - return NULL; - } - - return ctx->passwd_cb; - } - - - WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata( - WOLFSSL_CTX *ctx) - { - if (ctx == NULL) { - return NULL; - } - - return ctx->userdata; - } - #endif /* OPENSSL_EXTRA */ @@ -15328,32 +14990,9 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex"); if (format == WOLFSSL_FILETYPE_PEM) { - int ecc = 0; - #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; - #else - EncryptedInfo info[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_ENCRYPTEDINFO); - if (info == NULL) { - return NULL; - } - #endif - - info->set = 0; - info->ctx = NULL; - info->consumed = 0; - - if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0) { + if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, NULL, NULL) != 0) { FreeDer(&der); } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif } else { ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL); @@ -17518,6 +17157,8 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, byte* curr = NULL; byte* prev = NULL; WOLFSSL_X509* x509; + const char* header = NULL; + const char* footer = NULL; if (type != X509_FILETYPE_PEM) return BAD_FUNC_ARG; @@ -17545,7 +17186,9 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, prev = curr = pem; do { - if (XSTRNSTR((char*)curr, BEGIN_X509_CRL, (unsigned int)sz) != NULL) { + /* get PEM header and footer based on type */ + if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 && + XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) { #ifdef HAVE_CRL WOLFSSL_CERT_MANAGER* cm = lookup->store->cm; @@ -17560,9 +17203,10 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, if (ret != WOLFSSL_SUCCESS) goto end; #endif - curr = (byte*)XSTRNSTR((char*)curr, END_X509_CRL, (unsigned int)sz); + curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz); } - else if (XSTRNSTR((char*)curr, BEGIN_CERT, (unsigned int)sz) != NULL) { + else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 && + XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) { x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz, WOLFSSL_FILETYPE_PEM); if (x509 == NULL) @@ -17571,7 +17215,7 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, wolfSSL_X509_free(x509); if (ret != WOLFSSL_SUCCESS) goto end; - curr = (byte*)XSTRNSTR((char*)curr, END_CERT, (unsigned int)sz); + curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz); } else goto end; @@ -21269,17 +20913,14 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) if (ssl != NULL && fname != NULL) { #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; byte staticBuffer[1]; /* force heap usage */ #else - EncryptedInfo info[1]; byte staticBuffer[FILE_BUFFER_SIZE]; #endif byte* myBuffer = staticBuffer; int dynamic = 0; XFILE file = XBADFILE; size_t sz = 0; - int eccKey = 0; WOLFSSL_CTX* ctx = ssl->ctx; WOLFSSL_X509* peer_cert = &ssl->peerCert; DerBuffer* fileDer = NULL; @@ -21298,34 +20939,18 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) dynamic = 1; } - #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_ENCRYPTEDINFO); - if (info == NULL) - ret = MEMORY_E; - else - #endif + + if ((myBuffer != NULL) && + (sz > 0) && + (XFREAD(myBuffer, 1, sz, file) == sz) && + (PemToDer(myBuffer, (long)sz, CERT_TYPE, + &fileDer, ctx->heap, NULL, NULL) == 0) && + (fileDer->length != 0) && + (fileDer->length == peer_cert->derCert->length) && + (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer, + fileDer->length) == 0)) { - info->set = 0; - info->ctx = ctx; - info->consumed = 0; - - if ((myBuffer != NULL) && - (sz > 0) && - (XFREAD(myBuffer, 1, sz, file) == sz) && - (PemToDer(myBuffer, (long)sz, CERT_TYPE, - &fileDer, ctx->heap, info, &eccKey) == 0) && - (fileDer->length != 0) && - (fileDer->length == peer_cert->derCert->length) && - (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer, - fileDer->length) == 0)) - { - ret = 0; - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif + ret = 0; } FreeDer(&fileDer); @@ -25443,33 +25068,22 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, return WOLFSSL_FAILURE; } #endif - info->set = 0; - info->ctx = NULL; - info->consumed = 0; - /* set iv size */ -#ifndef NO_DES3 - if (XSTRNCMP(cipher, "DES", 3) == 0) - info->ivSz = DES_IV_SIZE; - else -#endif -#ifndef NO_AES - if (XSTRNCMP(cipher, "AES", 3) == 0) - info->ivSz = AES_IV_SIZE; - else -#endif - { - WOLFSSL_MSG("unsupported cipher"); -#ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); -#endif - return WOLFSSL_FAILURE; - } + XMEMSET(info, 0, sizeof(EncryptedInfo)); /* set the cipher name on info */ XSTRNCPY(info->name, cipher, NAME_SZ-1); info->name[NAME_SZ-1] = '\0'; /* null term */ + ret = wc_EncryptedInfoGet(info, info->name); + if (ret != 0) { + WOLFSSL_MSG("unsupported cipher"); + #ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); + #endif + return WOLFSSL_FAILURE; + } + /* Generate a random salt */ if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("generate iv failed"); @@ -25487,8 +25101,7 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, (*derSz) += paddingSz; /* encrypt buffer */ - if (wolfssl_encrypt_buffer_key(der, *derSz, - passwd, passwdSz, info) != WOLFSSL_SUCCESS) { + if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz) != 0) { WOLFSSL_MSG("encrypt key failed"); #ifdef WOLFSSL_SMALL_STACK XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); @@ -25525,7 +25138,7 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, return WOLFSSL_SUCCESS; } -#endif /* defined(WOLFSSL_KEY_GEN) */ +#endif /* WOLFSSL_KEY_GEN */ #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) /* Takes a WOLFSSL_RSA key and writes it out to a WOLFSSL_BIO @@ -25686,6 +25299,9 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, { byte *derBuf, *tmp, *cipherInfo = NULL; int der_max_len = 0, derSz = 0; + const int type = PRIVATEKEY_TYPE; + const char* header = NULL; + const char* footer = NULL; WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey"); @@ -25694,6 +25310,9 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, return WOLFSSL_FAILURE; } + if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) + return WOLFSSL_FAILURE; + if (rsa->inSet == 0) { WOLFSSL_MSG("No RSA internal set, do it"); @@ -25735,11 +25354,14 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, } /* tmp buffer with a max size */ - *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + - sizeof(END_RSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE; + } + else { + /* tmp buffer with a max size */ + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1; } - 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_PEM); if (tmp == NULL) { @@ -25751,7 +25373,7 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, } /* DER to PEM */ - *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, PRIVATEKEY_TYPE); + *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type); if (*plen <= 0) { WOLFSSL_MSG("wc_DerToPemEx failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -27129,6 +26751,9 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, { byte *derBuf, *tmp, *cipherInfo = NULL; int der_max_len = 0, derSz = 0; + const int type = ECC_PRIVATEKEY_TYPE; + const char* header = NULL; + const char* footer = NULL; WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey"); @@ -27137,6 +26762,9 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, return WOLFSSL_FAILURE; } + if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) + return WOLFSSL_FAILURE; + if (ecc->inSet == 0) { WOLFSSL_MSG("No ECC internal set, do it"); @@ -27177,11 +26805,13 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, } /* tmp buffer with a max size */ - *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + - sizeof(END_EC_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE; + } + else { /* tmp buffer with a max size */ + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1; } - 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_PEM); if (tmp == NULL) { @@ -27193,7 +26823,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, } /* DER to PEM */ - *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, ECC_PRIVATEKEY_TYPE); + *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type); if (*plen <= 0) { WOLFSSL_MSG("wc_DerToPemEx failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -27304,6 +26934,9 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, { byte *derBuf, *tmp, *cipherInfo = NULL; int der_max_len = 0, derSz = 0; + const int type = DSA_PRIVATEKEY_TYPE; + const char* header = NULL; + const char* footer = NULL; WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey"); @@ -27312,6 +26945,9 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, return WOLFSSL_FAILURE; } + if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) + return WOLFSSL_FAILURE; + if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); @@ -27352,11 +26988,13 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, } /* tmp buffer with a max size */ - *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + - sizeof(END_DSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE; + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE; + } + else { /* tmp buffer with a max size */ + *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + + (int)XSTRLEN(footer) + 1; } - 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_PEM); if (tmp == NULL) { @@ -27368,7 +27006,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, } /* DER to PEM */ - *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, DSA_PRIVATEKEY_TYPE); + *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type); if (*plen <= 0) { WOLFSSL_MSG("wc_DerToPemEx failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); @@ -27547,31 +27185,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, #endif XMEMSET(info, 0, sizeof(EncryptedInfo)); - - if (pass != NULL) { - info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); - if (info->ctx == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - WOLFSSL_MSG("Error creating ctx for password"); - XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); - return NULL; - } - - if (cb == NULL) { - localCb = OurPasswordCb; - } - wolfSSL_CTX_set_default_passwd_cb(info->ctx, localCb); - wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, pass); - } - + info->passwd_cb = localCb; + info->passwd_userdata = pass; ret = PemToDer((const unsigned char*)mem, memSz, PRIVATEKEY_TYPE, &der, - NULL, info, &eccFlag); - - if (info->ctx) { - wolfSSL_CTX_free(info->ctx); - } + NULL, info, &eccFlag); if (ret < 0) { WOLFSSL_MSG("Bad Pem To Der"); @@ -28004,11 +27621,10 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx) int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, unsigned char* buf, int inLen, int* outLen) { - const char header[] = "-----BEGIN CERTIFICATE-----\n"; - const char footer[] = "-----END CERTIFICATE-----\n"; - - int headerLen = sizeof(header) - 1; - int footerLen = sizeof(footer) - 1; + const char* header = NULL; + const char* footer = NULL; + int headerLen; + int footerLen; int i; int err; word32 szNeeded = 0; @@ -28017,6 +27633,13 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain)) return BAD_FUNC_ARG; + err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer); + if (err != 0) + return err; + + headerLen = (int)XSTRLEN(header); + footerLen = (int)XSTRLEN(footer); + /* Null output buffer return size needed in outLen */ if(!buf) { if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length, @@ -28640,6 +28263,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) unsigned char* pem = NULL; int pemSz; long i = 0, l; + const char* footer = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509"); @@ -28684,12 +28308,15 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return NULL; i = 0; + if (wc_PemGetHeaderFooter(CERT_TYPE, NULL, &footer) != 0) + return NULL; + /* TODO: Inefficient - * reading in one byte at a time until see END_CERT + * reading in one byte at a time until see "END CERTIFICATE" */ while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) { i++; - if (i > 26 && XMEMCMP((char *)&pem[i-26], END_CERT, 25) == 0) { + if (i > 26 && XMEMCMP((char *)&pem[i-26], footer, 25) == 0) { if (pem[i-1] == '\r') { /* found \r , Windows line ending is \r\n so try to read one * more byte for \n, ignoring return value */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index afd01ee34..86c1b8d98 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -57,6 +57,7 @@ ASN Options: #include #include #include +#include #include #include @@ -7363,7 +7364,268 @@ const char* const END_PUB_KEY = "-----END PUBLIC KEY-----"; const char* const END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----"; #endif -#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) + +int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) +{ + int ret = BAD_FUNC_ARG; + + switch (type) { + case CA_TYPE: /* same as below */ + case TRUSTED_PEER_TYPE: + case CERT_TYPE: + if (header) *header = BEGIN_CERT; + if (footer) *footer = END_CERT; + ret = 0; + break; + + case CRL_TYPE: + if (header) *header = BEGIN_X509_CRL; + if (footer) *footer = END_X509_CRL; + ret = 0; + break; + #ifndef NO_DH + case DH_PARAM_TYPE: + if (header) *header = BEGIN_DH_PARAM; + if (footer) *footer = END_DH_PARAM; + ret = 0; + break; + #endif + #ifndef NO_DSA + case DSA_PARAM_TYPE: + if (header) *header = BEGIN_DSA_PARAM; + if (footer) *footer = END_DSA_PARAM; + ret = 0; + break; + #endif + #ifdef WOLFSSL_CERT_REQ + case CERTREQ_TYPE: + if (header) *header = BEGIN_CERT_REQ; + if (footer) *footer = END_CERT_REQ; + ret = 0; + break; + #endif + #ifndef NO_DSA + case DSA_TYPE: + case DSA_PRIVATEKEY_TYPE: + if (header) *header = BEGIN_DSA_PRIV; + if (footer) *footer = END_DSA_PRIV; + ret = 0; + break; + #endif + #ifdef HAVE_ECC + case ECC_TYPE: + case ECC_PRIVATEKEY_TYPE: + if (header) *header = BEGIN_EC_PRIV; + if (footer) *footer = END_EC_PRIV; + ret = 0; + break; + #endif + case RSA_TYPE: + case PRIVATEKEY_TYPE: + if (header) *header = BEGIN_RSA_PRIV; + if (footer) *footer = END_RSA_PRIV; + ret = 0; + break; + #ifdef HAVE_ED25519 + case ED25519_TYPE: + case EDDSA_PRIVATEKEY_TYPE: + if (header) *header = BEGIN_EDDSA_PRIV; + if (footer) *footer = END_EDDSA_PRIV; + ret = 0; + break; + #endif + case PUBLICKEY_TYPE: + if (header) *header = BEGIN_PUB_KEY; + if (footer) *footer = END_PUB_KEY; + ret = 0; + break; + default: + break; + } + return ret; +} + +#ifdef WOLFSSL_ENCRYPTED_KEYS + +static const char* const kProcTypeHeader = "Proc-Type"; +static const char* const kDecInfoHeader = "DEK-Info"; + +static const char* const kEncTypeDes = "DES-CBC"; +static const char* const kEncTypeDes3 = "DES-EDE3-CBC"; +static const char* const kEncTypeAesCbc128 = "AES-128-CBC"; +static const char* const kEncTypeAesCbc192 = "AES-192-CBC"; +static const char* const kEncTypeAesCbc256 = "AES-256-CBC"; + +int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo) +{ + int ret = 0; + + if (info == NULL || cipherInfo == NULL) + return BAD_FUNC_ARG; + + /* determine cipher information */ +#ifndef NO_DES3 + if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) { + info->cipherType = WC_CIPHER_DES; + info->keySz = DES_KEY_SIZE; + info->ivSz = DES_IV_SIZE; + } + else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) { + info->cipherType = WC_CIPHER_DES3; + info->keySz = DES3_KEY_SIZE; + info->ivSz = DES_IV_SIZE; + } + else +#endif /* NO_DES3 */ +#ifndef NO_AES +#ifdef HAVE_AES_CBC +#ifdef WOLFSSL_AES_128 + if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) { + info->cipherType = WC_CIPHER_AES_CBC; + info->keySz = AES_128_KEY_SIZE; + info->ivSz = AES_IV_SIZE; + } + else +#endif +#ifdef WOLFSSL_AES_192 + if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) { + info->cipherType = WC_CIPHER_AES_CBC; + info->keySz = AES_192_KEY_SIZE; + info->ivSz = AES_IV_SIZE; + } + else +#endif +#ifdef WOLFSSL_AES_256 + if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) { + info->cipherType = WC_CIPHER_AES_CBC; + info->keySz = AES_256_KEY_SIZE; + info->ivSz = AES_IV_SIZE; + } + else +#endif +#endif /* HAVE_AES_CBC */ +#endif /* NO_AES */ + { + ret = NOT_COMPILED_IN; + } + return ret; +} + +static int wc_EncryptedInfo_Parse(EncryptedInfo* info, + char** pBuffer, size_t bufSz) +{ + int err = 0; + char* bufferStart; + char* bufferEnd; + char* line; + word32 lineSz; + char* finish; + word32 finishSz; + char* start = NULL; + word32 startSz; + char* newline = NULL; + + if (info == NULL || pBuffer == NULL || bufSz == 0) + return BAD_FUNC_ARG; + + bufferStart = *pBuffer; + bufferEnd = bufferStart + bufSz; + + /* find encrypted info marker */ + line = XSTRNSTR(bufferStart, kProcTypeHeader, + min((word32)bufSz, PEM_LINE_LEN)); + if (line != NULL) { + if (line >= bufferEnd) { + return BUFFER_E; + } + + lineSz = (word32)(bufferEnd - line); + + /* find DEC-Info marker */ + start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN)); + + if (start == NULL) + return BUFFER_E; + if (start >= bufferEnd) + return BUFFER_E; + + /* skip dec-info and ": " */ + start += XSTRLEN(kDecInfoHeader) + 2; + if (start[0] == ':') + start++; + if (start[0] == ' ') + start++; + + startSz = (word32)(bufferEnd - start); + finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN)); + + if ((start != NULL) && (finish != NULL) && (start < finish)) { + if (finish >= bufferEnd) { + return BUFFER_E; + } + + finishSz = (word32)(bufferEnd - finish); + newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN)); + + if (NAME_SZ < (finish - start)) /* buffer size of info->name */ + return BUFFER_E; + if (XMEMCPY(info->name, start, finish - start) == NULL) + return BUFFER_E; + info->name[finish - start] = '\0'; /* null term */ + if (finishSz < sizeof(info->iv) + 1) + return BUFFER_E; + if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL) + return BUFFER_E; + + if (newline == NULL) + newline = XSTRNSTR(finish, "\n", min(finishSz, + PEM_LINE_LEN)); + if ((newline != NULL) && (newline > finish)) { + info->ivSz = (word32)(newline - (finish + 1)); + info->set = 1; + } + else + return BUFFER_E; + } + else + return BUFFER_E; + + /* eat blank line */ + while (newline < bufferEnd && + (*newline == '\r' || *newline == '\n')) { + newline++; + } + + /* return new headerEnd */ + if (pBuffer) + *pBuffer = newline; + + /* populate info */ + err = wc_EncryptedInfoGet(info, info->name); + } + + return err; +} + +static int wc_EncryptedInfo_Append(char* dest, char* cipherInfo) +{ + if (cipherInfo != NULL) { + size_t cipherInfoStrLen = XSTRLEN(cipherInfo); + if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3)) + cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3); + + XSTRNCAT(dest, kProcTypeHeader, 9); + XSTRNCAT(dest, ": 4,ENCRYPTED\n", 14); + XSTRNCAT(dest, kDecInfoHeader, 8); + XSTRNCAT(dest, ": ", 2); + XSTRNCAT(dest, cipherInfo, cipherInfoStrLen); + XSTRNCAT(dest, "\n\n", 3); + } + return 0; +} +#endif /* WOLFSSL_ENCRYPTED_KEYS */ + +#ifdef WOLFSSL_DER_TO_PEM /* Used for compatibility API */ int wc_DerToPem(const byte* der, word32 derSz, @@ -7377,6 +7639,8 @@ int wc_DerToPem(const byte* der, word32 derSz, int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, byte *cipher_info, int type) { + const char* headerStr = NULL; + const char* footerStr = NULL; #ifdef WOLFSSL_SMALL_STACK char* header = NULL; char* footer = NULL; @@ -7393,6 +7657,10 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, if (der == output) /* no in place conversion */ return BAD_FUNC_ARG; + err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr); + if (err != 0) + return err; + #ifdef WOLFSSL_SMALL_STACK header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (header == NULL) @@ -7410,71 +7678,23 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, footer[--footerLen] = '\0'; footer[--footerLen] = '\0'; /* build header and footer based on type */ - if (type == CERT_TYPE) { - XSTRNCPY(header, BEGIN_CERT, headerLen); - XSTRNCPY(footer, END_CERT, footerLen); - } - else if (type == PRIVATEKEY_TYPE) { - XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen); - XSTRNCPY(footer, END_RSA_PRIV, footerLen); - } - else if (type == PUBLICKEY_TYPE) { - XSTRNCPY(header, BEGIN_PUB_KEY, headerLen); - XSTRNCPY(footer, END_PUB_KEY, footerLen); - } -#ifndef NO_DSA - else if (type == DSA_PRIVATEKEY_TYPE) { - XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen); - XSTRNCPY(footer, END_DSA_PRIV, footerLen); - } -#endif -#ifdef HAVE_ECC - else if (type == ECC_PRIVATEKEY_TYPE) { - XSTRNCPY(header, BEGIN_EC_PRIV, headerLen); - XSTRNCPY(footer, END_EC_PRIV, footerLen); - } -#endif -#ifdef HAVE_ED25519 - else if (type == EDDSA_PRIVATEKEY_TYPE) { - XSTRNCPY(header, BEGIN_EDDSA_PRIV, headerLen); - XSTRNCPY(footer, END_EDDSA_PRIV, footerLen); - } -#endif -#ifdef WOLFSSL_CERT_REQ - else if (type == CERTREQ_TYPE) { - XSTRNCPY(header, BEGIN_CERT_REQ, headerLen); - XSTRNCPY(footer, END_CERT_REQ, footerLen); - } -#endif -#ifdef HAVE_CRL - else if (type == CRL_TYPE) { - XSTRNCPY(header, BEGIN_X509_CRL, headerLen); - XSTRNCPY(footer, END_X509_CRL, footerLen); - } -#endif - else { -#ifdef WOLFSSL_SMALL_STACK - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BAD_FUNC_ARG; - } + XSTRNCPY(header, headerStr, headerLen); + XSTRNCPY(footer, footerStr, footerLen); /* add new line to end */ XSTRNCAT(header, "\n", 2); XSTRNCAT(footer, "\n", 2); - /* extra header information for encrypted key */ - if (cipher_info != NULL) { - size_t cipherInfoStrLen = XSTRLEN((char*)cipher_info); - if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (23+10+3)) - cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (23+10+3); - - XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23); - XSTRNCAT(header, "DEK-Info: ", 10); - XSTRNCAT(header, (char*)cipher_info, cipherInfoStrLen); - XSTRNCAT(header, "\n\n", 3); +#ifdef WOLFSSL_ENCRYPTED_KEYS + err = wc_EncryptedInfo_Append(header, (char*)cipher_info); + if (err != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return err; } +#endif headerLen = (int)XSTRLEN(header); footerLen = (int)XSTRLEN(footer); @@ -7544,7 +7764,7 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, return outLen + headerLen + footerLen; } -#endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN || OPENSSL_EXTRA */ +#endif /* WOLFSSL_DER_TO_PEM */ int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap) { @@ -7600,7 +7820,6 @@ void FreeDer(DerBuffer** pDer) } } - /* Remove PEM header/footer, convert to ASN1, store any encrypted data info->consumed tracks of PEM bytes consumed in case multiple parts */ int PemToDer(const unsigned char* buff, long longSz, int type, @@ -7620,46 +7839,12 @@ int PemToDer(const unsigned char* buff, long longSz, int type, WOLFSSL_ENTER("PemToDer"); - switch (type) { - case CA_TYPE: /* same as below */ - case TRUSTED_PEER_TYPE: - case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT; - break; - case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL; - break; -#ifndef NO_DH - case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM; - break; -#endif -#ifndef NO_DSA - case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM; - break; -#endif -#ifdef WOLFSSL_CERT_REQ - case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ; - break; -#endif -#ifndef NO_DSA - case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; - break; -#endif -#ifdef HAVE_ECC - case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV; - break; -#endif - case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; - break; -#ifdef HAVE_ED25519 - case ED25519_TYPE: header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV; - break; -#endif - case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY; footer=END_PUB_KEY; - break; - default: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; - break; - } + /* get PEM header and footer based on type */ + ret = wc_PemGetHeaderFooter(type, &header, &footer); + if (ret != 0) + return ret; - /* find header */ + /* map header if not found for type */ for (;;) { headerEnd = XSTRNSTR((char*)buff, header, sz); @@ -7714,96 +7899,22 @@ int PemToDer(const unsigned char* buff, long longSz, int type, if (type == PRIVATEKEY_TYPE) { if (eccKey) { #ifdef HAVE_ECC - *eccKey = header == BEGIN_EC_PRIV; + *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0; #else *eccKey = 0; #endif } } -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(HAVE_WEBSERVER) - { - /* remove encrypted header if there */ - const char* const encHeader = "Proc-Type"; - word32 headerEndSz = (word32)(bufferEnd - headerEnd); - char* line = XSTRNSTR(headerEnd, encHeader, min(headerEndSz, - PEM_LINE_LEN)); - if (line != NULL) { - word32 lineSz; - char* finish; - word32 finishSz; - char* start = NULL; - word32 startSz; - char* newline; - - if (line >= bufferEnd) { - return BUFFER_E; - } - - lineSz = (word32)(bufferEnd - line); - #ifndef NO_DES3 - start = XSTRNSTR(line, "DES", min(lineSz, PEM_LINE_LEN)); - #endif - - #ifndef NO_AES - if (start == NULL) { - start = XSTRNSTR(line, "AES", min(lineSz, PEM_LINE_LEN)); - } - #endif - - (void)lineSz; - if (start == NULL) return BUFFER_E; - if (info == NULL) return BUFFER_E; - - if (start >= bufferEnd) { - return BUFFER_E; - } - - startSz = (word32)(bufferEnd - start); - finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN)); - - if ((start != NULL) && (finish != NULL) && (start < finish)) { - if (finish >= bufferEnd) { - return BUFFER_E; - } - - finishSz = (word32)(bufferEnd - finish); - newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN)); - - if (NAME_SZ < (finish - start)) /* buffer size of info->name*/ - return BUFFER_E; - if (XMEMCPY(info->name, start, finish - start) == NULL) - return WOLFSSL_FATAL_ERROR; - info->name[finish - start] = 0; - if (finishSz < sizeof(info->iv) + 1) - return BUFFER_E; - if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL) - return WOLFSSL_FATAL_ERROR; - - if (newline == NULL) - newline = XSTRNSTR(finish, "\n", min(finishSz, - PEM_LINE_LEN)); - if ((newline != NULL) && (newline > finish)) { - info->ivSz = (word32)(newline - (finish + 1)); - info->set = 1; - } - else - return BUFFER_E; - } - else - return BUFFER_E; - - /* eat blank line */ - while (newline < bufferEnd && - (*newline == '\r' || *newline == '\n')) - newline++; - headerEnd = newline; - +#ifdef WOLFSSL_ENCRYPTED_KEYS + if (info) { + ret = wc_EncryptedInfo_Parse(info, &headerEnd, bufferEnd - headerEnd); + if (ret < 0) + return ret; + if (info->set) encrypted_key = 1; - } } -#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */ +#endif /* WOLFSSL_ENCRYPTED_KEYS */ /* find footer */ footerEnd = XSTRNSTR((char*)buff, footer, sz); @@ -7855,25 +7966,30 @@ int PemToDer(const unsigned char* buff, long longSz, int type, return 0; } -#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED) +#ifdef WOLFSSL_ENCRYPTED_KEYS if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) { - int passwordSz; + int passwordSz = NAME_SZ; #ifdef WOLFSSL_SMALL_STACK char* password = NULL; #else char password[NAME_SZ]; #endif - if (!info || !info->ctx || !info->ctx->passwd_cb) - return BUFFER_E; /* no callback error */ + if (!info || !info->passwd_cb) { + WOLFSSL_MSG("No password callback set"); + return NO_PASSWORD; + } #ifdef WOLFSSL_SMALL_STACK - password = (char*)XMALLOC(NAME_SZ, heap, DYNAMIC_TYPE_STRING); + password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING); if (password == NULL) return MEMORY_E; #endif - passwordSz = info->ctx->passwd_cb(password, NAME_SZ, 0, - info->ctx->userdata); + + /* get password */ + passwordSz = info->passwd_cb(password, passwordSz, PEM_PASS_READ, + info->passwd_userdata); + /* convert and adjust length */ if (header == BEGIN_ENC_PRIV_KEY) { ret = ToTraditionalEnc(der->buffer, der->length, @@ -7889,19 +8005,16 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } /* decrypt the key */ else { - ret = wolfssl_decrypt_buffer_key(der, (byte*)password, - passwordSz, info); + ret = wc_BufferKeyDecrypt(info, der->buffer, der->length, + (byte*)password, passwordSz); #ifdef WOLFSSL_SMALL_STACK XFREE(password, heap, DYNAMIC_TYPE_STRING); #endif - if (ret != WOLFSSL_SUCCESS) { - return ret; - } } } -#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */ +#endif /* WOLFSSL_ENCRYPTED_KEYS */ - return 0; + return ret; } int wc_PemToDer(const unsigned char* buff, long longSz, int type, @@ -7918,16 +8031,13 @@ int wc_PemToDer(const unsigned char* buff, long longSz, int type, int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) { #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; byte staticBuffer[1]; /* force XMALLOC */ #else - EncryptedInfo info[1]; byte staticBuffer[FILE_BUFFER_SIZE]; #endif byte* fileBuf = staticBuffer; int dynamic = 0; int ret = 0; - int ecc = 0; long sz = 0; XFILE file = XFOPEN(fileName, "rb"); DerBuffer* converted = NULL; @@ -7950,7 +8060,7 @@ int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) WOLFSSL_MSG("File was larger then static buffer"); return MEMORY_E; #endif - fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE); + fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE); if (fileBuf == NULL) ret = MEMORY_E; else @@ -7962,20 +8072,7 @@ int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) ret = BUFFER_E; } else { - #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_ENCRYPTEDINFO); - if (info == NULL) - ret = MEMORY_E; - else - #endif - { - ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, - 0, info, &ecc); - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif - } + ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, NULL,NULL); } if (ret == 0) { @@ -7992,7 +8089,7 @@ int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) XFCLOSE(file); if (dynamic) - XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE); + XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE); } return ret; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index bdbc2c23e..f9757642d 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -154,6 +154,56 @@ int wc_HashGetDigestSize(enum wc_HashType hash_type) return dig_size; } + +/* Get Hash block size */ +int wc_HashGetBlockSize(enum wc_HashType hash_type) +{ + int block_size = HASH_TYPE_E; /* Default to hash type error */ + switch (hash_type) + { + case WC_HASH_TYPE_MD5: +#ifndef NO_MD5 + block_size = WC_MD5_BLOCK_SIZE; +#endif + break; + case WC_HASH_TYPE_SHA: +#ifndef NO_SHA + block_size = WC_SHA_BLOCK_SIZE; +#endif + break; + case WC_HASH_TYPE_SHA224: +#ifdef WOLFSSL_SHA224 + block_size = WC_SHA224_BLOCK_SIZE; +#endif + break; + case WC_HASH_TYPE_SHA256: +#ifndef NO_SHA256 + block_size = WC_SHA256_BLOCK_SIZE; +#endif + break; + case WC_HASH_TYPE_SHA384: +#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384) + block_size = WC_SHA384_BLOCK_SIZE; +#endif + break; + case WC_HASH_TYPE_SHA512: +#ifdef WOLFSSL_SHA512 + block_size = WC_SHA512_BLOCK_SIZE; +#endif + break; + + /* Not Supported */ + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD4: + case WC_HASH_TYPE_NONE: + default: + block_size = BAD_FUNC_ARG; + break; + } + return block_size; +} + /* Generic Hashing Wrapper */ int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index e5ded0e71..57e14f50d 100755 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -30,11 +30,9 @@ #include #include +#include #include #include -#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) - #include -#endif #ifdef NO_INLINE #include @@ -44,120 +42,112 @@ #endif -#ifndef NO_SHA -/* PBKDF1 needs at least SHA available */ -int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, - int sLen, int iterations, int kLen, int hashType) +/* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */ +int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen, + const byte* passwd, int passwdLen, const byte* salt, int saltLen, + int iterations, int hashType, void* heap) { - wc_Sha sha; -#ifndef NO_MD5 - wc_Md5 md5; -#endif - int hLen = (int)WC_SHA_DIGEST_SIZE; - int i, ret = 0; - byte buffer[WC_SHA_DIGEST_SIZE]; /* max size */ - - if (hashType != WC_MD5 && hashType != WC_SHA) - return BAD_FUNC_ARG; - -#ifndef NO_MD5 - if (hashType == WC_MD5) - hLen = (int)WC_MD5_DIGEST_SIZE; + int err; + int keyLeft, ivLeft, i; + int digestLeft, store; + int keyOutput = 0; + int diestLen; + byte digest[WC_MAX_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_HashAlg* hash = NULL; +#else + wc_HashAlg hash[1]; #endif - if ((kLen > hLen) || (kLen < 0)) - return BAD_FUNC_ARG; + (void)heap; - if (iterations < 1) - return BAD_FUNC_ARG; + err = wc_HashGetDigestSize(hashType); + if (err < 0) + return err; + diestLen = err; - switch (hashType) { -#ifndef NO_MD5 - case WC_MD5: - ret = wc_InitMd5(&md5); - if (ret != 0) { - return ret; - } - ret = wc_Md5Update(&md5, passwd, pLen); - if (ret != 0) { - return ret; - } - ret = wc_Md5Update(&md5, salt, sLen); - if (ret != 0) { - return ret; - } - ret = wc_Md5Final(&md5, buffer); - if (ret != 0) { - return ret; - } - break; -#endif /* NO_MD5 */ - case WC_SHA: - default: - ret = wc_InitSha(&sha); - if (ret != 0) - return ret; - wc_ShaUpdate(&sha, passwd, pLen); - wc_ShaUpdate(&sha, salt, sLen); - wc_ShaFinal(&sha, buffer); - break; + if (key == NULL || keyLen < 0 || passwd == NULL || passwdLen == 0 || + iterations < 1) { + return BAD_FUNC_ARG; } - for (i = 1; i < iterations; i++) { - if (hashType == WC_SHA) { - wc_ShaUpdate(&sha, buffer, hLen); - wc_ShaFinal(&sha, buffer); - } -#ifndef NO_MD5 - else { - ret = wc_Md5Update(&md5, buffer, hLen); - if (ret != 0) { - return ret; - } - ret = wc_Md5Final(&md5, buffer); - if (ret != 0) { - return ret; - } - } + /* initialize hash */ +#ifdef WOLFSSL_SMALL_STACK + hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap, + DYNAMIC_TYPE_HASHCTX); + if (hash == NULL) + return MEMORY_E; #endif + + err = wc_HashInit(hash, hashType); + if (err != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX); + #endif + return err; } - XMEMCPY(output, buffer, kLen); + + keyLeft = keyLen; + ivLeft = ivLen; + while (keyOutput < (keyLen + ivLen)) { + digestLeft = diestLen; + /* D_(i - 1) */ + if (keyOutput) /* first time D_0 is empty */ + err = wc_HashUpdate(hash, hashType, digest, diestLen); + + /* data */ + if (err == 0) + err = wc_HashUpdate(hash, hashType, passwd, passwdLen); + /* salt */ + if (salt && err == 0) + err = wc_HashUpdate(hash, hashType, salt, saltLen); + + if (err == 0) + err = wc_HashFinal(hash, hashType, digest); + + /* count */ + if (err == 0) { + for (i = 1; i < iterations; i++) { + err = wc_HashUpdate(hash, hashType, digest, diestLen); + err = wc_HashFinal(hash, hashType, digest); + } + } + + if (keyLeft) { + store = min(keyLeft, diestLen); + XMEMCPY(&key[keyLen - keyLeft], digest, store); + + keyOutput += store; + keyLeft -= store; + digestLeft -= store; + } + + if (ivLeft && digestLeft) { + store = min(ivLeft, digestLeft); + if (iv != NULL) + XMEMCPY(&iv[ivLen - ivLeft], + &digest[diestLen - digestLeft], store); + keyOutput += store; + ivLeft -= store; + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX); +#endif + + if (keyOutput != (keyLen + ivLen)) + return BUFFER_E; return 0; } -#endif /* NO_SHA */ - -int GetDigestSize(int hashType) +/* PKCS#5 v1.5 */ +int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, + int sLen, int iterations, int kLen, int hashType) { - int hLen; - - switch (hashType) { -#ifndef NO_MD5 - case WC_MD5: - hLen = WC_MD5_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA - case WC_SHA: - hLen = WC_SHA_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA256 - case WC_SHA256: - hLen = WC_SHA256_DIGEST_SIZE; - break; -#endif -#ifdef WOLFSSL_SHA512 - case WC_SHA512: - hLen = WC_SHA512_DIGEST_SIZE; - break; -#endif - default: - return BAD_FUNC_ARG; - } - - return hLen; + return wc_PBKDF1_ex(output, kLen, NULL, 0, + passwd, pLen, salt, sLen, iterations, hashType, NULL); } @@ -167,14 +157,15 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, word32 i = 1; int hLen; int j, ret; - Hmac hmac; #ifdef WOLFSSL_SMALL_STACK byte* buffer; + Hmac* hmac; #else byte buffer[WC_MAX_DIGEST_SIZE]; + Hmac hmac[1]; #endif - hLen = GetDigestSize(hashType); + hLen = wc_HashGetDigestSize(hashType); if (hLen < 0) return BAD_FUNC_ARG; @@ -182,16 +173,19 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buffer == NULL) return MEMORY_E; + hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_HMAC); + if (buffer == NULL) + return MEMORY_E; #endif - ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); + ret = wc_HmacInit(hmac, NULL, INVALID_DEVID); if (ret == 0) { - ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen); + ret = wc_HmacSetKey(hmac, hashType, passwd, pLen); while (ret == 0 && kLen) { int currentLen; - ret = wc_HmacUpdate(&hmac, salt, sLen); + ret = wc_HmacUpdate(hmac, salt, sLen); if (ret != 0) break; @@ -199,7 +193,7 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, for (j = 0; j < 4; j++) { byte b = (byte)(i >> ((3-j) * 8)); - ret = wc_HmacUpdate(&hmac, &b, 1); + ret = wc_HmacUpdate(hmac, &b, 1); if (ret != 0) break; } @@ -208,7 +202,7 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, if (ret != 0) break; - ret = wc_HmacFinal(&hmac, buffer); + ret = wc_HmacFinal(hmac, buffer); if (ret != 0) break; @@ -216,10 +210,10 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, XMEMCPY(output, buffer, currentLen); for (j = 1; j < iterations; j++) { - ret = wc_HmacUpdate(&hmac, buffer, hLen); + ret = wc_HmacUpdate(hmac, buffer, hLen); if (ret != 0) break; - ret = wc_HmacFinal(&hmac, buffer); + ret = wc_HmacFinal(hmac, buffer); if (ret != 0) break; xorbuf(output, buffer, currentLen); @@ -233,194 +227,64 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, kLen -= currentLen; i++; } - wc_HmacFree(&hmac); + wc_HmacFree(hmac); } #ifdef WOLFSSL_SMALL_STACK XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hmac, NULL, DYNAMIC_TYPE_HMAC); #endif return ret; } -#ifdef WOLFSSL_SHA512 - #define PBKDF_DIGEST_SIZE WC_SHA512_BLOCK_SIZE -#elif !defined(NO_SHA256) - #define PBKDF_DIGEST_SIZE WC_SHA256_BLOCK_SIZE -#else - #define PBKDF_DIGEST_SIZE WC_SHA_DIGEST_SIZE -#endif - -/* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */ -int GetPKCS12HashSizes(int hashType, word32* v, word32* u) -{ - if (!v || !u) - return BAD_FUNC_ARG; - - switch (hashType) { -#ifndef NO_MD5 - case WC_MD5: - *v = WC_MD5_BLOCK_SIZE; - *u = WC_MD5_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA - case WC_SHA: - *v = WC_SHA_BLOCK_SIZE; - *u = WC_SHA_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA256 - case WC_SHA256: - *v = WC_SHA256_BLOCK_SIZE; - *u = WC_SHA256_DIGEST_SIZE; - break; -#endif -#ifdef WOLFSSL_SHA512 - case WC_SHA512: - *v = WC_SHA512_BLOCK_SIZE; - *u = WC_SHA512_DIGEST_SIZE; - break; -#endif - default: - return BAD_FUNC_ARG; - } - - return 0; -} - /* helper for PKCS12_PBKDF(), does hash operation */ -int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen, +static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen, byte* Ai, word32 u, int iterations) { int i; int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + wc_HashAlg* hash = NULL; +#else + wc_HashAlg hash[1]; +#endif if (buffer == NULL || Ai == NULL) return BAD_FUNC_ARG; - switch (hashType) { -#ifndef NO_MD5 - case WC_MD5: - { - wc_Md5 md5; - ret = wc_InitMd5(&md5); - if (ret != 0) { - break; - } - ret = wc_Md5Update(&md5, buffer, totalLen); - if (ret != 0) { - break; - } - ret = wc_Md5Final(&md5, Ai); - if (ret != 0) { - break; - } + /* initialize hash */ +#ifdef WOLFSSL_SMALL_STACK + hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL, + DYNAMIC_TYPE_HASHCTX); + if (hash == NULL) + return MEMORY_E; +#endif - for (i = 1; i < iterations; i++) { - ret = wc_Md5Update(&md5, Ai, u); - if (ret != 0) { - break; - } - ret = wc_Md5Final(&md5, Ai); - if (ret != 0) { - break; - } - } - } - break; -#endif /* NO_MD5 */ -#ifndef NO_SHA - case WC_SHA: - { - wc_Sha sha; - ret = wc_InitSha(&sha); - if (ret != 0) - break; - ret = wc_ShaUpdate(&sha, buffer, totalLen); - if (ret != 0) { - break; - } - ret = wc_ShaFinal(&sha, Ai); - if (ret != 0) { - break; - } - - for (i = 1; i < iterations; i++) { - ret = wc_ShaUpdate(&sha, Ai, u); - if (ret != 0) { - break; - } - ret = wc_ShaFinal(&sha, Ai); - if (ret != 0) { - break; - } - } - } - break; -#endif /* NO_SHA */ -#ifndef NO_SHA256 - case WC_SHA256: - { - wc_Sha256 sha256; - ret = wc_InitSha256(&sha256); - if (ret != 0) - break; - - ret = wc_Sha256Update(&sha256, buffer, totalLen); - if (ret != 0) - break; - - ret = wc_Sha256Final(&sha256, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = wc_Sha256Update(&sha256, Ai, u); - if (ret != 0) - break; - - ret = wc_Sha256Final(&sha256, Ai); - if (ret != 0) - break; - } - } - break; -#endif /* NO_SHA256 */ -#ifdef WOLFSSL_SHA512 - case WC_SHA512: - { - wc_Sha512 sha512; - ret = wc_InitSha512(&sha512); - if (ret != 0) - break; - - ret = wc_Sha512Update(&sha512, buffer, totalLen); - if (ret != 0) - break; - - ret = wc_Sha512Final(&sha512, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = wc_Sha512Update(&sha512, Ai, u); - if (ret != 0) - break; - - ret = wc_Sha512Final(&sha512, Ai); - if (ret != 0) - break; - } - } - break; -#endif /* WOLFSSL_SHA512 */ - - default: - ret = BAD_FUNC_ARG; - break; + ret = wc_HashInit(hash, hashType); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX); + #endif + return ret; } + ret = wc_HashUpdate(hash, hashType, buffer, totalLen); + + if (ret == 0) + ret = wc_HashFinal(hash, hashType, Ai); + + for (i = 1; i < iterations; i++) { + if (ret == 0) + ret = wc_HashUpdate(hash, hashType, Ai, u); + if (ret == 0) + ret = wc_HashFinal(hash, hashType, Ai); + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX); +#endif + return ret; } @@ -455,8 +319,8 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, byte* Ai; byte* B; #else - byte Ai[PBKDF_DIGEST_SIZE]; - byte B[PBKDF_DIGEST_SIZE]; + byte Ai[WC_MAX_DIGEST_SIZE]; + byte B[WC_MAX_BLOCK_SIZE]; #endif (void)heap; @@ -464,27 +328,33 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, if (!iterations) iterations = 1; - ret = GetPKCS12HashSizes(hashType, &v, &u); + ret = wc_HashGetDigestSize(hashType); if (ret < 0) - return BAD_FUNC_ARG; + return ret; + u = ret; + + ret = wc_HashGetBlockSize(hashType); + if (ret < 0) + return ret; + v = ret; #ifdef WOLFSSL_SMALL_STACK - Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); if (Ai == NULL) return MEMORY_E; - B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); if (B == NULL) { - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif - XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE); - XMEMSET(B, 0, PBKDF_DIGEST_SIZE); + XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE); + XMEMSET(B, 0, WC_MAX_BLOCK_SIZE); dLen = v; - sLen = v * ((saltLen + v - 1) / v); + sLen = v * ((saltLen + v - 1) / v); if (passLen) pLen = v * ((passLen + v - 1) / v); else @@ -497,8 +367,8 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, buffer = (byte*)XMALLOC(totalLen, heap, DYNAMIC_TYPE_KEY); if (buffer == NULL) { #ifdef WOLFSSL_SMALL_STACK - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } @@ -585,8 +455,8 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen, if (dynamic) XFREE(buffer, heap, DYNAMIC_TYPE_KEY); #ifdef WOLFSSL_SMALL_STACK - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; @@ -829,7 +699,7 @@ end: } #endif -#undef PBKDF_DIGEST_SIZE +#undef WC_MAX_DIGEST_SIZE #endif /* NO_PWDBASED */ diff --git a/wolfcrypt/src/wc_encrypt.c b/wolfcrypt/src/wc_encrypt.c index 1928a6868..e57a27903 100644 --- a/wolfcrypt/src/wc_encrypt.c +++ b/wolfcrypt/src/wc_encrypt.c @@ -27,9 +27,19 @@ #include #include #include +#include #include #include +#include +#include +#include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif #if !defined(NO_AES) && defined(HAVE_AES_CBC) #ifdef HAVE_AES_DECRYPT @@ -224,3 +234,116 @@ int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, } #endif /* !NO_DES3 */ + + +#ifdef WOLFSSL_ENCRYPTED_KEYS + +int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz) +{ + int ret; +#ifdef WOLFSSL_SMALL_STACK + byte* key = NULL; +#else + byte key[AES_MAX_KEY_SIZE]; +#endif + + (void)derSz; + + if (der == NULL || password == NULL || info == NULL || info->keySz == 0) { + return BAD_FUNC_ARG; + } + + /* use file's salt for key derivation, hex decode first */ + if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) { + return BUFFER_E; + } + +#ifdef WOLFSSL_SMALL_STACK + key = (byte*)XMALLOC(AES_MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); + if (key == NULL) { + return MEMORY_E; + } +#endif + + if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, info->ivSz, 1, + info->keySz, info->hashType)) != 0) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); +#endif + return ret; + } + + ret = NOT_COMPILED_IN; /* set error in case no cipher is enabled/matched */ +#ifndef NO_DES3 + if (info->cipherType == WC_CIPHER_DES) + ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv); + if (info->cipherType == WC_CIPHER_DES3) + ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv); +#endif /* NO_DES3 */ +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) + if (info->cipherType == WC_CIPHER_AES_CBC) + ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz, + info->iv); +#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */ + +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); +#endif + + return ret; +} + +int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz) +{ + int ret; +#ifdef WOLFSSL_SMALL_STACK + byte* key = NULL; +#else + byte key[AES_MAX_KEY_SIZE]; +#endif + + (void)derSz; + + if (der == NULL || password == NULL || info == NULL || info->keySz == 0 || + info->ivSz == 0) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_SMALL_STACK + key = (byte*)XMALLOC(AES_MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); + if (key == NULL) { + return MEMORY_E; + } +#endif /* WOLFSSL_SMALL_STACK */ + + if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, info->ivSz, 1, + info->keySz, info->hashType)) != 0) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); +#endif + return ret; + } + + ret = NOT_COMPILED_IN; /* set error in case no cipher is enabled/matched */ +#ifndef NO_DES3 + if (info->cipherType == WC_CIPHER_DES) + ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv); + if (info->cipherType == WC_CIPHER_DES3) + ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv); +#endif /* NO_DES3 */ +#ifndef NO_AES + if (info->cipherType == WC_CIPHER_AES_CBC) + ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz, + info->iv); +#endif /* NO_AES */ + +#ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); +#endif + + return ret; +} + +#endif /* WOLFSSL_ENCRYPTED_KEYS */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9c17b50e8..467289940 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1069,7 +1069,6 @@ enum Misc { COMPRESS_UPPER = 55, /* compression calc numerator */ COMPRESS_LOWER = 64, /* compression calc denominator */ - PEM_LINE_LEN = 80, /* PEM line max + fudge */ LENGTH_SZ = 2, /* length field for HMAC, data only */ VERSION_SZ = 2, /* length of proctocol version */ SEQ_SZ = 8, /* 64 bit sequence number */ @@ -1152,15 +1151,6 @@ enum Misc { MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ - RC4_KEY_SIZE = 16, /* always 128bit */ - DES_KEY_SIZE = 8, /* des */ - DES3_KEY_SIZE = 24, /* 3 des ede */ - DES_IV_SIZE = DES_BLOCK_SIZE, - AES_256_KEY_SIZE = 32, /* for 256 bit */ - AES_192_KEY_SIZE = 24, /* for 192 bit */ - AES_IV_SIZE = 16, /* always block size */ - AES_128_KEY_SIZE = 16, /* for 128 bit */ - AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */ AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */ @@ -1238,8 +1228,6 @@ enum Misc { MAX_X509_SIZE = 2048, /* max static x509 buffer size */ CERT_MIN_SIZE = 256, /* min PEM cert size with header/footer */ - FILE_BUFFER_SIZE = 1024, /* default static file buffer size for input, - will use dynamic buffer if not big enough */ MAX_NTRU_PUB_KEY_SZ = 1027, /* NTRU max for now */ MAX_NTRU_ENCRYPT_SZ = 1027, /* NTRU max for now */ @@ -2428,10 +2416,9 @@ struct WOLFSSL_CTX { #ifdef HAVE_ANON byte haveAnon; /* User wants to allow Anon suites */ #endif /* HAVE_ANON */ -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(HAVE_WEBSERVER) +#ifdef WOLFSSL_ENCRYPTED_KEYS pem_password_cb* passwd_cb; - void* userdata; + void* passwd_userdata; #endif #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ca880e15b..244d0e086 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef HAVE_WOLF_EVENT #include @@ -592,7 +593,6 @@ WOLFSSL_API #endif /* SESSION_INDEX && SESSION_CERTS */ typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*); -typedef int (pem_password_cb)(char*, int, int, void*); #ifdef OPENSSL_EXTRA typedef void (CallbackInfoState)(const WOLFSSL*, int, int); @@ -958,7 +958,8 @@ WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX*, void* userdata); WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX*, pem_password_cb*); - +WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx); +WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx); WOLFSSL_API void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX*, void (*)(const WOLFSSL* ssl, int type, int val)); @@ -2519,8 +2520,6 @@ WOLFSSL_API size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out, size_t outlen); WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, size_t outSz); -WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx); -WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 0e399cfeb..a0921793b 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -73,7 +73,12 @@ enum { AES_ENCRYPTION = 0, AES_DECRYPTION = 1, KEYWRAP_BLOCK_SIZE = 8, - AES_BLOCK_SIZE = 16 + AES_BLOCK_SIZE = 16, + + AES_128_KEY_SIZE = 16, /* for 128 bit */ + AES_256_KEY_SIZE = 32, /* for 256 bit */ + AES_192_KEY_SIZE = 24, /* for 192 bit */ + AES_IV_SIZE = 16, /* always block size */ }; diff --git a/wolfssl/wolfcrypt/arc4.h b/wolfssl/wolfcrypt/arc4.h index 52cfc7066..632a68c0f 100644 --- a/wolfssl/wolfcrypt/arc4.h +++ b/wolfssl/wolfcrypt/arc4.h @@ -38,7 +38,8 @@ enum { ARC4_ENC_TYPE = 4, /* cipher unique type */ - ARC4_STATE_SIZE = 256 + ARC4_STATE_SIZE = 256, + RC4_KEY_SIZE = 16, /* always 128bit */ }; /* ARC4 encryption and decryption */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 575642c36..dfd493530 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -221,13 +221,21 @@ enum Misc_ASN { EIGHTK_BUF = 8192, /* Tmp buffer size */ MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, /* use bigger NTRU size */ +#ifdef WOLFSSL_ENCRYPTED_KEYS HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */ +#else + HEADER_ENCRYPTED_KEY_SIZE = 0, +#endif TRAILING_ZERO = 1, /* Used for size of zero pad */ MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \ defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) MAX_TIME_STRING_SZ = 25, /* Max length of formatted time string */ #endif + + PEM_LINE_LEN = 80, /* PEM line max + fudge */ + FILE_BUFFER_SIZE = 1024, /* default static file buffer size for input, + will use dynamic buffer if not big enough */ }; @@ -713,43 +721,6 @@ struct DecodedCert { }; -extern const char* const BEGIN_CERT; -extern const char* const END_CERT; -#ifdef WOLFSSL_CERT_REQ - extern const char* const BEGIN_CERT_REQ; - extern const char* const END_CERT_REQ; -#endif -#ifndef NO_DSA - extern const char* const BEGIN_DSA_PARAM; - extern const char* const END_DSA_PARAM; -#endif -#ifndef NO_DH - extern const char* const BEGIN_DH_PARAM; - extern const char* const END_DH_PARAM; -#endif -extern const char* const BEGIN_X509_CRL; -extern const char* const END_X509_CRL; -extern const char* const BEGIN_RSA_PRIV; -extern const char* const END_RSA_PRIV; -extern const char* const BEGIN_PRIV_KEY; -extern const char* const END_PRIV_KEY; -extern const char* const BEGIN_ENC_PRIV_KEY; -extern const char* const END_ENC_PRIV_KEY; -#ifdef HAVE_ECC - extern const char* const BEGIN_EC_PRIV; - extern const char* const END_EC_PRIV; -#endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA) - extern const char* const BEGIN_DSA_PRIV; - extern const char* const END_DSA_PRIV; -#endif -extern const char* const BEGIN_PUB_KEY; -extern const char* const END_PUB_KEY; -#ifdef HAVE_ED25519 - extern const char* const BEGIN_EDDSA_PRIV; - extern const char* const END_EDDSA_PRIV; -#endif - #ifdef NO_SHA #define SIGNER_DIGEST_SIZE WC_SHA256_DIGEST_SIZE #else diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 9752b13ee..69f2d7384 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -125,17 +125,31 @@ typedef struct DerBuffer { } DerBuffer; enum { - IV_SZ = 32, /* max iv sz */ - NAME_SZ = 80 /* max one line */ + IV_SZ = 32, /* max iv sz */ + NAME_SZ = 80, /* max one line */ + + PEM_PASS_READ = 0, + PEM_PASS_WRITE = 1, }; + +typedef int (pem_password_cb)(char* passwd, int sz, int rw, void* userdata); + typedef struct EncryptedInfo { - char name[NAME_SZ]; /* encryption name */ - byte iv[IV_SZ]; /* encrypted IV */ - word32 ivSz; /* encrypted IV size */ + pem_password_cb* passwd_cb; + void* passwd_userdata; + long consumed; /* tracks PEM bytes consumed */ - byte set; /* if encryption set */ - struct WOLFSSL_CTX* ctx; /* CTX owner */ + + int cipherType; + int hashType; + word32 keySz; + word32 ivSz; /* salt or encrypted IV size */ + + char name[NAME_SZ]; /* cipher name, such as "DES-CBC" */ + byte iv[IV_SZ]; /* salt or encrypted IV */ + + byte set:1; /* if encryption set */ } EncryptedInfo; @@ -248,32 +262,32 @@ typedef struct Cert { keyType = RSA_KEY (default) */ WOLFSSL_API int wc_InitCert(Cert*); -WOLFSSL_API int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, +WOLFSSL_API int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key, WC_RNG* rng); -WOLFSSL_API int wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, +WOLFSSL_API int wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, ecc_key*, WC_RNG*); #ifdef WOLFSSL_CERT_REQ - WOLFSSL_API int wc_MakeCertReq_ex(Cert*, byte* derBuffer, word32 derSz, + WOLFSSL_API int wc_MakeCertReq_ex(Cert*, byte* derBuffer, word32 derSz, int, void*); - WOLFSSL_API int wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz, + WOLFSSL_API int wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz, RsaKey*, ecc_key*); #endif -WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buffer, +WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz, int keyType, void* key, WC_RNG* rng); -WOLFSSL_API int wc_SignCert(int requestSz, int sigType, byte* derBuffer, +WOLFSSL_API int wc_SignCert(int requestSz, int sigType, byte* derBuffer, word32 derSz, RsaKey*, ecc_key*, WC_RNG*); -WOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, +WOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, WC_RNG*); -WOLFSSL_API int wc_SetIssuer(Cert*, const char*); -WOLFSSL_API int wc_SetSubject(Cert*, const char*); +WOLFSSL_API int wc_SetIssuer(Cert*, const char*); +WOLFSSL_API int wc_SetSubject(Cert*, const char*); #ifdef WOLFSSL_ALT_NAMES - WOLFSSL_API int wc_SetAltNames(Cert*, const char*); + WOLFSSL_API int wc_SetAltNames(Cert*, const char*); #endif -WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int); -WOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int); -WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int); -WOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int); +WOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int); #ifdef WOLFSSL_CERT_EXT WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, @@ -319,7 +333,7 @@ WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz, #endif /* WOLFSSL_CERT_EXT */ #ifdef HAVE_NTRU - WOLFSSL_API int wc_MakeNtruCert(Cert*, byte* derBuffer, word32 derSz, + WOLFSSL_API int wc_MakeNtruCert(Cert*, byte* derBuffer, word32 derSz, const byte* ntruKey, word16 keySz, WC_RNG*); #endif @@ -342,14 +356,15 @@ WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz, #endif /* WOLFSSL_PEMPUBKEY_TODER_DEFINED */ #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */ -#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA) \ - || defined(OPENSSL_EXTRA) +#ifdef WOLFSSL_DER_TO_PEM WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outputSz, int type); WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outputSz, byte *cipherIno, int type); #endif +WOLFSSL_API int wc_PemGetHeaderFooter(int type, const char** header, + const char** footer); WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type, DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey); @@ -423,6 +438,12 @@ WOLFSSL_API int wc_CreatePKCS8Key(byte* out, word32* outSz, */ WOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize); +#ifdef WOLFSSL_ENCRYPTED_KEYS + WOLFSSL_API int wc_EncryptedInfoGet(EncryptedInfo* info, + const char* cipherInfo); +#endif + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index 77f6324db..c0057f572 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -48,8 +48,13 @@ enum { DES_ENC_TYPE = 2, /* cipher unique type */ DES3_ENC_TYPE = 3, /* cipher unique type */ + DES_BLOCK_SIZE = 8, - DES_KS_SIZE = 32, + DES_KS_SIZE = 32, /* internal DES key buffer size */ + + DES_KEY_SIZE = 8, /* des */ + DES3_KEY_SIZE = 24, /* 3 des ede */ + DES_IV_SIZE = DES_BLOCK_SIZE, DES_ENCRYPTION = 0, DES_DECRYPTION = 1 diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 0de33fa39..43a4b1913 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -95,22 +95,31 @@ typedef union { Note if this gets up to the size of 80 or over check smallstack build */ #if defined(WOLFSSL_SHA3) #define WC_MAX_DIGEST_SIZE WC_SHA3_512_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA3_224_BLOCK_SIZE /* 224 is the largest block size */ #elif defined(WOLFSSL_SHA512) #define WC_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA512_BLOCK_SIZE #elif defined(HAVE_BLAKE2) #define WC_MAX_DIGEST_SIZE BLAKE2B_OUTBYTES + #define WC_MAX_BLOCK_SIZE BLAKE2B_BLOCKBYTES #elif defined(WOLFSSL_SHA384) #define WC_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA384_BLOCK_SIZE #elif !defined(NO_SHA256) #define WC_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA256_BLOCK_SIZE #elif defined(WOLFSSL_SHA224) #define WC_MAX_DIGEST_SIZE WC_SHA224_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA224_BLOCK_SIZE #elif !defined(NO_SHA) #define WC_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_SHA_BLOCK_SIZE #elif !defined(NO_MD5) #define WC_MAX_DIGEST_SIZE WC_MD5_DIGEST_SIZE + #define WC_MAX_BLOCK_SIZE WC_MD5_BLOCK_SIZE #else #define WC_MAX_DIGEST_SIZE 64 /* default to max size of 64 */ + #define WC_MAX_BLOCK_SIZE 128 #endif #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) @@ -118,6 +127,7 @@ WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type); #endif WOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type); +WOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type); WOLFSSL_API int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len); diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index c3556b332..aa93f0d57 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -83,38 +83,18 @@ enum { WC_SHA3_256 = 11, WC_SHA3_384 = 12, WC_SHA3_512 = 13, -#else - /* These values are used for HMAC, not SHA-3 directly. - * They come from from FIPS PUB 202. */ - WC_SHA3_224_BLOCK_SIZE = 144, - WC_SHA3_256_BLOCK_SIZE = 136, - WC_SHA3_384_BLOCK_SIZE = 104, - WC_SHA3_512_BLOCK_SIZE = 72, -#endif - -/* Select the largest available hash for the buffer size. */ -#if defined(WOLFSSL_SHA3) - WC_HMAC_BLOCK_SIZE = WC_SHA3_224_BLOCK_SIZE - /* SHA3-224 has the largest block size */ -#elif defined(WOLFSSL_SHA512) - WC_HMAC_BLOCK_SIZE = WC_SHA512_BLOCK_SIZE, -#elif defined(HAVE_BLAKE2) - WC_HMAC_BLOCK_SIZE = BLAKE2B_BLOCKBYTES, -#elif defined(WOLFSSL_SHA384) - WC_HMAC_BLOCK_SIZE = WC_SHA384_BLOCK_SIZE -#elif !defined(NO_SHA256) - WC_HMAC_BLOCK_SIZE = WC_SHA256_BLOCK_SIZE -#elif defined(WOLFSSL_SHA224) - WC_HMAC_BLOCK_SIZE = WC_SHA224_BLOCK_SIZE -#elif !defined(NO_SHA) - WC_HMAC_BLOCK_SIZE = WC_SHA_BLOCK_SIZE, -#elif !defined(NO_MD5) - WC_HMAC_BLOCK_SIZE = WC_MD5_BLOCK_SIZE, -#else - #error "You have to have some kind of hash if you want to use HMAC." #endif }; +/* Select the largest available hash for the buffer size. */ +#define WC_HMAC_BLOCK_SIZE WC_MAX_BLOCK_SIZE + +#if !defined(WOLFSSL_SHA3) && !defined(WOLFSSL_SHA512) && !defined(HAVE_BLAKE2) && \ + !defined(WOLFSSL_SHA384) && defined(NO_SHA256) && defined(WOLFSSL_SHA224) && \ + defined(NO_SHA) && defined(NO_MD5) + #error "You have to have some kind of hash if you want to use HMAC." +#endif + /* hash union */ typedef union { diff --git a/wolfssl/wolfcrypt/pwdbased.h b/wolfssl/wolfcrypt/pwdbased.h index d7662be14..bad38a8cc 100644 --- a/wolfssl/wolfcrypt/pwdbased.h +++ b/wolfssl/wolfcrypt/pwdbased.h @@ -30,11 +30,6 @@ #ifndef NO_PWDBASED -#ifndef NO_MD5 - #include /* for hash type */ -#endif - -#include #ifdef __cplusplus extern "C" { @@ -44,6 +39,10 @@ * hashType renamed to typeH to avoid shadowing global declaration here: * wolfssl/wolfcrypt/asn.h line 173 in enum Oid_Types */ +WOLFSSL_API int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen, + const byte* passwd, int passwdLen, + const byte* salt, int saltLen, int iterations, + int hashType, void* heap); WOLFSSL_API int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int typeH); @@ -63,12 +62,6 @@ WOLFSSL_API int wc_scrypt(byte* output, const byte* passwd, int passLen, int blockSize, int parallel, int dkLen); #endif -/* helper functions */ -WOLFSSL_LOCAL int GetDigestSize(int typeH); -WOLFSSL_LOCAL int GetPKCS12HashSizes(int typeH, word32* v, word32* u); -WOLFSSL_LOCAL int DoPKCS12Hash(int typeH, byte* buffer, word32 totalLen, - byte* Ai, word32 u, int iterations); - #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index b847ce334..cdcfeca09 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1652,6 +1652,23 @@ extern void uITRON4_free(void *p) ; #endif /* OPENSSL_EXTRA */ +/* support for encrypted keys */ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ + defined(HAVE_WEBSERVER) + #undef WOLFSSL_ENCRYPTED_KEYS + #define WOLFSSL_ENCRYPTED_KEYS + + /* requires PWDBASED */ + #undef NO_PWDBASED +#endif + +/* support for converting DER to PEM */ +#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || \ + defined(OPENSSL_EXTRA) + #undef WOLFSSL_DER_TO_PEM + #define WOLFSSL_DER_TO_PEM +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index b6eb7dd3d..54c1f695c 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -58,7 +58,14 @@ enum { SHA3_512 = 13, /* hash type unique */ SHA3_512_DIGEST_SIZE = 64, - SHA3_512_COUNT = 9 + SHA3_512_COUNT = 9, + + /* These values are used for HMAC, not SHA-3 directly. + * They come from from FIPS PUB 202. */ + WC_SHA3_224_BLOCK_SIZE = 144, + WC_SHA3_256_BLOCK_SIZE = 136, + WC_SHA3_384_BLOCK_SIZE = 104, + WC_SHA3_512_BLOCK_SIZE = 72, }; #define WC_SHA3_224 SHA3_224 diff --git a/wolfssl/wolfcrypt/wc_encrypt.h b/wolfssl/wolfcrypt/wc_encrypt.h index 09d79cc73..3eab17b26 100644 --- a/wolfssl/wolfcrypt/wc_encrypt.h +++ b/wolfssl/wolfcrypt/wc_encrypt.h @@ -33,31 +33,76 @@ extern "C" { #endif +enum CipherTypes { + WC_CIPHER_NONE, #ifndef NO_AES -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); + #ifdef HAVE_AES_CBC + WC_CIPHER_AES_CBC, + #endif + #ifdef HAVE_AESGCM + WC_CIPHER_AES_GCM, + #endif + #ifdef WOLFSSL_AES_COUNTER + WC_CIPHER_AES_CTR, + #endif + #ifdef WOLFSSL_AES_XTS + WC_CIPHER_AES_XTS, + #endif + #ifdef WOLFSSL_AES_CFB + WC_CIPHER_AES_CFB, + #endif +#endif +#ifndef NO_DES3 + WC_CIPHER_DES3, +#endif +#ifndef NO_DES + WC_CIPHER_DES, +#endif +#ifdef HAVE_CHAHCA + WC_CIPHER_CHACHA, +#endif +#ifdef HAVE_HC128 + WC_CIPHER_HC128, +#endif +}; + + +#ifndef NO_AES +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); #endif /* !NO_AES */ #ifndef NO_DES3 -WOLFSSL_API int wc_Des_CbcDecryptWithKey(byte* out, +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_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, const byte* key, const byte* iv); -WOLFSSL_API int wc_Des_CbcEncryptWithKey(byte* out, +WOLFSSL_API int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, const byte* key, const byte* iv); -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); #endif /* !NO_DES3 */ + + + +#ifdef WOLFSSL_ENCRYPTED_KEYS + struct EncryptedInfo; + WOLFSSL_API int wc_BufferKeyDecrypt(struct EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz); + WOLFSSL_API int wc_BufferKeyEncrypt(struct EncryptedInfo* info, byte* der, word32 derSz, + const byte* password, int passwordSz); +#endif /* WOLFSSL_ENCRYPTED_KEYS */ + #ifdef __cplusplus } /* extern "C" */ #endif