17void pc_ntlm_nt_hash(
const char *password, uint8_t nt_hash[16])
26 for (
const char *p = password; *p; p++)
28 uint8_t pair[2] = {(uint8_t)*p, 0};
34bool pc_ntlm_ntowfv2(
const uint8_t nt_hash[16],
const char *user,
const char *domain, uint8_t owf[16])
38 for (
const char *p = user; *p; p++)
41 if (up >=
'a' && up <=
'z')
45 if (n + 2 >
sizeof(buf))
49 buf[n++] = (uint8_t)up;
52 for (
const char *p = domain; *p; p++)
54 if (n + 2 >
sizeof(buf))
58 buf[n++] = (uint8_t)*p;
67static void pc_hmac_md5_2(
const uint8_t key[16],
const uint8_t *m1,
size_t l1,
const uint8_t *m2,
size_t l2,
72 for (
int i = 0; i < 64; i++)
74 uint8_t k = (i < 16) ? key[i] : 0;
75 ipad[i] = (uint8_t)(k ^ 0x36);
76 opad[i] = (uint8_t)(k ^ 0x5c);
99size_t pc_ntlm_v2_response(
const uint8_t owf[16],
const uint8_t server_challenge[8],
const uint8_t client_challenge[8],
100 const uint8_t timestamp[8],
const uint8_t *target_info,
size_t ti_len, uint8_t *out,
101 size_t out_cap, uint8_t session_key[16])
103 const size_t temp_len = 2 + 6 + 8 + 8 + 4 + ti_len + 4;
104 const size_t pc_resp_len = 16 + temp_len;
105 if (!out || pc_resp_len > out_cap)
111 uint8_t *temp = out + 16;
115 memset(temp + k, 0, 6);
117 memcpy(temp + k, timestamp, 8);
119 memcpy(temp + k, client_challenge, 8);
121 memset(temp + k, 0, 4);
123 memcpy(temp + k, target_info, ti_len);
125 memset(temp + k, 0, 4);
128 pc_hmac_md5_2(owf, server_challenge, 8, temp, temp_len, ntproof);
129 memcpy(out, ntproof, 16);
137size_t pc_ntlm_set_mic_flag(
const uint8_t *target_info,
size_t ti_len, uint8_t *out,
size_t out_cap)
139 if (!target_info || !out)
146 if (ti_len > out_cap)
150 memcpy(out, target_info, ti_len);
154 while (p + 4 <= ti_len)
156 uint16_t
id = (uint16_t)(out[p] | (out[p + 1] << 8));
157 uint16_t len = (uint16_t)(out[p + 2] | (out[p + 3] << 8));
163 if (
id == 6 && len == 4 && p + 8 <= ti_len)
168 if (p + 4 + len < p + 4)
181 if (ti_len + 8 > out_cap)
185 const size_t at = eol != ti_len ? eol : ti_len;
188 memmove(out + at + 8, out + at, ti_len - at);
201void pc_ntlm_mic(
const uint8_t session_key[16],
const uint8_t *neg,
size_t neg_len,
const uint8_t *chal,
202 size_t chal_len,
const uint8_t *auth,
size_t auth_len, uint8_t out[16])
207 for (
int i = 0; i < 64; i++)
209 uint8_t k = i < 16 ? session_key[i] : 0;
210 ipad[i] = (uint8_t)(k ^ 0x36);
211 opad[i] = (uint8_t)(k ^ 0x5c);
RAII scope guard for secure borrows - marks on entry, wipes and reclaims on every exit.
void pc_md5_init(MdCtx *c)
void pc_md4_init(MdCtx *c)
void pc_md4_update(MdCtx *c, const uint8_t *data, size_t len)
MdCtx * pc_md_wants(void)
Storage this module wants for one MD4/MD5 context.
void pc_md5_update(MdCtx *c, const uint8_t *data, size_t len)
void pc_md5_final(MdCtx *c, uint8_t out[16])
void pc_md4_final(MdCtx *c, uint8_t out[16])
void pc_hmac_md5(const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len, uint8_t out[16])
HMAC-MD5 (RFC 2104): the NTLMv2 MAC primitive.
MD4 (RFC 1320), MD5 (RFC 1321), and HMAC-MD5 (RFC 2104) - the legacy digests NTLM needs.
NTLMv2 response computation (MS-NLMP ยง3.3.2) for the SMB2 client (PC_ENABLE_SMB).
Secure pool accessor - borrows that hold key material.