Upgrade cryptography from 2.5 to 3.3

Source code is from https://github.com/pyca/cryptography/tree/3.3.x

Run setup.py locally and rename _openssl.so/_padding.so

Bug: 205265538
Test: None
Change-Id: If031739ef5830ba2fb177add74515e4660e2906e
diff --git a/tests/wycheproof/test_aes.py b/tests/wycheproof/test_aes.py
index 55e4545..9992095 100644
--- a/tests/wycheproof/test_aes.py
+++ b/tests/wycheproof/test_aes.py
@@ -11,9 +11,7 @@
 from cryptography.exceptions import InvalidTag
 from cryptography.hazmat.backends.interfaces import CipherBackend
 from cryptography.hazmat.primitives import padding
-from cryptography.hazmat.primitives.ciphers import (
-    Cipher, algorithms, modes
-)
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
 from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESGCM
 
 from ..hazmat.primitives.test_aead import _aead_supported
@@ -31,8 +29,9 @@
 
     cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend)
     enc = cipher.encryptor()
-    computed_ct = enc.update(
-        padder.update(msg) + padder.finalize()) + enc.finalize()
+    computed_ct = (
+        enc.update(padder.update(msg) + padder.finalize()) + enc.finalize()
+    )
     dec = cipher.decryptor()
     padded_msg = dec.update(ct) + dec.finalize()
     unpadder = padding.PKCS7(128).unpadder()
@@ -55,6 +54,15 @@
     msg = binascii.unhexlify(wycheproof.testcase["msg"])
     ct = binascii.unhexlify(wycheproof.testcase["ct"])
     tag = binascii.unhexlify(wycheproof.testcase["tag"])
+    if len(iv) < 8 or len(iv) > 128:
+        pytest.skip(
+            "Less than 64-bit IVs (and greater than 1024-bit) are no longer "
+            "supported"
+        )
+    if backend._fips_enabled and len(iv) != 12:
+        # Red Hat disables non-96-bit IV support as part of its FIPS
+        # patches.
+        pytest.skip("Non-96-bit IVs unsupported in FIPS mode.")
     if wycheproof.valid or wycheproof.acceptable:
         enc = Cipher(algorithms.AES(key), modes.GCM(iv), backend).encryptor()
         enc.authenticate_additional_data(aad)
@@ -65,19 +73,16 @@
         dec = Cipher(
             algorithms.AES(key),
             modes.GCM(iv, tag, min_tag_length=len(tag)),
-            backend
+            backend,
         ).decryptor()
         dec.authenticate_additional_data(aad)
         computed_msg = dec.update(ct) + dec.finalize()
         assert computed_msg == msg
-    elif len(iv) == 0:
-        with pytest.raises(ValueError):
-            Cipher(algorithms.AES(key), modes.GCM(iv), backend)
     else:
         dec = Cipher(
             algorithms.AES(key),
             modes.GCM(iv, tag, min_tag_length=len(tag)),
-            backend
+            backend,
         ).decryptor()
         dec.authenticate_additional_data(aad)
         dec.update(ct)
@@ -94,15 +99,22 @@
     msg = binascii.unhexlify(wycheproof.testcase["msg"])
     ct = binascii.unhexlify(wycheproof.testcase["ct"])
     tag = binascii.unhexlify(wycheproof.testcase["tag"])
+    if len(iv) < 8 or len(iv) > 128:
+        pytest.skip(
+            "Less than 64-bit IVs (and greater than 1024-bit) are no longer "
+            "supported"
+        )
+
+    if backend._fips_enabled and len(iv) != 12:
+        # Red Hat disables non-96-bit IV support as part of its FIPS
+        # patches.
+        pytest.skip("Non-96-bit IVs unsupported in FIPS mode.")
     aesgcm = AESGCM(key)
     if wycheproof.valid or wycheproof.acceptable:
         computed_ct = aesgcm.encrypt(iv, msg, aad)
         assert computed_ct == ct + tag
         computed_msg = aesgcm.decrypt(iv, ct + tag, aad)
         assert computed_msg == msg
-    elif len(iv) == 0:
-        with pytest.raises(ValueError):
-            aesgcm.encrypt(iv, msg, aad)
     else:
         with pytest.raises(InvalidTag):
             aesgcm.decrypt(iv, ct + tag, aad)
@@ -123,8 +135,8 @@
     tag = binascii.unhexlify(wycheproof.testcase["tag"])
 
     if (
-        wycheproof.invalid and
-        wycheproof.testcase["comment"] == "Invalid tag size"
+        wycheproof.invalid
+        and wycheproof.testcase["comment"] == "Invalid tag size"
     ):
         with pytest.raises(ValueError):
             AESCCM(key, tag_length=wycheproof.testgroup["tagSize"] // 8)
diff --git a/tests/wycheproof/test_chacha20poly1305.py b/tests/wycheproof/test_chacha20poly1305.py
index deef5a0..48023ca 100644
--- a/tests/wycheproof/test_chacha20poly1305.py
+++ b/tests/wycheproof/test_chacha20poly1305.py
@@ -17,7 +17,7 @@
 
 @pytest.mark.skipif(
     not _aead_supported(ChaCha20Poly1305),
-    reason="Requires OpenSSL with ChaCha20Poly1305 support"
+    reason="Requires OpenSSL with ChaCha20Poly1305 support",
 )
 @pytest.mark.requires_backend_interface(interface=CipherBackend)
 @pytest.mark.wycheproof_tests("chacha20_poly1305_test.json")
diff --git a/tests/wycheproof/test_dsa.py b/tests/wycheproof/test_dsa.py
index 3dc3056..9185b3e 100644
--- a/tests/wycheproof/test_dsa.py
+++ b/tests/wycheproof/test_dsa.py
@@ -23,6 +23,10 @@
 @pytest.mark.requires_backend_interface(interface=DSABackend)
 @pytest.mark.wycheproof_tests(
     "dsa_test.json",
+    "dsa_2048_224_sha224_test.json",
+    "dsa_2048_224_sha256_test.json",
+    "dsa_2048_256_sha256_test.json",
+    "dsa_3072_256_sha256_test.json",
 )
 def test_dsa_signature(backend, wycheproof):
     key = serialization.load_der_public_key(
@@ -30,10 +34,8 @@
     )
     digest = _DIGESTS[wycheproof.testgroup["sha"]]
 
-    if (
-        wycheproof.valid or (
-            wycheproof.acceptable and not wycheproof.has_flag("NoLeadingZero")
-        )
+    if wycheproof.valid or (
+        wycheproof.acceptable and not wycheproof.has_flag("NoLeadingZero")
     ):
         key.verify(
             binascii.unhexlify(wycheproof.testcase["sig"]),
diff --git a/tests/wycheproof/test_ecdh.py b/tests/wycheproof/test_ecdh.py
index 5fcc45b..b89dc68 100644
--- a/tests/wycheproof/test_ecdh.py
+++ b/tests/wycheproof/test_ecdh.py
@@ -21,6 +21,7 @@
     "secp256r1": ec.SECP256R1(),
     "secp384r1": ec.SECP384R1(),
     "secp521r1": ec.SECP521R1(),
+    "secp224k1": None,
     "secp256k1": ec.SECP256K1(),
     "brainpoolP224r1": None,
     "brainpoolP256r1": ec.BrainpoolP256R1(),
diff --git a/tests/wycheproof/test_ecdsa.py b/tests/wycheproof/test_ecdsa.py
index 5214052..802bb9f 100644
--- a/tests/wycheproof/test_ecdsa.py
+++ b/tests/wycheproof/test_ecdsa.py
@@ -20,6 +20,10 @@
     "SHA-256": hashes.SHA256(),
     "SHA-384": hashes.SHA384(),
     "SHA-512": hashes.SHA512(),
+    "SHA3-224": hashes.SHA3_224(),
+    "SHA3-256": hashes.SHA3_256(),
+    "SHA3-384": hashes.SHA3_384(),
+    "SHA3-512": hashes.SHA3_512(),
 }
 
 
@@ -34,13 +38,23 @@
     "ecdsa_secp224r1_sha224_test.json",
     "ecdsa_secp224r1_sha256_test.json",
     "ecdsa_secp224r1_sha512_test.json",
+    "ecdsa_secp224r1_sha3_224_test.json",
+    "ecdsa_secp224r1_sha3_256_test.json",
+    "ecdsa_secp224r1_sha3_512_test.json",
     "ecdsa_secp256k1_sha256_test.json",
     "ecdsa_secp256k1_sha512_test.json",
+    "ecdsa_secp256k1_sha3_256_test.json",
+    "ecdsa_secp256k1_sha3_512_test.json",
     "ecdsa_secp256r1_sha256_test.json",
     "ecdsa_secp256r1_sha512_test.json",
+    "ecdsa_secp256r1_sha3_256_test.json",
+    "ecdsa_secp256r1_sha3_512_test.json",
     "ecdsa_secp384r1_sha384_test.json",
     "ecdsa_secp384r1_sha512_test.json",
+    "ecdsa_secp384r1_sha3_384_test.json",
+    "ecdsa_secp384r1_sha3_512_test.json",
     "ecdsa_secp521r1_sha512_test.json",
+    "ecdsa_secp521r1_sha3_512_test.json",
 )
 def test_ecdsa_signature(backend, wycheproof):
     try:
@@ -48,9 +62,9 @@
             binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend
         )
     except (UnsupportedAlgorithm, ValueError):
-        # In OpenSSL 1.0.1, some keys fail to load with ValueError, instead of
-        # Unsupported Algorithm. We can remove handling for that exception
-        # when we drop support.
+        # In some OpenSSL 1.0.2s, some keys fail to load with ValueError,
+        # instead of  Unsupported Algorithm. We can remove handling for that
+        # exception when we drop support.
         pytest.skip(
             "unable to load key (curve {})".format(
                 wycheproof.testgroup["key"]["curve"]
@@ -58,9 +72,11 @@
         )
     digest = _DIGESTS[wycheproof.testgroup["sha"]]
 
-    if (
-        wycheproof.valid or
-        (wycheproof.acceptable and not wycheproof.has_flag("MissingZero"))
+    if not backend.hash_supported(digest):
+        pytest.skip("Hash {} not supported".format(digest))
+
+    if wycheproof.valid or (
+        wycheproof.acceptable and not wycheproof.has_flag("MissingZero")
     ):
         key.verify(
             binascii.unhexlify(wycheproof.testcase["sig"]),
diff --git a/tests/wycheproof/test_eddsa.py b/tests/wycheproof/test_eddsa.py
new file mode 100644
index 0000000..42c1498
--- /dev/null
+++ b/tests/wycheproof/test_eddsa.py
@@ -0,0 +1,63 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+
+import pytest
+
+from cryptography.exceptions import InvalidSignature
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
+from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PublicKey
+
+
+@pytest.mark.supported(
+    only_if=lambda backend: backend.ed25519_supported(),
+    skip_message="Requires OpenSSL with Ed25519 support",
+)
+@pytest.mark.wycheproof_tests("eddsa_test.json")
+def test_ed25519_signature(backend, wycheproof):
+    # We want to fail if/when wycheproof adds more edwards curve tests
+    # so we can add them as well.
+    assert wycheproof.testgroup["key"]["curve"] == "edwards25519"
+
+    key = Ed25519PublicKey.from_public_bytes(
+        binascii.unhexlify(wycheproof.testgroup["key"]["pk"])
+    )
+
+    if wycheproof.valid or wycheproof.acceptable:
+        key.verify(
+            binascii.unhexlify(wycheproof.testcase["sig"]),
+            binascii.unhexlify(wycheproof.testcase["msg"]),
+        )
+    else:
+        with pytest.raises(InvalidSignature):
+            key.verify(
+                binascii.unhexlify(wycheproof.testcase["sig"]),
+                binascii.unhexlify(wycheproof.testcase["msg"]),
+            )
+
+
+@pytest.mark.supported(
+    only_if=lambda backend: backend.ed448_supported(),
+    skip_message="Requires OpenSSL with Ed448 support",
+)
+@pytest.mark.wycheproof_tests("ed448_test.json")
+def test_ed448_signature(backend, wycheproof):
+    key = Ed448PublicKey.from_public_bytes(
+        binascii.unhexlify(wycheproof.testgroup["key"]["pk"])
+    )
+
+    if wycheproof.valid or wycheproof.acceptable:
+        key.verify(
+            binascii.unhexlify(wycheproof.testcase["sig"]),
+            binascii.unhexlify(wycheproof.testcase["msg"]),
+        )
+    else:
+        with pytest.raises(InvalidSignature):
+            key.verify(
+                binascii.unhexlify(wycheproof.testcase["sig"]),
+                binascii.unhexlify(wycheproof.testcase["msg"]),
+            )
diff --git a/tests/wycheproof/test_hkdf.py b/tests/wycheproof/test_hkdf.py
new file mode 100644
index 0000000..3e1687e
--- /dev/null
+++ b/tests/wycheproof/test_hkdf.py
@@ -0,0 +1,50 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+
+import pytest
+
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.kdf.hkdf import HKDF
+
+
+_HASH_ALGORITHMS = {
+    "HKDF-SHA-1": hashes.SHA1(),
+    "HKDF-SHA-256": hashes.SHA256(),
+    "HKDF-SHA-384": hashes.SHA384(),
+    "HKDF-SHA-512": hashes.SHA512(),
+}
+
+
+@pytest.mark.wycheproof_tests(
+    "hkdf_sha1_test.json",
+    "hkdf_sha256_test.json",
+    "hkdf_sha384_test.json",
+    "hkdf_sha512_test.json",
+)
+def test_hkdf(backend, wycheproof):
+    hash_algo = _HASH_ALGORITHMS[wycheproof.testfiledata["algorithm"]]
+    if wycheproof.invalid:
+        with pytest.raises(ValueError):
+            HKDF(
+                algorithm=hash_algo,
+                length=wycheproof.testcase["size"],
+                salt=binascii.unhexlify(wycheproof.testcase["salt"]),
+                info=binascii.unhexlify(wycheproof.testcase["info"]),
+                backend=backend,
+            )
+        return
+
+    h = HKDF(
+        algorithm=hash_algo,
+        length=wycheproof.testcase["size"],
+        salt=binascii.unhexlify(wycheproof.testcase["salt"]),
+        info=binascii.unhexlify(wycheproof.testcase["info"]),
+        backend=backend,
+    )
+    result = h.derive(binascii.unhexlify(wycheproof.testcase["ikm"]))
+    assert result == binascii.unhexlify(wycheproof.testcase["okm"])
diff --git a/tests/wycheproof/test_hmac.py b/tests/wycheproof/test_hmac.py
new file mode 100644
index 0000000..0cf908f
--- /dev/null
+++ b/tests/wycheproof/test_hmac.py
@@ -0,0 +1,66 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+
+import pytest
+
+from cryptography.exceptions import InvalidSignature
+from cryptography.hazmat.primitives import hashes, hmac
+
+
+_HMAC_ALGORITHMS = {
+    "HMACSHA1": hashes.SHA1(),
+    "HMACSHA224": hashes.SHA224(),
+    "HMACSHA256": hashes.SHA256(),
+    "HMACSHA384": hashes.SHA384(),
+    "HMACSHA512": hashes.SHA512(),
+    "HMACSHA3-224": hashes.SHA3_224(),
+    "HMACSHA3-256": hashes.SHA3_256(),
+    "HMACSHA3-384": hashes.SHA3_384(),
+    "HMACSHA3-512": hashes.SHA3_512(),
+}
+
+
+@pytest.mark.wycheproof_tests(
+    "hmac_sha1_test.json",
+    "hmac_sha224_test.json",
+    "hmac_sha256_test.json",
+    "hmac_sha384_test.json",
+    "hmac_sha3_224_test.json",
+    "hmac_sha3_256_test.json",
+    "hmac_sha3_384_test.json",
+    "hmac_sha3_512_test.json",
+    "hmac_sha512_test.json",
+)
+def test_hmac(backend, wycheproof):
+    hash_algo = _HMAC_ALGORITHMS[wycheproof.testfiledata["algorithm"]]
+    if wycheproof.testgroup["tagSize"] // 8 != hash_algo.digest_size:
+        pytest.skip("Truncated HMAC not supported")
+    if not backend.hash_supported(hash_algo):
+        pytest.skip("Hash {} not supported".format(hash_algo.name))
+
+    h = hmac.HMAC(
+        key=binascii.unhexlify(wycheproof.testcase["key"]),
+        algorithm=hash_algo,
+        backend=backend,
+    )
+    h.update(binascii.unhexlify(wycheproof.testcase["msg"]))
+
+    if wycheproof.invalid:
+        with pytest.raises(InvalidSignature):
+            h.verify(binascii.unhexlify(wycheproof.testcase["tag"]))
+    else:
+        tag = h.finalize()
+        assert tag == binascii.unhexlify(wycheproof.testcase["tag"])
+
+        h = hmac.HMAC(
+            key=binascii.unhexlify(wycheproof.testcase["key"]),
+            algorithm=hash_algo,
+            backend=backend,
+        )
+        h.update(binascii.unhexlify(wycheproof.testcase["msg"]))
+        h.verify(binascii.unhexlify(wycheproof.testcase["tag"]))
diff --git a/tests/wycheproof/test_keywrap.py b/tests/wycheproof/test_keywrap.py
index 5f694e4..9c7d522 100644
--- a/tests/wycheproof/test_keywrap.py
+++ b/tests/wycheproof/test_keywrap.py
@@ -44,11 +44,9 @@
     key_to_wrap = binascii.unhexlify(wycheproof.testcase["msg"])
     expected = binascii.unhexlify(wycheproof.testcase["ct"])
 
-    if (
-        wycheproof.valid or (
-            wycheproof.acceptable and
-            wycheproof.testcase["comment"] != "invalid size of wrapped key"
-        )
+    if wycheproof.valid or (
+        wycheproof.acceptable
+        and wycheproof.testcase["comment"] != "invalid size of wrapped key"
     ):
         result = keywrap.aes_key_wrap(wrapping_key, key_to_wrap, backend)
         assert result == expected
diff --git a/tests/wycheproof/test_rsa.py b/tests/wycheproof/test_rsa.py
index 3d35f42..926bb44 100644
--- a/tests/wycheproof/test_rsa.py
+++ b/tests/wycheproof/test_rsa.py
@@ -20,6 +20,13 @@
     "SHA-256": hashes.SHA256(),
     "SHA-384": hashes.SHA384(),
     "SHA-512": hashes.SHA512(),
+    # Not supported by OpenSSL for RSA signing
+    "SHA-512/224": None,
+    "SHA-512/256": None,
+    "SHA3-224": hashes.SHA3_224(),
+    "SHA3-256": hashes.SHA3_256(),
+    "SHA3-384": hashes.SHA3_384(),
+    "SHA3-512": hashes.SHA3_512(),
 }
 
 
@@ -28,39 +35,34 @@
         return True
 
     if wycheproof.acceptable:
-        if (
-            backend._lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER and
-            wycheproof.has_flag("MissingNull")
-        ):
-            return False
-        return True
+        return not wycheproof.has_flag("MissingNull")
 
     return False
 
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
-@pytest.mark.supported(
-    only_if=lambda backend: (
-        # TODO: this also skips on LibreSSL, which is ok for now, since these
-        # don't pass on Libre, but we'll need to fix this when LibreSSL 2.8 is
-        # released.
-        not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102
-    ),
-    skip_message=(
-        "Many of these tests fail on OpenSSL < 1.0.2 and since upstream isn't"
-        " maintaining it, they'll never be fixed."
-    ),
-)
 @pytest.mark.wycheproof_tests(
     "rsa_signature_test.json",
     "rsa_signature_2048_sha224_test.json",
     "rsa_signature_2048_sha256_test.json",
+    "rsa_signature_2048_sha384_test.json",
     "rsa_signature_2048_sha512_test.json",
+    "rsa_signature_2048_sha512_224_test.json",
+    "rsa_signature_2048_sha512_256_test.json",
+    "rsa_signature_2048_sha3_224_test.json",
+    "rsa_signature_2048_sha3_256_test.json",
+    "rsa_signature_2048_sha3_384_test.json",
+    "rsa_signature_2048_sha3_512_test.json",
     "rsa_signature_3072_sha256_test.json",
     "rsa_signature_3072_sha384_test.json",
     "rsa_signature_3072_sha512_test.json",
+    "rsa_signature_3072_sha512_256_test.json",
+    "rsa_signature_3072_sha3_256_test.json",
+    "rsa_signature_3072_sha3_384_test.json",
+    "rsa_signature_3072_sha3_512_test.json",
     "rsa_signature_4096_sha384_test.json",
     "rsa_signature_4096_sha512_test.json",
+    "rsa_signature_4096_sha512_256_test.json",
 )
 def test_rsa_pkcs1v15_signature(backend, wycheproof):
     key = serialization.load_der_public_key(
@@ -68,6 +70,11 @@
     )
     digest = _DIGESTS[wycheproof.testgroup["sha"]]
 
+    if digest is None or not backend.hash_supported(digest):
+        pytest.skip(
+            "Hash {} not supported".format(wycheproof.testgroup["sha"])
+        )
+
     if should_verify(backend, wycheproof):
         key.verify(
             binascii.unhexlify(wycheproof.testcase["sig"]),
@@ -85,11 +92,30 @@
             )
 
 
+@pytest.mark.wycheproof_tests("rsa_sig_gen_misc_test.json")
+def test_rsa_pkcs1v15_signature_generation(backend, wycheproof):
+    key = serialization.load_pem_private_key(
+        wycheproof.testgroup["privateKeyPem"].encode(),
+        password=None,
+        backend=backend,
+    )
+    digest = _DIGESTS[wycheproof.testgroup["sha"]]
+
+    sig = key.sign(
+        binascii.unhexlify(wycheproof.testcase["msg"]),
+        padding.PKCS1v15(),
+        digest,
+    )
+    assert sig == binascii.unhexlify(wycheproof.testcase["sig"])
+
+
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.wycheproof_tests(
     "rsa_pss_2048_sha1_mgf1_20_test.json",
     "rsa_pss_2048_sha256_mgf1_0_test.json",
     "rsa_pss_2048_sha256_mgf1_32_test.json",
+    "rsa_pss_2048_sha512_256_mgf1_28_test.json",
+    "rsa_pss_2048_sha512_256_mgf1_32_test.json",
     "rsa_pss_3072_sha256_mgf1_32_test.json",
     "rsa_pss_4096_sha256_mgf1_32_test.json",
     "rsa_pss_4096_sha512_mgf1_32_test.json",
@@ -102,15 +128,23 @@
     digest = _DIGESTS[wycheproof.testgroup["sha"]]
     mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]]
 
+    if digest is None or mgf_digest is None:
+        pytest.skip(
+            "PSS with digest={} and MGF digest={} not supported".format(
+                wycheproof.testgroup["sha"],
+                wycheproof.testgroup["mgfSha"],
+            )
+        )
+
     if wycheproof.valid or wycheproof.acceptable:
         key.verify(
             binascii.unhexlify(wycheproof.testcase["sig"]),
             binascii.unhexlify(wycheproof.testcase["msg"]),
             padding.PSS(
                 mgf=padding.MGF1(mgf_digest),
-                salt_length=wycheproof.testgroup["sLen"]
+                salt_length=wycheproof.testgroup["sLen"],
             ),
-            digest
+            digest,
         )
     else:
         with pytest.raises(InvalidSignature):
@@ -119,7 +153,88 @@
                 binascii.unhexlify(wycheproof.testcase["msg"]),
                 padding.PSS(
                     mgf=padding.MGF1(mgf_digest),
-                    salt_length=wycheproof.testgroup["sLen"]
+                    salt_length=wycheproof.testgroup["sLen"],
                 ),
-                digest
+                digest,
+            )
+
+
+@pytest.mark.requires_backend_interface(interface=RSABackend)
+@pytest.mark.wycheproof_tests(
+    "rsa_oaep_2048_sha1_mgf1sha1_test.json",
+    "rsa_oaep_2048_sha224_mgf1sha1_test.json",
+    "rsa_oaep_2048_sha224_mgf1sha224_test.json",
+    "rsa_oaep_2048_sha256_mgf1sha1_test.json",
+    "rsa_oaep_2048_sha256_mgf1sha256_test.json",
+    "rsa_oaep_2048_sha384_mgf1sha1_test.json",
+    "rsa_oaep_2048_sha384_mgf1sha384_test.json",
+    "rsa_oaep_2048_sha512_mgf1sha1_test.json",
+    "rsa_oaep_2048_sha512_mgf1sha512_test.json",
+    "rsa_oaep_3072_sha256_mgf1sha1_test.json",
+    "rsa_oaep_3072_sha256_mgf1sha256_test.json",
+    "rsa_oaep_3072_sha512_mgf1sha1_test.json",
+    "rsa_oaep_3072_sha512_mgf1sha512_test.json",
+    "rsa_oaep_4096_sha256_mgf1sha1_test.json",
+    "rsa_oaep_4096_sha256_mgf1sha256_test.json",
+    "rsa_oaep_4096_sha512_mgf1sha1_test.json",
+    "rsa_oaep_4096_sha512_mgf1sha512_test.json",
+    "rsa_oaep_misc_test.json",
+)
+def test_rsa_oaep_encryption(backend, wycheproof):
+    key = serialization.load_pem_private_key(
+        wycheproof.testgroup["privateKeyPem"].encode("ascii"),
+        password=None,
+        backend=backend,
+    )
+    digest = _DIGESTS[wycheproof.testgroup["sha"]]
+    mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]]
+
+    padding_algo = padding.OAEP(
+        mgf=padding.MGF1(algorithm=mgf_digest),
+        algorithm=digest,
+        label=binascii.unhexlify(wycheproof.testcase["label"]),
+    )
+
+    if not backend.rsa_padding_supported(padding_algo):
+        pytest.skip(
+            "OAEP with digest={} and MGF digest={} not supported".format(
+                wycheproof.testgroup["sha"],
+                wycheproof.testgroup["mgfSha"],
+            )
+        )
+
+    if wycheproof.valid or wycheproof.acceptable:
+        pt = key.decrypt(
+            binascii.unhexlify(wycheproof.testcase["ct"]), padding_algo
+        )
+        assert pt == binascii.unhexlify(wycheproof.testcase["msg"])
+    else:
+        with pytest.raises(ValueError):
+            key.decrypt(
+                binascii.unhexlify(wycheproof.testcase["ct"]), padding_algo
+            )
+
+
+@pytest.mark.wycheproof_tests(
+    "rsa_pkcs1_2048_test.json",
+    "rsa_pkcs1_3072_test.json",
+    "rsa_pkcs1_4096_test.json",
+)
+def test_rsa_pkcs1_encryption(backend, wycheproof):
+    key = serialization.load_pem_private_key(
+        wycheproof.testgroup["privateKeyPem"].encode("ascii"),
+        password=None,
+        backend=backend,
+    )
+
+    if wycheproof.valid:
+        pt = key.decrypt(
+            binascii.unhexlify(wycheproof.testcase["ct"]), padding.PKCS1v15()
+        )
+        assert pt == binascii.unhexlify(wycheproof.testcase["msg"])
+    else:
+        with pytest.raises(ValueError):
+            key.decrypt(
+                binascii.unhexlify(wycheproof.testcase["ct"]),
+                padding.PKCS1v15(),
             )
diff --git a/tests/wycheproof/test_utils.py b/tests/wycheproof/test_utils.py
index 82c0a35..593d26b 100644
--- a/tests/wycheproof/test_utils.py
+++ b/tests/wycheproof/test_utils.py
@@ -4,18 +4,9 @@
 
 from __future__ import absolute_import, division, print_function
 
-import pytest
-
-from ..utils import WycheproofTest, skip_if_wycheproof_none
+from ..utils import WycheproofTest
 
 
 def test_wycheproof_test_repr():
-    wycheproof = WycheproofTest({}, {"tcId": 3})
-    assert repr(wycheproof) == "<WycheproofTest({}, {'tcId': 3}, tcId=3)>"
-
-
-def test_skip_if_wycheproof_none():
-    with pytest.raises(pytest.skip.Exception):
-        skip_if_wycheproof_none(None)
-
-    skip_if_wycheproof_none("abc")
+    wycheproof = WycheproofTest({}, {}, {"tcId": 3})
+    assert repr(wycheproof) == "<WycheproofTest({}, {}, {'tcId': 3}, tcId=3)>"
diff --git a/tests/wycheproof/test_x25519.py b/tests/wycheproof/test_x25519.py
index 0727ec3..ce2a965 100644
--- a/tests/wycheproof/test_x25519.py
+++ b/tests/wycheproof/test_x25519.py
@@ -8,20 +8,22 @@
 
 import pytest
 
-from cryptography.hazmat.backends.interfaces import DHBackend
 from cryptography.hazmat.primitives.asymmetric.x25519 import (
-    X25519PrivateKey, X25519PublicKey
+    X25519PrivateKey,
+    X25519PublicKey,
 )
 
 
 @pytest.mark.supported(
     only_if=lambda backend: backend.x25519_supported(),
-    skip_message="Requires OpenSSL with X25519 support"
+    skip_message="Requires OpenSSL with X25519 support",
 )
-@pytest.mark.requires_backend_interface(interface=DHBackend)
 @pytest.mark.wycheproof_tests("x25519_test.json")
 def test_x25519(backend, wycheproof):
-    assert list(wycheproof.testgroup.items()) == [("curve", "curve25519")]
+    assert set(wycheproof.testgroup.items()) == {
+        ("curve", "curve25519"),
+        ("type", "XdhComp"),
+    }
 
     private_key = X25519PrivateKey.from_private_bytes(
         binascii.unhexlify(wycheproof.testcase["private"])
diff --git a/tests/wycheproof/test_x448.py b/tests/wycheproof/test_x448.py
new file mode 100644
index 0000000..fcac809
--- /dev/null
+++ b/tests/wycheproof/test_x448.py
@@ -0,0 +1,50 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+
+import pytest
+
+from cryptography.hazmat.primitives.asymmetric.x448 import (
+    X448PrivateKey,
+    X448PublicKey,
+)
+
+
+@pytest.mark.supported(
+    only_if=lambda backend: backend.x448_supported(),
+    skip_message="Requires OpenSSL with X448 support",
+)
+@pytest.mark.wycheproof_tests("x448_test.json")
+def test_x448(backend, wycheproof):
+    assert set(wycheproof.testgroup.items()) == {
+        ("curve", "curve448"),
+        ("type", "XdhComp"),
+    }
+
+    private_key = X448PrivateKey.from_private_bytes(
+        binascii.unhexlify(wycheproof.testcase["private"])
+    )
+    public_key_bytes = binascii.unhexlify(wycheproof.testcase["public"])
+    if len(public_key_bytes) == 57:
+        assert wycheproof.acceptable
+        assert wycheproof.has_flag("NonCanonicalPublic")
+        with pytest.raises(ValueError):
+            X448PublicKey.from_public_bytes(public_key_bytes)
+        return
+
+    public_key = X448PublicKey.from_public_bytes(public_key_bytes)
+
+    assert wycheproof.valid or wycheproof.acceptable
+
+    expected = binascii.unhexlify(wycheproof.testcase["shared"])
+    if expected == b"\x00" * 56:
+        assert wycheproof.acceptable
+        # OpenSSL returns an error on all zeros shared key
+        with pytest.raises(ValueError):
+            private_key.exchange(public_key)
+    else:
+        assert private_key.exchange(public_key) == expected