summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorAlexander Stetsenko <alex.stetsenko@gmail.com>2021-07-09 14:20:16 +0300
committerRobert Mustacchi <rm@fingolfin.org>2022-01-23 23:07:38 +0000
commitdee7ba860656acbc12d71ef94c95f07396697c49 (patch)
tree6dee5a1be5933ab4de41322ec04bae5b5bd05644 /usr
parentdc5774e5554edd469013b4fe1c42fbd63f5212e1 (diff)
downloadillumos-gate-dee7ba860656acbc12d71ef94c95f07396697c49.tar.gz
13914 smbd encrypt_cipher property should list enabled ciphers explicitly
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com> Reviewed by: Andrew Stormont <andyjstormont@gmail.com> Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr')
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_cfg.c41
-rw-r--r--usr/src/man/man4/smb.438
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_negotiate.c47
-rw-r--r--usr/src/uts/common/smbsrv/smb2.h8
-rw-r--r--usr/src/uts/common/smbsrv/smbinfo.h19
5 files changed, 94 insertions, 59 deletions
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
index 0dc291d95d..160629e2ed 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2020 Tintri by DDN, Inc. All rights reserved.
- * Copyright 2020 RackTop Systems, Inc.
+ * Copyright 2021 RackTop Systems, Inc.
*/
/*
@@ -181,9 +181,10 @@ smb_versions[] = {
* Supported encryption ciphers.
*/
static struct str_val
-smb31_encrypt_ciphers[] = {
- { "aes128-ccm", SMB3_CIPHER_AES128_CCM }, /* SMB 3.x */
- { "aes128-gcm", SMB3_CIPHER_AES128_GCM }, /* SMB 3.1.1 */
+smb31_enc_ciphers[] = {
+ { "aes128-ccm", SMB3_CIPHER_FLAG_AES128_CCM }, /* SMB 3.x */
+ { "aes128-gcm", SMB3_CIPHER_FLAG_AES128_GCM }, /* SMB 3.1.1 */
+ { "all", SMB3_ALL_CIPHERS },
{ NULL, 0 }
};
@@ -1280,27 +1281,45 @@ smb_config_check_protocol(char *value)
* Only SMB 3.x supports encryption.
* SMB 3.0.2 uses AES128-CCM only.
* SMB 3.1.1 - AES128-CCM or AES128-GCM.
+ * This function returns bitmask for enabled ciphers
*/
uint16_t
smb31_config_get_encrypt_cipher(void)
{
uint32_t max_proto = smb_config_get_max_protocol();
- uint16_t cipher = SMB3_CIPHER_AES128_GCM; /* by default AES128-GCM */
- char str[12];
+ uint16_t cipher = 0;
+ char str[50];
int i;
+ /* SMB 3.0 supports only AES-128-CCM */
if (max_proto < SMB_VERS_3_11)
- return (SMB3_CIPHER_NONE);
+ return (SMB3_CIPHER_FLAG_AES128_CCM);
/* SMB 3.1.1 */
if (smb_config_getstr(SMB_CI_ENCRYPT_CIPHER, str, sizeof (str))
== SMBD_SMF_OK) {
- for (i = 0; smb31_encrypt_ciphers[i].str != NULL; i++) {
- if (strcmp(str, smb31_encrypt_ciphers[i].str) == 0)
- cipher = smb31_encrypt_ciphers[i].val;
- }
+ char *s = str;
+ char *p = NULL;
+
+ do {
+ p = strchr(s, ',');
+ if (p != NULL)
+ *p++ = '\0';
+
+ /* # of ciphers too small - don't care about O(n2) */
+ for (i = 0; smb31_enc_ciphers[i].str != NULL; i++) {
+ if (strcmp(s, smb31_enc_ciphers[i].str) == 0)
+ cipher |= smb31_enc_ciphers[i].val;
+ }
+
+ if (p != NULL)
+ s = p;
+ } while (p != NULL && *s != '\0');
}
+ if (cipher == 0)
+ cipher = SMB3_ALL_CIPHERS;
+
return (cipher);
}
diff --git a/usr/src/man/man4/smb.4 b/usr/src/man/man4/smb.4
index cecabe8179..637d22c862 100644
--- a/usr/src/man/man4/smb.4
+++ b/usr/src/man/man4/smb.4
@@ -1,7 +1,7 @@
'\" te
.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 2017, Nexenta Systems, Inc. All Rights Reserved.
-.\" Copyright 2020, RackTop Systems, Inc. All Rights Reserved.
+.\" Copyright 2021, RackTop Systems, Inc. All Rights Reserved.
.\" The contents of this file are subject to the terms of the
.\" Common Development and Distribution License (the "License").
.\" You may not use this file except in compliance with the License.
@@ -156,24 +156,25 @@ message that CAN be encrypted MUST be encrypted.
.ad
.sp .6
.RS 4n
-Specifies the maximum SMB 3.1.1 encryption cipher. This property is only used
-when encryption is On (see \fBencrypt\fR property) and negotiated SMB dialect is
-3.1.1 or higher (see \fBmax_protocol\fR property). Otherwise it is ignored.
+Specifies a list of enabled SMB 3.1.1 encryption ciphers. This property is only
+used when encryption is On (see \fBencrypt\fR property) and negotiated SMB
+dialect is 3.1.1 or higher (see \fBmax_protocol\fR property). Otherwise it is
+ignored.
.sp
-When the property is set the valid values are aes-128-ccm and aes-128-gcm.
-If aes-128-gcm is selected both CCM and GCM are allowed, but GCM is preferred.
-If aes-128-ccm is selected it is the only allowed cipher. If the property is not
-set explicitly the default value is used - aes-128-gcm.
+When the property is set, a list of comma separated ciphers should be specified,
+or the value \fBall\fR should be used instead to enable all supported ciphers.
+By default, when the property is empty, it is equivalent to value \fBall\fR -
+all available ciphers will be enabled.
.sp
-The property can be set to one of these values:
+The list of ciphers should contain these values:
.sp
.ne 2
.na
\fBaes128-ccm\fR
.ad
.RS 13n
-The only allowed cipher is AES-128-CCM. It is the only cipher used for SMB 3.0.2
-dialect. In SMB 3.1.1 it is deprecated.
+AES-128-CCM cipher is enabled. It is the only cipher used for SMB 3.0.2
+dialect.
.RE
.sp
@@ -182,10 +183,19 @@ dialect. In SMB 3.1.1 it is deprecated.
\fBaes128-gcm\fR
.ad
.RS 13n
-Both AES-128-CCM and AES-128-GCM ciphers are allowed, but AES-128-GCM is
+AES-128-GCM cipher is enabled.
preferred.
.RE
+.sp
+.ne 2
+.na
+\fBall\fR
+.ad
+.RS 13n
+All ciphers are enabled.
+.RE
+
.RE
.sp
@@ -400,8 +410,8 @@ The UID of the Unix user.
.sp .6
.RS 4n
Specifies the maximum SMB protocol level that the SMB service
-should allow clients to negotiate. The default value is \fB2.1\fR.
-Valid settings include: \fB1\fR, \fB2.1\fR, \fB3.0\fR
+should allow clients to negotiate. The default value is \fB3.11\fR.
+Valid settings include: \fB1\fR, \fB2.1\fR, \fB3.0\fR, \fB3.02\fR, \fB3.11\fR
.RE
.sp
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
index af9fd46761..7d67247588 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
@@ -269,6 +269,9 @@ typedef struct smb2_neg_ctxs {
#define STATUS_PREAUTH_HASH_OVERLAP \
STATUS_SMB_NO_PREAUTH_INEGRITY_HASH_OVERLAP
+#define SMB3_CIPHER_ENABLED(c, f) ((c) <= SMB3_CIPHER_MAX && \
+ SMB3_CIPHER_BIT(c) & (f))
+
/*
* This function should be called only for dialect >= 0x311
* Negotiate context list should contain exactly one
@@ -283,10 +286,9 @@ smb31_decode_neg_ctxs(smb_request_t *sr, smb2_neg_ctxs_t *neg_ctxs)
smb_session_t *s = sr->session;
smb2_preauth_caps_t *picap = &neg_ctxs->preauth_ctx.preauth_caps;
smb2_encrypt_caps_t *encap = &neg_ctxs->encrypt_ctx.encrypt_caps;
- boolean_t preauth_sha512_enabled = B_FALSE;
- boolean_t encrypt_ccm_enabled = B_FALSE;
- boolean_t encrypt_gcm_enabled = B_FALSE;
- uint16_t cipher = sr->sr_server->sv_cfg.skc_encrypt_cipher;
+ boolean_t found_sha512 = B_FALSE;
+ boolean_t found_cipher = B_FALSE;
+ uint16_t ciphers = sr->sr_server->sv_cfg.skc_encrypt_cipher;
uint32_t status = 0;
int32_t skip;
int found_preauth_ctx = 0;
@@ -420,7 +422,7 @@ smb31_decode_neg_ctxs(smb_request_t *sr, smb2_neg_ctxs_t *neg_ctxs)
}
if (picap->picap_hash_id == SMB3_HASH_SHA512)
- preauth_sha512_enabled = B_TRUE;
+ found_sha512 = B_TRUE;
break;
case SMB2_ENCRYPTION_CAPS:
memcpy(&neg_ctxs->preauth_ctx.neg_ctx, &neg_ctx,
@@ -452,16 +454,17 @@ smb31_decode_neg_ctxs(smb_request_t *sr, smb2_neg_ctxs_t *neg_ctxs)
goto errout;
}
+ /*
+ * Select the first enabled cipher.
+ * Client should list more prioritized ciphers first.
+ */
for (int k = 0; k < encap->encap_cipher_count; k++) {
- switch (encap->encap_cipher_ids[k]) {
- case SMB3_CIPHER_AES128_CCM:
- encrypt_ccm_enabled = B_TRUE;
- break;
- case SMB3_CIPHER_AES128_GCM:
- encrypt_gcm_enabled = B_TRUE;
+ uint16_t c = encap->encap_cipher_ids[k];
+
+ if (SMB3_CIPHER_ENABLED(c, ciphers)) {
+ s->smb31_enc_cipherid = c;
+ found_cipher = B_TRUE;
break;
- default:
- ;
}
}
break;
@@ -479,29 +482,15 @@ smb31_decode_neg_ctxs(smb_request_t *sr, smb2_neg_ctxs_t *neg_ctxs)
goto errout;
}
- if (!preauth_sha512_enabled) {
+ if (!found_sha512) {
status = STATUS_PREAUTH_HASH_OVERLAP;
goto errout;
}
s->smb31_preauth_hashid = SMB3_HASH_SHA512;
- switch (cipher) {
- case SMB3_CIPHER_AES128_GCM:
- if (encrypt_gcm_enabled) {
- s->smb31_enc_cipherid = SMB3_CIPHER_AES128_GCM;
- break;
- }
- /* FALLTHROUGH */
- case SMB3_CIPHER_AES128_CCM:
- if (encrypt_ccm_enabled) {
- s->smb31_enc_cipherid = SMB3_CIPHER_AES128_CCM;
- break;
- }
- /* FALLTHROUGH */
- default:
+ if (!found_cipher)
s->smb31_enc_cipherid = 0;
- }
errout:
return (status);
diff --git a/usr/src/uts/common/smbsrv/smb2.h b/usr/src/uts/common/smbsrv/smb2.h
index f18fcbd379..30693b5dcf 100644
--- a/usr/src/uts/common/smbsrv/smb2.h
+++ b/usr/src/uts/common/smbsrv/smb2.h
@@ -11,6 +11,7 @@
/*
* Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2021 RackTop Systems, Inc.
*/
#ifndef _SMB_SMB2_H
@@ -413,6 +414,13 @@ typedef enum {
/* SMB2 Oplock Break: lease break notification flags */
#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED 0x01
+/* SMB3.1.1 the only pre-authentication hash */
+#define SMB3_HASH_SHA512 1
+
+/* SMB3.x encryption ciphers */
+#define SMB3_CIPHER_AES128_CCM 1 /* 3.0 */
+#define SMB3_CIPHER_AES128_GCM 2 /* 3.1.1 */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/smbsrv/smbinfo.h b/usr/src/uts/common/smbsrv/smbinfo.h
index 238ee31c96..e83d871bff 100644
--- a/usr/src/uts/common/smbsrv/smbinfo.h
+++ b/usr/src/uts/common/smbsrv/smbinfo.h
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2020 Tintri by DDN, Inc. All rights reserved.
- * Copyright 2020 RackTop Systems, Inc.
+ * Copyright 2021 RackTop Systems, Inc.
*/
#ifndef _SMBSRV_SMBINFO_H
@@ -32,6 +32,7 @@
#include <smbsrv/netbios.h>
#include <netinet/in.h>
#include <smbsrv/smb_inet.h>
+#include <smbsrv/smb2.h>
#ifdef __cplusplus
extern "C" {
@@ -237,11 +238,19 @@ const char *smbnative_lm_str(smb_version_t *);
#define SMB_VERS_3_02 0x302 /* "3.02" */
#define SMB_VERS_3_11 0x311 /* "3.11" */
-#define SMB3_HASH_SHA512 1
+/*
+ * Maxiumum currently supported encryption cipher.
+ */
+#define SMB3_CIPHER_MAX SMB3_CIPHER_AES128_GCM
+
+/*
+ * SMB 3.x encryption ciphers bits.
+ */
+#define SMB3_ALL_CIPHERS ((1 << (SMB3_CIPHER_MAX)) - 1)
+#define SMB3_CIPHER_BIT(c) (1 << ((c) - 1))
-#define SMB3_CIPHER_NONE 0
-#define SMB3_CIPHER_AES128_CCM 1
-#define SMB3_CIPHER_AES128_GCM 2
+#define SMB3_CIPHER_FLAG_AES128_CCM SMB3_CIPHER_BIT(SMB3_CIPHER_AES128_CCM)
+#define SMB3_CIPHER_FLAG_AES128_GCM SMB3_CIPHER_BIT(SMB3_CIPHER_AES128_GCM)
#ifdef __cplusplus
}