chromeos-base/update_engine: add OpenSSL 3.0 support

Use EVP_PKEY_get1_EC_KEY/EVP_PKEY_get1_RSA instead of
EVP_PKEY_get0_EC_KEY/EVP_PKEY_get0_RSA as the former is
compatible with OpenSSL 3.0.

BUG=b/257113269
TEST=presubmit
RELEASE_NOTE=None

Change-Id: I19b911ff5a4066a81057f85813a166c85efec192
Reviewed-on: https://cos-review.googlesource.com/c/third_party/overlays/chromiumos-overlay/+/44438
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com>
diff --git a/chromeos-base/update_engine/files/update_engine-0.0.3-openssl-3.patch b/chromeos-base/update_engine/files/update_engine-0.0.3-openssl-3.patch
new file mode 100644
index 0000000..d0c47f0
--- /dev/null
+++ b/chromeos-base/update_engine/files/update_engine-0.0.3-openssl-3.patch
@@ -0,0 +1,87 @@
+diff --git a/payload_consumer/payload_verifier.cc b/payload_consumer/payload_verifier.cc
+index 85902c80e844..d86763be761e 100644
+--- a/payload_consumer/payload_verifier.cc
++++ b/payload_consumer/payload_verifier.cc
+@@ -175,7 +175,7 @@ bool PayloadVerifier::VerifyRawSignature(
+     }
+ 
+     if (key_type == EVP_PKEY_EC) {
+-      EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(public_key.get());
++      EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(public_key.get());
+       TEST_AND_RETURN_FALSE(ec_key != nullptr);
+       if (ECDSA_verify(0,
+                        sha256_hash_data.data(),
+@@ -183,8 +183,10 @@ bool PayloadVerifier::VerifyRawSignature(
+                        sig_data.data(),
+                        sig_data.size(),
+                        ec_key) == 1) {
++	EC_KEY_free(ec_key);
+         return true;
+       }
++      EC_KEY_free(ec_key);
+     }
+ 
+     LOG(ERROR) << "Unsupported key type " << key_type;
+@@ -203,12 +205,13 @@ bool PayloadVerifier::GetRawHashFromSignature(
+   //
+   // openssl rsautl -verify -pubin -inkey <(echo pem_public_key)
+   //   -in |sig_data| -out |out_hash_data|
+-  RSA* rsa = EVP_PKEY_get0_RSA(const_cast<EVP_PKEY*>(public_key));
++  RSA* rsa = EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(public_key));
+ 
+   TEST_AND_RETURN_FALSE(rsa != nullptr);
+   unsigned int keysize = RSA_size(rsa);
+   if (sig_data.size() > 2 * keysize) {
+     LOG(ERROR) << "Signature size is too big for public key size.";
++    RSA_free(rsa);
+     return false;
+   }
+ 
+@@ -216,6 +219,7 @@ bool PayloadVerifier::GetRawHashFromSignature(
+   brillo::Blob hash_data(keysize);
+   int decrypt_size = RSA_public_decrypt(
+       sig_data.size(), sig_data.data(), hash_data.data(), rsa, RSA_NO_PADDING);
++  RSA_free(rsa);
+   TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
+                         decrypt_size <= static_cast<int>(hash_data.size()));
+   hash_data.resize(decrypt_size);
+diff --git a/payload_generator/payload_signer.cc b/payload_generator/payload_signer.cc
+index dd87ab7ae465..795bf886ea5b 100644
+--- a/payload_generator/payload_signer.cc
++++ b/payload_generator/payload_signer.cc
+@@ -309,7 +309,7 @@ bool PayloadSigner::SignHash(const brillo::Blob& hash,
+   int key_type = EVP_PKEY_id(private_key.get());
+   brillo::Blob signature;
+   if (key_type == EVP_PKEY_RSA) {
+-    RSA* rsa = EVP_PKEY_get0_RSA(private_key.get());
++    RSA* rsa = EVP_PKEY_get1_RSA(private_key.get());
+     TEST_AND_RETURN_FALSE(rsa != nullptr);
+ 
+     brillo::Blob padded_hash = hash;
+@@ -324,12 +324,14 @@ bool PayloadSigner::SignHash(const brillo::Blob& hash,
+     if (signature_size < 0) {
+       LOG(ERROR) << "Signing hash failed: "
+                  << ERR_error_string(ERR_get_error(), nullptr);
++      RSA_free(rsa);
+       return false;
+     }
++    RSA_free(rsa);
+     TEST_AND_RETURN_FALSE(static_cast<size_t>(signature_size) ==
+                           signature.size());
+   } else if (key_type == EVP_PKEY_EC) {
+-    EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(private_key.get());
++    EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(private_key.get());
+     TEST_AND_RETURN_FALSE(ec_key != nullptr);
+ 
+     signature.resize(ECDSA_size(ec_key));
+@@ -342,8 +344,10 @@ bool PayloadSigner::SignHash(const brillo::Blob& hash,
+                    ec_key) != 1) {
+       LOG(ERROR) << "Signing hash failed: "
+                  << ERR_error_string(ERR_get_error(), nullptr);
++      EC_KEY_free(ec_key);
+       return false;
+     }
++    EC_KEY_free(ec_key);
+ 
+     // NIST P-256
+     LOG(ERROR) << "signature max size " << signature.size() << " size "
diff --git a/chromeos-base/update_engine/update_engine-0.0.3-r4163.ebuild b/chromeos-base/update_engine/update_engine-0.0.3-r4163.ebuild
index 2a11577..fc3b460 100644
--- a/chromeos-base/update_engine/update_engine-0.0.3-r4163.ebuild
+++ b/chromeos-base/update_engine/update_engine-0.0.3-r4163.ebuild
@@ -74,6 +74,10 @@
 	virtual/update-policy:=
 "
 
+PATCHES=(
+	"${FILESDIR}/${P}-openssl-3.patch"
+)
+
 platform_pkg_test() {
 	local unittests_binary="${OUT}"/update_engine_unittests