iPXE
Data Structures | Macros | Enumerations | Functions | Variables
ntlm.h File Reference

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

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

Go to the source code of this file.

Data Structures

struct  ntlm_header
 A message header. More...
 
struct  ntlm_version
 A version descriptor. More...
 
struct  ntlm_nonce
 A nonce. More...
 
struct  ntlm_data
 A variable-length data descriptor. More...
 
struct  ntlm_negotiate
 A Negotiate message. More...
 
struct  ntlm_challenge
 A Challenge message. More...
 
struct  ntlm_authenticate
 An Authenticate message. More...
 
struct  ntlm_lm_response
 A LAN Manager response. More...
 
struct  ntlm_nt_response
 An NT response. More...
 
struct  ntlm_challenge_info
 NTLM challenge information. More...
 
struct  ntlm_key
 An NTLM verification key. More...
 

Macros

#define NTLM_MAGIC   { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' }
 Magic signature. More...
 
#define NTLM_VERSION_NTLMV2   0x01
 NTLM version. More...
 

Enumerations

enum  ntlm_type { NTLM_NEGOTIATE = 0x00000001UL, NTLM_CHALLENGE = 0x00000002UL, NTLM_AUTHENTICATE = 0x00000003UL }
 Message types. More...
 
enum  ntlm_flags {
  NTLM_NEGOTIATE_KEY_EXCH = 0x20000000UL, NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000UL, NTLM_NEGOTIATE_ALWAYS_SIGN = 0x00008000UL, NTLM_NEGOTIATE_NTLM = 0x00000200UL,
  NTLM_REQUEST_TARGET = 0x00000004UL, NTLM_NEGOTIATE_UNICODE = 0x00000001UL
}
 Negotiation flags. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
int ntlm_challenge (struct ntlm_challenge *challenge, size_t len, struct ntlm_challenge_info *info)
 Parse NTLM Challenge. More...
 
void ntlm_key (const char *domain, const char *username, const char *password, struct ntlm_key *key)
 Calculate NTLM verification key. More...
 
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. More...
 
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. More...
 
size_t ntlm_authenticate_len (struct ntlm_challenge_info *info, const char *domain, const char *username, const char *workstation)
 Calculate NTLM Authenticate message length. More...
 

Variables

const struct ntlm_negotiate ntlm_negotiate
 Negotiate message. More...
 

Detailed Description

NT LAN Manager (NTLM) authentication.

Definition in file ntlm.h.

Macro Definition Documentation

◆ NTLM_MAGIC

#define NTLM_MAGIC   { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' }

Magic signature.

Definition at line 25 of file ntlm.h.

◆ NTLM_VERSION_NTLMV2

#define NTLM_VERSION_NTLMV2   0x01

NTLM version.

Definition at line 162 of file ntlm.h.

Enumeration Type Documentation

◆ ntlm_type

enum ntlm_type

Message types.

Enumerator
NTLM_NEGOTIATE 

Negotiate message type.

NTLM_CHALLENGE 

Challenge message type.

NTLM_AUTHENTICATE 

Authenticate message.

Definition at line 28 of file ntlm.h.

28  {
29  /** Negotiate message type */
30  NTLM_NEGOTIATE = 0x00000001UL,
31  /** Challenge message type */
32  NTLM_CHALLENGE = 0x00000002UL,
33  /** Authenticate message */
34  NTLM_AUTHENTICATE = 0x00000003UL,
35 };
Authenticate message.
Definition: ntlm.h:34
Challenge message type.
Definition: ntlm.h:32
Negotiate message type.
Definition: ntlm.h:30

◆ ntlm_flags

enum ntlm_flags

Negotiation flags.

Enumerator
NTLM_NEGOTIATE_KEY_EXCH 

Negotiate key exchange.

NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY 

Negotiate extended security.

NTLM_NEGOTIATE_ALWAYS_SIGN 

Negotiate always sign.

NTLM_NEGOTIATE_NTLM 

Negotiate NTLM key.

NTLM_REQUEST_TARGET 

Request target name and information.

NTLM_NEGOTIATE_UNICODE 

Negotiate Unicode character encoding.

Definition at line 38 of file ntlm.h.

38  {
39  /** Negotiate key exchange */
40  NTLM_NEGOTIATE_KEY_EXCH = 0x20000000UL,
41  /** Negotiate extended security */
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 };
Negotiate NTLM key.
Definition: ntlm.h:46
Negotiate always sign.
Definition: ntlm.h:44
Negotiate extended security.
Definition: ntlm.h:42
Negotiate key exchange.
Definition: ntlm.h:40
Request target name and information.
Definition: ntlm.h:48
Negotiate Unicode character encoding.
Definition: ntlm.h:50

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ 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 68 of file ntlm.c.

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

References DBGC, DBGC_HDA, EINVAL, info, ntlm_challenge::info, le16_to_cpu, le32_to_cpu, len, ntlm_data::len, ntlm_challenge::nonce, offset, and ntlm_data::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 114 of file ntlm.c.

115  {
116  struct digest_algorithm *md4 = &md4_algorithm;
117  struct digest_algorithm *md5 = &md5_algorithm;
118  union {
119  uint8_t md4[MD4_CTX_SIZE];
121  } ctx;
122  uint8_t digest[MD4_DIGEST_SIZE];
123  uint8_t c;
124  uint16_t wc;
125 
126  /* Use empty usernames/passwords if not specified */
127  if ( ! domain )
128  domain = "";
129  if ( ! username )
130  username = "";
131  if ( ! password )
132  password = "";
133 
134  /* Construct MD4 digest of (Unicode) password */
135  digest_init ( md4, ctx.md4 );
136  while ( ( c = *(password++) ) ) {
137  wc = cpu_to_le16 ( c );
138  digest_update ( md4, ctx.md4, &wc, sizeof ( wc ) );
139  }
140  digest_final ( md4, ctx.md4, digest );
141 
142  /* Construct HMAC-MD5 of (Unicode) upper-case username */
143  hmac_init ( md5, ctx.md5, digest, sizeof ( digest ) );
144  while ( ( c = *(username++) ) ) {
145  wc = cpu_to_le16 ( toupper ( c ) );
146  hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
147  }
148  while ( ( c = *(domain++) ) ) {
149  wc = cpu_to_le16 ( c );
150  hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
151  }
152  hmac_final ( md5, ctx.md5, key->raw );
153  DBGC ( key, "NTLM key:\n" );
154  DBGC_HDA ( key, 0, key, sizeof ( *key ) );
155 }
#define MD4_DIGEST_SIZE
MD4 digest size.
Definition: md4.h:72
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
static wchar_t wc
Definition: wchar.h:22
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:206
unsigned short uint16_t
Definition: stdint.h:11
static __always_inline void off_t int c
Definition: librm.h:173
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:212
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static int toupper(int character)
Convert character to upper case.
Definition: ctype.h:120
#define DBGC_HDA(...)
Definition: compiler.h:506
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:201
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
#define MD5_CTX_SIZE
MD5 context size.
Definition: md5.h:66
unsigned char uint8_t
Definition: stdint.h:10
#define MD5_BLOCK_SIZE
MD5 block size.
Definition: md5.h:69
static struct dynamic_item password
Definition: login_ui.c:36
#define MD4_CTX_SIZE
MD4 context size.
Definition: md4.h:66
#define cpu_to_le16(value)
Definition: byteswap.h:106
A message digest algorithm.
Definition: crypto.h:18
static struct dynamic_item username
Definition: login_ui.c:35
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87
struct digest_algorithm md4_algorithm
MD4 algorithm.
Definition: md4.c:261
union @383 key
Sense key.
Definition: scsi.h:18
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References c, 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 166 of file ntlm.c.

168  {
169  struct digest_algorithm *md5 = &md5_algorithm;
170  struct ntlm_nonce tmp_nonce;
172  unsigned int i;
173 
174  /* Generate random nonce, if needed */
175  if ( ! nonce ) {
176  for ( i = 0 ; i < sizeof ( tmp_nonce ) ; i++ )
177  tmp_nonce.raw[i] = random();
178  nonce = &tmp_nonce;
179  }
180 
181  /* Construct LAN Manager response */
182  memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
183  hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
184  hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
185  hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->nonce ) );
186  hmac_final ( md5, ctx, lm->digest );
187  DBGC ( key, "NTLM LAN Manager response:\n" );
188  DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );
189 
190  /* Construct NT response */
191  memset ( nt, 0, sizeof ( *nt ) );
192  nt->version = NTLM_VERSION_NTLMV2;
193  nt->high = NTLM_VERSION_NTLMV2;
194  memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
195  hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
196  hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
197  hmac_update ( md5, ctx, &nt->version,
198  ( sizeof ( *nt ) -
199  offsetof ( typeof ( *nt ), version ) ) );
200  hmac_update ( md5, ctx, info->target, info->len );
201  hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
202  hmac_final ( md5, ctx, nt->digest );
203  DBGC ( key, "NTLM NT response prefix:\n" );
204  DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
205 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
u32 info
Definition: ar9003_mac.h:67
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint8_t digest[MD5_DIGEST_SIZE]
HMAC-MD5 digest.
Definition: ntlm.h:138
#define DBGC_HDA(...)
Definition: compiler.h:506
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
#define MD5_CTX_SIZE
MD5 context size.
Definition: md5.h:66
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
A nonce.
Definition: ntlm.h:68
#define MD5_BLOCK_SIZE
MD5 block size.
Definition: md5.h:69
struct ntlm_nonce nonce
Client nonce.
Definition: ntlm.h:140
u8 nonce[32]
Nonce value.
Definition: wpa.h:52
#define NTLM_VERSION_NTLMV2
NTLM version.
Definition: ntlm.h:162
A message digest algorithm.
Definition: crypto.h:18
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
union @383 key
Sense key.
Definition: scsi.h:18
struct mschapv2_nt_response nt
NT response.
Definition: mschapv2.h:16
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
void * memset(void *dest, int character, size_t len) __nonnull

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_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 266 of file ntlm.c.

270  {
271  void *tmp;
272  size_t nt_len;
273  size_t len;
274 
275  /* Construct response header */
276  if ( auth ) {
277  memset ( auth, 0, sizeof ( *auth ) );
279  sizeof ( auth->header.magic ) );
281  auth->flags = ntlm_negotiate.flags;
282  }
283  tmp = ( ( ( void * ) auth ) + sizeof ( *auth ) );
284 
285  /* Construct LAN Manager response */
286  if ( auth )
287  memcpy ( tmp, lm, sizeof ( *lm ) );
288  tmp = ntlm_append ( &auth->header, &auth->lm, tmp, sizeof ( *lm ) );
289 
290  /* Construct NT response */
291  nt_len = ( sizeof ( *nt ) + info->len + sizeof ( nt->zero ) );
292  if ( auth ) {
293  memcpy ( tmp, nt, sizeof ( *nt ) );
294  memcpy ( ( tmp + sizeof ( *nt ) ), info->target, info->len );
295  memset ( ( tmp + sizeof ( *nt ) + info->len ), 0,
296  sizeof ( nt->zero ) );
297  }
298  tmp = ntlm_append ( &auth->header, &auth->nt, tmp, nt_len );
299 
300  /* Populate domain, user, and workstation names */
301  tmp = ntlm_append_string ( &auth->header, &auth->domain, tmp, domain );
302  tmp = ntlm_append_string ( &auth->header, &auth->user, tmp, username );
303  tmp = ntlm_append_string ( &auth->header, &auth->workstation, tmp,
304  workstation );
305 
306  /* Calculate length */
307  len = ( tmp - ( ( void * ) auth ) );
308  if ( auth ) {
309  DBGC ( auth, "NTLM authenticate message:\n" );
310  DBGC_HDA ( auth, 0, auth, len );
311  }
312 
313  return len;
314 }
uint8_t magic[8]
Magic signature.
Definition: ntlm.h:19
u32 info
Definition: ar9003_mac.h:67
struct ntlm_data lm
LAN Manager response.
Definition: ntlm.h:120
#define DBGC(...)
Definition: compiler.h:505
struct ntlm_header header
Message header.
Definition: ntlm.h:118
Authenticate message.
Definition: ntlm.h:34
unsigned long tmp
Definition: linux_pci.h:63
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
#define cpu_to_le32(value)
Definition: byteswap.h:107
uint32_t flags
Negotiation flags.
Definition: ntlm.h:92
struct ntlm_data workstation
Workstation name.
Definition: ntlm.h:128
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:237
struct ntlm_data domain
Domain name.
Definition: ntlm.h:124
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:216
struct ntlm_header header
Message header.
Definition: ntlm.h:90
struct ntlm_data nt
NT response.
Definition: ntlm.h:122
uint32_t flags
Negotiation flags.
Definition: ntlm.h:132
struct ntlm_data user
User name.
Definition: ntlm.h:126
uint32_t type
Message type.
Definition: ntlm.h:21
static struct dynamic_item username
Definition: login_ui.c:35
uint32_t len
Length.
Definition: ena.h:14
struct mschapv2_nt_response nt
NT response.
Definition: mschapv2.h:16
void * memset(void *dest, int character, size_t len) __nonnull
A Negotiate message.
Definition: ntlm.h:88

References cpu_to_le32, DBGC, DBGC_HDA, ntlm_authenticate::domain, ntlm_negotiate::flags, ntlm_authenticate::flags, ntlm_negotiate::header, ntlm_authenticate::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 325 of file ntlm.c.

327  {
328 
329  return ntlm_authenticate ( info, domain, username, workstation,
330  NULL, NULL, NULL );
331 }
u32 info
Definition: ar9003_mac.h:67
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:266
static struct dynamic_item username
Definition: login_ui.c:35
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by http_ntlm_authenticate(), and ntlm_authenticate_okx().

Variable Documentation

◆ ntlm_negotiate

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 48 of file ntlm.c.