> On Feb 20, 2018, at 11:00 , cryptography-dev-requ...@python.org 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. andrew.don...@gmail.com, +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 Cryptography-dev@python.org https://mail.python.org/mailman/listinfo/cryptography-dev