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

Make aes_hw_ctr32_encrypt_blocks handle len=0 correctly #1690

Merged
merged 16 commits into from
Aug 2, 2024

Conversation

nebeid
Copy link
Contributor

@nebeid nebeid commented Jul 5, 2024

Issues:

Resolves #CryptoAlg-2498

Description of changes:

aes_hw_ctr32_encrypt_blocks encrypts (and writes to the output) 2 blocks when the input length is 0 blocks in the case of AArch64 and 1 block in the case of x86_64 and x86.
The function is guarded wherever it's called by checks that len != 0.
This change fixes this behaviour without taxing the performance.

Testing:

Tested the performance on Graviton3 and on Mac x86_64.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@nebeid nebeid requested a review from a team as a code owner July 5, 2024 22:00
@codecov-commenter
Copy link

codecov-commenter commented Jul 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 78.34%. Comparing base (916b3d1) to head (2e37583).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1690      +/-   ##
==========================================
- Coverage   78.35%   78.34%   -0.01%     
==========================================
  Files         573      573              
  Lines       96123    96129       +6     
  Branches    13780    13780              
==========================================
- Hits        75318    75317       -1     
- Misses      20200    20205       +5     
- Partials      605      607       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@andrewhop andrewhop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test that calls aes_hw_ctr32_encrypt_blocks with a length of zero and verifies the input/output buffers aren't modified. Does address sanitizer find this original issue without this change?

@nebeid
Copy link
Contributor Author

nebeid commented Jul 24, 2024

Can you add a test that calls aes_hw_ctr32_encrypt_blocks with a length of zero and verifies the input/output buffers aren't modified. Does address sanitizer find this original issue without this change?

Yeah, I had added the test here 69b858a with printouts to verify for myself. I reverted that commit which included the fix for x86 (due to performance regression). I can add back the test #ifdefed for AArch64.

@nebeid
Copy link
Contributor Author

nebeid commented Jul 24, 2024

amazonlinux2023_gcc11x_aarch_valgrind complained

[ RUN      ] AESTest.ABI
==3382== Conditional jump or move depends on uninitialised value(s)
==3382==    at 0x504B60: bssl::internal::operator==(bssl::Span<unsigned char const>, bssl::Span<unsigned char const>) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x5039EB: operator==(Bytes const&, Bytes const&) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x510C5F: testing::AssertionResult testing::internal::CmpHelperEQ<Bytes, Bytes>(char const*, char const*, Bytes const&, Bytes const&) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x504E83: testing::AssertionResult testing::internal::EqHelper::Compare<Bytes, Bytes, (void*)0>(char const*, char const*, Bytes const&, Bytes const&) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x697383: AESTest_ABI_Test::TestBody() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8F25BF: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8ED0D3: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8D1ACB: testing::Test::Run() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8D21C3: testing::TestInfo::Run() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8D28A7: testing::TestSuite::Run() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8DB943: testing::internal::UnitTestImpl::RunAllTests() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==    by 0x8F3593: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382==  Uninitialised value was created by a stack allocation
==3382==    at 0x696764: AESTest_ABI_Test::TestBody() (in /codebuild/output/src1610932754/src/github.com/aws/aws-lc/test_build_dir/crypto/crypto_test)
==3382== 
[       OK ] AESTest.ABI (54 ms)

and still complained after comparing std::string instead of Bytes.
It needed initialising buf.

in amazonlinux2023_gcc11x_aarch_valgrind.
nebeid and others added 3 commits July 26, 2024 11:34
Prior to the fix, the first block was written to when
the number of input blocks is 0.
The test for this case is no longer restricted to AArch64.
It should not actually affect the performance.
@nebeid nebeid requested a review from andrewhop July 26, 2024 20:11
for (size_t i = 0; i < 64; i++) {
buf[i] = i;
}
Bytes buf_before = Bytes(buf,64);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bytes/span doesn't create a copy of the data, they reference the original memory. So this test passes even if aes_hw_encrypt touches buf. For example this passes:

TEST(BytesTest, copyOrClone) {
  uint8_t buf[64] = {0};
  Bytes buf_before = Bytes(buf,64);
  buf[0] = 1;
  ASSERT_EQ(buf_before, Bytes(buf, 64));
}

Copy link
Contributor Author

@nebeid nebeid Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Andrew. I brought back the string comparison I had when I was testing in 110ab16.

@@ -1234,6 +1234,7 @@ sub aesni_generate8 {

.align 16
.Lctr32_bulk:
jb .Lctr32_epilogue # if $len < 1, go to done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be right after cmp in line 1216?

@nebeid nebeid changed the title Make aes_hw_ctr32_encrypt_blocks (AArch64) handle len=0 correctly Make aes_hw_ctr32_encrypt_blocks handle len=0 correctly Aug 2, 2024
@nebeid nebeid merged commit b929d74 into aws:main Aug 2, 2024
116 of 117 checks passed
@nebeid nebeid deleted the ctr32-armv8 branch August 2, 2024 18:07
pennyannn added a commit to pennyannn/LNSym-public that referenced this pull request Aug 6, 2024
shigoel pushed a commit to leanprover/LNSym that referenced this pull request Aug 6, 2024
### Description:

This PR updates program and tests for `aes_hw_ctr32_encrypt_blocks`
based on the fix of a bug from the PR
aws/aws-lc#1690

### Testing:

What tests have been run? Did `make all` succeed for your changes? Was
conformance testing successful on an Aarch64 machine? Yes for both.

### License:

By submitting this pull request, I confirm that my contribution is
made under the terms of the Apache 2.0 license.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants