summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/ntlm.h
blob: b0436c9ac40ca967285bba3a4fa0487ce70e4147 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef _IPXE_NTLM_H
#define _IPXE_NTLM_H

/** @file
 *
 * NT LAN Manager (NTLM) authentication
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/crypto.h>
#include <ipxe/md5.h>

/** A message header */
struct ntlm_header {
	/** Magic signature */
	uint8_t magic[8];
	/** Message type */
	uint32_t type;
} __attribute__ (( packed ));

/** Magic signature */
#define NTLM_MAGIC { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' }

/** Message types */
enum ntlm_type {
	/** Negotiate message type */
	NTLM_NEGOTIATE = 0x00000001UL,
	/** Challenge message type */
	NTLM_CHALLENGE = 0x00000002UL,
	/** Authenticate message */
	NTLM_AUTHENTICATE = 0x00000003UL,
};

/** Negotiation flags */
enum ntlm_flags {
	/** Negotiate key exchange */
	NTLM_NEGOTIATE_KEY_EXCH = 0x20000000UL,
	/** Negotiate extended security */
	NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000UL,
	/** Negotiate always sign */
	NTLM_NEGOTIATE_ALWAYS_SIGN = 0x00008000UL,
	/** Negotiate NTLM key */
	NTLM_NEGOTIATE_NTLM = 0x00000200UL,
	/** Request target name and information */
	NTLM_REQUEST_TARGET = 0x00000004UL,
	/** Negotiate Unicode character encoding */
	NTLM_NEGOTIATE_UNICODE = 0x00000001UL,
};

/** A version descriptor */
struct ntlm_version {
	/** Product major version */
	uint8_t major;
	/** Product minor version */
	uint8_t minor;
	/** Product build number */
	uint16_t build;
	/** Reserved */
	uint8_t reserved[3];
	/** NTLMSSP revision */
	uint8_t revision;
} __attribute__ (( packed ));

/** A nonce */
struct ntlm_nonce {
	/** Raw bytes */
	uint8_t raw[8];
} __attribute__ (( packed ));

/** A variable-length data descriptor */
struct ntlm_data {
	/** Length (in bytes) */
	uint16_t len;
	/** Maximum length (in bytes)
	 *
	 * Should always be set equal to the length; this field is
	 * entirely superfluous.
	 */
	uint16_t max_len;
	/** Offset from start of message header */
	uint32_t offset;
} __attribute__ (( packed ));

/** A Negotiate message */
struct ntlm_negotiate {
	/** Message header */
	struct ntlm_header header;
	/** Negotiation flags */
	uint32_t flags;
	/** Domain name */
	struct ntlm_data domain;
	/** Workstation name */
	struct ntlm_data workstation;
} __attribute__ (( packed ));

/** A Challenge message */
struct ntlm_challenge {
	/** Message header */
	struct ntlm_header header;
	/** Target name */
	struct ntlm_data name;
	/** Negotiation flags */
	uint32_t flags;
	/** Server nonce */
	struct ntlm_nonce nonce;
	/** Reserved */
	uint8_t reserved[8];
	/** Target information */
	struct ntlm_data info;
} __attribute__ (( packed ));

/** An Authenticate message */
struct ntlm_authenticate {
	/** Message header */
	struct ntlm_header header;
	/** LAN Manager response */
	struct ntlm_data lm;
	/** NT response */
	struct ntlm_data nt;
	/** Domain name */
	struct ntlm_data domain;
	/** User name */
	struct ntlm_data user;
	/** Workstation name */
	struct ntlm_data workstation;
	/** Session key */
	struct ntlm_data session;
	/** Negotiation flags */
	uint32_t flags;
} __attribute__ (( packed ));

/** A LAN Manager response */
struct ntlm_lm_response {
	/** HMAC-MD5 digest */
	uint8_t digest[MD5_DIGEST_SIZE];
	/** Client nonce */
	struct ntlm_nonce nonce;
} __attribute__ (( packed ));

/** An NT response */
struct ntlm_nt_response {
	/** HMAC-MD5 digest */
	uint8_t digest[MD5_DIGEST_SIZE];
	/** Response version */
	uint8_t version;
	/** Highest response version */
	uint8_t high;
	/** Reserved */
	uint8_t reserved_a[6];
	/** Current time */
	uint64_t time;
	/** Client nonce */
	struct ntlm_nonce nonce;
	/** Must be zero */
	uint32_t zero;
} __attribute__ (( packed ));

/** NTLM version */
#define NTLM_VERSION_NTLMV2 0x01

/** NTLM challenge information */
struct ntlm_challenge_info {
	/** Server nonce */
	struct ntlm_nonce *nonce;
	/** Target information */
	void *target;
	/** Length of target information */
	size_t len;
};

/** An NTLM verification key */
struct ntlm_key {
	/** Raw bytes */
	uint8_t raw[MD5_DIGEST_SIZE];
};

extern const struct ntlm_negotiate ntlm_negotiate;
extern int ntlm_challenge ( struct ntlm_challenge *challenge, size_t len,
			    struct ntlm_challenge_info *info );
extern void ntlm_key ( const char *domain, const char *username,
		       const char *password, struct ntlm_key *key );
extern void ntlm_response ( struct ntlm_challenge_info *info,
			    struct ntlm_key *key, struct ntlm_nonce *nonce,
			    struct ntlm_lm_response *lm,
			    struct ntlm_nt_response *nt );
extern size_t ntlm_authenticate ( struct ntlm_challenge_info *info,
				  const char *domain, const char *username,
				  const char *workstation,
				  struct ntlm_lm_response *lm,
				  struct ntlm_nt_response *nt,
				  struct ntlm_authenticate *auth );
extern size_t ntlm_authenticate_len ( struct ntlm_challenge_info *info,
				      const char *domain, const char *username,
				      const char *workstation );

#endif /* _IPXE_NTLM_H */