ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ntlm.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#ifndef PROTOCORE_NTLM_H
5#define PROTOCORE_NTLM_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file ntlm.h
13 * @brief NTLMv2 response computation (MS-NLMP §3.3.2) for the SMB2 client (PROTOCORE_ENABLE_SMB).
14 *
15 * The auth core: from the user's password and the server's CHALLENGE (the 8-byte server challenge
16 * + the target-info AV_PAIR blob), compute the NtChallengeResponse and the session base key that
17 * seed SESSION_SETUP. Built on the KAT-verified MD4 / MD5 / HMAC-MD5 (crypto/hash/md.h). Pure, zero heap.
18 *
19 * NThash = MD4(UTF-16LE(password))
20 * NTOWFv2 = HMAC-MD5(NThash, UTF-16LE(Uppercase(user) + domain))
21 * temp = 0x01 0x01 Z(6) Time(8) ClientChallenge(8) Z(4) TargetInfo Z(4)
22 * NTProofStr = HMAC-MD5(NTOWFv2, ServerChallenge(8) + temp)
23 * NtChallengeResponse = NTProofStr(16) + temp
24 * SessionBaseKey = HMAC-MD5(NTOWFv2, NTProofStr)
25 *
26 * Verified against the MS-NLMP §4.2 worked example (test_ntlm).
27 *
28 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
29 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
30 * a caller drives every namespace the same way.
31 *
32 * @author Douglas Quigg (dstroy0)
33 * @date 2026
34 */
35
36// PROTOCORE_NTLM_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
37// it into its arena. Its size and its offset are each a static_assert, so a feature
38// combination that does not fit fails to compile rather than overrunning at run time.
39
40/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
41typedef struct
42{
43 void (*nt_hash)(uint8_t *, const char *, uint8_t *);
44 proto_bool (*ntowfv2)(uint8_t *, const uint8_t *, const char *, const char *, uint8_t *);
45 size_t (*v2_response)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *,
46 const uint8_t *, size_t, uint8_t *, size_t, uint8_t *);
47 size_t (*set_mic_flag)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t);
48 void (*mic)(uint8_t *, const uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t, const uint8_t *, size_t,
49 uint8_t *);
50} NtlmNs;
51PROTOCORE_NS_LAYOUT(NtlmNs, nt_hash, ntowfv2, v2_response, set_mic_flag, mic);
52
53/**
54 * @brief The NT hash: MD4 of the UTF-16LE password (password is ASCII/UTF-8, .
55 * @param work PROTOCORE_NTLM_BORROW bytes the caller took. Not held past the call.
56 * @param password Password
57 * @param nt_hash 16 bytes
58 */
59void protocore_ntlm_nt_hash(uint8_t *work, const char *password, uint8_t *nt_hash);
60/**
61 * @brief NTOWFv2 = HMAC-MD5(NThash, UTF-16LE(Uppercase(user) + domain)). .
62 * @param work PROTOCORE_NTLM_BORROW bytes the caller took. Not held past the call.
63 * @param nt_hash 16 bytes
64 * @param user User
65 * @param domain Domain
66 * @param owf 16 bytes
67 * @return PROTO_TRUE on success.
68 */
69proto_bool protocore_ntlm_ntowfv2(uint8_t *work, const uint8_t *nt_hash, const char *user, const char *domain,
70 uint8_t *owf);
71/**
72 * @brief Compute the NTLMv2 NtChallengeResponse (NTProofStr + temp) and the .
73 * @param work PROTOCORE_NTLM_BORROW bytes the caller took. Not held past the call.
74 * @param owf NTOWFv2 (from protocore_ntlm_ntowfv2) 16 bytes
75 * @param server_challenge the 8-byte challenge from the server's CHALLENGE_MESSAGE 8 bytes
76 * @param client_challenge the 8-byte client-generated challenge 8 bytes
77 * @param timestamp the 8-byte little-endian FILETIME (may be zero) 8 bytes
78 * @param target_info the AV_PAIR blob from the CHALLENGE_MESSAGE
79 * @param ti_len Ti len
80 * @param out Out
81 * @param out_cap Out cap
82 * @param session_key receives the 16-byte SessionBaseKey (may be null) 16 bytes
83 * @return The size_t.
84 */
85size_t protocore_ntlm_v2_response(uint8_t *work, const uint8_t *owf, const uint8_t *server_challenge,
86 const uint8_t *client_challenge, const uint8_t *timestamp, const uint8_t *target_info,
87 size_t ti_len, uint8_t *out, size_t out_cap, uint8_t *session_key);
88/**
89 * @brief Copy the CHALLENGE target-info AV_PAIR list into out, setting the .
90 * @param work PROTOCORE_NTLM_BORROW bytes the caller took. Not held past the call.
91 * @param target_info Target info
92 * @param ti_len Ti len
93 * @param out Out
94 * @param out_cap Out cap
95 * @return The size_t.
96 */
97size_t protocore_ntlm_set_mic_flag(uint8_t *work, const uint8_t *target_info, size_t ti_len, uint8_t *out,
98 size_t out_cap);
99/**
100 * @brief The NTLMSSP AUTHENTICATE MIC (MS-NLMP §3.1.5.1.2): HMAC-MD5 over .
101 * @param work PROTOCORE_NTLM_BORROW bytes the caller took. Not held past the call.
102 * @param session_key 16 bytes
103 * @param neg Neg
104 * @param neg_len Neg len
105 * @param chal Chal
106 * @param chal_len Chal len
107 * @param auth Auth
108 * @param auth_len Auth len
109 * @param out 16 bytes
110 */
111void protocore_ntlm_mic(uint8_t *work, const uint8_t *session_key, const uint8_t *neg, size_t neg_len,
112 const uint8_t *chal, size_t chal_len, const uint8_t *auth, size_t auth_len, uint8_t *out);
113
114/** @brief Module namespace. */
120
122
123#endif // PROTOCORE_NTLM_H
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
size_t protocore_ntlm_set_mic_flag(uint8_t *work, const uint8_t *target_info, size_t ti_len, uint8_t *out, size_t out_cap)
Copy the CHALLENGE target-info AV_PAIR list into out, setting the .
void protocore_ntlm_nt_hash(uint8_t *work, const char *password, uint8_t *nt_hash)
The NT hash: MD4 of the UTF-16LE password (password is ASCII/UTF-8, .
size_t protocore_ntlm_v2_response(uint8_t *work, const uint8_t *owf, const uint8_t *server_challenge, const uint8_t *client_challenge, const uint8_t *timestamp, const uint8_t *target_info, size_t ti_len, uint8_t *out, size_t out_cap, uint8_t *session_key)
Compute the NTLMv2 NtChallengeResponse (NTProofStr + temp) and the .
PROTOCORE_NS NtlmNs Ntlm PROTOCORE_UNUSED
Module namespace.
Definition ntlm.h:115
void protocore_ntlm_mic(uint8_t *work, const uint8_t *session_key, const uint8_t *neg, size_t neg_len, const uint8_t *chal, size_t chal_len, const uint8_t *auth, size_t auth_len, uint8_t *out)
The NTLMSSP AUTHENTICATE MIC (MS-NLMP §3.1.5.1.2): HMAC-MD5 over .
proto_bool protocore_ntlm_ntowfv2(uint8_t *work, const uint8_t *nt_hash, const char *user, const char *domain, uint8_t *owf)
NTOWFv2 = HMAC-MD5(NThash, UTF-16LE(Uppercase(user) + domain)). .
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition ntlm.h:42
void(* nt_hash)(uint8_t *, const char *, uint8_t *)
Definition ntlm.h:43
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97