14e065a9fSAlexander Stetsenko /*
24e065a9fSAlexander Stetsenko  * This file and its contents are supplied under the terms of the
34e065a9fSAlexander Stetsenko  * Common Development and Distribution License ("CDDL"), version 1.0.
44e065a9fSAlexander Stetsenko  * You may only use this file in accordance with the terms of version
54e065a9fSAlexander Stetsenko  * 1.0 of the CDDL.
64e065a9fSAlexander Stetsenko  *
74e065a9fSAlexander Stetsenko  * A full copy of the text of the CDDL should have accompanied this
84e065a9fSAlexander Stetsenko  * source.  A copy of the CDDL is also available via the Internet at
94e065a9fSAlexander Stetsenko  * http://www.illumos.org/license/CDDL.
104e065a9fSAlexander Stetsenko  */
114e065a9fSAlexander Stetsenko 
124e065a9fSAlexander Stetsenko /*
13*e472a1cdSGordon Ross  * Copyright 2021 RackTop Systems, Inc.
144e065a9fSAlexander Stetsenko  */
154e065a9fSAlexander Stetsenko 
16*e472a1cdSGordon Ross #include <stdlib.h>
17*e472a1cdSGordon Ross #include <smbsrv/smb_kproto.h>
18*e472a1cdSGordon Ross #include <smbsrv/smb_kcrypt.h>
19*e472a1cdSGordon Ross #include <security/cryptoki.h>
20*e472a1cdSGordon Ross #include <security/pkcs11.h>
214e065a9fSAlexander Stetsenko 
224e065a9fSAlexander Stetsenko /*
23*e472a1cdSGordon Ross  * SMB 3.1.1 Preauth Integrity
24*e472a1cdSGordon Ross  */
25*e472a1cdSGordon Ross static int
getmech_sha512(smb_crypto_mech_t * mech)26*e472a1cdSGordon Ross getmech_sha512(smb_crypto_mech_t *mech)
27*e472a1cdSGordon Ross {
28*e472a1cdSGordon Ross 	ulong_t mid = CKM_SHA512;
29*e472a1cdSGordon Ross 	CK_SESSION_HANDLE hdl;
30*e472a1cdSGordon Ross 	CK_RV rv;
31*e472a1cdSGordon Ross 
32*e472a1cdSGordon Ross 	rv = SUNW_C_GetMechSession(mid, &hdl);
33*e472a1cdSGordon Ross 	if (rv != CKR_OK) {
34*e472a1cdSGordon Ross 		cmn_err(CE_NOTE, "PKCS#11: no mech 0x%x",
35*e472a1cdSGordon Ross 		    (unsigned int)mid);
36*e472a1cdSGordon Ross 		return (-1);
37*e472a1cdSGordon Ross 	}
38*e472a1cdSGordon Ross 	(void) C_CloseSession(hdl);
39*e472a1cdSGordon Ross 
40*e472a1cdSGordon Ross 	mech->mechanism = mid;
41*e472a1cdSGordon Ross 	mech->pParameter = NULL;
42*e472a1cdSGordon Ross 	mech->ulParameterLen = 0;
43*e472a1cdSGordon Ross 	return (0);
44*e472a1cdSGordon Ross }
45*e472a1cdSGordon Ross 
46*e472a1cdSGordon Ross /*
47*e472a1cdSGordon Ross  * (called from smb2_negotiate_common)
484e065a9fSAlexander Stetsenko  */
494e065a9fSAlexander Stetsenko void
smb31_preauth_init_mech(smb_session_t * s)504e065a9fSAlexander Stetsenko smb31_preauth_init_mech(smb_session_t *s)
514e065a9fSAlexander Stetsenko {
52*e472a1cdSGordon Ross 	smb_crypto_mech_t *mech;
53*e472a1cdSGordon Ross 	int rc;
54*e472a1cdSGordon Ross 
55*e472a1cdSGordon Ross 	ASSERT3S(s->dialect, >=, SMB_VERS_3_11);
56*e472a1cdSGordon Ross 
57*e472a1cdSGordon Ross 	if (s->preauth_mech != NULL)
58*e472a1cdSGordon Ross 		return;
59*e472a1cdSGordon Ross 
60*e472a1cdSGordon Ross 	mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);
61*e472a1cdSGordon Ross 	rc = getmech_sha512(mech);
62*e472a1cdSGordon Ross 	if (rc != 0) {
63*e472a1cdSGordon Ross 		kmem_free(mech, sizeof (*mech));
64*e472a1cdSGordon Ross 		return;
65*e472a1cdSGordon Ross 	}
66*e472a1cdSGordon Ross 	s->preauth_mech = mech;
674e065a9fSAlexander Stetsenko }
684e065a9fSAlexander Stetsenko 
694e065a9fSAlexander Stetsenko void
smb31_preauth_fini(smb_session_t * s)704e065a9fSAlexander Stetsenko smb31_preauth_fini(smb_session_t *s)
714e065a9fSAlexander Stetsenko {
72*e472a1cdSGordon Ross 	smb_crypto_mech_t *mech;
73*e472a1cdSGordon Ross 
74*e472a1cdSGordon Ross 	if ((mech = s->preauth_mech) != NULL) {
75*e472a1cdSGordon Ross 		kmem_free(mech, sizeof (*mech));
76*e472a1cdSGordon Ross 		s->preauth_mech = NULL;
77*e472a1cdSGordon Ross 	}
78*e472a1cdSGordon Ross }
79*e472a1cdSGordon Ross 
80*e472a1cdSGordon Ross /*
81*e472a1cdSGordon Ross  * Start the KCF session, load the key
82*e472a1cdSGordon Ross  */
83*e472a1cdSGordon Ross int
smb_sha512_init(smb_sign_ctx_t * ctxp,smb_crypto_mech_t * mech)84*e472a1cdSGordon Ross smb_sha512_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech)
85*e472a1cdSGordon Ross {
86*e472a1cdSGordon Ross 	CK_RV rv;
87*e472a1cdSGordon Ross 
88*e472a1cdSGordon Ross 	rv = SUNW_C_GetMechSession(mech->mechanism, ctxp);
89*e472a1cdSGordon Ross 	if (rv != CKR_OK)
90*e472a1cdSGordon Ross 		return (-1);
91*e472a1cdSGordon Ross 
92*e472a1cdSGordon Ross 	rv = C_DigestInit(*ctxp, mech);
93*e472a1cdSGordon Ross 
94*e472a1cdSGordon Ross 	return (rv == CKR_OK ? 0 : -1);
95*e472a1cdSGordon Ross }
96*e472a1cdSGordon Ross 
97*e472a1cdSGordon Ross /*
98*e472a1cdSGordon Ross  * Digest one segment
99*e472a1cdSGordon Ross  */
100*e472a1cdSGordon Ross int
smb_sha512_update(smb_sign_ctx_t ctx,void * buf,size_t len)101*e472a1cdSGordon Ross smb_sha512_update(smb_sign_ctx_t ctx, void *buf, size_t len)
102*e472a1cdSGordon Ross {
103*e472a1cdSGordon Ross 	CK_RV rv;
104*e472a1cdSGordon Ross 
105*e472a1cdSGordon Ross 	rv = C_DigestUpdate(ctx, buf, len);
106*e472a1cdSGordon Ross 	if (rv != CKR_OK)
107*e472a1cdSGordon Ross 		(void) C_CloseSession(ctx);
108*e472a1cdSGordon Ross 
109*e472a1cdSGordon Ross 	return (rv == CKR_OK ? 0 : -1);
110*e472a1cdSGordon Ross }
111*e472a1cdSGordon Ross 
112*e472a1cdSGordon Ross /*
113*e472a1cdSGordon Ross  * Get the final digest.
114*e472a1cdSGordon Ross  */
115*e472a1cdSGordon Ross int
smb_sha512_final(smb_sign_ctx_t ctx,uint8_t * digest)116*e472a1cdSGordon Ross smb_sha512_final(smb_sign_ctx_t ctx, uint8_t *digest)
117*e472a1cdSGordon Ross {
118*e472a1cdSGordon Ross 	CK_ULONG len = SHA512_DIGEST_LENGTH;
119*e472a1cdSGordon Ross 	CK_RV rv;
120*e472a1cdSGordon Ross 
121*e472a1cdSGordon Ross 	rv = C_DigestFinal(ctx, digest, &len);
122*e472a1cdSGordon Ross 	(void) C_CloseSession(ctx);
123*e472a1cdSGordon Ross 
124*e472a1cdSGordon Ross 	return (rv == CKR_OK ? 0 : -1);
1254e065a9fSAlexander Stetsenko }
1264e065a9fSAlexander Stetsenko 
1274e065a9fSAlexander Stetsenko int
smb31_preauth_sha512_calc(smb_request_t * sr,struct mbuf_chain * mbc,uint8_t * in_hashval,uint8_t * out_hashval)1284e065a9fSAlexander Stetsenko smb31_preauth_sha512_calc(smb_request_t *sr, struct mbuf_chain *mbc,
1294e065a9fSAlexander Stetsenko     uint8_t *in_hashval, uint8_t *out_hashval)
1304e065a9fSAlexander Stetsenko {
131*e472a1cdSGordon Ross 	smb_session_t *s = sr->session;
132*e472a1cdSGordon Ross 	smb_sign_ctx_t ctx = 0;
133*e472a1cdSGordon Ross 	struct mbuf *mbuf = mbc->chain;
134*e472a1cdSGordon Ross 	int rc;
135*e472a1cdSGordon Ross 
136*e472a1cdSGordon Ross 	ASSERT3U(s->smb31_preauth_hashid, !=, 0);
137*e472a1cdSGordon Ross 
138*e472a1cdSGordon Ross 	if (s->preauth_mech == NULL)
139*e472a1cdSGordon Ross 		return (-1);
140*e472a1cdSGordon Ross 
141*e472a1cdSGordon Ross 	if ((rc = smb_sha512_init(&ctx, s->preauth_mech)) != 0)
142*e472a1cdSGordon Ross 		return (rc);
143*e472a1cdSGordon Ross 
144*e472a1cdSGordon Ross 	/* Digest current hashval */
145*e472a1cdSGordon Ross 	rc = smb_sha512_update(ctx, in_hashval, SHA512_DIGEST_LENGTH);
146*e472a1cdSGordon Ross 	if (rc != 0)
147*e472a1cdSGordon Ross 		return (rc);
148*e472a1cdSGordon Ross 
149*e472a1cdSGordon Ross 	while (mbuf != NULL) {
150*e472a1cdSGordon Ross 		rc = smb_sha512_update(ctx, mbuf->m_data, mbuf->m_len);
151*e472a1cdSGordon Ross 		if (rc != 0)
152*e472a1cdSGordon Ross 			return (rc);
153*e472a1cdSGordon Ross 		mbuf = mbuf->m_next;
154*e472a1cdSGordon Ross 	}
155*e472a1cdSGordon Ross 
156*e472a1cdSGordon Ross 	rc = smb_sha512_final(ctx, out_hashval);
157*e472a1cdSGordon Ross 	return (rc);
1584e065a9fSAlexander Stetsenko }
159