Skip to content

Commit 5c28f69

Browse files
haydenroche5danielinux
authored andcommitted
Improve the RSA PSS code.
- sign_pss and verify_pss need to digest the data before calling into their respective wolfCrypt functions. Those wolfCrypt functions expect digests, not plaintext. - RsaPrivate make_key should take an optional hash_type parameter for the case where the key will be used to create PSS signatures. - test_rsa_pss_sign_verify appears to have been deliberately coded to have the input plaintext length line up with the digest size, which masked the problem where we weren't digesting the plaintext. I modified the plaintext so that this is no longer the case.
1 parent bf0a4c2 commit 5c28f69

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

tests/test_ciphers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ def test_rsa_sign_verify(rsa_private, rsa_public):
450450

451451
if _lib.RSA_PSS_ENABLED:
452452
def test_rsa_pss_sign_verify(rsa_private_pss, rsa_public_pss):
453-
plaintext = t2b("Everyone gets Friday off yippee.")
453+
plaintext = t2b("Everyone gets Friday off.")
454454

455455
# normal usage, sign with private, verify with public
456456
signature = rsa_private_pss.sign_pss(plaintext)

wolfcrypt/ciphers.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from wolfcrypt.utils import t2b
2626
from wolfcrypt.random import Random
2727
from wolfcrypt.asn import pem_to_der
28+
from wolfcrypt.hashes import hash_type_to_cls
2829

2930
from wolfcrypt.exceptions import WolfCryptError
3031

@@ -597,6 +598,14 @@ def verify_pss(self, plaintext, signature):
597598
598599
Returns a string containing the plaintext.
599600
"""
601+
if not self._hash_type:
602+
raise WolfCryptError(("Hash type not set. Cannot verify a "
603+
"PSS signature without a hash type."))
604+
605+
hash_cls = hash_type_to_cls(self._hash_type)
606+
if not hash_cls:
607+
raise WolfCryptError("Unsupported PSS hash type.")
608+
600609
plaintext = t2b(plaintext)
601610
signature = t2b(signature)
602611
if self._mgf is None:
@@ -610,7 +619,9 @@ def verify_pss(self, plaintext, signature):
610619

611620
if ret < 0: # pragma: no cover
612621
raise WolfCryptError("Verify error (%d)" % ret)
613-
ret = _lib.wc_RsaPSS_CheckPadding(plaintext, len(plaintext),
622+
623+
digest = hash_cls.new(plaintext).digest()
624+
ret = _lib.wc_RsaPSS_CheckPadding(digest, len(digest),
614625
verify, ret, self._hash_type)
615626

616627
return ret
@@ -620,11 +631,11 @@ def verify_pss(self, plaintext, signature):
620631
class RsaPrivate(RsaPublic):
621632
if _lib.KEYGEN_ENABLED:
622633
@classmethod
623-
def make_key(cls, size, rng=Random()):
634+
def make_key(cls, size, rng=Random(), hash_type=None):
624635
"""
625636
Generates a new key pair of desired length **size**.
626637
"""
627-
rsa = cls(None)
638+
rsa = cls(hash_type=hash_type)
628639
if rsa == None: # pragma: no cover
629640
raise WolfCryptError("Invalid key error (%d)" % ret)
630641

@@ -776,11 +787,22 @@ def sign_pss(self, plaintext):
776787
777788
Returns a string containing the signature.
778789
"""
790+
if not self._hash_type:
791+
raise WolfCryptError(("Hash type not set. Cannot verify a "
792+
"PSS signature without a hash type."))
793+
794+
hash_cls = hash_type_to_cls(self._hash_type)
795+
if not hash_cls:
796+
raise WolfCryptError("Unsupported PSS hash type.")
797+
779798
plaintext = t2b(plaintext)
799+
digest = hash_cls.new(plaintext).digest()
800+
780801
signature = _ffi.new("byte[%d]" % self.output_size)
781802
if self._mgf is None:
782803
self._get_mgf()
783-
ret = _lib.wc_RsaPSS_Sign(plaintext, len(plaintext),
804+
805+
ret = _lib.wc_RsaPSS_Sign(digest, len(digest),
784806
signature, self.output_size,
785807
self._hash_type, self._mgf,
786808
self.native_object,

wolfcrypt/hashes.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,17 @@ class HmacSha512(_Hmac):
377377
"""
378378
_type = _TYPE_SHA512
379379
digest_size = Sha512.digest_size
380+
381+
def hash_type_to_cls(hash_type):
382+
if _lib.SHA_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA:
383+
hash_cls = Sha
384+
elif _lib.SHA256_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA256:
385+
hash_cls = Sha256
386+
elif _lib.SHA384_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA384:
387+
hash_cls = Sha384
388+
elif _lib.SHA512_ENABLED and hash_type == _lib.WC_HASH_TYPE_SHA512:
389+
hash_cls = Sha512
390+
else:
391+
hash_cls = None
392+
393+
return hash_cls

0 commit comments

Comments
 (0)