diff --git a/scripts/build_ffi.py b/scripts/build_ffi.py index 18caa3a..4d5ad22 100644 --- a/scripts/build_ffi.py +++ b/scripts/build_ffi.py @@ -375,7 +375,7 @@ def get_features(local_wolfssl, features): features["WC_RNG_SEED_CB"] = 1 if '#define WC_RNG_SEED_CB' in defines else 0 features["AESGCM_STREAM"] = 1 if '#define WOLFSSL_AESGCM_STREAM' in defines else 0 features["RSA_PSS"] = 1 if '#define WC_RSA_PSS' in defines else 0 - features["CHACHA20_POLY1305"] = 1 if '#define HAVE_CHACHA' and '#define HAVE_POLY1305' in defines else 0 + features["CHACHA20_POLY1305"] = 1 if ('#define HAVE_CHACHA' in defines and '#define HAVE_POLY1305' in defines) else 0 features["ML_DSA"] = 1 if '#define HAVE_DILITHIUM' in defines else 0 features["ML_KEM"] = 1 if '#define WOLFSSL_HAVE_MLKEM' in defines else 0 features["HKDF"] = 1 if "#define HAVE_HKDF" in defines else 0 @@ -386,7 +386,7 @@ def get_features(local_wolfssl, features): raise RuntimeError(e) features["FIPS"] = 1 - version_match = re.search(r'#define HAVE_FIPS_VERSION\s+(\d+)', defines) + version_match = re.search(r'#define HAVE_FIPS_VERSION\s+(\d+)', '\n'.join(defines)) if version_match is not None: features["FIPS_VERSION"] = int(version_match.group(1)) else: @@ -756,6 +756,8 @@ def build_ffi(local_wolfssl, features): int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, int type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz); + int wc_RsaSSL_Sign(const byte*, word32, byte*, word32, RsaKey*, WC_RNG*); + int wc_RsaSSL_Verify(const byte*, word32, byte*, word32, RsaKey*); """ if features["RSA_PSS"]: @@ -766,8 +768,6 @@ def build_ffi(local_wolfssl, features): enum wc_HashType hash, int mgf, RsaKey* key); int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig, word32 sigSz, enum wc_HashType hashType); - int wc_RsaSSL_Sign(const byte*, word32, byte*, word32, RsaKey*, WC_RNG*); - int wc_RsaSSL_Verify(const byte*, word32, byte*, word32, RsaKey*); """ if features["RSA_BLINDING"]: diff --git a/tests/test_ciphers.py b/tests/test_ciphers.py index ec1ed17..79092e2 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -456,14 +456,14 @@ def test_rsa_pss_sign_verify(rsa_private_pss, rsa_public_pss): signature = rsa_private_pss.sign_pss(plaintext) assert 1024 / 8 == len(signature) == rsa_private_pss.output_size - assert 0 == rsa_public_pss.verify_pss(plaintext, signature) + assert rsa_public_pss.verify_pss(plaintext, signature) is True # private object holds both private and public info, so it can also verify # using the known public key. signature = rsa_private_pss.sign_pss(plaintext) assert 1024 / 8 == len(signature) == rsa_private_pss.output_size - assert 0 == rsa_private_pss.verify_pss(plaintext, signature) + assert rsa_private_pss.verify_pss(plaintext, signature) is True def test_rsa_sign_verify_pem(rsa_private_pem, rsa_public_pem): plaintext = t2b("Everyone gets Friday off.") diff --git a/wolfcrypt/ciphers.py b/wolfcrypt/ciphers.py index 6da9f28..105224e 100644 --- a/wolfcrypt/ciphers.py +++ b/wolfcrypt/ciphers.py @@ -530,8 +530,13 @@ def _decrypt(self, destination, source): return _lib.wc_Chacha_Process(self._dec, destination, source, len(source)) + _NONCE_SIZE = 12 + def set_iv(self, nonce, counter = 0): self._IV_nonce = t2b(nonce) + if len(self._IV_nonce) != self._NONCE_SIZE: + raise ValueError("nonce must be %d bytes, got %d" % + (self._NONCE_SIZE, len(self._IV_nonce))) self._IV_counter = counter self._set_key(0) @@ -811,8 +816,10 @@ def verify_pss(self, plaintext, signature): ret = _lib.wc_RsaPSS_CheckPadding(digest, len(digest), verify, ret, self._hash_type) - return ret + if ret < 0: # pragma: no cover + raise WolfCryptError("PSS padding check error (%d)" % ret) + return ret == 0 class RsaPrivate(RsaPublic): diff --git a/wolfcrypt/hashes.py b/wolfcrypt/hashes.py index 920305b..ef3989e 100644 --- a/wolfcrypt/hashes.py +++ b/wolfcrypt/hashes.py @@ -209,14 +209,7 @@ class Sha3(_Hash): SHA3_384_DIGEST_SIZE = 48 SHA3_512_DIGEST_SIZE = 64 - def __init__(self): # pylint: disable=W0231 - self._native_object = _ffi.new(self._native_type) - self.digest_size = SHA3_384_DIGEST_SIZE - ret = self._init() - if ret < 0: # pragma: no cover - raise WolfCryptError("Sha3 init error (%d)" % ret) - - def __init__(self, string, size=SHA3_384_DIGEST_SIZE): # pylint: disable=W0231 + def __init__(self, string=None, size=SHA3_384_DIGEST_SIZE): # pylint: disable=W0231 self._native_object = _ffi.new(self._native_type) self.digest_size = size ret = self._init() @@ -225,6 +218,15 @@ def __init__(self, string, size=SHA3_384_DIGEST_SIZE): # pylint: disable=W0231 if string: self.update(string) + @classmethod + def new(cls, string=None, size=SHA3_384_DIGEST_SIZE): + return cls(string, size) + + def copy(self): + c = Sha3(size=self.digest_size) + _ffi.memmove(c._native_object, self._native_object, self._native_size) + return c + def _init(self): if (self.digest_size != Sha3.SHA3_224_DIGEST_SIZE and self.digest_size != Sha3.SHA3_256_DIGEST_SIZE and