refactor(security): add OpenSSL 1.x compatibility

When updated to work with OpenSSL 3.0, the host tools lost their
compatibility with previous versions (1.x) of OpenSSL. This is
mainly due to the fact that 1.x APIs became deprecated in 3.0 and
therefore their use cause compiling errors. In addition, updating
for a newer version of OpenSSL meant improving the stability
against security threats. However, although version 1.1.1 is
now deprecated, it still receives security updates, so it would
not imply major security issues to keep compatibility with it too.

This patch adds backwards compatibility with OpenSSL 1.x versions
by adding back 1.x API code. It defines a macro USING_OPENSSL3,
which will select the appropriate OpenSSL API version depending on
the OpenSSL library path chosen (which is determined by the
already-existing OPENSSL_DIR variable).

In addition, cleanup items were packed in functions and moved to
the proper modules in order to make the code more maintainable and
legible.

Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
Change-Id: I8deceb5e419edc73277792861882404790ccd33c
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 2857a3b..0061b8a 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 key_t *keys;
 unsigned int num_keys;
 
+#if !USING_OPENSSL3
 /*
  * Create a new key container
  */
@@ -37,9 +38,11 @@
 
 	return 1;
 }
+#endif
 
 static int key_create_rsa(key_t *key, int key_bits)
 {
+#if USING_OPENSSL3
 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
 	if (rsa == NULL) {
 		printf("Cannot generate RSA key\n");
@@ -47,11 +50,52 @@
 	}
 	key->key = rsa;
 	return 1;
+#else
+	BIGNUM *e;
+	RSA *rsa = NULL;
+
+	e = BN_new();
+	if (e == NULL) {
+		printf("Cannot create RSA exponent\n");
+		return 0;
+	}
+
+	if (!BN_set_word(e, RSA_F4)) {
+		printf("Cannot assign RSA exponent\n");
+		goto err2;
+	}
+
+	rsa = RSA_new();
+	if (rsa == NULL) {
+		printf("Cannot create RSA key\n");
+		goto err2;
+	}
+
+	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
+		printf("Cannot generate RSA key\n");
+		goto err;
+	}
+
+	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
+		printf("Cannot assign RSA key\n");
+		goto err;
+	}
+
+	BN_free(e);
+	return 1;
+
+err:
+	RSA_free(rsa);
+err2:
+	BN_free(e);
+	return 0;
+#endif
 }
 
 #ifndef OPENSSL_NO_EC
 static int key_create_ecdsa(key_t *key, int key_bits)
 {
+#if USING_OPENSSL3
 	EVP_PKEY *ec = EVP_EC_gen("prime256v1");
 	if (ec == NULL) {
 		printf("Cannot generate EC key\n");
@@ -59,6 +103,31 @@
 	}
 	key->key = ec;
 	return 1;
+#else
+	EC_KEY *ec;
+
+	ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+	if (ec == NULL) {
+		printf("Cannot create EC key\n");
+		return 0;
+	}
+	if (!EC_KEY_generate_key(ec)) {
+		printf("Cannot generate EC key\n");
+		goto err;
+	}
+	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
+	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
+	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
+		printf("Cannot assign EC key\n");
+		goto err;
+	}
+
+	return 1;
+
+err:
+	EC_KEY_free(ec);
+	return 0;
+#endif
 }
 #endif /* OPENSSL_NO_EC */
 
@@ -194,3 +263,20 @@
 
 	return NULL;
 }
+
+void key_cleanup(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_keys; i++) {
+		EVP_PKEY_free(keys[i].key);
+		if (keys[i].fn != NULL) {
+			void *ptr = keys[i].fn;
+
+			free(ptr);
+			keys[i].fn = NULL;
+		}
+	}
+	free(keys);
+}
+