17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: smb_crypt.c,v 1.13 2005/01/26 23:50:50 lindak Exp $
33 */
34
35 /*
36 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
37 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
38 */
39
40 /*
41 * NTLM support functions
42 *
43 * Some code from the driver: smb_smb.c, smb_crypt.c
44 */
45
46 #include <sys/errno.h>
47 #include <sys/types.h>
48 #include <sys/md4.h>
49 #include <sys/md5.h>
50
51 #include <ctype.h>
52 #include <stdlib.h>
53 #include <strings.h>
54
55 #include <netsmb/smb_lib.h>
56
57 #include "private.h"
167 /*
168 * Calculate an NTLMv1 session key (16 bytes).
169 */
170 static void
171 ntlm_v1_session_key(uchar_t *ssn_key, const uchar_t *nt_hash)
172 {
173 MD4_CTX md4;
174
175 MD4Init(&md4);
176 MD4Update(&md4, nt_hash, NTLM_HASH_SZ);
177 MD4Final(ssn_key, &md4);
178 }
179
180 /*
181 * Compute both the LM(v1) response and the NTLM(v1) response,
182 * and put them in the mbdata chains passed. This allocates
183 * mbuf chains in the output args, which the caller frees.
184 */
185 int
186 ntlm_put_v1_responses(struct smb_ctx *ctx,
187 struct mbdata *lm_mbp, struct mbdata *nt_mbp)
188 {
189 uchar_t *lmresp, *ntresp;
190 int err;
191
192 /* Get mbuf chain for the LM response. */
193 if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
194 return (err);
195
196 /* Get mbuf chain for the NT response. */
197 if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
198 return (err);
199
200 /*
201 * Compute the NTLM response, derived from
202 * the challenge and the NT hash (a.k.a ResponseKeyNT)
203 */
204 err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
205 if (err)
206 return (err);
207 bzero(ntresp, NTLM_V1_RESP_SZ);
212 * Compute the LM response, derived from
213 * the challenge and the ASCII password.
214 * Per. [MS-NLMP 3.3.1] if NoLmResponse,
215 * send the NT response for both NT+LM.
216 */
217 err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
218 if (err)
219 return (err);
220 memcpy(lmresp, ntresp, NTLM_V1_RESP_SZ);
221 if (ctx->ct_authflags & SMB_AT_LM1) {
222 /* They asked to send the LM hash too. */
223 err = ntlm_v1_response(lmresp, ctx->ct_lmhash,
224 ctx->ct_srv_chal, NTLM_CHAL_SZ);
225 if (err)
226 return (err);
227 }
228
229 /*
230 * Compute the session key
231 */
232 ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash);
233
234 return (err);
235 }
236
237 /*
238 * Compute both the LM(v1x) response and the NTLM(v1x) response,
239 * and put them in the mbdata chains passed. "v1x" here refers to
240 * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY used with NTLMSSP,
241 * also known by its shorter alias NTLMSSP_NEGOTIATE_NTLM2.
242 * [MS-NLMP 3.3.1]
243 *
244 * This allocates mbuf chains in the output args (caller frees).
245 */
246 int
247 ntlm_put_v1x_responses(struct smb_ctx *ctx,
248 struct mbdata *lm_mbp, struct mbdata *nt_mbp)
249 {
250 MD5_CTX context;
251 uchar_t challenges[2 * NTLM_CHAL_SZ];
252 uchar_t digest[NTLM_HASH_SZ];
253 uchar_t *lmresp, *ntresp;
254 int err;
255
256 /* Get mbuf chain for the LM response. */
257 if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
258 return (err);
259
260 /* Get mbuf chain for the NT response. */
261 if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
262 return (err);
263
264 /*
265 * challenges = ConcatenationOf(ServerChallenge, ClientChallenge)
266 */
267 memcpy(challenges, ctx->ct_srv_chal, NTLM_CHAL_SZ);
268 memcpy(challenges + NTLM_CHAL_SZ, ctx->ct_clnonce, NTLM_CHAL_SZ);
282 err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
283 if (err)
284 return (err);
285 bzero(ntresp, NTLM_V1_RESP_SZ);
286 err = ntlm_v1_response(ntresp, ctx->ct_nthash,
287 digest, NTLM_CHAL_SZ);
288
289 /*
290 * With "Extended Session Security", the LM response
291 * is simply the client challenge (nonce) padded out.
292 */
293 err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
294 if (err)
295 return (err);
296 bzero(lmresp, NTLM_V1_RESP_SZ);
297 memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ);
298
299 /*
300 * Compute the session key
301 */
302 ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash);
303
304 return (err);
305 }
306
307 /*
308 * A variation on HMAC-MD5 known as HMACT64 is used by Windows systems.
309 * The HMACT64() function is the same as the HMAC-MD5() except that
310 * it truncates the input key to 64 bytes rather than hashing it down
311 * to 16 bytes using the MD5() function.
312 *
313 * Output: digest (16-bytes)
314 */
315 static void
316 HMACT64(uchar_t *digest,
317 const uchar_t *key, size_t key_len,
318 const uchar_t *data, size_t data_len)
319 {
320 MD5_CTX context;
321 uchar_t k_ipad[64]; /* inner padding - key XORd with ipad */
322 uchar_t k_opad[64]; /* outer padding - key XORd with opad */
460 */
461 static void
462 ntlm_v2_session_key(uchar_t *ssn_key,
463 const uchar_t *v2hash,
464 const uchar_t *ntresp)
465 {
466
467 /* session key uses only 1st 16 bytes of ntresp */
468 HMACT64(ssn_key, v2hash, NTLM_HASH_SZ, ntresp, NTLM_HASH_SZ);
469 }
470
471
472 /*
473 * Compute both the LMv2 response and the NTLMv2 response,
474 * and put them in the mbdata chains passed. This allocates
475 * mbuf chains in the output args, which the caller frees.
476 * Also computes the session key.
477 */
478 int
479 ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
480 struct mbdata *lm_mbp, struct mbdata *nt_mbp)
481 {
482 uchar_t *lmresp, *ntresp;
483 int err;
484 char *ucuser = NULL; /* upper-case user name */
485 uchar_t v2hash[NTLM_HASH_SZ];
486 struct mbuf *tim = ti_mbp->mb_top;
487
488 /*
489 * Convert the user name to upper-case, as
490 * that's what's used when computing LMv2
491 * and NTLMv2 responses. Note that the
492 * domain name is NOT upper-cased!
493 */
494 if (ctx->ct_user[0] == '\0')
495 return (EINVAL);
496 ucuser = utf8_str_toupper(ctx->ct_user);
497 if (ucuser == NULL)
498 return (ENOMEM);
499
500 if ((err = mb_init(lm_mbp)) != 0)
530 /*
531 * Compute the NTLMv2 response, derived
532 * from the server challenge and the
533 * "target info." blob passed in.
534 *
535 * Again composed from two parts:
536 * 1: 16-byte response hash
537 * 2: "target info." blob
538 */
539 ntresp = mb_reserve(nt_mbp, NTLM_HASH_SZ);
540 err = ntlm_v2_resp_hash(ntresp,
541 v2hash, ctx->ct_srv_chal,
542 (uchar_t *)tim->m_data, tim->m_len);
543 if (err)
544 goto out;
545 mb_put_mem(nt_mbp, tim->m_data, tim->m_len, MB_MSYSTEM);
546
547 /*
548 * Compute the session key
549 */
550 ntlm_v2_session_key(ctx->ct_ssn_key, v2hash, ntresp);
551
552 out:
553 if (err) {
554 mb_done(lm_mbp);
555 mb_done(nt_mbp);
556 }
557 free(ucuser);
558
559 return (err);
560 }
561
562 /*
563 * Helper for ntlm_build_target_info below.
564 * Put a name in the NTLMv2 "target info." blob.
565 */
566 static void
567 smb_put_blob_name(struct mbdata *mbp, char *name, int type)
568 {
569 uint16_t *ucs = NULL;
570 int nlen;
633 err = mb_put_mem(mbp, names->m_data, names->m_len, MB_MSYSTEM);
634 } else {
635 /* Get upper-case names. */
636 ucdom = utf8_str_toupper(ctx->ct_domain);
637 if (ucdom == NULL) {
638 err = ENOMEM;
639 goto out;
640 }
641 smb_put_blob_name(mbp, ucdom, NAMETYPE_DOMAIN_NB);
642 smb_put_blob_name(mbp, NULL, NAMETYPE_EOL);
643 /* OK, that's the whole "target info." blob! */
644 }
645 err = 0;
646
647 out:
648 free(ucdom);
649 return (err);
650 }
651
652 /*
653 * Build the MAC key (for SMB signing)
654 */
655 int
656 ntlm_build_mac_key(struct smb_ctx *ctx, struct mbdata *ntresp_mbp)
657 {
658 struct mbuf *m;
659 size_t len;
660 char *p;
661
662 /*
663 * MAC_key = concat(session_key, nt_response)
664 */
665 m = ntresp_mbp->mb_top;
666 len = NTLM_HASH_SZ + m->m_len;
667 if ((p = malloc(len)) == NULL)
668 return (ENOMEM);
669 ctx->ct_mackeylen = len;
670 ctx->ct_mackey = p;
671 memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ);
672 memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len);
673
674 return (0);
675 }
676
677 /*
678 * Helper for ntlmssp_put_type3 - Build the "key exchange key"
679 * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2.
680 * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7]))
681 */
682 void
683 ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, uchar_t *kxkey)
684 {
685 uchar_t data[NTLM_HASH_SZ];
686 uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *);
687
688 /* concat(ServerChallenge, LmResponse[0..7]) */
689 memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ);
690 memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ);
691
692 /* HMAC_MD5(SessionBaseKey, concat(...)) */
693 HMACT64(kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ,
694 data, NTLM_HASH_SZ);
695 }
|
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: smb_crypt.c,v 1.13 2005/01/26 23:50:50 lindak Exp $
33 */
34
35 /*
36 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
37 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
38 */
39
40 /*
41 * NTLM support functions
42 *
43 * Some code from the driver: smb_smb.c, smb_crypt.c
44 */
45
46 #include <sys/errno.h>
47 #include <sys/types.h>
48 #include <sys/md4.h>
49 #include <sys/md5.h>
50
51 #include <ctype.h>
52 #include <stdlib.h>
53 #include <strings.h>
54
55 #include <netsmb/smb_lib.h>
56
57 #include "private.h"
167 /*
168 * Calculate an NTLMv1 session key (16 bytes).
169 */
170 static void
171 ntlm_v1_session_key(uchar_t *ssn_key, const uchar_t *nt_hash)
172 {
173 MD4_CTX md4;
174
175 MD4Init(&md4);
176 MD4Update(&md4, nt_hash, NTLM_HASH_SZ);
177 MD4Final(ssn_key, &md4);
178 }
179
180 /*
181 * Compute both the LM(v1) response and the NTLM(v1) response,
182 * and put them in the mbdata chains passed. This allocates
183 * mbuf chains in the output args, which the caller frees.
184 */
185 int
186 ntlm_put_v1_responses(struct smb_ctx *ctx,
187 struct mbdata *lm_mbp, struct mbdata *nt_mbp,
188 uchar_t *ssn_key)
189 {
190 uchar_t *lmresp, *ntresp;
191 int err;
192
193 /* Get mbuf chain for the LM response. */
194 if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
195 return (err);
196
197 /* Get mbuf chain for the NT response. */
198 if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
199 return (err);
200
201 /*
202 * Compute the NTLM response, derived from
203 * the challenge and the NT hash (a.k.a ResponseKeyNT)
204 */
205 err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
206 if (err)
207 return (err);
208 bzero(ntresp, NTLM_V1_RESP_SZ);
213 * Compute the LM response, derived from
214 * the challenge and the ASCII password.
215 * Per. [MS-NLMP 3.3.1] if NoLmResponse,
216 * send the NT response for both NT+LM.
217 */
218 err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
219 if (err)
220 return (err);
221 memcpy(lmresp, ntresp, NTLM_V1_RESP_SZ);
222 if (ctx->ct_authflags & SMB_AT_LM1) {
223 /* They asked to send the LM hash too. */
224 err = ntlm_v1_response(lmresp, ctx->ct_lmhash,
225 ctx->ct_srv_chal, NTLM_CHAL_SZ);
226 if (err)
227 return (err);
228 }
229
230 /*
231 * Compute the session key
232 */
233 ntlm_v1_session_key(ssn_key, ctx->ct_nthash);
234
235 return (err);
236 }
237
238 /*
239 * Compute both the LM(v1x) response and the NTLM(v1x) response,
240 * and put them in the mbdata chains passed. "v1x" here refers to
241 * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY used with NTLMSSP,
242 * also known by its shorter alias NTLMSSP_NEGOTIATE_NTLM2.
243 * [MS-NLMP 3.3.1]
244 *
245 * This allocates mbuf chains in the output args (caller frees).
246 */
247 int
248 ntlm_put_v1x_responses(struct smb_ctx *ctx,
249 struct mbdata *lm_mbp, struct mbdata *nt_mbp,
250 uchar_t *ssn_key)
251 {
252 MD5_CTX context;
253 uchar_t challenges[2 * NTLM_CHAL_SZ];
254 uchar_t digest[NTLM_HASH_SZ];
255 uchar_t *lmresp, *ntresp;
256 int err;
257
258 /* Get mbuf chain for the LM response. */
259 if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
260 return (err);
261
262 /* Get mbuf chain for the NT response. */
263 if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
264 return (err);
265
266 /*
267 * challenges = ConcatenationOf(ServerChallenge, ClientChallenge)
268 */
269 memcpy(challenges, ctx->ct_srv_chal, NTLM_CHAL_SZ);
270 memcpy(challenges + NTLM_CHAL_SZ, ctx->ct_clnonce, NTLM_CHAL_SZ);
284 err = mb_fit(nt_mbp, NTLM_V1_RESP_SZ, (char **)&ntresp);
285 if (err)
286 return (err);
287 bzero(ntresp, NTLM_V1_RESP_SZ);
288 err = ntlm_v1_response(ntresp, ctx->ct_nthash,
289 digest, NTLM_CHAL_SZ);
290
291 /*
292 * With "Extended Session Security", the LM response
293 * is simply the client challenge (nonce) padded out.
294 */
295 err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
296 if (err)
297 return (err);
298 bzero(lmresp, NTLM_V1_RESP_SZ);
299 memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ);
300
301 /*
302 * Compute the session key
303 */
304 ntlm_v1_session_key(ssn_key, ctx->ct_nthash);
305
306 return (err);
307 }
308
309 /*
310 * A variation on HMAC-MD5 known as HMACT64 is used by Windows systems.
311 * The HMACT64() function is the same as the HMAC-MD5() except that
312 * it truncates the input key to 64 bytes rather than hashing it down
313 * to 16 bytes using the MD5() function.
314 *
315 * Output: digest (16-bytes)
316 */
317 static void
318 HMACT64(uchar_t *digest,
319 const uchar_t *key, size_t key_len,
320 const uchar_t *data, size_t data_len)
321 {
322 MD5_CTX context;
323 uchar_t k_ipad[64]; /* inner padding - key XORd with ipad */
324 uchar_t k_opad[64]; /* outer padding - key XORd with opad */
462 */
463 static void
464 ntlm_v2_session_key(uchar_t *ssn_key,
465 const uchar_t *v2hash,
466 const uchar_t *ntresp)
467 {
468
469 /* session key uses only 1st 16 bytes of ntresp */
470 HMACT64(ssn_key, v2hash, NTLM_HASH_SZ, ntresp, NTLM_HASH_SZ);
471 }
472
473
474 /*
475 * Compute both the LMv2 response and the NTLMv2 response,
476 * and put them in the mbdata chains passed. This allocates
477 * mbuf chains in the output args, which the caller frees.
478 * Also computes the session key.
479 */
480 int
481 ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
482 struct mbdata *lm_mbp, struct mbdata *nt_mbp,
483 uchar_t *ssn_key)
484 {
485 uchar_t *lmresp, *ntresp;
486 int err;
487 char *ucuser = NULL; /* upper-case user name */
488 uchar_t v2hash[NTLM_HASH_SZ];
489 struct mbuf *tim = ti_mbp->mb_top;
490
491 /*
492 * Convert the user name to upper-case, as
493 * that's what's used when computing LMv2
494 * and NTLMv2 responses. Note that the
495 * domain name is NOT upper-cased!
496 */
497 if (ctx->ct_user[0] == '\0')
498 return (EINVAL);
499 ucuser = utf8_str_toupper(ctx->ct_user);
500 if (ucuser == NULL)
501 return (ENOMEM);
502
503 if ((err = mb_init(lm_mbp)) != 0)
533 /*
534 * Compute the NTLMv2 response, derived
535 * from the server challenge and the
536 * "target info." blob passed in.
537 *
538 * Again composed from two parts:
539 * 1: 16-byte response hash
540 * 2: "target info." blob
541 */
542 ntresp = mb_reserve(nt_mbp, NTLM_HASH_SZ);
543 err = ntlm_v2_resp_hash(ntresp,
544 v2hash, ctx->ct_srv_chal,
545 (uchar_t *)tim->m_data, tim->m_len);
546 if (err)
547 goto out;
548 mb_put_mem(nt_mbp, tim->m_data, tim->m_len, MB_MSYSTEM);
549
550 /*
551 * Compute the session key
552 */
553 ntlm_v2_session_key(ssn_key, v2hash, ntresp);
554
555 out:
556 if (err) {
557 mb_done(lm_mbp);
558 mb_done(nt_mbp);
559 }
560 free(ucuser);
561
562 return (err);
563 }
564
565 /*
566 * Helper for ntlm_build_target_info below.
567 * Put a name in the NTLMv2 "target info." blob.
568 */
569 static void
570 smb_put_blob_name(struct mbdata *mbp, char *name, int type)
571 {
572 uint16_t *ucs = NULL;
573 int nlen;
636 err = mb_put_mem(mbp, names->m_data, names->m_len, MB_MSYSTEM);
637 } else {
638 /* Get upper-case names. */
639 ucdom = utf8_str_toupper(ctx->ct_domain);
640 if (ucdom == NULL) {
641 err = ENOMEM;
642 goto out;
643 }
644 smb_put_blob_name(mbp, ucdom, NAMETYPE_DOMAIN_NB);
645 smb_put_blob_name(mbp, NULL, NAMETYPE_EOL);
646 /* OK, that's the whole "target info." blob! */
647 }
648 err = 0;
649
650 out:
651 free(ucdom);
652 return (err);
653 }
654
655 /*
656 * Helper for ntlmssp_put_type3 - Build the "key exchange key"
657 * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2.
658 * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7]))
659 */
660 void
661 ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp,
662 uchar_t *ssn_key, uchar_t *kxkey)
663 {
664 uchar_t data[NTLM_HASH_SZ];
665 uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *);
666
667 /* concat(ServerChallenge, LmResponse[0..7]) */
668 memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ);
669 memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ);
670
671 /* HMAC_MD5(SessionBaseKey, concat(...)) */
672 HMACT64(kxkey, ssn_key, NTLM_HASH_SZ,
673 data, NTLM_HASH_SZ);
674 }
|