-
Notifications
You must be signed in to change notification settings - Fork 466
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
Improve SSE4.1/AES-NI support #644
Conversation
Maybe I should cc @karel-m |
Did you try the proposed change of #641 and whether this maybe fixes it already? |
#641 doesn't help, unfortunately. Here is a crash from the
|
This comment was marked as spam.
This comment was marked as spam.
Sorry for the long delay.
FMU that's a different problem. You can also see that it fails in A valid test-case for AES-NI would be to first configure&build the library as you did and then execute this: #include <tomcrypt.h>
int main(void)
{
aes_test();
} Regarding what you're seeing: You're explicitly enabling SSE4.1, which allows the compiler to generate SSE-specific instructions. WARNING: I checked the disassembly in the past and was too lazy to re-check now, so I hope the following statement is still correct :) Please correct me if I'm wrong! The following code comes from an era when compilers were not yet that smart: libtomcrypt/src/encauth/gcm/gcm_mult_h.c Lines 19 to 41 in f7e6519
By enabling You should also be able to reproduce this failure with the latest release (master branch) that has no AES-NI support yet. Maybe also try to add debug information when building the library to see where exactly it breaks? Yes, these details are only slightly related to the error you see, but should show you the problem. |
And also you're right with this PR... now I understand the purpose :) With this we have now a "proper" runtime check for AES-NI. It allows to build the rest of the library for all amd64 (also non SSE) and only requires the AES-NI related parts to be built with SSE4.1 support. |
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.
LGTM
No worries. Thanks for looking at this.
That's precisely the point: currently, if you want to enable AES-NI support, you need to enable SSE4.1 unconditionally for the whole source tree. This is especially relevant when building binary packages. The same binary package should (ideally) be able to run different CPUs with different capabilities.
Yes, exactly. :) |
I've force-pushed a new commit that includes the change you requested. |
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.
Uhm ... I've just had a third look at this and wouldn't it even make sense to compile aesni.c
always with those flags? ... but then we'd need some kind of configure step which determines the target architecture ... What do you think?
Also I've only now realized that there's no CMake support for this feature, that's why I haven't merged it yet.
Why don't we use target attributes? See the new commit. This avoids the need for flags altogether. You only have to make sure that
I defined (However, I don't think MSVC will work anyway, because apparently it does not support inline assembly on x64. So the |
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.
ltc's source checker in helper.pl doesn't like it when you redefine compiler specific symbols. It may be better to make an LTC macro for what you want, like this.
I've pushed a new commit that is rebased on current |
src/ciphers/aes/aesni.c
Outdated
#if defined(__GNUC__) || defined(__clang__) | ||
#define LTC_ATTRIBUTE(x) __attribute__(x) | ||
#else | ||
#define LTC_ATTRIBUTE(x) | ||
#endif |
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.
Could you please directly put this in tomcrypt_cfg.h
?
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.
Thanks a lot for the improvements on this and thanks for the PR. Looks very good now.
(and please rebase on top of current develop :) )
Done! |
This also supersedes #641 right? |
Yes, I believe it does. |
Before merging this I have one more question: Wouldn't it now make sense to enable this by default on x86/amd64? Btw. thanks (and sorry) @tbvdm for doing this lengthy exercise with us ;) |
@tbvdm could you please rebase this PR's branch on top of current develop? I will try to make a dev release of CryptX perl bindings with this patch to check what will happen on cpantesters & co. |
I do not have a strong opinion on this but I would rather keep it off by default, According to my experiance you basically need:
|
I think I'm leaning on the cautious side re the default. @karel-m said it a lot better |
Alright, then we'll stay away from the danger zone and leave it off by default ;) @tbvdm I took the liberty to rebase and force-push your branch, I hope that's OK |
I guess we forgot to enable this in the CI build ... ;) libtomcrypt/.github/workflows/main.yml Line 41 in ce904c8
|
Thanks for merging this. :) Yes, it seems I missed main.yml when I grepped the tree for relevant files. |
The CryptX Perl module contains a vendored copy of libtomcrypt. It uses
-msse4.1 -maes
to enable AES-NI support. The problem is that these flags are used for all source files. This results inSIGILL
crashes on CPUs without SSE4.1.I think the solution is for CryptX to use
-msse4.1 -maes
only foraesni.c
. But this is not possible without several changes to libtomcrypt. This pull request is a proposal for those changes.The primary change is in how SSE4.1 is detected. Currently libtomcrypt checks
__SSE4_1__
. But this requires that-msse4.1
is used for multiple source files. Moreover, it's a compile-time check, not a run-time one. I think it would be better to detect SSE4.1 withcpuid
.Then there is the build procedure. I came up with the following approach. By default, AES-NI support is disabled. To enable it, add
-DLTC_AES_NI
toCFLAGS
and set the required compiler flags inCFLAGS_AES_NI
(typically-maes -msse4.1
). For example:Checklist
Closes #641