From 7339b5b74dc629b5d474d5cc75ca286261478d92 Mon Sep 17 00:00:00 2001 From: jr conlin Date: Wed, 21 Dec 2016 17:02:15 -0800 Subject: [PATCH] bug: Allow sign and verify to use different hashes than sha256 closes #52 --- CHANGES.txt | 5 +++++ pyelliptic/__init__.py | 2 +- pyelliptic/ecc.py | 22 +++++++++++++++------- pyelliptic/hash.py | 12 ++++++++++++ pyelliptic/openssl.py | 8 ++++++++ setup.py | 4 +++- 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7856d0e..dbf8585 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,8 @@ +v1.6.0, 2016-12-21 +------------------ + +- allow other SHA digests (other than SHA_256) + v1.5.7, 2015-08-31 ------------------ diff --git a/pyelliptic/__init__.py b/pyelliptic/__init__.py index 85f8aa0..fd631a1 100644 --- a/pyelliptic/__init__.py +++ b/pyelliptic/__init__.py @@ -31,7 +31,7 @@ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -__version__ = '1.5.7' +__version__ = '1.6.0' __all__ = [ 'OpenSSL', diff --git a/pyelliptic/ecc.py b/pyelliptic/ecc.py index 86b0938..3e67677 100644 --- a/pyelliptic/ecc.py +++ b/pyelliptic/ecc.py @@ -68,10 +68,12 @@ class ECC: """ def __init__(self, pubkey=None, privkey=None, pubkey_x=None, - pubkey_y=None, raw_privkey=None, curve='sect283r1'): + pubkey_y=None, raw_privkey=None, curve='sect283r1', + hasher='sha256'): """ - For a normal and High level use, specifie pubkey, - privkey (if you need) and the curve + For a normal and High level use, specify pubkey, + privkey (if you need), the curve, and the hashing method. + """ if type(curve) == str: self.curve = OpenSSL.get_curve(curve) @@ -88,6 +90,14 @@ def __init__(self, pubkey=None, privkey=None, pubkey_x=None, else: self.privkey, self.pubkey_x, self.pubkey_y = self._generate() + _hashers = { + "sha256": OpenSSL.EVP_sha256(), + "sha384": OpenSSL.EVP_sha384(), + "sha512": OpenSSL.EVP_sha512(), + } + self.hashval = hasher + self.hasher = _hashers[hasher] + def _set_keys(self, pubkey_x, pubkey_y, privkey): if self.raw_check_key(privkey, pubkey_x, pubkey_y) < 0: self.pubkey_x = None @@ -414,7 +424,7 @@ def sign(self, inputb): raise Exception("[OpenSSL] EC_KEY_check_key FAIL ... " + OpenSSL.get_error()) OpenSSL.EVP_MD_CTX_init(md_ctx) - OpenSSL.EVP_DigestInit_ex(md_ctx, OpenSSL.EVP_sha256(), None) + OpenSSL.EVP_DigestInit_ex(md_ctx, self.hasher, None) if (OpenSSL.EVP_DigestUpdate(md_ctx, buff, size)) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ... " + OpenSSL.get_error()) @@ -466,12 +476,10 @@ def verify(self, sig, inputb): raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ... " + OpenSSL.get_error()) if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ... " + OpenSSL.get_error()) - OpenSSL.EVP_MD_CTX_init(md_ctx) - OpenSSL.EVP_DigestInit_ex(md_ctx, OpenSSL.EVP_sha256(), None) + OpenSSL.EVP_DigestInit_ex(md_ctx, self.hasher, None) if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ... " + OpenSSL.get_error()) - OpenSSL.EVP_DigestFinal_ex(md_ctx, digest, dgst_len) ret = OpenSSL.ECDSA_verify( 0, digest, dgst_len.contents, bsig, len(sig), key) diff --git a/pyelliptic/hash.py b/pyelliptic/hash.py index 98d89e3..62c9560 100644 --- a/pyelliptic/hash.py +++ b/pyelliptic/hash.py @@ -70,6 +70,18 @@ def hmac_sha256(k, m): return md.raw +def hmac_sha384(k, m): + """ + Compute the key and the message with HMAC SHA384 + """ + key = OpenSSL.malloc(k, len(k)) + d = OpenSSL.malloc(m, len(m)) + md = OpenSSL.malloc(0, 64) + i = OpenSSL.pointer(OpenSSL.c_int(0)) + OpenSSL.HMAC(OpenSSL.EVP_sha384(), key, len(k), d, len(m), md, i) + return md.raw + + def hmac_sha512(k, m): """ Compute the key and the message with HMAC SHA512 diff --git a/pyelliptic/openssl.py b/pyelliptic/openssl.py index c91b272..8dbd49d 100644 --- a/pyelliptic/openssl.py +++ b/pyelliptic/openssl.py @@ -100,6 +100,10 @@ def __init__(self, library): self.BN_bin2bn.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] + self.BN_bn2dec = self._lib.BN_bn2dec + self.BN_bn2dec.restype = ctypes.c_char_p + self.BN_bn2dec.argtypes = [ctypes.c_void_p] + self.EC_GROUP_get_degree = self._lib.EC_GROUP_get_degree self.EC_GROUP_get_degree.restype = ctypes.c_int self.EC_GROUP_get_degree.argtypes = [ctypes.c_void_p] @@ -344,6 +348,10 @@ def __init__(self, library): self.EVP_sha256.restype = ctypes.c_void_p self.EVP_sha256.argtypes = [] + self.EVP_sha384 = self._lib.EVP_sha384 + self.EVP_sha384.restype = ctypes.c_void_p + self.EVP_sha384.argtypes = [] + self.i2o_ECPublicKey = self._lib.i2o_ECPublicKey self.i2o_ECPublicKey.restype = ctypes.c_int self.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p] diff --git a/setup.py b/setup.py index a43f08a..ddca82d 100644 --- a/setup.py +++ b/setup.py @@ -31,9 +31,11 @@ from setuptools import setup, find_packages +from pyelliptic import __version__ + setup( name="pyelliptic", - version='1.5.7', + version=__version__, url='https://github.com/yann2192/pyelliptic', license='BSD', description=