From patchwork Thu Sep 9 18:13:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 165021 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o89II9f3002945 for ; Thu, 9 Sep 2010 18:18:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753592Ab0IISSI (ORCPT ); Thu, 9 Sep 2010 14:18:08 -0400 Received: from mail-px0-f174.google.com ([209.85.212.174]:45474 "EHLO mail-px0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753199Ab0IISSH (ORCPT ); Thu, 9 Sep 2010 14:18:07 -0400 Received: by mail-px0-f174.google.com with SMTP id 10so618299pxi.19 for ; Thu, 09 Sep 2010 11:18:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=P7c2mLO9F+d1l8hBWX06b99BsdjUZXsQAMIassR3FuA=; b=REanep7DaO3evtnJJc4JZiZHlaz8HI4HMayrlovq0Hvl5uqhqbz5d8acI5QtU3GaLb qPf8i8j/0WPYnF2DPRC6VC8jAg0RQ8BjZyWS0bN16MAV7oeaiD4b7l0p1U01zyx91+HA Fq7eNN45fq+D/jQ0HDCAPNxqyA7lBum8LSTBY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=ts01RTUi0u0YKKP0CmPA7VXOlIZju+QIwnG0vsH0E9NQamuQ871huph50o2YOmoH7B rDtNFQhcqEB0g+LgngGvpRXWpnh4tFvcZFXHoC6tDR/ifBIGfjjWgTVOQjIHDDZilD7G uaveb22Vz5sTwlJL+dRQGMrikv//e4J+nR1nU= Received: by 10.114.66.9 with SMTP id o9mr110098waa.51.1284056286345; Thu, 09 Sep 2010 11:18:06 -0700 (PDT) Received: from localhost ([32.97.110.58]) by mx.google.com with ESMTPS id i6sm1385996iba.14.2010.09.09.11.18.04 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 09 Sep 2010 11:18:05 -0700 (PDT) From: shirishpargaonkar@gmail.com To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, linux-crypto@vger.kernel.org, Shirish Pargaonkar Subject: [PATCH -v2 5/6] convert hash calculations to use crypto apis Date: Thu, 9 Sep 2010 13:13:30 -0500 Message-Id: <1284056010-867-1-git-send-email-shirishpargaonkar@gmail.com> X-Mailer: git-send-email 1.6.0.2 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 09 Sep 2010 18:18:09 +0000 (UTC) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 09d9f74..e72b0e5 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -342,38 +342,52 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, { int rc = 0; int len; - char nt_hash[16]; - struct HMACMD5Context *pctxt; + char nt_hash[CIFS_NTHASH_SIZE]; wchar_t *user; wchar_t *domain; + wchar_t *server; - pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); - - if (pctxt == NULL) - return -ENOMEM; + if (!ses->server->secmech.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + return -1; + } /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash); - /* convert Domainname to unicode and uppercase */ - hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); + crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, + CIFS_NTHASH_SIZE); + + rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); + return rc; + } /* convert ses->userName to unicode and uppercase */ len = strlen(ses->userName); user = kmalloc(2 + (len * 2), GFP_KERNEL); - if (user == NULL) + if (user == NULL) { + cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); + rc = -ENOMEM; goto calc_exit_2; + } len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); UniStrupr(user); - hmac_md5_update((char *)user, 2*len, pctxt); + + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + (char *)user, 2 * len); /* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len = strlen(ses->domainName); domain = kmalloc(2 + (len * 2), GFP_KERNEL); - if (domain == NULL) + if (domain == NULL) { + cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); + rc = -ENOMEM; goto calc_exit_1; + } len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, nls_cp); /* the following line was removed since it didn't work well @@ -381,18 +395,76 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, Maybe converting the domain name earlier makes sense */ /* UniStrupr(domain); */ - hmac_md5_update((char *)domain, 2*len, pctxt); + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + (char *)domain, 2 * len); kfree(domain); + } else if (ses->serverName) { + len = strlen(ses->serverName); + + server = kmalloc(2 + (len * 2), GFP_KERNEL); + if (server == NULL) { + cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); + rc = -ENOMEM; + goto calc_exit_1; + } + len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, + nls_cp); + /* the following line was removed since it didn't work well + with lower cased domain name that passed as an option. + Maybe converting the domain name earlier makes sense */ + /* UniStrupr(domain); */ + + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + (char *)server, 2 * len); + + kfree(server); } + + rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + ses->server->ntlmv2_hash); + calc_exit_1: kfree(user); calc_exit_2: /* BB FIXME what about bytes 24 through 40 of the signing key? compare with the NTLM example */ - hmac_md5_final(ses->server->ntlmv2_hash, pctxt); - kfree(pctxt); + return rc; +} + +static int +CalcNTLMv2_response(const struct cifsSesInfo *ses, char *v2_session_response) +{ + int rc; + + if (!ses->server->secmech.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + return -1; + } + + crypto_shash_setkey(ses->server->secmech.hmacmd5, + ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); + + rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); + return rc; + } + + memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, + ses->server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, + sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); + + if (ses->tilen) + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + ses->tiblob, ses->tilen); + + rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + v2_session_response); + return rc; } @@ -402,7 +474,6 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, { int rc; struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; - struct HMACMD5Context context; buf->blob_signature = cpu_to_le32(0x00000101); buf->reserved = 0; @@ -432,15 +503,35 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, cERROR(1, "could not get v2 hash rc %d", rc); goto setup_ntlmv2_rsp_ret; } - CalcNTLMv2_response(ses, resp_buf); + rc = CalcNTLMv2_response(ses, resp_buf); + if (rc) { + cERROR(1, "could not get v2 hash rc %d", rc); + goto setup_ntlmv2_rsp_ret; + } + + if (!ses->server->secmech.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + rc = -1; + goto setup_ntlmv2_rsp_ret; + } + + crypto_shash_setkey(ses->server->secmech.hmacmd5, + ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); + + rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n"); + goto setup_ntlmv2_rsp_ret; + } + + crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + resp_buf, CIFS_HMAC_MD5_HASH_SIZE); - /* now calculate the MAC key for NTLMv2 */ - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); - hmac_md5_update(resp_buf, 16, &context); - hmac_md5_final(ses->server->session_key.data.ntlmv2.key, &context); + rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + ses->server->session_key.data.ntlmv2.key); memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, - sizeof(struct ntlmv2_resp)); + sizeof(struct ntlmv2_resp)); ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); return 0; @@ -452,25 +543,6 @@ setup_ntlmv2_rsp_ret: return rc; } -void CalcNTLMv2_response(const struct cifsSesInfo *ses, - char *v2_session_response) -{ - struct HMACMD5Context context; - /* rest of v2 struct already generated */ - memcpy(v2_session_response + 8, ses->server->cryptKey, 8); - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); - - hmac_md5_update(v2_session_response+8, - sizeof(struct ntlmv2_resp) - 8, &context); - - if (ses->tilen) - hmac_md5_update(ses->tiblob, - ses->tilen, &context); - - hmac_md5_final(v2_session_response, &context); -/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ -} - int calc_seckey(struct TCP_Server_Info *server) { diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index d89a87a..8fe46f5 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -366,7 +366,6 @@ extern int cifs_verify_signature(struct smb_hdr *, __u32 expected_sequence_number); extern int cifs_calculate_session_key(struct session_key *key, const char *rn, const char *pass); -extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);