1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#if defined(USE_CURL_NTLM_CORE)
26
27/*
28 * NTLM details:
29 *
30 * https://davenport.sourceforge.io/ntlm.html
31 * https://www.innovation.ch/java/ntlm.html
32 */
33
34/* Please keep the SSL backend-specific #if branches in this order:
35
36 1. USE_OPENSSL
37 2. USE_GNUTLS
38 3. USE_NSS
39 4. USE_MBEDTLS
40 5. USE_SECTRANSP
41 6. USE_OS400CRYPTO
42 7. USE_WIN32_CRYPTO
43
44 This ensures that:
45 - the same SSL branch gets activated throughout this source
46 file even if multiple backends are enabled at the same time.
47 - OpenSSL and NSS have higher priority than Windows Crypt, due
48 to issues with the latter supporting NTLM2Session responses
49 in NTLM type-3 messages.
50 */
51
52#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
53
54#ifdef USE_WOLFSSL
55#include <wolfssl/options.h>
56#endif
57
58# include <openssl/des.h>
59# include <openssl/md5.h>
60# include <openssl/ssl.h>
61# include <openssl/rand.h>
62# if (defined(OPENSSL_VERSION_NUMBER) && \
63 (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
64# define DES_key_schedule des_key_schedule
65# define DES_cblock des_cblock
66# define DES_set_odd_parity des_set_odd_parity
67# define DES_set_key des_set_key
68# define DES_ecb_encrypt des_ecb_encrypt
69# define DESKEY(x) x
70# define DESKEYARG(x) x
71# else
72# define DESKEYARG(x) *x
73# define DESKEY(x) &x
74# endif
75
76#elif defined(USE_GNUTLS)
77
78# include <nettle/des.h>
79
80#elif defined(USE_NSS)
81
82# include <nss.h>
83# include <pk11pub.h>
84# include <hasht.h>
85
86#elif defined(USE_MBEDTLS)
87
88# include <mbedtls/des.h>
89
90#elif defined(USE_SECTRANSP)
91
92# include <CommonCrypto/CommonCryptor.h>
93# include <CommonCrypto/CommonDigest.h>
94
95#elif defined(USE_OS400CRYPTO)
96# include "cipher.mih" /* mih/cipher */
97#elif defined(USE_WIN32_CRYPTO)
98# include <wincrypt.h>
99#else
100# error "Can't compile NTLM support without a crypto library."
101#endif
102
103#include "urldata.h"
104#include "non-ascii.h"
105#include "strcase.h"
106#include "curl_ntlm_core.h"
107#include "curl_md5.h"
108#include "curl_hmac.h"
109#include "warnless.h"
110#include "curl_endian.h"
111#include "curl_des.h"
112#include "curl_md4.h"
113/* The last 3 #include files should be in this order */
114#include "curl_printf.h"
115#include "curl_memory.h"
116#include "memdebug.h"
117
118#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
119#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
120
121/*
122* Turns a 56-bit key into being 64-bit wide.
123*/
124static void extend_key_56_to_64(const unsigned char *key_56, char *key)
125{
126 key[0] = key_56[0];
127 key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
128 key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
129 key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
130 key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
131 key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
132 key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
133 key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
134}
135
136#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
137/*
138 * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
139 * key schedule ks is also set.
140 */
141static void setup_des_key(const unsigned char *key_56,
142 DES_key_schedule DESKEYARG(ks))
143{
144 DES_cblock key;
145
146 /* Expand the 56-bit key to 64-bits */
147 extend_key_56_to_64(key_56, (char *) &key);
148
149 /* Set the key parity to odd */
150 DES_set_odd_parity(&key);
151
152 /* Set the key */
153 DES_set_key(&key, ks);
154}
155
156#elif defined(USE_GNUTLS)
157
158static void setup_des_key(const unsigned char *key_56,
159 struct des_ctx *des)
160{
161 char key[8];
162
163 /* Expand the 56-bit key to 64-bits */
164 extend_key_56_to_64(key_56, key);
165
166 /* Set the key parity to odd */
167 Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
168
169 /* Set the key */
170 des_set_key(des, (const uint8_t *) key);
171}
172
173#elif defined(USE_NSS)
174
175/*
176 * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
177 * the expanded key. The caller is responsible for giving 64 bit of valid
178 * data is IN and (at least) 64 bit large buffer as OUT.
179 */
180static bool encrypt_des(const unsigned char *in, unsigned char *out,
181 const unsigned char *key_56)
182{
183 const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
184 char key[8]; /* expanded 64 bit key */
185 SECItem key_item;
186 PK11SymKey *symkey = NULL;
187 SECItem *param = NULL;
188 PK11Context *ctx = NULL;
189 int out_len; /* not used, required by NSS */
190 bool rv = FALSE;
191
192 /* use internal slot for DES encryption (requires NSS to be initialized) */
193 PK11SlotInfo *slot = PK11_GetInternalKeySlot();
194 if(!slot)
195 return FALSE;
196
197 /* Expand the 56-bit key to 64-bits */
198 extend_key_56_to_64(key_56, key);
199
200 /* Set the key parity to odd */
201 Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
202
203 /* Import the key */
204 key_item.data = (unsigned char *)key;
205 key_item.len = sizeof(key);
206 symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
207 &key_item, NULL);
208 if(!symkey)
209 goto fail;
210
211 /* Create the DES encryption context */
212 param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
213 if(!param)
214 goto fail;
215 ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
216 if(!ctx)
217 goto fail;
218
219 /* Perform the encryption */
220 if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
221 (unsigned char *)in, /* inbuflen */ 8)
222 && SECSuccess == PK11_Finalize(ctx))
223 rv = /* all OK */ TRUE;
224
225fail:
226 /* cleanup */
227 if(ctx)
228 PK11_DestroyContext(ctx, PR_TRUE);
229 if(symkey)
230 PK11_FreeSymKey(symkey);
231 if(param)
232 SECITEM_FreeItem(param, PR_TRUE);
233 PK11_FreeSlot(slot);
234 return rv;
235}
236
237#elif defined(USE_MBEDTLS)
238
239static bool encrypt_des(const unsigned char *in, unsigned char *out,
240 const unsigned char *key_56)
241{
242 mbedtls_des_context ctx;
243 char key[8];
244
245 /* Expand the 56-bit key to 64-bits */
246 extend_key_56_to_64(key_56, key);
247
248 /* Set the key parity to odd */
249 mbedtls_des_key_set_parity((unsigned char *) key);
250
251 /* Perform the encryption */
252 mbedtls_des_init(&ctx);
253 mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
254 return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
255}
256
257#elif defined(USE_SECTRANSP)
258
259static bool encrypt_des(const unsigned char *in, unsigned char *out,
260 const unsigned char *key_56)
261{
262 char key[8];
263 size_t out_len;
264 CCCryptorStatus err;
265
266 /* Expand the 56-bit key to 64-bits */
267 extend_key_56_to_64(key_56, key);
268
269 /* Set the key parity to odd */
270 Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
271
272 /* Perform the encryption */
273 err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
274 kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
275 8 /* outbuflen */, &out_len);
276
277 return err == kCCSuccess;
278}
279
280#elif defined(USE_OS400CRYPTO)
281
282static bool encrypt_des(const unsigned char *in, unsigned char *out,
283 const unsigned char *key_56)
284{
285 char key[8];
286 _CIPHER_Control_T ctl;
287
288 /* Setup the cipher control structure */
289 ctl.Func_ID = ENCRYPT_ONLY;
290 ctl.Data_Len = sizeof(key);
291
292 /* Expand the 56-bit key to 64-bits */
293 extend_key_56_to_64(key_56, ctl.Crypto_Key);
294
295 /* Set the key parity to odd */
296 Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
297
298 /* Perform the encryption */
299 _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
300
301 return TRUE;
302}
303
304#elif defined(USE_WIN32_CRYPTO)
305
306static bool encrypt_des(const unsigned char *in, unsigned char *out,
307 const unsigned char *key_56)
308{
309 HCRYPTPROV hprov;
310 HCRYPTKEY hkey;
311 struct {
312 BLOBHEADER hdr;
313 unsigned int len;
314 char key[8];
315 } blob;
316 DWORD len = 8;
317
318 /* Acquire the crypto provider */
319 if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
320 CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
321 return FALSE;
322
323 /* Setup the key blob structure */
324 memset(&blob, 0, sizeof(blob));
325 blob.hdr.bType = PLAINTEXTKEYBLOB;
326 blob.hdr.bVersion = 2;
327 blob.hdr.aiKeyAlg = CALG_DES;
328 blob.len = sizeof(blob.key);
329
330 /* Expand the 56-bit key to 64-bits */
331 extend_key_56_to_64(key_56, blob.key);
332
333 /* Set the key parity to odd */
334 Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
335
336 /* Import the key */
337 if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
338 CryptReleaseContext(hprov, 0);
339
340 return FALSE;
341 }
342
343 memcpy(out, in, 8);
344
345 /* Perform the encryption */
346 CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
347
348 CryptDestroyKey(hkey);
349 CryptReleaseContext(hprov, 0);
350
351 return TRUE;
352}
353
354#endif /* defined(USE_WIN32_CRYPTO) */
355
356 /*
357 * takes a 21 byte array and treats it as 3 56-bit DES keys. The
358 * 8 byte plaintext is encrypted with each key and the resulting 24
359 * bytes are stored in the results array.
360 */
361void Curl_ntlm_core_lm_resp(const unsigned char *keys,
362 const unsigned char *plaintext,
363 unsigned char *results)
364{
365#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
366 DES_key_schedule ks;
367
368 setup_des_key(keys, DESKEY(ks));
369 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
370 DESKEY(ks), DES_ENCRYPT);
371
372 setup_des_key(keys + 7, DESKEY(ks));
373 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
374 DESKEY(ks), DES_ENCRYPT);
375
376 setup_des_key(keys + 14, DESKEY(ks));
377 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
378 DESKEY(ks), DES_ENCRYPT);
379#elif defined(USE_GNUTLS)
380 struct des_ctx des;
381 setup_des_key(keys, &des);
382 des_encrypt(&des, 8, results, plaintext);
383 setup_des_key(keys + 7, &des);
384 des_encrypt(&des, 8, results + 8, plaintext);
385 setup_des_key(keys + 14, &des);
386 des_encrypt(&des, 8, results + 16, plaintext);
387#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
388 || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
389 encrypt_des(plaintext, results, keys);
390 encrypt_des(plaintext, results + 8, keys + 7);
391 encrypt_des(plaintext, results + 16, keys + 14);
392#endif
393}
394
395/*
396 * Set up lanmanager hashed password
397 */
398CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
399 const char *password,
400 unsigned char *lmbuffer /* 21 bytes */)
401{
402 CURLcode result;
403 unsigned char pw[14];
404 static const unsigned char magic[] = {
405 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
406 };
407 size_t len = CURLMIN(strlen(password), 14);
408
409 Curl_strntoupper((char *)pw, password, len);
410 memset(&pw[len], 0, 14 - len);
411
412 /*
413 * The LanManager hashed password needs to be created using the
414 * password in the network encoding not the host encoding.
415 */
416 result = Curl_convert_to_network(data, (char *)pw, 14);
417 if(result)
418 return result;
419
420 {
421 /* Create LanManager hashed password. */
422
423#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
424 DES_key_schedule ks;
425
426 setup_des_key(pw, DESKEY(ks));
427 DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
428 DESKEY(ks), DES_ENCRYPT);
429
430 setup_des_key(pw + 7, DESKEY(ks));
431 DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
432 DESKEY(ks), DES_ENCRYPT);
433#elif defined(USE_GNUTLS)
434 struct des_ctx des;
435 setup_des_key(pw, &des);
436 des_encrypt(&des, 8, lmbuffer, magic);
437 setup_des_key(pw + 7, &des);
438 des_encrypt(&des, 8, lmbuffer + 8, magic);
439#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
440 || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
441 encrypt_des(magic, lmbuffer, pw);
442 encrypt_des(magic, lmbuffer + 8, pw + 7);
443#endif
444
445 memset(lmbuffer + 16, 0, 21 - 16);
446 }
447
448 return CURLE_OK;
449}
450
451#ifdef USE_NTRESPONSES
452static void ascii_to_unicode_le(unsigned char *dest, const char *src,
453 size_t srclen)
454{
455 size_t i;
456 for(i = 0; i < srclen; i++) {
457 dest[2 * i] = (unsigned char)src[i];
458 dest[2 * i + 1] = '\0';
459 }
460}
461
462#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
463
464static void ascii_uppercase_to_unicode_le(unsigned char *dest,
465 const char *src, size_t srclen)
466{
467 size_t i;
468 for(i = 0; i < srclen; i++) {
469 dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i]));
470 dest[2 * i + 1] = '\0';
471 }
472}
473
474#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
475
476/*
477 * Set up nt hashed passwords
478 * @unittest: 1600
479 */
480CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
481 const char *password,
482 unsigned char *ntbuffer /* 21 bytes */)
483{
484 size_t len = strlen(password);
485 unsigned char *pw;
486 CURLcode result;
487 if(len > SIZE_T_MAX/2) /* avoid integer overflow */
488 return CURLE_OUT_OF_MEMORY;
489 pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
490 if(!pw)
491 return CURLE_OUT_OF_MEMORY;
492
493 ascii_to_unicode_le(pw, password, len);
494
495 /*
496 * The NT hashed password needs to be created using the password in the
497 * network encoding not the host encoding.
498 */
499 result = Curl_convert_to_network(data, (char *)pw, len * 2);
500 if(!result) {
501 /* Create NT hashed password. */
502 Curl_md4it(ntbuffer, pw, 2 * len);
503 memset(ntbuffer + 16, 0, 21 - 16);
504 }
505 free(pw);
506
507 return result;
508}
509
510#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
511
512/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
513struct ms_filetime {
514 unsigned int dwLowDateTime;
515 unsigned int dwHighDateTime;
516};
517
518/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */
519static void time2filetime(struct ms_filetime *ft, time_t t)
520{
521#if SIZEOF_TIME_T > 4
522 t = (t + CURL_OFF_T_C(11644473600)) * 10000000;
523 ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF);
524 ft->dwHighDateTime = (unsigned int) (t >> 32);
525#else
526 unsigned int r, s;
527 unsigned int i;
528
529 ft->dwLowDateTime = t & 0xFFFFFFFF;
530 ft->dwHighDateTime = 0;
531
532# ifndef HAVE_TIME_T_UNSIGNED
533 /* Extend sign if needed. */
534 if(ft->dwLowDateTime & 0x80000000)
535 ft->dwHighDateTime = ~0;
536# endif
537
538 /* Bias seconds to Jan 1, 1601.
539 134774 days = 11644473600 seconds = 0x2B6109100 */
540 r = ft->dwLowDateTime;
541 ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
542 ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02;
543
544 /* Convert to tenths of microseconds. */
545 ft->dwHighDateTime *= 10000000;
546 i = 32;
547 do {
548 i -= 8;
549 s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1);
550 r = (s << i) & 0xFFFFFFFF;
551 s >>= 1; /* Split shift to avoid width overflow. */
552 s >>= 31 - i;
553 ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF;
554 if(ft->dwLowDateTime < r)
555 s++;
556 ft->dwHighDateTime += s;
557 } while(i);
558 ft->dwHighDateTime &= 0xFFFFFFFF;
559#endif
560}
561
562/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
563 * (uppercase UserName + Domain) as the data
564 */
565CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
566 const char *domain, size_t domlen,
567 unsigned char *ntlmhash,
568 unsigned char *ntlmv2hash)
569{
570 /* Unicode representation */
571 size_t identity_len;
572 unsigned char *identity;
573 CURLcode result = CURLE_OK;
574
575 if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH))
576 return CURLE_OUT_OF_MEMORY;
577
578 identity_len = (userlen + domlen) * 2;
579 identity = malloc(identity_len + 1);
580
581 if(!identity)
582 return CURLE_OUT_OF_MEMORY;
583
584 ascii_uppercase_to_unicode_le(identity, user, userlen);
585 ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
586
587 result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
588 ntlmv2hash);
589 free(identity);
590
591 return result;
592}
593
594/*
595 * Curl_ntlm_core_mk_ntlmv2_resp()
596 *
597 * This creates the NTLMv2 response as set in the ntlm type-3 message.
598 *
599 * Parameters:
600 *
601 * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
602 * challenge_client [in] - The client nonce (8 bytes)
603 * ntlm [in] - The ntlm data struct being used to read TargetInfo
604 and Server challenge received in the type-2 message
605 * ntresp [out] - The address where a pointer to newly allocated
606 * memory holding the NTLMv2 response.
607 * ntresp_len [out] - The length of the output message.
608 *
609 * Returns CURLE_OK on success.
610 */
611CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
612 unsigned char *challenge_client,
613 struct ntlmdata *ntlm,
614 unsigned char **ntresp,
615 unsigned int *ntresp_len)
616{
617/* NTLMv2 response structure :
618------------------------------------------------------------------------------
6190 HMAC MD5 16 bytes
620------BLOB--------------------------------------------------------------------
62116 Signature 0x01010000
62220 Reserved long (0x00000000)
62324 Timestamp LE, 64-bit signed value representing the number of
624 tenths of a microsecond since January 1, 1601.
62532 Client Nonce 8 bytes
62640 Unknown 4 bytes
62744 Target Info N bytes (from the type-2 message)
62844+N Unknown 4 bytes
629------------------------------------------------------------------------------
630*/
631
632 unsigned int len = 0;
633 unsigned char *ptr = NULL;
634 unsigned char hmac_output[HMAC_MD5_LENGTH];
635 struct ms_filetime tw;
636
637 CURLcode result = CURLE_OK;
638
639 /* Calculate the timestamp */
640#ifdef DEBUGBUILD
641 char *force_timestamp = getenv("CURL_FORCETIME");
642 if(force_timestamp)
643 time2filetime(&tw, (time_t) 0);
644 else
645#endif
646 time2filetime(&tw, time(NULL));
647
648 /* Calculate the response len */
649 len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
650
651 /* Allocate the response */
652 ptr = calloc(1, len);
653 if(!ptr)
654 return CURLE_OUT_OF_MEMORY;
655
656 /* Create the BLOB structure */
657 msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
658 "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
659 "%c%c%c%c" /* Reserved = 0 */
660 "%c%c%c%c%c%c%c%c", /* Timestamp */
661 NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
662 NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
663 0, 0, 0, 0,
664 LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime));
665
666 memcpy(ptr + 32, challenge_client, 8);
667 memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
668
669 /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
670 memcpy(ptr + 8, &ntlm->nonce[0], 8);
671 result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
672 NTLMv2_BLOB_LEN + 8, hmac_output);
673 if(result) {
674 free(ptr);
675 return result;
676 }
677
678 /* Concatenate the HMAC MD5 output with the BLOB */
679 memcpy(ptr, hmac_output, HMAC_MD5_LENGTH);
680
681 /* Return the response */
682 *ntresp = ptr;
683 *ntresp_len = len;
684
685 return result;
686}
687
688/*
689 * Curl_ntlm_core_mk_lmv2_resp()
690 *
691 * This creates the LMv2 response as used in the ntlm type-3 message.
692 *
693 * Parameters:
694 *
695 * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
696 * challenge_client [in] - The client nonce (8 bytes)
697 * challenge_client [in] - The server challenge (8 bytes)
698 * lmresp [out] - The LMv2 response (24 bytes)
699 *
700 * Returns CURLE_OK on success.
701 */
702CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
703 unsigned char *challenge_client,
704 unsigned char *challenge_server,
705 unsigned char *lmresp)
706{
707 unsigned char data[16];
708 unsigned char hmac_output[16];
709 CURLcode result = CURLE_OK;
710
711 memcpy(&data[0], challenge_server, 8);
712 memcpy(&data[8], challenge_client, 8);
713
714 result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
715 hmac_output);
716 if(result)
717 return result;
718
719 /* Concatenate the HMAC MD5 output with the client nonce */
720 memcpy(lmresp, hmac_output, 16);
721 memcpy(lmresp + 16, challenge_client, 8);
722
723 return result;
724}
725
726#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
727
728#endif /* USE_NTRESPONSES */
729
730#endif /* USE_CURL_NTLM_CORE */
731