@@ -480,6 +480,7 @@ static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
480480 byte * tmp = NULL ;
481481 byte * cipherInfo = NULL ;
482482 int pemSz = 0 ;
483+ int derAllocSz = derSz ;
483484 int hashType = WC_HASH_TYPE_NONE ;
484485#if !defined(NO_MD5 )
485486 hashType = WC_MD5 ;
@@ -515,6 +516,7 @@ static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
515516 }
516517 else {
517518 der = tmpBuf ;
519+ derAllocSz = derSz + blockSz ;
518520
519521 /* Encrypt DER inline. */
520522 ret = EncryptDerKey (der , & derSz , cipher , passwd , passwdSz ,
@@ -562,7 +564,10 @@ static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
562564
563565 XFREE (tmp , NULL , DYNAMIC_TYPE_KEY );
564566 XFREE (cipherInfo , NULL , DYNAMIC_TYPE_STRING );
565- XFREE (der , heap , DYNAMIC_TYPE_TMP_BUFFER );
567+ if (der != NULL ) {
568+ ForceZero (der , (word32 )derAllocSz );
569+ XFREE (der , heap , DYNAMIC_TYPE_TMP_BUFFER );
570+ }
566571
567572 return ret ;
568573}
@@ -2104,6 +2109,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
21042109 derSz = wc_DsaKeyToDer ((DsaKey * )dsa -> internal , derBuf , (word32 )der_max_len );
21052110 if (derSz < 0 ) {
21062111 WOLFSSL_MSG ("wc_DsaKeyToDer failed" );
2112+ ForceZero (derBuf , (word32 )der_max_len );
21072113 XFREE (derBuf , NULL , DYNAMIC_TYPE_DER );
21082114 return 0 ;
21092115 }
@@ -2116,6 +2122,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
21162122 & cipherInfo , der_max_len , WC_MD5 );
21172123 if (ret != 1 ) {
21182124 WOLFSSL_MSG ("EncryptDerKey failed" );
2125+ ForceZero (derBuf , (word32 )der_max_len );
21192126 XFREE (derBuf , NULL , DYNAMIC_TYPE_DER );
21202127 return ret ;
21212128 }
@@ -2131,6 +2138,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
21312138 tmp = (byte * )XMALLOC ((size_t )* pLen , NULL , DYNAMIC_TYPE_PEM );
21322139 if (tmp == NULL ) {
21332140 WOLFSSL_MSG ("malloc failed" );
2141+ ForceZero (derBuf , (word32 )der_max_len );
21342142 XFREE (derBuf , NULL , DYNAMIC_TYPE_DER );
21352143 XFREE (cipherInfo , NULL , DYNAMIC_TYPE_STRING );
21362144 return 0 ;
@@ -2141,11 +2149,13 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
21412149 type );
21422150 if (* pLen <= 0 ) {
21432151 WOLFSSL_MSG ("wc_DerToPemEx failed" );
2152+ ForceZero (derBuf , (word32 )der_max_len );
21442153 XFREE (derBuf , NULL , DYNAMIC_TYPE_DER );
21452154 XFREE (tmp , NULL , DYNAMIC_TYPE_PEM );
21462155 XFREE (cipherInfo , NULL , DYNAMIC_TYPE_STRING );
21472156 return 0 ;
21482157 }
2158+ ForceZero (derBuf , (word32 )der_max_len );
21492159 XFREE (derBuf , NULL , DYNAMIC_TYPE_DER );
21502160 XFREE (cipherInfo , NULL , DYNAMIC_TYPE_STRING );
21512161
@@ -7107,6 +7117,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
71077117 char password [NAME_SZ ];
71087118 byte * key = NULL ;
71097119 word32 keySz = 0 ;
7120+ word32 allocSz = 0 ;
71107121 int type = PKCS8_PRIVATEKEY_TYPE ;
71117122
71127123 /* Validate parameters. */
@@ -7139,9 +7150,11 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
71397150 * pemSz += 54 ;
71407151 }
71417152
7153+ allocSz = (word32 )* pemSz ;
71427154 /* Allocate enough memory to hold PEM encoded encrypted key. */
7143- * pem = (byte * )XMALLOC ((size_t )* pemSz , NULL , DYNAMIC_TYPE_TMP_BUFFER );
7155+ * pem = (byte * )XMALLOC ((size_t )allocSz , NULL , DYNAMIC_TYPE_TMP_BUFFER );
71447156 if (* pem == NULL ) {
7157+ allocSz = 0 ;
71457158 res = 0 ;
71467159 }
71477160 else {
@@ -7198,6 +7211,20 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
71987211 }
71997212 }
72007213
7214+ /* Zero any remnants of the DER staging area that persist after PEM
7215+ * conversion so plaintext private key material is not left in freed heap
7216+ * memory. On success, only the bytes past the actual PEM output need
7217+ * clearing; on failure, the whole buffer is zeroed since its state is
7218+ * indeterminate. */
7219+ if (* pem != NULL ) {
7220+ if (res == 1 && (word32 )* pemSz < allocSz ) {
7221+ ForceZero (* pem + * pemSz , allocSz - (word32 )* pemSz );
7222+ }
7223+ else if (res != 1 ) {
7224+ ForceZero (* pem , allocSz );
7225+ }
7226+ }
7227+
72017228 /* Return appropriate return code. */
72027229 return (res == 0 ) ? 0 : ret ;
72037230
0 commit comments