Skip to content

Comments

TLSv1.3: Use TLSv1.3 style nonce construction (new approach)#1947

Closed
mattcaswell wants to merge 7 commits intoopenssl:masterfrom
mattcaswell:tls1_3-ivs-alt
Closed

TLSv1.3: Use TLSv1.3 style nonce construction (new approach)#1947
mattcaswell wants to merge 7 commits intoopenssl:masterfrom
mattcaswell:tls1_3-ivs-alt

Conversation

@mattcaswell
Copy link
Member

@mattcaswell mattcaswell commented Nov 17, 2016

Checklist
  • tests are added or updated
  • CLA is signed
Description of change

This is an alternative approach to that in #1940. Here we use the existing AEAD interface to libcrypto, rather than modifying the existing <=TLS1.2 cipher implementation in libcrypto. This goes slightly further than #1940 in that it actually starts to use the new nonce construction in the encryption of records. Due to the differing approach I have had to implement a new test for this as well.

Copy link
Contributor

@davidben davidben left a comment

Choose a reason for hiding this comment

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

With the caveat that I'm not familiar this code and can only give a cursory look, I think this is a much better approach. Probably worth doing something similar to the 1.2 code at some point too. (Though I guess you have to keep EVP_CTRL_AEAD_TLS1_AAD around for stability reasons...)

Copy link
Contributor

Choose a reason for hiding this comment

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

Since none of these will ever set read_hash and thus never hit the MAC code and also will never hit the constant-time CBC business, I believe the 0 / -1 distinction and constant-time worries aren't meaningful. (Hopefully once the refactoring in #1438 happens, it'll be less confusing.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Er, I guess that bug is talking about lots of different things. By "the refactoring in #1438" I mean folding tls1_mac into tls1_enc, so that you always do encrypt + MAC checks as a unit, rather than the one to tidy up tls1_cbc_remove_padding's return value.

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps not, although the return code values need to be consistent between tls1_enc and tls13_enc because this gets called by this line in ssl3_get_record() which has no awareness of TLSv1.3:

    enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
    /*-
     * enc_err is:
     *    0: (in non-constant time) if the record is publically invalid.
     *    1: if the padding is valid
     *    -1: if the padding is invalid
     */
    if (enc_err == 0) {
        al = SSL_AD_DECRYPTION_FAILED;
        SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
        goto f_err;
    }

I guess the difference is that 0 means a failure occurred before we even attempted to decrypt because it is clearly wrong before we even start, a -1 means some failure occurred after decryption was attempted. 0 gets you decryption_failed, while -1 gets you bad_record_mac. I'm not sure whether we care about that difference or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Glancing at tls1_enc, I think this wants to be -1?

Copy link
Contributor

Choose a reason for hiding this comment

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

(The only zero return in tls1_enc is when tls1_cbc_remove_padding returns 0. This matches ssl3_get_record which sets SSL_R_BLOCK_CIPHER_PAD_IS_WRONG on zero return.)

Copy link
Member Author

Choose a reason for hiding this comment

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

The thinking here is that this goes into the category of "publicly invalid" (which is defined as a 0 return). We have received an encrypted record that is shorter than the tag length.

@mattcaswell mattcaswell mentioned this pull request Nov 21, 2016
2 tasks
@mattcaswell
Copy link
Member Author

New commit added to this to fix a Travis failure.

Copy link
Contributor

Choose a reason for hiding this comment

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

You get a double-free after this, if you don't add here a *key = NULL;

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. Thanks.

@mattcaswell
Copy link
Member Author

New commits pushed. Fixed another Travis failure, and a double free in tls13encryptiontest.

@mattcaswell
Copy link
Member Author

I rebased this on the latest master. All commits in this PR are now for review.

@mattcaswell
Copy link
Member Author

I rebased again to pick up the latest master travis fixes.

@mattcaswell
Copy link
Member Author

Rebased again. Ping?

Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a comment that OPENSSL_malloc returns NULL if size is zero (since that's not guaranteed by regular malloc).

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

squash to a single comment line.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

move up to the decl? it's what we usually do. or if not, then remove the blank line before the if.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

"can't" --> "doesn't"

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

that looks longer than 509 chars and will therefore break on some platforms. and you need a comment saying how this data was generated or where it came from.

Copy link
Member Author

Choose a reason for hiding this comment

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

They came from: https://www.ietf.org/id/draft-thomson-tls-tls13-vectors-01.txt

I added a comment for that. The 509 chars thing is problematic...I might need to make a few changes to get around that. I'll give it some thought.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe look at what I did in #1775 about gluing things together.

Copy link
Contributor

Choose a reason for hiding this comment

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

I know you don't like it, but "if ((a=..)==NULL" is the construct we use throughout the rest of the code.

Copy link
Member Author

Choose a reason for hiding this comment

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

No we don't!!!! There are examples of that, sure. But there are plenty of examples where we don't. It is definitely not our standard, and it isn't in our style guide. There are occasions where it makes sense, but those are rare and this isn't one of them.

Copy link
Contributor

Choose a reason for hiding this comment

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

interestingly, you're right that it's not style:

; g grep 'if.*==.*NULL' > /tmp/x
; wc /tmp/x
  3056  20404 156963 /tmp/x
; grep '=.*==' /tmp/x | wc
    939    8288   64894

Copy link
Contributor

Choose a reason for hiding this comment

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

If you're going to keep this multi-line comment, then the blank lines between the memcpy and the EVP_CIPHER setup should be removed. Comments should go only for a single "paragraph" of code ... Or split into three comments.

Copy link
Member Author

Choose a reason for hiding this comment

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

I split it into three.

Copy link
Contributor

Choose a reason for hiding this comment

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

remove this blank line, it's part of the same paragraph as above.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think you mean the one between tls13_enc() and test_record(), rather than this one...at least that makes more sense to me in terms of paragraphs of code - so I removed that one.

Copy link
Contributor

Choose a reason for hiding this comment

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

remove this blank line too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

move this blank line to just before the err label :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@mattcaswell
Copy link
Member Author

I pushed a new commit to address the feedback so far and rebased to pick up the encrypt-then-mac test fix from master. I've not yet addressed the 509 char limit thing, or the index vs pointer thing. They need a bit more thought.

@richsalz
Copy link
Contributor

the 509 char and the index/pointer are my only remaining concerns.

@richsalz
Copy link
Contributor

(comment hidden because the commit got superceeded). A point is better; see http://doc.cat-v.org/bell_labs/pikestyle on "the use of pointers"

@mattcaswell
Copy link
Member Author

A point is better; see http://doc.cat-v.org/bell_labs/pikestyle on "the use of pointers"

That's a good essay. I don't agree with all of it, but there are some useful rules in there. I particularly like rule 6 in the "Complexity" section. :-)

…ndex

We also split the long string literals into 3 to avoid problems where we
go over the 509 character limit.
@mattcaswell
Copy link
Member Author

New commits pushed. The first one deals with the 509 character limit problem, and converts it to pass a pointer around not an index. The second commit marks refdata as static to avoid a clang issue.

@richsalz
Copy link
Contributor

+1

@mattcaswell
Copy link
Member Author

Pushed. Thanks.

@mattcaswell mattcaswell closed this Dec 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants