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 struct shash_desc shash
;
51 char ctx
[crypto_shash_descsize(server
->ntlmssp
.md5
)];
54 if (cifs_pdu
== NULL
|| server
== NULL
|| signature
== NULL
)
57 sdesc
.shash
.tfm
= server
->ntlmssp
.md5
;
58 sdesc
.shash
.flags
= 0x0;
60 rc
= crypto_shash_init(&sdesc
.shash
);
62 cERROR(1, "could not initialize master crypto API hmacmd5\n");
66 if (server
->secType
== RawNTLMSSP
)
67 crypto_shash_update(&sdesc
.shash
,
68 server
->session_key
.data
.ntlmv2
.key
,
69 CIFS_NTLMV2_SESSKEY_SIZE
);
71 crypto_shash_update(&sdesc
.shash
,
72 (char *)&server
->session_key
.data
,
73 server
->session_key
.len
);
75 crypto_shash_update(&sdesc
.shash
,
76 cifs_pdu
->Protocol
, cifs_pdu
->smb_buf_length
);
78 rc
= crypto_shash_final(&sdesc
.shash
, signature
);
84 int cifs_sign_smb(struct smb_hdr
*cifs_pdu
, struct TCP_Server_Info
*server
,
85 __u32
*pexpected_response_sequence_number
)
88 char smb_signature
[20];
90 if ((cifs_pdu
== NULL
) || (server
== NULL
))
93 if ((cifs_pdu
->Flags2
& SMBFLG2_SECURITY_SIGNATURE
) == 0)
96 spin_lock(&GlobalMid_Lock
);
97 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
98 cpu_to_le32(server
->sequence_number
);
99 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
101 *pexpected_response_sequence_number
= server
->sequence_number
++;
102 server
->sequence_number
++;
103 spin_unlock(&GlobalMid_Lock
);
105 rc
= cifs_calculate_signature(cifs_pdu
, server
, smb_signature
);
107 memset(cifs_pdu
->Signature
.SecuritySignature
, 0, 8);
109 memcpy(cifs_pdu
->Signature
.SecuritySignature
, smb_signature
, 8);
114 static int cifs_calc_signature2(const struct kvec
*iov
, int n_vec
,
115 struct TCP_Server_Info
*server
, char *signature
)
120 struct shash_desc shash
;
121 char ctx
[crypto_shash_descsize(server
->ntlmssp
.md5
)];
124 if (iov
== NULL
|| server
== NULL
|| signature
== NULL
)
127 sdesc
.shash
.tfm
= server
->ntlmssp
.md5
;
128 sdesc
.shash
.flags
= 0x0;
130 rc
= crypto_shash_init(&sdesc
.shash
);
132 cERROR(1, "could not initialize master crypto API hmacmd5\n");
136 if (server
->secType
== RawNTLMSSP
)
137 crypto_shash_update(&sdesc
.shash
,
138 server
->session_key
.data
.ntlmv2
.key
,
139 CIFS_NTLMV2_SESSKEY_SIZE
);
141 crypto_shash_update(&sdesc
.shash
,
142 (char *)&server
->session_key
.data
,
143 server
->session_key
.len
);
145 for (i
= 0; i
< n_vec
; i
++) {
146 if (iov
[i
].iov_len
== 0)
148 if (iov
[i
].iov_base
== NULL
) {
149 cERROR(1, "null iovec entry");
152 /* The first entry includes a length field (which does not get
153 signed that occupies the first 4 bytes before the header */
155 if (iov
[0].iov_len
<= 8) /* cmd field at offset 9 */
156 break; /* nothing to sign or corrupt header */
157 crypto_shash_update(&sdesc
.shash
,
158 iov
[i
].iov_base
+ 4, iov
[i
].iov_len
- 4);
160 crypto_shash_update(&sdesc
.shash
,
161 iov
[i
].iov_base
, iov
[i
].iov_len
);
164 rc
= crypto_shash_final(&sdesc
.shash
, signature
);
169 int cifs_sign_smb2(struct kvec
*iov
, int n_vec
, struct TCP_Server_Info
*server
,
170 __u32
*pexpected_response_sequence_number
)
173 char smb_signature
[20];
174 struct smb_hdr
*cifs_pdu
= iov
[0].iov_base
;
176 if ((cifs_pdu
== NULL
) || (server
== NULL
))
179 if ((cifs_pdu
->Flags2
& SMBFLG2_SECURITY_SIGNATURE
) == 0)
182 spin_lock(&GlobalMid_Lock
);
183 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
184 cpu_to_le32(server
->sequence_number
);
185 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
187 *pexpected_response_sequence_number
= server
->sequence_number
++;
188 server
->sequence_number
++;
189 spin_unlock(&GlobalMid_Lock
);
191 rc
= cifs_calc_signature2(iov
, n_vec
, server
, smb_signature
);
193 memset(cifs_pdu
->Signature
.SecuritySignature
, 0, 8);
195 memcpy(cifs_pdu
->Signature
.SecuritySignature
, smb_signature
, 8);
200 int cifs_verify_signature(struct smb_hdr
*cifs_pdu
,
201 struct TCP_Server_Info
*server
,
202 __u32 expected_sequence_number
)
205 char server_response_sig
[8];
206 char what_we_think_sig_should_be
[20];
208 if (cifs_pdu
== NULL
|| server
== NULL
)
211 if (cifs_pdu
->Command
== SMB_COM_NEGOTIATE
)
214 if (cifs_pdu
->Command
== SMB_COM_LOCKING_ANDX
) {
215 struct smb_com_lock_req
*pSMB
=
216 (struct smb_com_lock_req
*)cifs_pdu
;
217 if (pSMB
->LockType
& LOCKING_ANDX_OPLOCK_RELEASE
)
221 /* BB what if signatures are supposed to be on for session but
222 server does not send one? BB */
224 /* Do not need to verify session setups with signature "BSRSPYL " */
225 if (memcmp(cifs_pdu
->Signature
.SecuritySignature
, "BSRSPYL ", 8) == 0)
226 cFYI(1, "dummy signature received for smb command 0x%x",
229 /* save off the origiginal signature so we can modify the smb and check
230 its signature against what the server sent */
231 memcpy(server_response_sig
, cifs_pdu
->Signature
.SecuritySignature
, 8);
233 cifs_pdu
->Signature
.Sequence
.SequenceNumber
=
234 cpu_to_le32(expected_sequence_number
);
235 cifs_pdu
->Signature
.Sequence
.Reserved
= 0;
237 rc
= cifs_calculate_signature(cifs_pdu
, server
,
238 what_we_think_sig_should_be
);
243 /* cifs_dump_mem("what we think it should be: ",
244 what_we_think_sig_should_be, 16); */
246 if (memcmp(server_response_sig
, what_we_think_sig_should_be
, 8))
253 /* We fill in key by putting in 40 byte array which was allocated by caller */
254 int cifs_calculate_session_key(struct session_key
*key
, const char *rn
,
255 const char *password
)
258 if ((key
== NULL
) || (rn
== NULL
))
261 E_md4hash(password
, temp_key
);
262 mdfour(key
->data
.ntlm
, temp_key
, 16);
263 memcpy(key
->data
.ntlm
+16, rn
, CIFS_SESS_KEY_SIZE
);
268 #ifdef CONFIG_CIFS_WEAK_PW_HASH
269 void calc_lanman_hash(const char *password
, const char *cryptkey
, bool encrypt
,
270 char *lnm_session_key
)
273 char password_with_pad
[CIFS_ENCPWD_SIZE
];
275 memset(password_with_pad
, 0, CIFS_ENCPWD_SIZE
);
277 strncpy(password_with_pad
, password
, CIFS_ENCPWD_SIZE
);
279 if (!encrypt
&& global_secflags
& CIFSSEC_MAY_PLNTXT
) {
280 memset(lnm_session_key
, 0, CIFS_SESS_KEY_SIZE
);
281 memcpy(lnm_session_key
, password_with_pad
,
286 /* calculate old style session key */
287 /* calling toupper is less broken than repeatedly
288 calling nls_toupper would be since that will never
289 work for UTF8, but neither handles multibyte code pages
290 but the only alternative would be converting to UCS-16 (Unicode)
291 (using a routine something like UniStrupr) then
292 uppercasing and then converting back from Unicode - which
293 would only worth doing it if we knew it were utf8. Basically
294 utf8 and other multibyte codepages each need their own strupper
295 function since a byte at a time will ont work. */
297 for (i
= 0; i
< CIFS_ENCPWD_SIZE
; i
++)
298 password_with_pad
[i
] = toupper(password_with_pad
[i
]);
300 SMBencrypt(password_with_pad
, cryptkey
, lnm_session_key
);
302 /* clear password before we return/free memory */
303 memset(password_with_pad
, 0, CIFS_ENCPWD_SIZE
);
305 #endif /* CIFS_WEAK_PW_HASH */
307 static int calc_ntlmv2_hash(struct cifsSesInfo
*ses
,
308 const struct nls_table
*nls_cp
)
312 char nt_hash
[CIFS_NTHASH_SIZE
];
317 struct shash_desc shash
;
318 char ctx
[crypto_shash_descsize(ses
->server
->ntlmssp
.hmacmd5
)];
321 /* calculate md4 hash of password */
322 E_md4hash(ses
->password
, nt_hash
);
324 sdesc
.shash
.tfm
= ses
->server
->ntlmssp
.hmacmd5
;
325 sdesc
.shash
.flags
= 0x0;
327 crypto_shash_setkey(ses
->server
->ntlmssp
.hmacmd5
, nt_hash
,
330 rc
= crypto_shash_init(&sdesc
.shash
);
332 cERROR(1, "could not initialize master crypto API hmacmd5\n");
336 /* convert ses->userName to unicode and uppercase */
337 len
= strlen(ses
->userName
);
338 user
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
341 len
= cifs_strtoUCS((__le16
*)user
, ses
->userName
, len
, nls_cp
);
344 crypto_shash_update(&sdesc
.shash
, (char *)user
, 2 * len
);
346 /* convert ses->domainName to unicode and uppercase */
347 if (ses
->domainName
) {
348 len
= strlen(ses
->domainName
);
350 domain
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
353 len
= cifs_strtoUCS((__le16
*)domain
, ses
->domainName
, len
,
355 /* the following line was removed since it didn't work well
356 with lower cased domain name that passed as an option.
357 Maybe converting the domain name earlier makes sense */
358 /* UniStrupr(domain); */
360 crypto_shash_update(&sdesc
.shash
, (char *)domain
, 2 * len
);
363 } else if (ses
->serverName
) {
364 len
= strlen(ses
->serverName
);
366 server
= kmalloc(2 + (len
* 2), GFP_KERNEL
);
369 len
= cifs_strtoUCS((__le16
*)server
, ses
->serverName
, len
,
371 /* the following line was removed since it didn't work well
372 with lower cased domain name that passed as an option.
373 Maybe converting the domain name earlier makes sense */
374 /* UniStrupr(domain); */
376 crypto_shash_update(&sdesc
.shash
, (char *)server
, 2 * len
);
383 /* BB FIXME what about bytes 24 through 40 of the signing key?
384 compare with the NTLM example */
385 rc
= crypto_shash_final(&sdesc
.shash
, ses
->server
->ntlmv2_hash
);
391 find_domain_name(struct cifsSesInfo
*ses
)
394 unsigned int attrsize
;
396 unsigned char *blobptr
;
397 struct ntlmssp2_name
*attrptr
;
399 if (ses
->server
->tiblob
) {
400 blobptr
= ses
->server
->tiblob
;
401 attrptr
= (struct ntlmssp2_name
*) blobptr
;
403 while ((type
= attrptr
->type
) != 0) {
404 blobptr
+= 2; /* advance attr type */
405 attrsize
= attrptr
->length
;
406 blobptr
+= 2; /* advance attr size */
407 if (type
== NTLMSSP_AV_NB_DOMAIN_NAME
) {
408 if (!ses
->domainName
) {
410 kmalloc(attrptr
->length
+ 1,
412 if (!ses
->domainName
)
414 cifs_from_ucs2(ses
->domainName
,
418 load_nls_default(), false);
421 blobptr
+= attrsize
; /* advance attr value */
422 attrptr
= (struct ntlmssp2_name
*) blobptr
;
425 ses
->server
->tilen
= 2 * sizeof(struct ntlmssp2_name
);
426 ses
->server
->tiblob
= kmalloc(ses
->server
->tilen
, GFP_KERNEL
);
427 if (!ses
->server
->tiblob
) {
428 ses
->server
->tilen
= 0;
429 cERROR(1, "Challenge target info allocation failure");
432 memset(ses
->server
->tiblob
, 0x0, ses
->server
->tilen
);
433 attrptr
= (struct ntlmssp2_name
*) ses
->server
->tiblob
;
434 attrptr
->type
= cpu_to_le16(NTLMSSP_DOMAIN_TYPE
);
441 CalcNTLMv2_response(const struct TCP_Server_Info
*server
,
442 char *v2_session_response
)
446 struct shash_desc shash
;
447 char ctx
[crypto_shash_descsize(server
->ntlmssp
.hmacmd5
)];
450 sdesc
.shash
.tfm
= server
->ntlmssp
.hmacmd5
;
451 sdesc
.shash
.flags
= 0x0;
453 crypto_shash_setkey(server
->ntlmssp
.hmacmd5
, server
->ntlmv2_hash
,
454 CIFS_HMAC_MD5_HASH_SIZE
);
456 rc
= crypto_shash_init(&sdesc
.shash
);
458 cERROR(1, "could not initialize master crypto API hmacmd5\n");
462 memcpy(v2_session_response
+ CIFS_SERVER_CHALLENGE_SIZE
,
463 server
->cryptKey
, CIFS_SERVER_CHALLENGE_SIZE
);
464 crypto_shash_update(&sdesc
.shash
,
465 v2_session_response
+ CIFS_SERVER_CHALLENGE_SIZE
,
466 sizeof(struct ntlmv2_resp
) - CIFS_SERVER_CHALLENGE_SIZE
);
469 crypto_shash_update(&sdesc
.shash
,
470 server
->tiblob
, server
->tilen
);
472 rc
= crypto_shash_final(&sdesc
.shash
, v2_session_response
);
478 setup_ntlmv2_rsp(struct cifsSesInfo
*ses
, char *resp_buf
,
479 const struct nls_table
*nls_cp
)
482 struct ntlmv2_resp
*buf
= (struct ntlmv2_resp
*)resp_buf
;
484 struct shash_desc shash
;
485 char ctx
[crypto_shash_descsize(ses
->server
->ntlmssp
.hmacmd5
)];
488 buf
->blob_signature
= cpu_to_le32(0x00000101);
490 buf
->time
= cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME
));
491 get_random_bytes(&buf
->client_chal
, sizeof(buf
->client_chal
));
494 if (!ses
->domainName
) {
495 rc
= find_domain_name(ses
);
497 cERROR(1, "could not get domain/server name rc %d", rc
);
502 /* calculate buf->ntlmv2_hash */
503 rc
= calc_ntlmv2_hash(ses
, nls_cp
);
505 cERROR(1, "could not get v2 hash rc %d", rc
);
508 rc
= CalcNTLMv2_response(ses
->server
, resp_buf
);
510 cERROR(1, "could not get v2 hash rc %d", rc
);
514 crypto_shash_setkey(ses
->server
->ntlmssp
.hmacmd5
,
515 ses
->server
->ntlmv2_hash
, CIFS_HMAC_MD5_HASH_SIZE
);
517 sdesc
.shash
.tfm
= ses
->server
->ntlmssp
.hmacmd5
;
518 sdesc
.shash
.flags
= 0x0;
520 rc
= crypto_shash_init(&sdesc
.shash
);
522 cERROR(1, "could not initialize master crypto API hmacmd5\n");
526 crypto_shash_update(&sdesc
.shash
, resp_buf
, CIFS_HMAC_MD5_HASH_SIZE
);
528 rc
= crypto_shash_final(&sdesc
.shash
,
529 ses
->server
->session_key
.data
.ntlmv2
.key
);
531 memcpy(&ses
->server
->session_key
.data
.ntlmv2
.resp
, resp_buf
,
532 sizeof(struct ntlmv2_resp
));
533 ses
->server
->session_key
.len
= 16 + sizeof(struct ntlmv2_resp
);
539 calc_seckey(struct TCP_Server_Info
*server
)
542 unsigned char sec_key
[CIFS_NTLMV2_SESSKEY_SIZE
];
543 struct crypto_blkcipher
*tfm_arc4
;
544 struct scatterlist sgin
, sgout
;
545 struct blkcipher_desc desc
;
547 get_random_bytes(sec_key
, CIFS_NTLMV2_SESSKEY_SIZE
);
549 tfm_arc4
= crypto_alloc_blkcipher("ecb(arc4)",
550 0, CRYPTO_ALG_ASYNC
);
551 if (!tfm_arc4
|| IS_ERR(tfm_arc4
)) {
552 cERROR(1, "could not allocate " "master crypto API arc4\n");
558 crypto_blkcipher_setkey(tfm_arc4
,
559 server
->session_key
.data
.ntlmv2
.key
, CIFS_CPHTXT_SIZE
);
560 sg_init_one(&sgin
, sec_key
, CIFS_CPHTXT_SIZE
);
561 sg_init_one(&sgout
, server
->ntlmssp
.ciphertext
, CIFS_CPHTXT_SIZE
);
562 rc
= crypto_blkcipher_encrypt(&desc
, &sgout
, &sgin
, CIFS_CPHTXT_SIZE
);
565 memcpy(server
->session_key
.data
.ntlmv2
.key
,
566 sec_key
, CIFS_NTLMV2_SESSKEY_SIZE
);
568 crypto_free_blkcipher(tfm_arc4
);
574 cifs_crypto_shash_release(struct TCP_Server_Info
*server
)
576 if (server
->ntlmssp
.md5
)
577 crypto_free_shash(server
->ntlmssp
.md5
);
579 if (server
->ntlmssp
.hmacmd5
)
580 crypto_free_shash(server
->ntlmssp
.hmacmd5
);
584 cifs_crypto_shash_allocate(struct TCP_Server_Info
*server
)
586 server
->ntlmssp
.hmacmd5
= crypto_alloc_shash("hmac(md5)", 0, 0);
587 if (!server
->ntlmssp
.hmacmd5
||
588 IS_ERR(server
->ntlmssp
.hmacmd5
)) {
589 cERROR(1, "could not allocate master crypto API hmacmd5\n");
593 server
->ntlmssp
.md5
= crypto_alloc_shash("md5", 0, 0);
594 if (!server
->ntlmssp
.md5
|| IS_ERR(server
->ntlmssp
.md5
)) {
595 crypto_free_shash(server
->ntlmssp
.hmacmd5
);
596 cERROR(1, "could not allocate master crypto API md5\n");