ssh_key_material.c
Go to the documentation of this file.
1 /**
2  * @file ssh_key_material.c
3  * @brief Key material generation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2026 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.6.6
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_key_material.h"
37 #include "ssh/ssh_misc.h"
38 #include "kdf/ssh_kdf.h"
39 #include "debug.h"
40 
41 //Check SSH stack configuration
42 #if (SSH_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Initialize encryption engine
47  * @param[in] connection Pointer to the SSH connection
48  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
49  * be initialized
50  * @param[in] encAlgo Selected encryption algorithm (NULL-terminated string)
51  * @param[in] macAlgo Selected integrity algorithm (NULL-terminated string)
52  * @param[in] x A single character used to derive keys
53  * @return Error code
54  **/
55 
57  SshEncryptionEngine *encryptionEngine, const char_t *encAlgo,
58  const char_t *macAlgo, uint8_t x)
59 {
60  error_t error;
61 
62  //Select the relevant cipher algorithm
63  error = sshSelectCipherAlgo(encryptionEngine, encAlgo);
64  //Any error to report?
65  if(error)
66  return error;
67 
68  //Select the relevant hash algorithm
69  error = sshSelectHashAlgo(encryptionEngine, encAlgo, macAlgo);
70  //Any error to report?
71  if(error)
72  return error;
73 
74 #if (SSH_STREAM_CIPHER_SUPPORT == ENABLED)
75  //Stream cipher?
76  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM)
77  {
78  //Compute encryption key
79  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
80  connection->h, connection->hLen, connection->sessionId,
81  connection->sessionIdLen, x + 2, encryptionEngine->encKey,
82  encryptionEngine->encKeyLen);
83  //Any error to report?
84  if(error)
85  return error;
86 
87  //Compute integrity key
88  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
89  connection->h, connection->hLen, connection->sessionId,
90  connection->sessionIdLen, x + 4, encryptionEngine->macKey,
91  encryptionEngine->hashAlgo->digestSize);
92  //Any error to report?
93  if(error)
94  return error;
95 
96  //Initialize stream cipher context
97  error = encryptionEngine->cipherAlgo->init(&encryptionEngine->cipherContext,
98  encryptionEngine->encKey, encryptionEngine->encKeyLen);
99  //Any error to report?
100  if(error)
101  return error;
102 
103  //Improved RC4 mode?
104  if(sshCompareAlgo(encAlgo, "arcfour128") ||
105  sshCompareAlgo(encAlgo, "arcfour256"))
106  {
107  //Discard the first 1536 bytes of keystream so as to ensure that the
108  //cipher's internal state is thoroughly mixed (refer to RFC 4345,
109  //section 1)
110  encryptionEngine->cipherAlgo->encryptStream(
111  &encryptionEngine->cipherContext, NULL, NULL, 1536);
112  }
113 
114  //Initialize HMAC context
115  encryptionEngine->hmacContext = &connection->hmacContext;
116  }
117  else
118 #endif
119 #if (SSH_CBC_CIPHER_SUPPORT == ENABLED || SSH_CTR_CIPHER_SUPPORT == ENABLED)
120  //CBC or CTR block cipher?
121  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC ||
122  encryptionEngine->cipherMode == CIPHER_MODE_CTR)
123  {
124  //Compute initial IV
125  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
126  connection->h, connection->hLen, connection->sessionId,
127  connection->sessionIdLen, x, encryptionEngine->iv,
128  encryptionEngine->cipherAlgo->blockSize);
129  //Any error to report?
130  if(error)
131  return error;
132 
133  //Compute encryption key
134  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
135  connection->h, connection->hLen, connection->sessionId,
136  connection->sessionIdLen, x + 2, encryptionEngine->encKey,
137  encryptionEngine->encKeyLen);
138  //Any error to report?
139  if(error)
140  return error;
141 
142  //Compute integrity key
143  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
144  connection->h, connection->hLen, connection->sessionId,
145  connection->sessionIdLen, x + 4, encryptionEngine->macKey,
146  encryptionEngine->hashAlgo->digestSize);
147  //Any error to report?
148  if(error)
149  return error;
150 
151  //Initialize block cipher context
152  error = encryptionEngine->cipherAlgo->init(&encryptionEngine->cipherContext,
153  encryptionEngine->encKey, encryptionEngine->encKeyLen);
154  //Any error to report?
155  if(error)
156  return error;
157 
158  //Initialize HMAC context
159  encryptionEngine->hmacContext = &connection->hmacContext;
160  }
161  else
162 #endif
163 #if (SSH_GCM_CIPHER_SUPPORT == ENABLED || SSH_RFC5647_SUPPORT == ENABLED)
164  //GCM AEAD cipher?
165  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
166  {
167  //AES-GCM requires a 12-octet initial IV
168  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
169  connection->h, connection->hLen, connection->sessionId,
170  connection->sessionIdLen, x, encryptionEngine->iv, 12);
171  //Any error to report?
172  if(error)
173  return error;
174 
175  //AES-GCM requires a encryption key of either 16 or 32 octets
176  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
177  connection->h, connection->hLen, connection->sessionId,
178  connection->sessionIdLen, x + 2, encryptionEngine->encKey,
179  encryptionEngine->encKeyLen);
180  //Any error to report?
181  if(error)
182  return error;
183 
184  //Because an AEAD algorithm such as AES-GCM uses the encryption key to
185  //provide both confidentiality and data integrity, the integrity key is
186  //not used with AES-GCM (refer to RFC 5647, section 5.1)
187  error = encryptionEngine->cipherAlgo->init(&encryptionEngine->cipherContext,
188  encryptionEngine->encKey, encryptionEngine->encKeyLen);
189  //Any error to report?
190  if(error)
191  return error;
192 
193  //Initialize GCM context
194  error = gcmInit(&encryptionEngine->gcmContext, encryptionEngine->cipherAlgo,
195  &encryptionEngine->cipherContext);
196  //Any error to report?
197  if(error)
198  return error;
199  }
200  else
201 #endif
202 #if (SSH_CHACHA20_POLY1305_SUPPORT == ENABLED)
203  //ChaCha20Poly1305 AEAD cipher?
204  if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
205  {
206  //The cipher requires 512 bits of key material as output from the SSH
207  //key exchange. This forms two 256 bit keys (K_1 and K_2), used by two
208  //separate instances of ChaCha20
209  error = sshKdf(connection->hashAlgo, connection->k, connection->kLen,
210  connection->h, connection->hLen, connection->sessionId,
211  connection->sessionIdLen, x + 2, encryptionEngine->encKey,
212  encryptionEngine->encKeyLen);
213  //Any error to report?
214  if(error)
215  return error;
216  }
217  else
218 #endif
219  //Invalid cipher mode?
220  {
221  //The specified cipher mode is not supported
223  }
224 
225  //Successful processing
226  return NO_ERROR;
227 }
228 
229 
230 /**
231  * @brief Release encryption engine
232  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
233  **/
234 
236 {
237  //Valid cipher context?
238  if(encryptionEngine->cipherAlgo != NULL)
239  {
240  //Erase cipher context
241  encryptionEngine->cipherAlgo->deinit(&encryptionEngine->cipherContext);
242  }
243 
244 #if (SSH_GCM_CIPHER_SUPPORT == ENABLED || SSH_RFC5647_SUPPORT == ENABLED)
245  //Erase GCM context
246  osMemset(&encryptionEngine->gcmContext, 0, sizeof(GcmContext));
247 #endif
248 
249  //Reset encryption parameters
250  encryptionEngine->cipherMode = CIPHER_MODE_NULL;
251  encryptionEngine->cipherAlgo = NULL;
252  encryptionEngine->hashAlgo = NULL;
253  encryptionEngine->hmacContext = NULL;
254  encryptionEngine->macSize = 0;
255  encryptionEngine->etm = FALSE;
256 
257  //Erase IV
258  osMemset(encryptionEngine->iv, 0, SSH_MAX_CIPHER_BLOCK_SIZE);
259 
260  //Erase encryption key
261  osMemset(encryptionEngine->encKey, 0, SSH_MAX_ENC_KEY_SIZE);
262  encryptionEngine->encKeyLen = 0;
263 
264  //Erase integrity key
265  osMemset(encryptionEngine->macKey, 0, SSH_MAX_HASH_DIGEST_SIZE);
266 }
267 
268 
269 /**
270  * @brief Select the relevant cipher algorithm
271  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
272  * be initialized
273  * @param[in] encAlgo Encryption algorithm name
274  * @return Error code
275  **/
276 
278  const char_t *encAlgo)
279 {
280  error_t error;
281 
282  //Initialize status code
283  error = NO_ERROR;
284 
285 #if (SSH_RC4_SUPPORT == ENABLED && SSH_STREAM_CIPHER_SUPPORT == ENABLED)
286  //Legacy RC4 encryption algorithm?
287  if(sshCompareAlgo(encAlgo, "arcfour"))
288  {
289  //This cipher uses RC4 with a 128-bit key (refer to RFC 4253, section 6.3)
290  encryptionEngine->cipherMode = CIPHER_MODE_STREAM;
291  encryptionEngine->cipherAlgo = RC4_CIPHER_ALGO;
292  encryptionEngine->encKeyLen = 16;
293  }
294  else
295 #endif
296 #if (SSH_RC4_128_SUPPORT == ENABLED && SSH_STREAM_CIPHER_SUPPORT == ENABLED)
297  //RC4 with 128-bit key encryption algorithm?
298  if(sshCompareAlgo(encAlgo, "arcfour128"))
299  {
300  //This cipher uses RC4 with a 128-bit key (refer to RFC 4345, section 4)
301  encryptionEngine->cipherMode = CIPHER_MODE_STREAM;
302  encryptionEngine->cipherAlgo = RC4_CIPHER_ALGO;
303  encryptionEngine->encKeyLen = 16;
304  }
305  else
306 #endif
307 #if (SSH_RC4_256_SUPPORT == ENABLED && SSH_STREAM_CIPHER_SUPPORT == ENABLED)
308  //RC4 with 256-bit key encryption algorithm?
309  if(sshCompareAlgo(encAlgo, "arcfour256"))
310  {
311  //This cipher uses RC4 with a 256-bit key (refer to RFC 4345, section 4)
312  encryptionEngine->cipherMode = CIPHER_MODE_STREAM;
313  encryptionEngine->cipherAlgo = RC4_CIPHER_ALGO;
314  encryptionEngine->encKeyLen = 32;
315  }
316  else
317 #endif
318 #if (SSH_CAST128_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
319  //CAST-128-CBC encryption algorithm?
320  if(sshCompareAlgo(encAlgo, "cast128-cbc"))
321  {
322  //This cipher uses CAST-128 in CBC mode with a 128-bit key (refer to
323  //RFC 4253, section 6.3)
324  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
325  encryptionEngine->cipherAlgo = CAST128_CIPHER_ALGO;
326  encryptionEngine->encKeyLen = 16;
327  }
328  else
329 #endif
330 #if (SSH_CAST128_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
331  //CAST-128-CTR encryption algorithm?
332  if(sshCompareAlgo(encAlgo, "cast128-ctr"))
333  {
334  //This cipher uses CAST-128 in CTR mode with a 128-bit key (refer to
335  //RFC 4344, section 4)
336  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
337  encryptionEngine->cipherAlgo = CAST128_CIPHER_ALGO;
338  encryptionEngine->encKeyLen = 16;
339  }
340  else
341 #endif
342 #if (SSH_IDEA_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
343  //IDEA-CBC encryption algorithm?
344  if(sshCompareAlgo(encAlgo, "idea-cbc"))
345  {
346  //This cipher uses IDEA in CBC mode (refer to RFC 4253, section 6.3)
347  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
348  encryptionEngine->cipherAlgo = IDEA_CIPHER_ALGO;
349  encryptionEngine->encKeyLen = 16;
350  }
351  else
352 #endif
353 #if (SSH_IDEA_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
354  //IDEA-CTR encryption algorithm?
355  if(sshCompareAlgo(encAlgo, "idea-ctr"))
356  {
357  //This cipher uses IDEA in CTR mode (refer to RFC 4344, section 4)
358  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
359  encryptionEngine->cipherAlgo = IDEA_CIPHER_ALGO;
360  encryptionEngine->encKeyLen = 16;
361  }
362  else
363 #endif
364 #if (SSH_BLOWFISH_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
365  //Blowfish-CBC encryption algorithm?
366  if(sshCompareAlgo(encAlgo, "blowfish-cbc"))
367  {
368  //This cipher uses Blowfish in CBC mode with a 128-bit key (refer to
369  //RFC 4253, section 6.3)
370  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
371  encryptionEngine->cipherAlgo = BLOWFISH_CIPHER_ALGO;
372  encryptionEngine->encKeyLen = 16;
373  }
374  else
375 #endif
376 #if (SSH_BLOWFISH_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
377  //Blowfish-CTR encryption algorithm?
378  if(sshCompareAlgo(encAlgo, "blowfish-ctr"))
379  {
380  //This cipher uses Blowfish in CTR mode with a 256-bit key (refer to
381  //RFC 4344, section 4)
382  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
383  encryptionEngine->cipherAlgo = BLOWFISH_CIPHER_ALGO;
384  encryptionEngine->encKeyLen = 32;
385  }
386  else
387 #endif
388 #if (SSH_3DES_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
389  //3DES-CBC encryption algorithm?
390  if(sshCompareAlgo(encAlgo, "3des-cbc"))
391  {
392  //This cipher uses Triple DES EDE in CBC mode (refer to RFC 4253,
393  //section 6.3)
394  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
395  encryptionEngine->cipherAlgo = DES3_CIPHER_ALGO;
396  encryptionEngine->encKeyLen = 24;
397  }
398  else
399 #endif
400 #if (SSH_3DES_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
401  //3DES-CTR encryption algorithm?
402  if(sshCompareAlgo(encAlgo, "3des-ctr"))
403  {
404  //This cipher uses Triple DES EDE in CTR mode (refer to RFC 4344,
405  //section 4)
406  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
407  encryptionEngine->cipherAlgo = DES3_CIPHER_ALGO;
408  encryptionEngine->encKeyLen = 24;
409  }
410  else
411 #endif
412 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
413  //AES-CBC with 128-bit key encryption algorithm?
414  if(sshCompareAlgo(encAlgo, "aes128-cbc"))
415  {
416  //This cipher uses AES in CBC mode with a 128-bit key (refer to
417  //RFC 4253, section 6.3)
418  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
419  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
420  encryptionEngine->encKeyLen = 16;
421  }
422  else
423 #endif
424 #if (SSH_AES_192_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
425  //AES-CBC with 192-bit key encryption algorithm?
426  if(sshCompareAlgo(encAlgo, "aes192-cbc"))
427  {
428  //This cipher uses AES in CBC mode with a 192-bit key (refer to
429  //RFC 4253, section 6.3)
430  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
431  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
432  encryptionEngine->encKeyLen = 24;
433  }
434  else
435 #endif
436 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
437  //AES-CBC with 256-bit key encryption algorithm?
438  if(sshCompareAlgo(encAlgo, "aes256-cbc"))
439  {
440  //This cipher uses AES in CBC mode with a 256-bit key (refer to
441  //RFC 4253, section 6.3)
442  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
443  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
444  encryptionEngine->encKeyLen = 32;
445  }
446  else
447 #endif
448 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
449  //AES-CTR with 128-bit key encryption algorithm?
450  if(sshCompareAlgo(encAlgo, "aes128-ctr"))
451  {
452  //This cipher uses AES in CTR mode with a 128-bit key (refer to
453  //RFC 4344, section 4)
454  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
455  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
456  encryptionEngine->encKeyLen = 16;
457  }
458  else
459 #endif
460 #if (SSH_AES_192_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
461  //AES-CTR with 192-bit key encryption algorithm?
462  if(sshCompareAlgo(encAlgo, "aes192-ctr"))
463  {
464  //This cipher uses AES in CTR mode with a 192-bit key (refer to
465  //RFC 4344, section 4)
466  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
467  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
468  encryptionEngine->encKeyLen = 24;
469  }
470  else
471 #endif
472 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
473  //AES-CTR with 256-bit key encryption algorithm?
474  if(sshCompareAlgo(encAlgo, "aes256-ctr"))
475  {
476  //This cipher uses AES in CTR mode with a 256-bit key (refer to
477  //RFC 4344, section 4)
478  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
479  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
480  encryptionEngine->encKeyLen = 32;
481  }
482  else
483 #endif
484 #if (SSH_TWOFISH_128_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
485  //Twofish-CBC with 128-bit key encryption algorithm?
486  if(sshCompareAlgo(encAlgo, "twofish128-cbc"))
487  {
488  //This cipher uses Twofish in CBC mode with a 128-bit key
489  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
490  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
491  encryptionEngine->encKeyLen = 16;
492  }
493  else
494 #endif
495 #if (SSH_TWOFISH_192_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
496  //Twofish-CBC with 192-bit key encryption algorithm?
497  if(sshCompareAlgo(encAlgo, "twofish192-cbc"))
498  {
499  //This cipher uses Twofish in CBC mode with a 192-bit key
500  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
501  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
502  encryptionEngine->encKeyLen = 24;
503  }
504  else
505 #endif
506 #if (SSH_TWOFISH_256_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
507  //Twofish-CBC with 256-bit key encryption algorithm?
508  if(sshCompareAlgo(encAlgo, "twofish256-cbc") ||
509  sshCompareAlgo(encAlgo, "twofish-cbc"))
510  {
511  //This cipher uses Twofish in CBC mode with a 256-bit key
512  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
513  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
514  encryptionEngine->encKeyLen = 32;
515  }
516  else
517 #endif
518 #if (SSH_TWOFISH_128_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
519  //Twofish-CTR with 128-bit key encryption algorithm?
520  if(sshCompareAlgo(encAlgo, "twofish128-ctr"))
521  {
522  //This cipher uses Twofish in CTR mode with a 128-bit key
523  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
524  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
525  encryptionEngine->encKeyLen = 16;
526  }
527  else
528 #endif
529 #if (SSH_TWOFISH_192_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
530  //Twofish-CTR with 192-bit key encryption algorithm?
531  if(sshCompareAlgo(encAlgo, "twofish192-ctr"))
532  {
533  //This cipher uses Twofish in CTR mode with a 192-bit key
534  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
535  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
536  encryptionEngine->encKeyLen = 24;
537  }
538  else
539 #endif
540 #if (SSH_TWOFISH_256_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
541  //Twofish-CTR with 256-bit key encryption algorithm?
542  if(sshCompareAlgo(encAlgo, "twofish256-ctr"))
543  {
544  //This cipher uses Twofish in CTR mode with a 256-bit key
545  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
546  encryptionEngine->cipherAlgo = TWOFISH_CIPHER_ALGO;
547  encryptionEngine->encKeyLen = 32;
548  }
549  else
550 #endif
551 #if (SSH_SERPENT_128_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
552  //Serpent-CBC with 128-bit key encryption algorithm?
553  if(sshCompareAlgo(encAlgo, "serpent128-cbc"))
554  {
555  //This cipher uses Serpent in CBC mode with a 128-bit key
556  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
557  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
558  encryptionEngine->encKeyLen = 16;
559  }
560  else
561 #endif
562 #if (SSH_SERPENT_192_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
563  //Serpent-CBC with 192-bit key encryption algorithm?
564  if(sshCompareAlgo(encAlgo, "serpent192-cbc"))
565  {
566  //This cipher uses Serpent in CBC mode with a 192-bit key
567  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
568  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
569  encryptionEngine->encKeyLen = 24;
570  }
571  else
572 #endif
573 #if (SSH_SERPENT_256_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
574  //Serpent-CBC with 256-bit key encryption algorithm?
575  if(sshCompareAlgo(encAlgo, "serpent256-cbc"))
576  {
577  //This cipher uses Serpent in CBC mode with a 256-bit key
578  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
579  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
580  encryptionEngine->encKeyLen = 32;
581  }
582  else
583 #endif
584 #if (SSH_SERPENT_128_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
585  //Serpent-CTR with 128-bit key encryption algorithm?
586  if(sshCompareAlgo(encAlgo, "serpent128-ctr"))
587  {
588  //This cipher uses Serpent in CTR mode with a 128-bit key
589  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
590  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
591  encryptionEngine->encKeyLen = 16;
592  }
593  else
594 #endif
595 #if (SSH_SERPENT_192_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
596  //Serpent-CTR with 192-bit key encryption algorithm?
597  if(sshCompareAlgo(encAlgo, "serpent192-ctr"))
598  {
599  //This cipher uses Serpent in CTR mode with a 192-bit key
600  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
601  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
602  encryptionEngine->encKeyLen = 24;
603  }
604  else
605 #endif
606 #if (SSH_SERPENT_256_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
607  //Serpent-CTR with 256-bit key encryption algorithm?
608  if(sshCompareAlgo(encAlgo, "serpent256-ctr"))
609  {
610  //This cipher uses Serpent in CTR mode with a 256-bit key
611  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
612  encryptionEngine->cipherAlgo = SERPENT_CIPHER_ALGO;
613  encryptionEngine->encKeyLen = 32;
614  }
615  else
616 #endif
617 #if (SSH_CAMELLIA_128_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
618  //Camellia-CBC with 128-bit key encryption algorithm?
619  if(sshCompareAlgo(encAlgo, "camellia128-cbc"))
620  {
621  //This cipher uses Camellia in CBC mode with a 128-bit key
622  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
623  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
624  encryptionEngine->encKeyLen = 16;
625  }
626  else
627 #endif
628 #if (SSH_CAMELLIA_192_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
629  //Camellia-CBC with 192-bit key encryption algorithm?
630  if(sshCompareAlgo(encAlgo, "camellia192-cbc"))
631  {
632  //This cipher uses Camellia in CBC mode with a 192-bit key
633  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
634  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
635  encryptionEngine->encKeyLen = 24;
636  }
637  else
638 #endif
639 #if (SSH_CAMELLIA_256_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
640  //Camellia-CBC with 256-bit key encryption algorithm?
641  if(sshCompareAlgo(encAlgo, "camellia256-cbc"))
642  {
643  //This cipher uses Camellia in CBC mode with a 256-bit key
644  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
645  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
646  encryptionEngine->encKeyLen = 32;
647  }
648  else
649 #endif
650 #if (SSH_CAMELLIA_128_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
651  //Camellia-CTR with 128-bit key encryption algorithm?
652  if(sshCompareAlgo(encAlgo, "camellia128-ctr"))
653  {
654  //This cipher uses Camellia in CTR mode with a 128-bit key
655  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
656  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
657  encryptionEngine->encKeyLen = 16;
658  }
659  else
660 #endif
661 #if (SSH_CAMELLIA_192_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
662  //Camellia-CTR with 192-bit key encryption algorithm?
663  if(sshCompareAlgo(encAlgo, "camellia192-ctr"))
664  {
665  //This cipher uses Camellia in CTR mode with a 192-bit key
666  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
667  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
668  encryptionEngine->encKeyLen = 24;
669  }
670  else
671 #endif
672 #if (SSH_CAMELLIA_256_SUPPORT == ENABLED && SSH_CTR_CIPHER_SUPPORT == ENABLED)
673  //Camellia-CTR with 256-bit key encryption algorithm?
674  if(sshCompareAlgo(encAlgo, "camellia256-ctr"))
675  {
676  //This cipher uses Camellia in CTR mode with a 256-bit key
677  encryptionEngine->cipherMode = CIPHER_MODE_CTR;
678  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
679  encryptionEngine->encKeyLen = 32;
680  }
681  else
682 #endif
683 #if (SSH_SEED_SUPPORT == ENABLED && SSH_CBC_CIPHER_SUPPORT == ENABLED)
684  //SEED-CBC encryption algorithm?
685  if(sshCompareAlgo(encAlgo, "seed-cbc@ssh.com"))
686  {
687  //This cipher uses SEED in CBC mode
688  encryptionEngine->cipherMode = CIPHER_MODE_CBC;
689  encryptionEngine->cipherAlgo = SEED_CIPHER_ALGO;
690  encryptionEngine->encKeyLen = 16;
691  }
692  else
693 #endif
694 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_GCM_CIPHER_SUPPORT == ENABLED)
695  //AES-GCM with 128-bit key encryption algorithm?
696  if(sshCompareAlgo(encAlgo, "aes128-gcm") ||
697  sshCompareAlgo(encAlgo, "aes128-gcm@openssh.com"))
698  {
699  //AEAD algorithms offer both encryption and authentication
700  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
701  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
702  encryptionEngine->encKeyLen = 16;
703  }
704  else
705 #endif
706 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_GCM_CIPHER_SUPPORT == ENABLED)
707  //AES-GCM with 256-bit key encryption algorithm?
708  if(sshCompareAlgo(encAlgo, "aes256-gcm") ||
709  sshCompareAlgo(encAlgo, "aes256-gcm@openssh.com"))
710  {
711  //AEAD algorithms offer both encryption and authentication
712  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
713  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
714  encryptionEngine->encKeyLen = 32;
715  }
716  else
717 #endif
718 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
719  //AES-GCM with 128-bit key encryption algorithm?
720  if(sshCompareAlgo(encAlgo, "AEAD_AES_128_GCM"))
721  {
722  //AEAD algorithms offer both encryption and authentication
723  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
724  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
725  encryptionEngine->encKeyLen = 16;
726  }
727  else
728 #endif
729 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
730  //AES-GCM with 256-bit key encryption algorithm?
731  if(sshCompareAlgo(encAlgo, "AEAD_AES_256_GCM"))
732  {
733  //AEAD algorithms offer both encryption and authentication
734  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
735  encryptionEngine->cipherAlgo = AES_CIPHER_ALGO;
736  encryptionEngine->encKeyLen = 32;
737  }
738  else
739 #endif
740 #if (SSH_CAMELLIA_128_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
741  //Camellia-GCM with 128-bit key encryption algorithm?
742  if(sshCompareAlgo(encAlgo, "AEAD_CAMELLIA_128_GCM"))
743  {
744  //AEAD algorithms offer both encryption and authentication
745  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
746  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
747  encryptionEngine->encKeyLen = 16;
748  }
749  else
750 #endif
751 #if (SSH_CAMELLIA_256_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
752  //Camellia-GCM with 256-bit key encryption algorithm?
753  if(sshCompareAlgo(encAlgo, "AEAD_CAMELLIA_256_GCM"))
754  {
755  //AEAD algorithms offer both encryption and authentication
756  encryptionEngine->cipherMode = CIPHER_MODE_GCM;
757  encryptionEngine->cipherAlgo = CAMELLIA_CIPHER_ALGO;
758  encryptionEngine->encKeyLen = 32;
759  }
760  else
761 #endif
762 #if (SSH_CHACHA20_POLY1305_SUPPORT == ENABLED)
763  //ChaCha20Poly1305 encryption algorithm?
764  if(sshCompareAlgo(encAlgo, "chacha20-poly1305") ||
765  sshCompareAlgo(encAlgo, "chacha20-poly1305@openssh.com"))
766  {
767  //AEAD algorithms offer both encryption and authentication
768  encryptionEngine->cipherMode = CIPHER_MODE_CHACHA20_POLY1305;
769  encryptionEngine->cipherAlgo = NULL;
770  encryptionEngine->encKeyLen = 64;
771  }
772  else
773 #endif
774  //Unknown encryption algorithm?
775  {
776  //Report an error
778  }
779 
780  //Return status code
781  return error;
782 }
783 
784 
785 /**
786  * @brief Select the relevant hash algorithm
787  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
788  * be initialized
789  * @param[in] encAlgo Encryption algorithm name
790  * @param[in] macAlgo Integrity algorithm name
791  * @return Error code
792  **/
793 
795  const char_t *encAlgo, const char_t *macAlgo)
796 {
797  error_t error;
798 
799  //Initialize status code
800  error = NO_ERROR;
801 
802 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_GCM_CIPHER_SUPPORT == ENABLED)
803  //AES-GCM with 128-bit key authenticated encryption algorithm?
804  if(sshCompareAlgo(encAlgo, "aes128-gcm") ||
805  sshCompareAlgo(encAlgo, "aes128-gcm@openssh.com"))
806  {
807  //AEAD algorithms offer both encryption and authentication
808  encryptionEngine->hashAlgo = NULL;
809  encryptionEngine->macSize = 16;
810  encryptionEngine->etm = FALSE;
811  }
812  else
813 #endif
814 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_GCM_CIPHER_SUPPORT == ENABLED)
815  //AES-GCM with 256-bit key authenticated encryption algorithm?
816  if(sshCompareAlgo(encAlgo, "aes256-gcm") ||
817  sshCompareAlgo(encAlgo, "aes256-gcm@openssh.com"))
818  {
819  //AEAD algorithms offer both encryption and authentication
820  encryptionEngine->hashAlgo = NULL;
821  encryptionEngine->macSize = 16;
822  encryptionEngine->etm = FALSE;
823  }
824  else
825 #endif
826 #if (SSH_AES_128_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
827  //AES-GCM with 128-bit key authenticated encryption algorithm?
828  if(sshCompareAlgo(encAlgo, "AEAD_AES_128_GCM"))
829  {
830  //AEAD algorithms offer both encryption and authentication
831  encryptionEngine->hashAlgo = NULL;
832  encryptionEngine->macSize = 16;
833  encryptionEngine->etm = FALSE;
834  }
835  else
836 #endif
837 #if (SSH_AES_256_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
838  //AES-GCM with 256-bit key authenticated encryption algorithm?
839  if(sshCompareAlgo(encAlgo, "AEAD_AES_256_GCM"))
840  {
841  //AEAD algorithms offer both encryption and authentication
842  encryptionEngine->hashAlgo = NULL;
843  encryptionEngine->macSize = 16;
844  encryptionEngine->etm = FALSE;
845  }
846  else
847 #endif
848 #if (SSH_CAMELLIA_128_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
849  //Camellia-GCM with 128-bit key authenticated encryption algorithm?
850  if(sshCompareAlgo(encAlgo, "AEAD_CAMELLIA_128_GCM"))
851  {
852  //AEAD algorithms offer both encryption and authentication
853  encryptionEngine->hashAlgo = NULL;
854  encryptionEngine->macSize = 16;
855  encryptionEngine->etm = FALSE;
856  }
857  else
858 #endif
859 #if (SSH_CAMELLIA_256_SUPPORT == ENABLED && SSH_RFC5647_SUPPORT == ENABLED)
860  //Camellia-GCM with 256-bit key authenticated encryption algorithm?
861  if(sshCompareAlgo(encAlgo, "AEAD_CAMELLIA_256_GCM"))
862  {
863  //AEAD algorithms offer both encryption and authentication
864  encryptionEngine->hashAlgo = NULL;
865  encryptionEngine->macSize = 16;
866  encryptionEngine->etm = FALSE;
867  }
868  else
869 #endif
870 #if (SSH_CHACHA20_POLY1305_SUPPORT == ENABLED)
871  //ChaCha20Poly1305 authenticated encryption algorithm?
872  if(sshCompareAlgo(encAlgo, "chacha20-poly1305") ||
873  sshCompareAlgo(encAlgo, "chacha20-poly1305@openssh.com"))
874  {
875  //AEAD algorithms offer both encryption and authentication
876  encryptionEngine->hashAlgo = NULL;
877  encryptionEngine->macSize = 16;
878  encryptionEngine->etm = FALSE;
879  }
880  else
881 #endif
882 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_MD5_SUPPORT == ENABLED)
883  //HMAC with MD5 integrity algorithm?
884  if(sshCompareAlgo(macAlgo, "hmac-md5"))
885  {
886  //Select MAC-then-encrypt mode
887  encryptionEngine->hashAlgo = MD5_HASH_ALGO;
888  encryptionEngine->macSize = MD5_DIGEST_SIZE;
889  encryptionEngine->etm = FALSE;
890  }
891  else
892 #endif
893 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_MD5_SUPPORT == ENABLED && \
894  SSH_ETM_SUPPORT == ENABLED)
895  //HMAC with MD5 integrity algorithm (EtM mode)?
896  if(sshCompareAlgo(macAlgo, "hmac-md5-etm@openssh.com"))
897  {
898  //Select encrypt-then-MAC mode
899  encryptionEngine->hashAlgo = MD5_HASH_ALGO;
900  encryptionEngine->macSize = MD5_DIGEST_SIZE;
901  encryptionEngine->etm = TRUE;
902  }
903  else
904 #endif
905 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_MD5_96_SUPPORT == ENABLED)
906  //HMAC with MD5/96 integrity algorithm?
907  if(sshCompareAlgo(macAlgo, "hmac-md5-96"))
908  {
909  //Select MAC-then-encrypt mode
910  encryptionEngine->hashAlgo = MD5_HASH_ALGO;
911  encryptionEngine->macSize = 12;
912  encryptionEngine->etm = FALSE;
913  }
914  else
915 #endif
916 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_MD5_96_SUPPORT == ENABLED && \
917  SSH_ETM_SUPPORT == ENABLED)
918  //HMAC with MD5/96 integrity algorithm (EtM mode)?
919  if(sshCompareAlgo(macAlgo, "hmac-md5-96-etm@openssh.com"))
920  {
921  //Select encrypt-then-MAC mode
922  encryptionEngine->hashAlgo = MD5_HASH_ALGO;
923  encryptionEngine->macSize = 12;
924  encryptionEngine->etm = TRUE;
925  }
926  else
927 #endif
928 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_RIPEMD160_SUPPORT == ENABLED)
929  //HMAC with RIPEMD-160 integrity algorithm?
930  if(sshCompareAlgo(macAlgo, "hmac-ripemd160") ||
931  sshCompareAlgo(macAlgo, "hmac-ripemd160@openssh.com"))
932  {
933  //Select MAC-then-encrypt mode
934  encryptionEngine->hashAlgo = RIPEMD160_HASH_ALGO;
935  encryptionEngine->macSize = RIPEMD160_DIGEST_SIZE;
936  encryptionEngine->etm = FALSE;
937  }
938  else
939 #endif
940 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_RIPEMD160_SUPPORT == ENABLED && \
941  SSH_ETM_SUPPORT == ENABLED)
942  //HMAC with RIPEMD-160 integrity algorithm (EtM mode)?
943  if(sshCompareAlgo(macAlgo, "hmac-ripemd160-etm@openssh.com"))
944  {
945  //Select encrypt-then-MAC mode
946  encryptionEngine->hashAlgo = RIPEMD160_HASH_ALGO;
947  encryptionEngine->macSize = RIPEMD160_DIGEST_SIZE;
948  encryptionEngine->etm = TRUE;
949  }
950  else
951 #endif
952 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA1_SUPPORT == ENABLED)
953  //HMAC with SHA-1 integrity algorithm?
954  if(sshCompareAlgo(macAlgo, "hmac-sha1"))
955  {
956  //Select MAC-then-encrypt mode
957  encryptionEngine->hashAlgo = SHA1_HASH_ALGO;
958  encryptionEngine->macSize = SHA1_DIGEST_SIZE;
959  encryptionEngine->etm = FALSE;
960  }
961  else
962 #endif
963 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA1_SUPPORT == ENABLED && \
964  SSH_ETM_SUPPORT == ENABLED)
965  //HMAC with SHA-1 integrity algorithm (EtM mode)?
966  if(sshCompareAlgo(macAlgo, "hmac-sha1-etm@openssh.com"))
967  {
968  //Select encrypt-then-MAC mode
969  encryptionEngine->hashAlgo = SHA1_HASH_ALGO;
970  encryptionEngine->macSize = SHA1_DIGEST_SIZE;
971  encryptionEngine->etm = TRUE;
972  }
973  else
974 #endif
975 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA1_96_SUPPORT == ENABLED)
976  //HMAC with SHA-1/96 integrity algorithm?
977  if(sshCompareAlgo(macAlgo, "hmac-sha1-96"))
978  {
979  //Select MAC-then-encrypt mode
980  encryptionEngine->hashAlgo = SHA1_HASH_ALGO;
981  encryptionEngine->macSize = 12;
982  encryptionEngine->etm = FALSE;
983  }
984  else
985 #endif
986 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA1_96_SUPPORT == ENABLED && \
987  SSH_ETM_SUPPORT == ENABLED)
988  //HMAC with SHA-1/96 integrity algorithm (EtM mode)?
989  if(sshCompareAlgo(macAlgo, "hmac-sha1-96-etm@openssh.com"))
990  {
991  //Select encrypt-then-MAC mode
992  encryptionEngine->hashAlgo = SHA1_HASH_ALGO;
993  encryptionEngine->macSize = 12;
994  encryptionEngine->etm = TRUE;
995  }
996  else
997 #endif
998 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA256_SUPPORT == ENABLED)
999  //HMAC with SHA-256 integrity algorithm?
1000  if(sshCompareAlgo(macAlgo, "hmac-sha2-256"))
1001  {
1002  //Select MAC-then-encrypt mode
1003  encryptionEngine->hashAlgo = SHA256_HASH_ALGO;
1004  encryptionEngine->macSize = SHA256_DIGEST_SIZE;
1005  encryptionEngine->etm = FALSE;
1006  }
1007  else
1008 #endif
1009 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA256_SUPPORT == ENABLED && \
1010  SSH_ETM_SUPPORT == ENABLED)
1011  //HMAC with SHA-256 integrity algorithm (EtM mode)?
1012  if(sshCompareAlgo(macAlgo, "hmac-sha2-256-etm@openssh.com"))
1013  {
1014  //Select encrypt-then-MAC mode
1015  encryptionEngine->hashAlgo = SHA256_HASH_ALGO;
1016  encryptionEngine->macSize = SHA256_DIGEST_SIZE;
1017  encryptionEngine->etm = TRUE;
1018  }
1019  else
1020 #endif
1021 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA512_SUPPORT == ENABLED)
1022  //HMAC with SHA-512 integrity algorithm?
1023  if(sshCompareAlgo(macAlgo, "hmac-sha2-512"))
1024  {
1025  //Select MAC-then-encrypt mode
1026  encryptionEngine->hashAlgo = SHA512_HASH_ALGO;
1027  encryptionEngine->macSize = SHA512_DIGEST_SIZE;
1028  encryptionEngine->etm = FALSE;
1029  }
1030  else
1031 #endif
1032 #if (SSH_HMAC_SUPPORT == ENABLED && SSH_SHA512_SUPPORT == ENABLED && \
1033  SSH_ETM_SUPPORT == ENABLED)
1034  //HMAC with SHA-512 integrity algorithm (EtM mode)?
1035  if(sshCompareAlgo(macAlgo, "hmac-sha2-512-etm@openssh.com"))
1036  {
1037  //Select encrypt-then-MAC mode
1038  encryptionEngine->hashAlgo = SHA512_HASH_ALGO;
1039  encryptionEngine->macSize = SHA512_DIGEST_SIZE;
1040  encryptionEngine->etm = TRUE;
1041  }
1042  else
1043 #endif
1044  //Unknown integrity algorithm?
1045  {
1046  //Report an error
1048  }
1049 
1050  //Return status code
1051  return error;
1052 }
1053 
1054 
1055 /**
1056  * @brief Dump secret key (for debugging purpose only)
1057  * @param[in] connection Pointer to the SSH connection
1058  * @param[in] label Identifying label (NULL-terminated string)
1059  * @param[in] key Pointer to the secret key
1060  * @param[in] keyLen Length of the secret key, in bytes
1061  **/
1062 
1063 void sshDumpKey(SshConnection *connection, const char_t *label,
1064  const uint8_t *key, size_t keyLen)
1065 {
1066 #if (SSH_KEY_LOG_SUPPORT == ENABLED)
1067  SshContext *context;
1068 
1069  //Point to the SSH context
1070  context = connection->context;
1071 
1072  //Any registered callback?
1073  if(context->keyLogCallback != NULL)
1074  {
1075  size_t i;
1076  size_t n;
1077  char_t *buffer;
1078 
1079  //Allocate a buffer to hold the formatted string
1080  buffer = sshAllocMem(2 * SSH_COOKIE_SIZE + 2 * keyLen +
1081  osStrlen(label) + 3);
1082 
1083  //Successful memory allocation?
1084  if(buffer != NULL)
1085  {
1086  //Convert the cookie to a hex string
1087  for(i = 0, n = 0; i < SSH_COOKIE_SIZE; i++)
1088  {
1089  //Format current byte
1090  n += osSprintf(buffer + n, "%02" PRIX8, connection->cookie[i]);
1091  }
1092 
1093  //The middle part is a static label indicating the type of key material
1094  //that follows
1095  n += osSprintf(buffer + n, " %s ", label);
1096 
1097  //Convert the shared secret to a hex string
1098  for(i = 0; i < keyLen; i++)
1099  {
1100  //Format current byte
1101  n += osSprintf(buffer + n, "%02" PRIX8, key[i]);
1102  }
1103 
1104  //Properly terminate the string with a NULL character
1105  buffer[n] = '\0';
1106 
1107  //Invoke user callback function
1108  context->keyLogCallback(connection, buffer);
1109 
1110  //Release previously allocated memory
1111  sshFreeMem(buffer);
1112  }
1113  }
1114 #endif
1115 }
1116 
1117 #endif
error_t sshKdf(const HashAlgo *hashAlgo, const uint8_t *k, size_t kLen, const uint8_t *h, size_t hLen, const uint8_t *sessionId, size_t sessionIdLen, uint8_t x, uint8_t *output, size_t outputLen)
SSH key derivation function.
Definition: ssh_kdf.c:58
@ CIPHER_MODE_CBC
Definition: cipher_modes.h:82
#define TWOFISH_CIPHER_ALGO
Definition: twofish.h:40
#define SHA256_HASH_ALGO
Definition: sha256.h:49
#define SHA1_HASH_ALGO
Definition: sha1.h:49
#define SHA512_HASH_ALGO
Definition: sha512.h:49
void sshFreeEncryptionEngine(SshEncryptionEngine *encryptionEngine)
Release encryption engine.
uint8_t macKey[SSH_MAX_HASH_DIGEST_SIZE]
Integrity key.
Definition: ssh.h:1392
#define BLOWFISH_CIPHER_ALGO
Definition: blowfish.h:40
uint8_t iv[SSH_MAX_CIPHER_BLOCK_SIZE]
Initialization vector.
Definition: ssh.h:1389
void sshDumpKey(SshConnection *connection, const char_t *label, const uint8_t *key, size_t keyLen)
Dump secret key (for debugging purpose only)
uint8_t x
Definition: lldp_ext_med.h:211
const HashAlgo * hashAlgo
Hash algorithm for MAC operations.
Definition: ssh.h:1385
#define TRUE
Definition: os_port.h:50
size_t digestSize
Definition: crypto.h:1249
GcmContext gcmContext
GCM context.
Definition: ssh.h:1395
@ CIPHER_MODE_CTR
Definition: cipher_modes.h:85
size_t macSize
Size of the MAC tag, in bytes.
Definition: ssh.h:1387
#define IDEA_CIPHER_ALGO
Definition: idea.h:40
size_t blockSize
Definition: crypto.h:1289
@ CIPHER_MODE_NULL
Definition: cipher_modes.h:79
__weak_func error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
Definition: gcm.c:99
#define osStrlen(s)
Definition: os_port.h:171
#define SERPENT_CIPHER_ALGO
Definition: serpent.h:40
@ CIPHER_MODE_STREAM
Definition: cipher_modes.h:80
Encryption engine.
Definition: ssh.h:1381
#define SSH_MAX_CIPHER_BLOCK_SIZE
Definition: ssh.h:783
CipherAlgoInit init
Definition: crypto.h:1290
CipherAlgoEncryptStream encryptStream
Definition: crypto.h:1291
@ ERROR_UNSUPPORTED_CIPHER_MODE
Definition: error.h:128
Key material generation.
#define FALSE
Definition: os_port.h:46
@ ERROR_UNSUPPORTED_HASH_ALGO
Definition: error.h:130
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: cipher_modes.h:91
#define SshContext
Definition: ssh.h:931
error_t
Error codes.
Definition: error.h:43
CipherMode cipherMode
Cipher mode of operation.
Definition: ssh.h:1382
#define osSprintf(dest,...)
Definition: os_port.h:237
#define SEED_CIPHER_ALGO
Definition: seed.h:40
bool_t sshCompareAlgo(const char_t *name1, const char_t *name2)
Compare algorithm names.
Definition: ssh_misc.c:1758
#define RIPEMD160_DIGEST_SIZE
Definition: ripemd160.h:40
@ CIPHER_MODE_GCM
Definition: cipher_modes.h:87
#define MD5_HASH_ALGO
Definition: md5.h:49
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: ssh.h:1383
uint8_t encKey[SSH_MAX_ENC_KEY_SIZE]
Encryption key.
Definition: ssh.h:1390
#define RC4_CIPHER_ALGO
Definition: rc4.h:38
bool_t etm
Encrypt-then-MAC.
Definition: ssh.h:1388
error_t sshInitEncryptionEngine(SshConnection *connection, SshEncryptionEngine *encryptionEngine, const char_t *encAlgo, const char_t *macAlgo, uint8_t x)
Initialize encryption engine.
CipherContext cipherContext
Cipher context.
Definition: ssh.h:1384
#define CAMELLIA_CIPHER_ALGO
Definition: camellia.h:40
error_t sshSelectCipherAlgo(SshEncryptionEngine *encryptionEngine, const char_t *encAlgo)
Select the relevant cipher algorithm.
#define MD5_DIGEST_SIZE
Definition: md5.h:45
#define RIPEMD160_HASH_ALGO
Definition: ripemd160.h:44
#define SSH_MAX_HASH_DIGEST_SIZE
Definition: ssh.h:820
error_t sshSelectHashAlgo(SshEncryptionEngine *encryptionEngine, const char_t *encAlgo, const char_t *macAlgo)
Select the relevant hash algorithm.
char char_t
Definition: compiler_port.h:55
GCM context.
Definition: gcm.h:64
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define sshFreeMem(p)
Definition: ssh.h:760
#define SSH_MAX_ENC_KEY_SIZE
Definition: ssh.h:776
@ ERROR_UNSUPPORTED_CIPHER_ALGO
Definition: error.h:129
uint8_t n
#define SshConnection
Definition: ssh.h:935
CipherAlgoDeinit deinit
Definition: crypto.h:1295
SSH helper functions.
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define CAST128_CIPHER_ALGO
Definition: cast128.h:40
HmacContext * hmacContext
HMAC context.
Definition: ssh.h:1386
#define sshAllocMem(size)
Definition: ssh.h:755
#define DES3_CIPHER_ALGO
Definition: des3.h:46
SSH key derivation function.
#define SSH_COOKIE_SIZE
Definition: ssh.h:920
#define osMemset(p, value, length)
Definition: os_port.h:141
Secure Shell (SSH)
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
size_t encKeyLen
Length of the encryption key, in bytes.
Definition: ssh.h:1391