Esempio n. 1
0
/**
 * Compute the GHASH of a piece of data given an arbitrary Y_0,
 * as specified in NIST SP 800 38D.
 *
 * \param y_out      The resulting GHASH (16 bytes).
 * \param block_data Pointer to the data to hash.
 * \param len        Length of the data to hash (multiple of 16).
 * \param y_in       The initial Y (Y_0, 16 bytes).
 * \param exp_key    The expanded hash key (16*256*16 bytes + alignment).
 *
 * y_out and y_int can point to the same buffer.
 */
EXPORT_SYM int ghash(
        uint8_t y_out[16],
        const uint8_t block_data[],
        size_t len,
        const uint8_t y_in[16],
        const t_exp_key *exp_key
        )
{
    int i;
    const t_v_tables *v_tables;

    if (NULL==y_out || NULL==block_data || NULL==y_in || NULL==exp_key)
        return ERR_NULL;

    if (len % 16)
        return ERR_NOT_ENOUGH_DATA;
     
    v_tables = (const t_v_tables*)(exp_key->buffer + exp_key->offset);

    memcpy(y_out, y_in, 16);
    for (i=0; i<len; i+=16) {
        int j;
        uint8_t x[16];

        for (j=0; j<16; j++) {
            x[j] = y_out[j] ^ block_data[i+j];
        }
        gcm_mult2(y_out, v_tables, x);
    }

    return 0;
}
Esempio n. 2
0
/**
 * Compute the GHASH of a piece of an arbitrary data given an
 * arbitrary Y_0, as specified in NIST SP 800 38D.
 *
 * \param y_out             The resulting GHASH (16 bytes).
 * \param block_data        Pointer to the data to hash.
 * \param len               Length of the data to hash (multiple of 16).
 * \param y_in              The initial Y (Y_0, 16 bytes).
 * \param key_tables        The hash key, possibly expanded to 16*256*16 bytes.
 * \param key_tables_len    The length of the data pointed by key_table.
 */
static void ghash(
        uint8_t y_out[16],
        const uint8_t block_data[],
        int len,
        const uint8_t y_in[16],
        const void *key_tables,
        int key_tables_len
        )
{
    int i, j;
    uint8_t x[16];
    const t_key_tables *key_tables_64 = NULL;
    const uint8_t (*key)[16] = NULL;

    switch (key_tables_len) {
        case sizeof(t_key_tables):
            {
                key_tables_64 = (const t_key_tables*) key_tables;
                break;
            }
        case 16:
            {
                key = (const uint8_t (*)[16]) key_tables;
                break;
            }
        default:
            return;
    }

    memcpy(y_out, y_in, 16);

    if (key_tables_64) {
        for (i=0; i<len; i+=16) {
            for (j=0; j<16; j++) {
                x[j] = y_out[j] ^ block_data[i+j];
            }
            gcm_mult2(y_out, key_tables_64, x);
        }
    } else {
        for (i=0; i<len; i+=16) {
            for (j=0; j<16; j++) {
                x[j] = y_out[j] ^ block_data[i+j];
            }
            gcm_mult(y_out, *key, x);
        }
    }
}