ssh_kex_dh.c
Go to the documentation of this file.
1 /**
2  * @file ssh_kex_dh.c
3  * @brief Diffie-Hellman key exchange
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSH Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SSH_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ssh/ssh.h"
36 #include "ssh/ssh_algorithms.h"
37 #include "ssh/ssh_transport.h"
38 #include "ssh/ssh_kex.h"
39 #include "ssh/ssh_kex_dh.h"
40 #include "ssh/ssh_packet.h"
41 #include "ssh/ssh_key_material.h"
42 #include "ssh/ssh_exchange_hash.h"
43 #include "ssh/ssh_modp_groups.h"
44 #include "ssh/ssh_key_verify.h"
45 #include "ssh/ssh_cert_verify.h"
46 #include "ssh/ssh_misc.h"
47 #include "debug.h"
48 
49 //Check SSH stack configuration
50 #if (SSH_SUPPORT == ENABLED && SSH_DH_KEX_SUPPORT == ENABLED)
51 
52 
53 /**
54  * @brief Send SSH_MSG_KEX_DH_INIT message
55  * @param[in] connection Pointer to the SSH connection
56  * @return Error code
57  **/
58 
60 {
61 #if (SSH_CLIENT_SUPPORT == ENABLED)
62  error_t error;
63  size_t length;
64  uint8_t *message;
65  SshContext *context;
66 
67  //Point to the SSH context
68  context = connection->context;
69 
70  //Point to the buffer where to format the message
71  message = connection->buffer + SSH_PACKET_HEADER_SIZE;
72 
73  //Load the MODP group that matches the key exchange algorithm name
74  error = sshLoadDhModpGroup(&connection->dhContext.params,
75  connection->kexAlgo);
76 
77  //Check status code
78  if(!error)
79  {
80  //Generate an ephemeral key pair
81  error = dhGenerateKeyPair(&connection->dhContext, context->prngAlgo,
82  context->prngContext);
83  }
84 
85  //Check status code
86  if(!error)
87  {
88  //Format SSH_MSG_KEX_DH_INIT message
89  error = sshFormatKexDhInit(connection, message, &length);
90  }
91 
92  //Check status code
93  if(!error)
94  {
95  //Debug message
96  TRACE_INFO("Sending SSH_MSG_KEX_DH_INIT message (%" PRIuSIZE " bytes)...\r\n", length);
98 
99  //Send message
100  error = sshSendPacket(connection, message, length);
101  }
102 
103  //Check status code
104  if(!error)
105  {
106  //The server responds with an SSH_MSG_KEX_DH_REPLY message
107  connection->state = SSH_CONN_STATE_KEX_DH_REPLY;
108  }
109 
110  //Return status code
111  return error;
112 #else
113  //Client operation mode is not implemented
114  return ERROR_NOT_IMPLEMENTED;
115 #endif
116 }
117 
118 
119 /**
120  * @brief Send SSH_MSG_KEX_DH_REPLY message
121  * @param[in] connection Pointer to the SSH connection
122  * @return Error code
123  **/
124 
126 {
127 #if (SSH_SERVER_SUPPORT == ENABLED)
128  error_t error;
129  size_t length;
130  uint8_t *message;
131  SshContext *context;
132 
133  //Point to the SSH context
134  context = connection->context;
135 
136  //Point to the buffer where to format the message
137  message = connection->buffer + SSH_PACKET_HEADER_SIZE;
138 
139  //Generate an ephemeral key pair
140  error = dhGenerateKeyPair(&connection->dhContext, context->prngAlgo,
141  context->prngContext);
142 
143  //Check status code
144  if(!error)
145  {
146  //Format SSH_MSG_KEX_DH_REPLY message
147  error = sshFormatKexDhReply(connection, message, &length);
148  }
149 
150  //Check status code
151  if(!error)
152  {
153  //Debug message
154  TRACE_INFO("Sending SSH_MSG_KEX_DH_REPLY message (%" PRIuSIZE " bytes)...\r\n", length);
156 
157  //Send message
158  error = sshSendPacket(connection, message, length);
159  }
160 
161  //Check status code
162  if(!error)
163  {
164  //Key exchange ends by each side sending an SSH_MSG_NEWKEYS message
165  connection->state = SSH_CONN_STATE_SERVER_NEW_KEYS;
166  }
167 
168  //Return status code
169  return error;
170 #else
171  //Server operation mode is not implemented
172  return ERROR_NOT_IMPLEMENTED;
173 #endif
174 }
175 
176 
177 /**
178  * @brief Format SSH_MSG_KEX_DH_INIT message
179  * @param[in] connection Pointer to the SSH connection
180  * @param[out] p Buffer where to format the message
181  * @param[out] length Length of the resulting message, in bytes
182  * @return Error code
183  **/
184 
186  size_t *length)
187 {
188 #if (SSH_CLIENT_SUPPORT == ENABLED)
189  error_t error;
190  size_t n;
191 
192  //Total length of the message
193  *length = 0;
194 
195  //Set message type
196  p[0] = SSH_MSG_KEX_DH_INIT;
197 
198  //Point to the first field of the message
199  p += sizeof(uint8_t);
200  *length += sizeof(uint8_t);
201 
202  //Format client's ephemeral public key (e)
203  error = sshFormatMpint(&connection->dhContext.ya, p, &n);
204  //Any error to report?
205  if(error)
206  return error;
207 
208  //Total length of the message
209  *length += n;
210 
211  //Successful processing
212  return NO_ERROR;
213 #else
214  //Client operation mode is not implemented
215  return ERROR_NOT_IMPLEMENTED;
216 #endif
217 }
218 
219 
220 /**
221  * @brief Format SSH_MSG_KEX_DH_REPLY message
222  * @param[in] connection Pointer to the SSH connection
223  * @param[out] p Buffer where to format the message
224  * @param[out] length Length of the resulting message, in bytes
225  * @return Error code
226  **/
227 
229  size_t *length)
230 {
231 #if (SSH_SERVER_SUPPORT == ENABLED)
232  error_t error;
233  size_t n;
234 
235  //Total length of the message
236  *length = 0;
237 
238  //Set message type
239  p[0] = SSH_MSG_KEX_DH_REPLY;
240 
241  //Point to the first field of the message
242  p += sizeof(uint8_t);
243  *length += sizeof(uint8_t);
244 
245  //Format server's public host key (K_S)
246  error = sshFormatHostKey(connection, p + sizeof(uint32_t), &n);
247  //Any error to report?
248  if(error)
249  return error;
250 
251  //The octet string value is preceded by a uint32 containing its length
252  STORE32BE(n, p);
253 
254  //Point to the next field
255  p += sizeof(uint32_t) + n;
256  *length += sizeof(uint32_t) + n;
257 
258  //Format server's ephemeral public key (f)
259  error = sshFormatMpint(&connection->dhContext.ya, p, &n);
260  //Any error to report?
261  if(error)
262  return error;
263 
264  //Update exchange hash H with f (exchange value sent by the server)
265  error = sshUpdateExchangeHashRaw(connection, p, n);
266  //Any error to report?
267  if(error)
268  return error;
269 
270  //Point to the next field
271  p += n;
272  *length += n;
273 
274  //Compute the shared secret K
275  error = sshComputeDhSharedSecret(connection);
276  //Any error to report?
277  if(error)
278  return error;
279 
280  //Update exchange hash H with K (shared secret)
281  error = sshUpdateExchangeHashRaw(connection, connection->k,
282  connection->kLen);
283  //Any error to report?
284  if(error)
285  return error;
286 
287  //Compute the signature on the exchange hash
288  error = sshGenerateExchangeHashSignature(connection, p + sizeof(uint32_t),
289  &n);
290  //Any error to report?
291  if(error)
292  return error;
293 
294  //The octet string value is preceded by a uint32 containing its length
295  STORE32BE(n, p);
296 
297  //Total length of the message
298  *length += sizeof(uint32_t) + n;
299 
300  //The ephemeral private key shall be destroyed as soon as possible (refer
301  //to RFC 9212, section 6)
302  dhFree(&connection->dhContext);
303  dhInit(&connection->dhContext);
304 
305  //Successful processing
306  return NO_ERROR;
307 #else
308  //Server operation mode is not implemented
309  return ERROR_NOT_IMPLEMENTED;
310 #endif
311 }
312 
313 
314 /**
315  * @brief Parse SSH_MSG_KEX_DH_INIT message
316  * @param[in] connection Pointer to the SSH connection
317  * @param[in] message Pointer to message
318  * @param[in] length Length of the message, in bytes
319  * @return Error code
320  **/
321 
322 error_t sshParseKexDhInit(SshConnection *connection, const uint8_t *message,
323  size_t length)
324 {
325 #if (SSH_SERVER_SUPPORT == ENABLED)
326  error_t error;
327  const uint8_t *p;
328  SshBinaryString publicKey;
329 
330  //Debug message
331  TRACE_INFO("SSH_MSG_KEX_DH_INIT message received (%" PRIuSIZE " bytes)...\r\n", length);
333 
334  //Check operation mode
335  if(connection->context->mode != SSH_OPERATION_MODE_SERVER)
337 
338  //Check connection state
339  if(connection->state != SSH_CONN_STATE_KEX_DH_INIT)
341 
342  //Sanity check
343  if(length < sizeof(uint8_t))
344  return ERROR_INVALID_MESSAGE;
345 
346  //Point to the first field of the message
347  p = message + sizeof(uint8_t);
348  //Remaining bytes to process
349  length -= sizeof(uint8_t);
350 
351  //Decode client's ephemeral public key (e)
352  error = sshParseBinaryString(p, length, &publicKey);
353  //Any error to report?
354  if(error)
355  return error;
356 
357  //Point to the next field
358  p += sizeof(uint32_t) + publicKey.length;
359  length -= sizeof(uint32_t) + publicKey.length;
360 
361  //Malformed message?
362  if(length != 0)
363  return ERROR_INVALID_MESSAGE;
364 
365  //Update exchange hash H with e (exchange value sent by the client)
366  error = sshUpdateExchangeHash(connection, publicKey.value,
367  publicKey.length);
368  //Any error to report?
369  if(error)
370  return error;
371 
372  //Load the MODP group that matches the key exchange algorithm name
373  error = sshLoadDhModpGroup(&connection->dhContext.params,
374  connection->kexAlgo);
375  //Any error to report?
376  if(error)
377  return error;
378 
379  //Load client's ephemeral public key
380  error = dhImportPeerPublicKey(&connection->dhContext, publicKey.value,
381  publicKey.length, MPI_FORMAT_BIG_ENDIAN);
382  //Any error to report?
383  if(error)
384  return error;
385 
386  //The server responds with an SSH_MSG_KEX_DH_REPLY message
387  return sshSendKexDhReply(connection);
388 #else
389  //Server operation mode is not implemented
391 #endif
392 }
393 
394 
395 /**
396  * @brief Parse SSH_MSG_KEX_DH_REPLY message
397  * @param[in] connection Pointer to the SSH connection
398  * @param[in] message Pointer to message
399  * @param[in] length Length of the message, in bytes
400  * @return Error code
401  **/
402 
403 error_t sshParseKexDhReply(SshConnection *connection, const uint8_t *message,
404  size_t length)
405 {
406 #if (SSH_CLIENT_SUPPORT == ENABLED)
407  error_t error;
408  const uint8_t *p;
409  SshString hostKeyAlgo;
410  SshBinaryString hostKey;
411  SshBinaryString publicKey;
412  SshBinaryString signature;
413 
414  //Debug message
415  TRACE_INFO("SSH_MSG_KEX_DH_REPLY message received (%" PRIuSIZE " bytes)...\r\n", length);
417 
418  //Check operation mode
419  if(connection->context->mode != SSH_OPERATION_MODE_CLIENT)
421 
422  //Check connection state
423  if(connection->state != SSH_CONN_STATE_KEX_DH_REPLY)
425 
426  //Sanity check
427  if(length < sizeof(uint8_t))
428  return ERROR_INVALID_MESSAGE;
429 
430  //Point to the first field of the message
431  p = message + sizeof(uint8_t);
432  //Remaining bytes to process
433  length -= sizeof(uint8_t);
434 
435  //Decode server's public host key (K_S)
436  error = sshParseBinaryString(p, length, &hostKey);
437  //Any error to report?
438  if(error)
439  return error;
440 
441  //Point to the next field
442  p += sizeof(uint32_t) + hostKey.length;
443  length -= sizeof(uint32_t) + hostKey.length;
444 
445  //Decode server's ephemeral public key (f)
446  error = sshParseBinaryString(p, length, &publicKey);
447  //Any error to report?
448  if(error)
449  return error;
450 
451  //Point to the next field
452  p += sizeof(uint32_t) + publicKey.length;
453  length -= sizeof(uint32_t) + publicKey.length;
454 
455  //Decode the signature field
456  error = sshParseBinaryString(p, length, &signature);
457  //Any error to report?
458  if(error)
459  return error;
460 
461  //Point to the next field
462  p += sizeof(uint32_t) + signature.length;
463  length -= sizeof(uint32_t) + signature.length;
464 
465  //Malformed message?
466  if(length != 0)
467  return ERROR_INVALID_MESSAGE;
468 
469  //Get the selected server's host key algorithm
470  hostKeyAlgo.value = connection->serverHostKeyAlgo;
471  hostKeyAlgo.length = osStrlen(connection->serverHostKeyAlgo);
472 
473 #if (SSH_CERT_SUPPORT == ENABLED)
474  //Certificate-based authentication?
475  if(sshIsCertPublicKeyAlgo(&hostKeyAlgo))
476  {
477  //Verify server's certificate
478  error = sshVerifyServerCertificate(connection, &hostKeyAlgo, &hostKey);
479  }
480  else
481 #endif
482  {
483  //Verify server's host key
484  error = sshVerifyServerHostKey(connection, &hostKeyAlgo, &hostKey);
485  }
486 
487  //If the client fails to verify the server's host key, it should disconnect
488  //from the server by sending an SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE
489  //message
490  if(error)
491  return ERROR_INVALID_KEY;
492 
493  //Update exchange hash H with K_S (server's public host key)
494  error = sshUpdateExchangeHash(connection, hostKey.value, hostKey.length);
495  //Any error to report?
496  if(error)
497  return error;
498 
499  //Update exchange hash H with e (exchange value sent by the client)
500  error = sshDigestClientDhPublicKey(connection);
501  //Any error to report?
502  if(error)
503  return error;
504 
505  //Update exchange hash H with f (exchange value sent by the server)
506  error = sshUpdateExchangeHash(connection, publicKey.value, publicKey.length);
507  //Any error to report?
508  if(error)
509  return error;
510 
511  //Load server's ephemeral public key
512  error = dhImportPeerPublicKey(&connection->dhContext, publicKey.value,
513  publicKey.length, MPI_FORMAT_BIG_ENDIAN);
514  //Any error to report?
515  if(error)
516  return error;
517 
518  //Compute the shared secret K
519  error = sshComputeDhSharedSecret(connection);
520  //Any error to report?
521  if(error)
522  return error;
523 
524  //Update exchange hash H with K (shared secret)
525  error = sshUpdateExchangeHashRaw(connection, connection->k,
526  connection->kLen);
527  //Any error to report?
528  if(error)
529  return error;
530 
531  //Verify the signature on the exchange hash
532  error = sshVerifyExchangeHashSignature(connection, &hostKey, &signature);
533  //Any error to report?
534  if(error)
535  return error;
536 
537  //The ephemeral private key shall be destroyed as soon as possible (refer
538  //to RFC 9212, section 6)
539  dhFree(&connection->dhContext);
540  dhInit(&connection->dhContext);
541 
542  //Key exchange ends by each side sending an SSH_MSG_NEWKEYS message
543  return sshSendNewKeys(connection);
544 #else
545  //Client operation mode is not implemented
547 #endif
548 }
549 
550 
551 /**
552  * @brief Parse Diffie-Hellman specific messages
553  * @param[in] connection Pointer to the SSH connection
554  * @param[in] type SSH message type
555  * @param[in] message Pointer to message
556  * @param[in] length Length of the message, in bytes
557  * @return Error code
558  **/
559 
561  const uint8_t *message, size_t length)
562 {
563  error_t error;
564 
565 #if (SSH_CLIENT_SUPPORT == ENABLED)
566  //Client operation mode?
567  if(connection->context->mode == SSH_OPERATION_MODE_CLIENT)
568  {
569  //Check message type
571  {
572  //Parse SSH_MSG_KEX_DH_REPLY message
573  error = sshParseKexDhReply(connection, message, length);
574  }
575  else
576  {
577  //Unknown message type
578  error = ERROR_INVALID_TYPE;
579  }
580  }
581  else
582 #endif
583 #if (SSH_SERVER_SUPPORT == ENABLED)
584  //Server operation mode?
585  if(connection->context->mode == SSH_OPERATION_MODE_SERVER)
586  {
587  //Check message type
589  {
590  //Parse SSH_MSG_KEX_DH_INIT message
591  error = sshParseKexDhInit(connection, message, length);
592  }
593  else
594  {
595  //Unknown message type
596  error = ERROR_INVALID_TYPE;
597  }
598  }
599  else
600 #endif
601  //Invalid operation mode?
602  {
603  //Report an error
604  error = ERROR_INVALID_TYPE;
605  }
606 
607  //Return status code
608  return error;
609 }
610 
611 
612 /**
613  * @brief Diffie-Hellman shared secret calculation
614  * @param[in] connection Pointer to the SSH connection
615  * @return Error code
616  **/
617 
619 {
620  error_t error;
621 
622  //Compute the shared secret K
623  error = dhComputeSharedSecret(&connection->dhContext, connection->k,
625 
626  //Check status code
627  if(!error)
628  {
629  //Log shared secret (for debugging purpose only)
630  sshDumpKey(connection, "SHARED_SECRET", connection->k, connection->kLen);
631 
632  //Convert the shared secret K to mpint representation
633  error = sshConvertArrayToMpint(connection->k, connection->kLen,
634  connection->k, &connection->kLen);
635  }
636 
637  //Return status code
638  return error;
639 }
640 
641 
642 /**
643  * @brief Update exchange hash with client's ephemeral public key
644  * @param[in] connection Pointer to the SSH connection
645  * @return Error code
646  **/
647 
649 {
650  error_t error;
651  size_t n;
652  uint8_t *buffer;
653 
654  //Allocate a temporary buffer
655  buffer = sshAllocMem(SSH_BUFFER_SIZE);
656 
657  //Successful memory allocation?
658  if(buffer != NULL)
659  {
660  //Format client's ephemeral public key
661  error = sshFormatMpint(&connection->dhContext.ya, buffer, &n);
662 
663  //Check status code
664  if(!error)
665  {
666  //Update exchange hash H with e (exchange value sent by the client)
667  error = sshUpdateExchangeHashRaw(connection, buffer, n);
668  }
669 
670  //Release previously allocated memory
671  sshFreeMem(buffer);
672  }
673  else
674  {
675  //Failed to allocate memory
676  error = ERROR_OUT_OF_MEMORY;
677  }
678 
679  //Return status code
680  return error;
681 }
682 
683 #endif
Modular exponentiation (MODP) groups.
@ SSH_MSG_KEX_DH_REPLY
Definition: ssh.h:951
error_t sshGenerateExchangeHashSignature(SshConnection *connection, uint8_t *p, size_t *written)
Compute the signature on the exchange hash.
error_t sshSendKexDhInit(SshConnection *connection)
Send SSH_MSG_KEX_DH_INIT message.
Definition: ssh_kex_dh.c:59
SSH host key verification.
Binary string.
Definition: ssh_types.h:67
Diffie-Hellman key exchange.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
void sshDumpKey(SshConnection *connection, const char_t *label, const uint8_t *key, size_t keyLen)
Dump secret key (for debugging purpose only)
uint8_t p
Definition: ndp.h:300
uint8_t message[]
Definition: chap.h:154
error_t sshParseKexDhInit(SshConnection *connection, const uint8_t *message, size_t length)
Parse SSH_MSG_KEX_DH_INIT message.
Definition: ssh_kex_dh.c:322
error_t sshFormatKexDhReply(SshConnection *connection, uint8_t *p, size_t *length)
Format SSH_MSG_KEX_DH_REPLY message.
Definition: ssh_kex_dh.c:228
error_t sshVerifyServerHostKey(SshConnection *connection, const SshString *publicKeyAlgo, const SshBinaryString *hostKey)
Verify server's host key.
error_t sshVerifyExchangeHashSignature(SshConnection *connection, const SshBinaryString *serverHostKey, const SshBinaryString *signature)
Verify the signature on the exchange hash.
SSH transport layer protocol.
error_t sshUpdateExchangeHashRaw(SshConnection *connection, const void *data, size_t length)
Update exchange hash calculation (raw data)
uint8_t type
Definition: coap_common.h:176
SSH certificate verification.
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
size_t length
Definition: ssh_types.h:58
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
#define SSH_MAX_SHARED_SECRET_LEN
Definition: ssh.h:842
#define osStrlen(s)
Definition: os_port.h:168
error_t sshLoadDhModpGroup(DhParameters *params, const char_t *kexAlgo)
Load Diffie-Hellman parameters.
#define SSH_PACKET_HEADER_SIZE
Definition: ssh_packet.h:38
error_t sshSendPacket(SshConnection *connection, uint8_t *payload, size_t payloadLen)
Send SSH packet.
Definition: ssh_packet.c:57
bool_t sshIsCertPublicKeyAlgo(const SshString *publicKeyAlgo)
Test if the specified public key algorithm is using certificates.
error_t sshSendNewKeys(SshConnection *connection)
Send SSH_MSG_NEWKEYS message.
Definition: ssh_kex.c:194
size_t length
Definition: ssh_types.h:69
Key material generation.
error_t dhComputeSharedSecret(DhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute Diffie-Hellman shared secret.
Definition: dh.c:289
error_t sshConvertArrayToMpint(const uint8_t *value, size_t length, uint8_t *p, size_t *written)
Convert a binary string to mpint representation.
Definition: ssh_misc.c:1625
@ SSH_MSG_KEX_DH_INIT
Definition: ssh.h:950
#define SshContext
Definition: ssh.h:870
const char_t * value
Definition: ssh_types.h:57
#define SSH_MAX_MPINT_OVERHEAD
Definition: ssh.h:861
error_t
Error codes.
Definition: error.h:43
@ SSH_OPERATION_MODE_SERVER
Definition: ssh.h:893
@ SSH_OPERATION_MODE_CLIENT
Definition: ssh.h:892
error_t sshVerifyServerCertificate(SshConnection *connection, const SshString *publicKeyAlgo, const SshBinaryString *hostKey)
Verify server's certificate.
void dhFree(DhContext *context)
Release Diffie-Hellman context.
Definition: dh.c:71
error_t sshDigestClientDhPublicKey(SshConnection *connection)
Update exchange hash with client's ephemeral public key.
Definition: ssh_kex_dh.c:648
@ ERROR_INVALID_TYPE
Definition: error.h:115
error_t dhImportPeerPublicKey(DhContext *context, const uint8_t *input, size_t length, MpiFormat format)
Import peer's public key.
Definition: dh.c:218
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
@ SSH_CONN_STATE_SERVER_NEW_KEYS
Definition: ssh.h:1052
String.
Definition: ssh_types.h:56
SSH key exchange.
const uint8_t * value
Definition: ssh_types.h:68
error_t sshFormatMpint(const Mpi *value, uint8_t *p, size_t *written)
Format a multiple precision integer.
Definition: ssh_misc.c:1507
#define sshFreeMem(p)
Definition: ssh.h:729
error_t sshComputeDhSharedSecret(SshConnection *connection)
Diffie-Hellman shared secret calculation.
Definition: ssh_kex_dh.c:618
error_t sshParseKexDhMessage(SshConnection *connection, uint8_t type, const uint8_t *message, size_t length)
Parse Diffie-Hellman specific messages.
Definition: ssh_kex_dh.c:560
@ SSH_CONN_STATE_KEX_DH_INIT
Definition: ssh.h:1041
uint8_t n
Exchange hash calculation.
#define SshConnection
Definition: ssh.h:874
SSH helper functions.
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
error_t sshFormatHostKey(SshConnection *connection, uint8_t *p, size_t *written)
Format host key structure.
Definition: ssh_misc.c:864
@ SSH_CONN_STATE_KEX_DH_REPLY
Definition: ssh.h:1042
SSH packet encryption/decryption.
error_t sshUpdateExchangeHash(SshConnection *connection, const void *data, size_t length)
Update exchange hash calculation.
error_t sshParseBinaryString(const uint8_t *p, size_t length, SshBinaryString *string)
Parse a binary string.
Definition: ssh_misc.c:1204
error_t sshFormatKexDhInit(SshConnection *connection, uint8_t *p, size_t *length)
Format SSH_MSG_KEX_DH_INIT message.
Definition: ssh_kex_dh.c:185
#define sshAllocMem(size)
Definition: ssh.h:724
error_t sshSendKexDhReply(SshConnection *connection)
Send SSH_MSG_KEX_DH_REPLY message.
Definition: ssh_kex_dh.c:125
error_t dhGenerateKeyPair(DhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Diffie-Hellman key pair generation.
Definition: dh.c:119
#define PRIuSIZE
Secure Shell (SSH)
SSH algorithm negotiation.
void dhInit(DhContext *context)
Initialize Diffie-Hellman context.
Definition: dh.c:54
#define SSH_BUFFER_SIZE
Definition: ssh.h:866
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
@ ERROR_INVALID_KEY
Definition: error.h:106
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t sshParseKexDhReply(SshConnection *connection, const uint8_t *message, size_t length)
Parse SSH_MSG_KEX_DH_REPLY message.
Definition: ssh_kex_dh.c:403
#define TRACE_VERBOSE_ARRAY(p, a, n)
Definition: debug.h:140