Ejemplo n.º 1
0
/*ARGSUSED*/
static int
skein_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
{
	int error = CRYPTO_SUCCESS;

	ASSERT(SKEIN_CTX(ctx) != NULL);

	switch (data->cd_format) {
	case CRYPTO_DATA_RAW:
		SKEIN_OP(SKEIN_CTX(ctx), Update,
		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
		    data->cd_length);
		break;
	case CRYPTO_DATA_UIO:
		error = skein_digest_update_uio(SKEIN_CTX(ctx), data);
		break;
	case CRYPTO_DATA_MBLK:
		error = skein_digest_update_mblk(SKEIN_CTX(ctx), data);
		break;
	default:
		error = CRYPTO_ARGUMENTS_BAD;
	}

	return (error);
}
Ejemplo n.º 2
0
/*
 * Initializes a skein digest context to the configuration in `mechanism'.
 * The mechanism cm_type must be one of SKEIN_*_MECH_INFO_TYPE. The cm_param
 * field may contain a skein_param_t structure indicating the length of the
 * digest the algorithm should produce. Otherwise the default output lengths
 * are applied (32 bytes for Skein-256, 64 bytes for Skein-512 and 128 bytes
 * for Skein-1024).
 */
static int
skein_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
    crypto_req_handle_t req)
{
	int	error = CRYPTO_SUCCESS;

	if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type))
		return (CRYPTO_MECHANISM_INVALID);

	SKEIN_CTX_LVALUE(ctx) = kmem_alloc(sizeof (*SKEIN_CTX(ctx)),
	    crypto_kmflag(req));
	if (SKEIN_CTX(ctx) == NULL)
		return (CRYPTO_HOST_MEMORY);

	SKEIN_CTX(ctx)->sc_mech_type = mechanism->cm_type;
	error = skein_get_digest_bitlen(mechanism,
	    &SKEIN_CTX(ctx)->sc_digest_bitlen);
	if (error != CRYPTO_SUCCESS)
		goto errout;
	SKEIN_OP(SKEIN_CTX(ctx), Init, SKEIN_CTX(ctx)->sc_digest_bitlen);

	return (CRYPTO_SUCCESS);
errout:
	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	SKEIN_CTX_LVALUE(ctx) = NULL;
	return (error);
}
Ejemplo n.º 3
0
/*
 * Initializes a skein MAC context. You may pass a ctx_template, in which
 * case the template will be reused to make initialization more efficient.
 * Otherwise a new context will be constructed. The mechanism cm_type must
 * be one of SKEIN_*_MAC_MECH_INFO_TYPE. Same as in skein_digest_init, you
 * may pass a skein_param_t in cm_param to configure the length of the
 * digest. The key must be in raw format.
 */
static int
skein_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
    crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
    crypto_req_handle_t req)
{
	int	error;

	SKEIN_CTX_LVALUE(ctx) = kmem_alloc(sizeof (*SKEIN_CTX(ctx)),
	    crypto_kmflag(req));
	if (SKEIN_CTX(ctx) == NULL)
		return (CRYPTO_HOST_MEMORY);

	if (ctx_template != NULL) {
		bcopy(ctx_template, SKEIN_CTX(ctx),
		    sizeof (*SKEIN_CTX(ctx)));
	} else {
		error = skein_mac_ctx_build(SKEIN_CTX(ctx), mechanism, key);
		if (error != CRYPTO_SUCCESS)
			goto errout;
	}

	return (CRYPTO_SUCCESS);
errout:
	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	return (error);
}
Ejemplo n.º 4
0
/*
 * Frees a skein context in a parent crypto context.
 */
static int
skein_free_context(crypto_ctx_t *ctx)
{
	if (SKEIN_CTX(ctx) != NULL) {
		bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		SKEIN_CTX_LVALUE(ctx) = NULL;
	}

	return (CRYPTO_SUCCESS);
}
Ejemplo n.º 5
0
/*
 * 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);
}
Ejemplo n.º 6
0
/*ARGSUSED*/
static int
skein_final(crypto_ctx_t *ctx, 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);
	}

	switch (digest->cd_format) {
	case CRYPTO_DATA_RAW:
		SKEIN_OP(SKEIN_CTX(ctx), Final,
		    (uint8_t *)digest->cd_raw.iov_base + digest->cd_offset);
		break;
	case CRYPTO_DATA_UIO:
		error = skein_digest_final_uio(SKEIN_CTX(ctx), digest, req);
		break;
	default:
		error = CRYPTO_ARGUMENTS_BAD;
	}

	if (error == CRYPTO_SUCCESS)
		digest->cd_length =
		    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen);
	else
		digest->cd_length = 0;

	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*(SKEIN_CTX(ctx))));
	SKEIN_CTX_LVALUE(ctx) = NULL;

	return (error);
}