Hello,

I'm seeing memory corruption when generating HMAC-SHA1 digests. This results in a crash or simply incorrect digests.

I also see in the debugger that macType has changed to '6' (54) after calling HmacSetKey. Not sure if that's normal.

Please see code and memory dumps below. Solution/Project files are attached.

Thank you in advance!

Environment

CyaSSL embedded SSL: v2.7.0 from the Github repo (clean, upgraded to VC++ 2012).
Compiler: Visual C++ 2012, update 3.
OS: Windows 8 (x64).

Testing was done using the "Debug" configuration.

Update #1

test1 reads from a file, and shows wrong results.

test2 initializes an array in memory. The result is correct, but the program crashes during debugging:

Run-Time Check Failure #2 - Stack around the variable 'key' was corrupted.

Code:

#include <cyassl/ctaocrypt/hmac.h>
#include <stdio.h>

#pragma comment(lib, "cyassl.lib")

void dump(const unsigned char* data, unsigned int length)
{
    int i = 0;
    for (; i < 20; ++i) {
        printf("%02x", data[i]);
    }
}

unsigned char* readFile(const char* filePath, size_t* fileSize) {
    FILE* fp;
    size_t n;
    size_t totalRead = 0;
    unsigned char* input;

    if (!(fp = fopen(filePath, "rb")))
        return 0;

    fseek(fp, 0, SEEK_END);
    *fileSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    input = (unsigned char*)malloc(*fileSize);
    while ((n = fread(input + totalRead, 1, 512, fp)) > 0) {
        totalRead += n;
    }

    return input;
}

void test1()
{
    unsigned char key[] = "0123456789abcdefghij";
    unsigned char input[249];
    unsigned char hash[SHA_DIGEST_SIZE];
    Hmac sha1;
    size_t keyLength;
    size_t inputLength;

    printf("--- Test 1 ---\n");

    memset(hash, 0xaa, SHA_DIGEST_SIZE); // Look for 0xaa in memory dump
    memset(&sha1, 0, sizeof(sha1));

    keyLength = strlen((char*)key);
    inputLength = sizeof(input);
    memset(input, 0, sizeof(input));

    HmacSetKey(&sha1, SHA, key, keyLength);
    HmacUpdate(&sha1, input, inputLength);
    HmacFinal(&sha1, hash);

    printf("Input length: %u bytes\n", inputLength);
    printf("Hash: ");
    dump(hash, sizeof(hash));
    printf("\n");
}

void test2()
{
    unsigned char key[] = "0123456789abcdefghij";
    unsigned char* input;
    unsigned char hash[SHA_DIGEST_SIZE];
    Hmac sha1;
    size_t keyLength;
    size_t inputLength;

    printf("--- Test 2 ---\n");

    memset(hash, 0xaa, SHA_DIGEST_SIZE); // Look for 0xaa in memory dump
    memset(&sha1, 0, sizeof(sha1));

    keyLength = strlen((char*)key);
    input = readFile("test.bin", &inputLength);

    HmacSetKey(&sha1, SHA, key, keyLength);
    HmacUpdate(&sha1, input, inputLength);
    HmacFinal(&sha1, hash);

    printf("Input length: %u bytes\n", inputLength);
    printf("Hash: ");
    dump(hash, sizeof(hash));
    printf("\n");
}

int main()
{
    test1();
    test2();
}

Update #2

test1:
Dump of input before calling HmacSetKey:

0x00CFF948  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF95C  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF970  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF984  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF998  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF9AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................

Dump again, but after calling HmacSetKey:

0x00CFF948  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................
0x00CFF95C  00 00 00 00 00 00 00 00 6c 6d 6e 6f 68 69 6a 6b 64 65 3d 3e  ........lmnohijkde=>
0x00CFF970  3f 38 39 3a 3b 34 35 36 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c  ?89:;456\\\\\\\\\\\\
0x00CFF984  5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c  \\\\\\\\\\\\\\\\\\\\
0x00CFF998  5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 00 00 00 00 00 00 00 00  \\\\\\\\\\\\........
0x00CFF9AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ....................

input was overwritten.

test2:
Dump of key before calling HmacSetKey:

0x010FFD98  30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66 67 68 69 6a  0123456789abcdefghij
0x010FFDAC  00 cc cc cc cc cc cc cc b3 8c 7e 8c 8c fe 0f 01 a8 15 c5 00  .ÌÌÌÌÌÌÌ.Œ~ŒŒþ..¨.Å.
0x010FFDC0  00 00 00 00 00 00 00 00 00 e0 1d 7f cc cc cc cc cc cc cc cc  .........à..ÌÌÌÌÌÌÌÌ
0x010FFDD4  cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ
0x010FFDE8  cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ
0x010FFDFC  cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

Dump again, but after calling HmacSetKey:

0x010FFD98  30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66 6c 6d 6e 6f  0123456789abcdeflmno
0x010FFDAC  68 69 6a 6b 64 65 3d 3e 3f 38 39 3a 3b 34 35 36 5c 5c 5c 5c  hijkde=>?89:;456\\\\
0x010FFDC0  5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c  \\\\\\\\\\\\\\\\\\\\
0x010FFDD4  5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c  \\\\\\\\\\\\\\\\\\\\
0x010FFDE8  cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ
0x010FFDFC  cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

key was overwritten.

Update #3

After replacing CyaSSL's HMAC-SHA1 implemention with the one from the following page, all problems disappeared. No crashing, and the digests are correct.

http://www.aarongifford.com/computers/sha.html

Thanks, Chris! smile

Chris, I hope you've not spent a lot of time on this.

I don't know the exact cause, but it seems like the issue is no more. Would love to blame it on a server issue I learned about later, because of the embarrassing possible truth. neutral

I was absolutely sure that I recompiled everything (wolfSSL and everything that uses wolfSSL) from scratch several times, so I was completely focused on wolfSSL, and blind to perhaps the most obvious thing. I still don't want to believe that I made such a stupid mistake, but it's a good chance that I did. neutral

Chris, sorry for making you work for nothing, and thank you for your efforts.

I'll look into it even more thoroughly and will hopefully not need to mention this again.

PS: Any chance this forum thread and especially my stupid messages can mysteriously go missing somehow? smile

Thank you, Chris!

Please let me know if there's anything I can do to help. smile

Hello,

Since wolfSSL embedded SSL v2.6.2, my program crashes in wolfSSL_CTX_load_verify_buffer(), which I use to load a CA cert. It's fine in v2.6.0.

I've also tested with the latest development code.

OS: Windows 8 x64
Compiler: VC++ 2012 (XP target)

Call stack:

     msvcr110d.dll!cmpDWORD(const void * lhs=0x030dccfc, const void * rhs=0x00000027) Line 104    C
     msvcr110d.dll!unaligned_memcmp(const unsigned char * bLHS=0x030dcd10, const unsigned char * bRHS=0x0000003b, unsigned int siz=20) Line 162    C
     msvcr110d.dll!memcmp(const void * lhs=0x030dccfc, const void * rhs=0x00000027, unsigned int siz=20) Line 269    C
>    sample_gui_app.exe!AlreadySigner(CYASSL_CERT_MANAGER * cm=0x00c197f8, unsigned char * hash=0x030dccfc) Line 1011    C
     sample_gui_app.exe!AddCA(CYASSL_CERT_MANAGER * cm=0x00c197f8, buffer der={...}, int type=1, int verify=0) Line 1114    C
     sample_gui_app.exe!ProcessBuffer(CYASSL_CTX * ctx=0x046ede90, const unsigned char * buff=0x0063d266, long sz=126326, int format=1, int type=4, CYASSL * ssl=0x00000000, long * used=0x030ddec0, int userChain=0) Line 1658    C
     sample_gui_app.exe!ProcessChainBuffer(CYASSL_CTX * ctx=0x046ede90, const unsigned char * buff=0x0063c930, long sz=128684, int format=1, int type=4, CYASSL * ssl=0x00000000) Line 1784    C
     sample_gui_app.exe!CyaSSL_CTX_load_verify_buffer(CYASSL_CTX * ctx=0x046ede90, const unsigned char * in=0x0063c930, long sz=128684, int format=1) Line 5041    C
     sample_gui_app.exe!aufw::web_api::sslContextCallback(void * ctx=0x046ede90) Line 43    C++

Here's some of my code, which has been working fine until v2.6.2 and later.

    // Load CA certificate from memory
    certificates::StartComCaCert cert;
    const unsigned char* certData = cert.GetData();
    CyaSSL_CTX_load_verify_buffer(
        reinterpret_cast<CYASSL_CTX*>(ctx),
        certData,
        cert.GetSize(),
        SSL_FILETYPE_PEM);

Update
Commit 98b7ed9: Last version that doesn't crash my program.
Commit 9dbf6a5: Crashes somewhere else.
Commit 05dd845: Crashes in AlreadySigner().

Call stack (commit 05dd845):

     msvcr110d.dll!cmpDWORD(const void * lhs=0x049bce70, const void * rhs=0x0000000f) Line 104    C
     msvcr110d.dll!unaligned_memcmp(const unsigned char * bLHS=0x049bce84, const unsigned char * bRHS=0x00000023, unsigned int siz=20) Line 162    C
     msvcr110d.dll!memcmp(const void * lhs=0x049bce70, const void * rhs=0x0000000f, unsigned int siz=20) Line 269    C
>    sample_gui_app.exe!AlreadySigner(CYASSL_CERT_MANAGER * cm=0x04acd768, unsigned char * hash=0x049bce70) Line 883    C
     sample_gui_app.exe!AddCA(CYASSL_CERT_MANAGER * cm=0x04acd768, buffer der={...}, int type=1, int verify=0) Line 942    C
     sample_gui_app.exe!ProcessBuffer(CYASSL_CTX * ctx=0x04acd938, const unsigned char * buff=0x00feb930, long sz=128684, int format=1, int type=4, CYASSL * ssl=0x00000000, long * used=0x049be290, int userChain=0) Line 1459    C
     sample_gui_app.exe!ProcessChainBuffer(CYASSL_CTX * ctx=0x04acd938, const unsigned char * buff=0x00feb930, long sz=128684, int format=1, int type=4, CYASSL * ssl=0x00000000) Line 1585    C
     sample_gui_app.exe!CyaSSL_CTX_load_verify_buffer(CYASSL_CTX * ctx=0x04acd938, const unsigned char * in=0x00feb930, long sz=128684, int format=1) Line 4008    C
     sample_gui_app.exe!aufw::web_api::sslContextCallback(void * ctx=0x04acd938) Line 43    C++

CA bundle used during testing, if needed:
http://www.startssl.com/certs/ca-bundle.pem

Thank you in advance!

6

(8 replies, posted in wolfSSL)

I see. Thanks.

I (as a user of the library) would actually very much appreciate the documentation regardless (with warnings if you prefer). If I have to use the ECB mode, then it's good to know that I *can* use wolfSSL after all, instead of looking elsewhere (wasting time and efforts).

When it's a matter of either using wolfSSL or ditching it completely for one of your competitors' library, don't you think everyone will benefit from this being documented? They've documented this, and I was close to ditch wolfSSL for my current project. smile

I think it would make your manual even more valuable if you had the documentation, warning/suggestion, etc. It allows it to teach its readers something important, if they happen to not know that ECB mode is insecure. I'm not suggesting that a whole page with details about this should be written.

What do you think? smile

7

(8 replies, posted in wolfSSL)

I see. Thanks. smile

You may know this already, but these functions and the ECB mode doesn't appear to be documented in the manual. smile

8

(8 replies, posted in wolfSSL)

Thank you very much, John!

Since these functions are not compiled by default, is there anything I should consider before/while using them (except that ECB mode isn't secure enough)?

I've confirmed that they work fine, but I guess there's a different reason why they're not compiled by default?

Thank you! smile

9

(8 replies, posted in wolfSSL)

Thank you for the reply, Chris!

Unfortunately, I have to adapt to a 3rd party system and whatever it uses.

If it requires a lot of effort to support the ECB mode, then please don't worry about it. Sadly, I must give up on using wolfSSL this time.

Thanks, again. smile

10

(8 replies, posted in wolfSSL)

Hello,

I'm working on a project that uses an SSL/crypto library, and I would like to make it compatible with wolfSSL embedded SSL as well. It makes use of AES encryption in ECB mode.

I was expecting functions named AesEcbEncrypt and AesEcbDecrypt, so I'm not quite sure how to do this correctly with wolfSSL. I did see the functions AES_ECB_encrypt/AES_ECB_decrypt.

I use mostly default settings when compiling wolfSSL.

Thank you in advance! smile