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

fix aesccm when using m2crypto #410

Merged
merged 2 commits into from
Jun 1, 2020

Conversation

inikolcev
Copy link
Collaborator

@inikolcev inikolcev commented May 26, 2020

fixes #406

The first issue was that the CBC IV was not reset properly which is now handled by the setter.
The second issue was with the _8 ciphers where the authentication value was not padded before going through CTR.


This change is Reviewable

Copy link
Member

@tomato42 tomato42 left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 2 files at r1.
Reviewable status: 1 of 2 files reviewed, 2 unresolved discussions (waiting on @inikolcev)

a discussion (no related file):
test coverage for this?



tlslite/utils/aesccm.py, line 109 at r1 (raw file):

            assert self.tagLength == 8
            self._pad_with_zeroes(mac, 16)
            auth_value = self._ctr.encrypt(mac)[:-8]

why -8 and not 8?

Copy link
Member

@tomato42 tomato42 left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 2 files at r1.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @inikolcev)

@tomato42 tomato42 added the bug unintented behaviour in tlslite-ng code label May 26, 2020
@inikolcev
Copy link
Collaborator Author

I added tests that open/seal 2 messages one after another for both openssl and python and both 16 and 8 tags. This should help us catch errors like not proprely reseting IV or not properly incrementing the counter.

Copy link
Collaborator Author

@inikolcev inikolcev left a comment

Choose a reason for hiding this comment

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

Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on @inikolcev and @tomato42)


tlslite/utils/aesccm.py, line 109 at r1 (raw file):

Previously, tomato42 (Hubert Kario) wrote…

why -8 and not 8?

Changed it to 8

Copy link
Member

@tomato42 tomato42 left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 1 files at r2, 1 of 1 files at r3.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @inikolcev)


unit_tests/test_tlslite_utils_aesccm.py, line 410 at r3 (raw file):

            self.assertEqual(ciphertext, encData)

        def test_open_multiple_messages(self):

isn't this incorrectly indented?


unit_tests/test_tlslite_utils_aesccm.py, line 452 at r3 (raw file):

                                     b'\xda\xaa\xc0\xa9\'\xb3\xd5\x12\xa2\x1fF,'
                                     b'\x8e\x04\xf5{\xf8\xfdN\xfe\xe2\xe9x\xfe1'
                                     b'\x175\xa6\xc4\\Q3\x80\xf4\xcaR\x8c')]

those are the same variables as in test_seal_multiple_messages, wouldn't it be better to move those two tests to a separate class and use class variables to store them, to clearly show that one test is the inverse of the other?


unit_tests/test_tlslite_utils_aesccm.py, line 548 at r3 (raw file):

                                 b'\'\xb3\xd5\x12\xa2\x1fF,\x8e\x04'
                                 b'\xf5{\xf8\xfdN\xfe\xe2\xde\xb8\x0e'
                                 b'\xb6\xb6M+\x02')]

same here, redefines variables from test_seal_multiple_messages_small_tag instead of reusing them


unit_tests/test_tlslite_utils_aesccm.py, line 856 at r3 (raw file):

                                     b'\'\xb3\xd5\x12\xa2\x1fF,\x8e\x04'
                                     b'\xf5{\xf8\xfdN\xfe\xe2\xde\xb8\x0e'
                                     b'\xb6\xb6M+\x02')]

the openssl tests should definitely use the same variables as the python tests, to show that they create and process ciphertext the same way

@tomato42
Copy link
Member

I added tests that open/seal 2 messages one after another for both openssl and python and both 16 and 8 tags. This should help us catch errors like not proprely reseting IV or not properly incrementing the counter.

how those tests do that? Don't we need to encrypt two same plaintexts to show that a new IV is used (as it will result in different ciphertexts)? Don't we need to encrypt two blocks of identical plaintext to show that the counter is incremented (as that will show two different blocks of ciphertext)?

@inikolcev
Copy link
Collaborator Author

I added tests that open/seal 2 messages one after another for both openssl and python and both 16 and 8 tags. This should help us catch errors like not proprely reseting IV or not properly incrementing the counter.

how those tests do that? Don't we need to encrypt two same plaintexts to show that a new IV is used (as it will result in different ciphertexts)? Don't we need to encrypt two blocks of identical plaintext to show that the counter is incremented (as that will show two different blocks of ciphertext)?

Here I'm talking about the CBC-MAC IV which should always be 0. This was why it was not working properly with openssl before, because after the first message it was not being reset to 0 properly, and the current tests didn't catch it because they only open/seal 1 message, and it never came to using the non 0 IV after the first message. Encrypting/decrypting 2 or more messages should ensure us that the IV is properly reset to 0.

@tomato42
Copy link
Member

tomato42 commented May 27, 2020

so encrypting the same plaintext with the same key and nonce wouldn't create the same ciphertext? so a test should actually use the same object to encrypt the same plaintext twice and compare outputs of those, to check if they are identical?

what about the counter?

@inikolcev
Copy link
Collaborator Author

Encrypting the same plaintext with the same key and same nonce will create the same ciphertext, why do you think it wouldn't?
Yeah encrypting the same plaintext twice is another way to do it, but it doesn't matter what the second plaintext is as long we encrypt two messages with the same object and get the correct ciphertext for the second message.

I was thinking the same way for the counter, it is reset after each message, if we regress down the line and not reset properly after the first message, this should catch it.
I'll rewrite the tests to reuse the variables later today.

@tomato42
Copy link
Member

Encrypting the same plaintext with the same key and same nonce will create the same ciphertext, why do you think it wouldn't?

my point is that the old code wouldn't do that, would it? It would produce two different ciphertexts on encryption, no?

Yeah encrypting the same plaintext twice is another way to do it, but it doesn't matter what the second plaintext is as long we encrypt two messages with the same object and get the correct ciphertext for the second message.

yes, using known good second ciphertext will work, but the test doesn't make it apparent that:

  • running the same instance over the same data will produce the same outputs
  • that the second output is known-good

or to put it other way: yes, the test does test what it should test but it isn't obvious why it does test what it should

I was thinking the same way for the counter, it is reset after each message, if we regress down the line and not reset properly after the first message, this should catch it.

aah, so it's for handling possible bugs, not present ones, got it

@inikolcev inikolcev force-pushed the fix_openssl_aesccm branch 2 times, most recently from 52adb5b to c96ac2f Compare May 31, 2020 21:32
@inikolcev
Copy link
Collaborator Author

Moved the tests to a separate class and made it to use the same plaintext/ciphertext twice.

Copy link
Member

@tomato42 tomato42 left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 1 files at r4.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @inikolcev)


unit_tests/test_tlslite_utils_aesccm.py, line 547 at r4 (raw file):

            self.assertEqual(self.plaintext, decData)

    if m2cryptoLoaded:

why not @unittest.skipUnless(m2cryptoLoaded)?

@inikolcev
Copy link
Collaborator Author

Reviewed 1 of 1 files at r4.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @inikolcev)

unit_tests/test_tlslite_utils_aesccm.py, line 547 at r4 (raw file):

            self.assertEqual(self.plaintext, decData)

    if m2cryptoLoaded:

why not @unittest.skipUnless(m2cryptoLoaded)?

No reason really, just didn't think of it. I changed it to use skipUnless.

Copy link
Member

@tomato42 tomato42 left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 1 files at r5.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

@tomato42
Copy link
Member

tomato42 commented Jun 1, 2020

looks good, feel free to merge as soon as Travis passes. Thanks!

@inikolcev inikolcev merged commit 7c6fbf9 into tlsfuzzer:master Jun 1, 2020
@inikolcev inikolcev deleted the fix_openssl_aesccm branch June 1, 2020 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug unintented behaviour in tlslite-ng code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AES-CCM ciphers don't interoperate any more
2 participants