diff --git a/tests/test_ciphers.py b/tests/test_ciphers.py index 3151e1c..733a489 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -450,7 +450,7 @@ if _lib.RSA_ENABLED: if _lib.RSA_PSS_ENABLED: def test_rsa_pss_sign_verify(rsa_private_pss, rsa_public_pss): - plaintext = t2b("Everyone gets Friday off yippee.") + plaintext = t2b("Everyone gets Friday off.") # normal usage, sign with private, verify with public signature = rsa_private_pss.sign_pss(plaintext) diff --git a/wolfcrypt/ciphers.py b/wolfcrypt/ciphers.py index 005cf3f..6462069 100644 --- a/wolfcrypt/ciphers.py +++ b/wolfcrypt/ciphers.py @@ -25,6 +25,7 @@ from wolfcrypt._ffi import lib as _lib from wolfcrypt.utils import t2b from wolfcrypt.random import Random from wolfcrypt.asn import pem_to_der +from wolfcrypt.hashes import hash_type_to_cls from wolfcrypt.exceptions import WolfCryptError @@ -597,6 +598,14 @@ if _lib.RSA_ENABLED: Returns a string containing the plaintext. """ + if not self._hash_type: + raise WolfCryptError(("Hash type not set. Cannot verify a " + "PSS signature without a hash type.")) + + hash_cls = hash_type_to_cls(self._hash_type) + if not hash_cls: + raise WolfCryptError("Unsupported PSS hash type.") + plaintext = t2b(plaintext) signature = t2b(signature) if self._mgf is None: @@ -610,7 +619,9 @@ if _lib.RSA_ENABLED: if ret < 0: # pragma: no cover raise WolfCryptError("Verify error (%d)" % ret) - ret = _lib.wc_RsaPSS_CheckPadding(plaintext, len(plaintext), + + digest = hash_cls.new(plaintext).digest() + ret = _lib.wc_RsaPSS_CheckPadding(digest, len(digest), verify, ret, self._hash_type) return ret @@ -620,11 +631,11 @@ if _lib.RSA_ENABLED: class RsaPrivate(RsaPublic): if _lib.KEYGEN_ENABLED: @classmethod - def make_key(cls, size, rng=Random()): + def make_key(cls, size, rng=Random(), hash_type=None): """ Generates a new key pair of desired length **size**. """ - rsa = cls(None) + rsa = cls(hash_type=hash_type) if rsa == None: # pragma: no cover raise WolfCryptError("Invalid key error (%d)" % ret) @@ -776,11 +787,22 @@ if _lib.RSA_ENABLED: Returns a string containing the signature. """ + if not self._hash_type: + raise WolfCryptError(("Hash type not set. Cannot verify a " + "PSS signature without a hash type.")) + + hash_cls = hash_type_to_cls(self._hash_type) + if not hash_cls: + raise WolfCryptError("Unsupported PSS hash type.") + plaintext = t2b(plaintext) + digest = hash_cls.new(plaintext).digest() + signature = _ffi.new("byte[%d]" % self.output_size) if self._mgf is None: self._get_mgf() - ret = _lib.wc_RsaPSS_Sign(plaintext, len(plaintext), + + ret = _lib.wc_RsaPSS_Sign(digest, len(digest), signature, self.output_size, self._hash_type, self._mgf, self.native_object, diff --git a/wolfcrypt/hashes.py b/wolfcrypt/hashes.py index cd7f963..920305b 100644 --- a/wolfcrypt/hashes.py +++ b/wolfcrypt/hashes.py @@ -377,3 +377,17 @@ if _lib.HMAC_ENABLED: """ _type = _TYPE_SHA512 digest_size = Sha512.digest_size + +def hash_type_to_cls(hash_type): + if _lib.SHA_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA: + hash_cls = Sha + elif _lib.SHA256_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA256: + hash_cls = Sha256 + elif _lib.SHA384_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA384: + hash_cls = Sha384 + elif _lib.SHA512_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA512: + hash_cls = Sha512 + else: + hash_cls = None + + return hash_cls