-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setting parameters on big endian systems #12
Comments
I don't quite recall, but I do believe the plan was at some point to expose those functions to the outside, for users that would want to make their own portable parameter blocks. But since no such users ever appeared, those functions ended up never getting exposed. Even internally, for |
I wonder if that means CPython's blake2 implementation, for example, has a bug on big endian platforms? They seem to be setting the |
That's an excellent question. I think there's no bug, because the reference implementation explicitly loads the parameter block in little endian order. The optimized x86 implementations do not do this, but everything's assumed to be little-endian in those. But in all honesty I did not check if there is a bug or not; I don't have big-endian hardware to verify this right now. |
I was staring at that earlier, and here was how I read it: The I haven't owned PowerPC hardware in...some time...but I might try to fire up QEMU tonight and see if I can test this. Edit: These look useful for testing |
Yeah, I think you're right. In hindsight, the parameter block ought to be an opaque structure, with the functions used to set the appropriate bytes of it. |
Confirmed! I don't know of any official test vectors that set
It should be simple to patch CPython, and I'll see if I can add a test for this. On the libb2 side of things, probably we should at least stick some clarifying comments inline in Can you think of any other languages or libraries that expose these fields, that we'd want to eyeball for the same bug? |
I've pushed a candidate solution to a separate branch, under which existing correct code should be able to continue functioning properly, but a new API exists to explicit build correct parameter blocks. To be able to do this, I'm using unnamed structs in unions, which appears to be something only standardized in C11, but recent GCC, Clang, and MSVC all appear to support this. I don't know the extent of the damage. To my knowledge, most bindings/implementations are limited to the variable length and key parameters, for which endianness does not matter. |
Those changes look good to me, though I don't have much experience with this code. Maybe we could stick a comment on the anonymous struct like:
|
Also will https://github.com/BLAKE2/BLAKE2 want to make similar changes? |
Yes, the plan is to merge the two repositories at some point. Hopefully soon. |
Oh, I think on lines 178-179 of |
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 BLAKE2/libb2#12.
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 BLAKE2/libb2#12.
…onGH-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 BLAKE2/libb2#12. (cherry picked from commit dcfb0e3)
) (#4262) 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 BLAKE2/libb2#12. (cherry picked from commit dcfb0e3)
It almost certainly doesn't really matter which one we pick. I originally went with big endian because that's the vaguely standardized "network byte order". I'm switching to little endian because the BLAKE2 standard made the same switch relative to BLAKE (https://blake2.net/blake2.pdf), and that seems like a very relevant precedent to follow. Little endian is also what DJB chose for his NaCl library. The main downside of little endian in my mind, is that because it's also the most common native endianness in practice, implementations are more likely to write code that "happens to work" on their machine and fails on big endian architectures. In fact this totally happened in the official implementation of BLAKE2 (BLAKE2/libb2#12). However, a contributing factor in that case was the bug only affected a couple of obscure options, which might actually never have been exercised on any big endian machines, ever. This isn't the case for bao; if you flip the endianness of your header length, then almost all of your hashes will be wrong.
…on#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 BLAKE2/libb2#12.
Another design comment about https://github.com/BLAKE2/libb2/tree/fix-bigendian: I think |
Excellent idea, I'll incorporate this. |
It looks like functions like
blake2b_param_set_node_offset
convert their argument to little-endian on the way in. But those functions aren't exposed in theblake2.h
API. Is the expectation that callers (who plan on supporting big endian platforms) will convert their parameters to little endian on their own? Or maybe the plan was to expose the setter functions inblake2.h
eventually?The text was updated successfully, but these errors were encountered: