iPXE
ntlm.c File Reference

NT LAN Manager (NTLM) authentication. More...

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/md4.h>
#include <ipxe/md5.h>
#include <ipxe/hmac.h>
#include <ipxe/ntlm.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
int ntlm_challenge (struct ntlm_challenge *challenge, size_t len, struct ntlm_challenge_info *info)
 Parse NTLM Challenge.
void ntlm_key (const char *domain, const char *username, const char *password, struct ntlm_key *key)
 Calculate NTLM verification key.
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)
 Construct NTLM responses.
static void * ntlm_append (struct ntlm_header *header, struct ntlm_data *data, void *payload, size_t len)
 Append data to NTLM message.
static void * ntlm_append_string (struct ntlm_header *header, struct ntlm_data *data, void *payload, const char *string)
 Append Unicode string data to NTLM message.
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)
 Construct NTLM Authenticate message.
size_t ntlm_authenticate_len (struct ntlm_challenge_info *info, const char *domain, const char *username, const char *workstation)
 Calculate NTLM Authenticate message length.

Variables

const struct ntlm_negotiate ntlm_negotiate
 Negotiate message.

Detailed Description

NT LAN Manager (NTLM) authentication.

Definition in file ntlm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ ntlm_challenge()

int ntlm_challenge ( struct ntlm_challenge * challenge,
size_t len,
struct ntlm_challenge_info * info )

Parse NTLM Challenge.

Parameters
challengeChallenge message
lenLength of Challenge message
infoChallenge information to fill in
Return values
rcReturn status code

Definition at line 69 of file ntlm.c.

70 {
71 size_t offset;
72
73 DBGC ( challenge, "NTLM challenge message:\n" );
74 DBGC_HDA ( challenge, 0, challenge, len );
75
76 /* Sanity checks */
77 if ( len < sizeof ( *challenge ) ) {
78 DBGC ( challenge, "NTLM underlength challenge (%zd bytes)\n",
79 len );
80 return -EINVAL;
81 }
82
83 /* Extract nonce */
84 info->nonce = &challenge->nonce;
85 DBGC ( challenge, "NTLM challenge nonce:\n" );
86 DBGC_HDA ( challenge, 0, info->nonce, sizeof ( *info->nonce ) );
87
88 /* Extract target information */
89 info->len = le16_to_cpu ( challenge->info.len );
90 offset = le32_to_cpu ( challenge->info.offset );
91 if ( ( offset > len ) ||
92 ( info->len > ( len - offset ) ) ) {
93 DBGC ( challenge, "NTLM target information outside "
94 "challenge\n" );
95 DBGC_HDA ( challenge, 0, challenge, len );
96 return -EINVAL;
97 }
98 info->target = ( ( ( void * ) challenge ) + offset );
99 DBGC ( challenge, "NTLM challenge target information:\n" );
100 DBGC_HDA ( challenge, 0, info->target, info->len );
101
102 return 0;
103}
u32 info
Definition ar9003_mac.h:0
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
#define le16_to_cpu(value)
Definition byteswap.h:113
#define le32_to_cpu(value)
Definition byteswap.h:114
struct ntlm_nonce nonce
Server nonce.
Definition ntlm.h:109
struct ntlm_data info
Target information.
Definition ntlm.h:113
uint16_t len
Length (in bytes)
Definition ntlm.h:77
uint32_t offset
Offset from start of message header.
Definition ntlm.h:85

References DBGC, DBGC_HDA, EINVAL, info, ntlm_challenge::info, le16_to_cpu, le32_to_cpu, len, ntlm_data::len, ntlm_challenge::nonce, ntlm_data::offset, and offset.

◆ ntlm_key()

void ntlm_key ( const char * domain,
const char * username,
const char * password,
struct ntlm_key * key )

Calculate NTLM verification key.

Parameters
domainDomain name (or NULL)
usernameUser name (or NULL)
passwordPassword (or NULL)
keyKey to fill in

This is the NTOWFv2() function as defined in MS-NLMP.

Definition at line 115 of file ntlm.c.

116 {
117 struct digest_algorithm *md4 = &md4_algorithm;
118 struct digest_algorithm *md5 = &md5_algorithm;
119 union {
122 } ctx;
123 uint8_t digest[MD4_DIGEST_SIZE];
124 uint8_t c;
125 uint16_t wc;
126
127 /* Use empty usernames/passwords if not specified */
128 if ( ! domain )
129 domain = "";
130 if ( ! username )
131 username = "";
132 if ( ! password )
133 password = "";
134
135 /* Construct MD4 digest of (Unicode) password */
136 digest_init ( md4, ctx.md4 );
137 while ( ( c = *(password++) ) ) {
138 wc = cpu_to_le16 ( c );
139 digest_update ( md4, ctx.md4, &wc, sizeof ( wc ) );
140 }
141 digest_final ( md4, ctx.md4, digest );
142
143 /* Construct HMAC-MD5 of (Unicode) upper-case username */
144 hmac_init ( md5, ctx.md5, digest, sizeof ( digest ) );
145 while ( ( c = *(username++) ) ) {
146 wc = cpu_to_le16 ( toupper ( c ) );
147 hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
148 }
149 while ( ( c = *(domain++) ) ) {
150 wc = cpu_to_le16 ( c );
151 hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
152 }
153 hmac_final ( md5, ctx.md5, key->raw );
154 DBGC ( key, "NTLM key:\n" );
155 DBGC_HDA ( key, 0, key, sizeof ( *key ) );
156}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
struct golan_eq_context ctx
Definition CIB_PRM.h:0
unsigned short uint16_t
Definition stdint.h:11
unsigned char uint8_t
Definition stdint.h:10
static int toupper(int character)
Convert character to upper case.
Definition ctype.h:121
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition hmac.c:58
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:88
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition hmac.h:43
#define cpu_to_le16(value)
Definition byteswap.h:107
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:219
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:230
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
static struct dynamic_item username
Definition login_ui.c:36
static struct dynamic_item password
Definition login_ui.c:37
struct digest_algorithm md4_algorithm
MD4 algorithm.
Definition md4.c:262
#define MD4_CTX_SIZE
MD4 context size.
Definition md4.h:67
#define MD4_DIGEST_SIZE
MD4 digest size.
Definition md4.h:73
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition md5.c:287
#define MD5_CTX_SIZE
MD5 context size.
Definition md5.h:67
#define MD5_BLOCK_SIZE
MD5 block size.
Definition md5.h:70
A message digest algorithm.
Definition crypto.h:19
static wchar_t wc
Definition wchar.h:23

References cpu_to_le16, ctx, DBGC, DBGC_HDA, digest_final(), digest_init(), digest_update(), hmac_final(), hmac_init(), hmac_update(), key, md4_algorithm, MD4_CTX_SIZE, MD4_DIGEST_SIZE, md5_algorithm, MD5_BLOCK_SIZE, MD5_CTX_SIZE, password, toupper(), username, and wc.

Referenced by http_ntlm_authenticate(), ntlm_authenticate_okx(), and ntlm_key_okx().

◆ ntlm_response()

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 )

Construct NTLM responses.

Parameters
infoChallenge information
keyVerification key
nonceNonce, or NULL to use a random nonce
lmLAN Manager response to fill in
ntNT response to fill in

Definition at line 167 of file ntlm.c.

169 {
170 struct digest_algorithm *md5 = &md5_algorithm;
171 struct ntlm_nonce tmp_nonce;
173 unsigned int i;
174
175 /* Generate random nonce, if needed */
176 if ( ! nonce ) {
177 for ( i = 0 ; i < sizeof ( tmp_nonce ) ; i++ )
178 tmp_nonce.raw[i] = random();
179 nonce = &tmp_nonce;
180 }
181
182 /* Construct LAN Manager response */
183 memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
184 hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
185 hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
186 hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->nonce ) );
187 hmac_final ( md5, ctx, lm->digest );
188 DBGC ( key, "NTLM LAN Manager response:\n" );
189 DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );
190
191 /* Construct NT response */
192 memset ( nt, 0, sizeof ( *nt ) );
193 nt->version = NTLM_VERSION_NTLMV2;
194 nt->high = NTLM_VERSION_NTLMV2;
195 memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
196 hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
197 hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
198 hmac_update ( md5, ctx, &nt->version,
199 ( sizeof ( *nt ) -
200 offsetof ( typeof ( *nt ), version ) ) );
201 hmac_update ( md5, ctx, info->target, info->len );
202 hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
203 hmac_final ( md5, ctx, nt->digest );
204 DBGC ( key, "NTLM NT response prefix:\n" );
205 DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
206}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
u32 version
Driver version.
Definition ath9k_hw.c:1985
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
struct mschapv2_nt_response nt
NT response.
Definition mschapv2.h:5
#define NTLM_VERSION_NTLMV2
NTLM version.
Definition ntlm.h:163
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
uint8_t digest[MD5_DIGEST_SIZE]
HMAC-MD5 digest.
Definition ntlm.h:139
struct ntlm_nonce nonce
Client nonce.
Definition ntlm.h:141
A nonce.
Definition ntlm.h:69
u8 nonce[32]
Nonce value.
Definition wpa.h:25

References ctx, DBGC, DBGC_HDA, ntlm_lm_response::digest, hmac_final(), hmac_init(), hmac_update(), info, key, md5_algorithm, MD5_BLOCK_SIZE, MD5_CTX_SIZE, memcpy(), memset(), nonce, ntlm_lm_response::nonce, nt, NTLM_VERSION_NTLMV2, offsetof, random(), ntlm_nonce::raw, typeof(), and version.

Referenced by http_ntlm_authenticate(), and ntlm_authenticate_okx().

◆ ntlm_append()

void * ntlm_append ( struct ntlm_header * header,
struct ntlm_data * data,
void * payload,
size_t len )
static

Append data to NTLM message.

Parameters
headerMessage header, or NULL to only calculate next payload
dataData descriptor
payloadData payload
lenLength of data
Return values
payloadNext data payload

Definition at line 217 of file ntlm.c.

218 {
219
220 /* Populate data descriptor */
221 if ( header ) {
222 data->offset = cpu_to_le32 ( payload - ( ( void * ) header ) );
223 data->len = data->max_len = cpu_to_le16 ( len );
224 }
225
226 return ( payload + len );
227}
uint8_t data[48]
Additional event data.
Definition ena.h:11
struct ena_llq_option header
Header locations.
Definition ena.h:5
#define cpu_to_le32(value)
Definition byteswap.h:108

References cpu_to_le16, cpu_to_le32, data, header, and len.

Referenced by ntlm_append_string(), and ntlm_authenticate().

◆ ntlm_append_string()

void * ntlm_append_string ( struct ntlm_header * header,
struct ntlm_data * data,
void * payload,
const char * string )
static

Append Unicode string data to NTLM message.

Parameters
headerMessage header, or NULL to only calculate next payload
dataData descriptor
payloadData payload
stringString to append, or NULL
Return values
payloadNext data payload

Definition at line 238 of file ntlm.c.

240 {
241 uint16_t *tmp = payload;
242 uint8_t c;
243
244 /* Convert string to Unicode */
245 for ( tmp = payload ; ( string && ( c = *(string++) ) ) ; tmp++ ) {
246 if ( header )
247 *tmp = cpu_to_le16 ( c );
248 }
249
250 /* Append string data */
251 return ntlm_append ( header, data, payload,
252 ( ( ( void * ) tmp ) - payload ) );
253}
unsigned long tmp
Definition linux_pci.h:65
static void * ntlm_append(struct ntlm_header *header, struct ntlm_data *data, void *payload, size_t len)
Append data to NTLM message.
Definition ntlm.c:217

References cpu_to_le16, data, header, ntlm_append(), and tmp.

Referenced by ntlm_authenticate().

◆ ntlm_authenticate()

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 )

Construct NTLM Authenticate message.

Parameters
infoChallenge information
domainDomain name, or NULL
usernameUser name, or NULL
workstationWorkstation name, or NULL
lmLAN Manager response
ntNT response
authMessage to fill in, or NULL to only calculate length
Return values
lenLength of message

Definition at line 267 of file ntlm.c.

271 {
272 void *tmp;
273 size_t nt_len;
274 size_t len;
275
276 /* Construct response header */
277 if ( auth ) {
278 memset ( auth, 0, sizeof ( *auth ) );
280 sizeof ( auth->header.magic ) );
282 auth->flags = ntlm_negotiate.flags;
283 }
284 tmp = ( ( ( void * ) auth ) + sizeof ( *auth ) );
285
286 /* Construct LAN Manager response */
287 if ( auth )
288 memcpy ( tmp, lm, sizeof ( *lm ) );
289 tmp = ntlm_append ( &auth->header, &auth->lm, tmp, sizeof ( *lm ) );
290
291 /* Construct NT response */
292 nt_len = ( sizeof ( *nt ) + info->len + sizeof ( nt->zero ) );
293 if ( auth ) {
294 memcpy ( tmp, nt, sizeof ( *nt ) );
295 memcpy ( ( tmp + sizeof ( *nt ) ), info->target, info->len );
296 memset ( ( tmp + sizeof ( *nt ) + info->len ), 0,
297 sizeof ( nt->zero ) );
298 }
299 tmp = ntlm_append ( &auth->header, &auth->nt, tmp, nt_len );
300
301 /* Populate domain, user, and workstation names */
302 tmp = ntlm_append_string ( &auth->header, &auth->domain, tmp, domain );
303 tmp = ntlm_append_string ( &auth->header, &auth->user, tmp, username );
304 tmp = ntlm_append_string ( &auth->header, &auth->workstation, tmp,
305 workstation );
306
307 /* Calculate length */
308 len = ( tmp - ( ( void * ) auth ) );
309 if ( auth ) {
310 DBGC ( auth, "NTLM authenticate message:\n" );
311 DBGC_HDA ( auth, 0, auth, len );
312 }
313
314 return len;
315}
static void * ntlm_append_string(struct ntlm_header *header, struct ntlm_data *data, void *payload, const char *string)
Append Unicode string data to NTLM message.
Definition ntlm.c:238
@ NTLM_AUTHENTICATE
Authenticate message.
Definition ntlm.h:35
struct ntlm_data lm
LAN Manager response.
Definition ntlm.h:121
struct ntlm_data user
User name.
Definition ntlm.h:127
struct ntlm_data domain
Domain name.
Definition ntlm.h:125
struct ntlm_data nt
NT response.
Definition ntlm.h:123
struct ntlm_header header
Message header.
Definition ntlm.h:119
struct ntlm_data workstation
Workstation name.
Definition ntlm.h:129
uint32_t flags
Negotiation flags.
Definition ntlm.h:133
uint32_t type
Message type.
Definition ntlm.h:22
uint8_t magic[8]
Magic signature.
Definition ntlm.h:20
A Negotiate message.
Definition ntlm.h:89
uint32_t flags
Negotiation flags.
Definition ntlm.h:93
struct ntlm_header header
Message header.
Definition ntlm.h:91

References cpu_to_le32, DBGC, DBGC_HDA, ntlm_authenticate::domain, ntlm_authenticate::flags, ntlm_negotiate::flags, ntlm_authenticate::header, ntlm_negotiate::header, info, len, ntlm_authenticate::lm, ntlm_header::magic, memcpy(), memset(), nt, ntlm_authenticate::nt, ntlm_append(), ntlm_append_string(), NTLM_AUTHENTICATE, tmp, ntlm_header::type, ntlm_authenticate::user, username, and ntlm_authenticate::workstation.

Referenced by http_format_ntlm_auth(), and ntlm_authenticate_len().

◆ ntlm_authenticate_len()

size_t ntlm_authenticate_len ( struct ntlm_challenge_info * info,
const char * domain,
const char * username,
const char * workstation )

Calculate NTLM Authenticate message length.

Parameters
infoChallenge information
domainDomain name, or NULL
usernameUser name, or NULL
workstationWorkstation name, or NULL
Return values
lenLength of Authenticate message

Definition at line 326 of file ntlm.c.

328 {
329
330 return ntlm_authenticate ( info, domain, username, workstation,
331 NULL, NULL, NULL );
332}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
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)
Construct NTLM Authenticate message.
Definition ntlm.c:267

References info, ntlm_authenticate(), NULL, and username.

Referenced by http_ntlm_authenticate(), and ntlm_authenticate_okx().

Variable Documentation

◆ ntlm_negotiate

const struct ntlm_negotiate ntlm_negotiate
Initial value:
= {
.header = {
.magic = NTLM_MAGIC,
},
}
@ NTLM_NEGOTIATE_NTLM
Negotiate NTLM key.
Definition ntlm.h:47
@ NTLM_REQUEST_TARGET
Request target name and information.
Definition ntlm.h:49
@ NTLM_NEGOTIATE_UNICODE
Negotiate Unicode character encoding.
Definition ntlm.h:51
@ NTLM_NEGOTIATE_ALWAYS_SIGN
Negotiate always sign.
Definition ntlm.h:45
@ NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY
Negotiate extended security.
Definition ntlm.h:43
@ NTLM_NEGOTIATE
Negotiate message type.
Definition ntlm.h:31
#define NTLM_MAGIC
Magic signature.
Definition ntlm.h:26

Negotiate message.

This message content is fixed since there is no need to specify the calling workstation name or domain name, and the set of flags is mandated by the MS-NLMP specification.

Definition at line 49 of file ntlm.c.