From 99e5241d36bf5beda675b347b9223a38ff2b5d26 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Aug 2009 17:28:35 +0200 Subject: libcli/auth: add support for AES/HMAC-SHA256 schannel session key support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit metze Signed-off-by: Günther Deschner --- libcli/auth/credentials.c | 66 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'libcli/auth') diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index 81304764a8..dfbfdb356a 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -30,7 +30,17 @@ static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *cre 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 iv[AES_BLOCK_SIZE]; + + AES_set_encrypt_key(creds->session_key, 128, &key); + ZERO_STRUCT(iv); + + aes_cfb8_encrypt(in->data, out->data, 8, &key, iv, AES_ENCRYPT); + } else { + des_crypt112(out->data, in->data, creds->session_key, 1); + } } /* @@ -85,6 +95,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) @@ -227,7 +265,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_128BIT) { + 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); @@ -338,6 +381,10 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me creds->negotiate_flags = negotiate_flags; creds->secure_channel_type = secure_channel_type; + dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); + dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); + dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); + creds->computer_name = talloc_strdup(creds, client_computer_name); if (!creds->computer_name) { talloc_free(creds); @@ -349,7 +396,12 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me return NULL; } - if (negotiate_flags & NETLOGON_NEG_128BIT) { + 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 { @@ -359,6 +411,12 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me netlogon_creds_first_step(creds, client_challenge, server_challenge); + dump_data_pw("Session key", creds->session_key, 16); + dump_data_pw("Client Credential ", creds->client.data, 8); + dump_data_pw("Server Credential ", creds->server.data, 8); + + dump_data_pw("Credentials in", credentials_in->data, sizeof(credentials_in->data)); + /* And before we leak information about the machine account * password, check that they got the first go right */ if (!netlogon_creds_server_check_internal(creds, credentials_in)) { @@ -368,6 +426,8 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me *credentials_out = creds->server; + dump_data_pw("Credentials out", credentials_out->data, sizeof(credentials_out->data)); + return creds; } -- cgit