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