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

EVP_cast5_cfb master/1.1.1.f encryption output discrepancy #11459

Closed
guidovranken opened this issue Apr 1, 2020 · 3 comments
Closed

EVP_cast5_cfb master/1.1.1.f encryption output discrepancy #11459

guidovranken opened this issue Apr 1, 2020 · 3 comments
Assignees
Labels
issue: bug report The issue was opened to report a bug

Comments

@guidovranken
Copy link
Contributor

This is a reproducer for OSS-Fuzz bug https://oss-fuzz.com/testcase-detail/5088449485078528

#include <vector>
#include <openssl/evp.h>

#define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
#define CF_CHECK_NE(expr, res) if ( (expr) == (res) ) { goto end; }

std::vector<unsigned char> openssl(const std::vector<unsigned char>& cleartext, const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv) {
    std::vector<unsigned char> out(16);

    const EVP_CIPHER* cipher = nullptr;
    EVP_CIPHER_CTX* ctx = nullptr;

    CF_CHECK_NE(cipher = EVP_cast5_cfb(), nullptr);
    CF_CHECK_NE(ctx = EVP_CIPHER_CTX_new(), nullptr);
    CF_CHECK_EQ(EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr), 1);
    CF_CHECK_EQ(EVP_EncryptInit_ex(ctx, nullptr, nullptr, key.data(), iv.data()), 1);
    {
        size_t outIdx = 0;
        int len = -1;

        CF_CHECK_EQ(EVP_EncryptUpdate(ctx, out.data() + outIdx, &len, cleartext.data(), cleartext.size()), 1);
        outIdx += len;

        CF_CHECK_EQ(EVP_EncryptFinal_ex(ctx, out.data() + outIdx, &len), 1);
        outIdx += len;
    }

end:
    EVP_CIPHER_CTX_free(ctx);
    
    return out;
}

int main(void)
{
    const std::vector<unsigned char> cleartext = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
    const std::vector<unsigned char> key = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20};
    const std::vector<unsigned char> iv = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff};

    const auto openssl_out = openssl(cleartext, key, iv);

    for (size_t i = 0; i < openssl_out.size(); i++) {
        printf("%02X ", openssl_out[i]);
    }
    printf("\n");

    return 0;
}

Output when compiled against master branch:

CF 90 97 8A 85 CD 20 7D 6F 73 49 2F 30 EF 7D A9

Output when compiled against 1.1.1f:

62 F5 FE 05 67 8E 82 C6 76 42 E1 A7 54 89 53 10

The latter is probably the correct one as this is consistent with Crypto++.

@guidovranken guidovranken added the issue: bug report The issue was opened to report a bug label Apr 1, 2020
@slontis slontis self-assigned this May 2, 2020
@slontis
Copy link
Member

slontis commented May 2, 2020

Will have a look - there are other KAT tests for cast so this is a bit strange.

@slontis
Copy link
Member

slontis commented May 2, 2020

Hmm this works as a test vector in evp_test.. Must be the sequence of calls.

@slontis
Copy link
Member

slontis commented May 2, 2020

The default keylength is wrong for 2 of the modes.. Fixing it up now.

slontis added a commit to slontis/openssl that referenced this issue May 2, 2020
Fixes openssl#11459

It was incorrectly using 8 bytes instead of 16 as the default.
This was verified by expanding the macros used in e_cast.c.
The issue occurs if EVP_CIPHER_CTX_set_key_length() is not called.
evp_test.c hides this issue as it always calls EVP_CIPHER_CTX_set_key_length() before
using EVP_CipherInit_ex(...., key, ..).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue: bug report The issue was opened to report a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants