Exemplo n.º 1
0
int
k5_ef_mac(krb5_context context,
          krb5_keyblock *key,
          krb5_data *ivec,
          const krb5_data *input,
          krb5_data *output)
{
    int rv;
    iovec_t v1, v2;
    crypto_data_t d1, d2;
    crypto_mechanism_t mech;

    KRB5_LOG0(KRB5_INFO, "k5_ef_mac() start");

    ASSERT(input != NULL);
    ASSERT(ivec != NULL);
    ASSERT(output != NULL);

    v2.iov_base = (void *)output->data;
    v2.iov_len = output->length;

    bzero(&d1, sizeof (d1));
    bzero(&d2, sizeof (d2));

    d2.cd_format = CRYPTO_DATA_RAW;
    d2.cd_offset = 0;
    d2.cd_length = output->length;
    d2.cd_raw = v2;

    mech.cm_type = context->kef_hash_mt;
    if (mech.cm_type == CRYPTO_MECH_INVALID) {
        KRB5_LOG(KRB5_ERR,
                 "k5_ef_mac() invalid mech specified: 0x%llx",
                 (long long)context->kef_hash_mt);
        return (CRYPTO_FAILED);
    }

    mech.cm_param = ivec->data;
    mech.cm_param_len = ivec->length;

    v1.iov_base = (void *)input->data;
    v1.iov_len = input->length;

    d1.cd_format = CRYPTO_DATA_RAW;
    d1.cd_offset = 0;
    d1.cd_length = input->length;
    d1.cd_raw = v1;

    rv = crypto_mac(&mech, &d1, &key->kef_key, key->key_tmpl, &d2, NULL);
    if (rv != CRYPTO_SUCCESS) {
        KRB5_LOG(KRB5_ERR,
                 "k5_ef_mac(): crypto_mac error: %0x", rv);
    }

    return (rv);
}
Exemplo n.º 2
0
/* ARGSUSED */
krb5_error_code
krb5_hmac(krb5_context context, const krb5_keyblock *key,
	krb5_const krb5_data *input, krb5_data *output)
{
	int rv = CRYPTO_FAILED;
        crypto_mechanism_t mac_mech;
	crypto_data_t dd;
	crypto_data_t mac;

	KRB5_LOG0(KRB5_INFO, "krb5_hmac() start");
	if (output == NULL || output->data == NULL) {
		KRB5_LOG0(KRB5_INFO, "krb5_hmac() NULL output");
		return (rv);
	}
	if (input == NULL || input->data == NULL) {
		KRB5_LOG0(KRB5_INFO, "krb5_hmac() NULL input");
		return (rv);
	}

	dd.cd_format = CRYPTO_DATA_RAW;
	dd.cd_offset = 0;
	dd.cd_length = input->length;
	dd.cd_raw.iov_base = (char *)input->data;
	dd.cd_raw.iov_len = input->length;

	mac.cd_format = CRYPTO_DATA_RAW;
	mac.cd_offset = 0;
	mac.cd_length = output->length;
	mac.cd_raw.iov_base = (char *)output->data;
	mac.cd_raw.iov_len = output->length;

	mac_mech.cm_type = context->kef_hash_mt;
	mac_mech.cm_param = NULL;
	mac_mech.cm_param_len = 0;

	rv = crypto_mac(&mac_mech, &dd,
			(crypto_key_t *)&key->kef_key,
			key->key_tmpl, &mac, NULL);

	if (rv != CRYPTO_SUCCESS) {
		KRB5_LOG(KRB5_ERR,"crypto_mac error: %0x", rv);
	}

	KRB5_LOG(KRB5_INFO, "krb5_hmac() end ret=%d\n", rv);
	return(rv);
}
Exemplo n.º 3
0
static int
hkdf_sha512_extract(uint8_t *salt, uint_t salt_len, uint8_t *key_material,
    uint_t km_len, uint8_t *out_buf)
{
	int ret;
	crypto_mechanism_t mech;
	crypto_key_t key;
	crypto_data_t input_cd, output_cd;

	/* initialize HMAC mechanism */
	mech.cm_type = crypto_mech2id(SUN_CKM_SHA512_HMAC);
	mech.cm_param = NULL;
	mech.cm_param_len = 0;

	/* initialize the salt as a crypto key */
	key.ck_format = CRYPTO_KEY_RAW;
	key.ck_length = CRYPTO_BYTES2BITS(salt_len);
	key.ck_data = salt;

	/* initialize crypto data for the input and output data */
	input_cd.cd_format = CRYPTO_DATA_RAW;
	input_cd.cd_offset = 0;
	input_cd.cd_length = km_len;
	input_cd.cd_raw.iov_base = (char *)key_material;
	input_cd.cd_raw.iov_len = input_cd.cd_length;

	output_cd.cd_format = CRYPTO_DATA_RAW;
	output_cd.cd_offset = 0;
	output_cd.cd_length = SHA512_DIGEST_LENGTH;
	output_cd.cd_raw.iov_base = (char *)out_buf;
	output_cd.cd_raw.iov_len = output_cd.cd_length;

	ret = crypto_mac(&mech, &input_cd, &key, NULL, &output_cd, NULL);
	if (ret != CRYPTO_SUCCESS)
		return (SET_ERROR(EIO));

	return (0);
}
Exemplo n.º 4
0
static int
pbkdf2(uint8_t *passphrase, size_t passphraselen, uint8_t *salt,
    size_t saltlen, uint64_t iterations, uint8_t *output,
    size_t outputlen)
{
	int ret;
	uint64_t iter;
	uint32_t blockptr, i;
	uint16_t hmac_key_len;
	uint8_t *hmac_key;
	uint8_t block[SHA1_DIGEST_LEN * 2];
	uint8_t *hmacresult = block + SHA1_DIGEST_LEN;
	crypto_mechanism_t mech;
	crypto_key_t key;
	crypto_data_t in_data, out_data;
	crypto_ctx_template_t tmpl = NULL;

	/* initialize output */
	memset(output, 0, outputlen);

	/* initialize icp for use */
	thread_init();
	icp_init();

	/* HMAC key size is max(sizeof(uint32_t) + salt len, sha 256 len) */
	if (saltlen > SHA1_DIGEST_LEN) {
		hmac_key_len = saltlen + sizeof (uint32_t);
	} else {
		hmac_key_len = SHA1_DIGEST_LEN;
	}

	hmac_key = calloc(hmac_key_len, 1);
	if (!hmac_key) {
		ret = ENOMEM;
		goto error;
	}

	/* initialize sha 256 hmac mechanism */
	mech.cm_type = crypto_mech2id(SUN_CKM_SHA1_HMAC);
	mech.cm_param = NULL;
	mech.cm_param_len = 0;

	/* initialize passphrase as a crypto key */
	key.ck_format = CRYPTO_KEY_RAW;
	key.ck_length = CRYPTO_BYTES2BITS(passphraselen);
	key.ck_data = passphrase;

	/*
	 * initialize crypto data for the input data. length will change
	 * after the first iteration, so we will initialize it in the loop.
	 */
	in_data.cd_format = CRYPTO_DATA_RAW;
	in_data.cd_offset = 0;
	in_data.cd_raw.iov_base = (char *)hmac_key;

	/* initialize crypto data for the output data */
	out_data.cd_format = CRYPTO_DATA_RAW;
	out_data.cd_offset = 0;
	out_data.cd_length = SHA1_DIGEST_LEN;
	out_data.cd_raw.iov_base = (char *)hmacresult;
	out_data.cd_raw.iov_len = out_data.cd_length;

	/* initialize the context template */
	ret = crypto_create_ctx_template(&mech, &key, &tmpl, KM_SLEEP);
	if (ret != CRYPTO_SUCCESS) {
		ret = EIO;
		goto error;
	}

	/* main loop */
	for (blockptr = 0; blockptr < outputlen; blockptr += SHA1_DIGEST_LEN) {

		/*
		 * for the first iteration, the HMAC key is the user-provided
		 * salt concatenated with the block index (1-indexed)
		 */
		i = htobe32(1 + (blockptr / SHA1_DIGEST_LEN));
		memmove(hmac_key, salt, saltlen);
		memmove(hmac_key + saltlen, (uint8_t *)(&i), sizeof (uint32_t));

		/* block initializes to zeroes (no XOR) */
		memset(block, 0, SHA1_DIGEST_LEN);

		for (iter = 0; iter < iterations; iter++) {
			if (iter > 0) {
				in_data.cd_length = SHA1_DIGEST_LEN;
				in_data.cd_raw.iov_len = in_data.cd_length;
			} else {
				in_data.cd_length = saltlen + sizeof (uint32_t);
				in_data.cd_raw.iov_len = in_data.cd_length;
			}

			ret = crypto_mac(&mech, &in_data, &key, tmpl,
			    &out_data, NULL);
			if (ret != CRYPTO_SUCCESS) {
				ret = EIO;
				goto error;
			}

			/* HMAC key now becomes the output of this iteration */
			memmove(hmac_key, hmacresult, SHA1_DIGEST_LEN);

			/* XOR this iteration's result with the current block */
			for (i = 0; i < SHA1_DIGEST_LEN; i++) {
				block[i] ^= hmacresult[i];
			}
		}

		/*
		 * compute length of this block, make sure we don't write
		 * beyond the end of the output, truncating if necessary
		 */
		if (blockptr + SHA1_DIGEST_LEN > outputlen) {
			memmove(output + blockptr, block, outputlen - blockptr);
		} else {
			memmove(output + blockptr, block, SHA1_DIGEST_LEN);
		}
	}

	crypto_destroy_ctx_template(tmpl);
	free(hmac_key);
	icp_fini();
	thread_fini();

	return (0);

error:
	crypto_destroy_ctx_template(tmpl);
	if (hmac_key != NULL)
		free(hmac_key);
	icp_fini();
	thread_fini();

	return (ret);
}