1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 /* 28 * Support for SMB2 "signing" (message integrity) 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/conf.h> 34 #include <sys/proc.h> 35 #include <sys/fcntl.h> 36 #include <sys/socket.h> 37 #include <sys/md4.h> 38 #include <sys/md5.h> 39 #include <sys/des.h> 40 #include <sys/kmem.h> 41 #include <sys/cmn_err.h> 42 #include <sys/stream.h> 43 #include <sys/strsun.h> 44 #include <sys/sdt.h> 45 46 #include <netsmb/smb_osdep.h> 47 #include <netsmb/smb2.h> 48 #include <netsmb/smb_conn.h> 49 #include <netsmb/smb_subr.h> 50 #include <netsmb/smb_dev.h> 51 #include <netsmb/smb_rq.h> 52 #include <netsmb/smb_signing.h> 53 54 #define SMB2_SIG_OFF 48 55 #define SMB2_SIG_LEN 16 56 57 typedef struct smb_mac_ops { 58 int (*mac_init)(smb_sign_ctx_t *, smb_sign_mech_t *, 59 uint8_t *, size_t); 60 int (*mac_update)(smb_sign_ctx_t, uint8_t *, size_t); 61 int (*mac_final)(smb_sign_ctx_t, uint8_t *); 62 } smb_mac_ops_t; 63 64 static smb_mac_ops_t 65 smb2_sign_ops = { 66 smb2_hmac_init, 67 smb2_hmac_update, 68 smb2_hmac_final 69 }; 70 71 static struct smb_mac_ops 72 smb3_sign_ops = { 73 smb3_cmac_init, 74 smb3_cmac_update, 75 smb3_cmac_final 76 }; 77 78 /* 79 * Input to KDF for SigningKey. 80 * See comment for smb3_do_kdf for content. 81 */ 82 static uint8_t sign_kdf_input[29] = { 83 0, 0, 0, 1, 'S', 'M', 'B', '2', 84 'A', 'E', 'S', 'C', 'M', 'A', 'C', 0, 85 0, 'S', 'm', 'b', 'S', 'i', 'g', 'n', 86 0, 0, 0, 0, 0x80 }; 87 88 int smb3_do_kdf(void *outbuf, size_t outbuf_len, 89 void *input, size_t input_len, 90 uint8_t *key, uint32_t key_len); 91 92 /* 93 * smb2_sign_init 94 * 95 * Get the mechanism info and initilize SMB2 or SMB3 signing. 96 */ 97 int 98 smb2_sign_init(smb_vc_t *vcp) 99 { 100 uint_t copysize; 101 int rc; 102 103 ASSERT(vcp->vc_ssnkey != NULL); 104 ASSERT(vcp->vc_mackey == NULL); 105 106 if (SMB_DIALECT(vcp) < SMB2_DIALECT_0300) 107 rc = smb2_hmac_getmech(&vcp->vc_signmech); 108 else 109 rc = smb3_cmac_getmech(&vcp->vc_signmech); 110 if (rc != 0) 111 return (EAUTH); 112 113 /* 114 * Convert the session key to the MAC key. 115 * 116 * For SMB2, the signing key is just the first 16 bytes 117 * of the session key (truncated or padded with zeros). 118 * For SMB3, the signing key is a "KDF" hash of the 119 * session key. [MS-SMB2] 3.2.5.3.1 120 */ 121 vcp->vc_mackeylen = SMB2_SIG_LEN; 122 vcp->vc_mackey = kmem_zalloc(vcp->vc_mackeylen, KM_SLEEP); 123 if (SMB_DIALECT(vcp) < SMB2_DIALECT_0300) { 124 copysize = vcp->vc_ssnkeylen; 125 if (copysize > vcp->vc_mackeylen) 126 copysize = vcp->vc_mackeylen; 127 bcopy(vcp->vc_ssnkey, vcp->vc_mackey, copysize); 128 129 vcp->vc_sign_ops = &smb2_sign_ops; 130 } else { 131 rc = smb3_do_kdf(vcp->vc_mackey, vcp->vc_mackeylen, 132 sign_kdf_input, sizeof (sign_kdf_input), 133 vcp->vc_ssnkey, vcp->vc_ssnkeylen); 134 if (rc != 0) 135 return (EAUTH); 136 vcp->vc_sign_ops = &smb3_sign_ops; 137 } 138 139 return (0); 140 } 141 142 /* 143 * Derive SMB3 key as described in [MS-SMB2] 3.1.4.2 144 * and [NIST SP800-108] 145 * 146 * r = 32, L = 128, PRF = HMAC-SHA256, key = (session key) 147 * 148 * Note that these describe pre-3.1.1 inputs. 149 * 150 * Session.SigningKey for binding a session: 151 * - Session.SessionKey as K1 152 * - label = SMB2AESCMAC (size 12) 153 * - context = SmbSign (size 8) 154 * Channel.SigningKey for for all other requests 155 * - if SMB2_SESSION_FLAG_BINDING, GSS key (in Session.SessionKey?) as K1; 156 * - otherwise, Session.SessionKey as K1 157 * - label = SMB2AESCMAC (size 12) 158 * - context = SmbSign (size 8) 159 * Session.ApplicationKey for ... (not sure what yet) 160 * - Session.SessionKey as K1 161 * - label = SMB2APP (size 8) 162 * - context = SmbRpc (size 7) 163 * Session.EncryptionKey for encrypting server messages 164 * - Session.SessionKey as K1 165 * - label = "SMB2AESCCM" (size 11) 166 * - context = "ServerOut" (size 10) 167 * Session.DecryptionKey for decrypting client requests 168 * - Session.SessionKey as K1 169 * - label = "SMB2AESCCM" (size 11) 170 * - context = "ServerIn " (size 10) (Note the space) 171 */ 172 int 173 smb3_do_kdf(void *outbuf, size_t outbuf_len, 174 void *input, size_t input_len, 175 uint8_t *key, uint32_t key_len) 176 { 177 uint8_t digest32[SHA256_DIGEST_LENGTH]; 178 smb_sign_mech_t mech; 179 smb_sign_ctx_t hctx = 0; 180 int rc; 181 182 bzero(&mech, sizeof (mech)); 183 if ((rc = smb2_hmac_getmech(&mech)) != 0) 184 return (rc); 185 186 /* Limit the SessionKey input to its maximum size (16 bytes) */ 187 if (key_len > SMB2_SIG_SIZE) 188 key_len = SMB2_SIG_SIZE; 189 rc = smb2_hmac_init(&hctx, &mech, key, key_len); 190 if (rc != 0) 191 return (rc); 192 193 if ((rc = smb2_hmac_update(hctx, input, input_len)) != 0) 194 return (rc); 195 196 if ((rc = smb2_hmac_final(hctx, digest32)) != 0) 197 return (rc); 198 199 /* Output is first 16 bytes of digest. */ 200 bcopy(digest32, outbuf, outbuf_len); 201 return (0); 202 } 203 204 /* 205 * Compute MAC signature of packet data, using the stored MAC key. 206 * 207 * The signature is in the last 16 bytes of the SMB2 header. 208 * The signature algorighm is to compute HMAC SHA256 over the 209 * entire command, with the signature field set to zeros. 210 * 211 * See similar code for the server side: 212 * uts/common/fs/smbsrv/smb2_signing.c : smb2_sign_calc 213 */ 214 static int 215 smb2_compute_MAC(struct smb_vc *vcp, mblk_t *mp, uchar_t *signature) 216 { 217 uint8_t tmp_hdr[SMB2_HDR_SIZE]; 218 smb_sign_ctx_t ctx = 0; 219 smb_mac_ops_t *ops; 220 mblk_t *m = mp; 221 int size; 222 int rc; 223 224 if (vcp->vc_mackey == NULL) 225 return (-1); 226 if ((ops = vcp->vc_sign_ops) == NULL) 227 return (-1); 228 229 rc = ops->mac_init(&ctx, &vcp->vc_signmech, 230 vcp->vc_mackey, vcp->vc_mackeylen); 231 if (rc != 0) 232 return (rc); 233 234 /* Our caller should ensure mp has a contiguous header */ 235 ASSERT(m != NULL); 236 ASSERT(MBLKL(m) >= SMB2_HDRLEN); 237 238 /* 239 * Copy of the SMB2 header, zero out the signature, and digest. 240 */ 241 size = SMB2_HDRLEN; 242 bcopy(m->b_rptr, tmp_hdr, size); 243 bzero(tmp_hdr + SMB2_SIG_OFF, SMB2_SIG_LEN); 244 rc = ops->mac_update(ctx, tmp_hdr, size); 245 if (rc != 0) 246 return (rc); 247 248 /* 249 * Digest the rest of the SMB2 header packet, starting at 250 * the data just after the SMB2 header. 251 */ 252 size = MBLKL(m) - SMB2_HDRLEN; 253 rc = ops->mac_update(ctx, m->b_rptr + SMB2_HDRLEN, size); 254 if (rc != 0) 255 return (rc); 256 m = m->b_cont; 257 258 /* Digest rest of the SMB2 message. */ 259 while (m != NULL) { 260 size = MBLKL(m); 261 if (size > 0) { 262 rc = ops->mac_update(ctx, m->b_rptr, size); 263 if (rc != 0) 264 return (rc); 265 } 266 m = m->b_cont; 267 } 268 rc = ops->mac_final(ctx, signature); 269 270 return (rc); 271 } 272 273 /* 274 * Sign a request with HMAC-MD5. 275 */ 276 void 277 smb2_rq_sign(struct smb_rq *rqp) 278 { 279 struct smb_vc *vcp = rqp->sr_vc; 280 mblk_t *mp = rqp->sr_rq.mb_top; 281 uint8_t *sigloc; 282 int rc; 283 284 /* 285 * smb_rq_new() ensures this, 286 * but just in case.. 287 */ 288 ASSERT(MBLKL(mp) >= SMB2_HDRLEN); 289 sigloc = mp->b_rptr + SMB2_SIG_OFF; 290 291 if (vcp->vc_mackey == NULL) 292 return; 293 294 /* 295 * This will compute the MAC and store it 296 * directly into the message at sigloc. 297 */ 298 rc = smb2_compute_MAC(vcp, mp, sigloc); 299 if (rc != 0) { 300 SMBSDEBUG("Crypto error %d", rc); 301 bzero(sigloc, SMB2_SIG_LEN); 302 } 303 } 304 305 /* 306 * Verify reply signature. 307 */ 308 int 309 smb2_rq_verify(struct smb_rq *rqp) 310 { 311 struct smb_vc *vcp = rqp->sr_vc; 312 mblk_t *mp = rqp->sr_rp.md_top; 313 uint8_t sigbuf[SMB2_SIG_LEN]; 314 uint8_t *sigloc; 315 int rc; 316 317 /* 318 * Note vc_mackey and vc_mackeylen gets filled in by 319 * smb_usr_iod_work as the connection comes in. 320 */ 321 if (vcp->vc_mackey == NULL) { 322 SMBSDEBUG("no mac key\n"); 323 return (0); 324 } 325 326 /* 327 * Let caller deal with empty reply or short messages by 328 * returning zero. Caller will fail later, in parsing. 329 */ 330 if (mp == NULL) { 331 SMBSDEBUG("empty reply\n"); 332 return (0); 333 } 334 335 /* smb2_iod_process ensures this */ 336 ASSERT(MBLKL(mp) >= SMB2_HDRLEN); 337 sigloc = mp->b_rptr + SMB2_SIG_OFF; 338 339 /* 340 * Compute the expected signature in sigbuf. 341 */ 342 rc = smb2_compute_MAC(vcp, mp, sigbuf); 343 if (rc != 0) { 344 SMBSDEBUG("Crypto error %d", rc); 345 /* 346 * If we can't compute a MAC, then there's 347 * no point trying other seqno values. 348 */ 349 return (EBADRPC); 350 } 351 352 /* 353 * Compare the computed signature with the 354 * one found in the message (at sigloc) 355 */ 356 if (bcmp(sigbuf, sigloc, SMB2_SIG_LEN) == 0) 357 return (0); 358 359 SMBERROR("BAD signature, Server=%s MID=0x%llx\n", 360 vcp->vc_srvname, (long long)rqp->sr2_messageid); 361 362 return (EBADRPC); 363 } 364