diff options
Diffstat (limited to 'fs/cifs/smbencrypt.c')
-rw-r--r-- | fs/cifs/smbencrypt.c | 124 |
1 files changed, 99 insertions, 25 deletions
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index b5041c849981..1525d5e662b6 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -47,6 +47,88 @@ | |||
47 | #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) | 47 | #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) |
48 | #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) | 48 | #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) |
49 | 49 | ||
50 | static void | ||
51 | str_to_key(unsigned char *str, unsigned char *key) | ||
52 | { | ||
53 | int i; | ||
54 | |||
55 | key[0] = str[0] >> 1; | ||
56 | key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2); | ||
57 | key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3); | ||
58 | key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4); | ||
59 | key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5); | ||
60 | key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); | ||
61 | key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); | ||
62 | key[7] = str[6] & 0x7F; | ||
63 | for (i = 0; i < 8; i++) | ||
64 | key[i] = (key[i] << 1); | ||
65 | } | ||
66 | |||
67 | static int | ||
68 | smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) | ||
69 | { | ||
70 | int rc; | ||
71 | unsigned char key2[8]; | ||
72 | struct crypto_blkcipher *tfm_des; | ||
73 | struct scatterlist sgin, sgout; | ||
74 | struct blkcipher_desc desc; | ||
75 | |||
76 | str_to_key(key, key2); | ||
77 | |||
78 | tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC); | ||
79 | if (IS_ERR(tfm_des)) { | ||
80 | rc = PTR_ERR(tfm_des); | ||
81 | cERROR(1, "could not allocate des crypto API\n"); | ||
82 | goto smbhash_err; | ||
83 | } | ||
84 | |||
85 | desc.tfm = tfm_des; | ||
86 | |||
87 | crypto_blkcipher_setkey(tfm_des, key2, 8); | ||
88 | |||
89 | sg_init_one(&sgin, in, 8); | ||
90 | sg_init_one(&sgout, out, 8); | ||
91 | |||
92 | rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8); | ||
93 | if (rc) { | ||
94 | cERROR(1, "could not encrypt crypt key rc: %d\n", rc); | ||
95 | crypto_free_blkcipher(tfm_des); | ||
96 | goto smbhash_err; | ||
97 | } | ||
98 | |||
99 | smbhash_err: | ||
100 | return rc; | ||
101 | } | ||
102 | |||
103 | static int | ||
104 | E_P16(unsigned char *p14, unsigned char *p16) | ||
105 | { | ||
106 | int rc; | ||
107 | unsigned char sp8[8] = | ||
108 | { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; | ||
109 | |||
110 | rc = smbhash(p16, sp8, p14); | ||
111 | if (rc) | ||
112 | return rc; | ||
113 | rc = smbhash(p16 + 8, sp8, p14 + 7); | ||
114 | return rc; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24) | ||
119 | { | ||
120 | int rc; | ||
121 | |||
122 | rc = smbhash(p24, c8, p21); | ||
123 | if (rc) | ||
124 | return rc; | ||
125 | rc = smbhash(p24 + 8, c8, p21 + 7); | ||
126 | if (rc) | ||
127 | return rc; | ||
128 | rc = smbhash(p24 + 16, c8, p21 + 14); | ||
129 | return rc; | ||
130 | } | ||
131 | |||
50 | /* produce a md4 message digest from data of length n bytes */ | 132 | /* produce a md4 message digest from data of length n bytes */ |
51 | int | 133 | int |
52 | mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | 134 | mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) |
@@ -87,40 +169,30 @@ mdfour_err: | |||
87 | return rc; | 169 | return rc; |
88 | } | 170 | } |
89 | 171 | ||
90 | /* Does the des encryption from the NT or LM MD4 hash. */ | ||
91 | static void | ||
92 | SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, | ||
93 | unsigned char p24[24]) | ||
94 | { | ||
95 | unsigned char p21[21]; | ||
96 | |||
97 | memset(p21, '\0', 21); | ||
98 | |||
99 | memcpy(p21, passwd, 16); | ||
100 | E_P24(p21, c8, p24); | ||
101 | } | ||
102 | |||
103 | /* | 172 | /* |
104 | This implements the X/Open SMB password encryption | 173 | This implements the X/Open SMB password encryption |
105 | It takes a password, a 8 byte "crypt key" and puts 24 bytes of | 174 | It takes a password, a 8 byte "crypt key" and puts 24 bytes of |
106 | encrypted password into p24 */ | 175 | encrypted password into p24 */ |
107 | /* Note that password must be uppercased and null terminated */ | 176 | /* Note that password must be uppercased and null terminated */ |
108 | void | 177 | int |
109 | SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) | 178 | SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) |
110 | { | 179 | { |
111 | unsigned char p14[15], p21[21]; | 180 | int rc; |
181 | unsigned char p14[14], p16[16], p21[21]; | ||
112 | 182 | ||
113 | memset(p21, '\0', 21); | ||
114 | memset(p14, '\0', 14); | 183 | memset(p14, '\0', 14); |
115 | strncpy((char *) p14, (char *) passwd, 14); | 184 | memset(p16, '\0', 16); |
185 | memset(p21, '\0', 21); | ||
116 | 186 | ||
117 | /* strupper((char *)p14); *//* BB at least uppercase the easy range */ | 187 | memcpy(p14, passwd, 14); |
118 | E_P16(p14, p21); | 188 | rc = E_P16(p14, p16); |
189 | if (rc) | ||
190 | return rc; | ||
119 | 191 | ||
120 | SMBOWFencrypt(p21, c8, p24); | 192 | memcpy(p21, p16, 16); |
193 | rc = E_P24(p21, c8, p24); | ||
121 | 194 | ||
122 | memset(p14, 0, 15); | 195 | return rc; |
123 | memset(p21, 0, 21); | ||
124 | } | 196 | } |
125 | 197 | ||
126 | /* Routines for Windows NT MD4 Hash functions. */ | 198 | /* Routines for Windows NT MD4 Hash functions. */ |
@@ -279,16 +351,18 @@ int | |||
279 | SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) | 351 | SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) |
280 | { | 352 | { |
281 | int rc; | 353 | int rc; |
282 | unsigned char p21[21]; | 354 | unsigned char p16[16], p21[21]; |
283 | 355 | ||
356 | memset(p16, '\0', 16); | ||
284 | memset(p21, '\0', 21); | 357 | memset(p21, '\0', 21); |
285 | 358 | ||
286 | rc = E_md4hash(passwd, p21); | 359 | rc = E_md4hash(passwd, p16); |
287 | if (rc) { | 360 | if (rc) { |
288 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); | 361 | cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); |
289 | return rc; | 362 | return rc; |
290 | } | 363 | } |
291 | SMBOWFencrypt(p21, c8, p24); | 364 | memcpy(p21, p16, 16); |
365 | rc = E_P24(p21, c8, p24); | ||
292 | return rc; | 366 | return rc; |
293 | } | 367 | } |
294 | 368 | ||