• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 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  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 
25 #include "curl_setup.h"
26 
27 #if defined(USE_CURL_NTLM_CORE)
28 
29 #include <string.h>
30 
31 #include "strdup.h"
32 #include "curl_md4.h"
33 #include "warnless.h"
34 
35 #ifdef USE_OPENSSL
36 #include <openssl/opensslv.h>
37 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) && !defined(USE_AMISSL)
38 /* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
39 #define OPENSSL_NO_MD4
40 #else
41 /* Cover also OPENSSL_NO_MD4 configured in openssl */
42 #include <openssl/opensslconf.h>
43 #endif
44 #endif /* USE_OPENSSL */
45 
46 #ifdef USE_WOLFSSL
47 #include <wolfssl/options.h>
48 #define VOID_MD4_INIT
49 #ifdef NO_MD4
50 #define WOLFSSL_NO_MD4
51 #endif
52 #endif
53 
54 #ifdef USE_MBEDTLS
55 #include <mbedtls/version.h>
56 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
57 #include <mbedtls/mbedtls_config.h>
58 #else
59 #include <mbedtls/config.h>
60 #endif
61 #if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
62    (MBEDTLS_VERSION_NUMBER < 0x03000000)
63   #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
64 #endif
65 #endif /* USE_MBEDTLS */
66 
67 #if defined(USE_GNUTLS)
68 #include <nettle/md4.h>
69 /* When OpenSSL or wolfSSL is available, we use their MD4 functions. */
70 #elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
71 #include <wolfssl/openssl/md4.h>
72 #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
73 #include <openssl/md4.h>
74 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
75               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
76        defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
77               (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \
78       (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
79               (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \
80        defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
81               (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000))
82 #define AN_APPLE_OS
83 #include <CommonCrypto/CommonDigest.h>
84 #elif defined(USE_WIN32_CRYPTO)
85 #include <wincrypt.h>
86 #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
87 #include <mbedtls/md4.h>
88 #endif
89 
90 /* The last 3 #include files should be in this order */
91 #include "curl_printf.h"
92 #include "curl_memory.h"
93 #include "memdebug.h"
94 
95 
96 #if defined(USE_GNUTLS)
97 
98 typedef struct md4_ctx MD4_CTX;
99 
MD4_Init(MD4_CTX * ctx)100 static int MD4_Init(MD4_CTX *ctx)
101 {
102   md4_init(ctx);
103   return 1;
104 }
105 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)106 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
107 {
108   md4_update(ctx, size, data);
109 }
110 
MD4_Final(unsigned char * result,MD4_CTX * ctx)111 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
112 {
113   md4_digest(ctx, MD4_DIGEST_SIZE, result);
114 }
115 
116 #elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
117 
118 #ifdef OPENSSL_COEXIST
119   #define MD4_CTX WOLFSSL_MD4_CTX
120   #define MD4_Init wolfSSL_MD4_Init
121   #define MD4_Update wolfSSL_MD4_Update
122   #define MD4_Final wolfSSL_MD4_Final
123 #endif
124 
125 #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
126 
127 #elif defined(AN_APPLE_OS)
128 typedef CC_MD4_CTX MD4_CTX;
129 
MD4_Init(MD4_CTX * ctx)130 static int MD4_Init(MD4_CTX *ctx)
131 {
132   return CC_MD4_Init(ctx);
133 }
134 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)135 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
136 {
137   (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
138 }
139 
MD4_Final(unsigned char * result,MD4_CTX * ctx)140 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
141 {
142   (void)CC_MD4_Final(result, ctx);
143 }
144 
145 #elif defined(USE_WIN32_CRYPTO)
146 
147 struct md4_ctx {
148   HCRYPTPROV hCryptProv;
149   HCRYPTHASH hHash;
150 };
151 typedef struct md4_ctx MD4_CTX;
152 
MD4_Init(MD4_CTX * ctx)153 static int MD4_Init(MD4_CTX *ctx)
154 {
155   ctx->hCryptProv = 0;
156   ctx->hHash = 0;
157 
158   if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
159                           CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
160     return 0;
161 
162   if(!CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash)) {
163     CryptReleaseContext(ctx->hCryptProv, 0);
164     ctx->hCryptProv = 0;
165     return 0;
166   }
167 
168   return 1;
169 }
170 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)171 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
172 {
173   CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
174 }
175 
MD4_Final(unsigned char * result,MD4_CTX * ctx)176 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
177 {
178   unsigned long length = 0;
179 
180   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
181   if(length == MD4_DIGEST_LENGTH)
182     CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
183 
184   if(ctx->hHash)
185     CryptDestroyHash(ctx->hHash);
186 
187   if(ctx->hCryptProv)
188     CryptReleaseContext(ctx->hCryptProv, 0);
189 }
190 
191 #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
192 
193 struct md4_ctx {
194   void *data;
195   unsigned long size;
196 };
197 typedef struct md4_ctx MD4_CTX;
198 
MD4_Init(MD4_CTX * ctx)199 static int MD4_Init(MD4_CTX *ctx)
200 {
201   ctx->data = NULL;
202   ctx->size = 0;
203   return 1;
204 }
205 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)206 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
207 {
208   if(!ctx->data) {
209     ctx->data = Curl_memdup(data, size);
210     if(ctx->data)
211       ctx->size = size;
212   }
213 }
214 
MD4_Final(unsigned char * result,MD4_CTX * ctx)215 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
216 {
217   if(ctx->data) {
218 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
219     mbedtls_md4(ctx->data, ctx->size, result);
220 #else
221     (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
222 #endif
223 
224     Curl_safefree(ctx->data);
225     ctx->size = 0;
226   }
227 }
228 
229 #else
230 /* When no other crypto library is available, or the crypto library does not
231  * support MD4, we use this code segment this implementation of it
232  *
233  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
234  * MD4 Message-Digest Algorithm (RFC 1320).
235  *
236  * Homepage:
237  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
238  *
239  * Author:
240  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
241  *
242  * This software was written by Alexander Peslyak in 2001. No copyright is
243  * claimed, and the software is hereby placed in the public domain. In case
244  * this attempt to disclaim copyright and place the software in the public
245  * domain is deemed null and void, then the software is Copyright (c) 2001
246  * Alexander Peslyak and it is hereby released to the general public under the
247  * following terms:
248  *
249  * Redistribution and use in source and binary forms, with or without
250  * modification, are permitted.
251  *
252  * There is ABSOLUTELY NO WARRANTY, express or implied.
253  *
254  * (This is a heavily cut-down "BSD license".)
255  *
256  * This differs from Colin Plumb's older public domain implementation in that
257  * no exactly 32-bit integer data type is required (any 32-bit or wider
258  * unsigned integer data type will do), there is no compile-time endianness
259  * configuration, and the function prototypes match OpenSSL's. No code from
260  * Colin Plumb's implementation has been reused; this comment merely compares
261  * the properties of the two independent implementations.
262  *
263  * The primary goals of this implementation are portability and ease of use.
264  * It is meant to be fast, but not as fast as possible. Some known
265  * optimizations are not included to reduce source code size and avoid
266  * compile-time configuration.
267  */
268 
269 /* Any 32-bit or wider unsigned integer data type will do */
270 typedef unsigned int MD4_u32plus;
271 
272 struct md4_ctx {
273   MD4_u32plus lo, hi;
274   MD4_u32plus a, b, c, d;
275   unsigned char buffer[64];
276   MD4_u32plus block[16];
277 };
278 typedef struct md4_ctx MD4_CTX;
279 
280 static int MD4_Init(MD4_CTX *ctx);
281 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
282 static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
283 
284 /*
285  * The basic MD4 functions.
286  *
287  * F and G are optimized compared to their RFC 1320 definitions, with the
288  * optimization for F borrowed from Colin Plumb's MD5 implementation.
289  */
290 #define MD4_F(x, y, z)                  ((z) ^ ((x) & ((y) ^ (z))))
291 #define MD4_G(x, y, z)                  (((x) & ((y) | (z))) | ((y) & (z)))
292 #define MD4_H(x, y, z)                  ((x) ^ (y) ^ (z))
293 
294 /*
295  * The MD4 transformation for all three rounds.
296  */
297 #define MD4_STEP(f, a, b, c, d, x, s) \
298         (a) += f((b), (c), (d)) + (x); \
299         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
300 
301 /*
302  * SET reads 4 input bytes in little-endian byte order and stores them
303  * in a properly aligned word in host byte order.
304  *
305  * The check for little-endian architectures that tolerate unaligned
306  * memory accesses is just an optimization. Nothing will break if it
307  * does not work.
308  */
309 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
310 #define MD4_SET(n) \
311         (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
312 #define MD4_GET(n) \
313         MD4_SET(n)
314 #else
315 #define MD4_SET(n) \
316         (ctx->block[(n)] = \
317         (MD4_u32plus)ptr[(n) * 4] | \
318         ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
319         ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
320         ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
321 #define MD4_GET(n) \
322         (ctx->block[(n)])
323 #endif
324 
325 /*
326  * This processes one or more 64-byte data blocks, but does NOT update
327  * the bit counters. There are no alignment requirements.
328  */
my_md4_body(MD4_CTX * ctx,const void * data,unsigned long size)329 static const void *my_md4_body(MD4_CTX *ctx,
330                                const void *data, unsigned long size)
331 {
332   const unsigned char *ptr;
333   MD4_u32plus a, b, c, d;
334 
335   ptr = (const unsigned char *)data;
336 
337   a = ctx->a;
338   b = ctx->b;
339   c = ctx->c;
340   d = ctx->d;
341 
342   do {
343     MD4_u32plus saved_a, saved_b, saved_c, saved_d;
344 
345     saved_a = a;
346     saved_b = b;
347     saved_c = c;
348     saved_d = d;
349 
350 /* Round 1 */
351     MD4_STEP(MD4_F, a, b, c, d, MD4_SET(0), 3)
352     MD4_STEP(MD4_F, d, a, b, c, MD4_SET(1), 7)
353     MD4_STEP(MD4_F, c, d, a, b, MD4_SET(2), 11)
354     MD4_STEP(MD4_F, b, c, d, a, MD4_SET(3), 19)
355     MD4_STEP(MD4_F, a, b, c, d, MD4_SET(4), 3)
356     MD4_STEP(MD4_F, d, a, b, c, MD4_SET(5), 7)
357     MD4_STEP(MD4_F, c, d, a, b, MD4_SET(6), 11)
358     MD4_STEP(MD4_F, b, c, d, a, MD4_SET(7), 19)
359     MD4_STEP(MD4_F, a, b, c, d, MD4_SET(8), 3)
360     MD4_STEP(MD4_F, d, a, b, c, MD4_SET(9), 7)
361     MD4_STEP(MD4_F, c, d, a, b, MD4_SET(10), 11)
362     MD4_STEP(MD4_F, b, c, d, a, MD4_SET(11), 19)
363     MD4_STEP(MD4_F, a, b, c, d, MD4_SET(12), 3)
364     MD4_STEP(MD4_F, d, a, b, c, MD4_SET(13), 7)
365     MD4_STEP(MD4_F, c, d, a, b, MD4_SET(14), 11)
366     MD4_STEP(MD4_F, b, c, d, a, MD4_SET(15), 19)
367 
368 /* Round 2 */
369     MD4_STEP(MD4_G, a, b, c, d, MD4_GET(0) + 0x5a827999, 3)
370     MD4_STEP(MD4_G, d, a, b, c, MD4_GET(4) + 0x5a827999, 5)
371     MD4_STEP(MD4_G, c, d, a, b, MD4_GET(8) + 0x5a827999, 9)
372     MD4_STEP(MD4_G, b, c, d, a, MD4_GET(12) + 0x5a827999, 13)
373     MD4_STEP(MD4_G, a, b, c, d, MD4_GET(1) + 0x5a827999, 3)
374     MD4_STEP(MD4_G, d, a, b, c, MD4_GET(5) + 0x5a827999, 5)
375     MD4_STEP(MD4_G, c, d, a, b, MD4_GET(9) + 0x5a827999, 9)
376     MD4_STEP(MD4_G, b, c, d, a, MD4_GET(13) + 0x5a827999, 13)
377     MD4_STEP(MD4_G, a, b, c, d, MD4_GET(2) + 0x5a827999, 3)
378     MD4_STEP(MD4_G, d, a, b, c, MD4_GET(6) + 0x5a827999, 5)
379     MD4_STEP(MD4_G, c, d, a, b, MD4_GET(10) + 0x5a827999, 9)
380     MD4_STEP(MD4_G, b, c, d, a, MD4_GET(14) + 0x5a827999, 13)
381     MD4_STEP(MD4_G, a, b, c, d, MD4_GET(3) + 0x5a827999, 3)
382     MD4_STEP(MD4_G, d, a, b, c, MD4_GET(7) + 0x5a827999, 5)
383     MD4_STEP(MD4_G, c, d, a, b, MD4_GET(11) + 0x5a827999, 9)
384     MD4_STEP(MD4_G, b, c, d, a, MD4_GET(15) + 0x5a827999, 13)
385 
386 /* Round 3 */
387     MD4_STEP(MD4_H, a, b, c, d, MD4_GET(0) + 0x6ed9eba1, 3)
388     MD4_STEP(MD4_H, d, a, b, c, MD4_GET(8) + 0x6ed9eba1, 9)
389     MD4_STEP(MD4_H, c, d, a, b, MD4_GET(4) + 0x6ed9eba1, 11)
390     MD4_STEP(MD4_H, b, c, d, a, MD4_GET(12) + 0x6ed9eba1, 15)
391     MD4_STEP(MD4_H, a, b, c, d, MD4_GET(2) + 0x6ed9eba1, 3)
392     MD4_STEP(MD4_H, d, a, b, c, MD4_GET(10) + 0x6ed9eba1, 9)
393     MD4_STEP(MD4_H, c, d, a, b, MD4_GET(6) + 0x6ed9eba1, 11)
394     MD4_STEP(MD4_H, b, c, d, a, MD4_GET(14) + 0x6ed9eba1, 15)
395     MD4_STEP(MD4_H, a, b, c, d, MD4_GET(1) + 0x6ed9eba1, 3)
396     MD4_STEP(MD4_H, d, a, b, c, MD4_GET(9) + 0x6ed9eba1, 9)
397     MD4_STEP(MD4_H, c, d, a, b, MD4_GET(5) + 0x6ed9eba1, 11)
398     MD4_STEP(MD4_H, b, c, d, a, MD4_GET(13) + 0x6ed9eba1, 15)
399     MD4_STEP(MD4_H, a, b, c, d, MD4_GET(3) + 0x6ed9eba1, 3)
400     MD4_STEP(MD4_H, d, a, b, c, MD4_GET(11) + 0x6ed9eba1, 9)
401     MD4_STEP(MD4_H, c, d, a, b, MD4_GET(7) + 0x6ed9eba1, 11)
402     MD4_STEP(MD4_H, b, c, d, a, MD4_GET(15) + 0x6ed9eba1, 15)
403 
404     a += saved_a;
405     b += saved_b;
406     c += saved_c;
407     d += saved_d;
408 
409     ptr += 64;
410   } while(size -= 64);
411 
412   ctx->a = a;
413   ctx->b = b;
414   ctx->c = c;
415   ctx->d = d;
416 
417   return ptr;
418 }
419 
MD4_Init(MD4_CTX * ctx)420 static int MD4_Init(MD4_CTX *ctx)
421 {
422   ctx->a = 0x67452301;
423   ctx->b = 0xefcdab89;
424   ctx->c = 0x98badcfe;
425   ctx->d = 0x10325476;
426 
427   ctx->lo = 0;
428   ctx->hi = 0;
429   return 1;
430 }
431 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)432 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
433 {
434   MD4_u32plus saved_lo;
435   unsigned long used;
436 
437   saved_lo = ctx->lo;
438   ctx->lo = (saved_lo + size) & 0x1fffffff;
439   if(ctx->lo < saved_lo)
440     ctx->hi++;
441   ctx->hi += (MD4_u32plus)size >> 29;
442 
443   used = saved_lo & 0x3f;
444 
445   if(used) {
446     unsigned long available = 64 - used;
447 
448     if(size < available) {
449       memcpy(&ctx->buffer[used], data, size);
450       return;
451     }
452 
453     memcpy(&ctx->buffer[used], data, available);
454     data = (const unsigned char *)data + available;
455     size -= available;
456     my_md4_body(ctx, ctx->buffer, 64);
457   }
458 
459   if(size >= 64) {
460     data = my_md4_body(ctx, data, size & ~(unsigned long)0x3f);
461     size &= 0x3f;
462   }
463 
464   memcpy(ctx->buffer, data, size);
465 }
466 
MD4_Final(unsigned char * result,MD4_CTX * ctx)467 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
468 {
469   unsigned long used, available;
470 
471   used = ctx->lo & 0x3f;
472 
473   ctx->buffer[used++] = 0x80;
474 
475   available = 64 - used;
476 
477   if(available < 8) {
478     memset(&ctx->buffer[used], 0, available);
479     my_md4_body(ctx, ctx->buffer, 64);
480     used = 0;
481     available = 64;
482   }
483 
484   memset(&ctx->buffer[used], 0, available - 8);
485 
486   ctx->lo <<= 3;
487   ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
488   ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
489   ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
490   ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
491   ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
492   ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
493   ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
494   ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
495 
496   my_md4_body(ctx, ctx->buffer, 64);
497 
498   result[0] = curlx_ultouc((ctx->a)&0xff);
499   result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
500   result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
501   result[3] = curlx_ultouc(ctx->a >> 24);
502   result[4] = curlx_ultouc((ctx->b)&0xff);
503   result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
504   result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
505   result[7] = curlx_ultouc(ctx->b >> 24);
506   result[8] = curlx_ultouc((ctx->c)&0xff);
507   result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
508   result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
509   result[11] = curlx_ultouc(ctx->c >> 24);
510   result[12] = curlx_ultouc((ctx->d)&0xff);
511   result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
512   result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
513   result[15] = curlx_ultouc(ctx->d >> 24);
514 
515   memset(ctx, 0, sizeof(*ctx));
516 }
517 
518 #endif /* CRYPTO LIBS */
519 
Curl_md4it(unsigned char * output,const unsigned char * input,const size_t len)520 CURLcode Curl_md4it(unsigned char *output, const unsigned char *input,
521                     const size_t len)
522 {
523   MD4_CTX ctx;
524 
525 #ifdef VOID_MD4_INIT
526   MD4_Init(&ctx);
527 #else
528   if(!MD4_Init(&ctx))
529     return CURLE_FAILED_INIT;
530 #endif
531 
532   MD4_Update(&ctx, input, curlx_uztoui(len));
533   MD4_Final(output, &ctx);
534   return CURLE_OK;
535 }
536 
537 #endif /* USE_CURL_NTLM_CORE */
538