36#ifndef PROTOCORE_SMB2_H
37#define PROTOCORE_SMB2_H
47enum class Smb2Command : uint16_t
49 SMB2_NEGOTIATE = 0x0000,
50 SMB2_SESSION_SETUP = 0x0001,
52 SMB2_TREE_CONNECT = 0x0003,
53 SMB2_TREE_DISCONNECT = 0x0004,
61enum class Smb2Dialect : uint16_t
63 SMB2_DIALECT_0202 = 0x0202,
64 SMB2_DIALECT_0210 = 0x0210,
65 SMB2_DIALECT_0300 = 0x0300,
66 SMB2_DIALECT_0302 = 0x0302,
67 SMB2_DIALECT_0311 = 0x0311,
75#define PC_SMB2_HEADER_SIZE 64
78struct Smb2SecurityMode
80 static constexpr uint16_t SMB2_NEGOTIATE_SIGNING_ENABLED = 0x0001;
81 static constexpr uint16_t SMB2_NEGOTIATE_SIGNING_REQUIRED = 0x0002;
87 static constexpr uint32_t SMB2_FLAGS_SERVER_TO_REDIR = 0x00000001;
88 static constexpr uint32_t SMB2_FLAGS_SIGNED = 0x00000008;
92struct Smb2SessionFlags
94 static constexpr uint16_t SMB2_SESSION_FLAG_IS_GUEST = 0x0001;
95 static constexpr uint16_t SMB2_SESSION_FLAG_IS_NULL = 0x0002;
96 static constexpr uint16_t SMB2_SESSION_FLAG_ENCRYPT_DATA = 0x0004;
102 static constexpr uint32_t SMB2_STATUS_SUCCESS = 0x00000000;
103 static constexpr uint32_t SMB2_STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016;
104 static constexpr uint32_t SMB2_STATUS_END_OF_FILE = 0xC0000011;
110 static constexpr uint8_t SMB2_SHARE_TYPE_DISK = 0x01;
111 static constexpr uint8_t SMB2_SHARE_TYPE_PIPE = 0x02;
112 static constexpr uint8_t SMB2_SHARE_TYPE_PRINT = 0x03;
118 static constexpr uint32_t SMB2_FILE_READ_DATA = 0x00000001;
119 static constexpr uint32_t SMB2_FILE_WRITE_DATA = 0x00000002;
120 static constexpr uint32_t SMB2_FILE_APPEND_DATA = 0x00000004;
121 static constexpr uint32_t SMB2_FILE_READ_ATTRIBUTES = 0x00000080;
122 static constexpr uint32_t SMB2_FILE_GENERIC_READ = 0x00120089;
123 static constexpr uint32_t SMB2_FILE_GENERIC_WRITE = 0x00120116;
127struct Smb2ShareAccess
129 static constexpr uint32_t SMB2_FILE_SHARE_READ = 0x01;
130 static constexpr uint32_t SMB2_FILE_SHARE_WRITE = 0x02;
131 static constexpr uint32_t SMB2_FILE_SHARE_DELETE = 0x04;
135struct Smb2Disposition
137 static constexpr uint32_t SMB2_FILE_SUPERSEDE = 0;
138 static constexpr uint32_t SMB2_FILE_OPEN = 1;
139 static constexpr uint32_t SMB2_FILE_CREATE = 2;
140 static constexpr uint32_t SMB2_FILE_OPEN_IF = 3;
141 static constexpr uint32_t SMB2_FILE_OVERWRITE = 4;
142 static constexpr uint32_t SMB2_FILE_OVERWRITE_IF = 5;
146struct Smb2CreateOptions
148 static constexpr uint32_t SMB2_FILE_DIRECTORY_FILE = 0x00000001;
149 static constexpr uint32_t SMB2_FILE_NON_DIRECTORY_FILE = 0x00000040;
161 uint16_t credit_response;
165struct Smb2NegotiateContextType
167 static constexpr uint16_t SMB2_PREAUTH_INTEGRITY_CAPABILITIES = 0x0001;
168 static constexpr uint16_t SMB2_ENCRYPTION_CAPABILITIES = 0x0002;
169 static constexpr uint16_t SMB2_COMPRESSION_CAPABILITIES = 0x0003;
170 static constexpr uint16_t SMB2_NETNAME_NEGOTIATE_CONTEXT_ID = 0x0005;
171 static constexpr uint16_t SMB2_TRANSPORT_CAPABILITIES = 0x0006;
172 static constexpr uint16_t SMB2_RDMA_TRANSFORM_CAPABILITIES = 0x0007;
173 static constexpr uint16_t SMB2_SIGNING_CAPABILITIES = 0x0008;
177struct Smb2HashAlgorithm
179 static constexpr uint16_t SMB2_PREAUTH_INTEGRITY_SHA512 = 0x0001;
183struct Smb2SigningAlgorithm
185 static constexpr uint16_t SMB2_SIGNING_HMAC_SHA256 = 0x0000;
186 static constexpr uint16_t SMB2_SIGNING_AES_CMAC = 0x0001;
187 static constexpr uint16_t SMB2_SIGNING_AES_GMAC = 0x0002;
195 static constexpr uint32_t SMB2_GLOBAL_CAP_ENCRYPTION = 0x00000040;
201 static constexpr uint16_t SMB2_ENCRYPTION_AES128_CCM = 0x0001;
202 static constexpr uint16_t SMB2_ENCRYPTION_AES128_GCM = 0x0002;
203 static constexpr uint16_t SMB2_ENCRYPTION_AES256_CCM = 0x0003;
204 static constexpr uint16_t SMB2_ENCRYPTION_AES256_GCM = 0x0004;
209inline size_t pc_smb2_cipher_key_len(uint16_t cipher)
213 case Smb2Cipher::SMB2_ENCRYPTION_AES128_CCM:
214 case Smb2Cipher::SMB2_ENCRYPTION_AES128_GCM:
216 case Smb2Cipher::SMB2_ENCRYPTION_AES256_CCM:
217 case Smb2Cipher::SMB2_ENCRYPTION_AES256_GCM:
227inline size_t pc_smb2_cipher_nonce_len(uint16_t cipher)
231 case Smb2Cipher::SMB2_ENCRYPTION_AES128_GCM:
232 case Smb2Cipher::SMB2_ENCRYPTION_AES256_GCM:
234 case Smb2Cipher::SMB2_ENCRYPTION_AES128_CCM:
235 case Smb2Cipher::SMB2_ENCRYPTION_AES256_CCM:
243struct Smb2NegotiateContexts
246 uint16_t hash_algorithm;
250 uint16_t signing_algorithm;
251 bool have_encryption;
256struct Smb2NegotiateResp
258 uint16_t security_mode;
260 uint8_t server_guid[16];
261 uint32_t capabilities;
262 uint32_t max_transact;
265 const uint8_t *sec_buf;
266 uint16_t sec_buf_len;
274size_t pc_smb2_transport_frame(uint8_t *out,
size_t cap,
const uint8_t *msg,
size_t msg_len);
281uint32_t pc_smb2_transport_len(
const uint8_t *buf,
size_t len);
287size_t pc_smb2_build_header(uint8_t *buf,
size_t cap, Smb2Command command, uint16_t credit_request, uint64_t message_id,
288 uint32_t tree_id, uint64_t session_id);
295bool pc_smb2_parse_header(
const uint8_t *buf,
size_t len, Smb2Header *out);
303size_t pc_smb2_build_negotiate(uint8_t *buf,
size_t cap,
const uint8_t client_guid[16], uint16_t security_mode);
313bool pc_smb2_parse_negotiate_response(
const uint8_t *msg,
size_t len, Smb2NegotiateResp *out);
316#define PC_SMB2_MAX_OFFER_CIPHERS 4
338size_t pc_smb2_build_negotiate_311(uint8_t *buf,
size_t cap,
const uint8_t client_guid[16], uint16_t security_mode,
339 const uint8_t *salt,
size_t salt_len,
const uint16_t *ciphers,
size_t cipher_count);
348bool pc_smb2_parse_negotiate_contexts(
const uint8_t *msg,
size_t len, Smb2NegotiateContexts *out);
351#define PC_SMB2_PREAUTH_HASH_LEN 64
360 uint8_t hash[PC_SMB2_PREAUTH_HASH_LEN];
364void pc_smb_preauth_init(SmbPreauth *p);
371void pc_smb_preauth_update(SmbPreauth *p,
const uint8_t *msg,
size_t len);
374struct Smb2SessionSetupResp
376 uint16_t session_flags;
377 const uint8_t *sec_buf;
378 uint16_t sec_buf_len;
393size_t pc_smb2_build_session_setup(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id,
394 uint8_t security_mode,
const uint8_t *sec_buf,
size_t sec_len);
408bool pc_smb2_parse_session_setup_response(
const uint8_t *msg,
size_t len, Smb2SessionSetupResp *out);
415size_t pc_smb2_build_tree_connect(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id,
416 const uint8_t *path_utf16,
size_t path_len);
421 static constexpr uint32_t SMB2_SHAREFLAG_ENCRYPT_DATA = 0x00008000;
425struct Smb2TreeConnectResp
428 uint32_t share_flags;
429 uint32_t capabilities;
430 uint32_t maximal_access;
437bool pc_smb2_parse_tree_connect_response(
const uint8_t *msg,
size_t len, Smb2TreeConnectResp *out);
449size_t pc_smb2_build_create(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id,
450 uint32_t desired_access, uint32_t share_access, uint32_t create_disposition,
451 uint32_t create_options,
const uint8_t *name_utf16,
size_t name_len);
457 uint64_t end_of_file;
458 uint32_t create_action;
459 uint32_t file_attributes;
466bool pc_smb2_parse_create_response(
const uint8_t *msg,
size_t len, Smb2CreateResp *out);
472size_t pc_smb2_build_close(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id,
473 const uint8_t file_id[16]);
478 uint64_t end_of_file;
479 uint32_t file_attributes;
486bool pc_smb2_parse_close_response(
const uint8_t *msg,
size_t len, Smb2CloseResp *out);
492size_t pc_smb2_build_read(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id,
493 const uint8_t file_id[16], uint32_t length, uint64_t offset);
506bool pc_smb2_parse_read_response(
const uint8_t *msg,
size_t len, Smb2ReadResp *out);
512size_t pc_smb2_build_write(uint8_t *buf,
size_t cap, uint64_t message_id, uint64_t session_id, uint32_t tree_id,
513 const uint8_t file_id[16],
const uint8_t *data,
size_t data_len, uint64_t offset);
525bool pc_smb2_parse_write_response(
const uint8_t *msg,
size_t len, Smb2WriteResp *out);
532enum class Smb2SignAlgo : uint8_t
546void pc_smb2_sign(
const uint8_t key[16], uint8_t *msg,
size_t msg_len);
554bool pc_smb2_verify(
const uint8_t key[16], uint8_t *msg,
size_t msg_len);
566void pc_smb2_sign_cmac(
const uint8_t key[16], uint8_t *msg,
size_t msg_len);
574bool pc_smb2_verify_cmac(
const uint8_t key[16], uint8_t *msg,
size_t msg_len);
591bool pc_smb3_derive_signing_key(
const uint8_t session_key[16], uint16_t dialect,
const uint8_t *preauth,
592 uint8_t out_key[16]);
603#define PC_SMB2_TRANSFORM_HDR_LEN 52
605#define PC_SMB2_TRANSFORM_PROTOCOL_ID 0x424D53FDu
608#define PC_SMB2_NONCE_FIELD_LEN 16
610#define PC_SMB2_GCM_NONCE_LEN 12
612#define PC_SMB2_CCM_NONCE_LEN 11
614#define PC_SMB2_MAX_CIPHER_KEY_LEN 32
629bool pc_smb3_derive_encryption_keys(
const uint8_t session_key[16], uint16_t dialect,
const uint8_t *preauth,
630 size_t key_len, uint8_t *out_c2s, uint8_t *out_s2c);
644size_t pc_smb2_encrypt(uint16_t cipher,
const uint8_t *key,
const uint8_t nonce[PC_SMB2_NONCE_FIELD_LEN],
645 uint64_t session_id,
const uint8_t *msg,
size_t msg_len, uint8_t *out,
size_t out_cap);
653size_t pc_smb2_decrypt(uint16_t cipher,
const uint8_t *key,
const uint8_t *in,
size_t in_len, uint8_t *out,
User-facing configuration for ProtoCore.