Incorrect SHA digest for very long messages when using kernel crypto

Viewed 59

I'm trying to compute the hash digest using SHA-1 using kernel crypto. I get the right results for messages under 4096 bytes. Anything beyond that is incorrect. The test itself does not fail but gives incorrect responses.

Comparison of kernel crypto versus OpenSSL

Left side shows output from OpenSSL and right side for kernel crypto. The reason I know left side (OpenSSL) gives right results is because the results were validated by a lab. In the image, the message length is 32984 which is 4123 bytes.

My code is shown below:

int numpages = (msgLength / PAGE_SIZE);
if ( msgLength % PAGE_SIZE )
    numpages++; // Overflow

struct crypto_shash *tfm = NULL;
struct shash_desc *desc = NULL;
unsigned char *page_msg[numpages];
unsigned char *page_hash;
int i, msg_remaining;

tfm = crypto_alloc_shash("sha1", 0, 0);

desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
    if (!desc) {
        LOG_ERROR("Unable to allocate struct shash_desc\n");
        goto free_return;
    }

desc->tfm = tfm;
desc->flags = 0;

// temporary storage for hash in block-memory
page_hash = (unsigned char*)get_zeroed_page(GFP_KERNEL);

// setup message in block-memory
i=0;
msg_remaining = msgLength;
while ( msg_remaining > 0 ) {
    page_msg[i] = (unsigned char*)get_zeroed_page(GFP_KERNEL);
    memcpy(page_msg[i], msg + (i * PAGE_SIZE), (msg_remaining > PAGE_SIZE) ? PAGE_SIZE : msg_remaining);
    i++;
    msg_remaining -= PAGE_SIZE;
}

// do the operation
crypto_shash_init(desc);
if ( 0 != crypto_shash_digest(desc, page_msg[0], msgLength, page_hash) ) {
    LOG_ERROR("Bad Digest Returned\n");
    goto free_return;
}

free_return:
    crypto_free_shash(tfm);
    free_page((unsigned long)page_hash);
    for ( i = 0; i < numpages; i++ ) {
        free_page((unsigned long)page_msg[i]);
    }
0 Answers
Related