1 /****************************************************************************
2 *																			*
3 *						  SSH Definitions Header File						*
4 *						Copyright Peter Gutmann 1998-2013					*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _SSH_DEFINED
9 
10 #define _SSH_DEFINED
11 
12 #if defined( USE_SSH_EXTENDED ) && defined( _MSC_VER )
13   #pragma message( "  Building with extended SSH facilities enabled." )
14 #endif /* USE_SSH_EXTENDED with VC++ */
15 
16 /****************************************************************************
17 *																			*
18 *								SSH Constants								*
19 *																			*
20 ****************************************************************************/
21 
22 /* Default SSH port */
23 
24 #define SSH_PORT				22
25 
26 /* Various SSH constants */
27 
28 #define ID_SIZE					1	/* ID byte */
29 #define LENGTH_SIZE				4	/* Size of packet length field */
30 #define UINT_SIZE				4	/* Size of integer value */
31 #define PADLENGTH_SIZE			1	/* Size of padding length field */
32 #define BOOLEAN_SIZE			1	/* Size of boolean value */
33 
34 #define SSH2_COOKIE_SIZE		16	/* Size of SSHv2 cookie */
35 #define SSH2_HEADER_SIZE		5	/* Size of SSHv2 packet header */
36 #define SSH2_MIN_ALGOID_SIZE	4	/* Size of shortest SSHv2 algo.name */
37 #define SSH2_MIN_PADLENGTH_SIZE	4	/* Minimum amount of padding for packets */
38 #define SSH2_PAYLOAD_HEADER_SIZE 9	/* Size of SSHv2 inner payload header */
39 #define SSH2_FIXED_KEY_SIZE		16	/* Size of SSHv2 fixed-size keys */
40 #ifdef USE_DH1024
41   #define SSH2_DEFAULT_KEYSIZE	128	/* Size of SSHv2 default DH key */
42 #else
43   #define SSH2_DEFAULT_KEYSIZE	192	/* Size of SSHv2 default DH key */
44 #endif /* USE_DH1024 */
45 
46 /* SSH packet/buffer size information.  The extra packet data is for
47    additional non-payload information including the header, MAC, and up to
48    256 bytes of padding */
49 
50 #define MAX_PACKET_SIZE			262144L
51 #define EXTRA_PACKET_SIZE		512
52 #define DEFAULT_PACKET_SIZE		16384
53 #define MAX_WINDOW_SIZE			( MAX_INTLENGTH - 8192 )
54 
55 /* By default cryptlib uses DH key agreement, which is supported by all
56    servers.  It's also possible to use ECDH key agreement, however due to
57    SSH's braindamaged way of choosing algorithms the peer will always go
58    for ECDH if it can handle it (see the comment in sesion/ssh2_svr.c for
59    more on this), so we disable ECDH by default.  To use ECDH key agreement
60    in preference to DH, uncomment the following */
61 
62 /* #define PREFER_ECC */
63 #if defined( PREFER_ECC ) && defined( _MSC_VER )
64   #pragma message( "  Building with ECC preferred for SSH." )
65 #endif /* PREFER_ECC && Visual C++ */
66 #if defined( PREFER_ECC ) && \
67 	!( defined( USE_ECDH ) && defined( USE_ECDSA ) )
68   #error PREFER_ECC can only be used with ECDH and ECDSA enabled
69 #endif /* PREFER_ECC && !( USE_ECDH && USE_ECDSA ) */
70 
71 /* SSH protocol-specific flags that encode details of implementation bugs
72    that we need to work around */
73 
74 #define SSH_PFLAG_NONE			0x0000/* No protocol-specific flags */
75 #define SSH_PFLAG_HMACKEYSIZE	0x0001/* Peer uses short HMAC keys */
76 #define SSH_PFLAG_SIGFORMAT		0x0002/* Peer omits signature algo name */
77 #define SSH_PFLAG_NOHASHSECRET	0x0004/* Peer omits secret in key derive */
78 #define SSH_PFLAG_NOHASHLENGTH	0x0008/* Peer omits length in exchange hash */
79 #define SSH_PFLAG_RSASIGPAD		0x0010/* Peer requires zero-padded RSA sig.*/
80 #define SSH_PFLAG_WINDOWSIZE	0x0020/* Peer mishandles large window sizes */
81 #define SSH_PFLAG_TEXTDIAGS		0x0040/* Peer dumps text diagnostics on error */
82 #define SSH_PFLAG_PAMPW			0x0080/* Peer chokes on "password" as PAM submethod */
83 #define SSH_PFLAG_DUMMYUSERAUTH	0x0100/* Peer requires dummy userAuth message */
84 #define SSH_PFLAG_EMPTYUSERAUTH	0x0200/* Peer sends empty userauth-failure response */
85 #define SSH_PFLAG_ZEROLENIGNORE	0x0400/* Peer sends zero-length SSH_IGNORE */
86 #define SSH_PFLAG_ASYMMCOPR		0x0800/* Peer sends asymmetric compression algos */
87 #define SSH_PFLAG_EMPTYSVCACCEPT 0x1000/* Peer sends empty SSH_SERVICE_ACCEPT */
88 #define SSH_PFLAG_CUTEFTP		0x2000/* CuteFTP, drops conn.during handshake */
89 #define SSH_PFLAG_MAX			0x3FFF/* Maximum possible flag value */
90 
91 /* Various data sizes used for read-ahead and buffering.  The minimum SSH
92    packet size is used to determine how much data we can read when reading
93    a packet header, the SSH header remainder size is how much data we've
94    got left once we've extracted just the length but no other data */
95 
96 #define MIN_PACKET_SIZE			16
97 #define SSH_HEADER_REMAINDER_SIZE ( MIN_PACKET_SIZE - LENGTH_SIZE )
98 
99 /* SSH ID information */
100 
101 #define SSH_ID					"SSH-"		/* Start of SSH ID */
102 #define SSH_ID_SIZE				4	/* Size of SSH ID */
103 #define SSH_VERSION_SIZE		4	/* Size of SSH version */
104 #define SSH_ID_MAX_SIZE			255	/* Max.size of SSH ID string */
105 #define SSH_ID_STRING			"SSH-2.0-cryptlib"	/* cryptlib SSH ID strings */
106 #define SSH_ID_STRING_SIZE		16	/* Size of ID strings */
107 
108 /* SSH packet types.  Note that the keyex (static DH keys), keyex_gex
109    (ephemeral DH keys), and keyex_ecdh (static ECDH keys) message types
110    overlap */
111 
112 #define SSH_MSG_DISCONNECT		1	/* Disconnect session */
113 #define SSH_MSG_IGNORE			2	/* No-op */
114 #define SSH_MSG_DEBUG			4	/* No-op */
115 #define SSH_MSG_SERVICE_REQUEST 5	/* Request authentiction */
116 #define SSH_MSG_SERVICE_ACCEPT	6	/* Acknowledge request */
117 #define SSH_MSG_KEXINIT			20	/* Hello */
118 #define SSH_MSG_NEWKEYS			21	/* Change cipherspec */
119 #define SSH_MSG_KEXDH_INIT		30	/* DH, phase 1 */
120 #define SSH_MSG_KEXDH_REPLY		31	/* DH, phase 2 */
121 #define SSH_MSG_KEXDH_GEX_REQUEST_OLD 30 /* Ephem.DH key request */
122 #define SSH_MSG_KEXDH_GEX_GROUP 31	/* Ephem.DH key response */
123 #define SSH_MSG_KEXDH_GEX_INIT	32	/* Ephem.DH, phase 1 */
124 #define SSH_MSG_KEXDH_GEX_REPLY 33	/* Ephem.DH, phase 2 */
125 #define SSH_MSG_KEXDH_GEX_REQUEST_NEW 34 /* Ephem.DH key request */
126 #define SSH_MSG_KEX_ECDH_INIT	30	/* ECDH, phase 1 */
127 #define SSH_MSG_KEX_ECDH_REPLY	31	/* ECDH, phase 2 */
128 #define SSH_MSG_USERAUTH_REQUEST 50 /* Request authentication */
129 #define SSH_MSG_USERAUTH_FAILURE 51 /* Authentication failed */
130 #define SSH_MSG_USERAUTH_SUCCESS 52 /* Authentication succeeded */
131 #define SSH_MSG_USERAUTH_BANNER 53	/* No-op */
132 #define SSH_MSG_USERAUTH_INFO_REQUEST 60 /* Generic auth.svr.request */
133 #define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* Generic auth.cli.response */
134 #define SSH_MSG_GLOBAL_REQUEST	80	/* Perform a global ioctl */
135 #define SSH_MSG_GLOBAL_SUCCESS	81	/* Global request succeeded */
136 #define SSH_MSG_GLOBAL_FAILURE	82	/* Global request failed */
137 #define	SSH_MSG_CHANNEL_OPEN	90	/* Open a channel over an SSH link */
138 #define	SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91	/* Channel open succeeded */
139 #define SSH_MSG_CHANNEL_OPEN_FAILURE 92	/* Channel open failed */
140 #define	SSH_MSG_CHANNEL_WINDOW_ADJUST 93	/* No-op */
141 #define SSH_MSG_CHANNEL_DATA	94	/* Data */
142 #define SSH_MSG_CHANNEL_EXTENDED_DATA 95	/* Out-of-band data */
143 #define SSH_MSG_CHANNEL_EOF		96	/* EOF */
144 #define SSH_MSG_CHANNEL_CLOSE	97	/* Close the channel */
145 #define SSH_MSG_CHANNEL_REQUEST 98	/* Perform a channel ioctl */
146 #define SSH_MSG_CHANNEL_SUCCESS 99	/* Channel request succeeded */
147 #define SSH_MSG_CHANNEL_FAILURE 100/* Channel request failed */
148 
149 /* Special-case expected-packet-type values that are passed to
150    readHSPacketSSH() to handle situations where more than one return value is
151    valid.  CMSG_USER can return failure meaning "no password" even if
152    there's no actual failure, CMSG_AUTH_PASSWORD can return SMSG_FAILURE
153    which indicates a wrong password used iff it's a response to the client
154    sending a password, and MSG_USERAUTH_REQUEST can similarly return a
155    failure or success response.
156 
157    In addition to these types there's an "any" type which is used during the
158    setup negotiation which will accept any (non-error) packet type and return
159    the type as the return code */
160 
161 #define SSH_MSG_SPECIAL_FIRST		500	/* Boundary for _SPECIAL types */
162 #define SSH_MSG_SPECIAL_USERAUTH	501	/* Value to handle SSH combined auth.*/
163 #define SSH_MSG_SPECIAL_USERAUTH_PAM 502 /* Value to handle SSH PAM auth.*/
164 #define SSH_MSG_SPECIAL_CHANNEL		503	/* Value to handle channel open */
165 #define SSH_MSG_SPECIAL_REQUEST		504	/* Value to handle SSH global/channel req.*/
166 #define SSH_MSG_SPECIAL_LAST		505	/* Last valid _SPECIAL type */
167 
168 /* SSH disconnection codes */
169 
170 enum { SSH_DISCONNECT_NONE, SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT,
171 	   SSH_DISCONNECT_PROTOCOL_ERROR, SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
172 	   SSH_DISCONNECT_RESERVED, SSH_DISCONNECT_MAC_ERROR,
173 	   SSH_DISCONNECT_COMPRESSION_ERROR, SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
174 	   SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
175 	   SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, SSH_DISCONNECT_CONNECTION_LOST,
176 	   SSH_DISCONNECT_BY_APPLICATION, SSH_DISCONNECT_TOO_MANY_CONNECTIONS,
177 	   SSH_DISCONNECT_AUTH_CANCELLED_BY_USER,
178 	   SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
179 	   SSH_DISCONNECT_ILLEGAL_USER_NAME, SSH_DISCONNECT_LAST };
180 
181 /* SSH channel open failure codes */
182 
183 #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED			1
184 #define SSH_OPEN_CONNECT_FAILED							2
185 #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE					3
186 #define SSH_OPEN_RESOURCE_SHORTAGE						4
187 
188 /* SSH requires the use of a number of additional (pseudo)-algorithm
189    types that don't correspond to normal cryptlib algorithms.  To handle
190    these, we define pseudo-algoID values that fall within the range of
191    the normal algorithm ID types but that aren't normal algorithm IDs */
192 
193 #define CRYPT_PSEUDOALGO_PASSWORD	( CRYPT_ALGO_LAST_CONVENTIONAL - 2 )
194 #define CRYPT_PSEUDOALGO_PAM		( CRYPT_ALGO_LAST_CONVENTIONAL - 1 )
195 #define CRYPT_PSEUDOALGO_LAST		( CRYPT_ALGO_LAST_CONVENTIONAL )
196 
197 #define MK_ALGO( value )			( CRYPT_ALGO_TYPE ) ( CRYPT_##value )
198 
199 /* The size of the encoded DH keyex value and the requested DHE key size,
200    which we have to store in encoded form so that we can hash them later in
201    the handshake */
202 
203 #define MAX_ENCODED_KEYEXSIZE		( CRYPT_MAX_PKCSIZE + 16 )
204 #define ENCODED_REQKEYSIZE			( UINT_SIZE * 3 )
205 
206 /* Check whether an algorithm ID is one of the above pseudo-algorithm
207    types */
208 
209 #define isPseudoAlgo( algorithm ) \
210 		( algorithm >= CRYPT_PSEUDOALGO_PASSWORD && \
211 		  algorithm <= CRYPT_PSEUDOALGO_PAM )
212 
213 /* SSH algorithms are grouped into classes such as keyex algorithms or MAC
214    algorithms, the following type identifies the different algorithm
215    classes */
216 
217 typedef enum {
218 	SSH_ALGOCLASS_NONE,		/* No algorithm class */
219 	SSH_ALGOCLASS_KEYEX,	/* Keyex algorithms */
220 	SSH_ALGOCLASS_KEYEX_NOECC,/* Keyex algorithms limited to non-ECC algos */
221 	SSH_ALGOCLASS_ENCR,		/* Encryption algorithms */
222 	SSH_ALGOCLASS_MAC,		/* MAC algorithms */
223 	SSH_ALGOCLASS_COPR,		/* Compression algorithms */
224 	SSH_ALGOCLASS_LAST		/* Last possible algorithm class */
225 	} SSH_ALGOCLASS_TYPE;
226 
227 /* Values for working with SSH channels.  Channels have a 32-bit ID
228    (although no sane implementation uses very large values), to deal with
229    range checking for these we limit them to LONG_MAX in 32-bit systems.
230 
231    SSH channels have a number of SSH-internal attributes that aren't exposed
232    as cryptlib-wide attribute types.  The following values are used to
233    access SSH-internal channel attributes */
234 
235 #ifdef SYSTEM_64BIT
236   #define CHANNEL_MAX				0x0FFFFFFFFUL
237 #else
238   #define CHANNEL_MAX				LONG_MAX
239 #endif /* 32- vs 64-bit systems */
240 
241 typedef enum {
242 	SSH_ATTRIBUTE_NONE,						/* No channel attribute */
243 	SSH_ATTRIBUTE_ACTIVE,					/* Channel is active */
244 	SSH_ATTRIBUTE_WINDOWCOUNT,				/* Data window count */
245 	SSH_ATTRIBUTE_WINDOWSIZE,				/* Data window size */
246 	SSH_ATTRIBUTE_ALTCHANNELNO,				/* Secondary channel no. */
247 	SSH_ATTRIBUTE_LAST						/* Last channel attribute */
248 	} SSH_ATTRIBUTE_TYPE;
249 
250 /* Check whether a DH/ECDH value is valid for a given server key size.  The
251    check is slightly different for the ECC version because the value is
252    a composite ECC point with two coordinates, so we have to divide the
253    length by two to get the size of a single coordinate */
254 
255 #define isValidDHsize( value, serverKeySize, extraLength ) \
256 		( ( value ) > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \
257 		  ( value ) < ( ( serverKeySize ) + 2 ) + ( extraLength ) )
258 #define isValidECDHsize( value, serverKeySize, extraLength ) \
259 		( ( value ) / 2 > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \
260 		  ( value ) / 2 < ( ( serverKeySize ) + 2 ) + ( extraLength ) )
261 
262 /* The following macro can be used to enable dumping of PDUs to disk.  As a
263    safeguard, this only works in the Win32 debug version to prevent it from
264    being accidentally enabled in any release version */
265 
266 #if defined( __WIN32__ ) && !defined( NDEBUG )
267   #define DEBUG_DUMP_SSH( buffer, length, isRead ) \
268 		  debugDumpSSH( sessionInfoPtr, buffer, length, isRead )
269 
270   STDC_NONNULL_ARG( ( 1, 2 ) ) \
271   void debugDumpSSH( const SESSION_INFO *sessionInfoPtr,
272 					 IN_BUFFER( length ) const void *buffer,
273 					 IN_LENGTH_SHORT const int length,
274 					 const BOOLEAN isRead );
275 #else
276   #define DEBUG_DUMP_SSH( buffer, length, isRead )
277 #endif /* Win32 debug */
278 
279 /****************************************************************************
280 *																			*
281 *								SSH Structures								*
282 *																			*
283 ****************************************************************************/
284 
285 /* Mapping of SSH algorithm names to cryptlib algorithm IDs, in preferred
286    algorithm order.  Some of the algorithms are pure algorithms while others
287    are more like cipher suites, in order to check whether they're available
288    for use we have to map the suite pseudo-value into one or more actual
289    algorithms, which are given via the checkXXXAlgo values */
290 
291 typedef struct {
292 	/* Mapping from algorithm name to cryptlib algorithm ID.  The
293 	   "encryption" algorithm may not be a real cryptlib algorithm type but
294 	   an SSH-specific pseudo-algorithm in the CRYPT_PSEUDOALGO_xxx
295 	   range, for example CRYPT_PSEUDOALGO_PASSWORD */
296 	BUFFER_FIXED( nameLen ) \
297 	const char FAR_BSS *name;				/* Algorithm name */
298 	const int nameLen;
299 	const CRYPT_ALGO_TYPE algo;				/* Algorithm ID */
300 
301 	/* Optional parameters needed when the algorithm actually represents a
302 	   cipher suite */
303 	const CRYPT_ALGO_TYPE subAlgo;
304 	} ALGO_STRING_INFO;
305 
306 /* SSH handshake state information.  This is passed around various
307    subfunctions that handle individual parts of the handshake */
308 
309 #ifdef SH
310   /* VxWorks defines 'SH' (for SuperH CPUs), so we have to undefine it to
311      allow the following struct to be declared.  The VxWorks include file
312 	 order is such that it comes after osspec.h is included, so we can't
313 	 cover up the problem in that */
314   #undef SH
315 #endif /* SH */
316 
317 struct SH;
318 
319 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
320 	int ( *SSH_HANDSHAKE_FUNCTION )( INOUT SESSION_INFO *sessionInfoPtr,
321 									 INOUT struct SH *handshakeInfo );
322 
323 typedef struct SH {
324 	/* SSH exchange hash */
325 	BUFFER_FIXED( SSH2_COOKIE_SIZE ) \
326 	BYTE cookie[ SSH2_COOKIE_SIZE + 8 ];	/* Anti-spoofing cookie */
327 	BUFFER_FIXED( CRYPT_MAX_HASHSIZE ) \
328 	BYTE sessionID[ CRYPT_MAX_HASHSIZE + 8 ];/* Session ID/exchange hash */
329 	int sessionIDlength;
330 	CRYPT_ALGO_TYPE exchangeHashAlgo;		/* Exchange hash algorithm */
331 	CRYPT_CONTEXT iExchangeHashContext, iExchangeHashAltContext;
332 											/* Hash of exchanged information */
333 
334 	/* Information needed to compute the session ID.  SSH requires the
335 	   client and server DH/ECDH values (along with various other things,
336 	   but these are hashed inline).  The SSH values are in MPI-encoded
337 	   form so we need to reserve a little extra room for the length and
338 	   leading zero-padding */
339 	BUFFER( MAX_ENCODED_KEYEXSIZE, clientKeyexValueLength ) \
340 	BYTE clientKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ];
341 	BUFFER( MAX_ENCODED_KEYEXSIZE, serverKeyexValueLength ) \
342 	BYTE serverKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ];
343 	int clientKeyexValueLength, serverKeyexValueLength;
344 
345 	/* Encryption algorithm and key information */
346 	CRYPT_ALGO_TYPE pubkeyAlgo;				/* Host signature algo */
347 	CRYPT_ALGO_TYPE hashAlgo;				/* Host signature hash algo */
348 	BUFFER( CRYPT_MAX_PKCSIZE, secretValueLength ) \
349 	BYTE secretValue[ CRYPT_MAX_PKCSIZE + 8 ];	/* Shared secret value */
350 	int secretValueLength;
351 
352 	/* DH/ECDH key agreement context and the client requested DH key size
353 	   for the key exchange.  Alongside the actual key size we also store
354 	   the original encoded form, which has to be hashed as part of the
355 	   exchange hash.  The long-term host key is stored as the session
356 	   information iKeyexCryptContext for the client and privateKey for the
357 	   server.   Since ECDH doesn't just entail a new algorithm but an
358 	   entire cipher suite, we provide a flag to make checking for this
359 	   easier */
360 	CRYPT_ALGO_TYPE keyexAlgo;				/* Keyex algo */
361 	CRYPT_CONTEXT iServerCryptContext;
362 	int serverKeySize, requestedServerKeySize;
363 	BUFFER( ENCODED_REQKEYSIZE, encodedReqKeySizesLength ) \
364 	BYTE encodedReqKeySizes[ ENCODED_REQKEYSIZE + 8 ];
365 	int encodedReqKeySizesLength;
366 	BOOLEAN isECDH;							/* Use of ECC cipher suite */
367 
368 	/* Table mapping SSH algorithm names to cryptlib algorithm IDs.  This
369 	   serves two purposes, firstly by declaring it once in ssh2.c and
370 	   referring to it via pointers we can make the data static const, which
371 	   is necessary in some environments to get them into the read-only
372 	   segment, and secondly for the server where we advertise algorithm X
373 	   to the client it allows us to switch to a restricted table that only
374 	   allows algorithm X in return from the client */
375 	const ALGO_STRING_INFO FAR_BSS *algoStringPubkeyTbl;
376 	int algoStringPubkeyTblNoEntries;
377 
378 	/* Function pointers to handshaking functions.  These are set up as
379 	   required depending on whether the session is client or server */
380 	FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, beginHandshake );
381 	FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, exchangeKeys );
382 	FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, completeHandshake );
383 	} SSH_HANDSHAKE_INFO;
384 
385 /* Channel number and ID used to mark an unused channel */
386 
387 #define UNUSED_CHANNEL_NO	CRYPT_ERROR
388 #define UNUSED_CHANNEL_ID	0
389 
390 /****************************************************************************
391 *																			*
392 *								SSH Functions								*
393 *																			*
394 ****************************************************************************/
395 
396 /* Unlike SSL, SSH only hashes portions of the handshake, and even then not
397    complete packets but arbitrary bits and pieces.  In order to perform the
398    hashing, we have to be able to bookmark positions in a stream to allow
399    the data at that point to be hashed once it's been encoded or decoded.
400    The following macros set and complete a bookmark.
401 
402    When we create or continue a packet stream, the packet type is written
403    before we can set the bookmark.  To handle this, we also provide a macro
404    that sets the bookmark for a full packet by adjusting for the packet type
405    that's already been written */
406 
407 #define streamBookmarkSet( stream, offset ) \
408 		offset = stell( stream )
409 #define streamBookmarkSetFullPacket( stream, offset ) \
410 		offset = stell( stream ) - ID_SIZE
411 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
412 int streamBookmarkComplete( INOUT STREAM *stream,
413 							OUT_OPT_PTR void **dataPtrPtr,
414 							OUT_DATALENGTH_Z int *length,
415 							IN_DATALENGTH const int position );
416 
417 /* Prototypes for functions in ssh2.c */
418 
419 STDC_NONNULL_ARG( ( 1 ) ) \
420 void initHandshakeCrypt( INOUT SSH_HANDSHAKE_INFO *handshakeInfo );
421 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
422 int hashHandshakeStrings( INOUT SSH_HANDSHAKE_INFO *handshakeInfo,
423 						  IN_BUFFER( clientStringLength ) \
424 								const void *clientString,
425 						  IN_LENGTH_SHORT const int clientStringLength,
426 						  IN_BUFFER( serverStringLength ) \
427 								const void *serverString,
428 						  IN_LENGTH_SHORT const int serverStringLength );
429 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 6 ) ) \
430 int readAlgoString( INOUT STREAM *stream,
431 					IN_ARRAY( noAlgoStringEntries ) \
432 						const ALGO_STRING_INFO *algoInfo,
433 					IN_RANGE( 1, 100 ) const int noAlgoStringEntries,
434 					OUT_ALGO_Z CRYPT_ALGO_TYPE *algo,
435 					const BOOLEAN useFirstMatch,
436 					INOUT ERROR_INFO *errorInfo );
437 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
438 int writeAlgoString( INOUT STREAM *stream,
439 					 IN_ALGO const CRYPT_ALGO_TYPE algo );
440 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
441 int writeAlgoStringEx( INOUT STREAM *stream,
442 					   IN_ALGO const CRYPT_ALGO_TYPE algo,
443 					   IN_ALGO_OPT const CRYPT_ALGO_TYPE subAlgo );
444 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
445 int writeAlgoList( INOUT STREAM *stream,
446 				   IN_ARRAY( noAlgoStringInfoEntries ) \
447 						const ALGO_STRING_INFO *algoStringInfoTbl,
448 				   IN_RANGE( 1, 10 ) const int noAlgoStringInfoEntries );
449 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
450 int writeAlgoClassList( INOUT STREAM *stream,
451 						IN_ENUM( SSH_ALGOCLASS ) \
452 							const SSH_ALGOCLASS_TYPE algoClass );
453 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
454 int processHelloSSH( INOUT SESSION_INFO *sessionInfoPtr,
455 					 INOUT SSH_HANDSHAKE_INFO *handshakeInfo,
456 					 OUT_LENGTH_SHORT_Z int *keyexLength,
457 					 const BOOLEAN isServer );
458 
459 /* Prototypes for functions in ssh2_authc.c/ssh2_auths.c  */
460 
461 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
462 int processClientAuth( INOUT SESSION_INFO *sessionInfoPtr,
463 					   INOUT SSH_HANDSHAKE_INFO *handshakeInfo );
464 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
465 int processServerAuth( INOUT SESSION_INFO *sessionInfoPtr,
466 					   const BOOLEAN userInfoPresent );
467 
468 /* Prototypes for functions in ssh2_chn.c */
469 
470 typedef enum { CHANNEL_NONE, CHANNEL_READ, CHANNEL_WRITE,
471 			   CHANNEL_BOTH, CHANNEL_LAST } CHANNEL_TYPE;
472 
473 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
474 int createChannel( INOUT SESSION_INFO *sessionInfoPtr );
475 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
476 int addChannel( INOUT SESSION_INFO *sessionInfoPtr,
477 				IN const long channelNo,
478 				IN_LENGTH_MIN( 1024 ) const int maxPacketSize,
479 				IN_BUFFER( typeLen ) const void *type,
480 				IN_LENGTH_SHORT const int typeLen,
481 				IN_BUFFER_OPT( arg1Len ) const void *arg1,
482 				IN_LENGTH_SHORT_Z const int arg1Len );
483 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
484 int deleteChannel( INOUT SESSION_INFO *sessionInfoPtr,
485 				   IN const long channelNo,
486 				   IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType,
487 				   const BOOLEAN deleteLastChannel );
488 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
489 int selectChannel( INOUT SESSION_INFO *sessionInfoPtr,
490 				   IN const long channelNo,
491 				   IN_ENUM_OPT( CHANNEL ) const CHANNEL_TYPE channelType );
492 CHECK_RETVAL_RANGE_NOERROR( UNUSED_CHANNEL_NO, CHANNEL_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \
493 long getCurrentChannelNo( const SESSION_INFO *sessionInfoPtr,
494 						  IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType );
495 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
496 CHANNEL_TYPE getChannelStatusByChannelNo( const SESSION_INFO *sessionInfoPtr,
497 										  IN const long channelNo );
498 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
499 CHANNEL_TYPE getChannelStatusByAddr( const SESSION_INFO *sessionInfoPtr,
500 									 IN_BUFFER( addrInfoLen ) const char *addrInfo,
501 									 IN_LENGTH_SHORT const int addrInfoLen );
502 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
503 int getChannelAttribute( const SESSION_INFO *sessionInfoPtr,
504 						 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
505 						 OUT_INT_Z int *value );
506 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
507 int getChannelAttributeS( const SESSION_INFO *sessionInfoPtr,
508 						  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
509 						  OUT_BUFFER_OPT( dataMaxLength, *dataLength ) \
510 								void *data,
511 						  IN_LENGTH_SHORT_Z const int dataMaxLength,
512 						  OUT_LENGTH_BOUNDED_Z( dataMaxLength ) \
513 								int *dataLength );
514 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
515 int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
516 							IN_ENUM( SSH_ATTRIBUTE ) \
517 								const SSH_ATTRIBUTE_TYPE attribute,
518 							OUT_INT_Z int *value );
519 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
520 int setChannelAttribute( INOUT SESSION_INFO *sessionInfoPtr,
521 						 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
522 						 IN_INT_SHORT const int value );
523 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
524 int setChannelAttributeS( INOUT SESSION_INFO *sessionInfoPtr,
525 						  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
526 						  IN_BUFFER( dataLength ) const void *data,
527 						  IN_LENGTH_TEXT const int dataLength );
528 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
529 int setChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
530 							IN_ATTRIBUTE const SSH_ATTRIBUTE_TYPE attribute,
531 							IN_INT_Z const int value );
532 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
533 int enqueueResponse( INOUT SESSION_INFO *sessionInfoPtr,
534 					 IN_RANGE( 1, 255 ) const int type,
535 					 IN_RANGE( 0, 4 ) const int noParams,
536 					 IN const long channelNo,
537 					 const int param1, const int param2, const int param3 );
538 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
539 int sendEnqueuedResponse( INOUT SESSION_INFO *sessionInfoPtr );
540 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
541 int enqueueChannelData( INOUT SESSION_INFO *sessionInfoPtr,
542 						IN_RANGE( 1, 255 ) const int type,
543 						IN const long channelNo,
544 						const int param );
545 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
546 int appendChannelData( INOUT SESSION_INFO *sessionInfoPtr,
547 					   IN_LENGTH_SHORT_Z const int offset );
548 
549 /* Prototypes for functions in ssh2_msg.c */
550 
551 CHECK_RETVAL_RANGE_NOERROR( 10000, MAX_WINDOW_SIZE ) STDC_NONNULL_ARG( ( 1 ) ) \
552 int getWindowSize( const SESSION_INFO *sessionInfoPtr );
553 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
554 int closeChannel( INOUT SESSION_INFO *sessionInfoPtr,
555 				  const BOOLEAN closeAllChannels );
556 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
557 int processChannelControlMessage( INOUT SESSION_INFO *sessionInfoPtr,
558 								  INOUT STREAM *stream );
559 
560 /* Prototypes for functions in ssh2_msgc.c */
561 
562 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
563 int sendChannelOpen( INOUT SESSION_INFO *sessionInfoPtr );
564 
565 /* Prototypes for functions in ssh2_msgs.c */
566 
567 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
568 int processChannelOpen( INOUT SESSION_INFO *sessionInfoPtr,
569 						INOUT STREAM *stream );
570 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
571 int processChannelRequest( INOUT SESSION_INFO *sessionInfoPtr,
572 						   INOUT STREAM *stream,
573 						   IN const long prevChannelNo );
574 
575 /* Prototypes for functions in ssh2_cry.c */
576 
577 typedef enum { MAC_NONE, MAC_START, MAC_END, MAC_LAST } MAC_TYPE;
578 
579 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
580 int initSecurityInfo( INOUT SESSION_INFO *sessionInfoPtr,
581 					  INOUT SSH_HANDSHAKE_INFO *handshakeInfo );
582 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
583 int initSecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr );
584 STDC_NONNULL_ARG( ( 1 ) ) \
585 void destroySecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr );
586 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
587 int initDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext,
588 					  OUT_LENGTH_SHORT_Z int *keySize,
589 					  IN_BUFFER_OPT( keyDataLength ) const void *keyData,
590 					  IN_LENGTH_SHORT_Z const int keyDataLength,
591 					  IN_LENGTH_SHORT_OPT const int requestedKeySize );
592 #ifdef USE_ECDH
593 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
594 int initECDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext,
595 						OUT_LENGTH_SHORT_Z int *keySize,
596 						IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo );
597 #endif /* USE_ECDH */
598 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
599 int completeKeyex( INOUT SESSION_INFO *sessionInfoPtr,
600 				   INOUT SSH_HANDSHAKE_INFO *handshakeInfo,
601 				   const BOOLEAN isServer );
602 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
603 int hashAsString( IN_HANDLE const CRYPT_CONTEXT iHashContext,
604 				  IN_BUFFER( dataLength ) const BYTE *data,
605 				  IN_LENGTH_SHORT const int dataLength );
606 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
607 int hashAsMPI( IN_HANDLE const CRYPT_CONTEXT iHashContext,
608 			   IN_BUFFER( dataLength ) const BYTE *data,
609 			   IN_LENGTH_SHORT const int dataLength );
610 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
611 int checkMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext,
612 				 IN_INT const long seqNo,
613 				 IN_BUFFER( dataMaxLength ) const BYTE *data,
614 				 IN_DATALENGTH const int dataMaxLength,
615 				 IN_DATALENGTH_Z const int dataLength,
616 				 IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength );
617 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
618 int checkMacSSHIncremental( IN_HANDLE const CRYPT_CONTEXT iMacContext,
619 							IN_INT_Z const long seqNo,
620 							IN_BUFFER( dataMaxLength ) const BYTE *data,
621 							IN_DATALENGTH const int dataMaxLength,
622 							IN_DATALENGTH_Z const int dataLength,
623 							IN_DATALENGTH_Z const int packetDataLength,
624 							IN_ENUM( MAC ) const MAC_TYPE macType,
625 							IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength );
626 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
627 int createMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext,
628 				  IN_INT const long seqNo,
629 				  IN_BUFFER( dataMaxLength ) BYTE *data,
630 				  IN_DATALENGTH const int dataMaxLength,
631 				  IN_DATALENGTH const int dataLength );
632 
633 /* Prototypes for functions in ssh2_rd.c */
634 
635 CHECK_RETVAL_PTR_NONNULL \
636 const char *getSSHPacketName( IN_RANGE( 0, 255 ) const int packetType );
637 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
638 int readPacketHeaderSSH2( INOUT SESSION_INFO *sessionInfoPtr,
639 						  IN_RANGE( SSH_MSG_DISCONNECT, \
640 									SSH_MSG_SPECIAL_REQUEST ) \
641 								const int expectedType,
642 						  OUT_LENGTH_Z long *packetLength,
643 						  OUT_DATALENGTH_Z int *packetExtraLength,
644 						  INOUT SSH_INFO *sshInfo,
645 						  INOUT_OPT READSTATE_INFO *readInfo );
646 CHECK_RETVAL_LENGTH_SHORT STDC_NONNULL_ARG( ( 1 ) ) \
647 int readHSPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
648 					  IN_RANGE( SSH_MSG_DISCONNECT, \
649 								SSH_MSG_SPECIAL_REQUEST ) \
650 							int expectedType,
651 					  IN_RANGE( 1, 1024 ) const int minPacketSize );
652 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
653 int getDisconnectInfo( INOUT SESSION_INFO *sessionInfoPtr,
654 					   INOUT STREAM *stream );
655 
656 /* Prototypes for functions in ssh2_wr.c */
657 
658 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
659 int openPacketStreamSSH( OUT STREAM *stream,
660 						 const SESSION_INFO *sessionInfoPtr,
661 						 IN_RANGE( SSH_MSG_DISCONNECT, \
662 								   SSH_MSG_CHANNEL_FAILURE )
663 							const int packetType );
664 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
665 int openPacketStreamSSHEx( OUT STREAM *stream,
666 						   const SESSION_INFO *sessionInfoPtr,
667 						   IN_DATALENGTH const int bufferSize,
668 						   IN_RANGE( SSH_MSG_DISCONNECT, \
669 									 SSH_MSG_CHANNEL_FAILURE )
670 								const int packetType );
671 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
672 int continuePacketStreamSSH( INOUT STREAM *stream,
673 							 IN_RANGE( SSH_MSG_DISCONNECT, \
674 									   SSH_MSG_CHANNEL_FAILURE ) \
675 								const int packetType,
676 							 OUT_DATALENGTH_Z int *packetOffset );
677 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
678 int wrapPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
679 					INOUT STREAM *stream,
680 					IN_DATALENGTH_Z const int offset,
681 					const BOOLEAN useQuantisedPadding,
682 					const BOOLEAN isWriteableStream );
683 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
684 int sendPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
685 					INOUT STREAM *stream,
686 					const BOOLEAN sendOnly );
687 
688 /* Prototypes for session mapping functions */
689 
690 STDC_NONNULL_ARG( ( 1 ) ) \
691 void initSSH2processing( INOUT SESSION_INFO *sessionInfoPtr );
692 STDC_NONNULL_ARG( ( 1 ) ) \
693 void initSSH2clientProcessing( INOUT SSH_HANDSHAKE_INFO *handshakeInfo );
694 STDC_NONNULL_ARG( ( 1 ) ) \
695 void initSSH2serverProcessing( INOUT SSH_HANDSHAKE_INFO *handshakeInfo );
696 #endif /* _SSH_DEFINED */
697