コード例 #1
0
krb5_error_code
k5_ef_hash(krb5_context context,
	CK_MECHANISM *mechanism,
	unsigned int icount,
	krb5_const krb5_data *input,
	krb5_data *output)
{
	CK_RV rv;
	int i;
	CK_ULONG outlen = output->length;

	if ((rv = C_DigestInit(krb_ctx_hSession(context), mechanism)) !=
	    CKR_OK) {
	    KRB5_LOG(KRB5_ERR, "C_DigestInit failed in k5_ef_hash: "
	    "rv = 0x%x.", rv);
	    return (PKCS_ERR);
	}

	for (i = 0; i < icount; i++) {
	    if ((rv = C_DigestUpdate(krb_ctx_hSession(context),
		(CK_BYTE_PTR)input[i].data,
		(CK_ULONG)input[i].length)) != CKR_OK) {
		KRB5_LOG(KRB5_ERR, "C_DigestUpdate failed in k5_ef_hash: "
		    "rv = 0x%x", rv);
		return (PKCS_ERR);
	    }
	}

	if ((rv = C_DigestFinal(krb_ctx_hSession(context),
	    (CK_BYTE_PTR)output->data, &outlen)) != CKR_OK) {
	    KRB5_LOG(KRB5_ERR, "C_DigestFinal failed in k5_ef_hash: "
		"rv = 0x%x", rv);
	    return (PKCS_ERR);
	}

	/* Narrowing conversion OK because hashes are much smaller than 2^32 */
	output->length = outlen;

	KRB5_LOG0(KRB5_INFO, "k5_ef_hash() end");
	return (0);
}
コード例 #2
0
ファイル: prng.c プロジェクト: andreiw/polaris
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_random_make_octets(krb5_context context, krb5_data *data)
{
/*
 * Solaris kerberos uses /dev/[u]random
 */
#ifndef _KERNEL /* User space code */

    krb5_error_code err = 0;
    CK_RV rv;

    KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() start, user space using "
	"krb5_get_random_octets()\n");

    rv = C_GenerateRandom(krb_ctx_hSession(context), (CK_BYTE_PTR)data->data,
		(CK_ULONG)data->length);

    if (rv != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_GenerateRandom failed in "
		"krb5_c_random_make_octets: rv = 0x%x.", rv);
	err = PKCS_ERR;
    }
    if (err != 0) {
	KRB5_LOG0(KRB5_ERR, "krb5_c_random_make_octets() end, error");
	return (err);
    }

#else  /* Kernel code section */

    /*
     * Solaris Kerberos: for kernel code we use the randomness generator native
     * to Solaris 9.  We avoid global variables and other nastiness this way.
     *
     * Using random_get_pseudo_bytes() instead of random_get_bytes() because it
     * will not return an error code if there isn't enough entropy but will use
     * a pseudo random algorithm to produce randomness.  Most of the time it
     * should be as good as random_get_bytes() and we don't have to worry about
     * dealing with a non-fatal error.
     */
    KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() start, kernel using "
	    "random_get_pseudo_bytes()\n ");

    if(random_get_pseudo_bytes((uint8_t *)data->data, data->length) != 0) {
	KRB5_LOG0(KRB5_ERR, "krb5_c_random_make_octets() end, "
		"random_get_pseudo_bytes() error.\n");
	return(KRB5_CRYPTO_INTERNAL);
    }

#endif /* !_KERNEL */

    KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() end\n");
    return(0);
}
コード例 #3
0
ファイル: prng.c プロジェクト: andreiw/polaris
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
	/*
	 * We can't do much if this fails, so ignore the
	 * return code.  /dev/urandom has its own entropy
	 * source, so seeding it from here is of questionable 
	 * value in the first place.
	 */
	(void) C_SeedRandom(krb_ctx_hSession(context),
		(CK_BYTE_PTR)data->data,
		(CK_ULONG)data->length);

	return(0);
}
コード例 #4
0
ファイル: decrypt.c プロジェクト: andreiw/polaris
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
	    krb5_keyusage usage, const krb5_data *ivec,
	    const krb5_enc_data *input, krb5_data *output)
{
    int i;
    krb5_error_code ret = 0;

    for (i=0; i<krb5_enctypes_length; i++) {
	if (krb5_enctypes_list[i].etype == key->enctype)
	    break;
    }

    if (i == krb5_enctypes_length)
	return(KRB5_BAD_ENCTYPE);

    if ((input->enctype != ENCTYPE_UNKNOWN) &&
	(krb5_enctypes_list[i].etype != input->enctype))
	return(KRB5_BAD_ENCTYPE);

#ifdef _KERNEL
    context->kef_cipher_mt = krb5_enctypes_list[i].kef_cipher_mt;
    context->kef_hash_mt = krb5_enctypes_list[i].kef_hash_mt;
    if (key->kef_key.ck_data == NULL)
      ret = init_key_kef(context->kef_cipher_mt, (krb5_keyblock *)key);
    if (ret)
	    return(ret);

#else
    if ((ret = init_key_uef(krb_ctx_hSession(context), (krb5_keyblock *)key)))
	return (ret);

#endif /* _KERNEL */

    return((*(krb5_enctypes_list[i].decrypt))
	   (context, krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
	    key, usage, ivec, &input->ciphertext, output));
}
コード例 #5
0
ファイル: k5_md5des.c プロジェクト: NanXiao/illumos-joyent
/*ARGSUSED*/
static krb5_error_code
k5_md5des_hash(krb5_context context, krb5_const krb5_keyblock *key,
	       krb5_keyusage usage, const krb5_data *ivec,
	       const krb5_data *input, krb5_data *output)
{
    krb5_error_code ret = 0;
    krb5_data data;
    unsigned char conf[CONFLENGTH];
    krb5_keyblock xorkey;
    int i;
    CK_MECHANISM mechanism;
    CK_RV rv;
    CK_ULONG hashlen = MD5_CKSUM_LENGTH;

    if (key->length != 8)
	return(KRB5_BAD_KEYSIZE);
    if (ivec)
	return(KRB5_CRYPTO_INTERNAL);
    if (output->length != (CONFLENGTH+MD5_CKSUM_LENGTH))
	return(KRB5_CRYPTO_INTERNAL);

    /* create the confouder */

    data.length = CONFLENGTH;
    data.data = (char *) conf;
    if ((ret = krb5_c_random_make_octets(context, &data)))
	return(ret);

    xorkey.magic = key->magic;
    xorkey.enctype = key->enctype;
    xorkey.length = key->length;
    xorkey.contents = (krb5_octet *)malloc(key->length);
    if (xorkey.contents == NULL)
	return(KRB5_CRYPTO_INTERNAL);

    (void) memcpy(xorkey.contents, key->contents, xorkey.length);

    for (i=0; i<xorkey.length; i++)
	xorkey.contents[i] ^= 0xf0;

    if (!mit_des_check_key_parity(xorkey.contents)) {
	ret = KRB5DES_BAD_KEYPAR;
	goto cleanup;
    }

    if (mit_des_is_weak_key(xorkey.contents)) {
	ret = KRB5DES_WEAK_KEY;
	goto cleanup;
    }

    /* hash the confounder, then the input data */
    mechanism.mechanism = CKM_MD5;
    mechanism.pParameter = NULL_PTR;
    mechanism.ulParameterLen = 0;

    if ((rv = C_DigestInit(krb_ctx_hSession(context), &mechanism)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestInit failed in k5_md5des_hash: "
	"rv = 0x%x.", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }

    if ((rv = C_DigestUpdate(krb_ctx_hSession(context),
	(CK_BYTE_PTR)conf, (CK_ULONG)sizeof(conf))) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestUpdate failed in k5_md5des_hash: "
	    "rv = 0x%x", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }

    if ((rv = C_DigestUpdate(krb_ctx_hSession(context),
	(CK_BYTE_PTR)input->data, (CK_ULONG)input->length)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestUpdate failed in k5_md5des_hash: "
	    "rv = 0x%x", rv);
	return(PKCS_ERR);
    }

    if ((rv = C_DigestFinal(krb_ctx_hSession(context),
	(CK_BYTE_PTR)(output->data + CONFLENGTH),
	(CK_ULONG_PTR)&hashlen)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestFinal failed in k5_md5des_hash: "
	    "rv = 0x%x", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }

    /* construct the buffer to be encrypted */

    (void) memcpy(output->data, conf, CONFLENGTH);

    /* encrypt it, in place.  this has a return value, but it's
       always zero.  */

    ret = mit_des_cbc_encrypt(context,
	(krb5_pointer) output->data,
	(krb5_pointer) output->data, output->length,
	&xorkey, (unsigned char*) mit_des_zeroblock, 1);

cleanup:
    free(xorkey.contents);
    return(ret);
}
コード例 #6
0
ファイル: k5_md5des.c プロジェクト: NanXiao/illumos-joyent
/*ARGSUSED*/
static krb5_error_code
k5_md5des_verify(krb5_context context,
	krb5_const krb5_keyblock *key, 
	krb5_keyusage usage,
	krb5_const krb5_data *ivec,
	krb5_const krb5_data *input,
	krb5_const krb5_data *hash,
	krb5_boolean *valid)
{
    krb5_error_code ret = 0;
    unsigned char plaintext[CONFLENGTH+MD5_CKSUM_LENGTH];
    unsigned char digest[MD5_CKSUM_LENGTH];
    krb5_keyblock xorkey;
    int i;
    int compathash = 0;
    CK_MECHANISM mechanism;
    CK_RV rv;
    CK_ULONG hashlen = MD5_CKSUM_LENGTH;

    if (key->length != 8)
	return(KRB5_BAD_KEYSIZE);
    if (ivec)
	return(KRB5_CRYPTO_INTERNAL);
    if (hash->length != (CONFLENGTH + MD5_CKSUM_LENGTH)) {
#ifdef KRB5_MD5DES_BETA5_COMPAT
	if (hash->length != MD5_CKSUM_LENGTH)
	    return(KRB5_CRYPTO_INTERNAL);
	else
	    compathash = 1;
#else
	return(KRB5_CRYPTO_INTERNAL);
#endif
    }

    /* create and the encryption key */
    xorkey.magic = key->magic;
    xorkey.enctype = key->enctype;
    xorkey.length = key->length;
    xorkey.contents = (krb5_octet *)malloc(key->length);
    if (xorkey.contents == NULL)
	return(KRB5_CRYPTO_INTERNAL);

    (void) memcpy(xorkey.contents, key->contents, xorkey.length);
    if (!compathash) {
        for (i=0; i<xorkey.length; i++)
	    xorkey.contents[i] ^= 0xf0;
    }

    if (!mit_des_check_key_parity(xorkey.contents)) {
	ret = KRB5DES_BAD_KEYPAR;
	goto cleanup;
    }

    if (mit_des_is_weak_key(xorkey.contents)) {
	ret = KRB5DES_WEAK_KEY;
	goto cleanup;
    }

    /* decrypt it.  this has a return value, but it's always zero.  */
    if (!compathash) {
	ret = mit_des_cbc_encrypt(context,
		(krb5_pointer) hash->data,
		(krb5_pointer) plaintext, hash->length,
		&xorkey, (unsigned char*) mit_des_zeroblock, 0);
    } else {
	ret = mit_des_cbc_encrypt(context,
		(krb5_pointer) hash->data,
		(krb5_pointer) plaintext, hash->length,
		&xorkey, xorkey.contents, 0);
    }
    if (ret) goto cleanup;

    /* hash the confounder, then the input data */
    mechanism.mechanism = CKM_MD5;
    mechanism.pParameter = NULL_PTR;
    mechanism.ulParameterLen = 0;

    if ((rv = C_DigestInit(krb_ctx_hSession(context), &mechanism)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestInit failed in k5_md5des_verify: "
	"rv = 0x%x.", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }

    if (!compathash) {
	if ((rv = C_DigestUpdate(krb_ctx_hSession(context),
	    (CK_BYTE_PTR)plaintext, (CK_ULONG)CONFLENGTH)) != CKR_OK) {
	    KRB5_LOG(KRB5_ERR, "C_DigestUpdate failed in k5_md5des_verify: "
		"rv = 0x%x", rv);
	    ret = PKCS_ERR;
	    goto cleanup;
	}
    }
    if ((rv = C_DigestUpdate(krb_ctx_hSession(context),
	(CK_BYTE_PTR)input->data, (CK_ULONG)input->length)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestUpdate failed in k5_md5des_verify: "
	    "rv = 0x%x", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }
    if ((rv = C_DigestFinal(krb_ctx_hSession(context),
	(CK_BYTE_PTR)digest, (CK_ULONG_PTR)&hashlen)) != CKR_OK) {
	KRB5_LOG(KRB5_ERR, "C_DigestFinal failed in k5_md5des_verify: "
	    "rv = 0x%x", rv);
	ret = PKCS_ERR;
	goto cleanup;
    }

    /* compare the decrypted hash to the computed one */

    if (!compathash) {
	*valid = (memcmp(plaintext+CONFLENGTH, digest, sizeof(digest)) == 0);
    } else {
	*valid = (memcmp(plaintext, digest, sizeof(digest)) == 0);
    }
    (void) memset(plaintext, 0, sizeof(plaintext));

cleanup:
    free(xorkey.contents);
    return(ret);
}
コード例 #7
0
krb5_error_code KRB5_CALLCONV
krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
		     const krb5_keyblock *key, krb5_keyusage usage,
		     const krb5_data *input, krb5_checksum *cksum)
{
    int i, e1, e2;
    krb5_data data;
    krb5_error_code ret = 0;
    size_t cksumlen;

    KRB5_LOG0(KRB5_INFO, "krb5_c_make_checksum() start.");

    for (i=0; i<krb5_cksumtypes_length; i++) {
	if (krb5_cksumtypes_list[i].ctype == cksumtype)
	    break;
    }

    if (i == krb5_cksumtypes_length)
	return(KRB5_BAD_ENCTYPE);

    if (krb5_cksumtypes_list[i].keyhash)
	cksumlen = krb5_cksumtypes_list[i].keyhash->hashsize;
    else
	cksumlen = krb5_cksumtypes_list[i].hash->hashsize;

#ifdef _KERNEL
    context->kef_cksum_mt = krb5_cksumtypes_list[i].kef_cksum_mt;
#endif
    cksum->length = cksumlen;

    if ((cksum->contents = (krb5_octet *) MALLOC(cksum->length)) == NULL)
	return(ENOMEM);

    data.length = cksum->length;
    data.data = (char *) cksum->contents;

    if (krb5_cksumtypes_list[i].keyhash) {
	/* check if key is compatible */

	if (krb5_cksumtypes_list[i].keyed_etype) {
	    for (e1=0; e1<krb5_enctypes_length; e1++) 
		if (krb5_enctypes_list[e1].etype ==
		    krb5_cksumtypes_list[i].keyed_etype)
		    break;

	    for (e2=0; e2<krb5_enctypes_length; e2++) 
		if (krb5_enctypes_list[e2].etype == key->enctype)
		    break;

	    if ((e1 == krb5_enctypes_length) ||
		(e2 == krb5_enctypes_length) ||
		(krb5_enctypes_list[e1].enc != krb5_enctypes_list[e2].enc)) {
		ret = KRB5_BAD_ENCTYPE;
		goto cleanup;
	    }
	}
#ifdef _KERNEL
	context->kef_cipher_mt = krb5_enctypes_list[e1].kef_cipher_mt;
	context->kef_hash_mt = krb5_enctypes_list[e1].kef_hash_mt;
	if (key->kef_key.ck_data == NULL) {
		if ((ret = init_key_kef(context->kef_cipher_mt,
				(krb5_keyblock *)key)))
			goto cleanup;
	}
#else
	if ((ret = init_key_uef(krb_ctx_hSession(context), (krb5_keyblock *)key)))
		return (ret);
#endif /* _KERNEL */

	ret = (*(krb5_cksumtypes_list[i].keyhash->hash))(context, key,
						usage, 0, input, &data);
    } else if (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE) {
#ifdef _KERNEL
    	context->kef_cipher_mt = get_cipher_mech_type(context,
					(krb5_keyblock *)key);
    	context->kef_hash_mt = get_hash_mech_type(context,
					(krb5_keyblock *)key);
	/*
	 * If the hash_mt is invalid, try using the cksum_mt
	 * because "hash" and "checksum" are overloaded terms
	 * in some places.
	 */ 
	if (context->kef_hash_mt == CRYPTO_MECH_INVALID)
		context->kef_hash_mt = context->kef_cksum_mt;
#else
	ret = init_key_uef(krb_ctx_hSession(context), (krb5_keyblock *)key);
	if (ret)
		return (ret);
#endif /* _KERNEL */
	ret = krb5_dk_make_checksum(context,
				krb5_cksumtypes_list[i].hash,
				key, usage, input, &data);
    } else {
	    /*
	     * No key is used, hash and cksum are synonymous
	     * in this case
	     */
#ifdef _KERNEL
	    context->kef_hash_mt = context->kef_cksum_mt;
#endif /* _KERNEL */
	    ret = (*(krb5_cksumtypes_list[i].hash->hash))(context, 1,
							input, &data);
    }

    if (!ret) {
	cksum->magic = KV5M_CHECKSUM;
	cksum->checksum_type = cksumtype;
	if (krb5_cksumtypes_list[i].trunc_size) {
	    krb5_octet *trunc;
            size_t old_len = cksum->length;

            /*
             * Solaris Kerberos:
             * The Kernel does not like 'realloc' (which is what
             * MIT code does here), so we do our own "realloc".
             */
            cksum->length = krb5_cksumtypes_list[i].trunc_size;
            trunc = (krb5_octet *) MALLOC(cksum->length);
            if (trunc) {
                (void) memcpy(trunc, cksum->contents, cksum->length);
                FREE(cksum->contents, old_len);
                cksum->contents = trunc;
            } else {
                ret = ENOMEM;
            }
        }
    }

cleanup:
    if (ret) {
	(void) memset(cksum->contents, 0, cksum->length);
	FREE(cksum->contents, cksum->length);
	cksum->length = 0;
	cksum->contents = NULL;
    }

    KRB5_LOG(KRB5_INFO, "krb5_c_make_checksum() end ret = %d\n", ret);
    return(ret);
}