bitwiseshiftleft / sjcl

Stanford Javascript Crypto Library

Home Page:http://bitwiseshiftleft.github.com/sjcl/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RIPEMD160 HMAC wrong result

guidovranken opened this issue · comments

{
    var cleartext = sjcl.codec.hex.toBits("0110000000c1dedda93605a0718000002100000030e6983de412000053796d626f6c2e6974567261746f720105000000002e0060006a4b3f00000094ffffff05d5f8000000000000f6000000000000210000003ce698e43237b7b053800bec8ffb0000332d4f7de515df76cf");
    var key = sjcl.codec.hex.toBits("003f8000000033304f7de515df76cf2b1a010500000020");
    var hmac = new sjcl.misc.hmac(key, sjcl.hash.ripemd160);
    var ret = sjcl.codec.hex.fromBits(hmac.encrypt(cleartext));
    console.log(ret);
}

Expected:

ce6525bffa612b826d3854ebfd37299abaee26ec

Actual result:

59ff1d603172e9d4d796f54b566febb41d7606c1

sjcl was configured with --with-ripemd160.

Reproducer for Botan

#include <botan/mac.h>
#include <string>
#include <stdlib.h>

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

int main(int argc, char** argv)
{
    const uint8_t key[] = {0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x33, 0x30, 0x4f, 0x7d, 0xe5, 0x15, 0xdf, 0x76, 0xcf, 0x2b, 
                           0x1a, 0x01, 0x05, 0x00, 0x00, 0x00, 0x20};
    const uint8_t input[] = {0x01, 0x10, 0x00, 0x00, 0x00, 0xc1, 0xde, 0xdd, 0xa9, 0x36, 0x05, 0xa0, 0x71, 0x80, 0x00, 0x00, 
                             0x21, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x98, 0x3d, 0xe4, 0x12, 0x00, 0x00, 0x53, 0x79, 0x6d, 0x62, 
                             0x6f, 0x6c, 0x2e, 0x69, 0x74, 0x56, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x01, 0x05, 0x00, 0x00, 0x00, 
                             0x00, 0x2e, 0x00, 0x60, 0x00, 0x6a, 0x4b, 0x3f, 0x00, 0x00, 0x00, 0x94, 0xff, 0xff, 0xff, 0x05, 
                             0xd5, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 
                             0x00, 0x00, 0x00, 0x3c, 0xe6, 0x98, 0xe4, 0x32, 0x37, 0xb7, 0xb0, 0x53, 0x80, 0x0b, 0xec, 0x8f, 
                             0xfb, 0x00, 0x00, 0x33, 0x2d, 0x4f, 0x7d, 0xe5, 0x15, 0xdf, 0x76, 0xcf};

    std::unique_ptr<::Botan::MessageAuthenticationCode> hmac = nullptr;

    try {
        /* Initialize */
        {
            CF_CHECK_NE(hmac = ::Botan::MessageAuthenticationCode::create("HMAC(RIPEMD-160)"), nullptr);
            hmac->set_key(key, sizeof(key));
        }

        hmac->update(input, sizeof(input));

        /* Finalize */
        {
            const auto res = hmac->final();
            for (size_t i = 0; i < res.size(); i++) {
                printf("%02x", res[i]);
            }
            printf("\n");
        }

    } catch ( ... ) { }
end:
    return 0;
}

Reproducer for OpenSSL

#include <openssl/hmac.h>
int main(void)
{
    unsigned char out[20];
    const unsigned char key[] = {0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x33, 0x30, 0x4f, 0x7d, 0xe5, 0x15, 0xdf, 0x76, 0xcf, 0x2b, 
                           0x1a, 0x01, 0x05, 0x00, 0x00, 0x00, 0x20};
    const unsigned char input[] = {0x01, 0x10, 0x00, 0x00, 0x00, 0xc1, 0xde, 0xdd, 0xa9, 0x36, 0x05, 0xa0, 0x71, 0x80, 0x00, 0x00, 
                             0x21, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x98, 0x3d, 0xe4, 0x12, 0x00, 0x00, 0x53, 0x79, 0x6d, 0x62, 
                             0x6f, 0x6c, 0x2e, 0x69, 0x74, 0x56, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x01, 0x05, 0x00, 0x00, 0x00, 
                             0x00, 0x2e, 0x00, 0x60, 0x00, 0x6a, 0x4b, 0x3f, 0x00, 0x00, 0x00, 0x94, 0xff, 0xff, 0xff, 0x05, 
                             0xd5, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 
                             0x00, 0x00, 0x00, 0x3c, 0xe6, 0x98, 0xe4, 0x32, 0x37, 0xb7, 0xb0, 0x53, 0x80, 0x0b, 0xec, 0x8f, 
                             0xfb, 0x00, 0x00, 0x33, 0x2d, 0x4f, 0x7d, 0xe5, 0x15, 0xdf, 0x76, 0xcf};
    unsigned int out_len = sizeof(out);
    if ( HMAC(EVP_ripemd160(), key, sizeof(key), input, sizeof(input), out, &out_len) == NULL ) {
        abort();
    }
    for (unsigned int i = 0; i < out_len; i++) {
        printf("%02x", out[i]);
    }
    printf("\n");
    return 0;
}