2 * fs/cifs/cifsencrypt.c
4 * Copyright (C) International Business Machines Corp., 2005,2006
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/slab.h>
26 #include "cifs_debug.h"
28 #include "cifs_unicode.h"
29 #include "cifsproto.h"
31 #include <linux/ctype.h>
32 #include <linux/random.h>
34 /* Calculate and return the CIFS signature based on the mac key and SMB PDU */
35 /* the 16 byte signature must be allocated by the caller */
36 /* Note we only use the 1st eight bytes */
37 /* Note that the smb header signature field on input contains the
38 sequence number before this function is called */
40 extern void mdfour(unsigned char *out
, unsigned char *in
, int n
);
41 extern void E_md4hash(const unsigned char *passwd
, unsigned char *p16
);
42 extern void SMBencrypt(unsigned char *passwd
, const unsigned char *c8
,
45 static int cifs_calculate_signature(const struct smb_hdr
*cifs_pdu
,
46 struct TCP_Server_Info
*server
, char *signature
)
50 if (cifs_pdu
== NULL
|| server
== NULL
|| signature
== NULL
)
53 if (!server
->ntlmssp
.sdescmd5
) {
55 "cifs_calculate_signature: can't generate signature\n");
59 rc
= crypto_shash_init(&server
->ntlmssp
.sdescmd5
->shash
);
61 cERROR(1, "cifs_calculate_signature: oould not init md5\n");
65 if (server
->secType
== RawNTLMSSP
)
66 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
67 server
->session_key
.data
.ntlmv2
.key
,
68 CIFS_NTLMV2_SESSKEY_SIZE
);
70 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
71 (char *)&server
->session_key
.data
,
72 server
->session_key
.len
);
74 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
75 cifs_pdu
->Protocol
, cifs_pdu
->smb_buf_length
);
77 rc
= crypto_shash_final(&server
->ntlmssp
.sdescmd5
->shash
, signature
);
83 int cifs_sign_smb(struct smb_hdr
*cifs_pdu
, struct TCP_Server_Info
*server
,
84 __u32
*pexpected_response_sequence_number
)
87 char smb_signature
[20];
89 if ((cifs_pdu
== NULL
) || (server
== NULL
))
92 if ((cifs_pdu
->Flags2
& SMBFLG2_SECURITY_SIGNATURE
) == 0)
95 spin_lock(&GlobalMid_Lock
);
96 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
97 cpu_to_le32(server
->sequence_number
);
98 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
100 *pexpected_response_sequence_number
= server
->sequence_number
++;
101 server
->sequence_number
++;
102 spin_unlock(&GlobalMid_Lock
);
104 rc
= cifs_calculate_signature(cifs_pdu
, server
, smb_signature
);
106 memset(cifs_pdu
->Signature
.SecuritySignature
, 0, 8);
108 memcpy(cifs_pdu
->Signature
.SecuritySignature
, smb_signature
, 8);
113 static int cifs_calc_signature2(const struct kvec
*iov
, int n_vec
,
114 struct TCP_Server_Info
*server
, char *signature
)
119 if (iov
== NULL
|| server
== NULL
|| signature
== NULL
)
122 if (!server
->ntlmssp
.sdescmd5
) {
123 cERROR(1, "cifs_calc_signature2: can't generate signature\n");
127 rc
= crypto_shash_init(&server
->ntlmssp
.sdescmd5
->shash
);
129 cERROR(1, "cifs_calc_signature2: oould not init md5\n");
133 if (server
->secType
== RawNTLMSSP
)
134 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
135 server
->session_key
.data
.ntlmv2
.key
,
136 CIFS_NTLMV2_SESSKEY_SIZE
);
138 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
139 (char *)&server
->session_key
.data
,
140 server
->session_key
.len
);
142 for (i
= 0; i
< n_vec
; i
++) {
143 if (iov
[i
].iov_len
== 0)
145 if (iov
[i
].iov_base
== NULL
) {
146 cERROR(1, "cifs_calc_signature2: null iovec entry");
149 /* The first entry includes a length field (which does not get
150 signed that occupies the first 4 bytes before the header */
152 if (iov
[0].iov_len
<= 8) /* cmd field at offset 9 */
153 break; /* nothing to sign or corrupt header */
154 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
155 iov
[i
].iov_base
+ 4, iov
[i
].iov_len
- 4);
157 crypto_shash_update(&server
->ntlmssp
.sdescmd5
->shash
,
158 iov
[i
].iov_base
, iov
[i
].iov_len
);
161 rc
= crypto_shash_final(&server
->ntlmssp
.sdescmd5
->shash
, signature
);
166 int cifs_sign_smb2(struct kvec
*iov
, int n_vec
, struct TCP_Server_Info
*server
,
167 __u32
*pexpected_response_sequence_number
)
170 char smb_signature
[20];
171 struct smb_hdr
*cifs_pdu
= iov
[0].iov_base
;
173 if ((cifs_pdu
== NULL
) || (server
== NULL
))
176 if ((cifs_pdu
->Flags2
& SMBFLG2_SECURITY_SIGNATURE
) == 0)
179 spin_lock(&GlobalMid_Lock
);
180 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
181 cpu_to_le32(server
->sequence_number
);
182 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
184 *pexpected_response_sequence_number
= server
->sequence_number
++;
185 server
->sequence_number
++;
186 spin_unlock(&GlobalMid_Lock
);
188 rc
= cifs_calc_signature2(iov
, n_vec
, server
, smb_signature
);
190 memset(cifs_pdu
->Signature
.SecuritySignature
, 0, 8);
192 memcpy(cifs_pdu
->Signature
.SecuritySignature
, smb_signature
, 8);
197 int cifs_verify_signature(struct smb_hdr
*cifs_pdu
,
198 struct TCP_Server_Info
*server
,
199 __u32 expected_sequence_number
)
202 char server_response_sig
[8];
203 char what_we_think_sig_should_be
[20];
205 if (cifs_pdu
== NULL
|| server
== NULL
)
208 if (cifs_pdu
->Command
== SMB_COM_NEGOTIATE
)
211 if (cifs_pdu
->Command
== SMB_COM_LOCKING_ANDX
) {
212 struct smb_com_lock_req
*pSMB
=
213 (struct smb_com_lock_req
*)cifs_pdu
;
214 if (pSMB
->LockType
& LOCKING_ANDX_OPLOCK_RELEASE
)
218 /* BB what if signatures are supposed to be on for session but
219 server does not send one? BB */
221 /* Do not need to verify session setups with signature "BSRSPYL " */
222 if (memcmp(cifs_pdu
->Signature
.SecuritySignature
, "BSRSPYL ", 8) == 0)
223 cFYI(1, "dummy signature received for smb command 0x%x",
226 /* save off the origiginal signature so we can modify the smb and check
227 its signature against what the server sent */
228 memcpy(server_response_sig
, cifs_pdu
->Signature
.SecuritySignature
, 8);
230 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
231 cpu_to_le32(expected_sequence_number
);
232 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
234 rc
= cifs_calculate_signature(cifs_pdu
, server
,
235 what_we_think_sig_should_be
);
240 /* cifs_dump_mem("what we think it should be: ",
241 what_we_think_sig_should_be, 16); */
243 if (memcmp(server_response_sig
, what_we_think_sig_should_be
, 8))
250 /* We fill in key by putting in 40 byte array which was allocated by caller */
251 int cifs_calculate_session_key(struct session_key
*key
, const char *rn
,
252 const char *password
)
255 if ((key
== NULL
) || (rn
== NULL
))
258 E_md4hash(password
, temp_key
);
259 mdfour(key
->data
.ntlm
, temp_key
, 16);
260 memcpy(key
->data
.ntlm
+16, rn
, CIFS_SESS_KEY_SIZE
);
265 #ifdef CONFIG_CIFS_WEAK_PW_HASH
266 void calc_lanman_hash(const char *password
, const char *cryptkey
, bool encrypt
,
267 char *lnm_session_key
)
270 char password_with_pad
[CIFS_ENCPWD_SIZE
];
272 memset(password_with_pad
, 0, CIFS_ENCPWD_SIZE
);
274 strncpy(password_with_pad
, password
, CIFS_ENCPWD_SIZE
);
276 if (!encrypt
&& global_secflags
& CIFSSEC_MAY_PLNTXT
) {
277 memset(lnm_session_key
, 0, CIFS_SESS_KEY_SIZE
);
278 memcpy(lnm_session_key
, password_with_pad
,
283 /* calculate old style session key */
284 /* calling toupper is less broken than repeatedly
285 calling nls_toupper would be since that will never
286 work for UTF8, but neither handles multibyte code pages
287 but the only alternative would be converting to UCS-16 (Unicode)
288 (using a routine something like UniStrupr) then
289 uppercasing and then converting back from Unicode - which
290 would only worth doing it if we knew it were utf8. Basically
291 utf8 and other multibyte codepages each need their own strupper
292 function since a byte at a time will ont work. */
294 for (i
= 0; i
< CIFS_ENCPWD_SIZE
; i
++)
295 password_with_pad
[i
] = toupper(password_with_pad
[i
]);
297 SMBencrypt(password_with_pad
, cryptkey
, lnm_session_key
);
299 /* clear password before we return/free memory */
300 memset(password_with_pad
, 0, CIFS_ENCPWD_SIZE
);
302 #endif /* CIFS_WEAK_PW_HASH */
304 static int calc_ntlmv2_hash(struct cifsSesInfo
*ses
,
305 const struct nls_table
*nls_cp
)
309 char nt_hash
[CIFS_NTHASH_SIZE
];
314 if (!ses
->server
->ntlmssp
.sdeschmacmd5
) {
315 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
319 /* calculate md4 hash of password */
320 E_md4hash(ses
->password
, nt_hash
);
322 crypto_shash_setkey(ses
->server
->ntlmssp
.hmacmd5
, nt_hash
,
325 rc
= crypto_shash_init(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
);
327 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
331 /* convert ses->userName to unicode and uppercase */
332 len
= strlen(ses
->userName
);
333 user
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
335 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
339 len
= cifs_strtoUCS((__le16
*)user
, ses
->userName
, len
, nls_cp
);
342 crypto_shash_update(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
343 (char *)user
, 2 * len
);
345 /* convert ses->domainName to unicode and uppercase */
346 if (ses
->domainName
) {
347 len
= strlen(ses
->domainName
);
349 domain
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
350 if (domain
== NULL
) {
351 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
355 len
= cifs_strtoUCS((__le16
*)domain
, ses
->domainName
, len
,
357 /* the following line was removed since it didn't work well
358 with lower cased domain name that passed as an option.
359 Maybe converting the domain name earlier makes sense */
360 /* UniStrupr(domain); */
362 crypto_shash_update(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
363 (char *)domain
, 2 * len
);
366 } else if (ses
->serverName
) {
367 len
= strlen(ses
->serverName
);
369 server
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
370 if (server
== NULL
) {
371 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
375 len
= cifs_strtoUCS((__le16
*)server
, ses
->serverName
, len
,
377 /* the following line was removed since it didn't work well
378 with lower cased domain name that passed as an option.
379 Maybe converting the domain name earlier makes sense */
380 /* UniStrupr(domain); */
382 crypto_shash_update(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
383 (char *)server
, 2 * len
);
388 rc
= crypto_shash_final(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
389 ses
->server
->ntlmv2_hash
);
394 /* BB FIXME what about bytes 24 through 40 of the signing key?
395 compare with the NTLM example */
401 find_domain_name(struct cifsSesInfo
*ses
)
404 unsigned int attrsize
;
406 unsigned char *blobptr
;
407 struct ntlmssp2_name
*attrptr
;
409 if (ses
->server
->tiblob
) {
410 blobptr
= ses
->server
->tiblob
;
411 attrptr
= (struct ntlmssp2_name
*) blobptr
;
413 while ((type
= attrptr
->type
) != 0) {
414 blobptr
+= 2; /* advance attr type */
415 attrsize
= attrptr
->length
;
416 blobptr
+= 2; /* advance attr size */
417 if (type
== NTLMSSP_AV_NB_DOMAIN_NAME
) {
418 if (!ses
->domainName
) {
420 kmalloc(attrptr
->length
+ 1,
422 if (!ses
->domainName
)
424 cifs_from_ucs2(ses
->domainName
,
428 load_nls_default(), false);
431 blobptr
+= attrsize
; /* advance attr value */
432 attrptr
= (struct ntlmssp2_name
*) blobptr
;
435 ses
->server
->tilen
= 2 * sizeof(struct ntlmssp2_name
);
436 ses
->server
->tiblob
= kmalloc(ses
->server
->tilen
, GFP_KERNEL
);
437 if (!ses
->server
->tiblob
) {
438 ses
->server
->tilen
= 0;
439 cERROR(1, "Challenge target info allocation failure");
442 memset(ses
->server
->tiblob
, 0x0, ses
->server
->tilen
);
443 attrptr
= (struct ntlmssp2_name
*) ses
->server
->tiblob
;
444 attrptr
->type
= cpu_to_le16(NTLMSSP_DOMAIN_TYPE
);
451 CalcNTLMv2_response(const struct TCP_Server_Info
*server
,
452 char *v2_session_response
)
456 if (!server
->ntlmssp
.sdeschmacmd5
) {
457 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
461 crypto_shash_setkey(server
->ntlmssp
.hmacmd5
, server
->ntlmv2_hash
,
462 CIFS_HMAC_MD5_HASH_SIZE
);
464 rc
= crypto_shash_init(&server
->ntlmssp
.sdeschmacmd5
->shash
);
466 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
470 memcpy(v2_session_response
+ CIFS_SERVER_CHALLENGE_SIZE
,
471 server
->cryptKey
, CIFS_SERVER_CHALLENGE_SIZE
);
472 crypto_shash_update(&server
->ntlmssp
.sdeschmacmd5
->shash
,
473 v2_session_response
+ CIFS_SERVER_CHALLENGE_SIZE
,
474 sizeof(struct ntlmv2_resp
) - CIFS_SERVER_CHALLENGE_SIZE
);
477 crypto_shash_update(&server
->ntlmssp
.sdeschmacmd5
->shash
,
478 server
->tiblob
, server
->tilen
);
480 rc
= crypto_shash_final(&server
->ntlmssp
.sdeschmacmd5
->shash
,
481 v2_session_response
);
487 setup_ntlmv2_rsp(struct cifsSesInfo
*ses
, char *resp_buf
,
488 const struct nls_table
*nls_cp
)
491 struct ntlmv2_resp
*buf
= (struct ntlmv2_resp
*)resp_buf
;
493 buf
->blob_signature
= cpu_to_le32(0x00000101);
495 buf
->time
= cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME
));
496 get_random_bytes(&buf
->client_chal
, sizeof(buf
->client_chal
));
499 if (!ses
->domainName
) {
500 rc
= find_domain_name(ses
);
502 cERROR(1, "could not get domain/server name rc %d", rc
);
507 /* calculate buf->ntlmv2_hash */
508 rc
= calc_ntlmv2_hash(ses
, nls_cp
);
510 cERROR(1, "could not get v2 hash rc %d", rc
);
513 rc
= CalcNTLMv2_response(ses
->server
, resp_buf
);
515 cERROR(1, "could not get v2 hash rc %d", rc
);
519 if (!ses
->server
->ntlmssp
.sdeschmacmd5
) {
520 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
524 crypto_shash_setkey(ses
->server
->ntlmssp
.hmacmd5
,
525 ses
->server
->ntlmv2_hash
, CIFS_HMAC_MD5_HASH_SIZE
);
527 rc
= crypto_shash_init(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
);
529 cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n");
533 crypto_shash_update(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
534 resp_buf
, CIFS_HMAC_MD5_HASH_SIZE
);
536 rc
= crypto_shash_final(&ses
->server
->ntlmssp
.sdeschmacmd5
->shash
,
537 ses
->server
->session_key
.data
.ntlmv2
.key
);
539 memcpy(&ses
->server
->session_key
.data
.ntlmv2
.resp
, resp_buf
,
540 sizeof(struct ntlmv2_resp
));
541 ses
->server
->session_key
.len
= 16 + sizeof(struct ntlmv2_resp
);
547 calc_seckey(struct TCP_Server_Info
*server
)
550 unsigned char sec_key
[CIFS_NTLMV2_SESSKEY_SIZE
];
551 struct crypto_blkcipher
*tfm_arc4
;
552 struct scatterlist sgin
, sgout
;
553 struct blkcipher_desc desc
;
555 get_random_bytes(sec_key
, CIFS_NTLMV2_SESSKEY_SIZE
);
557 tfm_arc4
= crypto_alloc_blkcipher("ecb(arc4)",
558 0, CRYPTO_ALG_ASYNC
);
559 if (!tfm_arc4
|| IS_ERR(tfm_arc4
)) {
560 cERROR(1, "could not allocate " "master crypto API arc4\n");
566 crypto_blkcipher_setkey(tfm_arc4
,
567 server
->session_key
.data
.ntlmv2
.key
, CIFS_CPHTXT_SIZE
);
568 sg_init_one(&sgin
, sec_key
, CIFS_CPHTXT_SIZE
);
569 sg_init_one(&sgout
, server
->ntlmssp
.ciphertext
, CIFS_CPHTXT_SIZE
);
570 rc
= crypto_blkcipher_encrypt(&desc
, &sgout
, &sgin
, CIFS_CPHTXT_SIZE
);
573 memcpy(server
->session_key
.data
.ntlmv2
.key
,
574 sec_key
, CIFS_NTLMV2_SESSKEY_SIZE
);
576 crypto_free_blkcipher(tfm_arc4
);
582 cifs_crypto_shash_release(struct TCP_Server_Info
*server
)
584 if (server
->ntlmssp
.md5
)
585 crypto_free_shash(server
->ntlmssp
.md5
);
587 if (server
->ntlmssp
.hmacmd5
)
588 crypto_free_shash(server
->ntlmssp
.hmacmd5
);
590 kfree(server
->ntlmssp
.sdeschmacmd5
);
592 kfree(server
->ntlmssp
.sdescmd5
);
596 cifs_crypto_shash_allocate(struct TCP_Server_Info
*server
)
601 server
->ntlmssp
.hmacmd5
= crypto_alloc_shash("hmac(md5)", 0, 0);
602 if (!server
->ntlmssp
.hmacmd5
||
603 IS_ERR(server
->ntlmssp
.hmacmd5
)) {
604 cERROR(1, "could not allocate crypto hmacmd5\n");
608 server
->ntlmssp
.md5
= crypto_alloc_shash("md5", 0, 0);
609 if (!server
->ntlmssp
.md5
|| IS_ERR(server
->ntlmssp
.md5
)) {
610 cERROR(1, "could not allocate crypto md5\n");
612 goto cifs_crypto_shash_allocate_ret1
;
615 size
= sizeof(struct shash_desc
) +
616 crypto_shash_descsize(server
->ntlmssp
.hmacmd5
);
617 server
->ntlmssp
.sdeschmacmd5
= kmalloc(size
, GFP_KERNEL
);
618 if (!server
->ntlmssp
.sdeschmacmd5
) {
619 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
621 goto cifs_crypto_shash_allocate_ret2
;
623 server
->ntlmssp
.sdeschmacmd5
->shash
.tfm
= server
->ntlmssp
.hmacmd5
;
624 server
->ntlmssp
.sdeschmacmd5
->shash
.flags
= 0x0;
627 size
= sizeof(struct shash_desc
) +
628 crypto_shash_descsize(server
->ntlmssp
.md5
);
629 server
->ntlmssp
.sdescmd5
= kmalloc(size
, GFP_KERNEL
);
630 if (!server
->ntlmssp
.sdescmd5
) {
631 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
633 goto cifs_crypto_shash_allocate_ret3
;
635 server
->ntlmssp
.sdescmd5
->shash
.tfm
= server
->ntlmssp
.md5
;
636 server
->ntlmssp
.sdescmd5
->shash
.flags
= 0x0;
640 cifs_crypto_shash_allocate_ret3
:
641 kfree(server
->ntlmssp
.sdeschmacmd5
);
643 cifs_crypto_shash_allocate_ret2
:
644 crypto_free_shash(server
->ntlmssp
.md5
);
646 cifs_crypto_shash_allocate_ret1
:
647 crypto_free_shash(server
->ntlmssp
.hmacmd5
);