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
Detect endian without relying on defined symbols. #8572
Conversation
Err.. B_ENDIAN is also used in bn_lib.c, sha512.c & wp_block.c. |
If we are going to go down the path of runtime rather than compile time detection this should be done in a single place - so we don't end up copying that fragment all over the place. And we should be working to avoid having any header file (certainly any public header file) that depends on B_ENDIAN ... |
Too late :) I think its already in multiple places :) |
It will end up being resolved at compile time, once the optimiser does constant propagation and dead code elimination. Put it into a function and this won't happen. It could be made into a pair of macros. I'd like to see if this fixes the endian problems in the tests before changing it everywhere. |
Human comprehension is more important than CPU optimization. I agree with @t-j-h |
In other places B_ENDIAN / L_ENDIAN is used when endianness is guaranteed to be this way, |
I did try to check if we use |
@levitte the param API tests fail on big endian machines because B_ENDIAN isn't defined for tests. |
It is trying to fix something by papering over the hole. It doesn't address the core problem. It uses a cut trick, which makes sense in very computationally expensive cryptography code, to get needless efficiency in corner cases of parameter passing which is NOT intended to be a heavily-used feature but rather to have a way to pass "opaque" structures between openssl core and cryptographic providers on the same machine. In my view, the whole approach that the project is using is wrong, too general and solving the wrong problem. The real fix is to remove the need for this kind of thing. Heck, use C's portable shift operators (going back to the days of BSD on a Vax and ntoh). What is needed is the ability to pass strings, octet buffers, and BIGNUM's around. Which is a long-winded and obnoxious way of saying "no," and implying that #8377 is still better. |
I wonder why you want bignums to be native byte-order? |
If this is for test apps, wouldn't it make more sense to make this part of testutil? |
So you are saying that B_ENDIAN is defined correctly in bn_lib.c, sha512.c & wp_block.c? |
The "problem" could also be resolved by building up a suitable BIGNUM and then pass it in and out using the API. However, the affected check tests that the API handles the expected format of a passed number correctly, regardless of size. Considering the format is documented, it must be followed, and suitably tested (this is something I expect from a unit test) |
It should be. B_ENDIAN is passed with the |
Not sure I understand your point in #8572 (comment), @levitte. Are you saying the design and docs are frozen and cannot be changed? That seems premature. Maybe the API so other work can progress. Apologies if you meant something else. |
Yes. B_ENDIAN / L_ENDIAN is only defined, when the target is known to be that way. |
What I wonder, why we seem to have a BIGNUM with native-byte ordering. |
Since we are only passing these in the same executable, it makes sense to be efficient. Passing a pointer in, and passing a native serialization out is one way, for example. Converting to/from a neutral string format, might be more portable but at the expense of performance. Or, heck, use DER encoding for ASN1 Integer. |
Given the complexity of the current model, I think using i2d/d2i might be the least-worst option, unfortunately. |
@richsalz, |
DER was actually suggested as a parameter passing format early on. That was not a welcome suggestion at the time. (the complexity is also higher with DER) |
That's an incorrect assumption. A dynamically loaded module can't reliably be viewed as the same executable as the loading application. |
I understand that things are frozen at the time of release. I thought your comment was saying it's frozen now. I'd like to know which supported platform supports dynamic modules in a separate executable. And if so, how does that reconcile with the PTR construct currently defined? |
I believe that OSSL_PARAM needs to be fairly frozen early. It will be harmful if it keeps being a moving target. |
The driving thought behind it was that an integer is an integer is an integer, regardless of size, and should therefore have the same byte order throughout. |
My current view is that tests should be written so they are portable without having to know the endianness. |
With that line of thinking, we can throw away all internal tests (there is a bunch of them), because they all rely on internal knowledge |
include/internal/endian.h
Outdated
@@ -0,0 +1,22 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a testutil header. It has no use in our libraries (even though I know that there's code that use the same technique)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would disagree, since there is code in the library (siv128.c) that uses this technique. Why not consolidate?
I should probably clarify that that would be if you test a public API. If you can't test a public API without knowing the endianness, I'm concerned that it's difficult for applications to properly use the API, and that it might just work by accident until they run it on a system with a different endianness. |
Normally, the BIGNUM stuff would be handled with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Travis failure not relevant here
This also done in modes/siv128.c: Lines 37 to 47 in 183f52e
|
For siv128.c, we could as well use B_ENDIAN. It's possible, though, that whoever authored it simply didn't know, or that the code was initially developed elsewhere. |
@levitte It was both. |
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from #8572)
This fragment also appears in: CTR, GCM, XTS, sha256, chacha20, blake2... Personally, I prefer this sequence to using the pre-processor because both branches get checked by the compiler. Regardless, our endian handling should be unified. There are other endian handling forms in the code, e.g. sha512 code includes I'm not even going to consider the assembly... |
Avoid using the B_ENDIAN define to determine host endianness.
Fixes #8570