From b7de76b74d84c4c45d86cca6fae2e9879f281695 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Wed, 2 Nov 2011 19:16:43 +0000
Subject: [PATCH] Add support for memory leak checking in fips_algvs.

Fix many memory leaks in algorithm test utilities.
---
 fips/aes/fips_aesavs.c    |  3 ++-
 fips/aes/fips_gcmtest.c   |  6 ++++++
 fips/des/fips_desmovs.c   |  2 ++
 fips/dsa/fips_dssvs.c     | 29 +++++++++++++++++++++++------
 fips/ecdh/fips_ecdhvs.c   | 20 +++++++++++++++++---
 fips/ecdsa/fips_ecdsavs.c | 17 ++++++++++++++++-
 fips/fips_test_suite.c    |  4 +++-
 fips/rsa/fips_rsastest.c  |  3 +++
 test/fips_algvs.c         | 24 +++++++++++++++++++++---
 9 files changed, 93 insertions(+), 15 deletions(-)

diff --git a/fips/aes/fips_aesavs.c b/fips/aes/fips_aesavs.c
index 9a0996422..bbdb93aab 100644
--- a/fips/aes/fips_aesavs.c
+++ b/fips/aes/fips_aesavs.c
@@ -535,7 +535,7 @@ static int do_mct(char *amode,
 		}
 	    }
 	}
-    
+    FIPS_cipher_ctx_cleanup(&ctx);
     return ret;
     }
 
@@ -850,6 +850,7 @@ static int proc_file(char *rqfile, char *rspfile)
 	fclose(rfp);
     if (afp)
 	fclose(afp);
+    FIPS_cipher_ctx_cleanup(&ctx);
     return err;
     }
 
diff --git a/fips/aes/fips_gcmtest.c b/fips/aes/fips_gcmtest.c
index a7c787368..02849bc2a 100644
--- a/fips/aes/fips_gcmtest.c
+++ b/fips/aes/fips_gcmtest.c
@@ -261,6 +261,7 @@ static void gcmtest(FILE *in, FILE *out, int encrypt)
 			iv = aad = ct = pt = key = tag = NULL;
 			}
 		}
+	FIPS_cipher_ctx_cleanup(&ctx);	
 	}
 
 static void xtstest(FILE *in, FILE *out)
@@ -335,6 +336,7 @@ static void xtstest(FILE *in, FILE *out)
 			iv = key = inbuf = outbuf = NULL;
 			}	
 		}
+	FIPS_cipher_ctx_cleanup(&ctx);	
 	}
 
 static void ccmtest(FILE *in, FILE *out)
@@ -428,6 +430,8 @@ static void ccmtest(FILE *in, FILE *out)
 			}
 		else if (!strcmp(keyword,"Adata"))
 			{
+			if (Adata)
+				OPENSSL_free(Adata);
 			Adata = hex2bin_m(value, &l);
 			if (Alen && l != Alen)
 				{
@@ -493,6 +497,8 @@ static void ccmtest(FILE *in, FILE *out)
 		OPENSSL_free(Key);
 	if (Nonce)
 		OPENSSL_free(Nonce);
+	if (Adata)
+		OPENSSL_free(Adata);
 	FIPS_cipher_ctx_cleanup(&ctx);
 	}
 
diff --git a/fips/des/fips_desmovs.c b/fips/des/fips_desmovs.c
index 29035f08c..79900aeae 100644
--- a/fips/des/fips_desmovs.c
+++ b/fips/des/fips_desmovs.c
@@ -263,6 +263,7 @@ static int do_tmct(char *amode,
 	if(imode == TOFB)
 	    for(n=0 ; n < 8 ; ++n)
 		text[n]=text0[n]^old_iv[n];
+	FIPS_cipher_ctx_cleanup(&ctx);
 	}
     return 1;
     }
@@ -622,6 +623,7 @@ static int tproc_file(char *rqfile, char *rspfile)
 	fclose(rfp);
     if (afp)
 	fclose(afp);
+    FIPS_cipher_ctx_cleanup(&ctx);
     return err;
     }
 
diff --git a/fips/dsa/fips_dssvs.c b/fips/dsa/fips_dssvs.c
index 706babf05..45eefb7c6 100644
--- a/fips/dsa/fips_dssvs.c
+++ b/fips/dsa/fips_dssvs.c
@@ -199,6 +199,7 @@ static void pqg(FILE *in, FILE *out)
 			{
 			fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
 			}
+		FIPS_dsa_free(dsa);
 		}
 	    }
 	else if(!strcmp(keyword,"P"))
@@ -519,6 +520,8 @@ static void keyver(FILE *in, FILE *out)
 	    BN_free(g);
 	if (Y2)
 	    BN_free(Y2);
+	if (ctx)
+	    BN_CTX_free(ctx);
     }
 
 static void keypair(FILE *in, FILE *out)
@@ -575,6 +578,8 @@ static void keypair(FILE *in, FILE *out)
 		do_bn_print_name(out, "Y",dsa->pub_key);
 	    	fputs(RESP_EOL, out);
 		}
+	    if (dsa)
+		FIPS_dsa_free(dsa);
 	    }
 	}
     }
@@ -648,8 +653,8 @@ static void siggen(FILE *in, FILE *out)
 	    FIPS_md_ctx_cleanup(&mctx);
 	    }
 	}
-	if (dsa)
-		FIPS_dsa_free(dsa);
+    if (dsa)
+	FIPS_dsa_free(dsa);
     }
 
 static void sigver(FILE *in, FILE *out)
@@ -687,15 +692,15 @@ static void sigver(FILE *in, FILE *out)
 	    dsa = FIPS_dsa_new();
 	    }
 	else if(!strcmp(keyword,"P"))
-	    dsa->p=hex2bn(value);
+	    do_hex2bn(&dsa->p, value);
 	else if(!strcmp(keyword,"Q"))
-	    dsa->q=hex2bn(value);
+	    do_hex2bn(&dsa->q, value);
 	else if(!strcmp(keyword,"G"))
-	    dsa->g=hex2bn(value);
+	    do_hex2bn(&dsa->g, value);
 	else if(!strcmp(keyword,"Msg"))
 	    n=hex2bin(value,msg);
 	else if(!strcmp(keyword,"Y"))
-	    dsa->pub_key=hex2bn(value);
+	    do_hex2bn(&dsa->pub_key, value);
 	else if(!strcmp(keyword,"R"))
 	    sig->r=hex2bn(value);
 	else if(!strcmp(keyword,"S"))
@@ -711,10 +716,22 @@ static void sigver(FILE *in, FILE *out)
 	    r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
 	    no_err = 0;
 	    FIPS_md_ctx_cleanup(&mctx);
+	    if (sig->s)
+		{
+		BN_free(sig->s);
+		sig->s = NULL;
+		}
+	    if (sig->r)
+		{
+		BN_free(sig->r);
+		sig->r = NULL;
+		}
 	
 	    fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
 	    }
 	}
+	if (dsa)
+	    FIPS_dsa_free(dsa);
     }
 
 #ifdef FIPS_ALGVS
diff --git a/fips/ecdh/fips_ecdhvs.c b/fips/ecdh/fips_ecdhvs.c
index 821821a96..a30e335e2 100644
--- a/fips/ecdh/fips_ecdhvs.c
+++ b/fips/ecdh/fips_ecdhvs.c
@@ -319,6 +319,7 @@ int main(int argc, char **argv)
 	EC_GROUP *group = NULL;
 	char *keyword = NULL, *value = NULL;
 	int do_verify = -1, exout = 0;
+	int rv = 1;
 
 	int curve_nids[5] = {0,0,0,0,0};
 	int param_set = -1;
@@ -463,10 +464,23 @@ int main(int argc, char **argv)
 					md, rhash, rhashlen);
 			}
 		}
-	return 0;
+	rv = 0;
 	parse_error:
-	fprintf(stderr, "Error Parsing request file\n");
-	exit(1);
+	if (id)
+		BN_free(id);
+	if (ix)
+		BN_free(ix);
+	if (iy)
+		BN_free(iy);
+	if (cx)
+		BN_free(cx);
+	if (cy)
+		BN_free(cy);
+	if (group)
+		EC_GROUP_free(group);
+	if (rv)
+		fprintf(stderr, "Error Parsing request file\n");
+	return rv;
 	}
 
 #endif
diff --git a/fips/ecdsa/fips_ecdsavs.c b/fips/ecdsa/fips_ecdsavs.c
index 50b1b7ca5..35ff25106 100644
--- a/fips/ecdsa/fips_ecdsavs.c
+++ b/fips/ecdsa/fips_ecdsavs.c
@@ -287,10 +287,13 @@ static int PKV(FILE *in, FILE *out)
 			no_err = 1;
 			rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
 			no_err = 0;
+			EC_KEY_free(key);
 			fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F");
 			}
 
 		}
+	BN_free(Qx);
+	BN_free(Qy);
 	return 1;
 	}
 
@@ -358,7 +361,7 @@ static int SigGen(FILE *in, FILE *out)
 			do_bn_print_name(out, "S", sig->s);
 
 			EC_KEY_free(key);
-
+			OPENSSL_free(msg);
 			FIPS_ecdsa_sig_free(sig);
 
 			}
@@ -451,12 +454,24 @@ static int SigVer(FILE *in, FILE *out)
 			FIPS_digestupdate(&mctx, msg, mlen);
 			no_err = 1;
 	    		rv = FIPS_ecdsa_verify_ctx(key, &mctx, sig);
+			EC_KEY_free(key);
+			if (msg)
+				OPENSSL_free(msg);
 			no_err = 0;
 
 			fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F");
 			}
 
 		}
+	if (sig->r)
+		BN_free(sig->r);
+	if (sig->s)
+		BN_free(sig->s);
+	if (Qx)
+		BN_free(Qx);
+	if (Qy)
+		BN_free(Qy);
+	EVP_MD_CTX_cleanup(&mctx);
 	return 1;
 	}
 #ifdef FIPS_ALGVS
diff --git a/fips/fips_test_suite.c b/fips/fips_test_suite.c
index 1344b1108..db0f18a16 100644
--- a/fips/fips_test_suite.c
+++ b/fips/fips_test_suite.c
@@ -651,6 +651,8 @@ static int Zeroize()
     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
         printf("\n");
 
+    FIPS_rsa_free(key);
+
     return 1;
     }
 
@@ -696,7 +698,7 @@ static int do_drbg_test(int type, int flags)
 	}
     rv = 1;
     err:
-    FIPS_drbg_uninstantiate(dctx);
+    FIPS_drbg_free(dctx);
     return rv;
     }
 
diff --git a/fips/rsa/fips_rsastest.c b/fips/rsa/fips_rsastest.c
index d11b06316..72e75a3cc 100644
--- a/fips/rsa/fips_rsastest.c
+++ b/fips/rsa/fips_rsastest.c
@@ -362,6 +362,9 @@ static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
 
 	error:
 
+	if (sigbuf)
+		OPENSSL_free(sigbuf);
+
 	return ret;
 	}
 #endif
diff --git a/test/fips_algvs.c b/test/fips_algvs.c
index a662d01df..36d7fb333 100644
--- a/test/fips_algvs.c
+++ b/test/fips_algvs.c
@@ -229,9 +229,23 @@ int main(int argc, char **argv)
 	char **xargv;
 	int lineno = 0, badarg = 0;
 	int nerr = 0, quiet = 0, verbose = 0;
+	int rv;
 	FILE *in = NULL;
+#ifdef FIPS_ALGVS_MEMCHECK
+	CRYPTO_malloc_debug_init();
+	OPENSSL_init();
+	CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+#endif
+
 	if (*args && *args[0] != '-')
-		return run_prg(argc - 1, args);
+		{
+		rv = run_prg(argc - 1, args);
+#ifdef FIPS_ALGVS_MEMCHECK
+		CRYPTO_mem_leaks_fp(stderr);
+#endif
+		return rv;
+		}
 	while (!badarg && *args && *args[0] == '-')
 		{
 		if (!strcmp(*args, "-script"))
@@ -276,7 +290,6 @@ int main(int argc, char **argv)
 			fprintf(stderr, "Error processing line %d\n", lineno);
 		else
 			{
-			int rv;
 			if (!quiet)
 				{
 				int i;
@@ -303,10 +316,15 @@ int main(int argc, char **argv)
 	if (!quiet)
 		printf("Completed with %d errors\n", nerr);
 
+	if (arg.data)
+		OPENSSL_free(arg.data);
+
 	fclose(in);
+#ifdef FIPS_ALGVS_MEMCHECK
+	CRYPTO_mem_leaks_fp(stderr);
+#endif
 	if (nerr == 0)
 		return 0;
 	return 1;
 	}
-
 #endif