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

crypto: fix edge case in authenticated encryption #22828

Closed
wants to merge 3 commits into from

Conversation

tniessen
Copy link
Member

@tniessen tniessen commented Sep 12, 2018

Restricting the authentication tag length and calling update or setAAD before setAuthTag caused an incorrect authentication tag to be passed to OpenSSL: The auth_tag_len_ field was already set, so the implementation assumed that the tag itself was known as well. This change allows the implementation to distinguish between knowing the tag length and the tag itself using the auth_tag_state_ field which replaces the auth_tag_set_ field.

This also allows #22538 to work for OCB! Sadly, CCM won't work without changes within OpenSSL and they probably won't change that due to a more or less related NIST recommendation.

This should finally fix #22421.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

Restricting the authentication tag length and calling update or
setAAD before setAuthTag caused an incorrect authentication tag to
be passed to OpenSSL: The auth_tag_len_ field was already set, so
the implementation assumed that the tag itself was known as well.
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. labels Sep 12, 2018
@tniessen
Copy link
Member Author

@addaleax I updated it so it matches the old behavior (which isn't optimal).

@@ -363,6 +363,12 @@ class CipherBase : public BaseObject {
kErrorMessageSize,
kErrorState
};
enum AuthTagState {
kAuthTagUnknown,
kAuthTagLengthKnown,
Copy link
Member

Choose a reason for hiding this comment

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

Is there currently a difference between these two states? Sorry for asking questions, but I’m not sure I’m fully qualified to review this…

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, you can use GCM (e.g. aes-128-gcm) without specifying the authentication tag length, then the state will be kAuthTagUnknown, but other modes such as CCM (aes-128-ccm) and OCB (aes-128-ocb) require the length of the authentication tag in advance (via the authTagLength option), so the cipher will start in the state kAuthTagLengthKnown. Once the user calls setAuthTag, the state becomes kAuthTagKnown, which implies that the length is known as well.

(Never apologize for asking questions. 😉)

Copy link
Member

Choose a reason for hiding this comment

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

Thank you! Is there any difference in how we treat those states after they have been entered?

Copy link
Member Author

@tniessen tniessen Sep 14, 2018

Choose a reason for hiding this comment

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

Technically, we do. But:
If auth_tag_state_ is either kAuthTagUnknown or kAuthTagLengthKnown, then auth_tag_state_ == kAuthTagUnknown iff auth_tag_len_ == kNoAuthTagLength. So you are right, we could totally drop the second state! (Or remove kNoAuthTagLength.)

@danbev
Copy link
Contributor

danbev commented Sep 18, 2018

@tniessen
Copy link
Member Author

Thank you, @danbev and @addaleax! Landed in a9e7369.

@tniessen tniessen closed this Sep 18, 2018
tniessen added a commit that referenced this pull request Sep 18, 2018
Restricting the authentication tag length and calling update or
setAAD before setAuthTag caused an incorrect authentication tag to
be passed to OpenSSL: The auth_tag_len_ field was already set, so
the implementation assumed that the tag itself was known as well.

PR-URL: #22828
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
targos pushed a commit that referenced this pull request Sep 18, 2018
Restricting the authentication tag length and calling update or
setAAD before setAuthTag caused an incorrect authentication tag to
be passed to OpenSSL: The auth_tag_len_ field was already set, so
the implementation assumed that the tag itself was known as well.

PR-URL: #22828
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
targos pushed a commit that referenced this pull request Sep 19, 2018
Restricting the authentication tag length and calling update or
setAAD before setAuthTag caused an incorrect authentication tag to
be passed to OpenSSL: The auth_tag_len_ field was already set, so
the implementation assumed that the tag itself was known as well.

PR-URL: #22828
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
targos pushed a commit that referenced this pull request Sep 20, 2018
Restricting the authentication tag length and calling update or
setAAD before setAuthTag caused an incorrect authentication tag to
be passed to OpenSSL: The auth_tag_len_ field was already set, so
the implementation assumed that the tag itself was known as well.

PR-URL: #22828
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

crypto Decipher: setAuthTag() must be called before update()
4 participants