Print this page
12513 SMB 3.1.1 support for server

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2020 RackTop Systems, Inc.
  */
 
 /*
  * CIFS configuration management library
  */

@@ -148,10 +149,11 @@
         {SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
         {SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0},
         {SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0},
         {SMB_CI_BYPASS_TRAVERSE_CHECKING,
             "bypass_traverse_checking", SCF_TYPE_BOOLEAN, 0},
+        {SMB_CI_ENCRYPT_CIPHER, "encrypt_cipher", SCF_TYPE_ASTRING, 0},
 
         /* SMB_CI_MAX */
 };
 
 /*

@@ -163,18 +165,29 @@
  * except for how we represent "1" (for SMB1) which is an
  * arbitrary value below SMB2_VERS_BASE.
  */
 static struct str_val
 smb_versions[] = {
+        { "3.11",       SMB_VERS_3_11 },
         { "3.02",       SMB_VERS_3_02 },
         { "3.0",        SMB_VERS_3_0 },
         { "2.1",        SMB_VERS_2_1 },
         { "2.002",      SMB_VERS_2_002 },
         { "1",          SMB_VERS_1 },
         { NULL,         0 }
 };
 
+/*
+ * 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 */
+        { NULL,         0 }
+};
+
 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
 
 static boolean_t smb_is_base64(unsigned char c);
 static char *smb_base64_encode(char *str_to_encode);
 static char *smb_base64_decode(char *encoded_str);

@@ -1222,11 +1235,11 @@
  * max_protocol. The expectation is that when those values are empty, we don't
  * constrain the range of supported protocol versions (and allow use of the
  * whole range that we implement). For that reason, this should usually be the
  * highest protocol version we implement.
  */
-uint32_t max_protocol_default = SMB_VERS_3_02;
+uint32_t max_protocol_default = SMB_VERS_3_11;
 
 uint32_t
 smb_config_get_max_protocol(void)
 {
         uint32_t max;

@@ -1261,10 +1274,38 @@
 
         return (-1);
 }
 
 /*
+ * Only SMB 3.x supports encryption.
+ * SMB 3.0.2 uses AES128-CCM only.
+ * SMB 3.1.1 - AES128-CCM or AES128-GCM.
+ */
+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];
+        int i;
+
+        if (max_proto < SMB_VERS_3_11)
+                return (SMB3_CIPHER_NONE);
+
+        /* 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;
+                }
+        }
+
+        return (cipher);
+}
+
+/*
  * If smb2_enable is present and max_protocol is empty,
  * set max_protocol.  Delete smb2_enable.
  */
 static void
 upgrade_smb2_enable()