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
94 /* max lenght of flattenedString we are willing to consider */
95 #define NTLM_MAX_STRING_LEN 2048
98 * Flags - defined here in native endianness; sent over the wire little-endian
100 #define NTLM_NegotiateUnicode 0x00000001
101 #define NTLM_NegotiateOEM 0x00000002
102 #define NTLM_RequestTarget 0x00000004
103 #define NTLM_Unknown1 0x00000008
104 #define NTLM_NegotiateSign 0x00000010
105 #define NTLM_NegotiateSeal 0x00000020
106 #define NTLM_NegotiateDatagram 0x00000040
107 #define NTLM_NegotiateLMKey 0x00000080
108 #define NTLM_NegotiateNetware 0x00000100
109 #define NTLM_NegotiateNTLM 0x00000200
110 #define NTLM_Unknown2 0x00000400
111 #define NTLM_Unknown3 0x00000800
112 #define NTLM_DomainSupplied 0x00001000
113 #define NTLM_WorkstationSupplies 0x00002000
114 #define NTLM_LocalCall 0x00004000
115 #define NTLM_AlwaysSign 0x00008000
116 #define NTLM_TargetTypeDomain 0x00010000
117 #define NTLM_TargetTypeServer 0x00020000
118 #define NTLM_TargetTypeShare 0x00040000
119 #define NTLM_NegotiateNTLM2Key 0x00080000
120 #define NTLM_RequestInitResp 0x00100000
121 #define NTLM_RequestAcceptResp 0x00200000
122 #define NTLM_RequestNonNTSessionKey 0x00400000
123 #define NTLM_NegotiateTargetInfo 0x00800000
124 #define NTLM_Unknown4 0x01000000
125 #define NTLM_Unknown5 0x02000000
126 #define NTLM_Unknown6 0x04000000
127 #define NTLM_Unknown7 0x08000000
128 #define NTLM_Unknown8 0x10000000
129 #define NTLM_Negotiate128Bit 0x20000000
130 #define NTLM_NegotiateKeyExchange 0x40000000
131 #define NTLM_Negotiate56Bit 0x80000000
134 /* write a 64-bit word, little endian */
136 CFMutableDataRef buf
,
139 /* write a 32-bit word, little endian */
141 CFMutableDataRef buf
,
144 /* write a 16-bit word, little endian */
146 CFMutableDataRef buf
,
150 * Write a security buffer, providing the index into the CFData at which
151 * this security buffer's offset is located. Just before the actual data is written,
152 * go back and update the offset with the start of that data using secBufOffset().
155 CFMutableDataRef buf
,
157 CFIndex
*offsetIndex
);
160 * Update a security buffer's offset to be the current end of data in a CFData.
163 CFMutableDataRef buf
,
164 CFIndex offsetIndex
); /* obtained from appendSecBuf() */
167 * Parse/validate a security buffer. Verifies that supplied offset/length don't go
168 * past end of avaialble data. Returns ptr to actual data and its length. Returns
169 * errSecParam on bogus values.
171 OSStatus
ntlmParseSecBuffer(
172 const unsigned char *cp
, /* start of security buffer */
173 const unsigned char *bufStart
, /* start of whole msg buffer */
174 unsigned bufLen
, /* # of valid bytes starting at bufStart */
175 const unsigned char **data
, /* RETURNED, start of actual data */
176 uint16_t *dataLen
); /* RETURNED, length of actual data */
178 /* random number generator */
181 void *buf
); /* allocated by caller, random data RETURNED */
183 /* Obtain host name in appropriate encoding */
184 OSStatus
ntlmHostName(
186 unsigned char **flat
, // mallocd and RETURNED
187 unsigned *flatLen
); // RETURNED
189 void ntlmAppendTimestamp(
190 CFMutableDataRef ntlmV2Blob
);
193 * Convert CFString to little-endian unicode.
195 OSStatus
ntlmStringToLE(
197 unsigned char **ucode
, // mallocd and RETURNED
198 unsigned *ucodeLen
); // RETURNED
201 * Convert a CFStringRef into a mallocd array of chars suitable for the specified
202 * encoding. This might return an error if the string can't be converted
205 OSStatus
ntlmStringFlatten(
208 unsigned char **flat
, // mallocd and RETURNED
209 unsigned *flatLen
); // RETURNED
211 /* MD4 and MD5 hash */
212 #define NTLM_DIGEST_LENGTH 16
214 const unsigned char *data
,
216 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH */
218 const unsigned char *data
,
220 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH */
223 * Calculate NTLM password hash (MD4 on a unicode password).
225 OSStatus
ntlmPasswordHash(
227 unsigned char *digest
); // caller-supplied, NTLM_DIGEST_LENGTH
230 * NTLM response: DES with three different keys.
232 OSStatus
lmv2Response(
233 const unsigned char *digest
, // NTLM_DIGEST_LENGTH bytes
234 const unsigned char *challenge
, // actually challenge or session hash
235 unsigned char *ntlmResp
); // caller-supplied NTLM_LM_RESPONSE_LEN
237 /* DES-related consts */
238 #define DES_BLOCK_SIZE 8
239 #define DES_RAW_KEY_SIZE 7
240 #define DES_KEY_SIZE 8
243 * Given 7 bytes, create 8-byte DES key. Our implementation ignores the
244 * parity bit (lsb), which simplifies this somewhat.
247 const unsigned char *inKey
, // DES_RAW_KEY_SIZE bytes
248 unsigned char *outKey
); // DES_KEY_SIZE bytes
251 * single block DES encrypt.
252 * This would really benefit from a DES implementation in CommonCrypto.
254 OSStatus
ntlmDesCrypt(
255 const unsigned char *key
, // DES_KEY_SIZE bytes
256 const unsigned char *inData
, // DES_BLOCK_SIZE bytes
257 unsigned char *outData
); // DES_BLOCK_SIZE bytes
262 OSStatus
ntlmHmacMD5(
263 const unsigned char *key
,
265 const unsigned char *inData
,
267 unsigned char *mac
); // caller provided, NTLM_DIGEST_LENGTH
271 const char *whereFrom
,
274 #define ntlmPrintFlags(w, f)
281 #endif /* _NTLM_BLOB_PRIV_H_ */