From 50dca9ce0f051c863f00cc949db2c19bf247887b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 Aug 2009 10:09:44 +0200 Subject: [PATCH] TODO: libcli/auth: add support for AES/HMAC-SHA256 schannel support metze --- libcli/auth/credentials.c | 75 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index a88f8fc803da..f6054830b9cc 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -24,12 +24,30 @@ #include "system/time.h" #include "../lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" +#include "heimdal/lib/hcrypto/aes.h" static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, const struct netr_Credential *in, struct netr_Credential *out) { - des_crypt112(out->data, in->data, creds->session_key, 1); + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + AES_KEY key; + uint8_t aes_in[AES_BLOCK_SIZE]; + uint8_t aes_out[AES_BLOCK_SIZE]; + + AES_set_encrypt_key(creds->session_key, 128, &key); + + ZERO_STRUCT(aes_in); + memcpy(aes_in, in->data, 8); + AES_encrypt(aes_in, aes_out, &key); + memcpy(out->data, aes_out, 8); + + ZERO_STRUCT(key); + ZERO_STRUCT(aes_in); + ZERO_STRUCT(aes_out); + } else { + des_crypt112(out->data, in->data, creds->session_key, 1); + } } /* @@ -84,6 +102,34 @@ static void netlogon_creds_init_128bit(struct netlogon_creds_CredentialState *cr hmac_md5_final(creds->session_key, &ctx); } +/* + initialise the credentials state for AES/HMAC-SHA256-style 128 bit session keys + + this call is made after the netr_ServerReqChallenge call +*/ +static void netlogon_creds_init_hmac_sha256(struct netlogon_creds_CredentialState *creds, + const struct netr_Credential *client_challenge, + const struct netr_Credential *server_challenge, + const struct samr_Password *machine_password) +{ + struct HMACSHA256Context ctx; + uint8_t digest[SHA256_DIGEST_LENGTH]; + + ZERO_STRUCT(creds->session_key); + + hmac_sha256_init(machine_password->hash, + sizeof(machine_password->hash), + &ctx); + hmac_sha256_update(client_challenge->data, 8, &ctx); + hmac_sha256_update(server_challenge->data, 8, &ctx); + hmac_sha256_final(digest, &ctx); + + memcpy(creds->session_key, digest, sizeof(creds->session_key)); + + ZERO_STRUCT(digest); + ZERO_STRUCT(ctx); +} + static void netlogon_creds_first_step(struct netlogon_creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge) @@ -226,7 +272,12 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); - if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { + if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + netlogon_creds_init_hmac_sha256(creds, + client_challenge, + server_challenge, + machine_password); + } else if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { netlogon_creds_init_128bit(creds, client_challenge, server_challenge, machine_password); } else { netlogon_creds_init_64bit(creds, client_challenge, server_challenge, machine_password); @@ -328,6 +379,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me { struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); bool ok = false; + bool try_aes = true; bool try_strong = true; bool try_weak = true; bool fallback = false; @@ -350,10 +402,28 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me return NULL; } + if (!ok && try_aes) { + if (fallback) { + DEBUG(2,("credentials check fallback to aes key\n")); + } + creds->negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES; + netlogon_creds_init_hmac_sha256(creds, + client_challenge, + server_challenge, + machine_password); + netlogon_creds_first_step(creds, client_challenge, server_challenge); + ok = netlogon_creds_server_check_internal(creds, credentials_in); + if (!ok) { + creds->negotiate_flags &= ~NETLOGON_NEG_SUPPORTS_AES; + fallback = true; + } + } + if (!ok && try_strong) { if (fallback) { DEBUG(2,("credentials check fallback to strong key\n")); } + creds->negotiate_flags &= ~NETLOGON_NEG_SUPPORTS_AES; creds->negotiate_flags |= NETLOGON_NEG_STRONG_KEYS; netlogon_creds_init_128bit(creds, client_challenge, server_challenge, machine_password); @@ -369,6 +439,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me if (fallback) { DEBUG(2,("credentials check fallback to weak key\n")); } + creds->negotiate_flags &= ~NETLOGON_NEG_SUPPORTS_AES; creds->negotiate_flags &= ~NETLOGON_NEG_STRONG_KEYS; netlogon_creds_init_64bit(creds, client_challenge, server_challenge, machine_password); -- 2.34.1