1 #ifndef _IPXE_NTLM_H
2 #define _IPXE_NTLM_H
3 
4 /** @file
5  *
6  * NT LAN Manager (NTLM) authentication
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/crypto.h>
14 #include <ipxe/md5.h>
15 
16 /** A message header */
17 struct ntlm_header {
18 	/** Magic signature */
19 	uint8_t magic[8];
20 	/** Message type */
21 	uint32_t type;
22 } __attribute__ (( packed ));
23 
24 /** Magic signature */
25 #define NTLM_MAGIC { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' }
26 
27 /** Message types */
28 enum ntlm_type {
29 	/** Negotiate message type */
30 	NTLM_NEGOTIATE = 0x00000001UL,
31 	/** Challenge message type */
32 	NTLM_CHALLENGE = 0x00000002UL,
33 	/** Authenticate message */
34 	NTLM_AUTHENTICATE = 0x00000003UL,
35 };
36 
37 /** Negotiation flags */
38 enum ntlm_flags {
39 	/** Negotiate key exchange */
40 	NTLM_NEGOTIATE_KEY_EXCH = 0x20000000UL,
41 	/** Negotiate extended security */
42 	NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000UL,
43 	/** Negotiate always sign */
44 	NTLM_NEGOTIATE_ALWAYS_SIGN = 0x00008000UL,
45 	/** Negotiate NTLM key */
46 	NTLM_NEGOTIATE_NTLM = 0x00000200UL,
47 	/** Request target name and information */
48 	NTLM_REQUEST_TARGET = 0x00000004UL,
49 	/** Negotiate Unicode character encoding */
50 	NTLM_NEGOTIATE_UNICODE = 0x00000001UL,
51 };
52 
53 /** A version descriptor */
54 struct ntlm_version {
55 	/** Product major version */
56 	uint8_t major;
57 	/** Product minor version */
58 	uint8_t minor;
59 	/** Product build number */
60 	uint16_t build;
61 	/** Reserved */
62 	uint8_t reserved[3];
63 	/** NTLMSSP revision */
64 	uint8_t revision;
65 } __attribute__ (( packed ));
66 
67 /** A nonce */
68 struct ntlm_nonce {
69 	/** Raw bytes */
70 	uint8_t raw[8];
71 } __attribute__ (( packed ));
72 
73 /** A variable-length data descriptor */
74 struct ntlm_data {
75 	/** Length (in bytes) */
76 	uint16_t len;
77 	/** Maximum length (in bytes)
78 	 *
79 	 * Should always be set equal to the length; this field is
80 	 * entirely superfluous.
81 	 */
82 	uint16_t max_len;
83 	/** Offset from start of message header */
84 	uint32_t offset;
85 } __attribute__ (( packed ));
86 
87 /** A Negotiate message */
88 struct ntlm_negotiate {
89 	/** Message header */
90 	struct ntlm_header header;
91 	/** Negotiation flags */
92 	uint32_t flags;
93 	/** Domain name */
94 	struct ntlm_data domain;
95 	/** Workstation name */
96 	struct ntlm_data workstation;
97 } __attribute__ (( packed ));
98 
99 /** A Challenge message */
100 struct ntlm_challenge {
101 	/** Message header */
102 	struct ntlm_header header;
103 	/** Target name */
104 	struct ntlm_data name;
105 	/** Negotiation flags */
106 	uint32_t flags;
107 	/** Server nonce */
108 	struct ntlm_nonce nonce;
109 	/** Reserved */
110 	uint8_t reserved[8];
111 	/** Target information */
112 	struct ntlm_data info;
113 } __attribute__ (( packed ));
114 
115 /** An Authenticate message */
116 struct ntlm_authenticate {
117 	/** Message header */
118 	struct ntlm_header header;
119 	/** LAN Manager response */
120 	struct ntlm_data lm;
121 	/** NT response */
122 	struct ntlm_data nt;
123 	/** Domain name */
124 	struct ntlm_data domain;
125 	/** User name */
126 	struct ntlm_data user;
127 	/** Workstation name */
128 	struct ntlm_data workstation;
129 	/** Session key */
130 	struct ntlm_data session;
131 	/** Negotiation flags */
132 	uint32_t flags;
133 } __attribute__ (( packed ));
134 
135 /** A LAN Manager response */
136 struct ntlm_lm_response {
137 	/** HMAC-MD5 digest */
138 	uint8_t digest[MD5_DIGEST_SIZE];
139 	/** Client nonce */
140 	struct ntlm_nonce nonce;
141 } __attribute__ (( packed ));
142 
143 /** An NT response */
144 struct ntlm_nt_response {
145 	/** HMAC-MD5 digest */
146 	uint8_t digest[MD5_DIGEST_SIZE];
147 	/** Response version */
148 	uint8_t version;
149 	/** Highest response version */
150 	uint8_t high;
151 	/** Reserved */
152 	uint8_t reserved_a[6];
153 	/** Current time */
154 	uint64_t time;
155 	/** Client nonce */
156 	struct ntlm_nonce nonce;
157 	/** Must be zero */
158 	uint32_t zero;
159 } __attribute__ (( packed ));
160 
161 /** NTLM version */
162 #define NTLM_VERSION_NTLMV2 0x01
163 
164 /** NTLM challenge information */
165 struct ntlm_challenge_info {
166 	/** Server nonce */
167 	struct ntlm_nonce *nonce;
168 	/** Target information */
169 	void *target;
170 	/** Length of target information */
171 	size_t len;
172 };
173 
174 /** An NTLM verification key */
175 struct ntlm_key {
176 	/** Raw bytes */
177 	uint8_t raw[MD5_DIGEST_SIZE];
178 };
179 
180 extern const struct ntlm_negotiate ntlm_negotiate;
181 extern int ntlm_challenge ( struct ntlm_challenge *challenge, size_t len,
182 			    struct ntlm_challenge_info *info );
183 extern void ntlm_key ( const char *domain, const char *username,
184 		       const char *password, struct ntlm_key *key );
185 extern void ntlm_response ( struct ntlm_challenge_info *info,
186 			    struct ntlm_key *key, struct ntlm_nonce *nonce,
187 			    struct ntlm_lm_response *lm,
188 			    struct ntlm_nt_response *nt );
189 extern size_t ntlm_authenticate ( struct ntlm_challenge_info *info,
190 				  const char *domain, const char *username,
191 				  const char *workstation,
192 				  struct ntlm_lm_response *lm,
193 				  struct ntlm_nt_response *nt,
194 				  struct ntlm_authenticate *auth );
195 extern size_t ntlm_authenticate_len ( struct ntlm_challenge_info *info,
196 				      const char *domain, const char *username,
197 				      const char *workstation );
198 
199 #endif /* _IPXE_NTLM_H */
200