From: Stefan Metzmacher Date: Tue, 10 Nov 2020 00:25:19 +0000 (+0100) Subject: libcli/smb: add aes-256-{gcm,ccm} support to smb2_signing_[en|de]crypt_pdu() X-Git-Tag: samba-4.15.0rc1~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d10153c8514a74b5805ee12d9684a8ca56537d92;p=thirdparty%2Fsamba.git libcli/smb: add aes-256-{gcm,ccm} support to smb2_signing_[en|de]crypt_pdu() Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h index 7d48ad4bb13..576f532999c 100644 --- a/libcli/smb/smb2_constants.h +++ b/libcli/smb/smb2_constants.h @@ -142,11 +142,13 @@ #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 : \ diff --git a/libcli/smb/smb2_negotiate_context.h b/libcli/smb/smb2_negotiate_context.h index aa0eb4097f3..5d0180b0d3b 100644 --- a/libcli/smb/smb2_negotiate_context.h +++ b/libcli/smb/smb2_negotiate_context.h @@ -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]; }; diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c index 07cfa39859f..a372d37e66d 100644 --- a/libcli/smb/smb2_signing.c +++ b/libcli/smb/smb2_signing.c @@ -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; } diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index f428308dc63..cb3a9c28bcf 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -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; diff --git a/libcli/smb/util.c b/libcli/smb/util.c index 79f1bac81b2..e62865a84a8 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -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} };