* [PATCH CIFS] use CryptoAPI MD4/MD5
2003-09-02 20:30 [RFC][PATCH] 2nd try to convert cifs to use CryptoAPI Erlend Aasland
@ 2003-10-01 13:30 ` Erlend Aasland
2003-10-01 19:55 ` Matt Mackall
0 siblings, 1 reply; 12+ messages in thread
From: Erlend Aasland @ 2003-10-01 13:30 UTC (permalink / raw)
To: Linux Kernel Mailing List, Steve French
Cc: Samba Technical Mailing List, James Morris
[-- Attachment #1: Type: text/plain, Size: 1060 bytes --]
Hi,
On 09/02/03 22:30, Erlend Aasland wrote:
> ...
> I've cleaned up my first patch (there were a lot of wrong code in it).
> This patch compiles on i386, but it is not tested yet.
> ...
I've looked over this code once more, modified it a little bit, and now
it not only compiles, _but_ I've also tested mounting against samba-3.0.0.
If this patch looks ok, we can remove the current CIFS implementation of
md4/md5 (I've attached a seperate (booted & tested) patch for this).
Both patches apply clean against linux-2.6.0-test6-bk[23].
Diffstat of the two patches:
add crypto-md[45] patch:
fs/Kconfig | 2
fs/cifs/Makefile | 2
fs/cifs/cifsencrypt.c | 89 ++++++--
fs/cifs/cifsencrypt.h | 18 +
fs/cifs/cifsfs.c | 23 ++
fs/cifs/smbencrypt.c | 148 +++++++++++--
remove old cifs md[45] patch:
fs/cifs/md4.c | 209 -------------------
fs/cifs/md5.c | 363 ---------------------------------
fs/cifs/md5.h | 38 ---
9 files changed, 239 insertions(+), 653 deletions(-)
Regards
Erlend Aasland
[-- Attachment #2: cifs-add-crypto-md5.patch --]
[-- Type: text/plain, Size: 15002 bytes --]
diff -urN linux-2.6.0-test6-bk2/fs/Kconfig linux-2.6.0-test6-bk2-dirty/fs/Kconfig
--- linux-2.6.0-test6-bk2/fs/Kconfig Tue Sep 30 15:59:09 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/Kconfig Wed Oct 1 14:57:08 2003
@@ -1470,6 +1470,8 @@
config CIFS
tristate "CIFS support (advanced network filesystem for Samba, Window and other CIFS compliant servers)(EXPERIMENTAL)"
depends on INET
+ select CRYPTO_MD4
+ select CRYPTO_MD5
help
This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block
diff -urN linux-2.6.0-test6-bk2/fs/cifs/cifsencrypt.c linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsencrypt.c
--- linux-2.6.0-test6-bk2/fs/cifs/cifsencrypt.c Sun Sep 28 02:50:30 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsencrypt.c Wed Oct 1 10:35:24 2003
@@ -20,32 +20,45 @@
*/
#include <linux/fs.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#include "cifsencrypt.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
-#include "md5.h"
#include "cifs_unicode.h"
+struct crypto_tfm *md5_tfm;
+struct crypto_tfm *md4_tfm;
+spinlock_t md5_tfm_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t md4_tfm_lock = SPIN_LOCK_UNLOCKED;
+
/* Calculate and return the CIFS signature based on the mac key and the smb pdu */
/* the 16 byte signature must be allocated by the caller */
/* Note we only use the 1st eight bytes */
/* Note that the smb header signature field on input contains the
sequence number before this function is called */
-extern void mdfour(unsigned char *out, unsigned char *in, int n);
-extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-
static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
{
- struct MD5Context context;
+ struct scatterlist sg[2];
if((cifs_pdu == NULL) || (signature == NULL))
return -EINVAL;
- MD5Init(&context);
- MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
- MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
- MD5Final(signature,&context);
+ sg[0].page = virt_to_page(key);
+ sg[0].offset = offset_in_page(key);
+ sg[0].length = CIFS_SESSION_KEY_SIZE+16;
+ sg[1].page = virt_to_page(cifs_pdu->Protocol);
+ sg[1].offset = offset_in_page(cifs_pdu->Protocol);
+ sg[1].length = cifs_pdu->smb_buf_length;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 2);
+ crypto_digest_final(md5_tfm, signature);
+ spin_unlock(&md5_tfm_lock);
+
return 0;
}
@@ -136,29 +149,42 @@
int cifs_calculate_mac_key(char * key, const char * rn, const char * password)
{
char temp_key[16];
+ struct scatterlist sg;
+
if ((key == NULL) || (rn == NULL) || (password == NULL))
return -EINVAL;
+ sg.page = virt_to_page(temp_key);
+ sg.offset = offset_in_page(temp_key);
+ sg.length = 16;
+
E_md4hash(password, temp_key);
- mdfour(key,temp_key,16);
+
+ spin_lock(&md4_tfm_lock);
+ crypto_digest_init(md4_tfm);
+ crypto_digest_update(md4_tfm, &sg, 1);
+ crypto_digest_final(md4_tfm, key);
+ spin_unlock(&md4_tfm_lock);
memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE);
+
return 0;
}
int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_info)
{
char temp_hash[16];
- struct HMACMD5Context ctx;
char * ucase_buf;
wchar_t * unicode_buf;
unsigned int i,user_name_len,dom_name_len;
+ u8 ipad[65], opad[65];
+ struct scatterlist sg[2];
if(ses)
return -EINVAL;
E_md4hash(ses->password_with_pad, temp_hash);
- hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
+ SMBencrypt_prepare_keypads(ipad, opad, temp_hash, 16);
user_name_len = strlen(ses->userName);
if(user_name_len > MAX_USERNAME_SIZE)
return -EINVAL;
@@ -183,24 +209,49 @@
dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
unicode_buf[user_name_len + dom_name_len] = 0;
- hmac_md5_update((const unsigned char *) unicode_buf,
- (user_name_len+dom_name_len)*2,&ctx);
- hmac_md5_final(ses->mac_signing_key,&ctx);
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(unicode_buf);
+ sg[1].offset = offset_in_page(unicode_buf);
+ sg[1].length = (user_name_len+dom_name_len)*2;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 2);
+ crypto_digest_final(md5_tfm, ses->mac_signing_key);
+ spin_unlock(&md5_tfm_lock);
+
+ SMBencrypt_update_with_opad(opad, ses->mac_signing_key);
+
kfree(ucase_buf);
kfree(unicode_buf);
return 0;
}
void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response)
{
- struct HMACMD5Context context;
+ u8 ipad[65], opad[65];
+ struct scatterlist sg[2];
+
memcpy(v2_session_response + 8, ses->server->cryptKey,8);
/* gen_blob(v2_session_response + 16); */
- hmac_md5_init_limK_to_64(ses->mac_signing_key, 16, &context);
- hmac_md5_update(ses->server->cryptKey,8,&context);
+ SMBencrypt_prepare_keypads(ipad, opad, ses->mac_signing_key, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(ses->server->cryptKey);
+ sg[1].offset = offset_in_page(ses->server->cryptKey);
+ sg[1].length = 8;
/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 2);
+ crypto_digest_final(md5_tfm, v2_session_response);
+ spin_unlock(&md5_tfm_lock);
- hmac_md5_final(v2_session_response,&context);
+ SMBencrypt_update_with_opad(opad, v2_session_response);
}
diff -urN linux-2.6.0-test6-bk2/fs/cifs/cifsencrypt.h linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsencrypt.h
--- linux-2.6.0-test6-bk2/fs/cifs/cifsencrypt.h Thu Jan 1 01:00:00 1970
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsencrypt.h Wed Oct 1 10:35:24 2003
@@ -0,0 +1,18 @@
+#ifndef CIFSENCRYPT_H
+#define CIFSENCRYPT_H
+
+#include <linux/crypto.h>
+#include <linux/spinlock.h>
+#include <asm/types.h>
+
+extern struct crypto_tfm *md5_tfm;
+extern struct crypto_tfm *md4_tfm;
+extern spinlock_t md5_tfm_lock;
+extern spinlock_t md4_tfm_lock;
+
+void E_md4hash(const unsigned char *passwd, unsigned char *p16);
+
+extern void SMBencrypt_prepare_keypads(u8 *ipad, u8 *opad, const u8 *key, int len);
+extern void SMBencrypt_update_with_opad(u8 *pad, u8 *digest);
+
+#endif
diff -urN linux-2.6.0-test6-bk2/fs/cifs/cifsfs.c linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsfs.c
--- linux-2.6.0-test6-bk2/fs/cifs/cifsfs.c Sun Sep 28 02:50:25 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/cifsfs.c Wed Oct 1 10:35:24 2003
@@ -31,6 +31,8 @@
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/vfs.h>
+#include <linux/crypto.h>
+#include "cifsencrypt.h"
#include "cifsfs.h"
#include "cifspdu.h"
#define DECLARE_GLOBALS_HERE
@@ -644,6 +646,18 @@
rc = cifs_init_inodecache();
if (!rc) {
+ md5_tfm = crypto_alloc_tfm("md5", 0);
+ if (unlikely(md5_tfm == NULL)) {
+ printk(KERN_ERR "failed to load transform for md5\n");
+ rc = 0;
+ }
+ md4_tfm = crypto_alloc_tfm("md4", 0);
+ if (unlikely(md4_tfm == NULL)) {
+ printk(KERN_ERR "failed to load transform for md4\n");
+ rc = 0;
+ }
+ }
+ if (!rc) {
rc = cifs_init_mids();
if (!rc) {
rc = cifs_init_request_bufs();
@@ -660,6 +674,7 @@
}
cifs_destroy_inodecache();
}
+
#ifdef CONFIG_PROC_FS
cifs_proc_clean();
#endif
@@ -680,6 +695,14 @@
if(oplockThread) {
send_sig(SIGTERM, oplockThread, 1);
wait_for_completion(&cifs_oplock_exited);
+ }
+ if (likely(md5_tfm != NULL)) {
+ crypto_free_tfm(md5_tfm);
+ md5_tfm = NULL;
+ }
+ if (likely(md4_tfm != NULL)) {
+ crypto_free_tfm(md4_tfm);
+ md4_tfm = NULL;
}
}
diff -urN linux-2.6.0-test6-bk2/fs/cifs/smbencrypt.c linux-2.6.0-test6-bk2-dirty/fs/cifs/smbencrypt.c
--- linux-2.6.0-test6-bk2/fs/cifs/smbencrypt.c Sun Sep 28 02:50:20 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/smbencrypt.c Wed Oct 1 10:35:24 2003
@@ -30,10 +30,12 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/random.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
#include "cifs_unicode.h"
#include "cifspdu.h"
-#include "md5.h"
#include "cifs_debug.h"
+#include "cifsencrypt.h"
#ifndef FALSE
#define FALSE 0
@@ -49,10 +51,6 @@
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((__u32)(val)))
-/*The following definitions come from lib/md4.c */
-
-void mdfour(unsigned char *out, unsigned char *in, int n);
-
/*The following definitions come from libsmb/smbdes.c */
void E_P16(unsigned char *p14, unsigned char *p16);
@@ -68,7 +66,6 @@
/*The following definitions come from libsmb/smbencrypt.c */
void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
-void E_md4hash(const unsigned char *passwd, unsigned char *p16);
void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
unsigned char p24[24]);
@@ -109,6 +106,46 @@
memset(p21,0,21);
}
+void
+SMBencrypt_prepare_keypads(u8 *ipad, u8 *opad, const u8 *key, int len)
+{
+ int i;
+
+ /* if key is longer than 64 bytes, truncate it */
+ len &= 0x3f;
+
+ /* start out by storing key in pads */
+ memset(ipad, 0, 64);
+ memset(opad, 0, 64);
+ memcpy(ipad, key, len);
+ memcpy(opad, key, len);
+
+ /* XOR key with ipad and opad values */
+ for (i = 0; i < 64; i++) {
+ ipad[i] ^= 0x36;
+ opad[i] ^= 0x5c;
+ }
+}
+
+void
+SMBencrypt_update_with_opad(u8 *pad, u8 *digest)
+{
+ struct scatterlist sg[2];
+
+ sg[0].page = virt_to_page(pad);
+ sg[0].offset = offset_in_page(pad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(digest);
+ sg[1].offset = offset_in_page(digest);
+ sg[1].length = 16;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 2);
+ crypto_digest_final(md5_tfm, digest);
+ spin_unlock(&md5_tfm_lock);
+}
+
/* Routines for Windows NT MD4 Hash functions. */
static int
_my_wcslen(__u16 * str)
@@ -152,6 +189,7 @@
{
int len;
__u16 wpwd[129];
+ struct scatterlist sg;
/* Password cannot be longer than 128 characters */
len = strlen((char *) passwd);
@@ -163,7 +201,15 @@
/* Calculate length in bytes */
len = _my_wcslen(wpwd) * sizeof (__u16);
- mdfour(p16, (unsigned char *) wpwd, len);
+ sg.page = virt_to_page(wpwd);
+ sg.offset = offset_in_page(wpwd);
+ sg.length = len;
+
+ spin_lock(&md4_tfm_lock);
+ crypto_digest_init(md4_tfm);
+ crypto_digest_update(md4_tfm, &sg, 1);
+ crypto_digest_final(md4_tfm, p16);
+ spin_unlock(&md4_tfm_lock);
memset(wpwd,0,129 * 2);
}
@@ -212,17 +258,18 @@
const char *domain_n, unsigned char kr_buf[16],
const struct nls_table *nls_codepage)
{
+ struct scatterlist sg[3];
wchar_t * user_u;
wchar_t * dom_u;
int user_l, domain_l;
- struct HMACMD5Context ctx;
+ u8 ipad[65], opad[65];
/* might as well do one alloc to hold both (user_u and dom_u) */
user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL);
if(user_u == NULL)
return;
dom_u = user_u + 1024;
-
+
/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
@@ -233,10 +280,25 @@
user_l++; /* trailing null */
domain_l++;
- hmac_md5_init_limK_to_64(owf, 16, &ctx);
- hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
- hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
- hmac_md5_final(kr_buf, &ctx);
+ SMBencrypt_prepare_keypads(ipad, opad, owf, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(user_u);
+ sg[1].offset = offset_in_page(user_u);
+ sg[1].length = user_l;
+ sg[2].page = virt_to_page(dom_u);
+ sg[2].offset = offset_in_page(dom_u);
+ sg[2].length = domain_l;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 3);
+ crypto_digest_final(md5_tfm, kr_buf);
+ spin_unlock(&md5_tfm_lock);
+
+ SMBencrypt_update_with_opad(opad, kr_buf);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
@@ -307,12 +369,28 @@
const struct data_blob * srv_chal,
const struct data_blob * cli_chal, unsigned char resp_buf[16])
{
- struct HMACMD5Context ctx;
+ struct scatterlist sg[3];
+ u8 ipad[65], opad[65];
+
+ SMBencrypt_prepare_keypads(ipad, opad, kr, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(srv_chal->data);
+ sg[1].offset = offset_in_page(srv_chal->data);
+ sg[1].length = srv_chal->length;
+ sg[2].page = virt_to_page(cli_chal->data);
+ sg[2].offset = offset_in_page(cli_chal->data);
+ sg[2].length = cli_chal->length;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 3);
+ crypto_digest_final(md5_tfm, resp_buf);
+ spin_unlock(&md5_tfm_lock);
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
- hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
- hmac_md5_final(resp_buf, &ctx);
+ SMBencrypt_update_with_opad(opad, resp_buf);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
@@ -390,11 +468,25 @@
SMBsesskeygen_ntv2(const unsigned char kr[16],
const unsigned char *nt_resp, __u8 sess_key[16])
{
- struct HMACMD5Context ctx;
+ struct scatterlist sg[2];
+ u8 ipad[65], opad[65];
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(nt_resp, 16, &ctx);
- hmac_md5_final((unsigned char *) sess_key, &ctx);
+ SMBencrypt_prepare_keypads(ipad, opad, kr, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(nt_resp);
+ sg[1].offset = offset_in_page(nt_resp);
+ sg[1].length = 16;
+
+ spin_lock(&md5_tfm_lock);
+ crypto_digest_init(md5_tfm);
+ crypto_digest_update(md5_tfm, sg, 2);
+ crypto_digest_final(md5_tfm, sess_key);
+ spin_unlock(&md5_tfm_lock);
+
+ SMBencrypt_update_with_opad(opad, sess_key);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
@@ -406,7 +498,17 @@
SMBsesskeygen_ntv1(const unsigned char kr[16],
const unsigned char *nt_resp, __u8 sess_key[16])
{
- mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
+ struct scatterlist sg;
+
+ sg.page = virt_to_page(kr);
+ sg.offset = offset_in_page(kr);
+ sg.length = 16;
+
+ spin_lock(&md4_tfm_lock);
+ crypto_digest_init(md4_tfm);
+ crypto_digest_update(md4_tfm, &sg, 1);
+ crypto_digest_final(md4_tfm, sess_key);
+ spin_unlock(&md4_tfm_lock);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
[-- Attachment #3: cifs-remove-old-md5.patch --]
[-- Type: text/plain, Size: 18405 bytes --]
diff -urN linux-2.6.0-test6-bk2/fs/cifs/Makefile linux-2.6.0-test6-bk2-dirty/fs/cifs/Makefile
--- linux-2.6.0-test6-bk2/fs/cifs/Makefile Sun Sep 28 02:50:13 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/Makefile Wed Oct 1 10:29:55 2003
@@ -3,4 +3,4 @@
#
obj-$(CONFIG_CIFS) += cifs.o
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o
+cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o
diff -urN linux-2.6.0-test6-bk2/fs/cifs/md4.c linux-2.6.0-test6-bk2-dirty/fs/cifs/md4.c
--- linux-2.6.0-test6-bk2/fs/cifs/md4.c Sun Sep 28 02:50:38 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/md4.c Thu Jan 1 01:00:00 1970
@@ -1,209 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- a implementation of MD4 designed for use in the SMB authentication protocol
- Copyright (C) Andrew Tridgell 1997-1998.
- Modified by Steve French (sfrench@us.ibm.com) 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-#include <linux/module.h>
-#include <linux/fs.h>
-
-/* NOTE: This code makes no attempt to be fast!
-
- It assumes that a int is at least 32 bits long
-*/
-
-static __u32 A, B, C, D;
-
-static __u32
-F(__u32 X, __u32 Y, __u32 Z)
-{
- return (X & Y) | ((~X) & Z);
-}
-
-static __u32
-G(__u32 X, __u32 Y, __u32 Z)
-{
- return (X & Y) | (X & Z) | (Y & Z);
-}
-
-static __u32
-H(__u32 X, __u32 Y, __u32 Z)
-{
- return X ^ Y ^ Z;
-}
-
-static __u32
-lshift(__u32 x, int s)
-{
- x &= 0xFFFFFFFF;
- return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
-}
-
-#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
-#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (__u32)0x5A827999,s)
-#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (__u32)0x6ED9EBA1,s)
-
-/* this applies md4 to 64 byte chunks */
-static void
-mdfour64(__u32 * M)
-{
- int j;
- __u32 AA, BB, CC, DD;
- __u32 X[16];
-
- for (j = 0; j < 16; j++)
- X[j] = M[j];
-
- AA = A;
- BB = B;
- CC = C;
- DD = D;
-
- ROUND1(A, B, C, D, 0, 3);
- ROUND1(D, A, B, C, 1, 7);
- ROUND1(C, D, A, B, 2, 11);
- ROUND1(B, C, D, A, 3, 19);
- ROUND1(A, B, C, D, 4, 3);
- ROUND1(D, A, B, C, 5, 7);
- ROUND1(C, D, A, B, 6, 11);
- ROUND1(B, C, D, A, 7, 19);
- ROUND1(A, B, C, D, 8, 3);
- ROUND1(D, A, B, C, 9, 7);
- ROUND1(C, D, A, B, 10, 11);
- ROUND1(B, C, D, A, 11, 19);
- ROUND1(A, B, C, D, 12, 3);
- ROUND1(D, A, B, C, 13, 7);
- ROUND1(C, D, A, B, 14, 11);
- ROUND1(B, C, D, A, 15, 19);
-
- ROUND2(A, B, C, D, 0, 3);
- ROUND2(D, A, B, C, 4, 5);
- ROUND2(C, D, A, B, 8, 9);
- ROUND2(B, C, D, A, 12, 13);
- ROUND2(A, B, C, D, 1, 3);
- ROUND2(D, A, B, C, 5, 5);
- ROUND2(C, D, A, B, 9, 9);
- ROUND2(B, C, D, A, 13, 13);
- ROUND2(A, B, C, D, 2, 3);
- ROUND2(D, A, B, C, 6, 5);
- ROUND2(C, D, A, B, 10, 9);
- ROUND2(B, C, D, A, 14, 13);
- ROUND2(A, B, C, D, 3, 3);
- ROUND2(D, A, B, C, 7, 5);
- ROUND2(C, D, A, B, 11, 9);
- ROUND2(B, C, D, A, 15, 13);
-
- ROUND3(A, B, C, D, 0, 3);
- ROUND3(D, A, B, C, 8, 9);
- ROUND3(C, D, A, B, 4, 11);
- ROUND3(B, C, D, A, 12, 15);
- ROUND3(A, B, C, D, 2, 3);
- ROUND3(D, A, B, C, 10, 9);
- ROUND3(C, D, A, B, 6, 11);
- ROUND3(B, C, D, A, 14, 15);
- ROUND3(A, B, C, D, 1, 3);
- ROUND3(D, A, B, C, 9, 9);
- ROUND3(C, D, A, B, 5, 11);
- ROUND3(B, C, D, A, 13, 15);
- ROUND3(A, B, C, D, 3, 3);
- ROUND3(D, A, B, C, 11, 9);
- ROUND3(C, D, A, B, 7, 11);
- ROUND3(B, C, D, A, 15, 15);
-
- A += AA;
- B += BB;
- C += CC;
- D += DD;
-
- A &= 0xFFFFFFFF;
- B &= 0xFFFFFFFF;
- C &= 0xFFFFFFFF;
- D &= 0xFFFFFFFF;
-
- for (j = 0; j < 16; j++)
- X[j] = 0;
-}
-
-static void
-copy64(__u32 * M, unsigned char *in)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
- (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
-}
-
-static void
-copy4(unsigned char *out, __u32 x)
-{
- out[0] = x & 0xFF;
- out[1] = (x >> 8) & 0xFF;
- out[2] = (x >> 16) & 0xFF;
- out[3] = (x >> 24) & 0xFF;
-}
-
-/* produce a md4 message digest from data of length n bytes */
-void
-mdfour(unsigned char *out, unsigned char *in, int n)
-{
- unsigned char buf[128];
- __u32 M[16];
- __u32 b = n * 8;
- int i;
-
- A = 0x67452301;
- B = 0xefcdab89;
- C = 0x98badcfe;
- D = 0x10325476;
-
- while (n > 64) {
- copy64(M, in);
- mdfour64(M);
- in += 64;
- n -= 64;
- }
-
- for (i = 0; i < 128; i++)
- buf[i] = 0;
- memcpy(buf, in, n);
- buf[n] = 0x80;
-
- if (n <= 55) {
- copy4(buf + 56, b);
- copy64(M, buf);
- mdfour64(M);
- } else {
- copy4(buf + 120, b);
- copy64(M, buf);
- mdfour64(M);
- copy64(M, buf + 64);
- mdfour64(M);
- }
-
- for (i = 0; i < 128; i++)
- buf[i] = 0;
- copy64(M, buf);
-
- copy4(out, A);
- copy4(out + 4, B);
- copy4(out + 8, C);
- copy4(out + 12, D);
-
- A = B = C = D = 0;
-}
diff -urN linux-2.6.0-test6-bk2/fs/cifs/md5.c linux-2.6.0-test6-bk2-dirty/fs/cifs/md5.c
--- linux-2.6.0-test6-bk2/fs/cifs/md5.c Sun Sep 28 02:50:31 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/md5.c Thu Jan 1 01:00:00 1970
@@ -1,363 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-/* This code slightly modified to fit into Samba by
- abartlet@samba.org Jun 2001
- and to fit the cifs vfs by
- Steve French sfrench@us.ibm.com */
-
-#include <linux/string.h>
-#include "md5.h"
-
-static void MD5Transform(__u32 buf[4], __u32 const in[16]);
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void
-byteReverse(unsigned char *buf, unsigned longs)
-{
- __u32 t;
- do {
- t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(__u32 *) buf = t;
- buf += 4;
- } while (--longs);
-}
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-MD5Init(struct MD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
- register __u32 t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memmove(p, buf, len);
- return;
- }
- memmove(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (__u32 *) ctx->in);
- buf += t;
- len -= t;
- }
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memmove(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (__u32 *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memmove(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
- unsigned int count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (__u32 *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((__u32 *) ctx->in)[14] = ctx->bits[0];
- ((__u32 *) ctx->in)[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (__u32 *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memmove(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
-}
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void
-MD5Transform(__u32 buf[4], __u32 const in[16])
-{
- register __u32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-/***********************************************************************
- the rfc 2104 version of hmac_md5 initialisation.
-***********************************************************************/
-void
-hmac_md5_init_rfc2104(unsigned char *key, int key_len,
- struct HMACMD5Context *ctx)
-{
- int i;
-
- /* if key is longer than 64 bytes reset it to key=MD5(key) */
- if (key_len > 64) {
- unsigned char tk[16];
- struct MD5Context tctx;
-
- MD5Init(&tctx);
- MD5Update(&tctx, key, key_len);
- MD5Final(tk, &tctx);
-
- key = tk;
- key_len = 16;
- }
-
- /* start out by storing key in pads */
- memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
- memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
- memcpy(ctx->k_ipad, key, key_len);
- memcpy(ctx->k_opad, key, key_len);
-
- /* XOR key with ipad and opad values */
- for (i = 0; i < 64; i++) {
- ctx->k_ipad[i] ^= 0x36;
- ctx->k_opad[i] ^= 0x5c;
- }
-
- MD5Init(&ctx->ctx);
- MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-}
-
-/***********************************************************************
- the microsoft version of hmac_md5 initialisation.
-***********************************************************************/
-void
-hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
- struct HMACMD5Context *ctx)
-{
- int i;
-
- /* if key is longer than 64 bytes truncate it */
- if (key_len > 64) {
- key_len = 64;
- }
-
- /* start out by storing key in pads */
- memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
- memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
- memcpy(ctx->k_ipad, key, key_len);
- memcpy(ctx->k_opad, key, key_len);
-
- /* XOR key with ipad and opad values */
- for (i = 0; i < 64; i++) {
- ctx->k_ipad[i] ^= 0x36;
- ctx->k_opad[i] ^= 0x5c;
- }
-
- MD5Init(&ctx->ctx);
- MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-}
-
-/***********************************************************************
- update hmac_md5 "inner" buffer
-***********************************************************************/
-void
-hmac_md5_update(const unsigned char *text, int text_len,
- struct HMACMD5Context *ctx)
-{
- MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */
-}
-
-/***********************************************************************
- finish off hmac_md5 "inner" buffer and generate outer one.
-***********************************************************************/
-void
-hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
-{
- struct MD5Context ctx_o;
-
- MD5Final(digest, &ctx->ctx);
-
- MD5Init(&ctx_o);
- MD5Update(&ctx_o, ctx->k_opad, 64);
- MD5Update(&ctx_o, digest, 16);
- MD5Final(digest, &ctx_o);
-}
-
-/***********************************************************
- single function to calculate an HMAC MD5 digest from data.
- use the microsoft hmacmd5 init method because the key is 16 bytes.
-************************************************************/
-void
-hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
- unsigned char *digest)
-{
- struct HMACMD5Context ctx;
- hmac_md5_init_limK_to_64(key, 16, &ctx);
- if (data_len != 0) {
- hmac_md5_update(data, data_len, &ctx);
- }
- hmac_md5_final(digest, &ctx);
-}
diff -urN linux-2.6.0-test6-bk2/fs/cifs/md5.h linux-2.6.0-test6-bk2-dirty/fs/cifs/md5.h
--- linux-2.6.0-test6-bk2/fs/cifs/md5.h Sun Sep 28 02:50:06 2003
+++ linux-2.6.0-test6-bk2-dirty/fs/cifs/md5.h Thu Jan 1 01:00:00 1970
@@ -1,38 +0,0 @@
-#ifndef MD5_H
-#define MD5_H
-#ifndef HEADER_MD5_H
-/* Try to avoid clashes with OpenSSL */
-#define HEADER_MD5_H
-#endif
-
-struct MD5Context {
- __u32 buf[4];
- __u32 bits[2];
- unsigned char in[64];
-};
-#endif /* !MD5_H */
-
-#ifndef _HMAC_MD5_H
-struct HMACMD5Context {
- struct MD5Context ctx;
- unsigned char k_ipad[65];
- unsigned char k_opad[65];
-};
-#endif /* _HMAC_MD5_H */
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, unsigned char const *buf,
- unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-
-/* The following definitions come from lib/hmacmd5.c */
-
-void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
- struct HMACMD5Context *ctx);
-void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
- struct HMACMD5Context *ctx);
-void hmac_md5_update(const unsigned char *text, int text_len,
- struct HMACMD5Context *ctx);
-void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
-void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
- unsigned char *digest);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-01 13:30 ` [PATCH CIFS] use CryptoAPI MD4/MD5 Erlend Aasland
@ 2003-10-01 19:55 ` Matt Mackall
2003-10-01 23:26 ` Erlend Aasland
0 siblings, 1 reply; 12+ messages in thread
From: Matt Mackall @ 2003-10-01 19:55 UTC (permalink / raw)
To: Erlend Aasland
Cc: Linux Kernel Mailing List, Steve French,
Samba Technical Mailing List, James Morris
On Wed, Oct 01, 2003 at 03:30:39PM +0200, Erlend Aasland wrote:
> static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
[...]
> + spin_lock(&md5_tfm_lock);
> + crypto_digest_init(md5_tfm);
> + crypto_digest_update(md5_tfm, sg, 2);
> + crypto_digest_final(md5_tfm, signature);
> + spin_unlock(&md5_tfm_lock);
Eek. How often does this get called? We're now up to three instances
of CryptoAPI conversion (/dev/random, cryptoloop, and cifs) that want
tfms-on-the-stack but instead use extra locking.
--
Matt Mackall : http://www.selenic.com : of or relating to the moon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-01 19:55 ` Matt Mackall
@ 2003-10-01 23:26 ` Erlend Aasland
2003-10-01 23:42 ` Matt Mackall
0 siblings, 1 reply; 12+ messages in thread
From: Erlend Aasland @ 2003-10-01 23:26 UTC (permalink / raw)
To: Matt Mackall
Cc: Steve French, Linux Kernel Mailing List,
Samba Technical Mailing List, James Morris
On 10/01/03 14:55, Matt Mackall wrote:
> On Wed, Oct 01, 2003 at 03:30:39PM +0200, Erlend Aasland wrote:
> > static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
> [...]
> Eek. How often does this get called?
It is (normally) called twice in SendReceive(). SendReceive() is called
very often in cifs. After a quick look at cifs, it seems that most of
these calls are protected with a per connection-lock (correct me if I'm
wrong). But since two connections can call SendReceive() at the same
time, we have to protect the tfm with locks. Correct?
Would a better solution be to allocate one tfm per connection, thus
no need to protect the tfm with a dedicated lock, right?
[Or is converting cifs to the cryptoapi is waste of time? (I hope not :-) ]
Regards
Erlend Aasland
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-01 23:26 ` Erlend Aasland
@ 2003-10-01 23:42 ` Matt Mackall
2003-10-01 23:52 ` Erlend Aasland
0 siblings, 1 reply; 12+ messages in thread
From: Matt Mackall @ 2003-10-01 23:42 UTC (permalink / raw)
To: Erlend Aasland
Cc: Steve French, Linux Kernel Mailing List,
Samba Technical Mailing List, James Morris
On Thu, Oct 02, 2003 at 01:26:50AM +0200, Erlend Aasland wrote:
> On 10/01/03 14:55, Matt Mackall wrote:
> > On Wed, Oct 01, 2003 at 03:30:39PM +0200, Erlend Aasland wrote:
> > > static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
> > [...]
> > Eek. How often does this get called?
> It is (normally) called twice in SendReceive(). SendReceive() is called
> very often in cifs. After a quick look at cifs, it seems that most of
> these calls are protected with a per connection-lock (correct me if I'm
> wrong). But since two connections can call SendReceive() at the same
> time, we have to protect the tfm with locks. Correct?
Correct. But this lock is going to be a huge bottleneck.
> Would a better solution be to allocate one tfm per connection, thus
> no need to protect the tfm with a dedicated lock, right?
Per connection sounds like a much better answer, assuming you can
guarantee that SendReceive() never gets called simultaneously on the
same connection.
> [Or is converting cifs to the cryptoapi is waste of time? (I hope not :-) ]
No, it's generally a good idea, but the allocation of tfms means that
conversion isn't necessarily straightforward.
--
Matt Mackall : http://www.selenic.com : of or relating to the moon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-01 23:42 ` Matt Mackall
@ 2003-10-01 23:52 ` Erlend Aasland
0 siblings, 0 replies; 12+ messages in thread
From: Erlend Aasland @ 2003-10-01 23:52 UTC (permalink / raw)
To: Matt Mackall
Cc: Steve French, Linux Kernel Mailing List,
Samba Technical Mailing List, James Morris
Hi Matt,
Thanks for your replies and suggestions.
On 10/01/03 18:42, Matt Mackall wrote:
> On Thu, Oct 02, 2003 at 01:26:50AM +0200, Erlend Aasland wrote:
> > On 10/01/03 14:55, Matt Mackall wrote:
> > > On Wed, Oct 01, 2003 at 03:30:39PM +0200, Erlend Aasland wrote:
> > > > static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
> > > [...]
> > > Eek. How often does this get called?
> > It is (normally) called twice in SendReceive(). SendReceive() is called
> > very often in cifs. After a quick look at cifs, it seems that most of
> > these calls are protected with a per connection-lock (correct me if I'm
> > wrong). But since two connections can call SendReceive() at the same
> > time, we have to protect the tfm with locks. Correct?
> Correct. But this lock is going to be a huge bottleneck.
Yes, I should have thought about this in the first place :-)
> > Would a better solution be to allocate one tfm per connection, thus
> > no need to protect the tfm with a dedicated lock, right?
> Per connection sounds like a much better answer, assuming you can
> guarantee that SendReceive() never gets called simultaneously on the
> same connection.
I will do this and try to trace each SendReceive() call, verifying
that this is a safe solution.
Regards
Erlend Aasland
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
[not found] <OF9C1504BB.5FB00D5A-ON87256DB3.0015672E-86256DB3.001798AE@us.ibm.com>
@ 2003-10-02 11:37 ` Erlend Aasland
2003-10-04 18:00 ` dean gaudet
0 siblings, 1 reply; 12+ messages in thread
From: Erlend Aasland @ 2003-10-02 11:37 UTC (permalink / raw)
To: Steven French
Cc: James Morris, Matt Mackall, Samba Technical Mailing List,
Linux Kernel Mailing List
[-- Attachment #1: Type: text/plain, Size: 594 bytes --]
Hello,
Thanks for your reply
On 10/01/03 23:17, Steven French wrote:
> Lots of locks to choose among - per tcp session or per smb session e.g.
Ok, the attached patch allocates tfms per session. There are more
than 30 calls to SendReceive() in cifssmb.c, and almost none of them are
protected by connection/session-semaphores, so I think the right thing
would be to use the session-semaphores: put down()/up() around
SendReceive(), correct?
Patch is against test6-bk3, it compiles and is tested
(mounting and ls'ing) with /proc/fs/cifs/{PacketSigning,NTLMv2}Enable
set to 1.
Regards
Erlend
[-- Attachment #2: cifs-add-crypto-md5.patch --]
[-- Type: text/plain, Size: 24939 bytes --]
diff -urN linux-2.6.0-test6-bk3/fs/Kconfig linux-2.6.0-test6-bk3-dirty/fs/Kconfig
--- linux-2.6.0-test6-bk3/fs/Kconfig Tue Sep 30 15:59:09 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/Kconfig Wed Oct 1 15:14:00 2003
@@ -1470,6 +1470,8 @@
config CIFS
tristate "CIFS support (advanced network filesystem for Samba, Window and other CIFS compliant servers)(EXPERIMENTAL)"
depends on INET
+ select CRYPTO_MD4
+ select CRYPTO_MD5
help
This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block
diff -urN linux-2.6.0-test6-bk3/fs/cifs/cifsencrypt.c linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsencrypt.c
--- linux-2.6.0-test6-bk3/fs/cifs/cifsencrypt.c Sun Sep 28 02:50:30 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsencrypt.c Thu Oct 2 11:45:15 2003
@@ -20,10 +20,10 @@
*/
#include <linux/fs.h>
+#include "cifsencrypt.h"
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
-#include "md5.h"
#include "cifs_unicode.h"
/* Calculate and return the CIFS signature based on the mac key and the smb pdu */
@@ -32,20 +32,23 @@
/* Note that the smb header signature field on input contains the
sequence number before this function is called */
-extern void mdfour(unsigned char *out, unsigned char *in, int n);
-extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-
-static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
+static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, struct crypto_tfm *md5_tfm,
+ const char * key, char * signature)
{
- struct MD5Context context;
+ struct scatterlist sg[2];
if((cifs_pdu == NULL) || (signature == NULL))
return -EINVAL;
- MD5Init(&context);
- MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
- MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
- MD5Final(signature,&context);
+ sg[0].page = virt_to_page(key);
+ sg[0].offset = offset_in_page(key);
+ sg[0].length = CIFS_SESSION_KEY_SIZE+16;
+ sg[1].page = virt_to_page(cifs_pdu->Protocol);
+ sg[1].offset = offset_in_page(cifs_pdu->Protocol);
+ sg[1].length = cifs_pdu->smb_buf_length;
+
+ cifs_do_hash(md5_tfm, sg, 2, signature);
+
return 0;
}
@@ -72,7 +75,7 @@
ses->sequence_number++;
write_unlock(&GlobalMid_Lock);
- rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
+ rc = cifs_calculate_signature(cifs_pdu, ses->md5_tfm, ses->mac_signing_key,smb_signature);
if(rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
else
@@ -81,8 +84,8 @@
return rc;
}
-int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
- __u32 expected_sequence_number)
+int cifs_verify_signature(struct smb_hdr * cifs_pdu, const struct cifsSesInfo * ses,
+ const char * mac_key, __u32 expected_sequence_number)
{
unsigned int rc;
char server_response_sig[8];
@@ -116,7 +119,7 @@
cifs_pdu->Signature.Sequence.SequenceNumber = expected_sequence_number;
cifs_pdu->Signature.Sequence.Reserved = 0;
- rc = cifs_calculate_signature(cifs_pdu, mac_key,
+ rc = cifs_calculate_signature(cifs_pdu, ses->md5_tfm, mac_key,
what_we_think_sig_should_be);
if(rc)
@@ -133,32 +136,84 @@
}
/* We fill in key by putting in 40 byte array which was allocated by caller */
-int cifs_calculate_mac_key(char * key, const char * rn, const char * password)
+int cifs_calculate_mac_key(const struct cifsSesInfo * ses, char * key, const char * rn,
+ const char * password)
{
char temp_key[16];
+ struct scatterlist sg;
+
if ((key == NULL) || (rn == NULL) || (password == NULL))
return -EINVAL;
- E_md4hash(password, temp_key);
- mdfour(key,temp_key,16);
+ sg.page = virt_to_page(temp_key);
+ sg.offset = offset_in_page(temp_key);
+ sg.length = 16;
+
+ E_md4hash(ses->md4_tfm, password, temp_key);
+ cifs_do_hash(ses->md4_tfm, &sg, 1, key);
+
memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE);
+
return 0;
}
+void cifs_prepare_keypads(u8 *ipad, u8 *opad, const u8 *key, int len)
+{
+ int i;
+
+ /* if key is longer than 64 bytes, truncate it */
+ len &= 0x3f;
+
+ /* start out by storing key in pads */
+ memset(ipad, 0, 64);
+ memset(opad, 0, 64);
+ memcpy(ipad, key, len);
+ memcpy(opad, key, len);
+
+ /* XOR key with ipad and opad values */
+ for (i = 0; i < 64; i++) {
+ ipad[i] ^= 0x36;
+ opad[i] ^= 0x5c;
+ }
+}
+
+/* a simple wrapper for crypto hashing */
+void cifs_do_hash(struct crypto_tfm *tfm, struct scatterlist *sg, int n, u8 *digest)
+{
+ crypto_digest_init(tfm);
+ crypto_digest_update(tfm, sg, n);
+ crypto_digest_final(tfm, digest);
+}
+
+void cifs_update_with_opad(struct crypto_tfm *md5_tfm, u8 *pad, u8 *digest)
+{
+ struct scatterlist sg[2];
+
+ sg[0].page = virt_to_page(pad);
+ sg[0].offset = offset_in_page(pad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(digest);
+ sg[1].offset = offset_in_page(digest);
+ sg[1].length = 16;
+
+ cifs_do_hash(md5_tfm, sg, 2, digest);
+}
+
int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_info)
{
char temp_hash[16];
- struct HMACMD5Context ctx;
char * ucase_buf;
wchar_t * unicode_buf;
unsigned int i,user_name_len,dom_name_len;
+ u8 ipad[65], opad[65];
+ struct scatterlist sg[2];
if(ses)
return -EINVAL;
- E_md4hash(ses->password_with_pad, temp_hash);
+ E_md4hash(ses->md4_tfm, ses->password_with_pad, temp_hash);
- hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
+ cifs_prepare_keypads(ipad, opad, temp_hash, 16);
user_name_len = strlen(ses->userName);
if(user_name_len > MAX_USERNAME_SIZE)
return -EINVAL;
@@ -183,24 +238,39 @@
dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
unicode_buf[user_name_len + dom_name_len] = 0;
- hmac_md5_update((const unsigned char *) unicode_buf,
- (user_name_len+dom_name_len)*2,&ctx);
- hmac_md5_final(ses->mac_signing_key,&ctx);
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(unicode_buf);
+ sg[1].offset = offset_in_page(unicode_buf);
+ sg[1].length = (user_name_len+dom_name_len)*2;
+
+ cifs_do_hash(ses->md5_tfm, sg, 2, ses->mac_signing_key);
+ cifs_update_with_opad(ses->md5_tfm, opad, ses->mac_signing_key);
+
kfree(ucase_buf);
kfree(unicode_buf);
return 0;
}
void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response)
{
- struct HMACMD5Context context;
+ u8 ipad[65], opad[65];
+ struct scatterlist sg[2];
+
memcpy(v2_session_response + 8, ses->server->cryptKey,8);
/* gen_blob(v2_session_response + 16); */
- hmac_md5_init_limK_to_64(ses->mac_signing_key, 16, &context);
- hmac_md5_update(ses->server->cryptKey,8,&context);
-/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
+ cifs_prepare_keypads(ipad, opad, ses->mac_signing_key, 16);
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(ses->server->cryptKey);
+ sg[1].offset = offset_in_page(ses->server->cryptKey);
+ sg[1].length = 8;
+/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
- hmac_md5_final(v2_session_response,&context);
+ cifs_do_hash(ses->md5_tfm, sg, 2, v2_session_response);
+ cifs_update_with_opad(ses->md5_tfm, opad, v2_session_response);
}
diff -urN linux-2.6.0-test6-bk3/fs/cifs/cifsencrypt.h linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsencrypt.h
--- linux-2.6.0-test6-bk3/fs/cifs/cifsencrypt.h Thu Jan 1 01:00:00 1970
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsencrypt.h Thu Oct 2 11:39:55 2003
@@ -0,0 +1,15 @@
+#ifndef CIFSENCRYPT_H
+#define CIFSENCRYPT_H
+
+#include <linux/crypto.h>
+#include <linux/spinlock.h>
+#include <asm/scatterlist.h>
+#include <asm/types.h>
+
+void E_md4hash(struct crypto_tfm *md4_tfm, const unsigned char *passwd, unsigned char *p16);
+
+extern void cifs_prepare_keypads(u8 *ipad, u8 *opad, const u8 *key, int len);
+extern void cifs_update_with_opad(struct crypto_tfm *md5_tfm, u8 *pad, u8 *digest);
+extern void cifs_do_hash(struct crypto_tfm *tfm, struct scatterlist *sg, int n, u8 *digest);
+
+#endif
diff -urN linux-2.6.0-test6-bk3/fs/cifs/cifsfs.c linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsfs.c
--- linux-2.6.0-test6-bk3/fs/cifs/cifsfs.c Sun Sep 28 02:50:25 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsfs.c Thu Oct 2 11:25:15 2003
@@ -31,6 +31,7 @@
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/vfs.h>
+#include "cifsencrypt.h"
#include "cifsfs.h"
#include "cifspdu.h"
#define DECLARE_GLOBALS_HERE
@@ -660,6 +661,7 @@
}
cifs_destroy_inodecache();
}
+
#ifdef CONFIG_PROC_FS
cifs_proc_clean();
#endif
diff -urN linux-2.6.0-test6-bk3/fs/cifs/cifsglob.h linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsglob.h
--- linux-2.6.0-test6-bk3/fs/cifs/cifsglob.h Sun Sep 28 02:50:10 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsglob.h Thu Oct 2 09:59:23 2003
@@ -162,6 +162,8 @@
char userName[MAX_USERNAME_SIZE + 1];
char domainName[MAX_USERNAME_SIZE + 1];
char password_with_pad[CIFS_ENCPWD_SIZE];
+ struct crypto_tfm *md5_tfm; /* crypto transform for md5 hashing */
+ struct crypto_tfm *md4_tfm; /* crypto transform for md4 hashing */
};
/*
diff -urN linux-2.6.0-test6-bk3/fs/cifs/cifsproto.h linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsproto.h
--- linux-2.6.0-test6-bk3/fs/cifs/cifsproto.h Sun Sep 28 02:50:06 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/cifsproto.h Thu Oct 2 11:35:04 2003
@@ -228,9 +228,10 @@
extern int cifs_reconnect(struct TCP_Server_Info *server);
extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *);
-extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key,
- __u32 expected_sequence_number);
-extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
+extern int cifs_verify_signature(const struct smb_hdr *, const struct cifsSesInfo * ses,
+ const char * mac_key, __u32 expected_sequence_number);
+extern int cifs_calculate_mac_key(const struct cifsSesInfo * ses, char * key,const char * rn,
+ const char * pass);
extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * );
diff -urN linux-2.6.0-test6-bk3/fs/cifs/connect.c linux-2.6.0-test6-bk3-dirty/fs/cifs/connect.c
--- linux-2.6.0-test6-bk3/fs/cifs/connect.c Sun Sep 28 02:50:59 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/connect.c Thu Oct 2 11:36:10 2003
@@ -18,6 +18,7 @@
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/crypto.h>
#include <linux/fs.h>
#include <linux/net.h>
#include <linux/string.h>
@@ -42,7 +43,7 @@
extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
-extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
+extern void SMBNTencrypt(const struct cifsSesInfo *ses, unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
extern int inet_addr(char *);
@@ -679,11 +680,11 @@
rc = -ENOMEM;
} else {
- SMBNTencrypt(pSesInfo->password_with_pad,
+ SMBNTencrypt(pSesInfo, pSesInfo->password_with_pad,
pSesInfo->server->cryptKey,
ntlm_session_key);
- cifs_calculate_mac_key(pSesInfo->mac_signing_key,
+ cifs_calculate_mac_key(pSesInfo, pSesInfo->mac_signing_key,
ntlm_session_key,
pSesInfo->password_with_pad);
}
@@ -697,11 +698,11 @@
nls_info);
}
} else { /* old style NTLM 0.12 session setup */
- SMBNTencrypt(pSesInfo->password_with_pad,
+ SMBNTencrypt(pSesInfo, pSesInfo->password_with_pad,
pSesInfo->server->cryptKey,
ntlm_session_key);
- cifs_calculate_mac_key(pSesInfo->mac_signing_key,
+ cifs_calculate_mac_key(pSesInfo, pSesInfo->mac_signing_key,
ntlm_session_key, pSesInfo->password_with_pad);
rc = CIFSSessSetup(xid, pSesInfo,
ntlm_session_key, nls_info);
@@ -917,7 +918,18 @@
sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
NIPQUAD(sin_server.sin_addr.s_addr));
}
-
+ if (!rc) {
+ pSesInfo->md5_tfm = crypto_alloc_tfm("md5", 0);
+ if (unlikely(pSesInfo->md5_tfm == NULL)) {
+ printk(KERN_WARNING "failed to load transform for md5\n");
+ rc = -ENOMEM;
+ }
+ pSesInfo->md4_tfm = crypto_alloc_tfm("md4", 0);
+ if (unlikely(pSesInfo->md4_tfm == NULL)) {
+ printk(KERN_WARNING "failed to load transform for md4\n");
+ rc = -ENOMEM;
+ }
+ }
if (!rc){
if (volume_info.password)
strncpy(pSesInfo->password_with_pad,
@@ -999,6 +1011,14 @@
/* on error free sesinfo and tcon struct if needed */
if (rc) {
+ if (pSesInfo->md5_tfm != NULL) {
+ crypto_free_tfm(pSesInfo->md5_tfm);
+ pSesInfo->md5_tfm = NULL;
+ }
+ if (pSesInfo->md4_tfm != NULL) {
+ crypto_free_tfm(pSesInfo->md4_tfm);
+ pSesInfo->md4_tfm = NULL;
+ }
/* If find_unc succeeded then rc == 0 so we can not end */
if (tcon) /* up here accidently freeing someone elses tcon struct */
tconInfoFree(tcon);
@@ -2422,6 +2442,14 @@
if (ses) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2);
+ }
+ if (ses->md5_tfm != NULL) {
+ crypto_free_tfm(ses->md5_tfm);
+ ses->md5_tfm = NULL;
+ }
+ if (ses->md4_tfm != NULL) {
+ crypto_free_tfm(ses->md4_tfm);
+ ses->md4_tfm = NULL;
}
if (ses)
sesInfoFree(ses);
diff -urN linux-2.6.0-test6-bk3/fs/cifs/smbencrypt.c linux-2.6.0-test6-bk3-dirty/fs/cifs/smbencrypt.c
--- linux-2.6.0-test6-bk3/fs/cifs/smbencrypt.c Sun Sep 28 02:50:20 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/smbencrypt.c Thu Oct 2 11:43:42 2003
@@ -30,10 +30,11 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/random.h>
+#include "cifsglob.h"
#include "cifs_unicode.h"
#include "cifspdu.h"
-#include "md5.h"
#include "cifs_debug.h"
+#include "cifsencrypt.h"
#ifndef FALSE
#define FALSE 0
@@ -49,10 +50,6 @@
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((__u32)(val)))
-/*The following definitions come from lib/md4.c */
-
-void mdfour(unsigned char *out, unsigned char *in, int n);
-
/*The following definitions come from libsmb/smbdes.c */
void E_P16(unsigned char *p14, unsigned char *p16);
@@ -68,13 +65,14 @@
/*The following definitions come from libsmb/smbencrypt.c */
void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
-void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
+void nt_lm_owf_gen(const struct cifsSesInfo *ses, char *pwd, unsigned char nt_p16[16],
+ unsigned char p16[16]);
void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
unsigned char p24[24]);
void NTLMSSPOWFencrypt(unsigned char passwd[8],
unsigned char *ntlmchalresp, unsigned char p24[24]);
-void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
+void SMBNTencrypt(const struct cifsSesInfo *ses, unsigned char *passwd,
+ unsigned char *c8, unsigned char *p24);
int make_oem_passwd_hash(char data[516], const char *passwd,
unsigned char old_pw_hash[16], int unicode);
int decode_pw_buffer(char in_buffer[516], char *new_pwrd,
@@ -148,10 +146,11 @@
*/
void
-E_md4hash(const unsigned char *passwd, unsigned char *p16)
+E_md4hash(struct crypto_tfm *md4_tfm, const unsigned char *passwd, unsigned char *p16)
{
int len;
__u16 wpwd[129];
+ struct scatterlist sg;
/* Password cannot be longer than 128 characters */
len = strlen((char *) passwd);
@@ -163,13 +162,17 @@
/* Calculate length in bytes */
len = _my_wcslen(wpwd) * sizeof (__u16);
- mdfour(p16, (unsigned char *) wpwd, len);
+ sg.page = virt_to_page(wpwd);
+ sg.offset = offset_in_page(wpwd);
+ sg.length = len;
+
+ cifs_do_hash(md4_tfm, &sg, 1, p16);
memset(wpwd,0,129 * 2);
}
/* Does both the NT and LM owfs of a user's password */
void
-nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
+nt_lm_owf_gen(const struct cifsSesInfo *ses, char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
{
char passwd[514];
@@ -180,7 +183,7 @@
memcpy(passwd, pwd, 512);
/* Calculate the MD4 hash (NT compatible) of the password */
memset(nt_p16, '\0', 16);
- E_md4hash(passwd, nt_p16);
+ E_md4hash(ses->md4_tfm, passwd, nt_p16);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("nt_lm_owf_gen: pwd, nt#\n"));
@@ -208,21 +211,22 @@
/* Does the NTLMv2 owfs of a user's password */
void
-ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
+ntv2_owf_gen(struct crypto_tfm *md5_tfm, const unsigned char owf[16], const char *user_n,
const char *domain_n, unsigned char kr_buf[16],
const struct nls_table *nls_codepage)
{
+ struct scatterlist sg[3];
wchar_t * user_u;
wchar_t * dom_u;
int user_l, domain_l;
- struct HMACMD5Context ctx;
+ u8 ipad[65], opad[65];
/* might as well do one alloc to hold both (user_u and dom_u) */
user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL);
if(user_u == NULL)
return;
dom_u = user_u + 1024;
-
+
/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
@@ -233,10 +237,20 @@
user_l++; /* trailing null */
domain_l++;
- hmac_md5_init_limK_to_64(owf, 16, &ctx);
- hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
- hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
- hmac_md5_final(kr_buf, &ctx);
+ cifs_prepare_keypads(ipad, opad, owf, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(user_u);
+ sg[1].offset = offset_in_page(user_u);
+ sg[1].length = user_l;
+ sg[2].page = virt_to_page(dom_u);
+ sg[2].offset = offset_in_page(dom_u);
+ sg[2].length = domain_l;
+
+ cifs_do_hash(md5_tfm, sg, 3, kr_buf);
+ cifs_update_with_opad(md5_tfm, opad, kr_buf);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
@@ -284,13 +298,14 @@
/* Does the NT MD4 hash then des encryption. */
void
-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
+SMBNTencrypt(const struct cifsSesInfo *ses, unsigned char *passwd, unsigned char *c8,
+ unsigned char *p24)
{
unsigned char p21[21];
memset(p21, '\0', 21);
- E_md4hash(passwd, p21);
+ E_md4hash(ses->md4_tfm, passwd, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
@@ -303,16 +318,27 @@
/* Does the md5 encryption from the NT hash for NTLMv2. */
void
-SMBOWFencrypt_ntv2(const unsigned char kr[16],
+SMBOWFencrypt_ntv2(struct crypto_tfm *md5_tfm, const unsigned char kr[16],
const struct data_blob * srv_chal,
const struct data_blob * cli_chal, unsigned char resp_buf[16])
{
- struct HMACMD5Context ctx;
+ struct scatterlist sg[3];
+ u8 ipad[65], opad[65];
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
- hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
- hmac_md5_final(resp_buf, &ctx);
+ cifs_prepare_keypads(ipad, opad, kr, 16);
+
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(srv_chal->data);
+ sg[1].offset = offset_in_page(srv_chal->data);
+ sg[1].length = srv_chal->length;
+ sg[2].page = virt_to_page(cli_chal->data);
+ sg[2].offset = offset_in_page(cli_chal->data);
+ sg[2].length = cli_chal->length;
+
+ cifs_do_hash(md5_tfm, sg, 3, resp_buf);
+ cifs_update_with_opad(md5_tfm, opad, resp_buf);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
@@ -322,8 +348,8 @@
#endif
}
-static struct data_blob LMv2_generate_response(const unsigned char ntlm_v2_hash[16],
- const struct data_blob * server_chal)
+static struct data_blob LMv2_generate_response(struct crypto_tfm *md5_tfm,
+ const unsigned char ntlm_v2_hash[16], const struct data_blob * server_chal)
{
unsigned char lmv2_response[16];
struct data_blob lmv2_client_data/* = data_blob(NULL, 8)*/; /* BB Fix BB */
@@ -333,7 +359,7 @@
/* client-supplied random data */
get_random_bytes(lmv2_client_data.data, lmv2_client_data.length);
/* Given that data, and the challenge from the server, generate a response */
- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
+ SMBOWFencrypt_ntv2(md5_tfm, ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));
/* after the first 16 bytes is the random data we generated above,
@@ -387,14 +413,23 @@
}
void
-SMBsesskeygen_ntv2(const unsigned char kr[16],
+SMBsesskeygen_ntv2(struct crypto_tfm *md5_tfm, const unsigned char kr[16],
const unsigned char *nt_resp, __u8 sess_key[16])
{
- struct HMACMD5Context ctx;
+ struct scatterlist sg[2];
+ u8 ipad[65], opad[65];
+
+ cifs_prepare_keypads(ipad, opad, kr, 16);
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(nt_resp, 16, &ctx);
- hmac_md5_final((unsigned char *) sess_key, &ctx);
+ sg[0].page = virt_to_page(ipad);
+ sg[0].offset = offset_in_page(ipad);
+ sg[0].length = 64;
+ sg[1].page = virt_to_page(nt_resp);
+ sg[1].offset = offset_in_page(nt_resp);
+ sg[1].length = 16;
+
+ cifs_do_hash(md5_tfm, sg, 2, sess_key);
+ cifs_update_with_opad(md5_tfm, opad, sess_key);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
@@ -403,10 +438,16 @@
}
void
-SMBsesskeygen_ntv1(const unsigned char kr[16],
+SMBsesskeygen_ntv1(struct crypto_tfm *md4_tfm, const unsigned char kr[16],
const unsigned char *nt_resp, __u8 sess_key[16])
{
- mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
+ struct scatterlist sg;
+
+ sg.page = virt_to_page(kr);
+ sg.offset = offset_in_page(kr);
+ sg.length = 16;
+
+ cifs_do_hash(md4_tfm, &sg, 1, sess_key);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
@@ -434,7 +475,7 @@
return TRUE;
}
-int SMBNTLMv2encrypt(const char *user, const char *domain, const char *password,
+int SMBNTLMv2encrypt(const struct cifsSesInfo* ses, const char *user, const char *domain, const char *password,
const struct data_blob *server_chal,
const struct data_blob *names_blob,
struct data_blob *lm_response, struct data_blob *nt_response,
@@ -442,13 +483,13 @@
{
unsigned char nt_hash[16];
unsigned char ntlm_v2_hash[16];
- E_md4hash(password, nt_hash);
+ E_md4hash(ses->md4_tfm, password, nt_hash);
/* We don't use the NT# directly. Instead we use it mashed up with
the username and domain.
This prevents username swapping during the auth exchange
*/
- ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash,nls_codepage);
+ ntv2_owf_gen(ses->md5_tfm, nt_hash, user, domain, ntlm_v2_hash,nls_codepage);
if (nt_response) {
/* *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal,
@@ -458,14 +499,14 @@
/* The NTLMv2 calculations also provide a session key, for signing etc later */
/* use only the first 16 bytes of nt_response for session key */
- SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data);
+ SMBsesskeygen_ntv2(ses->md5_tfm, ntlm_v2_hash, nt_response->data, nt_session_key->data);
}
}
/* LMv2 */
if (lm_response) {
- *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal);
+ *lm_response = LMv2_generate_response(ses->md5_tfm, ntlm_v2_hash, server_chal);
}
return TRUE;
diff -urN linux-2.6.0-test6-bk3/fs/cifs/transport.c linux-2.6.0-test6-bk3-dirty/fs/cifs/transport.c
--- linux-2.6.0-test6-bk3/fs/cifs/transport.c Sun Sep 28 02:50:14 2003
+++ linux-2.6.0-test6-bk3-dirty/fs/cifs/transport.c Thu Oct 2 09:50:42 2003
@@ -267,7 +267,7 @@
be32_to_cpu(out_buf->smb_buf_length);
if((out_buf->smb_buf_length > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) {
- rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
+ rc = cifs_verify_signature(out_buf, ses, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
if(rc)
cFYI(1,("Unexpected signature received from server"));
}
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-02 11:37 ` [PATCH CIFS] use CryptoAPI MD4/MD5 Erlend Aasland
@ 2003-10-04 18:00 ` dean gaudet
2003-10-04 18:24 ` Matt Mackall
0 siblings, 1 reply; 12+ messages in thread
From: dean gaudet @ 2003-10-04 18:00 UTC (permalink / raw)
To: Erlend Aasland
Cc: Steven French, James Morris, Matt Mackall,
Samba Technical Mailing List, Linux Kernel Mailing List
what about CryptoAPI is so expensive that you can't use a stack-based
context?
this seems pretty dumb converting a stack-based md5 context to multiple
instances in multiple structures.
the stack is almost guaranteed to be in L1 cache.
multiplying that structure by N connections is just a waste of memory
bandwidth. not to mention the locking crud you seem to need to do... the
stack is implicitly locked.
is CryptoAPI really this broken?
-dean
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-04 18:00 ` dean gaudet
@ 2003-10-04 18:24 ` Matt Mackall
2003-10-04 18:51 ` dean gaudet
0 siblings, 1 reply; 12+ messages in thread
From: Matt Mackall @ 2003-10-04 18:24 UTC (permalink / raw)
To: dean gaudet
Cc: Erlend Aasland, Steven French, James Morris,
Samba Technical Mailing List, Linux Kernel Mailing List
On Sat, Oct 04, 2003 at 11:00:01AM -0700, dean gaudet wrote:
> what about CryptoAPI is so expensive that you can't use a stack-based
> context?
The alloc functions hide a bunch of module lookup details and the size
of the context structures vary from one alg to the next. They also
tend to hide block-sized buffers to deal with fragments. So it's a
little ugly but not insurmountable.
> this seems pretty dumb converting a stack-based md5 context to multiple
> instances in multiple structures.
>
> the stack is almost guaranteed to be in L1 cache.
>
> multiplying that structure by N connections is just a waste of memory
> bandwidth. not to mention the locking crud you seem to need to do... the
> stack is implicitly locked.
>
> is CryptoAPI really this broken?
It's a bit inflexible in this regard, yes.
--
Matt Mackall : http://www.selenic.com : of or relating to the moon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-04 18:24 ` Matt Mackall
@ 2003-10-04 18:51 ` dean gaudet
2003-10-04 20:08 ` Francois Romieu
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: dean gaudet @ 2003-10-04 18:51 UTC (permalink / raw)
To: Matt Mackall
Cc: Erlend Aasland, Steven French, James Morris,
Samba Technical Mailing List, Linux Kernel Mailing List
On Sat, 4 Oct 2003, Matt Mackall wrote:
> On Sat, Oct 04, 2003 at 11:00:01AM -0700, dean gaudet wrote:
> > what about CryptoAPI is so expensive that you can't use a stack-based
> > context?
>
> The alloc functions hide a bunch of module lookup details and the size
> of the context structures vary from one alg to the next. They also
> tend to hide block-sized buffers to deal with fragments. So it's a
> little ugly but not insurmountable.
by "block-sized" you mean like 64 bytes for MD5 and SHA1, 16 bytes for
AES, and so forth? if so that's no biggie, those are already present
in most simple library implementations of these algos. but if "block"
means 4096 bytes then, aiee.
if module lookup is expensive then perhaps a much better api would be one
which yields a module handle -- and the module handle can be used in a
much less expensive allocator to create contexts where they're required.
it seems that the module handle could be a read-only structure and
therefore shared without locking.
> > this seems pretty dumb converting a stack-based md5 context to multiple
> > instances in multiple structures.
> >
> > the stack is almost guaranteed to be in L1 cache.
> >
> > multiplying that structure by N connections is just a waste of memory
> > bandwidth. not to mention the locking crud you seem to need to do... the
> > stack is implicitly locked.
> >
> > is CryptoAPI really this broken?
>
> It's a bit inflexible in this regard, yes.
this really sounds like two steps backwards and one step forward.
this CIFS patch alone replaces 89 lines with 250 lines of code! the new
code does not look anywhere near as readable as the original. but perhaps
that's just because i've dealt with the same trivial MD5Init/Update/Final
API for years.
i gather a lot of this comes from the desire to have run-time selectable
sw and hw implementations of various algorithms for "optimal" performance.
but there generally isn't an optimal algorithm for all situations.
for small short digests like passwords it's probably more overhead to
use the cryptoapi than is saved from any blindingly fast implementation
behind the scenes.
-dean
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-04 18:51 ` dean gaudet
@ 2003-10-04 20:08 ` Francois Romieu
2003-10-05 0:08 ` Matt Mackall
2003-10-05 12:29 ` Erlend Aasland
2 siblings, 0 replies; 12+ messages in thread
From: Francois Romieu @ 2003-10-04 20:08 UTC (permalink / raw)
To: dean gaudet
Cc: Matt Mackall, Erlend Aasland, Steven French, James Morris,
Samba Technical Mailing List, Linux Kernel Mailing List
dean gaudet <dean-list-linux-kernel@arctic.org> :
[...]
> this really sounds like two steps backwards and one step forward.
>
> this CIFS patch alone replaces 89 lines with 250 lines of code! the new
It could factor this sequence for example:
xxx.page = virt_to_page(key);
xxx.offset = offset_in_page(key);
xxx.length = foo;
(appears 19 times in the patch)
Btw, the patch add things like this (fs/cifs/connect.c::cifs_mount):
@@ -917,7 +918,18 @@
sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
NIPQUAD(sin_server.sin_addr.s_addr));
}
-
+ if (!rc) {
+ pSesInfo->md5_tfm = crypto_alloc_tfm("md5", 0);
+ if (unlikely(pSesInfo->md5_tfm == NULL)) {
+ printk(KERN_WARNING "failed to load transform
for md5\n");
+ rc = -ENOMEM;
+ }
+ pSesInfo->md4_tfm = crypto_alloc_tfm("md4", 0);
+ if (unlikely(pSesInfo->md4_tfm == NULL)) {
+ printk(KERN_WARNING "failed to load transform
for md4\n");
+ rc = -ENOMEM;
+ }
+ }
if (!rc){
if (volume_info.password)
strncpy(pSesInfo->password_with_pad,
@@ -999,6 +1011,14 @@
/* on error free sesinfo and tcon struct if needed */
if (rc) {
+ if (pSesInfo->md5_tfm != NULL) {
+ crypto_free_tfm(pSesInfo->md5_tfm);
+ pSesInfo->md5_tfm = NULL;
+ }
+ if (pSesInfo->md4_tfm != NULL) {
+ crypto_free_tfm(pSesInfo->md4_tfm);
+ pSesInfo->md4_tfm = NULL;
+ }
/* If find_unc succeeded then rc == 0 so we can not
end */
if (tcon) /* up here accidently freeing someone elses tcon
struct */
tconInfoFree(tcon);
@@ -2422,6 +2442,14 @@
The code doesn't remember what failed and must do extra checks. This adds
lines of code rather fast. Not a surprise in a function with a pile of
"if (rc)" and multiple exit paths.
> code does not look anywhere near as readable as the original. but perhaps
fs/cifs/connect.c::CIFSNTLMSSPNegotiateSessSetup):
[...]
ses->
serverDomain[1
+
(2
*
len)]
= 0;
Imho
CryptoAPI
is
not
the biggest
problem
here
--
Ueimor
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-04 18:51 ` dean gaudet
2003-10-04 20:08 ` Francois Romieu
@ 2003-10-05 0:08 ` Matt Mackall
2003-10-05 12:29 ` Erlend Aasland
2 siblings, 0 replies; 12+ messages in thread
From: Matt Mackall @ 2003-10-05 0:08 UTC (permalink / raw)
To: dean gaudet
Cc: Erlend Aasland, Steven French, James Morris,
Samba Technical Mailing List, Linux Kernel Mailing List
On Sat, Oct 04, 2003 at 11:51:57AM -0700, dean gaudet wrote:
> On Sat, 4 Oct 2003, Matt Mackall wrote:
>
> > On Sat, Oct 04, 2003 at 11:00:01AM -0700, dean gaudet wrote:
> > > what about CryptoAPI is so expensive that you can't use a stack-based
> > > context?
> >
> > The alloc functions hide a bunch of module lookup details and the size
> > of the context structures vary from one alg to the next. They also
> > tend to hide block-sized buffers to deal with fragments. So it's a
> > little ugly but not insurmountable.
>
> by "block-sized" you mean like 64 bytes for MD5 and SHA1, 16 bytes for
> AES, and so forth? if so that's no biggie, those are already present
> in most simple library implementations of these algos. but if "block"
> means 4096 bytes then, aiee.
Cipher-block-sized.
> if module lookup is expensive then perhaps a much better api would be one
> which yields a module handle -- and the module handle can be used in a
> much less expensive allocator to create contexts where they're required.
> it seems that the module handle could be a read-only structure and
> therefore shared without locking.
Indeed, I've proposed such an interface.
> this CIFS patch alone replaces 89 lines with 250 lines of code!
My experience is that aside from the context allocation/locking
issues, the thing is otherwise pretty painless to work with.
--
Matt Mackall : http://www.selenic.com : of or relating to the moon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH CIFS] use CryptoAPI MD4/MD5
2003-10-04 18:51 ` dean gaudet
2003-10-04 20:08 ` Francois Romieu
2003-10-05 0:08 ` Matt Mackall
@ 2003-10-05 12:29 ` Erlend Aasland
2 siblings, 0 replies; 12+ messages in thread
From: Erlend Aasland @ 2003-10-05 12:29 UTC (permalink / raw)
To: dean gaudet
Cc: Matt Mackall, Steven French, James Morris,
Samba Technical Mailing List, Linux Kernel Mailing List
Hi,
On 10/04/03 11:51, dean gaudet wrote:
> this CIFS patch alone replaces 89 lines with 250 lines of code!
... you forgot that if we find a nice way to use the CryptoAPI, we can
remove the old md4/md5 code: that makes 631 lines of code go away!
> the code does not look anywhere near as readable as the original. but perhaps
> that's just because i've dealt with the same trivial MD5Init/Update/Final
> API for years.
I agree that it could have been a bit more readable.
It is trivial to wrap the code that deals with the CryptoAPI into nice
"helper" functions. For example the cifs_do_hash() function does exactly
that. Putting scatterlist setup into one function will probably help a
lot on code readability and code size.
> i gather a lot of this comes from the desire to have run-time selectable
> sw and hw implementations of various algorithms for "optimal" performance.
> but there generally isn't an optimal algorithm for all situations.
> for small short digests like passwords it's probably more overhead to
> use the cryptoapi than is saved from any blindingly fast implementation
> behind the scenes.
True, I agree that it's perhaps a bit overkill. Anyway, this is just a
project for me to learn more about the kernel; it's not like I have a
burning desire to convert CIFS to use the CryptoAPI ;-)
Regards
Erlend
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2003-10-05 12:29 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <OF9C1504BB.5FB00D5A-ON87256DB3.0015672E-86256DB3.001798AE@us.ibm.com>
2003-10-02 11:37 ` [PATCH CIFS] use CryptoAPI MD4/MD5 Erlend Aasland
2003-10-04 18:00 ` dean gaudet
2003-10-04 18:24 ` Matt Mackall
2003-10-04 18:51 ` dean gaudet
2003-10-04 20:08 ` Francois Romieu
2003-10-05 0:08 ` Matt Mackall
2003-10-05 12:29 ` Erlend Aasland
2003-09-02 20:30 [RFC][PATCH] 2nd try to convert cifs to use CryptoAPI Erlend Aasland
2003-10-01 13:30 ` [PATCH CIFS] use CryptoAPI MD4/MD5 Erlend Aasland
2003-10-01 19:55 ` Matt Mackall
2003-10-01 23:26 ` Erlend Aasland
2003-10-01 23:42 ` Matt Mackall
2003-10-01 23:52 ` Erlend Aasland
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox