> On Feb 20, 2018, at 11:00 , [email protected] wrote:
>
> ec.derive_private_key_from_bytes(secret_bytes, ec.SECP384R1(), backend)
> could potentially be a way to do this specific operation while reducing the
> number of copies (to zero in Python and 2-3 in OpenSSL, although the latter
> are zeroed), but without tests that can detect non-required copies of
> secret material it would be extremely hard to prevent regression in the
> long term as the code is updated.
Paul,
Based upon your hint above I just went in to the code and looked
around. It looks like a straightforward extension. Note: I am not a library
developer and, hence, have not developed all of the various skills to properly
build pyca/cryptography. Nor am I particularly knowledgable about Python v2.7 &
v3.6 interoperation issues, much less CPython, Cython and PyPy interoperation.
The below code is a gedanken exploration to see how hard or involved it might
actually be to extend pyca/cryptography.
TL;DR: It isn’t hard. I C&P three functions and then modded them. Gratz
to the team on an excellent design.
It is clear that I could deploy my own copy of cryptography and call it
a day. But I believe that key hygiene is an important social good. I am happy
to help look at/write each routine that imports key material and propose
versions that allow good key hygiene. As you note above, there is no solution
for your regression testing issue except to discuss it in code commentary. Now
to find a routine that can bang the contents of a bytes array to 0, 1 and then
random.
Should I proceed to engage with your team or just continue on my merry
way? I want to help but if it isn’t something the team prioritizes highly right
now, I fully understand.
Anon,
Andrew
____________________________________
Andrew W. Donoho
Donoho Design Group, L.L.C.
[email protected], +1 (512) 666-7596, twitter.com/adonoho
No risk, no art.
No art, no reward.
-- Seth Godin
===== backend.py =====
def _bytes_to_bn(self, num, bn=None):
# Was: def _int_to_bn(self, num, bn=None):
"""
Converts a python bytes array to a BIGNUM. The returned BIGNUM will not
be garbage collected (to support adding them to structs that take
ownership of the object). Be sure to register it for GC if it will
be discarded after use.
"""
assert bn is None or bn != self._ffi.NULL
if bn is None:
bn = self._ffi.NULL
bn_ptr = self._lib.BN_bin2bn(num, len(num), bn)
self.openssl_assert(bn_ptr != self._ffi.NULL)
return bn_ptr
def derive_elliptic_curve_private_key_bytes(self, private_bytes, curve):
# Was: def derive_elliptic_curve_private_key(self, private_value, curve):
curve_nid = self._elliptic_curve_to_nid(curve)
ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid)
self.openssl_assert(ec_cdata != self._ffi.NULL)
ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free)
get_func, group = self._ec_key_determine_group_get_func(ec_cdata)
point = self._lib.EC_POINT_new(group)
self.openssl_assert(point != self._ffi.NULL)
point = self._ffi.gc(point, self._lib.EC_POINT_free)
value = self._bytes_to_bn(private_bytes)
value = self._ffi.gc(value, self._lib.BN_clear_free)
with self._tmp_bn_ctx() as bn_ctx:
res = self._lib.EC_POINT_mul(group, point, value, self._ffi.NULL,
self._ffi.NULL, bn_ctx)
self.openssl_assert(res == 1)
bn_x = self._lib.BN_CTX_get(bn_ctx)
bn_y = self._lib.BN_CTX_get(bn_ctx)
res = get_func(group, point, bn_x, bn_y, bn_ctx)
self.openssl_assert(res == 1)
res = self._lib.EC_KEY_set_public_key(ec_cdata, point)
self.openssl_assert(res == 1)
private = self._bytes_to_bn(private_bytes)
private = self._ffi.gc(private, self._lib.BN_clear_free)
res = self._lib.EC_KEY_set_private_key(ec_cdata, private)
self.openssl_assert(res == 1)
evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata)
return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey)
===== ec.py =====
def derive_private_key_bytes(private_value, curve, backend):
# Was: def derive_private_key(private_value, curve, backend):
if not isinstance(curve, EllipticCurve):
raise TypeError("curve must provide the EllipticCurve interface.")
return backend.derive_elliptic_curve_private_key_bytes(private_value, curve)
_______________________________________________
Cryptography-dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cryptography-dev