/* * Allocates a skein MAC template suitable for using in skein MAC checksum * computations and returns a pointer to it. */ void * abd_checksum_skein_tmpl_init(const zio_cksum_salt_t *salt) { Skein_512_Ctxt_t *ctx; ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); (void) Skein_512_InitExt(ctx, sizeof (zio_cksum_t) * 8, 0, salt->zcs_bytes, sizeof (salt->zcs_bytes)); return (ctx); }
int skeinMacInit(SkeinCtx_t* ctx, const uint8_t *key, size_t keyLen, size_t hashBitLen) { int ret = SKEIN_FAIL; u64b_t* X = NULL; size_t Xlen = 0; uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL; Skein_Assert(ctx, SKEIN_FAIL); X = ctx->m.s256.X; Xlen = (size_t)(ctx->skeinSize/8); Skein_Assert(hashBitLen, SKEIN_BAD_HASHLEN); switch (ctx->skeinSize) { case Skein256: ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen, treeInfo, (const u08b_t*)key, keyLen); break; case Skein512: ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen, treeInfo, (const u08b_t*)key, keyLen); break; case Skein1024: ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen, treeInfo, (const u08b_t*)key, keyLen); break; } if (ret == SKEIN_SUCCESS) { /* Save chaining variables for this combination of key, keyLen, hashBitLen */ memcpy(ctx->XSave, X, Xlen); } return ret; }
int skeinInit(SkeinCtx_t* ctx, size_t hashBitLen) { int ret = SKEIN_FAIL; size_t Xlen = 0; u64b_t* X = NULL; uint64_t treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL; Skein_Assert(ctx, SKEIN_FAIL); /* * The following two lines rely of the fact that the real Skein contexts are * a union in out context and thus have tha maximum memory available. * The beauty of C :-) . */ X = ctx->m.s256.X; Xlen = (size_t)(ctx->skeinSize/8); /* * If size is the same and hash bit length is zero then reuse * the save chaining variables. */ switch (ctx->skeinSize) { case Skein256: ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen, treeInfo, NULL, 0); break; case Skein512: ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen, treeInfo, NULL, 0); break; case Skein1024: ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen, treeInfo, NULL, 0); break; } if (ret == SKEIN_SUCCESS) { /* Save chaining variables for this combination of size and hashBitLen */ memcpy(ctx->XSave, X, Xlen); } return ret; }
/* * Perform keyed hashing. With Skein, HMAC is not used, rather Skein's * native MAC is used which is more optimal than HMAC. */ int hmac_init(mac_ctx_t *mctx, int cksum, crypto_ctx_t *cctx) { aes_ctx_t *actx = (aes_ctx_t *)(cctx->crypto_ctx); mctx->mac_cksum = cksum; if (cksum == CKSUM_SKEIN256) { Skein_512_Ctxt_t *ctx = malloc(sizeof (Skein_512_Ctxt_t)); if (!ctx) return (-1); Skein_512_InitExt(ctx, 256, SKEIN_CFG_TREE_INFO_SEQUENTIAL, actx->pkey, KEYLEN); mctx->mac_ctx = ctx; ctx = malloc(sizeof (Skein_512_Ctxt_t)); if (!ctx) { free(mctx->mac_ctx); return (-1); } memcpy(ctx, mctx->mac_ctx, sizeof (Skein_512_Ctxt_t)); mctx->mac_ctx_reinit = ctx; } else if (cksum == CKSUM_SKEIN512) { Skein_512_Ctxt_t *ctx = malloc(sizeof (Skein_512_Ctxt_t)); if (!ctx) return (-1); Skein_512_InitExt(ctx, 512, SKEIN_CFG_TREE_INFO_SEQUENTIAL, actx->pkey, KEYLEN); mctx->mac_ctx = ctx; ctx = malloc(sizeof (Skein_512_Ctxt_t)); if (!ctx) { free(mctx->mac_ctx); return (-1); } memcpy(ctx, mctx->mac_ctx, sizeof (Skein_512_Ctxt_t)); mctx->mac_ctx_reinit = ctx; } else if (cksum == CKSUM_SHA256 || cksum == CKSUM_CRC64) { if (cksum_provider == PROVIDER_OPENSSL) { HMAC_CTX *ctx = malloc(sizeof (HMAC_CTX)); if (!ctx) return (-1); HMAC_CTX_init(ctx); HMAC_Init_ex(ctx, actx->pkey, KEYLEN, EVP_sha256(), NULL); mctx->mac_ctx = ctx; ctx = malloc(sizeof (HMAC_CTX)); if (!ctx) { free(mctx->mac_ctx); return (-1); } if (!HMAC_CTX_copy(ctx, mctx->mac_ctx)) { free(ctx); free(mctx->mac_ctx); return (-1); } mctx->mac_ctx_reinit = ctx; } else { HMAC_SHA256_Context *ctx = malloc(sizeof (HMAC_SHA256_Context)); if (!ctx) return (-1); opt_HMAC_SHA256_Init(ctx, actx->pkey, KEYLEN); mctx->mac_ctx = ctx; ctx = malloc(sizeof (HMAC_SHA256_Context)); if (!ctx) { free(mctx->mac_ctx); return (-1); } memcpy(ctx, mctx->mac_ctx, sizeof (HMAC_SHA256_Context)); mctx->mac_ctx_reinit = ctx; } } else if (cksum == CKSUM_SHA512) { HMAC_CTX *ctx = malloc(sizeof (HMAC_CTX)); if (!ctx) return (-1); HMAC_CTX_init(ctx); HMAC_Init_ex(ctx, actx->pkey, KEYLEN, EVP_sha512(), NULL); mctx->mac_ctx = ctx; ctx = malloc(sizeof (HMAC_CTX)); if (!ctx) { free(mctx->mac_ctx); return (-1); } if (!HMAC_CTX_copy(ctx, mctx->mac_ctx)) { free(ctx); free(mctx->mac_ctx); return (-1); } mctx->mac_ctx_reinit = ctx; } else if (cksum == CKSUM_KECCAK256 || cksum == CKSUM_KECCAK512) { hashState *ctx = malloc(sizeof (hashState)); if (!ctx) return (-1); if (cksum == CKSUM_KECCAK256) { if (Keccak_Init(ctx, 256) != 0) return (-1); } else { if (Keccak_Init(ctx, 512) != 0) return (-1); } if (Keccak_Update(ctx, actx->pkey, KEYLEN << 3) != 0) return (-1); mctx->mac_ctx = ctx; ctx = malloc(sizeof (hashState)); if (!ctx) { free(mctx->mac_ctx); return (-1); } memcpy(ctx, mctx->mac_ctx, sizeof (hashState)); mctx->mac_ctx_reinit = ctx; } else { return (-1); } return (0); }