libcli/smb: add aes-256-{gcm,ccm} support to smb2_signing_[en|de]crypt_pdu()
authorStefan Metzmacher <metze@samba.org>
Tue, 10 Nov 2020 00:25:19 +0000 (01:25 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 15 Jul 2021 00:06:31 +0000 (00:06 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
libcli/smb/smb2_constants.h
libcli/smb/smb2_negotiate_context.h
libcli/smb/smb2_signing.c
libcli/smb/smbXcli_base.c
libcli/smb/util.c

index 7d48ad4bb13cd1a6a64ec8eafce0afacd76fbff1..576f532999c6c8c65536562753acb828bc219862 100644 (file)
 #define SMB2_SIGNING_HMAC_SHA256           0x0000 /* default <= 0x210 */
 #define SMB2_SIGNING_AES128_CMAC           0x0001 /* default >= 0x224 */
 
-/* Values for the SMB2_ENCRYPTION_CAPABILITIES Context (>= 0x310) */
+/* Values for the SMB2_ENCRYPTION_CAPABILITIES Context (>= 0x311) */
 #define SMB2_ENCRYPTION_INVALID_ALGO       0xffff /* only used internally */
 #define SMB2_ENCRYPTION_NONE               0x0000 /* only used internally */
 #define SMB2_ENCRYPTION_AES128_CCM         0x0001 /* only in dialect >= 0x224 */
-#define SMB2_ENCRYPTION_AES128_GCM         0x0002 /* only in dialect >= 0x310 */
+#define SMB2_ENCRYPTION_AES128_GCM         0x0002 /* only in dialect >= 0x311 */
+#define SMB2_ENCRYPTION_AES256_CCM         0x0003 /* only in dialect >= 0x311 */
+#define SMB2_ENCRYPTION_AES256_GCM         0x0004 /* only in dialect >= 0x311 */
 #define SMB2_NONCE_HIGH_MAX(nonce_len_bytes) ((uint64_t)(\
        ((nonce_len_bytes) >= 16) ? UINT64_MAX : \
        ((nonce_len_bytes) <= 8) ? 0 : \
index aa0eb4097f38243b4c76d4a2ef94557791fe9bd2..5d0180b0d3b245e5e4988f65700e9d62858765ec 100644 (file)
@@ -57,7 +57,7 @@ struct smb2_negotiate_context *smb2_negotiate_context_find(const struct smb2_neg
 #define WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK    31
 
 struct smb3_encryption_capabilities {
-#define SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS 2
+#define SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS 4
        uint16_t num_algos;
        uint16_t algos[SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS];
 };
index 07cfa39859f1f7c0f35226c633fe07dd4da765c3..a372d37e66d17fece69131a1c91d171d590aaab8 100644 (file)
@@ -224,6 +224,19 @@ static NTSTATUS smb2_signing_key_create(TALLOC_CTX *mem_ctx,
                }
                in_key_length = out_key_length = 16;
                break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+       case SMB2_ENCRYPTION_AES256_GCM:
+               /*
+                * AES256 uses the available input and
+                * generated a 32 byte encryption key.
+                */
+               if (master_key->length == 0) {
+                       DBG_ERR("cipher_algo_id[%u] without key\n",
+                               cipher_algo_id);
+                       return NT_STATUS_NO_USER_SESSION_KEY;
+               }
+               out_key_length = 32;
+               break;
        default:
                DBG_ERR("cipher_algo_id[%u] not supported\n", cipher_algo_id);
                return NT_STATUS_FWP_INCOMPATIBLE_CIPHER_CONFIG;
@@ -671,6 +684,14 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
                algo = GNUTLS_CIPHER_AES_128_GCM;
                iv_size = gnutls_cipher_get_iv_size(algo);
                break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+               algo = GNUTLS_CIPHER_AES_256_CCM;
+               iv_size = SMB2_AES_128_CCM_NONCE_SIZE;
+               break;
+       case SMB2_ENCRYPTION_AES256_GCM:
+               algo = GNUTLS_CIPHER_AES_256_GCM;
+               iv_size = gnutls_cipher_get_iv_size(algo);
+               break;
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -885,6 +906,14 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key,
                algo = GNUTLS_CIPHER_AES_128_GCM;
                iv_size = gnutls_cipher_get_iv_size(algo);
                break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+               algo = GNUTLS_CIPHER_AES_256_CCM;
+               iv_size = SMB2_AES_128_CCM_NONCE_SIZE;
+               break;
+       case SMB2_ENCRYPTION_AES256_GCM:
+               algo = GNUTLS_CIPHER_AES_256_GCM;
+               iv_size = gnutls_cipher_get_iv_size(algo);
+               break;
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
index f428308dc633d38ef1e70575e1813c6667ca98d7..cb3a9c28bcf05259ad168c0c9e2ad29205dd52ea 100644 (file)
@@ -6281,6 +6281,12 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
        case SMB2_ENCRYPTION_AES128_GCM:
                nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
                break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+               nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
+               break;
+       case SMB2_ENCRYPTION_AES256_GCM:
+               nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
+               break;
        default:
                nonce_size = 0;
                break;
index 79f1bac81b2e667d66417a500888260a206dd50c..e62865a84a8dc83baf884f495301173658e45787 100644 (file)
@@ -468,6 +468,8 @@ enum smb_encryption_setting smb_encryption_setting_translate(const char *str)
 static const struct enum_list enum_smb3_encryption_algorithms[] = {
        {SMB2_ENCRYPTION_AES128_GCM, "aes-128-gcm"},
        {SMB2_ENCRYPTION_AES128_CCM, "aes-128-ccm"},
+       {SMB2_ENCRYPTION_AES256_GCM, "aes-256-gcm"},
+       {SMB2_ENCRYPTION_AES256_CCM, "aes-256-ccm"},
        {-1, NULL}
 };