ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
smb2.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_SMB2_H
5#define PROTOCORE_SMB2_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file smb2.h
13 * @brief SMB2 client wire codec (MS-SMB2), PROTOCORE_ENABLE_SMB - increment 1: the transport
14frame, the 64-byte sync packet header, and the NEGOTIATE exchange.
15 *
16 * Windows-share program storage is a common CNC file path (Fanuc / Haas / Mazak / Heidenhain
17 * expose one), so a device can read/write `.nc` files over SMB2. This is the pure wire layer:
18 * build the little-endian SMB2 messages and parse the responses; the TCP socket is the
19 * application's. All fields are little-endian (SMB2 is a little-endian protocol).
20 *
21 * A client speaks SMB2 over Direct TCP (port 445): each message is prefixed by a 4-byte transport
22 * header (`0x00` + a 24-bit big-endian length), then the 64-byte SMB2 sync header (MS-SMB2
23 * §2.2.1.2), then the per-command body. The exchange begins with NEGOTIATE (§2.2.3 request /
24 * §2.2.4 response): the client offers a dialect list, the server picks one and returns the SPNEGO
25 * security token that seeds authentication.
26 *
27 * Shipped: the NEGOTIATE exchange; the NTLM crypto (smb_md / ntlm / ntlmssp); the SPNEGO wrapping
28 * (spnego); the SESSION_SETUP request/response framing that carries those tokens; and the
29 * TREE_CONNECT / CREATE / CLOSE / READ / WRITE file commands - the full read/write-a-file-on-a-share
30 * client; **SMB 2.x message signing** (protocore_smb2_sign / protocore_smb2_verify, HMAC-SHA256) wired into the
31 * client's SigningRequired path; and the **SMB 3.1.1 negotiate-context codec** (protocore_smb2_build_negotiate_311
32 * / protocore_smb2_parse_negotiate_contexts - preauth-integrity SHA-512, signing, and encryption capabilities);
33 * and the **SP800-108 counter-mode KDF** (protocore_kdf_ctr_hmac_sha256 in src/crypto/kdf, NIST-CAVP-verified) that
34 * SMB 3.x uses to derive its keys. **SMB 3.1.1 runs end to end:** the client offers 2.0.2 .. 3.1.1, chains
35 * the preauth-integrity hash (protocore_smb_preauth_*) across NEGOTIATE + both SESSION_SETUP rounds, derives the
36 * signing key (derive_signing_key), and signs the session with AES-128-CMAC (protocore_smb2_sign_cmac /
37 * _verify_cmac; crypto/aes_cmac) - the KDF assembly + CMAC cross-checked byte-for-byte against impacket.
38 *
39 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
40 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
41 * a caller drives every namespace the same way.
42 *
43 * @author Douglas Quigg (dstroy0)
44 * @date 2026
45 */
46
47// PROTOCORE_SMB2_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
48// it into its arena. Its size and its offset are each a static_assert, so a feature
49// combination that does not fit fails to compile rather than overrunning at run time.
50
51/** @brief Fixed SMB2 sync header size (MS-SMB2 §2.2.1). */
52#define PROTOCORE_SMB2_HEADER_SIZE 64
53
54/** @brief NEGOTIATE / SESSION_SETUP SecurityMode flags (MS-SMB2 §2.2.3). */
55#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x0001
56#define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x0002
57
58/** @brief SMB2 header Flags field (MS-SMB2 §2.2.1.2). */
59#define SMB2_FLAGS_SERVER_TO_REDIR 0x00000001 ///< set on a response (server -> client)
60#define SMB2_FLAGS_SIGNED 0x00000008 ///< the message carries an HMAC signature
61
62/** @brief SESSION_SETUP response SessionFlags (MS-SMB2 §2.2.6). */
63#define SMB2_SESSION_FLAG_IS_GUEST 0x0001
64#define SMB2_SESSION_FLAG_IS_NULL 0x0002
65#define SMB2_SESSION_FLAG_ENCRYPT_DATA 0x0004
66
67/** @brief NT status values seen in the SMB2 header during the SESSION_SETUP exchange. */
68#define SMB2_STATUS_SUCCESS 0x00000000
69#define SMB2_STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 ///< server wants the next round
70#define SMB2_STATUS_END_OF_FILE 0xC0000011 ///< a READ at/past end of file
71
72/** @brief TREE_CONNECT response ShareType (MS-SMB2 §2.2.10). */
73#define SMB2_SHARE_TYPE_DISK 0x01
74#define SMB2_SHARE_TYPE_PIPE 0x02
75#define SMB2_SHARE_TYPE_PRINT 0x03
76
77/** @brief CREATE DesiredAccess masks (MS-DTYP ACCESS_MASK; the common file rights). */
78#define SMB2_FILE_READ_DATA 0x00000001
79#define SMB2_FILE_WRITE_DATA 0x00000002
80#define SMB2_FILE_APPEND_DATA 0x00000004
81#define SMB2_FILE_READ_ATTRIBUTES 0x00000080
82#define SMB2_FILE_GENERIC_READ 0x00120089 ///< RC|SYNC|READ_ATTR|READ_EA|READ_DATA
83#define SMB2_FILE_GENERIC_WRITE 0x00120116 ///< RC|SYNC|WRITE_ATTR|WRITE_EA|APPEND|WRITE
84
85/** @brief CREATE ShareAccess (MS-SMB2 §2.2.13). */
86#define SMB2_FILE_SHARE_READ 0x01
87#define SMB2_FILE_SHARE_WRITE 0x02
88#define SMB2_FILE_SHARE_DELETE 0x04
89
90/** @brief CREATE CreateDisposition (MS-SMB2 §2.2.13). */
91#define SMB2_FILE_SUPERSEDE 0
92#define SMB2_FILE_OPEN 1 ///< open an existing file, fail if absent
93#define SMB2_FILE_CREATE 2 ///< create, fail if it exists
94#define SMB2_FILE_OPEN_IF 3 ///< open, create if absent
95#define SMB2_FILE_OVERWRITE 4 ///< open + truncate, fail if absent
96#define SMB2_FILE_OVERWRITE_IF 5
97
98/** @brief CREATE CreateOptions (MS-SMB2 §2.2.13; the two we set). */
99#define SMB2_FILE_DIRECTORY_FILE 0x00000001
100#define SMB2_FILE_NON_DIRECTORY_FILE 0x00000040
101
102/** @brief SMB 3.1.1 negotiate-context types (MS-SMB2 §2.2.3.1). */
103#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
104#define SMB2_ENCRYPTION_CAPABILITIES 0x0002
105#define SMB2_COMPRESSION_CAPABILITIES 0x0003
106#define SMB2_NETNAME_NEGOTIATE_CONTEXT_ID 0x0005
107#define SMB2_TRANSPORT_CAPABILITIES 0x0006
108#define SMB2_RDMA_TRANSFORM_CAPABILITIES 0x0007
109#define SMB2_SIGNING_CAPABILITIES 0x0008
110
111/** @brief Preauth-integrity hash algorithm IDs (MS-SMB2 §2.2.3.1.1). */
112#define SMB2_PREAUTH_INTEGRITY_SHA512 0x0001
113
114/** @brief Signing algorithm IDs (MS-SMB2 §2.2.3.1.7). */
115#define SMB2_SIGNING_HMAC_SHA256 0x0000
116#define SMB2_SIGNING_AES_CMAC 0x0001
117#define SMB2_SIGNING_AES_GMAC 0x0002
118
119/** @brief NEGOTIATE request/response Capabilities flags (MS-SMB2 §2.2.3 / §2.2.4). A client that supports
120 * transport encryption MUST advertise SMB2_GLOBAL_CAP_ENCRYPTION here, or a server (e.g. Samba with
121 * `smb encrypt = required`) will not negotiate a cipher and will reject the unencrypted session (§3.2.4.2.2). */
122#define SMB2_GLOBAL_CAP_ENCRYPTION 0x00000040
123
124/** @brief Encryption cipher IDs (MS-SMB2 §2.2.3.1.2). */
125#define SMB2_ENCRYPTION_AES128_CCM 0x0001
126#define SMB2_ENCRYPTION_AES128_GCM 0x0002
127#define SMB2_ENCRYPTION_AES256_CCM 0x0003
128#define SMB2_ENCRYPTION_AES256_GCM 0x0004
129
130/** @brief Max encryption ciphers a NEGOTIATE request can advertise (the four SMB 3.1.1 ciphers). */
131#define PROTOCORE_SMB2_MAX_OFFER_CIPHERS 4
132
133/** @brief Length of the SMB 3.1.1 preauth-integrity hash (SHA-512 digest size). */
134#define PROTOCORE_SMB2_PREAUTH_HASH_LEN 64
135
136/** @brief TREE_CONNECT response ShareFlags of interest (MS-SMB2 §2.2.10). */
137#define SMB2_SHAREFLAG_ENCRYPT_DATA 0x00008000 ///< the share mandates SMB3 encryption
138
139/** @brief TRANSFORM_HEADER size: ProtocolId(4)+Signature(16)+Nonce(16)+OriginalMessageSize(4)+Reserved(2)+
140 * Flags(2)+SessionId(8) = 52 bytes (MS-SMB2 §2.2.41). */
141#define PROTOCORE_SMB2_TRANSFORM_HDR_LEN 52
142
143/** @brief TRANSFORM_HEADER ProtocolId 0xFD 'S' 'M' 'B' as a little-endian u32. */
144#define PROTOCORE_SMB2_TRANSFORM_PROTOCOL_ID 0x424D53FDu
145
146/** @brief The TRANSFORM_HEADER Nonce field width (MS-SMB2 §2.2.41). The AEAD uses the leading
147 * protocore_smb2_cipher_nonce_len() bytes; the rest are zero. */
148#define PROTOCORE_SMB2_NONCE_FIELD_LEN 16
149
150/** @brief AES-GCM nonce length used within the 16-byte Nonce field. */
151#define PROTOCORE_SMB2_GCM_NONCE_LEN 12
152
153/** @brief AES-CCM nonce length used within the 16-byte Nonce field (MS-SMB2 §3.1.4.3). */
154#define PROTOCORE_SMB2_CCM_NONCE_LEN 11
155
156/** @brief Largest cipher key length across the four SMB 3.1.1 ciphers (AES-256), for buffer sizing. */
157#define PROTOCORE_SMB2_MAX_CIPHER_KEY_LEN 32
158
159/** @brief SMB2 command codes (MS-SMB2 §2.2.1.2). */
172
173/** @brief SMB2 dialect revision numbers (MS-SMB2 §2.2.4). */
175{
176 SMB2_DIALECT_0202 = 0x0202, ///< SMB 2.0.2
177 SMB2_DIALECT_0210 = 0x0210, ///< SMB 2.1
178 SMB2_DIALECT_0300 = 0x0300, ///< SMB 3.0
179 SMB2_DIALECT_0302 = 0x0302, ///< SMB 3.0.2
180 SMB2_DIALECT_0311 = 0x0311, ///< SMB 3.1.1
182
183/** @brief Parsed SMB2 sync header. */
184typedef struct
185{
187 uint32_t status; ///< NT status (response); 0 = STATUS_SUCCESS
188 uint32_t flags;
189 uint64_t message_id;
190 uint32_t tree_id;
191 uint64_t session_id;
193} Smb2Header;
194
195/** @brief Parsed SMB 3.1.1 NEGOTIATE-response negotiate contexts (MS-SMB2 §2.2.4 / §2.2.3.1). */
196typedef struct
197{
198 proto_bool have_preauth; ///< a PREAUTH_INTEGRITY_CAPABILITIES context was present
199 uint16_t hash_algorithm; ///< the server's chosen preauth hash (expect SMB2_PREAUTH_INTEGRITY_SHA512)
200 const uint8_t *salt; ///< the preauth-integrity salt (points into msg), or nullptr
201 uint16_t salt_len; ///< length of @ref salt
202 proto_bool have_signing; ///< a SIGNING_CAPABILITIES context was present
203 uint16_t signing_algorithm; ///< the server's chosen signing algorithm
204 proto_bool have_encryption; ///< an ENCRYPTION_CAPABILITIES context was present
205 uint16_t cipher; ///< the server's chosen cipher
207
208/** @brief Parsed NEGOTIATE response (MS-SMB2 §2.2.4). */
209typedef struct
210{
212 uint16_t dialect; ///< the DialectRevision the server chose
213 uint8_t server_guid[16];
214 uint32_t capabilities;
215 uint32_t max_transact;
216 uint32_t max_read;
217 uint32_t max_write;
218 const uint8_t *sec_buf; ///< SPNEGO/NTLM security token (points into @p msg), or nullptr
219 uint16_t sec_buf_len;
221
222/**
223 * @brief The SMB 3.1.1 preauth-integrity hash value (MS-SMB2 §3.1.5.2): a running SHA-512 chained over
224 * every NEGOTIATE and SESSION_SETUP message of the handshake. Its final value binds the whole
225 * pre-authentication exchange and feeds the 3.1.1 signing / encryption key derivation.
226 */
227typedef struct
228{
230} SmbPreauth;
231
232/** @brief Parsed SESSION_SETUP response (MS-SMB2 §2.2.6). */
233typedef struct
234{
236 const uint8_t *sec_buf; ///< the server's SPNEGO/NTLM token (points into @p msg), or nullptr
237 uint16_t sec_buf_len;
239
240/** @brief Parsed TREE_CONNECT response (MS-SMB2 §2.2.10). The TreeId is in the response header. */
241typedef struct
242{
243 uint8_t share_type;
244 uint32_t share_flags;
245 uint32_t capabilities;
248
249/** @brief Parsed CREATE response (MS-SMB2 §2.2.14). */
250typedef struct
251{
252 uint8_t file_id[16]; ///< the open handle (persistent 8 + volatile 8), for READ/WRITE/CLOSE
253 uint64_t end_of_file;
257
258/** @brief Parsed CLOSE response (MS-SMB2 §2.2.16). */
259typedef struct
260{
261 uint64_t end_of_file;
264
265/** @brief Parsed READ response (MS-SMB2 §2.2.20). */
266typedef struct
267{
268 const uint8_t *data; ///< the file bytes read (points into @p msg), or nullptr when DataLength is 0
269 uint32_t data_len;
271
272/** @brief Parsed WRITE response (MS-SMB2 §2.2.22). */
273typedef struct
274{
275 uint32_t count; ///< bytes actually written
277
278/** @brief The per-session message-signing algorithm the client selects from the negotiated dialect. */
280{
281 SMB2_SIGN_ALGO_HMAC_SHA256 = 0, ///< SMB 2.0.2 / 2.1 (key = the NTLMv2 session key)
282 SMB2_SIGN_ALGO_AES_CMAC = 1, ///< SMB 3.0 / 3.0.2 / 3.1.1 (key = the SP800-108-derived signing key)
284
285/** @brief AES key length in bytes for an SMB2 cipher id: 16 for the -128 ciphers, 32 for the -256 ciphers,
286 * 0 if @p cipher is not a recognized cipher id. */
287static inline size_t protocore_smb2_cipher_key_len(uint16_t cipher)
288{
289 switch (cipher)
290 {
293 return 16;
296 return 32;
297 default:
298 return 0;
299 }
300}
301
302/** @brief AEAD nonce length in bytes for an SMB2 cipher id: 12 for the GCM ciphers, 11 for the CCM ciphers
303 * (MS-SMB2 §3.1.4.3), 0 if unrecognized. Both are written into the 16-byte TRANSFORM_HEADER Nonce
304 * field with the remaining bytes zero. */
305static inline size_t protocore_smb2_cipher_nonce_len(uint16_t cipher)
306{
307 switch (cipher)
308 {
311 return 12;
314 return 11;
315 default:
316 return 0;
317 }
318}
319
320/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
321typedef struct
322{
323 size_t (*transport_frame)(uint8_t *, uint8_t *, size_t, const uint8_t *, size_t);
324 uint32_t (*transport_len)(uint8_t *, const uint8_t *, size_t);
325 size_t (*build_header)(uint8_t *, uint8_t *, size_t, Smb2Command, uint16_t, uint64_t, uint32_t, uint64_t);
326 proto_bool (*parse_header)(uint8_t *, const uint8_t *, size_t, Smb2Header *);
327 size_t (*build_negotiate)(uint8_t *, uint8_t *, size_t, const uint8_t *, uint16_t);
328 proto_bool (*parse_negotiate_response)(uint8_t *, const uint8_t *, size_t, Smb2NegotiateResp *);
329 size_t (*build_negotiate_311)(uint8_t *, uint8_t *, size_t, const uint8_t *, uint16_t, const uint8_t *, size_t,
330 const uint16_t *, size_t);
331 proto_bool (*parse_negotiate_contexts)(uint8_t *, const uint8_t *, size_t, Smb2NegotiateContexts *);
332 void (*preauth_init)(uint8_t *, SmbPreauth *);
333 void (*preauth_update)(uint8_t *, uint8_t *, SmbPreauth *, const uint8_t *, size_t);
334 size_t (*build_session_setup)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, uint8_t, const uint8_t *, size_t);
335 proto_bool (*parse_session_setup_response)(uint8_t *, const uint8_t *, size_t, Smb2SessionSetupResp *);
336 size_t (*build_tree_connect)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, const uint8_t *, size_t);
337 proto_bool (*parse_tree_connect_response)(uint8_t *, const uint8_t *, size_t, Smb2TreeConnectResp *);
338 size_t (*build_create)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, uint32_t, uint32_t, uint32_t, uint32_t,
339 uint32_t, const uint8_t *, size_t);
340 proto_bool (*parse_create_response)(uint8_t *, const uint8_t *, size_t, Smb2CreateResp *);
341 size_t (*build_close)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, uint32_t, const uint8_t *);
342 proto_bool (*parse_close_response)(uint8_t *, const uint8_t *, size_t, Smb2CloseResp *);
343 size_t (*build_read)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, uint32_t, const uint8_t *, uint32_t,
344 uint64_t);
345 proto_bool (*parse_read_response)(uint8_t *, const uint8_t *, size_t, Smb2ReadResp *);
346 size_t (*build_write)(uint8_t *, uint8_t *, size_t, uint64_t, uint64_t, uint32_t, const uint8_t *, const uint8_t *,
347 size_t, uint64_t);
348 proto_bool (*parse_write_response)(uint8_t *, const uint8_t *, size_t, Smb2WriteResp *);
349 void (*sign)(uint8_t *, uint8_t *, const uint8_t *, uint8_t *, size_t);
350 proto_bool (*verify)(uint8_t *, uint8_t *, const uint8_t *, uint8_t *, size_t);
351 void (*sign_cmac)(uint8_t *, uint8_t *, const uint8_t *, uint8_t *, size_t);
352 proto_bool (*verify_cmac)(uint8_t *, uint8_t *, const uint8_t *, uint8_t *, size_t);
353 proto_bool (*derive_signing_key)(uint8_t *, const uint8_t *, uint16_t, const uint8_t *, uint8_t *);
354 proto_bool (*derive_encryption_keys)(uint8_t *, const uint8_t *, uint16_t, const uint8_t *, size_t, uint8_t *,
355 uint8_t *);
356 size_t (*encrypt)(uint8_t *, uint16_t, const uint8_t *, const uint8_t *, uint64_t, const uint8_t *, size_t,
357 uint8_t *, size_t);
358 size_t (*decrypt)(uint8_t *, uint16_t, const uint8_t *, const uint8_t *, size_t, uint8_t *, size_t);
359} Smb2Ns;
360PROTOCORE_NS_LAYOUT(Smb2Ns, transport_frame, transport_len, build_header, parse_header, build_negotiate,
361 parse_negotiate_response, build_negotiate_311, parse_negotiate_contexts, preauth_init,
362 preauth_update, build_session_setup, parse_session_setup_response, build_tree_connect,
363 parse_tree_connect_response, build_create, parse_create_response, build_close, parse_close_response,
364 build_read, parse_read_response, build_write, parse_write_response, sign, verify, sign_cmac,
365 verify_cmac, derive_signing_key, derive_encryption_keys, encrypt, decrypt);
366
367/**
368 * @brief Prefix an SMB2 message with the 4-byte Direct-TCP transport header .
369 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
370 * @param out Out
371 * @param cap Cap
372 * @param msg Msg
373 * @param msg_len Msg len
374 * @return The size_t.
375 */
376size_t protocore_smb2_transport_frame(uint8_t *work, uint8_t *out, size_t cap, const uint8_t *msg, size_t msg_len);
377/**
378 * @brief Read the Direct-TCP transport length prefix.
379 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
380 * @param buf Buf
381 * @param len Len
382 * @return The uint32_t.
383 */
384uint32_t protocore_smb2_transport_len(uint8_t *work, const uint8_t *buf, size_t len);
385/**
386 * @brief Build a 64-byte SMB2 sync header into buf.
387 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
388 * @param buf Buf
389 * @param cap Cap
390 * @param command Command
391 * @param credit_request Credit request
392 * @param message_id Message id
393 * @param tree_id Tree id
394 * @param session_id Session id
395 * @return The size_t.
396 */
397size_t protocore_smb2_build_header(uint8_t *work, uint8_t *buf, size_t cap, Smb2Command command,
398 uint16_t credit_request, uint64_t message_id, uint32_t tree_id, uint64_t session_id);
399/**
400 * @brief Parse a 64-byte SMB2 sync header (validates ProtocolId + .
401 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
402 * @param buf Buf
403 * @param len Len
404 * @param out Out
405 * @return PROTO_TRUE on success.
406 */
407proto_bool protocore_smb2_parse_header(uint8_t *work, const uint8_t *buf, size_t len, Smb2Header *out);
408/**
409 * @brief Build a NEGOTIATE request (header + body) offering SMB 2.0.2 / 2.1 .
410 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
411 * @param buf Buf
412 * @param cap Cap
413 * @param client_guid the 16-byte client GUID 16 bytes
414 * @param security_mode SMB2_NEGOTIATE_SIGNING_ENABLED and/or _REQUIRED
415 * @return The size_t.
416 */
417size_t protocore_smb2_build_negotiate(uint8_t *work, uint8_t *buf, size_t cap, const uint8_t *client_guid,
418 uint16_t security_mode);
419/**
420 * @brief Parse a NEGOTIATE response message (the SMB2 header + §2.2.4 body).
421 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
422 * @param msg the SMB2 message (starting at the sync header, transport prefix already stripped)
423 * @param len Len
424 * @param out Out
425 * @return PROTO_TRUE on success.
426 */
427proto_bool protocore_smb2_parse_negotiate_response(uint8_t *work, const uint8_t *msg, size_t len,
428 Smb2NegotiateResp *out);
429/**
430 * @brief Build an SMB 3.1.1 NEGOTIATE request: the dialect list SMB 2.0.2 .. .
431 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
432 * @param buf Buf
433 * @param cap Cap
434 * @param client_guid 16 bytes
435 * @param security_mode Security mode
436 * @param salt the preauth-integrity salt (a fresh random blob the client keeps for the hash chain)
437 * @param salt_len salt length in bytes (>= 1); a common choice is 32
438 * @param ciphers cipher ids to offer, most-preferred first (a server picks the first it supports, in this
439 * @param cipher_count number of entries in ciphers (0 .. PROTOCORE_SMB2_MAX_OFFER_CIPHERS)
440 * @return The size_t.
441 */
442size_t protocore_smb2_build_negotiate_311(uint8_t *work, uint8_t *buf, size_t cap, const uint8_t *client_guid,
443 uint16_t security_mode, const uint8_t *salt, size_t salt_len,
444 const uint16_t *ciphers, size_t cipher_count);
445/**
446 * @brief Walk the negotiate-context list of a 3.1.1 NEGOTIATE response .
447 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
448 * @param msg Msg
449 * @param len Len
450 * @param out Out
451 * @return PROTO_TRUE on success.
452 */
453proto_bool protocore_smb2_parse_negotiate_contexts(uint8_t *work, const uint8_t *msg, size_t len,
455/**
456 * @brief Seed the preauth-integrity hash with 64 zero bytes (the initial .
457 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
458 * @param p P
459 */
461/**
462 * @brief Fold one handshake message into the preauth-integrity hash: hash = .
463 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
464 * @param crypto_work Crypto work
465 * @param p P
466 * @param msg Msg
467 * @param len Len
468 */
469void protocore_smb2_preauth_update(uint8_t *work, uint8_t *crypto_work, SmbPreauth *p, const uint8_t *msg, size_t len);
470/**
471 * @brief Build a SESSION_SETUP request (header + §2.2.5 body) carrying a .
472 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
473 * @param buf Buf
474 * @param cap Cap
475 * @param message_id the SMB2 MessageId (increments across the exchange)
476 * @param session_id 0 on the first round; the server-assigned SessionId on the second
477 * @param security_mode SMB2_NEGOTIATE_SIGNING_ENABLED and/or _REQUIRED (one byte on the wire)
478 * @param sec_buf Sec buf
479 * @param sec_len Sec len
480 * @return The size_t.
481 */
482size_t protocore_smb2_build_session_setup(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id,
483 uint64_t session_id, uint8_t security_mode, const uint8_t *sec_buf,
484 size_t sec_len);
485/**
486 * @brief Parse a SESSION_SETUP response message (the SMB2 header + §2.2.6 .
487 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
488 * @param msg the SMB2 message (starting at the sync header, transport prefix already stripped)
489 * @param len Len
490 * @param out Out
491 * @return PROTO_TRUE on success.
492 */
493proto_bool protocore_smb2_parse_session_setup_response(uint8_t *work, const uint8_t *msg, size_t len,
495/**
496 * @brief Build a TREE_CONNECT request (header + §2.2.9 body) for a share path.
497 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
498 * @param buf Buf
499 * @param cap Cap
500 * @param message_id Message id
501 * @param session_id Session id
502 * @param path_utf16 the UNC path `\\server\share` in UTF-16LE (no NUL); path_len its byte length
503 * @param path_len Path len
504 * @return The size_t.
505 */
506size_t protocore_smb2_build_tree_connect(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id,
507 uint64_t session_id, const uint8_t *path_utf16, size_t path_len);
508/**
509 * @brief Parse a TREE_CONNECT response message (validates command + .
510 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
511 * @param msg Msg
512 * @param len Len
513 * @param out Out
514 * @return PROTO_TRUE on success.
515 */
516proto_bool protocore_smb2_parse_tree_connect_response(uint8_t *work, const uint8_t *msg, size_t len,
518/**
519 * @brief Build a CREATE request (header + §2.2.13 body) to open/create a .
520 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
521 * @param buf Buf
522 * @param cap Cap
523 * @param message_id Message id
524 * @param session_id Session id
525 * @param tree_id Tree id
526 * @param desired_access e.g. SMB2_FILE_GENERIC_READ / _WRITE
527 * @param share_access SMB2_FILE_SHARE_* bitmask
528 * @param create_disposition SMB2_FILE_OPEN / _CREATE / _OPEN_IF /
529 * @param create_options SMB2_FILE_NON_DIRECTORY_FILE for a regular file
530 * @param name_utf16 the file name relative to the share root in UTF-16LE (no leading backslash, no NUL);
531 * @param name_len Name len
532 * @return The size_t.
533 */
534size_t protocore_smb2_build_create(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id,
535 uint32_t tree_id, uint32_t desired_access, uint32_t share_access,
536 uint32_t create_disposition, uint32_t create_options, const uint8_t *name_utf16,
537 size_t name_len);
538/**
539 * @brief Parse a CREATE response message (validates command + StructureSize .
540 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
541 * @param msg Msg
542 * @param len Len
543 * @param out Out
544 * @return PROTO_TRUE on success.
545 */
546proto_bool protocore_smb2_parse_create_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2CreateResp *out);
547/**
548 * @brief Build a CLOSE request (header + §2.2.15 body) for an open FileId.
549 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
550 * @param buf Buf
551 * @param cap Cap
552 * @param message_id Message id
553 * @param session_id Session id
554 * @param tree_id Tree id
555 * @param file_id 16 bytes
556 * @return The size_t.
557 */
558size_t protocore_smb2_build_close(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id,
559 uint32_t tree_id, const uint8_t *file_id);
560/**
561 * @brief Parse a CLOSE response message (validates command + StructureSize .
562 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
563 * @param msg Msg
564 * @param len Len
565 * @param out Out
566 * @return PROTO_TRUE on success.
567 */
568proto_bool protocore_smb2_parse_close_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2CloseResp *out);
569/**
570 * @brief Build a READ request (header + §2.2.19 body) for length bytes at .
571 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
572 * @param buf Buf
573 * @param cap Cap
574 * @param message_id Message id
575 * @param session_id Session id
576 * @param tree_id Tree id
577 * @param file_id 16 bytes
578 * @param length Length
579 * @param offset Offset
580 * @return The size_t.
581 */
582size_t protocore_smb2_build_read(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id,
583 uint32_t tree_id, const uint8_t *file_id, uint32_t length, uint64_t offset);
584/**
585 * @brief Parse a READ response message (validates command + StructureSize .
586 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
587 * @param msg Msg
588 * @param len Len
589 * @param out Out
590 * @return PROTO_TRUE on success.
591 */
592proto_bool protocore_smb2_parse_read_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2ReadResp *out);
593/**
594 * @brief Build a WRITE request (header + §2.2.21 body) writing data at .
595 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
596 * @param buf Buf
597 * @param cap Cap
598 * @param message_id Message id
599 * @param session_id Session id
600 * @param tree_id Tree id
601 * @param file_id 16 bytes
602 * @param data Data
603 * @param data_len Data len
604 * @param offset Offset
605 * @return The size_t.
606 */
607size_t protocore_smb2_build_write(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id,
608 uint32_t tree_id, const uint8_t *file_id, const uint8_t *data, size_t data_len,
609 uint64_t offset);
610/**
611 * @brief Parse a WRITE response message (validates command + StructureSize .
612 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
613 * @param msg Msg
614 * @param len Len
615 * @param out Out
616 * @return PROTO_TRUE on success.
617 */
618proto_bool protocore_smb2_parse_write_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2WriteResp *out);
619/**
620 * @brief Sign an SMB2 message in place (MS-SMB2 §3.1.4.1, SMB 2.x). Sets .
621 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
622 * @param crypto_work Crypto work
623 * @param key the session signing key (16 octets; the NTLMv2 session key for SMB 2.x) 16 bytes
624 * @param msg the full message (header + body), modified in place; must be at least a 64-byte header
625 * @param msg_len total message length. A message shorter than the header is left untouched
626 */
627void protocore_smb2_sign(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len);
628/**
629 * @brief Verify an SMB2 message's signature (MS-SMB2 §3.1.5.1). Recomputes .
630 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
631 * @param crypto_work Crypto work
632 * @param key 16 bytes
633 * @param msg Msg
634 * @param msg_len Msg len
635 * @return PROTO_TRUE on success.
636 */
637proto_bool protocore_smb2_verify(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len);
638/**
639 * @brief Sign an SMB2 message in place with AES-128-CMAC (MS-SMB2 §3.1.4.1, .
640 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
641 * @param crypto_work Crypto work
642 * @param key 16 bytes
643 * @param msg Msg
644 * @param msg_len Msg len
645 */
646void protocore_smb2_sign_cmac(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len);
647/**
648 * @brief Verify an AES-128-CMAC-signed SMB2 message (MS-SMB2 §3.1.5.1, SMB .
649 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
650 * @param crypto_work Crypto work
651 * @param key 16 bytes
652 * @param msg Msg
653 * @param msg_len Msg len
654 * @return PROTO_TRUE on success.
655 */
656proto_bool protocore_smb2_verify_cmac(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg,
657 size_t msg_len);
658/**
659 * @brief Derive the 16-byte SMB 3.x signing key from the NTLM session key .
660 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
661 * @param session_key the 16-byte NTLM ExportedSessionKey (SessionBaseKey for NTLMv2 with no key exch) 16 bytes
662 * @param dialect the negotiated DialectRevision (only 3.1.1 vs pre-3.1.1 matters here)
663 * @param preauth the 64-byte final preauth-integrity hash; required iff dialect == 3.1.1, else ignored
664 * @param out_key receives the 16-byte signing key 16 bytes
665 * @return PROTO_TRUE on success.
666 */
667proto_bool protocore_smb2_derive_signing_key(uint8_t *work, const uint8_t *session_key, uint16_t dialect,
668 const uint8_t *preauth, uint8_t *out_key);
669/**
670 * @brief Derive the two SMB 3.x cipher keys from the NTLM session key .
671 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
672 * @param session_key 16 bytes
673 * @param dialect Dialect
674 * @param preauth Preauth
675 * @param key_len Key len
676 * @param out_c2s client->server key (ENCRYPTS our requests); out_s2c server->client key (DECRYPTS
677 * @param out_s2c Out s2c
678 * @return PROTO_TRUE on success.
679 */
680proto_bool protocore_smb2_derive_encryption_keys(uint8_t *work, const uint8_t *session_key, uint16_t dialect,
681 const uint8_t *preauth, size_t key_len, uint8_t *out_c2s,
682 uint8_t *out_s2c);
683/**
684 * @brief Encrypt one SMB2 message into a TRANSFORM_HEADER-wrapped blob .
685 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
686 * @param cipher one of Smb2Cipher; selects the key length and AEAD nonce length
687 * @param key cipher key (protocore_smb2_cipher_key_len(cipher) bytes, i.e. the C2S key)
688 * @param nonce the 16-byte Nonce field; the leading nonce-length bytes must be UNIQUE per key (caller
689 * @param session_id echoed into the header; out needs >= PROTOCORE_SMB2_TRANSFORM_HDR_LEN + msg_len
690 * @param msg Msg
691 * @param msg_len Msg len
692 * @param out Out
693 * @param out_cap Out cap
694 * @return The size_t.
695 */
696size_t protocore_smb2_encrypt(uint8_t *work, uint16_t cipher, const uint8_t *key, const uint8_t *nonce,
697 uint64_t session_id, const uint8_t *msg, size_t msg_len, uint8_t *out, size_t out_cap);
698/**
699 * @brief Decrypt a TRANSFORM_HEADER-wrapped SMB2 message (MS-SMB2 §3.1.4.4): .
700 * @param work PROTOCORE_SMB2_BORROW bytes the caller took. Not held past the call.
701 * @param cipher one of Smb2Cipher; key the S2C cipher key; out needs >= OriginalMessageSize
702 * @param key Key
703 * @param in In
704 * @param in_len In len
705 * @param out Out
706 * @param out_cap Out cap
707 * @return The size_t.
708 */
709size_t protocore_smb2_decrypt(uint8_t *work, uint16_t cipher, const uint8_t *key, const uint8_t *in, size_t in_len,
710 uint8_t *out, size_t out_cap);
711
712/** @brief Module namespace. */
714 .transport_len = protocore_smb2_transport_len,
715 .build_header = protocore_smb2_build_header,
716 .parse_header = protocore_smb2_parse_header,
717 .build_negotiate = protocore_smb2_build_negotiate,
718 .parse_negotiate_response = protocore_smb2_parse_negotiate_response,
719 .build_negotiate_311 = protocore_smb2_build_negotiate_311,
720 .parse_negotiate_contexts = protocore_smb2_parse_negotiate_contexts,
721 .preauth_init = protocore_smb2_preauth_init,
722 .preauth_update = protocore_smb2_preauth_update,
723 .build_session_setup = protocore_smb2_build_session_setup,
724 .parse_session_setup_response =
726 .build_tree_connect = protocore_smb2_build_tree_connect,
727 .parse_tree_connect_response = protocore_smb2_parse_tree_connect_response,
728 .build_create = protocore_smb2_build_create,
729 .parse_create_response = protocore_smb2_parse_create_response,
730 .build_close = protocore_smb2_build_close,
731 .parse_close_response = protocore_smb2_parse_close_response,
732 .build_read = protocore_smb2_build_read,
733 .parse_read_response = protocore_smb2_parse_read_response,
734 .build_write = protocore_smb2_build_write,
735 .parse_write_response = protocore_smb2_parse_write_response,
736 .sign = protocore_smb2_sign,
737 .verify = protocore_smb2_verify,
738 .sign_cmac = protocore_smb2_sign_cmac,
739 .verify_cmac = protocore_smb2_verify_cmac,
740 .derive_signing_key = protocore_smb2_derive_signing_key,
741 .derive_encryption_keys = protocore_smb2_derive_encryption_keys,
742 .encrypt = protocore_smb2_encrypt,
743 .decrypt = protocore_smb2_decrypt};
744
746
747#endif // PROTOCORE_SMB2_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
#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_smb2_transport_frame(uint8_t *work, uint8_t *out, size_t cap, const uint8_t *msg, size_t msg_len)
Prefix an SMB2 message with the 4-byte Direct-TCP transport header .
size_t protocore_smb2_build_header(uint8_t *work, uint8_t *buf, size_t cap, Smb2Command command, uint16_t credit_request, uint64_t message_id, uint32_t tree_id, uint64_t session_id)
Build a 64-byte SMB2 sync header into buf.
void protocore_smb2_preauth_init(uint8_t *work, SmbPreauth *p)
Seed the preauth-integrity hash with 64 zero bytes (the initial .
enum PROTO_ENUM_PACKED Smb2Dialect
SMB2 dialect revision numbers (MS-SMB2 §2.2.4).
size_t protocore_smb2_build_tree_connect(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, const uint8_t *path_utf16, size_t path_len)
Build a TREE_CONNECT request (header + §2.2.9 body) for a share path.
proto_bool protocore_smb2_parse_write_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2WriteResp *out)
Parse a WRITE response message (validates command + StructureSize .
proto_bool protocore_smb2_verify_cmac(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len)
Verify an AES-128-CMAC-signed SMB2 message (MS-SMB2 §3.1.5.1, SMB .
proto_bool protocore_smb2_parse_tree_connect_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2TreeConnectResp *out)
Parse a TREE_CONNECT response message (validates command + .
#define SMB2_ENCRYPTION_AES128_CCM
Encryption cipher IDs (MS-SMB2 §2.2.3.1.2).
Definition smb2.h:125
void protocore_smb2_sign(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len)
Sign an SMB2 message in place (MS-SMB2 §3.1.4.1, SMB 2.x). Sets .
proto_bool protocore_smb2_parse_create_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2CreateResp *out)
Parse a CREATE response message (validates command + StructureSize .
proto_bool protocore_smb2_parse_negotiate_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2NegotiateResp *out)
Parse a NEGOTIATE response message (the SMB2 header + §2.2.4 body).
enum PROTO_ENUM_PACKED Smb2Command
SMB2 command codes (MS-SMB2 §2.2.1.2).
size_t protocore_smb2_build_create(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id, uint32_t desired_access, uint32_t share_access, uint32_t create_disposition, uint32_t create_options, const uint8_t *name_utf16, size_t name_len)
Build a CREATE request (header + §2.2.13 body) to open/create a .
#define SMB2_ENCRYPTION_AES256_GCM
Definition smb2.h:128
proto_bool protocore_smb2_parse_read_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2ReadResp *out)
Parse a READ response message (validates command + StructureSize .
enum PROTO_ENUM_PACKED Smb2SignAlgo
The per-session message-signing algorithm the client selects from the negotiated dialect.
size_t protocore_smb2_build_session_setup(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, uint8_t security_mode, const uint8_t *sec_buf, size_t sec_len)
Build a SESSION_SETUP request (header + §2.2.5 body) carrying a .
size_t protocore_smb2_encrypt(uint8_t *work, uint16_t cipher, const uint8_t *key, const uint8_t *nonce, uint64_t session_id, const uint8_t *msg, size_t msg_len, uint8_t *out, size_t out_cap)
Encrypt one SMB2 message into a TRANSFORM_HEADER-wrapped blob .
size_t protocore_smb2_build_close(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id, const uint8_t *file_id)
Build a CLOSE request (header + §2.2.15 body) for an open FileId.
size_t protocore_smb2_build_negotiate_311(uint8_t *work, uint8_t *buf, size_t cap, const uint8_t *client_guid, uint16_t security_mode, const uint8_t *salt, size_t salt_len, const uint16_t *ciphers, size_t cipher_count)
Build an SMB 3.1.1 NEGOTIATE request: the dialect list SMB 2.0.2 .. .
proto_bool protocore_smb2_derive_signing_key(uint8_t *work, const uint8_t *session_key, uint16_t dialect, const uint8_t *preauth, uint8_t *out_key)
Derive the 16-byte SMB 3.x signing key from the NTLM session key .
size_t protocore_smb2_build_negotiate(uint8_t *work, uint8_t *buf, size_t cap, const uint8_t *client_guid, uint16_t security_mode)
Build a NEGOTIATE request (header + body) offering SMB 2.0.2 / 2.1 .
void protocore_smb2_sign_cmac(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len)
Sign an SMB2 message in place with AES-128-CMAC (MS-SMB2 §3.1.4.1, .
PROTOCORE_NS Smb2Ns Smb2 PROTOCORE_UNUSED
Module namespace.
Definition smb2.h:713
proto_bool protocore_smb2_parse_negotiate_contexts(uint8_t *work, const uint8_t *msg, size_t len, Smb2NegotiateContexts *out)
Walk the negotiate-context list of a 3.1.1 NEGOTIATE response .
@ SMB2_DIALECT_0202
SMB 2.0.2.
Definition smb2.h:176
@ SMB2_TREE_DISCONNECT
Definition smb2.h:166
@ SMB2_DIALECT_0300
SMB 3.0.
Definition smb2.h:178
@ SMB2_DIALECT_0210
SMB 2.1.
Definition smb2.h:177
@ SMB2_LOGOFF
Definition smb2.h:164
@ SMB2_SIGN_ALGO_AES_CMAC
SMB 3.0 / 3.0.2 / 3.1.1 (key = the SP800-108-derived signing key)
Definition smb2.h:282
@ SMB2_READ
Definition smb2.h:169
@ SMB2_NEGOTIATE
Definition smb2.h:162
@ SMB2_TREE_CONNECT
Definition smb2.h:165
@ SMB2_WRITE
Definition smb2.h:170
@ SMB2_DIALECT_0302
SMB 3.0.2.
Definition smb2.h:179
@ SMB2_DIALECT_0311
SMB 3.1.1.
Definition smb2.h:180
@ SMB2_CLOSE
Definition smb2.h:168
@ SMB2_SESSION_SETUP
Definition smb2.h:163
@ SMB2_SIGN_ALGO_HMAC_SHA256
SMB 2.0.2 / 2.1 (key = the NTLMv2 session key)
Definition smb2.h:281
@ SMB2_CREATE
Definition smb2.h:167
uint32_t protocore_smb2_transport_len(uint8_t *work, const uint8_t *buf, size_t len)
Read the Direct-TCP transport length prefix.
size_t protocore_smb2_decrypt(uint8_t *work, uint16_t cipher, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out, size_t out_cap)
Decrypt a TRANSFORM_HEADER-wrapped SMB2 message (MS-SMB2 §3.1.4.4): .
#define PROTOCORE_SMB2_PREAUTH_HASH_LEN
Length of the SMB 3.1.1 preauth-integrity hash (SHA-512 digest size).
Definition smb2.h:134
proto_bool protocore_smb2_parse_session_setup_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2SessionSetupResp *out)
Parse a SESSION_SETUP response message (the SMB2 header + §2.2.6 .
#define SMB2_ENCRYPTION_AES128_GCM
Definition smb2.h:126
size_t protocore_smb2_build_read(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id, const uint8_t *file_id, uint32_t length, uint64_t offset)
Build a READ request (header + §2.2.19 body) for length bytes at .
proto_bool protocore_smb2_derive_encryption_keys(uint8_t *work, const uint8_t *session_key, uint16_t dialect, const uint8_t *preauth, size_t key_len, uint8_t *out_c2s, uint8_t *out_s2c)
Derive the two SMB 3.x cipher keys from the NTLM session key .
void protocore_smb2_preauth_update(uint8_t *work, uint8_t *crypto_work, SmbPreauth *p, const uint8_t *msg, size_t len)
Fold one handshake message into the preauth-integrity hash: hash = .
proto_bool protocore_smb2_verify(uint8_t *work, uint8_t *crypto_work, const uint8_t *key, uint8_t *msg, size_t msg_len)
Verify an SMB2 message's signature (MS-SMB2 §3.1.5.1). Recomputes .
proto_bool protocore_smb2_parse_close_response(uint8_t *work, const uint8_t *msg, size_t len, Smb2CloseResp *out)
Parse a CLOSE response message (validates command + StructureSize .
proto_bool protocore_smb2_parse_header(uint8_t *work, const uint8_t *buf, size_t len, Smb2Header *out)
Parse a 64-byte SMB2 sync header (validates ProtocolId + .
size_t protocore_smb2_build_write(uint8_t *work, uint8_t *buf, size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id, const uint8_t *file_id, const uint8_t *data, size_t data_len, uint64_t offset)
Build a WRITE request (header + §2.2.21 body) writing data at .
#define SMB2_ENCRYPTION_AES256_CCM
Definition smb2.h:127
Parsed CLOSE response (MS-SMB2 §2.2.16).
Definition smb2.h:260
uint32_t file_attributes
Definition smb2.h:262
uint64_t end_of_file
Definition smb2.h:261
Parsed CREATE response (MS-SMB2 §2.2.14).
Definition smb2.h:251
uint64_t end_of_file
Definition smb2.h:253
uint32_t create_action
Definition smb2.h:254
uint32_t file_attributes
Definition smb2.h:255
Parsed SMB2 sync header.
Definition smb2.h:185
uint32_t status
NT status (response); 0 = STATUS_SUCCESS.
Definition smb2.h:187
uint64_t message_id
Definition smb2.h:189
uint64_t session_id
Definition smb2.h:191
uint32_t flags
Definition smb2.h:188
uint32_t tree_id
Definition smb2.h:190
uint16_t credit_response
Definition smb2.h:192
Smb2Command command
Definition smb2.h:186
Parsed SMB 3.1.1 NEGOTIATE-response negotiate contexts (MS-SMB2 §2.2.4 / §2.2.3.1).
Definition smb2.h:197
uint16_t salt_len
length of salt
Definition smb2.h:201
uint16_t hash_algorithm
the server's chosen preauth hash (expect SMB2_PREAUTH_INTEGRITY_SHA512)
Definition smb2.h:199
proto_bool have_preauth
a PREAUTH_INTEGRITY_CAPABILITIES context was present
Definition smb2.h:198
proto_bool have_signing
a SIGNING_CAPABILITIES context was present
Definition smb2.h:202
uint16_t signing_algorithm
the server's chosen signing algorithm
Definition smb2.h:203
proto_bool have_encryption
an ENCRYPTION_CAPABILITIES context was present
Definition smb2.h:204
uint16_t cipher
the server's chosen cipher
Definition smb2.h:205
const uint8_t * salt
the preauth-integrity salt (points into msg), or nullptr
Definition smb2.h:200
Parsed NEGOTIATE response (MS-SMB2 §2.2.4).
Definition smb2.h:210
uint32_t max_write
Definition smb2.h:217
uint32_t capabilities
Definition smb2.h:214
uint16_t dialect
the DialectRevision the server chose
Definition smb2.h:212
uint16_t security_mode
Definition smb2.h:211
const uint8_t * sec_buf
SPNEGO/NTLM security token (points into msg), or nullptr.
Definition smb2.h:218
uint16_t sec_buf_len
Definition smb2.h:219
uint32_t max_transact
Definition smb2.h:215
uint32_t max_read
Definition smb2.h:216
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition smb2.h:322
size_t(* transport_frame)(uint8_t *, uint8_t *, size_t, const uint8_t *, size_t)
Definition smb2.h:323
Parsed READ response (MS-SMB2 §2.2.20).
Definition smb2.h:267
uint32_t data_len
Definition smb2.h:269
const uint8_t * data
the file bytes read (points into msg), or nullptr when DataLength is 0
Definition smb2.h:268
Parsed SESSION_SETUP response (MS-SMB2 §2.2.6).
Definition smb2.h:234
uint16_t session_flags
Definition smb2.h:235
uint16_t sec_buf_len
Definition smb2.h:237
const uint8_t * sec_buf
the server's SPNEGO/NTLM token (points into msg), or nullptr
Definition smb2.h:236
Parsed TREE_CONNECT response (MS-SMB2 §2.2.10). The TreeId is in the response header.
Definition smb2.h:242
uint32_t maximal_access
Definition smb2.h:246
uint8_t share_type
Definition smb2.h:243
uint32_t share_flags
Definition smb2.h:244
uint32_t capabilities
Definition smb2.h:245
Parsed WRITE response (MS-SMB2 §2.2.22).
Definition smb2.h:274
uint32_t count
bytes actually written
Definition smb2.h:275
The SMB 3.1.1 preauth-integrity hash value (MS-SMB2 §3.1.5.2): a running SHA-512 chained over every N...
Definition smb2.h:228
#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