iPXE
Data Structures | Defines | 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...

Defines

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

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)
struct ntlm_header __attribute__ ((packed))
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.
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

uint8_t magic [8]
 Magic signature.
uint32_t type
 Message type.
enum ntlm_type __attribute__
uint8_t major
 Product major version.
uint8_t minor
 Product minor version.
uint16_t build
 Product build number.
uint8_t reserved [3]
 Reserved.
uint8_t revision
 NTLMSSP revision.
uint8_t raw [8]
 Raw bytes.
uint16_t len
 Length (in bytes)
uint16_t max_len
 Maximum length (in bytes)
uint32_t offset
 Offset from start of message header.
struct ntlm_header header
 Message header.
uint32_t flags
 Negotiation flags.
struct ntlm_data domain
 Domain name.
struct ntlm_data workstation
 Workstation name.
struct ntlm_data name
 Target name.
struct ntlm_nonce nonce
 Server nonce.
struct ntlm_data info
 Target information.
struct ntlm_data lm
 LAN Manager response.
struct ntlm_data nt
 NT response.
struct ntlm_data user
 User name.
struct ntlm_data session
 Session key.
uint8_t digest [MD5_DIGEST_SIZE]
 HMAC-MD5 digest.
uint8_t version
 Response version.
uint8_t high
 Highest response version.
uint8_t reserved_a [6]
 Reserved.
uint64_t time
 Current time.
uint32_t zero
 Must be zero.
struct ntlm_negotiate ntlm_negotiate
 Negotiate message.

Detailed Description

NT LAN Manager (NTLM) authentication.

Definition in file ntlm.h.


Define Documentation

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

Magic signature.

Definition at line 25 of file ntlm.h.

#define NTLM_VERSION_NTLMV2   0x01

NTLM version.

Definition at line 162 of file ntlm.h.

Referenced by ntlm_response().


Enumeration Type Documentation

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.

               {
        /** Negotiate message type */
        NTLM_NEGOTIATE = 0x00000001UL,
        /** Challenge message type */
        NTLM_CHALLENGE = 0x00000002UL,
        /** Authenticate message */
        NTLM_AUTHENTICATE = 0x00000003UL,
};
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.

                {
        /** 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,
};

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
struct ntlm_header __attribute__ ( (packed)  )
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.

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

                                                        {
        size_t offset;

        DBGC ( challenge, "NTLM challenge message:\n" );
        DBGC_HDA ( challenge, 0, challenge, len );

        /* Sanity checks */
        if ( len < sizeof ( *challenge ) ) {
                DBGC ( challenge, "NTLM underlength challenge (%zd bytes)\n",
                       len );
                return -EINVAL;
        }

        /* Extract nonce */
        info->nonce = &challenge->nonce;
        DBGC ( challenge, "NTLM challenge nonce:\n" );
        DBGC_HDA ( challenge, 0, info->nonce, sizeof ( *info->nonce ) );

        /* Extract target information */
        info->len = le16_to_cpu ( challenge->info.len );
        offset = le32_to_cpu ( challenge->info.offset );
        if ( ( offset > len ) ||
             ( info->len > ( len - offset ) ) ) {
                DBGC ( challenge, "NTLM target information outside "
                       "challenge\n" );
                DBGC_HDA ( challenge, 0, challenge, len );
                return -EINVAL;
        }
        info->target = ( ( ( void * ) challenge ) + offset );
        DBGC ( challenge, "NTLM challenge target information:\n" );
        DBGC_HDA ( challenge, 0, info->target, info->len );

        return 0;
}
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.

References cpu_to_le16, ctx, DBGC, DBGC_HDA, digest, digest_final(), digest_init(), digest_update(), hmac_final(), hmac_init(), hmac_update(), md4_algorithm, MD4_CTX_SIZE, MD4_DIGEST_SIZE, md5_algorithm, MD5_CTX_SIZE, ntlm_key::raw, toupper(), and wc.

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

                                                             {
        struct digest_algorithm *md4 = &md4_algorithm;
        struct digest_algorithm *md5 = &md5_algorithm;
        union {
                uint8_t md4[MD4_CTX_SIZE];
                uint8_t md5[MD5_CTX_SIZE];
        } ctx;
        uint8_t digest[MD4_DIGEST_SIZE];
        size_t digest_len;
        uint8_t c;
        uint16_t wc;

        /* Use empty usernames/passwords if not specified */
        if ( ! domain )
                domain = "";
        if ( ! username )
                username = "";
        if ( ! password )
                password = "";

        /* Construct MD4 digest of (Unicode) password */
        digest_init ( md4, ctx.md4 );
        while ( ( c = *(password++) ) ) {
                wc = cpu_to_le16 ( c );
                digest_update ( md4, ctx.md4, &wc, sizeof ( wc ) );
        }
        digest_final ( md4, ctx.md4, digest );

        /* Construct HMAC-MD5 of (Unicode) upper-case username */
        digest_len = sizeof ( digest );
        hmac_init ( md5, ctx.md5, digest, &digest_len );
        while ( ( c = *(username++) ) ) {
                wc = cpu_to_le16 ( toupper ( c ) );
                hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
        }
        while ( ( c = *(domain++) ) ) {
                wc = cpu_to_le16 ( c );
                hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
        }
        hmac_final ( md5, ctx.md5, digest, &digest_len, key->raw );
        DBGC ( key, "NTLM key:\n" );
        DBGC_HDA ( key, 0, key, sizeof ( *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.

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

References ctx, DBGC, DBGC_HDA, ntlm_lm_response::digest, ntlm_nt_response::digest, ntlm_nt_response::high, hmac_final(), hmac_init(), hmac_update(), ntlm_challenge_info::len, md5_algorithm, MD5_CTX_SIZE, memcpy(), memset(), ntlm_lm_response::nonce, ntlm_nt_response::nonce, ntlm_challenge_info::nonce, NTLM_VERSION_NTLMV2, offsetof, random(), ntlm_nonce::raw, ntlm_key::raw, ntlm_challenge_info::target, ntlm_nt_response::version, version, and ntlm_nt_response::zero.

Referenced by http_ntlm_authenticate(), and ntlm_authenticate_okx().

                                                   {
        struct digest_algorithm *md5 = &md5_algorithm;
        struct ntlm_nonce tmp_nonce;
        uint8_t ctx[MD5_CTX_SIZE];
        size_t key_len = sizeof ( *key );
        unsigned int i;

        /* Generate random nonce, if needed */
        if ( ! nonce ) {
                for ( i = 0 ; i < sizeof ( tmp_nonce ) ; i++ )
                        tmp_nonce.raw[i] = random();
                nonce = &tmp_nonce;
        }

        /* Construct LAN Manager response */
        memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
        hmac_init ( md5, ctx, key->raw, &key_len );
        hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
        hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->nonce ) );
        hmac_final ( md5, ctx, key->raw, &key_len, lm->digest );
        DBGC ( key, "NTLM LAN Manager response:\n" );
        DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );

        /* Construct NT response */
        memset ( nt, 0, sizeof ( *nt ) );
        nt->version = NTLM_VERSION_NTLMV2;
        nt->high = NTLM_VERSION_NTLMV2;
        memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
        hmac_init ( md5, ctx, key->raw, &key_len );
        hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
        hmac_update ( md5, ctx, &nt->version,
                      ( sizeof ( *nt ) -
                        offsetof ( typeof ( *nt ), version ) ) );
        hmac_update ( md5, ctx, info->target, info->len );
        hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
        hmac_final ( md5, ctx, key->raw, &key_len, nt->digest );
        DBGC ( key, "NTLM NT response prefix:\n" );
        DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
}
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 269 of file ntlm.c.

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

Referenced by http_format_ntlm_auth(), and ntlm_authenticate_len().

                                                            {
        void *tmp;
        size_t nt_len;
        size_t len;

        /* Construct response header */
        if ( auth ) {
                memset ( auth, 0, sizeof ( *auth ) );
                memcpy ( auth->header.magic, ntlm_negotiate.header.magic,
                         sizeof ( auth->header.magic ) );
                auth->header.type = cpu_to_le32 ( NTLM_AUTHENTICATE );
                auth->flags = ntlm_negotiate.flags;
        }
        tmp = ( ( ( void * ) auth ) + sizeof ( *auth ) );

        /* Construct LAN Manager response */
        if ( auth )
                memcpy ( tmp, lm, sizeof ( *lm ) );
        tmp = ntlm_append ( &auth->header, &auth->lm, tmp, sizeof ( *lm ) );

        /* Construct NT response */
        nt_len = ( sizeof ( *nt ) + info->len + sizeof ( nt->zero ) );
        if ( auth ) {
                memcpy ( tmp, nt, sizeof ( *nt ) );
                memcpy ( ( tmp + sizeof ( *nt ) ), info->target, info->len );
                memset ( ( tmp + sizeof ( *nt ) + info->len ), 0,
                         sizeof ( nt->zero ) );
        }
        tmp = ntlm_append ( &auth->header, &auth->nt, tmp, nt_len );

        /* Populate domain, user, and workstation names */
        tmp = ntlm_append_string ( &auth->header, &auth->domain, tmp, domain );
        tmp = ntlm_append_string ( &auth->header, &auth->user, tmp, username );
        tmp = ntlm_append_string ( &auth->header, &auth->workstation, tmp,
                                   workstation );

        /* Calculate length */
        len = ( tmp - ( ( void * ) auth ) );
        if ( auth ) {
                DBGC ( auth, "NTLM authenticate message:\n" );
                DBGC_HDA ( auth, 0, auth, len );
        }

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

References ntlm_authenticate(), and NULL.

Referenced by http_ntlm_authenticate(), and ntlm_authenticate_okx().

                                                         {

        return ntlm_authenticate ( info, domain, username, workstation,
                                   NULL, NULL, NULL );
}

Variable Documentation

Message type.

Definition at line 26 of file ntlm.h.

Product major version.

Definition at line 67 of file ntlm.h.

Product minor version.

Definition at line 69 of file ntlm.h.

Product build number.

Definition at line 71 of file ntlm.h.

Reserved.

Definition at line 73 of file ntlm.h.

NTLMSSP revision.

Definition at line 75 of file ntlm.h.

Raw bytes.

Definition at line 73 of file ntlm.h.

Length (in bytes)

Definition at line 87 of file ntlm.h.

Offset from start of message header.

Definition at line 95 of file ntlm.h.

Message header.

Definition at line 99 of file ntlm.h.

Negotiation flags.

Definition at line 101 of file ntlm.h.

struct ntlm_data domain

Domain name.

Definition at line 103 of file ntlm.h.

Referenced by http_format_ntlm_auth(), http_ntlm_authenticate(), linux_socket(), and syslog_send().

Workstation name.

Definition at line 105 of file ntlm.h.

struct ntlm_data name

Target name.

Definition at line 117 of file ntlm.h.

struct ntlm_nonce nonce

Server nonce.

Client nonce.

Definition at line 121 of file ntlm.h.

Referenced by get_entropy_input_tmp(), and make_next_nonce().

struct ntlm_data info

Target information.

Definition at line 125 of file ntlm.h.

struct ntlm_data lm

LAN Manager response.

Definition at line 137 of file ntlm.h.

struct ntlm_data nt

NT response.

Definition at line 139 of file ntlm.h.

struct ntlm_data user

User name.

Definition at line 143 of file ntlm.h.

Referenced by fc_ulp_login(), fc_ulp_logout(), and fc_ulp_user_get().

Session key.

Definition at line 147 of file ntlm.h.

Referenced by xsmp_session_name().

HMAC-MD5 digest.

Definition at line 143 of file ntlm.h.

Response version.

Definition at line 163 of file ntlm.h.

Highest response version.

Definition at line 165 of file ntlm.h.

Reserved.

Definition at line 167 of file ntlm.h.

Must be zero.

Definition at line 173 of file ntlm.h.

Referenced by b44_set_rx_mode(), genesis_mac_init(), genesis_reset(), profile_test_exec(), rsa_decrypt(), and string_test_exec().

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.