Skip to content

OpenSSL 1.1.0 read pipeline logic regressed constant-time CBC unpad code #1438

@davidben

Description

@davidben

It seems the master branch may have broke the Lucky 13 fix. In 94777c9, the code around tls1_cbc_remove_padding was changed to:

            for (ctr = 0; ctr < numpipes; ctr++) {
                tmpret = tls1_cbc_remove_padding(s, &recs[ctr], bs, mac_size);
                if (tmpret == -1)
                    return -1;
                ret &= tmpret;
            }

However, tls1_cbc_remove_padding is documented to return:

 *   0: (in non-constant time) if the record is publicly invalid.
 *   1: if the padding was valid
 *  -1: otherwise.

0 is the return value for publicly invalid (and that ssl3_cbc_digest_record's preconditions are not satisfied and must not be called). 1 and -1 must be handled in timing-independent code, not 1 and 0.

I don't understand the pipelining code, but there might even be a crash here. ssl3_cbc_copy_mac and ssl3_cbc_digest_record rely on tls_cbc_remove_padding to ensure some preconditions are met. (The preconditions fail when the record is publicly invalid, so it works out.) But since tmpret is short-circuited, if a later record is publicly invalid, the caller won't notice.

By the way, this return convention is kind of confusing, so I just made this change in BoringSSL to make it a bit clearer:
https://boringssl.googlesource.com/boringssl/+/3f26a49eb6de454cd81ae5e58e621084cd7d645c%5E%21/
(Note that patch won't be directly applicable. Our code here's diverged significantly. Notably, in OpenSSL, this also interacts with tls1_enc's return value, while we do the decrypt and MAC check in one operation. We've also hidden all the legacy ciphers behind fake "AEAD"s which is why it's in libcrypto.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions