diff --git a/Makefile b/Makefile index 3abe20e..56320e7 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ clean-test: ## remove test and coverage artifacts rm -fr htmlcov/ lint: ## check style with flake8 - flake8 wolfcrypt tests + flake8 src tests test: ## run tests quickly with the default Python py.test tests diff --git a/src/wolfcrypt/_build_wolfssl.py b/src/wolfcrypt/_build_wolfssl.py index fafd489..a3428e8 100644 --- a/src/wolfcrypt/_build_wolfssl.py +++ b/src/wolfcrypt/_build_wolfssl.py @@ -87,7 +87,7 @@ def checkout_version(version): call("git checkout --force {}".format(version)) - return True # rebuild needed + return True # rebuild needed return False diff --git a/src/wolfcrypt/ciphers.py b/src/wolfcrypt/ciphers.py index 304232c..b7ae17f 100644 --- a/src/wolfcrypt/ciphers.py +++ b/src/wolfcrypt/ciphers.py @@ -17,25 +17,26 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -from wolfcrypt._ffi import ffi as _ffi -from wolfcrypt._ffi import lib as _lib -from wolfcrypt.utils import t2b + +from wolfcrypt._ffi import ffi as _ffi +from wolfcrypt._ffi import lib as _lib +from wolfcrypt.utils import t2b from wolfcrypt.random import Random -from wolfcrypt.exceptions import * +from wolfcrypt.exceptions import WolfCryptError # key direction flags -_ENCRYPTION = 0 -_DECRYPTION = 1 +_ENCRYPTION = 0 +_DECRYPTION = 1 # feedback modes -MODE_ECB = 1 # Electronic Code Book -MODE_CBC = 2 # Cipher Block Chaining -MODE_CFB = 3 # Cipher Feedback -MODE_OFB = 5 # Output Feedback -MODE_CTR = 6 # Counter +MODE_ECB = 1 # Electronic Code Book +MODE_CBC = 2 # Cipher Block Chaining +MODE_CFB = 3 # Cipher Feedback +MODE_OFB = 5 # Output Feedback +MODE_CTR = 6 # Counter _FEEDBACK_MODES = [MODE_ECB, MODE_CBC, MODE_CFB, MODE_OFB, MODE_CTR] @@ -78,7 +79,6 @@ class _Cipher(object): else: self._IV = _ffi.new('byte[%d]' % self.block_size) - @classmethod def new(cls, key, mode, IV=None, **kwargs): """ @@ -93,7 +93,6 @@ class _Cipher(object): """ return cls(key, mode, IV) - def encrypt(self, string): """ Encrypts a non-empty string, using the key-dependent data in @@ -121,7 +120,6 @@ class _Cipher(object): return _ffi.buffer(result)[:] - def decrypt(self, string): """ Decrypts **string**, using the key-dependent data in the @@ -155,12 +153,11 @@ class Aes(_Cipher): The **Advanced Encryption Standard** (AES), a.k.a. Rijndael, is a symmetric-key cipher standardized by **NIST**. """ - block_size = 16 - key_size = None # 16, 24, 32 - _key_sizes = [16, 24, 32] + block_size = 16 + key_size = None # 16, 24, 32 + _key_sizes = [16, 24, 32] _native_type = "Aes *" - def _set_key(self, direction): if direction == _ENCRYPTION: return _lib.wc_AesSetKey( @@ -169,13 +166,13 @@ class Aes(_Cipher): return _lib.wc_AesSetKey( self._dec, self._key, len(self._key), self._IV, _DECRYPTION) - def _encrypt(self, destination, source): - return _lib.wc_AesCbcEncrypt(self._enc, destination, source,len(source)) - + return _lib.wc_AesCbcEncrypt(self._enc, destination, + source, len(source)) def _decrypt(self, destination, source): - return _lib.wc_AesCbcDecrypt(self._dec, destination, source,len(source)) + return _lib.wc_AesCbcDecrypt(self._dec, destination, + source, len(source)) class Des3(_Cipher): @@ -185,24 +182,25 @@ class Des3(_Cipher): cipher, which applies the **Data Encryption Standard** (DES) cipher algorithm three times to each data block. """ - block_size = 8 - key_size = 24 + block_size = 8 + key_size = 24 _native_type = "Des3 *" - def _set_key(self, direction): if direction == _ENCRYPTION: - return _lib.wc_Des3_SetKey(self._enc,self._key,self._IV,_ENCRYPTION) + return _lib.wc_Des3_SetKey(self._enc, self._key, + self._IV, _ENCRYPTION) else: - return _lib.wc_Des3_SetKey(self._dec,self._key,self._IV,_DECRYPTION) - + return _lib.wc_Des3_SetKey(self._dec, self._key, + self._IV, _DECRYPTION) def _encrypt(self, destination, source): - return _lib.wc_Des3_CbcEncrypt(self._enc,destination,source,len(source)) - + return _lib.wc_Des3_CbcEncrypt(self._enc, destination, + source, len(source)) def _decrypt(self, destination, source): - return _lib.wc_Des3_CbcDecrypt(self._dec,destination,source,len(source)) + return _lib.wc_Des3_CbcDecrypt(self._dec, destination, + source, len(source)) class _Rsa(object): @@ -219,7 +217,6 @@ class _Rsa(object): if ret < 0: raise WolfCryptError("Key initialization error (%d)" % ret) - def __del__(self): if self.native_object: _lib.wc_FreeRsaKey(self.native_object) @@ -234,7 +231,8 @@ class RsaPublic(_Rsa): idx = _ffi.new("word32*") idx[0] = 0 - ret = _lib.wc_RsaPublicKeyDecode(key, idx, self.native_object, len(key)) + ret = _lib.wc_RsaPublicKeyDecode(key, idx, + self.native_object, len(key)) if ret < 0: raise WolfCryptError("Invalid key error (%d)" % ret) @@ -242,7 +240,6 @@ class RsaPublic(_Rsa): if self.output_size <= 0: raise WolfCryptError("Invalid key error (%d)" % self.output_size) - def encrypt(self, plaintext): """ Encrypts **plaintext**, using the public key data in the @@ -266,7 +263,6 @@ class RsaPublic(_Rsa): return _ffi.buffer(ciphertext)[:] - def verify(self, signature): """ Verifies **signature**, using the public key data in the @@ -298,7 +294,8 @@ class RsaPrivate(RsaPublic): idx = _ffi.new("word32*") idx[0] = 0 - ret = _lib.wc_RsaPrivateKeyDecode(key, idx, self.native_object,len(key)) + ret = _lib.wc_RsaPrivateKeyDecode(key, idx, + self.native_object, len(key)) if ret < 0: raise WolfCryptError("Invalid key error (%d)" % ret) @@ -306,7 +303,6 @@ class RsaPrivate(RsaPublic): if self.output_size <= 0: raise WolfCryptError("Invalid key error (%d)" % self.output_size) - def decrypt(self, ciphertext): """ Decrypts **ciphertext**, using the private key data in the @@ -328,7 +324,6 @@ class RsaPrivate(RsaPublic): return _ffi.buffer(plaintext, ret)[:] - def sign(self, plaintext): """ Signs **plaintext**, using the private key data in the object. diff --git a/src/wolfcrypt/hashes.py b/src/wolfcrypt/hashes.py index 75a4379..fbfa9f8 100644 --- a/src/wolfcrypt/hashes.py +++ b/src/wolfcrypt/hashes.py @@ -17,11 +17,13 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -from wolfcrypt._ffi import ffi as _ffi -from wolfcrypt._ffi import lib as _lib + +from wolfcrypt._ffi import ffi as _ffi +from wolfcrypt._ffi import lib as _lib from wolfcrypt.utils import t2b, b2h -from wolfcrypt.exceptions import * +from wolfcrypt.exceptions import WolfCryptError + class _Hash(object): """ @@ -37,7 +39,6 @@ class _Hash(object): if (string): self.update(string) - @classmethod def new(cls, string=None): """ @@ -48,7 +49,6 @@ class _Hash(object): """ return cls(string) - def copy(self): """ Returns a separate copy of this hashing object. An update @@ -62,7 +62,6 @@ class _Hash(object): return copy - def update(self, string): """ Hashes **string** into the current state of the hashing @@ -75,7 +74,6 @@ class _Hash(object): if ret < 0: raise WolfCryptError("Hash update error (%d)" % ret) - def digest(self): """ Returns the hash value of this hashing object as a string @@ -96,7 +94,6 @@ class _Hash(object): return _ffi.buffer(result, self.digest_size)[:] - def hexdigest(self): """ Returns the hash value of this hashing object as a string @@ -113,19 +110,16 @@ class Sha(_Hash): It produces an [ **160-bit | 20 bytes** ] message digest. """ - digest_size = 20 + digest_size = 20 _native_type = "wc_Sha *" _native_size = _ffi.sizeof("wc_Sha") - def _init(self): return _lib.wc_InitSha(self._native_object) - def _update(self, data): return _lib.wc_ShaUpdate(self._native_object, data, len(data)) - def _final(self, obj, ret): return _lib.wc_ShaFinal(obj, ret) @@ -137,19 +131,16 @@ class Sha256(_Hash): It produces a [ **256-bit | 32 bytes** ] message digest. """ - digest_size = 32 + digest_size = 32 _native_type = "wc_Sha256 *" _native_size = _ffi.sizeof("wc_Sha256") - def _init(self): return _lib.wc_InitSha256(self._native_object) - def _update(self, data): return _lib.wc_Sha256Update(self._native_object, data, len(data)) - def _final(self, obj, ret): return _lib.wc_Sha256Final(obj, ret) @@ -161,19 +152,16 @@ class Sha384(_Hash): It produces a [ **384-bit | 48 bytes** ] message digest. """ - digest_size = 48 + digest_size = 48 _native_type = "wc_Sha384 *" _native_size = _ffi.sizeof("wc_Sha384") - def _init(self): return _lib.wc_InitSha384(self._native_object) - def _update(self, data): return _lib.wc_Sha384Update(self._native_object, data, len(data)) - def _final(self, obj, ret): return _lib.wc_Sha384Final(obj, ret) @@ -185,26 +173,23 @@ class Sha512(_Hash): It produces a [ **512-bit | 64 bytes** ] message digest. """ - digest_size = 64 + digest_size = 64 _native_type = "wc_Sha512 *" _native_size = _ffi.sizeof("wc_Sha512") - def _init(self): return _lib.wc_InitSha512(self._native_object) - def _update(self, data): return _lib.wc_Sha512Update(self._native_object, data, len(data)) - def _final(self, obj, ret): return _lib.wc_Sha512Final(obj, ret) # Hmac types -_TYPE_SHA = 1 +_TYPE_SHA = 1 _TYPE_SHA256 = 2 _TYPE_SHA384 = 5 _TYPE_SHA512 = 4 @@ -216,11 +201,10 @@ class _Hmac(_Hash): A **PEP 247: Cryptographic Hash Functions** compliant **Keyed Hash Function Interface**. """ - digest_size = None + digest_size = None _native_type = "Hmac *" _native_size = _ffi.sizeof("Hmac") - def __init__(self, key, string=None): key = t2b(key) @@ -232,8 +216,6 @@ class _Hmac(_Hash): if (string): self.update(string) - - @classmethod def new(cls, key, string=None): """ @@ -245,15 +227,12 @@ class _Hmac(_Hash): """ return cls(key, string) - def _init(self, type, key): return _lib.wc_HmacSetKey(self._native_object, type, key, len(key)) - def _update(self, data): return _lib.wc_HmacUpdate(self._native_object, data, len(data)) - def _final(self, obj, ret): return _lib.wc_HmacFinal(obj, ret) diff --git a/src/wolfcrypt/random.py b/src/wolfcrypt/random.py index 7c19c5c..5e5f1ad 100644 --- a/src/wolfcrypt/random.py +++ b/src/wolfcrypt/random.py @@ -17,11 +17,11 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -from wolfcrypt._ffi import ffi as _ffi -from wolfcrypt._ffi import lib as _lib -from wolfcrypt.utils import t2b -from wolfcrypt.exceptions import * +from wolfcrypt._ffi import ffi as _ffi +from wolfcrypt._ffi import lib as _lib + +from wolfcrypt.exceptions import WolfCryptError class Random(object): @@ -36,7 +36,6 @@ class Random(object): self.native_object = None raise WolfCryptError("RNG init error (%d)" % ret) - def __del__(self): if self.native_object: try: @@ -45,7 +44,6 @@ class Random(object): # Can occur during interpreter shutdown pass - def byte(self): """ Generate and return a random byte. @@ -58,7 +56,6 @@ class Random(object): return _ffi.buffer(result, 1)[:] - def bytes(self, length): """ Generate and return a random sequence of length bytes. diff --git a/src/wolfcrypt/utils.py b/src/wolfcrypt/utils.py index ec3a038..fb3ed9c 100644 --- a/src/wolfcrypt/utils.py +++ b/src/wolfcrypt/utils.py @@ -21,12 +21,14 @@ # pylint: disable=unused-import, undefined-variable import sys -from binascii import hexlify as b2h, unhexlify as h2b +from binascii import hexlify as b2h, unhexlify as h2b # noqa: F401 + _PY3 = sys.version_info[0] == 3 -_TEXT_TYPE = str if _PY3 else unicode +_TEXT_TYPE = str if _PY3 else unicode # noqa: F821 _BINARY_TYPE = bytes if _PY3 else str + def t2b(string): """ Converts text to bynary. diff --git a/tests/test_ciphers.py b/tests/test_ciphers.py index 307e090..97dd193 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -34,25 +34,28 @@ def vectors(): TestVector.__new__.__defaults__ = (None,) * len(TestVector._fields) return { - Aes : TestVector( + Aes: TestVector( key="0123456789abcdef", iv="1234567890abcdef", plaintext=t2b("now is the time "), - ciphertext=h2b("959492575f4281532ccc9d4677a233cb")), - Des3 : TestVector( + ciphertext=h2b("959492575f4281532ccc9d4677a233cb") + ), + Des3: TestVector( key=h2b("0123456789abcdeffedeba987654321089abcdef01234567"), iv=h2b("1234567890abcdef"), plaintext=t2b("Now is the time for all "), - ciphertext=h2b("43a0297ed184f80e8964843212d508981894157487127db0")), - RsaPublic : TestVector( + ciphertext=h2b("43a0297ed184f80e8964843212d508981894157487127db0") + ), + RsaPublic: TestVector( key=h2b( "30819F300D06092A864886F70D010101050003818D0030818902818100BC" "730EA849F374A2A9EF18A5DA559921F9C8ECB36D48E53535757737ECD161" "905F3ED9E4D5DF94CAC1A9D719DA86C9E84DC4613682FEABAD7E7725BB8D" "11A5BC623AA838CC39A20466B4F7F7F3AADA4D020EBB5E8D6948DC77C928" "0E22E96BA426BA4CE8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B3C67C8DC" - "2700F6916865A90203010001")), - RsaPrivate : TestVector( + "2700F6916865A90203010001") + ), + RsaPrivate: TestVector( key=h2b( "3082025C02010002818100BC730EA849F374A2A9EF18A5DA559921F9C8EC" "B36D48E53535757737ECD161905F3ED9E4D5DF94CAC1A9D719DA86C9E84D" @@ -74,7 +77,8 @@ def vectors(): "C8DEF61BC2612376EFB09D1C44BE1343396717C89DCAFBF545648B38822C" "F28102403989E59C195530BAB7488C48140EF49F7E779743E1B419353123" "759C3B44AD691256EE0061641666D37C742B15B4A2FEBF086B1A5D3F9012" - "B105863129DBD9E2")) + "B105863129DBD9E2") + ) } @@ -107,13 +111,13 @@ def test_block_cipher(cipher_cls, vectors): ciphertext = vectors[cipher_cls].ciphertext with pytest.raises(ValueError): - cipher_cls.new(key[:-1], MODE_CBC, iv) # invalid key length + cipher_cls.new(key[:-1], MODE_CBC, iv) # invalid key length with pytest.raises(ValueError): - cipher_cls.new(key, MODE_ECB, iv) # invalid mode + cipher_cls.new(key, MODE_ECB, iv) # invalid mode with pytest.raises(ValueError): - cipher_cls.new(key, MODE_CBC, iv[:-1]) # invalid iv length + cipher_cls.new(key, MODE_CBC, iv[:-1]) # invalid iv length # single encryption cipher_obj = cipher_new(cipher_cls, vectors) @@ -124,8 +128,8 @@ def test_block_cipher(cipher_cls, vectors): cipher_obj = cipher_new(cipher_cls, vectors) result = t2b("") - segments = tuple(plaintext[i:i + cipher_obj.block_size] \ - for i in range(0, len(plaintext), cipher_obj.block_size)) + segments = tuple(plaintext[i:i + cipher_obj.block_size] + for i in range(0, len(plaintext), cipher_obj.block_size)) for segment in segments: result += cipher_obj.encrypt(segment) @@ -141,8 +145,8 @@ def test_block_cipher(cipher_cls, vectors): cipher_obj = cipher_new(cipher_cls, vectors) result = t2b("") - segments = tuple(ciphertext[i:i + cipher_obj.block_size] \ - for i in range(0, len(ciphertext), cipher_obj.block_size)) + segments = tuple(ciphertext[i:i + cipher_obj.block_size] + for i in range(0, len(ciphertext), cipher_obj.block_size)) for segment in segments: result += cipher_obj.decrypt(segment) @@ -159,10 +163,10 @@ def test_block_cipher(cipher_cls, vectors): def test_new_rsa_raises(vectors): with pytest.raises(WolfCryptError): - RsaPrivate(vectors[RsaPrivate].key[:-1]) # invalid key length + RsaPrivate(vectors[RsaPrivate].key[:-1]) # invalid key length with pytest.raises(WolfCryptError): - RsaPublic(vectors[RsaPublic].key[:-1]) # invalid key length + RsaPublic(vectors[RsaPublic].key[:-1]) # invalid key length def test_rsa_encrypt_decrypt(rsa_private, rsa_public): @@ -175,7 +179,7 @@ def test_rsa_encrypt_decrypt(rsa_private, rsa_public): assert plaintext == rsa_private.decrypt(ciphertext) # private object holds both private and public info, so it can also encrypt - # using the known public key, this isn't an encryption using the private key + # using the known public key. ciphertext = rsa_private.encrypt(plaintext) assert 1024 / 8 == len(ciphertext) == rsa_private.output_size @@ -192,7 +196,7 @@ def test_rsa_sign_verify(rsa_private, rsa_public): assert plaintext == rsa_public.verify(signature) # private object holds both private and public info, so it can also verify - # using the known public key, this isn't a verification using the private key + # using the known public key. signature = rsa_private.sign(plaintext) assert 1024 / 8 == len(signature) == rsa_private.output_size diff --git a/tests/test_hashes.py b/tests/test_hashes.py index 435e9b6..c472373 100644 --- a/tests/test_hashes.py +++ b/tests/test_hashes.py @@ -34,32 +34,40 @@ def vectors(): TestVector.__new__.__defaults__ = (None,) * len(TestVector._fields) return { - Sha : TestVector( - digest=t2b("1b6182d68ae91ce0853bd9c6b6edfedd4b6a510d")), - Sha256 : TestVector( - digest=t2b("96e02e7b1cbcd6f104fe1fdb4652027a" \ - + "5505b68652b70095c6318f9dce0d1844")), - Sha384 : TestVector( - digest=t2b("4c79d80531203a16f91bee325f18c6aada47f9382fe44fc1" \ - + "1f92917837e9b7902f5dccb7d3656f667a1dce3460bc884b")), - Sha512 : TestVector( - digest=t2b("88fcf67ffd8558d713f9cedcd852db47" \ - + "9e6573f0bd9955610a993f609637553c" \ - + "e8fff55e644ee8a106aae19c07f91b3f" \ - + "2a2a6d40dfa7302c0fa6a1a9a5bfa03f")), - HmacSha : TestVector( - digest=t2b("5dfabcfb3a25540824867cd21f065f52f73491e0")), - HmacSha256 : TestVector( - digest=t2b("4b641d721493d80f019d9447830ebfee" \ - + "89234a7d594378b89f8bb73873576bf6")), - HmacSha384 : TestVector( - digest=t2b("e72c72070c9c5c78e3286593068a510c1740cdf9dc34b512" \ - + "ccec97320295db1fe673216b46fe72e81f399a9ec04780ab")), - HmacSha512 : TestVector( - digest=t2b("c7f48db79314fc2b5be9a93fd58601a1" \ - + "bf42f397ec7f66dba034d44503890e6b" \ - + "5708242dcd71a248a78162d815c685f6" \ - + "038a4ac8cb34b8bf18986dbd300c9b41")), + Sha: TestVector( + digest=t2b("1b6182d68ae91ce0853bd9c6b6edfedd4b6a510d") + ), + Sha256: TestVector( + digest=t2b("96e02e7b1cbcd6f104fe1fdb4652027a" + + "5505b68652b70095c6318f9dce0d1844") + ), + Sha384: TestVector( + digest=t2b("4c79d80531203a16f91bee325f18c6aada47f9382fe44fc1" + + "1f92917837e9b7902f5dccb7d3656f667a1dce3460bc884b") + ), + Sha512: TestVector( + digest=t2b("88fcf67ffd8558d713f9cedcd852db47" + + "9e6573f0bd9955610a993f609637553c" + + "e8fff55e644ee8a106aae19c07f91b3f" + + "2a2a6d40dfa7302c0fa6a1a9a5bfa03f") + ), + HmacSha: TestVector( + digest=t2b("5dfabcfb3a25540824867cd21f065f52f73491e0") + ), + HmacSha256: TestVector( + digest=t2b("4b641d721493d80f019d9447830ebfee" + + "89234a7d594378b89f8bb73873576bf6") + ), + HmacSha384: TestVector( + digest=t2b("e72c72070c9c5c78e3286593068a510c1740cdf9dc34b512" + + "ccec97320295db1fe673216b46fe72e81f399a9ec04780ab") + ), + HmacSha512: TestVector( + digest=t2b("c7f48db79314fc2b5be9a93fd58601a1" + + "bf42f397ec7f66dba034d44503890e6b" + + "5708242dcd71a248a78162d815c685f6" + + "038a4ac8cb34b8bf18986dbd300c9b41") + ), }