static int edonr_incremental(void *buf, size_t size, void *arg) { EdonRState *ctx = arg; EdonRUpdate(ctx, buf, size * 8); return (0); }
void * abd_checksum_edonr_tmpl_init(const zio_cksum_salt_t *salt) { EdonRState *ctx; uint8_t salt_block[EDONR_BLOCK_SIZE]; /* * Edon-R needs all but the last hash invocation to be on full-size * blocks, but the salt is too small. Rather than simply padding it * with zeros, we expand the salt into a new salt block of proper * size by double-hashing it (the new salt block will be composed of * H(salt) || H(H(salt))). */ CTASSERT(EDONR_BLOCK_SIZE == 2 * (EDONR_MODE / 8)); EdonRHash(EDONR_MODE, salt->zcs_bytes, sizeof (salt->zcs_bytes) * 8, salt_block); EdonRHash(EDONR_MODE, salt_block, EDONR_MODE, salt_block + EDONR_MODE / 8); /* * Feed the new salt block into the hash function - this will serve * as our MAC key. */ ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); EdonRInit(ctx, EDONR_MODE); EdonRUpdate(ctx, salt_block, sizeof (salt_block) * 8); return (ctx); }
/*ARGSUSED*/ static void zio_checksum_edonr_native(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { uint8_t digest[EDONR_MODE / 8]; EdonRState ctx; ASSERT(ctx_template != NULL); bcopy(ctx_template, &ctx, sizeof (ctx)); EdonRUpdate(&ctx, buf, size * 8); EdonRFinal(&ctx, digest); bcopy(digest, zcp->zc_word, sizeof (zcp->zc_word)); }