/* * Same as skein_digest_atomic, performs an atomic Skein MAC operation in * one step. All the same properties apply to the arguments of this * function as to those of the partial operations above. */ static int skein_mac_atomic(crypto_provider_handle_t provider, crypto_session_id_t session_id, crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) { /* faux crypto context just for skein_digest_{update,final} */ int error; crypto_ctx_t ctx; skein_ctx_t skein_ctx; SKEIN_CTX_LVALUE(&ctx) = &skein_ctx; if (ctx_template != NULL) { bcopy(ctx_template, &skein_ctx, sizeof (skein_ctx)); } else { error = skein_mac_ctx_build(&skein_ctx, mechanism, key); if (error != CRYPTO_SUCCESS) goto errout; } if ((error = skein_update(&ctx, data, req)) != CRYPTO_SUCCESS) goto errout; if ((error = skein_final(&ctx, mac, req)) != CRYPTO_SUCCESS) goto errout; return (CRYPTO_SUCCESS); errout: bzero(&skein_ctx, sizeof (skein_ctx)); return (error); }
/* * Executes a skein_update and skein_digest on a pre-initialized crypto * context in a single step. See the documentation to these functions to * see what to pass here. */ static int skein_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest, crypto_req_handle_t req) { int error = CRYPTO_SUCCESS; ASSERT(SKEIN_CTX(ctx) != NULL); if (digest->cd_length < CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen)) { digest->cd_length = CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen); return (CRYPTO_BUFFER_TOO_SMALL); } error = skein_update(ctx, data, req); if (error != CRYPTO_SUCCESS) { bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx))); kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx))); SKEIN_CTX_LVALUE(ctx) = NULL; digest->cd_length = 0; return (error); } error = skein_final(ctx, digest, req); return (error); }
/*ARGSUSED*/ static int skein_digest_atomic(crypto_provider_handle_t provider, crypto_session_id_t session_id, crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_data_t *digest, crypto_req_handle_t req) { int error; skein_ctx_t skein_ctx; crypto_ctx_t ctx; SKEIN_CTX_LVALUE(&ctx) = &skein_ctx; /* Init */ if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type)) return (CRYPTO_MECHANISM_INVALID); skein_ctx.sc_mech_type = mechanism->cm_type; error = skein_get_digest_bitlen(mechanism, &skein_ctx.sc_digest_bitlen); if (error != CRYPTO_SUCCESS) goto out; SKEIN_OP(&skein_ctx, Init, skein_ctx.sc_digest_bitlen); if ((error = skein_update(&ctx, data, digest)) != CRYPTO_SUCCESS) goto out; if ((error = skein_final(&ctx, data, digest)) != CRYPTO_SUCCESS) goto out; out: if (error == CRYPTO_SUCCESS) digest->cd_length = CRYPTO_BITS2BYTES(skein_ctx.sc_digest_bitlen); else digest->cd_length = 0; bzero(&skein_ctx, sizeof (skein_ctx)); return (error); }
static void skein1024_update (void* context, const void* input, size_t bytes, uint32_t output_bits) { skein_update(context, input, bytes); }