Skip to content
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

ICP: AES-GCM: Unify gcm_init_ctx() and gmac_init_ctx() #14529

Merged

Conversation

AttilaFueloep
Copy link
Contributor

Motivation and Context

gmac_init_ctx() duplicates most of the code in gcm_int_ctx() while it just needs to set its own IV length and AAD tag length.

Description

Introduce gcm_init_ctx_impl() which handles the GCM and GMAC differences while reusing the duplicated code.

While here, constify the IV and AAD pointers passed to gcm_init{,_avx}().

How Has This Been Tested?

Builds, included in another PR which passes testing.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

@robn
Copy link
Member

robn commented Feb 25, 2023

The only difference I see is that previously, gmac_init_ctx would always do the key schedule byteswap check, and never do the MOVBE check, whereas gcm_init_ctx would do both checks only when AVX is selected by the cycle. Now, they both do it the gcm_init_ctx way.

I'm not sure if that was intentional or not, but it is a difference.

(It does seem like both checks should always be done, ie, doesn't matter how we decide to use AVX, but if we do, we should consider all the details).

@AttilaFueloep
Copy link
Contributor Author

Thanks, well spotted, this is very helpful feedback.

Only gcm_init_ctx() should do the MOVBE check since GMAC just calls gcm_init() and gcm_{en,de}crypt_final(). Both functions don't call into MOVBE/BSWAP code paths so there's no need to toggle between them in the GMAC case. I changed the code to skip the toggle in the GMAC case. Toggling gcm_avx_can_use_movbe makes only sense for the cycle implementation, so the current location is correct.

Not checking for a byte swapped key schedule if we are using the AVX implementation (as opposed to the cycle implementation) is a major bug with the potential of pool corruption. I could easily produce a panic by setting icp_gcm_impl to avx and icp_aes_impl to generic and starting some crypto i/o. Thanks for catching that! It was there from day one since I implemented the AVX support. Fortunately this isn't something one would do intentionally so hopefully no one has been bitten by it yet.

In summary, the key schedule byte swap check should be done for both, the cycle and the AVX implementation. In the cycle case we can silently fallback to a non-AVX implementation but for the AVX case we should print a warning in addition to the fallback at least.

The proper fix of course would be to deny setting the GCM implementation to one which won't work with the AES one and vice versa. Unfortunately this is a bit tricky since it would require synchronizing the routines setting the AES and GCM implementation. Not sure if it's worth the effort for such an edge case.

@AttilaFueloep AttilaFueloep force-pushed the zfs-unify-gcm-gmac-init-ctx branch from df2159d to bce39aa Compare February 26, 2023 11:32
@AttilaFueloep
Copy link
Contributor Author

Added fixes, rebased to master and force pushed to get a clean test run.

@behlendorf
Copy link
Contributor

@AttilaFueloep rebasing one more time should sort of the GitHub Actions CI infrastructure issue so you can get a clean test run.

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label Feb 27, 2023
@AttilaFueloep AttilaFueloep force-pushed the zfs-unify-gcm-gmac-init-ctx branch from bce39aa to 1024656 Compare February 28, 2023 09:48
@AttilaFueloep
Copy link
Contributor Author

Rebased. I wonder if we have the equivalent of pr_err_once(), that is log a message to syslog only on the first call, not always. Otherwise I'd say it's better to not log at all than flooding the syslog file. Since the ICP is used by the macOS and Windows ports as well, we can't use the Linux function here.

@AttilaFueloep
Copy link
Contributor Author

The make failures seem to be related to #14527. The zloop failure (ztest_dmu_snapshot_hold()) semms to be unrelated as well.

@AttilaFueloep AttilaFueloep force-pushed the zfs-unify-gcm-gmac-init-ctx branch from 1024656 to 0132fda Compare March 1, 2023 08:09
@AttilaFueloep
Copy link
Contributor Author

Once #14567 is merged I can drop d6eca66, rebase and squash. It should be ready for merging then.

@behlendorf
Copy link
Contributor

@AttilaFueloep merged #14567, I'll get this merged once you rebase.

@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Mar 7, 2023
gmac_init_ctx() duplicates most of the code in gcm_int_ctx() while
it just needs to set its own IV length and AAD tag length.

Introduce gcm_init_ctx_impl() which handles the GCM and GMAC
differences while reusing the duplicated code.

While here, fix a flaw where the AVX implementation would accept a
context using a byte swapped key schedule which it could not
handle. Also constify the IV and AAD pointers passed to
gcm_init{,_avx}().

Signed-off-by: Attila Fülöp <attila@fueloep.org>
@AttilaFueloep AttilaFueloep force-pushed the zfs-unify-gcm-gmac-init-ctx branch from 8630b06 to de478ad Compare March 7, 2023 22:55
@AttilaFueloep
Copy link
Contributor Author

Rebased, squashed and updated the commit message.

@behlendorf behlendorf merged commit 8d97525 into openzfs:master Mar 8, 2023
mcmilk pushed a commit to mcmilk/zfs that referenced this pull request Mar 13, 2023
gmac_init_ctx() duplicates most of the code in gcm_int_ctx() while
it just needs to set its own IV length and AAD tag length.

Introduce gcm_init_ctx_impl() which handles the GCM and GMAC
differences while reusing the duplicated code.

While here, fix a flaw where the AVX implementation would accept a
context using a byte swapped key schedule which it could not
handle. Also constify the IV and AAD pointers passed to
gcm_init{,_avx}().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Attila Fülöp <attila@fueloep.org>
Closes openzfs#14529
lundman pushed a commit to openzfsonwindows/openzfs that referenced this pull request Mar 16, 2023
gmac_init_ctx() duplicates most of the code in gcm_int_ctx() while
it just needs to set its own IV length and AAD tag length.

Introduce gcm_init_ctx_impl() which handles the GCM and GMAC
differences while reusing the duplicated code.

While here, fix a flaw where the AVX implementation would accept a
context using a byte swapped key schedule which it could not
handle. Also constify the IV and AAD pointers passed to
gcm_init{,_avx}().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Attila Fülöp <attila@fueloep.org>
Closes openzfs#14529
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants