-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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 encryption tests #17089
ICP encryption tests #17089
Conversation
for what it's worth, I'd love to help with the refactor of the ICP code. I (now) at least have some component level understanding, and having some tests there would allow us to refactor a bit more fearlessly. This takes us in the right direction, methinks |
Looks like it's passing on the runners 👍
|
This commit adds tests that ensure that the ICP crypto_encrypt() and crypto_decrypt() produce the correct results for all implementations available on this platform. The actual ZTS scripts are simple drivers for the crypto_test program in it's "correctness" mode. This mode takes a file full of test vectors (inputs and expected outputs), runs them, and checks that the results are expected. It will run the tests for each implementation of the algorithm provided by the ICP. The test vectors are taken from Project Wycheproof, which provides a huge number of tests, including exercising many edge cases and common implementation mistakes. These tests are provided are JSON files, so a program is included here to convert them into a simpler line-based format for crypto_test to consume. crypto_test also has a "performance" mode, which will run simple benchmarks against all implementations provded by the ICP and output them for comparison. This is not used by ZTS, but is available to assist with development of new implementations of the underlying primitives. Thanks-to: Joel Low <joel@joelsplace.sg> Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris <robn@despairlabs.com>
IVs != 96 bits get hashed with GHASH to bring them to 96 bits. Any call to GHASH will mix the ghash state in gcm_ghash. This is expected to be zero at first use in an encrypt or decrypt operation, so it needs to be zeroed after using GHASH in setup. gcm_init() does this, but gcm_avx_init() zeroed it before setup, not after, resulting in incorrect encrypt/decrypt results when using AVX GCM with an IV != 96 bits. OpenZFS _always_ uses a 96 bit IV (ZIO_DATA_IV_LEN) so this will never have been hit in any real-world use, which is extremely fortunate, as we would have incorrectly-encrypted data on-disk. Still, as long as we have this code here we should make sure it's correct. Thanks-to: Joel Low <joel@joelsplace.sg> Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris <robn@despairlabs.com>
4a86451
to
550a246
Compare
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 didn't find some issues. And testing is always good.
Thanks a lot @robn 👍
Thanks everyone! I hope this will help make it much easier to improve our encryption code in the future. <3 |
Motivation and Context
I wanted to do a good review of #17058, but really had no idea how to without some way to compare the output with what we already have.
And then I went mad and ended up writing a whole correctness and performance test driver for the ICP. And then it found a real (though inconsequential) bug. Good times all round!
Thanks @lowjoel for motivation and rubber-ducking 👍
Description
The main commit adds tests that ensure that the ICP
crypto_encrypt()
andcrypto_decrypt()
produce the correct results for all implementations available on this platform.The actual ZTS scripts are simple drivers for the
crypto_test
program in it's "correctness" mode. This mode takes a file full of test vectors (inputs and expected outputs), runs them, and checks that the results are expected. It will run the tests for each implementation of the algorithm provided by the ICP.The test vectors are taken from Project Wycheproof, which provides a huge number of tests, including exercising many edge cases and common implementation mistakes. These tests are provided are JSON files, so a program is included here to convert them into a simpler line-based format for
crypto_test
to consume.crypto_test
also has a "performance" mode, which will run simple benchmarks against all implementations provded by the ICP and output them for comparison. This is not used by ZTS, but is available to assist with development of new implementations of the underlying primitives.AVX GCM bug fix
While get it working we found that the AVX GCM was producting the wrong results for IVs != 96 bits (12 bytes). In this case AES-GCM does a couple of GHASH rounds on the provided IV to bring it to 96 bits. The AVX setup did this, but didn't clear the GHASH state before finishing init, so it had leftover state from the IV setup.
Fortunately, OpenZFS always uses 96-bit IVs, so we've avoided this. Just points out more code that we carry but don't use, but that's for another PR.
How Has This Been Tested?
It's all tests!
The ZTS additions are simple wrappers around
crypto_test -c <testfile>
. Those have been run successfully on Linux and FreeBSD. (note that FreeBSD is still important here, as the ICP is used for userspace crypto).In "correctness" mode, it runs all the test vectors for each available implementation:
Because there's currently no way to find out what implementations the ICP has available, and I didn't want to add more to this than necessary, we just try them all. If the platform doesn't support them, it's at least nice about it:
If any of the test runs fail, the program will return non-zero, so it wires up to ZTS nicely.
For the performance mode, it'll do the usual thing of run all implementations on various input sizes and show a table:
More benchmarks with the hardware I available here: https://gist.github.com/robn/994f1618b4994b2f90dc8c7838fa5654. Some nice opportunities there!
Types of changes
Checklist:
Signed-off-by
.