From dcfb0e3c04f1b29a0d09bb0a81dcd5ee5a5fef1a Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Fri, 3 Nov 2017 15:02:41 -0400 Subject: [PATCH] bpo-31933: fix blake2 multi-byte params on big endian platforms (#4250) All Blake2 params have to be encoded in little-endian byte order. For the two multi-byte integer params, leaf_length and node_offset, that means that assigning a native-endian integer to them appears to work on little-endian platforms, but gives the wrong result on big-endian. The current libb2 API doesn't make that very clear, and @sneves is working on new API functions in the GH issue above. In the meantime, we can work around the problem by explicitly assigning little-endian values to the parameter block. See https://github.com/BLAKE2/libb2/issues/12. --- Lib/test/test_hashlib.py | 36 +++++++++++++++++++ .../2017-11-03-08-36-03.bpo-31933.UrtoMP.rst | 2 ++ Modules/_blake2/blake2b_impl.c | 6 ++-- Modules/_blake2/blake2s_impl.c | 6 ++-- 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-11-03-08-36-03.bpo-31933.UrtoMP.rst diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 90e6a563a72..e4e5280dc8e 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -615,6 +615,24 @@ class HashLibTestCase(unittest.TestCase): "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"+ "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923") + @requires_blake2 + def test_case_blake2b_all_parameters(self): + # This checks that all the parameters work in general, and also that + # parameter byte order doesn't get confused on big endian platforms. + self.check('blake2b', b"foo", + "920568b0c5873b2f0ab67bedb6cf1b2b", + digest_size=16, + key=b"bar", + salt=b"baz", + person=b"bing", + fanout=2, + depth=3, + leaf_size=4, + node_offset=5, + node_depth=6, + inner_size=7, + last_node=True) + @requires_blake2 def test_blake2b_vectors(self): for msg, key, md in read_vectors('blake2b'): @@ -640,6 +658,24 @@ class HashLibTestCase(unittest.TestCase): self.check('blake2s', b"abc", "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982") + @requires_blake2 + def test_case_blake2s_all_parameters(self): + # This checks that all the parameters work in general, and also that + # parameter byte order doesn't get confused on big endian platforms. + self.check('blake2s', b"foo", + "bf2a8f7fe3c555012a6f8046e646bc75", + digest_size=16, + key=b"bar", + salt=b"baz", + person=b"bing", + fanout=2, + depth=3, + leaf_size=4, + node_offset=5, + node_depth=6, + inner_size=7, + last_node=True) + @requires_blake2 def test_blake2s_vectors(self): for msg, key, md in read_vectors('blake2s'): diff --git a/Misc/NEWS.d/next/Library/2017-11-03-08-36-03.bpo-31933.UrtoMP.rst b/Misc/NEWS.d/next/Library/2017-11-03-08-36-03.bpo-31933.UrtoMP.rst new file mode 100644 index 00000000000..c4ee1d24980 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-03-08-36-03.bpo-31933.UrtoMP.rst @@ -0,0 +1,2 @@ +Fix Blake2 params leaf_size and node_offset on big endian platforms. Patch +by Jack O'Connor. diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 3c2a035f3d7..822b9f285ca 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -162,7 +162,8 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, goto error; } } - self->param.leaf_length = (unsigned int)leaf_size; + // NB: Simple assignment here would be incorrect on big endian platforms. + store32(&(self->param.leaf_length), leaf_size); if (node_offset_obj != NULL) { node_offset = PyLong_AsUnsignedLongLong(node_offset_obj); @@ -178,7 +179,8 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, } store48(&(self->param.node_offset), node_offset); #else - self->param.node_offset = node_offset; + // NB: Simple assignment here would be incorrect on big endian platforms. + store64(&(self->param.node_offset), node_offset); #endif if (node_depth < 0 || node_depth > 255) { diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 2c5697299fc..3b76c9cd89d 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -162,7 +162,8 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, goto error; } } - self->param.leaf_length = (unsigned int)leaf_size; + // NB: Simple assignment here would be incorrect on big endian platforms. + store32(&(self->param.leaf_length), leaf_size); if (node_offset_obj != NULL) { node_offset = PyLong_AsUnsignedLongLong(node_offset_obj); @@ -178,7 +179,8 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, } store48(&(self->param.node_offset), node_offset); #else - self->param.node_offset = node_offset; + // NB: Simple assignment here would be incorrect on big endian platforms. + store64(&(self->param.node_offset), node_offset); #endif if (node_depth < 0 || node_depth > 255) {