| 
					
				 | 
			
			
				@@ -425,7 +425,7 @@ crypto_cipher_free(crypto_cipher_t *env) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(env->cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   aes_cipher_free(env->cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(env, 0, sizeof(crypto_cipher_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(env, 0, sizeof(crypto_cipher_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(env); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -529,7 +529,7 @@ crypto_pk_read_private_key_from_filename(crypto_pk_t *env, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* Try to parse it. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r = crypto_pk_read_private_key_from_string(env, contents, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(contents, 0, strlen(contents)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(contents, 0, strlen(contents)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(contents); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return -1; /* read_private_key_from_string already warned, so we don't.*/ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -671,7 +671,7 @@ crypto_pk_write_private_key_to_filename(crypto_pk_t *env, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   s[len]='\0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r = write_str_to_file(fname, s, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   BIO_free(bio); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(s, 0, strlen(s)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(s, 0, strlen(s)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -981,7 +981,7 @@ crypto_pk_private_sign_digest(crypto_pk_t *env, char *to, size_t tolen, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (crypto_digest(digest,from,fromlen)<0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r = crypto_pk_private_sign(env,to,tolen,digest,DIGEST_LEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1045,14 +1045,14 @@ crypto_pk_public_hybrid_encrypt(crypto_pk_t *env, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             from+pkeylen-overhead-CIPHER_KEY_LEN, symlen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (r<0) goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(buf, 0, pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(buf, 0, pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_cipher_free(cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(outlen+symlen < INT_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return (int)(outlen + symlen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(buf, 0, pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(buf, 0, pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_cipher_free(cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return -1; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1103,13 +1103,13 @@ crypto_pk_private_hybrid_decrypt(crypto_pk_t *env, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r = crypto_cipher_decrypt(cipher, to+outlen, from+pkeylen, fromlen-pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (r<0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(buf,0,pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(buf,0,pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_cipher_free(cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(outlen + fromlen < INT_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return (int)(outlen + (fromlen-pkeylen)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(buf,0,pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(buf,0,pkeylen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_cipher_free(cipher); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return -1; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1509,7 +1509,7 @@ crypto_digest_free(crypto_digest_t *digest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (!digest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(digest, 0, sizeof(crypto_digest_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(digest, 0, sizeof(crypto_digest_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(digest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1571,7 +1571,7 @@ crypto_digest_get_digest(crypto_digest_t *digest, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memcpy(out, r, out_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(r, 0, sizeof(r)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(r, 0, sizeof(r)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Allocate and return a new digest object with the same state as 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1673,10 +1673,10 @@ crypto_hmac_sha256(char *hmac_out, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SHA256_Final((uint8_t*)hmac_out, &st); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* Now clear everything. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(k, 0, sizeof(k)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(pad, 0, sizeof(pad)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(d, 0, sizeof(d)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(&st, 0, sizeof(st)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(k, 0, sizeof(k)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(pad, 0, sizeof(pad)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(d, 0, sizeof(d)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(&st, 0, sizeof(st)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #undef BLOCKSIZE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #undef DIGESTSIZE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2208,7 +2208,7 @@ crypto_dh_compute_secret(int severity, crypto_dh_t *dh, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (pubkey_bn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     BN_free(pubkey_bn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (secret_tmp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memset(secret_tmp, 0, secret_tmp_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memwipe(secret_tmp, 0, secret_tmp_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tor_free(secret_tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (result < 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2243,15 +2243,15 @@ crypto_expand_key_material(const char *key_in, size_t key_in_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len-(cp-key_out))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(tmp, 0, key_in_len+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(tmp, 0, key_in_len+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(tmp, 0, key_in_len+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(tmp, 0, key_in_len+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(digest, 0, sizeof(digest)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2343,7 +2343,7 @@ crypto_seed_rng(int startup) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return rand_poll_status ? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   RAND_seed(buf, sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(buf, 0, sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(buf, 0, sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   seed_weak_rng(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2360,7 +2360,7 @@ crypto_seed_rng(int startup) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     RAND_seed(buf, (int)sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memset(buf, 0, sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memwipe(buf, 0, sizeof(buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     seed_weak_rng(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2843,7 +2843,7 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(tmp, 0, srclen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(tmp, 0, srclen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tmp = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2888,11 +2888,54 @@ secret_to_key(char *key_out, size_t key_out_len, const char *secret, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_digest_get_digest(d, key_out, key_out_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  memset(tmp, 0, tmplen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memwipe(tmp, 0, tmplen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   crypto_digest_free(d); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Destroy the <b>sz</b> bytes of data stored at <b>mem</b>, setting them to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the value <b>byte</b>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This function is preferable to memset, since many compilers will happily 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * optimize out memset() when they can convince themselves that the data being 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * cleared will never be read. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Right now, our convention is to use this function when we are wiping data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * that's about to become inaccessible, such as stack buffers that are about 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to go out of scope or structures that are about to get freed.  (In 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * practice, it appears that the compilers we're currently using will optimize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * out the memset()s for stack-allocated buffers, but not those for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * about-to-be-freed structures. That could change, though, so we're being 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * wary.)  If there are live reads for the data, then you can just use 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * memset(). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+memwipe(void *mem, uint8_t byte, size_t sz) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Because whole-program-optimization exists, we may not be able to just 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * have this function call "memset".  A smart compiler could inline it, then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * eliminate dead memsets, and declare itself to be clever. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* This is a slow and ugly function from OpenSSL that fills 'mem' with junk 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * based on the pointer value, then uses that junk to update a global 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * variable.  It's an elaborate ruse to trick the compiler into not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * optimizing out the "wipe this memory" code.  Read it if you like zany 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * programming tricks! In later versions of Tor, we should look for better 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * not-optimized-out memory wiping stuff. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OPENSSL_cleanse(mem, sz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Just in case some caller of memwipe() is relying on getting a buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * filled with a particular value, fill the buffer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * If this function gets inlined, this memset might get eliminated, but 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * that's okay: We only care about this particular memset in the case where 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * the caller should have been using memset(), and the memset() wouldn't get 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * eliminated.  In other words, this is here so that we won't break anything 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * if somebody accidentally calls memwipe() instead of memset(). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   **/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(mem, byte, sz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef TOR_IS_MULTITHREADED 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Helper: OpenSSL uses this callback to manipulate mutexes. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void 
			 |