1*48e11a6eSGordon Ross /*
2*48e11a6eSGordon Ross * CDDL HEADER START
3*48e11a6eSGordon Ross *
4*48e11a6eSGordon Ross * The contents of this file are subject to the terms of the
5*48e11a6eSGordon Ross * Common Development and Distribution License (the "License").
6*48e11a6eSGordon Ross * You may not use this file except in compliance with the License.
7*48e11a6eSGordon Ross *
8*48e11a6eSGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*48e11a6eSGordon Ross * or http://www.opensolaris.org/os/licensing.
10*48e11a6eSGordon Ross * See the License for the specific language governing permissions
11*48e11a6eSGordon Ross * and limitations under the License.
12*48e11a6eSGordon Ross *
13*48e11a6eSGordon Ross * When distributing Covered Code, include this CDDL HEADER in each
14*48e11a6eSGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*48e11a6eSGordon Ross * If applicable, add the following below this CDDL HEADER, with the
16*48e11a6eSGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
17*48e11a6eSGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
18*48e11a6eSGordon Ross *
19*48e11a6eSGordon Ross * CDDL HEADER END
20*48e11a6eSGordon Ross */
21*48e11a6eSGordon Ross /*
22*48e11a6eSGordon Ross * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*48e11a6eSGordon Ross * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24*48e11a6eSGordon Ross * Copyright 2022-2024 RackTop Systems, Inc.
25*48e11a6eSGordon Ross */
26*48e11a6eSGordon Ross
27*48e11a6eSGordon Ross #include <netsmb/nsmb_kcrypt.h>
28*48e11a6eSGordon Ross #include <sys/types.h>
29*48e11a6eSGordon Ross #include <sys/sysmacros.h>
30*48e11a6eSGordon Ross #include <sys/ddi.h>
31*48e11a6eSGordon Ross #include <sys/sunddi.h>
32*48e11a6eSGordon Ross #include <sys/byteorder.h>
33*48e11a6eSGordon Ross #include <sys/debug.h>
34*48e11a6eSGordon Ross
35*48e11a6eSGordon Ross /*
36*48e11a6eSGordon Ross * Derive SMB3 key as described in [MS-SMB2] 3.1.4.2
37*48e11a6eSGordon Ross * and [NIST SP800-108]
38*48e11a6eSGordon Ross *
39*48e11a6eSGordon Ross * r = 32, PRF = HMAC-SHA256, key = (session key),
40*48e11a6eSGordon Ross * L = 128 or 256
41*48e11a6eSGordon Ross */
42*48e11a6eSGordon Ross
43*48e11a6eSGordon Ross /*
44*48e11a6eSGordon Ross * SMB 3.0.2 KDF Input
45*48e11a6eSGordon Ross *
46*48e11a6eSGordon Ross * Session.SigningKey for binding a session:
47*48e11a6eSGordon Ross * - Session.SessionKey as K1
48*48e11a6eSGordon Ross * - label = "SMB2AESCMAC" (size 12)
49*48e11a6eSGordon Ross * - context = "SmbSign" (size 8)
50*48e11a6eSGordon Ross * Channel.SigningKey for for all other requests
51*48e11a6eSGordon Ross * - if SMB2_SESSION_FLAG_BINDING, GSS key (in Session.SessionKey?) as K1;
52*48e11a6eSGordon Ross * - otherwise, Session.SessionKey as K1
53*48e11a6eSGordon Ross * - label = "SMB2AESCMAC" (size 12)
54*48e11a6eSGordon Ross * - context = "SmbSign" (size 8)
55*48e11a6eSGordon Ross * Session.ApplicationKey for ... (not sure what yet)
56*48e11a6eSGordon Ross * - Session.SessionKey as K1
57*48e11a6eSGordon Ross * - label = "SMB2APP" (size 8)
58*48e11a6eSGordon Ross * - context = "SmbRpc" (size 7)
59*48e11a6eSGordon Ross * Session.EncryptionKey for encrypting server messages
60*48e11a6eSGordon Ross * - Session.SessionKey as K1
61*48e11a6eSGordon Ross * - label = "SMB2AESCCM" (size 11)
62*48e11a6eSGordon Ross * - context = "ServerOut" (size 10)
63*48e11a6eSGordon Ross * Session.DecryptionKey for decrypting client requests
64*48e11a6eSGordon Ross * - Session.SessionKey as K1
65*48e11a6eSGordon Ross * - label = "SMB2AESCCM" (size 11)
66*48e11a6eSGordon Ross * - context = "ServerIn " (size 10) (Note the space)
67*48e11a6eSGordon Ross */
68*48e11a6eSGordon Ross
69*48e11a6eSGordon Ross /*
70*48e11a6eSGordon Ross * SMB 3.1.1 KDF Input
71*48e11a6eSGordon Ross *
72*48e11a6eSGordon Ross * Session.SigningKey for binding a session:
73*48e11a6eSGordon Ross * - Session.SessionKey as K1
74*48e11a6eSGordon Ross * - label = "SMBSigningKey" (size 14)
75*48e11a6eSGordon Ross * - context = preauth hashval
76*48e11a6eSGordon Ross * Channel.SigningKey for for all other requests
77*48e11a6eSGordon Ross * - if SMB2_SESSION_FLAG_BINDING, GSS key (in Session.SessionKey?) as K1;
78*48e11a6eSGordon Ross * - otherwise, Session.SessionKey as K1
79*48e11a6eSGordon Ross * - label = "SMBSigningKey" (size 14)
80*48e11a6eSGordon Ross * - context = preauth hashval
81*48e11a6eSGordon Ross * Session.EncryptionKey for encrypting server messages
82*48e11a6eSGordon Ross * - Session.SessionKey as K1
83*48e11a6eSGordon Ross * - label = "SMBS2CCipherKey" (size 16)
84*48e11a6eSGordon Ross * - context = preauth hashval
85*48e11a6eSGordon Ross * Session.DecryptionKey for decrypting client requests
86*48e11a6eSGordon Ross * - Session.SessionKey as K1
87*48e11a6eSGordon Ross * - label = "SMBC2SCipherKey" (size 16)
88*48e11a6eSGordon Ross * - context = preauth hashval
89*48e11a6eSGordon Ross */
90*48e11a6eSGordon Ross
91*48e11a6eSGordon Ross #define KDF_LABEL_MAXLEN 16
92*48e11a6eSGordon Ross #define KDF_CONTEXT_MAXLEN 64
93*48e11a6eSGordon Ross #define KDF_FIXEDPART_LEN 9
94*48e11a6eSGordon Ross #define KDF_BUFLEN 89 /* total of above */
95*48e11a6eSGordon Ross
96*48e11a6eSGordon Ross /*
97*48e11a6eSGordon Ross * SMB3KDF(Ki, Label, Context)
98*48e11a6eSGordon Ross * counter || Label || 0x00 || Context || L
99*48e11a6eSGordon Ross */
100*48e11a6eSGordon Ross int
nsmb_kdf(uint8_t * outbuf,uint32_t keylen,uint8_t * ssn_key,size_t ssn_keylen,uint8_t * label,size_t label_len,uint8_t * context,size_t context_len)101*48e11a6eSGordon Ross nsmb_kdf(uint8_t *outbuf, uint32_t keylen,
102*48e11a6eSGordon Ross uint8_t *ssn_key, size_t ssn_keylen,
103*48e11a6eSGordon Ross uint8_t *label, size_t label_len,
104*48e11a6eSGordon Ross uint8_t *context, size_t context_len)
105*48e11a6eSGordon Ross {
106*48e11a6eSGordon Ross smb_crypto_mech_t mech;
107*48e11a6eSGordon Ross uint8_t digest32[SHA256_DIGEST_LENGTH];
108*48e11a6eSGordon Ross uint8_t kdfbuf[KDF_BUFLEN];
109*48e11a6eSGordon Ross uint32_t L = keylen << 3; /* key len in bits */
110*48e11a6eSGordon Ross int pos = 0;
111*48e11a6eSGordon Ross int rc;
112*48e11a6eSGordon Ross
113*48e11a6eSGordon Ross if (label_len > KDF_LABEL_MAXLEN ||
114*48e11a6eSGordon Ross context_len > KDF_CONTEXT_MAXLEN) {
115*48e11a6eSGordon Ross ASSERT(0);
116*48e11a6eSGordon Ross return (-1);
117*48e11a6eSGordon Ross }
118*48e11a6eSGordon Ross
119*48e11a6eSGordon Ross /* Counter=1 (big-endian) */
120*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
121*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
122*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
123*48e11a6eSGordon Ross kdfbuf[pos++] = 1;
124*48e11a6eSGordon Ross
125*48e11a6eSGordon Ross bcopy(label, &kdfbuf[pos], label_len);
126*48e11a6eSGordon Ross pos += label_len;
127*48e11a6eSGordon Ross
128*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
129*48e11a6eSGordon Ross
130*48e11a6eSGordon Ross bcopy(context, &kdfbuf[pos], context_len);
131*48e11a6eSGordon Ross pos += context_len;
132*48e11a6eSGordon Ross
133*48e11a6eSGordon Ross /* Key length in bits, big-endian, possibly misaligned */
134*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
135*48e11a6eSGordon Ross kdfbuf[pos++] = 0;
136*48e11a6eSGordon Ross kdfbuf[pos++] = (uint8_t)(L >> 8);
137*48e11a6eSGordon Ross kdfbuf[pos++] = (uint8_t)L;
138*48e11a6eSGordon Ross
139*48e11a6eSGordon Ross bzero(&mech, sizeof (mech));
140*48e11a6eSGordon Ross if ((rc = nsmb_hmac_getmech(&mech)) != 0)
141*48e11a6eSGordon Ross return (rc);
142*48e11a6eSGordon Ross
143*48e11a6eSGordon Ross rc = nsmb_hmac_one(&mech,
144*48e11a6eSGordon Ross ssn_key, ssn_keylen,
145*48e11a6eSGordon Ross kdfbuf, pos,
146*48e11a6eSGordon Ross digest32, SHA256_DIGEST_LENGTH);
147*48e11a6eSGordon Ross if (rc != 0)
148*48e11a6eSGordon Ross return (rc);
149*48e11a6eSGordon Ross
150*48e11a6eSGordon Ross bcopy(digest32, outbuf, keylen);
151*48e11a6eSGordon Ross return (0);
152*48e11a6eSGordon Ross }
153