Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-6685 Potential memory leak in SMB KCF wrapper
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3728 SMB1 signing should use KCF like SMB2/3
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>

*** 8,18 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* * Helper functions for SMB signing using the * Kernel Cryptographic Framework (KCF) --- 8,18 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * Helper functions for SMB signing using the * Kernel Cryptographic Framework (KCF)
*** 24,57 **** #include <sys/types.h> #include <sys/kmem.h> #include <sys/crypto/api.h> #include <smbsrv/smb_kproto.h> ! #include <smbsrv/smb_signing.h> /* ! * SMB1 signing helpers: ! * (getmech, init, update, final) */ ! ! int ! smb_md5_getmech(smb_sign_mech_t *mech) { crypto_mech_type_t t; ! t = crypto_mech2id(SUN_CKM_MD5); ! if (t == CRYPTO_MECH_INVALID) return (-1); mech->cm_type = t; return (0); } /* * Start the KCF session, load the key */ int ! smb_md5_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech) { int rv; rv = crypto_digest_init(mech, ctxp, NULL); --- 24,68 ---- #include <sys/types.h> #include <sys/kmem.h> #include <sys/crypto/api.h> #include <smbsrv/smb_kproto.h> ! #include <smbsrv/smb_kcrypt.h> /* ! * Common function to see if a mech is available. */ ! static int ! find_mech(smb_crypto_mech_t *mech, crypto_mech_name_t name) { crypto_mech_type_t t; ! t = crypto_mech2id(name); ! if (t == CRYPTO_MECH_INVALID) { ! cmn_err(CE_NOTE, "smb: no kcf mech: %s", name); return (-1); + } mech->cm_type = t; return (0); } /* + * SMB1 signing helpers: + * (getmech, init, update, final) + */ + + int + smb_md5_getmech(smb_crypto_mech_t *mech) + { + return (find_mech(mech, SUN_CKM_MD5)); + } + + /* * Start the KCF session, load the key */ int ! smb_md5_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech) { int rv; rv = crypto_digest_init(mech, ctxp, NULL);
*** 73,83 **** data.cd_raw.iov_base = buf; data.cd_raw.iov_len = len; rv = crypto_digest_update(ctx, &data, 0); ! return (rv == CRYPTO_SUCCESS ? 0 : -1); } /* * Get the final digest. */ --- 84,99 ---- data.cd_raw.iov_base = buf; data.cd_raw.iov_len = len; rv = crypto_digest_update(ctx, &data, 0); ! if (rv != CRYPTO_SUCCESS) { ! crypto_cancel_ctx(ctx); ! return (-1); ! } ! ! return (0); } /* * Get the final digest. */
*** 102,127 **** * SMB2 signing helpers: * (getmech, init, update, final) */ int ! smb2_hmac_getmech(smb_sign_mech_t *mech) { ! crypto_mech_type_t t; ! ! t = crypto_mech2id(SUN_CKM_SHA256_HMAC); ! if (t == CRYPTO_MECH_INVALID) ! return (-1); ! mech->cm_type = t; ! return (0); } /* * Start the KCF session, load the key */ int ! smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech, uint8_t *key, size_t key_len) { crypto_key_t ckey; int rv; --- 118,137 ---- * SMB2 signing helpers: * (getmech, init, update, final) */ int ! smb2_hmac_getmech(smb_crypto_mech_t *mech) { ! return (find_mech(mech, SUN_CKM_SHA256_HMAC)); } /* * Start the KCF session, load the key */ int ! smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech, uint8_t *key, size_t key_len) { crypto_key_t ckey; int rv;
*** 150,160 **** data.cd_raw.iov_base = (void *)in; data.cd_raw.iov_len = len; rv = crypto_mac_update(ctx, &data, 0); ! return (rv == CRYPTO_SUCCESS ? 0 : -1); } /* * Note, the SMB2 signature is the first 16 bytes of the * 32-byte SHA256 HMAC digest. --- 160,175 ---- data.cd_raw.iov_base = (void *)in; data.cd_raw.iov_len = len; rv = crypto_mac_update(ctx, &data, 0); ! if (rv != CRYPTO_SUCCESS) { ! crypto_cancel_ctx(ctx); ! return (-1); ! } ! ! return (0); } /* * Note, the SMB2 signature is the first 16 bytes of the * 32-byte SHA256 HMAC digest.
*** 175,180 **** --- 190,272 ---- rv = crypto_mac_final(ctx, &out, 0); if (rv == CRYPTO_SUCCESS) bcopy(full_digest, digest16, 16); return (rv == CRYPTO_SUCCESS ? 0 : -1); + } + + /* + * SMB3 signing helpers: + * (getmech, init, update, final) + */ + + int + smb3_cmac_getmech(smb_crypto_mech_t *mech) + { + return (find_mech(mech, SUN_CKM_AES_CMAC)); + } + + /* + * Start the KCF session, load the key + */ + int + smb3_cmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech, + uint8_t *key, size_t key_len) + { + crypto_key_t ckey; + int rv; + + bzero(&ckey, sizeof (ckey)); + ckey.ck_format = CRYPTO_KEY_RAW; + ckey.ck_data = key; + ckey.ck_length = key_len * 8; /* in bits */ + + rv = crypto_mac_init(mech, &ckey, NULL, ctxp, NULL); + + return (rv == CRYPTO_SUCCESS ? 0 : -1); + } + + /* + * Digest one segment + */ + int + smb3_cmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len) + { + crypto_data_t data; + int rv; + + bzero(&data, sizeof (data)); + data.cd_format = CRYPTO_DATA_RAW; + data.cd_length = len; + data.cd_raw.iov_base = (void *)in; + data.cd_raw.iov_len = len; + + rv = crypto_mac_update(ctx, &data, 0); + + if (rv != CRYPTO_SUCCESS) { + crypto_cancel_ctx(ctx); + return (-1); + } + + return (0); + } + + /* + * Note, the SMB2 signature is just the AES CMAC digest. + * (both are 16 bytes long) + */ + int + smb3_cmac_final(smb_sign_ctx_t ctx, uint8_t *digest16) + { + crypto_data_t out; + int rv; + + bzero(&out, sizeof (out)); + out.cd_format = CRYPTO_DATA_RAW; + out.cd_length = SMB2_SIG_SIZE; + out.cd_raw.iov_len = SMB2_SIG_SIZE; + out.cd_raw.iov_base = (void *)digest16; + + rv = crypto_mac_final(ctx, &out, 0); + + return (rv == CRYPTO_SUCCESS ? 0 : -1); }