2 * Copyright (c) 2000-2004,2006-2008,2010,2013 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * ntlmBlobPriv.h - Private routines used by NtlmGenerator module.
28 #ifndef _NTLM_BLOB_PRIV_H_
29 #define _NTLM_BLOB_PRIV_H_
31 #include <CoreFoundation/CFData.h>
32 #include <CoreFoundation/CFString.h>
34 #include <Security/SecBase.h>
35 #include <Security/SecBasePriv.h>
36 #include <libkern/OSByteOrder.h>
46 #define dprintf(args...) printf(args)
48 #define dprintf(args...)
52 * Common error returns.
54 * This one for "I don't understand the server blob".
56 #define NTLM_ERR_PARSE_ERR errSecParam
59 * This one for protocol variant mismatch (e.g., app requires NTLMv2 but server
60 * doesn't accept that).
62 #define NTLM_ERR_PROTOCOL_MISMATCH errSecAuthFailed
65 * For debugging using fixed pamaters via sourceforge "test vectors".
67 #define DEBUG_FIXED_CHALLENGE 0
69 /* handy portable NULL-tolerant free() */
70 #define CFREE(p) if(p != NULL) { free(p); }
72 #define NTLM_SIGNATURE "NTLMSSP"
73 #define NTLM_SIGNATURE_LEN 8 /* including NULL! */
75 #define NTLM_MSG_MARKER_TYPE1 1 /* first client msg */
76 #define NTLM_MSG_MARKER_TYPE2 2 /* server challenge */
77 #define NTLM_MSG_MARKER_TYPE3 3 /* client response */
79 /* Size of a security buffer */
80 #define NTLM_SIZEOF_SEC_BUF (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t))
82 /* length of server challenge in bytes */
83 #define NTLM_CHALLENGE_LEN 8
85 /* length of client nonce in bytes */
86 #define NTLM_CLIENT_NONCE_LEN 8
88 /* length of LM and NTLM responses */
89 #define NTLM_LM_RESPONSE_LEN 24
91 /* foreced length of LM-style uppper case password */
92 #define NTLM_LM_PASSWORD_LEN 14
95 * Flags - defined here in native endianness; sent over the wire little-endian
97 #define NTLM_NegotiateUnicode 0x00000001
98 #define NTLM_NegotiateOEM 0x00000002
99 #define NTLM_RequestTarget 0x00000004
100 #define NTLM_Unknown1 0x00000008
101 #define NTLM_NegotiateSign 0x00000010
102 #define NTLM_NegotiateSeal 0x00000020
103 #define NTLM_NegotiateDatagram 0x00000040
104 #define NTLM_NegotiateLMKey 0x00000080
105 #define NTLM_NegotiateNetware 0x00000100
106 #define NTLM_NegotiateNTLM 0x00000200
107 #define NTLM_Unknown2 0x00000400
108 #define NTLM_Unknown3 0x00000800
109 #define NTLM_DomainSupplied 0x00001000
110 #define NTLM_WorkstationSupplies 0x00002000
111 #define NTLM_LocalCall 0x00004000
112 #define NTLM_AlwaysSign 0x00008000
113 #define NTLM_TargetTypeDomain 0x00010000
114 #define NTLM_TargetTypeServer 0x00020000
115 #define NTLM_TargetTypeShare 0x00040000
116 #define NTLM_NegotiateNTLM2Key 0x00080000
117 #define NTLM_RequestInitResp 0x00100000
118 #define NTLM_RequestAcceptResp 0x00200000
119 #define NTLM_RequestNonNTSessionKey 0x00400000
120 #define NTLM_NegotiateTargetInfo 0x00800000
121 #define NTLM_Unknown4 0x01000000
122 #define NTLM_Unknown5 0x02000000
123 #define NTLM_Unknown6 0x04000000
124 #define NTLM_Unknown7 0x08000000
125 #define NTLM_Unknown8 0x10000000
126 #define NTLM_Negotiate128Bit 0x20000000
127 #define NTLM_NegotiateKeyExchange 0x40000000
128 #define NTLM_Negotiate56Bit 0x80000000
131 /* write a 64-bit word, little endian */
133 CFMutableDataRef buf
,
136 /* write a 32-bit word, little endian */
138 CFMutableDataRef buf
,
141 /* write a 16-bit word, little endian */
143 CFMutableDataRef buf
,
147 * Write a security buffer, providing the index into the CFData at which
148 * this security buffer's offset is located. Just before the actual data is written,
149 * go back and update the offset with the start of that data using secBufOffset().
152 CFMutableDataRef buf
,
154 CFIndex
*offsetIndex
);
157 * Update a security buffer's offset to be the current end of data in a CFData.
160 CFMutableDataRef buf
,
161 CFIndex offsetIndex
); /* obtained from appendSecBuf() */
164 * Parse/validate a security buffer. Verifies that supplied offset/length don't go
165 * past end of avaialble data. Returns ptr to actual data and its length. Returns
166 * errSecParam on bogus values.
168 OSStatus
ntlmParseSecBuffer(
169 const unsigned char *cp
, /* start of security buffer */
170 const unsigned char *bufStart
, /* start of whole msg buffer */
171 unsigned bufLen
, /* # of valid bytes starting at bufStart */
172 const unsigned char **data
, /* RETURNED, start of actual data */
173 uint16_t *dataLen
); /* RETURNED, length of actual data */
175 /* random number generator */
178 void *buf
); /* allocated by caller, random data RETURNED */
180 /* Obtain host name in appropriate encoding */
181 OSStatus
ntlmHostName(
183 unsigned char **flat
, // mallocd and RETURNED
184 unsigned *flatLen
); // RETURNED
186 void ntlmAppendTimestamp(
187 CFMutableDataRef ntlmV2Blob
);
190 * Convert CFString to little-endian unicode.
194 unsigned char **ucode
, // mallocd and RETURNED
195 unsigned *ucodeLen
); // RETURNED
198 * Convert a CFStringRef into a mallocd array of chars suitable for the specified
199 * encoding. This might return an error if the string can't be converted
202 OSStatus
ntlmStringFlatten(
205 unsigned char **flat
, // mallocd and RETURNED
206 unsigned *flatLen
); // RETURNED
208 /* MD4 and MD5 hash */
209 #define NTLM_DIGEST_LENGTH 16
211 const unsigned char *data
,
213 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH */
215 const unsigned char *data
,
217 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH */
220 * Calculate LM-style password hash. This really only works if the password
221 * is convertible to ASCII.
223 OSStatus
lmPasswordHash(
225 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH
228 * Calculate NTLM password hash (MD4 on a unicode password).
230 void ntlmPasswordHash(
232 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH
235 * NTLM response: DES with three different keys.
237 OSStatus
ntlmResponse(
238 const unsigned char *digest
, // NTLM_DIGEST_LENGTH bytes
239 const unsigned char *challenge
, // actually challenge or session hash
240 unsigned char *ntlmResp
); // caller-supplied NTLM_LM_RESPONSE_LEN
242 /* DES-related consts */
243 #define DES_BLOCK_SIZE 8
244 #define DES_RAW_KEY_SIZE 7
245 #define DES_KEY_SIZE 8
248 * Given 7 bytes, create 8-byte DES key. Our implementation ignores the
249 * parity bit (lsb), which simplifies this somewhat.
252 const unsigned char *inKey
, // DES_RAW_KEY_SIZE bytes
253 unsigned char *outKey
); // DES_KEY_SIZE bytes
256 * single block DES encrypt.
257 * This would really benefit from a DES implementation in CommonCrypto.
259 OSStatus
ntlmDesCrypt(
260 const unsigned char *key
, // DES_KEY_SIZE bytes
261 const unsigned char *inData
, // DES_BLOCK_SIZE bytes
262 unsigned char *outData
); // DES_BLOCK_SIZE bytes
267 OSStatus
ntlmHmacMD5(
268 const unsigned char *key
,
270 const unsigned char *inData
,
272 unsigned char *mac
); // caller provided, NTLM_DIGEST_LENGTH
276 const char *whereFrom
,
279 #define ntlmPrintFlags(w, f)
286 #endif /* _NTLM_BLOB_PRIV_H_ */