xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_kef_generic.c (revision a28480febf31f0e61debac062a55216a98a05a92)
1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 #include <k5-int.h>
9 
10 #include <sys/crypto/api.h>
11 
12 #include <sys/callb.h>
13 #include <sys/uio.h>
14 
15 int
16 k5_ef_hash(krb5_context context, int icount,
17 	const krb5_data *input,
18 	krb5_data *output)
19 {
20 	int i;
21 	int rv = CRYPTO_FAILED;
22 	iovec_t v1, v2;
23 	crypto_data_t d1, d2;
24 	crypto_mechanism_t mech;
25 	crypto_context_t ctxp;
26 
27 	KRB5_LOG0(KRB5_INFO, "k5_ef_hash() start");
28 
29 	bzero(&d1, sizeof (d1));
30 	bzero(&d2, sizeof (d2));
31 
32 	v2.iov_base = (void *)output->data;
33 	v2.iov_len = output->length;
34 
35 	d2.cd_format = CRYPTO_DATA_RAW;
36 	d2.cd_offset = 0;
37 	d2.cd_length = output->length;
38 	d2.cd_raw = v2;
39 
40 	mech.cm_type = context->kef_cksum_mt;
41 	if (mech.cm_type == CRYPTO_MECH_INVALID) {
42 		KRB5_LOG(KRB5_ERR,
43 			"k5_ef_hash() invalid mech specified: 0x%llx",
44 			(long long)context->kef_hash_mt);
45 		return (CRYPTO_FAILED);
46 	}
47 	mech.cm_param = 0;
48 	mech.cm_param_len = 0;
49 
50 	rv = crypto_digest_init(&mech, &ctxp, NULL);
51 	if (rv != CRYPTO_SUCCESS) {
52 		KRB5_LOG(KRB5_ERR, "crypto_digest_init error: %0x", rv);
53 		return (rv);
54 	}
55 
56 	for (i = 0; i < icount; i++) {
57 		v1.iov_base = (void *)input[i].data;
58 		v1.iov_len = input[i].length;
59 		d1.cd_length = input[i].length;
60 		d1.cd_format = CRYPTO_DATA_RAW;
61 		d1.cd_offset = 0;
62 		d1.cd_raw = v1;
63 
64 		rv = crypto_digest_update(ctxp, &d1, NULL);
65 		if (rv != CRYPTO_SUCCESS) {
66 			KRB5_LOG(KRB5_ERR,
67 				"crypto_digest_update error: %0x", rv);
68 			crypto_cancel_ctx(ctxp);
69 			return (rv);
70 		}
71 	}
72 
73 	rv = crypto_digest_final(ctxp, &d2, NULL);
74 	/*
75 	 * crypto_digest_final() internally destroys the context. So, we
76 	 * do not use the context any more. This means we do not call
77 	 * crypto_cancel_ctx() for the failure case here unlike the failure
78 	 * case of crypto_digest_update() where we do.
79 	 */
80 	if (rv != CRYPTO_SUCCESS) {
81 		KRB5_LOG(KRB5_ERR, "crypto_digest_final error: %0x", rv);
82 	}
83 
84 	return (rv);
85 }
86 
87 int
88 k5_ef_mac(krb5_context context,
89 	krb5_keyblock *key,
90 	krb5_data *ivec,
91 	const krb5_data *input,
92 	krb5_data *output)
93 {
94 	int rv;
95 	iovec_t v1, v2;
96 	crypto_data_t d1, d2;
97 	crypto_mechanism_t mech;
98 
99 	KRB5_LOG0(KRB5_INFO, "k5_ef_mac() start");
100 
101 	ASSERT(input != NULL);
102 	ASSERT(ivec != NULL);
103 	ASSERT(output != NULL);
104 
105 	v2.iov_base = (void *)output->data;
106 	v2.iov_len = output->length;
107 
108 	bzero(&d1, sizeof (d1));
109 	bzero(&d2, sizeof (d2));
110 
111 	d2.cd_format = CRYPTO_DATA_RAW;
112 	d2.cd_offset = 0;
113 	d2.cd_length = output->length;
114 	d2.cd_raw = v2;
115 
116 	mech.cm_type = context->kef_hash_mt;
117 	if (mech.cm_type == CRYPTO_MECH_INVALID) {
118 		KRB5_LOG(KRB5_ERR,
119 			"k5_ef_mac() invalid mech specified: 0x%llx",
120 			(long long)context->kef_hash_mt);
121 		return (CRYPTO_FAILED);
122 	}
123 
124 	mech.cm_param = ivec->data;
125 	mech.cm_param_len = ivec->length;
126 
127 	v1.iov_base = (void *)input->data;
128 	v1.iov_len = input->length;
129 
130 	d1.cd_format = CRYPTO_DATA_RAW;
131 	d1.cd_offset = 0;
132 	d1.cd_length = input->length;
133 	d1.cd_raw = v1;
134 
135 	rv = crypto_mac(&mech, &d1, &key->kef_key, key->key_tmpl, &d2, NULL);
136 	if (rv != CRYPTO_SUCCESS) {
137 		KRB5_LOG(KRB5_ERR,
138 			"k5_ef_mac(): crypto_mac error: %0x", rv);
139 	}
140 
141 	return (rv);
142 }
143