forked from wolfSSL/wolfssh
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinternal.h
More file actions
1530 lines (1372 loc) · 45.6 KB
/
internal.h
File metadata and controls
1530 lines (1372 loc) · 45.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* internal.h
*
* Copyright (C) 2014-2026 wolfSSL Inc.
*
* This file is part of wolfSSH.
*
* wolfSSH is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* The internal module contains the private data and functions. The public
* API calls into this module to do the work of processing the connections.
*/
#ifndef _WOLFSSH_INTERNAL_H_
#define _WOLFSSH_INTERNAL_H_
#include <wolfssh/ssh.h>
#include <wolfssh/wolfsftp.h>
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/dh.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#ifdef WOLFSSH_SCP
#include <wolfssh/wolfscp.h>
#endif
#ifdef WOLFSSH_AGENT
#include <wolfssh/agent.h>
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_CERTS
#include <wolfssh/certman.h>
#endif /* WOLFSSH_CERTS */
#ifdef WOLFSSH_TPM
#include <wolftpm/tpm2_wrap.h>
#endif /* WOLFSSH_TPM */
#if !defined (ALIGN16)
#if defined (__GNUC__)
#define ALIGN16 __attribute__ ( (aligned (16)))
#elif defined(_MSC_VER)
/* disable align warning, we want alignment ! */
#pragma warning(disable: 4324)
#define ALIGN16 __declspec (align (16))
#else
#define ALIGN16
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Check options set by wolfSSL and set wolfSSH options as appropriate. If
* the derived options and any override options leave wolfSSH without
* at least one algorithm to use, throw an error.
*/
#if defined(NO_WOLFSSH_SERVER) && defined(NO_WOLFSSH_CLIENT)
#error "Both NO_WOLFSSH_SERVER and NO_WOLFSSH_CLIENT are defined. Omit one of --disable-server or --disable-client."
#endif
#ifdef NO_RSA
#undef WOLFSSH_NO_RSA
#define WOLFSSH_NO_RSA
#endif
#ifndef HAVE_ECC
#undef WOLFSSH_NO_ECDSA
#define WOLFSSH_NO_ECDSA
#undef WOLFSSH_NO_ECDH
#define WOLFSSH_NO_ECDH
#endif
#ifdef NO_DH
#undef WOLFSSH_NO_DH
#define WOLFSSH_NO_DH
#endif
#ifdef NO_SHA
#undef WOLFSSH_NO_SHA1
#define WOLFSSH_NO_SHA1
#endif
#if !defined(HAVE_ED25519) \
|| !defined(WOLFSSL_ED25519_STREAMING_VERIFY) \
|| !defined(HAVE_ED25519_KEY_IMPORT) \
|| !defined(HAVE_ED25519_KEY_EXPORT)
#undef WOLFSSH_NO_ED25519
#define WOLFSSH_NO_ED25519
#endif
#if defined(NO_HMAC) || defined(WOLFSSH_NO_SHA1)
#undef WOLFSSH_NO_HMAC_SHA1
#define WOLFSSH_NO_HMAC_SHA1
#endif
#if defined(NO_HMAC) || defined(WOLFSSH_NO_SHA1)
#undef WOLFSSH_NO_HMAC_SHA1_96
#define WOLFSSH_NO_HMAC_SHA1_96
#endif
#if defined(NO_HMAC) || defined(NO_SHA256)
#undef WOLFSSH_NO_HMAC_SHA2_256
#define WOLFSSH_NO_HMAC_SHA2_256
#endif
#if defined(NO_HMAC) || defined(NO_SHA512)
#undef WOLFSSH_NO_HMAC_SHA2_512
#define WOLFSSH_NO_HMAC_SHA2_512
#endif
#if defined(WOLFSSH_NO_HMAC_SHA1) && \
defined(WOLFSSH_NO_HMAC_SHA1_96) && \
defined(WOLFSSH_NO_HMAC_SHA2_256) && \
defined(WOLFSSH_NO_HMAC_SHA2_512)
#error "You need at least one MAC algorithm."
#endif
#if defined(WOLFSSH_NO_DH) || defined(WOLFSSH_NO_SHA1)
#undef WOLFSSH_NO_DH_GROUP1_SHA1
#define WOLFSSH_NO_DH_GROUP1_SHA1
#endif
#if defined(WOLFSSH_NO_DH) || defined(WOLFSSH_NO_SHA1)
#undef WOLFSSH_NO_DH_GROUP14_SHA1
#define WOLFSSH_NO_DH_GROUP14_SHA1
#endif
#if defined(WOLFSSH_NO_DH) || defined(WOLFSSH_NO_SHA256)
#undef WOLFSSH_NO_DH_GROUP14_SHA256
#define WOLFSSH_NO_DH_GROUP14_SHA256
#endif
#if defined(WOLFSSH_NO_DH) || defined(WOLFSSH_NO_SHA512)
#undef WOLFSSH_NO_DH_GROUP16_SHA512
#define WOLFSSH_NO_DH_GROUP16_SHA512
#endif
#if defined(WOLFSSH_NO_DH) || defined(NO_SHA256)
#undef WOLFSSH_NO_DH_GEX_SHA256
#define WOLFSSH_NO_DH_GEX_SHA256
#endif
#if defined(WOLFSSH_NO_ECDH) \
|| defined(NO_SHA256) || defined(NO_ECC256)
#undef WOLFSSH_NO_ECDH_SHA2_NISTP256
#define WOLFSSH_NO_ECDH_SHA2_NISTP256
#endif
#if defined(WOLFSSH_NO_ECDH) \
|| !defined(WOLFSSL_SHA384) || \
(!defined(HAVE_ECC384) && !defined(HAVE_ALL_CURVES))
#undef WOLFSSH_NO_ECDH_SHA2_NISTP384
#define WOLFSSH_NO_ECDH_SHA2_NISTP384
#endif
#if defined(WOLFSSH_NO_ECDH) \
|| !defined(WOLFSSL_SHA512) || \
(!defined(HAVE_ECC521) && !defined(HAVE_ALL_CURVES))
#undef WOLFSSH_NO_ECDH_SHA2_NISTP521
#define WOLFSSH_NO_ECDH_SHA2_NISTP521
#endif
#if !defined(WOLFSSL_HAVE_MLKEM) || defined(NO_SHA256) \
|| defined(WOLFSSH_NO_ECDH_SHA2_NISTP256)
#undef WOLFSSH_NO_NISTP256_MLKEM768_SHA256
#define WOLFSSH_NO_NISTP256_MLKEM768_SHA256
#endif
#if !defined(WOLFSSL_HAVE_MLKEM) || !defined(WOLFSSL_SHA384) \
|| defined(WOLFSSH_NO_ECDH_SHA2_NISTP384)
#undef WOLFSSH_NO_NISTP384_MLKEM1024_SHA384
#define WOLFSSH_NO_NISTP384_MLKEM1024_SHA384
#endif
#if !defined(WOLFSSL_HAVE_MLKEM) || defined(NO_SHA256) \
|| !defined(HAVE_CURVE25519)
#undef WOLFSSH_NO_CURVE25519_MLKEM768_SHA256
#define WOLFSSH_NO_CURVE25519_MLKEM768_SHA256
#endif
#if !defined(HAVE_CURVE25519) || defined(NO_SHA256)
#undef WOLFSSH_NO_CURVE25519_SHA256
#define WOLFSSH_NO_CURVE25519_SHA256
#endif
#if defined(WOLFSSH_NO_DH_GROUP1_SHA1) && \
defined(WOLFSSH_NO_DH_GROUP14_SHA1) && \
defined(WOLFSSH_NO_DH_GROUP14_SHA256) && \
defined(WOLFSSH_NO_DH_GROUP16_SHA512) && \
defined(WOLFSSH_NO_DH_GEX_SHA256) && \
defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && \
defined(WOLFSSH_NO_ECDH_SHA2_NISTP384) && \
defined(WOLFSSH_NO_ECDH_SHA2_NISTP521) && \
defined(WOLFSSH_NO_NISTP256_MLKEM768_SHA256) && \
defined(WOLFSSH_NO_NISTP384_MLKEM1024_SHA384) && \
defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256) && \
defined(WOLFSSH_NO_CURVE25519_SHA256)
#error "You need at least one key agreement algorithm."
#endif
#if defined(WOLFSSH_NO_DH_GROUP1_SHA1) && \
defined(WOLFSSH_NO_DH_GROUP14_SHA1) && \
defined(WOLFSSH_NO_DH_GROUP14_SHA256) && \
defined(WOLFSSH_NO_DH_GROUP16_SHA512) && \
defined(WOLFSSH_NO_DH_GEX_SHA256)
#undef WOLFSSH_NO_DH
#define WOLFSSH_NO_DH
#endif
#if defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && \
defined(WOLFSSH_NO_ECDH_SHA2_NISTP384) && \
defined(WOLFSSH_NO_ECDH_SHA2_NISTP521)
#undef WOLFSSH_NO_ECDH
#define WOLFSSH_NO_ECDH
#endif
#if defined(WOLFSSH_NO_RSA) || defined(WOLFSSH_NO_SHA1)
#undef WOLFSSH_NO_SSH_RSA_SHA1
#define WOLFSSH_NO_SSH_RSA_SHA1
#endif
#if defined(WOLFSSH_NO_RSA) || defined(NO_SHA256)
#undef WOLFSSH_NO_RSA_SHA2_256
#define WOLFSSH_NO_RSA_SHA2_256
#endif
#if defined(WOLFSSH_NO_RSA) || !defined(WOLFSSL_SHA512)
#undef WOLFSSH_NO_RSA_SHA2_512
#define WOLFSSH_NO_RSA_SHA2_512
#endif
#if defined(WOLFSSH_NO_ECDSA) || \
defined(NO_SHA256) || defined(NO_ECC256)
#undef WOLFSSH_NO_ECDSA_SHA2_NISTP256
#define WOLFSSH_NO_ECDSA_SHA2_NISTP256
#endif
#if defined(WOLFSSH_NO_ECDSA) || \
!defined(WOLFSSL_SHA384) || \
(!defined(HAVE_ECC384) && !defined(HAVE_ALL_CURVES))
#undef WOLFSSH_NO_ECDSA_SHA2_NISTP384
#define WOLFSSH_NO_ECDSA_SHA2_NISTP384
#endif
#if defined(WOLFSSH_NO_ECDSA) || \
!defined(WOLFSSL_SHA512) || \
(!defined(HAVE_ECC521) && !defined(HAVE_ALL_CURVES))
#undef WOLFSSH_NO_ECDSA_SHA2_NISTP521
#define WOLFSSH_NO_ECDSA_SHA2_NISTP521
#endif
#if defined(WOLFSSH_NO_SSH_RSA_SHA1) && \
defined(WOLFSSH_NO_RSA_SHA2_256) && \
defined(WOLFSSH_NO_RSA_SHA2_512) && \
defined(WOLFSSH_NO_ECDSA_SHA2_NISTP256) && \
defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && \
defined(WOLFSSH_NO_ECDSA_SHA2_NISTP521) && \
defined(WOLFSSH_NO_ED25519)
#error "You need at least one signing algorithm."
#endif
#if defined(WOLFSSH_NO_SSH_RSA_SHA1) && \
defined(WOLFSSH_NO_RSA_SHA2_256) && \
defined(WOLFSSH_NO_RSA_SHA2_512)
#undef WOLFSSH_NO_RSA
#define WOLFSSH_NO_RSA
#endif
#if defined(WOLFSSH_NO_ECDSA_SHA2_NISTP256) && \
defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && \
defined(WOLFSSH_NO_ECDSA_SHA2_NISTP521)
#undef WOLFSSH_NO_ECDSA
#define WOLFSSH_NO_ECDSA
#endif
#ifdef WOLFSSH_NO_AEAD
#undef WOLFSSH_NO_AES_GCM
#define WOLFSSH_NO_AES_GCM
#endif
#if defined(NO_AES) || !defined(HAVE_AES_CBC)
#undef WOLFSSH_NO_AES_CBC
#define WOLFSSH_NO_AES_CBC
#endif
#if defined(NO_AES) || !defined(WOLFSSL_AES_COUNTER)
#undef WOLFSSH_NO_AES_CTR
#define WOLFSSH_NO_AES_CTR
#endif
#if defined(NO_AES) || !defined(HAVE_AESGCM)
#undef WOLFSSH_NO_AES_GCM
#define WOLFSSH_NO_AES_GCM
#endif
#if defined(WOLFSSH_NO_AES_CBC) && \
defined(WOLFSSH_NO_AES_CTR) && \
defined(WOLFSSH_NO_AES_GCM)
#error "You need at least one encryption algorithm."
#endif
#if defined(WOLFSSH_NO_AES_GCM)
#undef WOLFSSH_NO_AEAD
#define WOLFSSH_NO_AEAD
#endif
/* FPKI support turned off if wolfSSL linking to is not compiled with FPKI */
#if !defined(WOLFSSL_FPKI)
#undef WOLFSSH_NO_FPKI
#define WOLFSSH_NO_FPKI
#endif
WOLFSSH_LOCAL const char* GetErrorString(int);
enum {
/* Any of the items can be none. */
ID_NONE,
/* Encryption IDs */
ID_AES128_CBC,
ID_AES192_CBC,
ID_AES256_CBC,
ID_AES128_CTR,
ID_AES192_CTR,
ID_AES256_CTR,
ID_AES128_GCM,
ID_AES192_GCM,
ID_AES256_GCM,
/* Integrity IDs */
ID_HMAC_SHA1,
ID_HMAC_SHA1_96,
ID_HMAC_SHA2_256,
ID_HMAC_SHA2_512,
/* Key Exchange IDs */
ID_DH_GROUP1_SHA1,
ID_DH_GROUP14_SHA1,
ID_DH_GROUP14_SHA256,
ID_DH_GROUP16_SHA512,
ID_DH_GEX_SHA256,
ID_ECDH_SHA2_NISTP256,
ID_ECDH_SHA2_NISTP384,
ID_ECDH_SHA2_NISTP521,
#ifndef WOLFSSH_NO_NISTP256_MLKEM768_SHA256
ID_NISTP256_MLKEM768_SHA256,
#endif
#ifndef WOLFSSH_NO_NISTP384_MLKEM1024_SHA384
ID_NISTP384_MLKEM1024_SHA384,
#endif
#ifndef WOLFSSH_NO_CURVE25519_MLKEM768_SHA256
ID_CURVE25519_MLKEM768_SHA256,
#endif
#ifndef WOLFSSH_NO_CURVE25519_SHA256
ID_CURVE25519_SHA256,
ID_CURVE25519_SHA256_LIBSSH,
#endif
ID_EXTINFO_S, /* Pseudo-KEX to indicate server extensions. */
ID_EXTINFO_C, /* Pseudo-KEX to indicate client extensions. */
/* Public Key IDs */
ID_SSH_RSA,
ID_RSA_SHA2_256,
ID_RSA_SHA2_512,
ID_ECDSA_SHA2_NISTP256,
ID_ECDSA_SHA2_NISTP384,
ID_ECDSA_SHA2_NISTP521,
ID_ED25519,
ID_X509V3_SSH_RSA,
ID_X509V3_ECDSA_SHA2_NISTP256,
ID_X509V3_ECDSA_SHA2_NISTP384,
ID_X509V3_ECDSA_SHA2_NISTP521,
/* Service IDs */
ID_SERVICE_USERAUTH,
ID_SERVICE_CONNECTION,
/* UserAuth IDs */
ID_USERAUTH_PASSWORD,
ID_USERAUTH_PUBLICKEY,
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
ID_USERAUTH_KEYBOARD,
#endif
/* Channel Type IDs */
ID_CHANTYPE_SESSION,
ID_CHANTYPE_TCPIP_FORWARD,
ID_CHANTYPE_TCPIP_DIRECT,
ID_CHANTYPE_AUTH_AGENT,
/* Global Request IDs */
ID_GLOBREQ_TCPIP_FWD,
ID_GLOBREQ_TCPIP_FWD_CANCEL,
ID_EXTINFO_SERVER_SIG_ALGS,
ID_CURVE_NISTP256,
ID_CURVE_NISTP384,
ID_CURVE_NISTP521,
ID_UNKNOWN
};
enum NameIdType {
TYPE_KEX, TYPE_KEY, TYPE_CIPHER, TYPE_MAC, TYPE_OTHER
};
#define WOLFSSH_MAX_NAMESZ 32
#ifndef WOLFSSH_MAX_CHN_NAMESZ
#define WOLFSSH_MAX_CHN_NAMESZ 4096
#endif
#define MAX_ENCRYPTION 3
#define MAX_INTEGRITY 2
#define MAX_KEY_EXCHANGE 2
#define MAX_PUBLIC_KEY 1
#define MIN_RSA_SIG_SZ 2
#define MAX_HMAC_SZ WC_MAX_DIGEST_SIZE
#define MIN_BLOCK_SZ 8
#define COOKIE_SZ 16
#define PAD_LENGTH_SZ 1
#define MIN_PAD_LENGTH 4
#define BOOLEAN_SZ 1
#define MSG_ID_SZ 1
#define SHA1_96_SZ 12
#define UINT32_SZ 4
#define LENGTH_SZ UINT32_SZ
#define SSH_PROTO_SZ 7 /* "SSH-2.0" */
#define TERMINAL_MODE_SZ 5 /* opcode byte + argument uint32 */
#define AEAD_IMP_IV_SZ 4
#define AEAD_EXP_IV_SZ 8
#define AEAD_NONCE_SZ (AEAD_IMP_IV_SZ+AEAD_EXP_IV_SZ)
#ifndef DEFAULT_HIGHWATER_MARK
#define DEFAULT_HIGHWATER_MARK ((1024 * 1024 * 1024) - (32 * 1024))
#endif
#ifndef DEFAULT_WINDOW_SZ
#define DEFAULT_WINDOW_SZ (128 * 1024)
#endif
#ifndef DEFAULT_MAX_PACKET_SZ
/* This is from RFC 4253 section 6.1. */
#define DEFAULT_MAX_PACKET_SZ 32768
#endif
#ifndef DEFAULT_NEXT_CHANNEL
#define DEFAULT_NEXT_CHANNEL 0
#endif
#ifndef MAX_PACKET_SZ
/* This is from RFC 4253 section 6.1. */
#define MAX_PACKET_SZ 35000
#endif
#ifndef WOLFSSH_DEFAULT_GEXDH_MIN
#define WOLFSSH_DEFAULT_GEXDH_MIN 1024
#endif
#ifndef WOLFSSH_DEFAULT_GEXDH_PREFERRED
#define WOLFSSH_DEFAULT_GEXDH_PREFERRED 3072
#endif
#ifndef WOLFSSH_DEFAULT_GEXDH_MAX
#define WOLFSSH_DEFAULT_GEXDH_MAX 8192
#endif
#ifndef MAX_KEX_KEY_SZ
#ifndef WOLFSSH_NO_NISTP384_MLKEM1024_SHA384
/* Private key size of ML-KEM 1024. Biggest artifact. */
#define MAX_KEX_KEY_SZ 3168
#elif !defined(WOLFSSH_NO_NISTP256_MLKEM768_SHA256) || \
!defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256)
/* Private key size of ML-KEM 768. Biggest artifact. */
#define MAX_KEX_KEY_SZ 2400
#else
/* This is based on the 8192-bit DH key that is the max size. */
#define MAX_KEX_KEY_SZ (WOLFSSH_DEFAULT_GEXDH_MAX / 8)
#endif
#endif
#ifndef WOLFSSH_MR_ROUNDS
#define WOLFSSH_MR_ROUNDS 8
#endif
#ifndef WOLFSSH_MAX_FILE_SIZE
#define WOLFSSH_MAX_FILE_SIZE (1024ul * 1024ul * 4)
#endif
#ifndef WOLFSSH_MAX_PVT_KEYS
#define WOLFSSH_MAX_PVT_KEYS 8
#endif
#ifndef WOLFSSH_MAX_PUB_KEY_ALGO
#define WOLFSSH_MAX_PUB_KEY_ALGO (WOLFSSH_MAX_PVT_KEYS + 2)
#endif
#ifndef WOLFSSH_KEY_QUANTITY_REQ
#define WOLFSSH_KEY_QUANTITY_REQ 1
#endif
/* Keep track of keying state for both sides of the connection.
* WOLFSSH_SELF_IS_KEYING gets set on sending KEX init and
* WOLFSSH_PEER_IS_KEYING gets set on receiving KEX init */
#define WOLFSSH_PEER_IS_KEYING 0x01
#define WOLFSSH_SELF_IS_KEYING 0x02
WOLFSSH_LOCAL byte NameToId(const char* name, word32 nameSz);
WOLFSSH_LOCAL const char* IdToName(byte id);
WOLFSSH_LOCAL const char* NameByIndexType(byte type, word32* idx);
/* For cases when openssl coexist is used */
#ifdef WC_NO_COMPAT_AES_BLOCK_SIZE
#define AES_BLOCK_SIZE WC_AES_BLOCK_SIZE
#endif
#define STATIC_BUFFER_LEN AES_BLOCK_SIZE
/* This is one AES block size. We always grab one
* block size first to decrypt to find the size of
* the rest of the data. */
typedef struct WOLFSSH_BUFFER {
void* heap; /* Heap for allocations */
int plainSz; /* amount of plain text bytes to send with WANT_WRITE */
word32 length; /* total buffer length used */
word32 idx; /* idx to part of length already consumed */
byte* buffer; /* place holder for actual buffer */
word32 bufferSz; /* current buffer size */
ALIGN16 byte staticBuffer[STATIC_BUFFER_LEN];
byte dynamicFlag; /* dynamic memory currently in use */
} WOLFSSH_BUFFER;
WOLFSSH_LOCAL int BufferInit(WOLFSSH_BUFFER* buffer, word32 size, void* heap);
WOLFSSH_LOCAL int GrowBuffer(WOLFSSH_BUFFER* buf, word32 sz);
WOLFSSH_LOCAL void ShrinkBuffer(WOLFSSH_BUFFER* buf, int forcedFree);
typedef struct WOLFSSH_PVT_KEY {
byte* key;
/* List of pointers to raw private keys. Owned by CTX. */
word32 keySz;
#ifdef WOLFSSH_CERTS
byte* cert;
/* Pointer to certificates for the private key. Owned by CTX. */
word32 certSz;
#endif
byte publicKeyFmt;
/* Public key format for the private key. Note, some public key
* formats are used with multiple public key signing algorithms. */
} WOLFSSH_PVT_KEY;
/* our wolfSSH Context */
struct WOLFSSH_CTX {
void* heap; /* heap hint */
WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */
WS_CallbackIOSend ioSendCb; /* I/O Send Callback */
WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */
WS_CallbackUserAuthTypes userAuthTypesCb; /* Authentication Types Allowed */
WS_CallbackUserAuthResult userAuthResultCb; /* User Authentication Result */
WS_CallbackHighwater highwaterCb; /* Data Highwater Mark Callback */
WS_CallbackGlobalReq globalReqCb; /* Global Request Callback */
WS_CallbackReqSuccess reqSuccessCb; /* Global Request Success Callback */
WS_CallbackReqSuccess reqFailureCb; /* Global Request Failure Callback */
WS_CallbackChannelOpen channelOpenCb; /* Channel Open Requested */
WS_CallbackChannelOpen channelOpenConfCb; /* Channel Open Confirm */
WS_CallbackChannelOpen channelOpenFailCb; /* Channel Open Fail */
WS_CallbackChannelReq channelReqShellCb; /* Channel Request "Shell" */
WS_CallbackChannelReq channelReqExecCb; /* Channel Request "Exec" */
WS_CallbackChannelReq channelReqSubsysCb; /* Channel Request "Subsystem" */
WS_CallbackChannelEof channelEofCb; /* Channel Eof Callback */
WS_CallbackChannelClose channelCloseCb; /* Channel Close Callback */
#ifdef WOLFSSH_SCP
WS_CallbackScpRecv scpRecvCb; /* SCP receive callback */
WS_CallbackScpSend scpSendCb; /* SCP send callback */
#endif
#ifdef WOLFSSH_AGENT
WS_CallbackAgent agentCb; /* WOLFSSH-AGENT callback */
WS_CallbackAgentIO agentIoCb; /* WOLFSSH-AGENT IO callback */
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_FWD
WS_CallbackFwd fwdCb; /* WOLFSSH-FWD callback */
WS_CallbackFwdIO fwdIoCb; /* WOLFSSH-FWD IO callback */
#endif /* WOLFSSH_FWD */
#ifdef WOLFSSH_CERTS
WOLFSSH_CERTMAN* certMan;
#endif /* WOLFSSH_CERTS */
WS_CallbackPublicKeyCheck publicKeyCheckCb;
/* Check server's public key callback */
WOLFSSH_PVT_KEY privateKey[WOLFSSH_MAX_PVT_KEYS];
word32 privateKeyCount;
byte publicKeyAlgo[WOLFSSH_MAX_PUB_KEY_ALGO];
word32 publicKeyAlgoCount;
word32 highwaterMark;
const char* banner;
const char* sshProtoIdStr;
const char* algoListKex;
const char* algoListKey;
const char* algoListCipher;
const char* algoListMac;
const char* algoListKeyAccepted;
word32 bannerSz;
word32 windowSz;
word32 maxPacketSz;
byte side; /* client or server */
byte showBanner;
#ifdef WOLFSSH_AGENT
byte agentEnabled;
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_TPM
WOLFTPM2_DEV* tpmDev;
WOLFTPM2_KEY* tpmKey;
#endif /* WOLFSSH_TPM */
WS_CallbackKeyingCompletion keyingCompletionCb;
};
typedef struct Ciphers {
Aes aes;
} Ciphers;
typedef struct Keys {
byte iv[AES_BLOCK_SIZE];
byte ivSz;
byte encKey[AES_256_KEY_SIZE];
byte encKeySz;
byte macKey[MAX_HMAC_SZ];
byte macKeySz;
} Keys;
typedef struct HandshakeInfo {
byte expectMsgId;
byte kexId;
byte kexIdGuess;
byte kexHashId;
byte pubKeyId;
byte encryptId;
byte macId;
byte kexPacketFollows;
byte aeadMode;
byte blockSz;
byte macSz;
Keys keys;
Keys peerKeys;
wc_HashAlg kexHash;
byte e[MAX_KEX_KEY_SZ+1]; /* May have a leading zero for unsigned
or is a Q_S value. */
word32 eSz;
byte x[MAX_KEX_KEY_SZ+1]; /* May have a leading zero, for unsigned. */
word32 xSz;
byte* kexInit;
word32 kexInitSz;
#ifndef WOLFSSH_NO_DH
word32 dhGexMinSz;
word32 dhGexPreferredSz;
word32 dhGexMaxSz;
byte* primeGroup;
word32 primeGroupSz;
byte* generator;
word32 generatorSz;
#endif
byte useDh:1;
byte useEcc:1;
byte useEccMlKem:1;
byte useCurve25519:1;
byte useCurve25519MlKem:1;
union {
#ifndef WOLFSSH_NO_DH
DhKey dh;
#endif
#ifndef WOLFSSH_NO_ECDH
ecc_key ecc;
#endif
#if !defined(WOLFSSH_NO_CURVE25519_SHA256) || \
!defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256)
curve25519_key curve25519;
#endif
} privKey;
} HandshakeInfo;
#if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \
!defined(NO_WOLFSSH_SERVER)
WOLFSSH_LOCAL int wolfSSH_GetPath(const char* defaultPath, byte* in,
word32 inSz, char* out, word32* outSz);
#endif
#ifdef WOLFSSH_SFTP
#define WOLFSSH_MAX_SFTPOFST 3
#ifndef NO_WOLFSSH_DIR
typedef struct WS_DIR_LIST WS_DIR_LIST;
#endif
#ifdef WOLFSSH_STOREHANDLE
typedef struct WS_HANDLE_LIST WS_HANDLE_LIST;
#endif
typedef struct SFTP_OFST {
word32 offset[2];
char from[WOLFSSH_MAX_FILENAME];
char to[WOLFSSH_MAX_FILENAME];
} SFTP_OFST;
struct WS_SFTP_RECV_INIT_STATE;
struct WS_SFTP_GET_STATE;
struct WS_SFTP_PUT_STATE;
struct WS_SFTP_LSTAT_STATE;
struct WS_SFTP_OPEN_STATE;
struct WS_SFTP_CLOSE_STATE;
struct WS_SFTP_SEND_READ_STATE;
struct WS_SFTP_SEND_WRITE_STATE;
struct WS_SFTP_GET_HANDLE_STATE;
struct WS_SFTP_PUT_STATE;
struct WS_SFTP_RENAME_STATE;
#ifdef USE_WINDOWS_API
#define MAX_DRIVE_LETTER 26
#endif /* USE_WINDOWS_API */
#endif /* WOLFSSH_SFTP */
#ifdef USE_WINDOWS_API
#ifndef WOLFSSL_MAX_ESCBUF
#define WOLFSSL_MAX_ESCBUF 19
#endif
#endif
struct WOLFSSH_AGENT_CTX;
/* our wolfSSH session */
struct WOLFSSH {
WOLFSSH_CTX* ctx; /* owner context */
int error;
WS_SOCKET_T rfd;
WS_SOCKET_T wfd;
void* ioReadCtx; /* I/O Read Context handle */
void* ioWriteCtx; /* I/O Write Context handle */
int rflags; /* optional read flags */
int wflags; /* optional write flags */
word32 txCount;
word32 rxCount;
word32 highwaterMark;
byte highwaterFlag; /* Set when highwater CB called */
void* highwaterCtx; /* Highwater CB context */
void* globalReqCtx; /* Global Request CB context */
void* reqSuccessCtx; /* Global Request Success CB context */
void* reqFailureCtx; /* Global Request Failure CB context */
void* channelOpenCtx; /* Channel Open CB context */
void* channelReqCtx; /* Channel Request CB context */
void* channelEofCtx; /* Channel EOF CB context */
void* channelCloseCtx; /* Channel Close CB context */
void* fs; /* File system handle */
word32 curSz;
word32 seq;
word32 peerSeq;
word32 packetStartIdx; /* Current send packet start index */
const char* algoListKex;
const char* algoListKey;
const char* algoListCipher;
const char* algoListMac;
const char* algoListKeyAccepted;
byte acceptState;
byte connectState;
byte clientState;
byte serverState;
byte processReplyState;
byte isKeying;
byte authId; /* if using public key or password */
byte supportedAuth[4]; /* supported auth IDs public key , password */
#ifdef WOLFSSH_SCP
byte scpState;
byte scpNextState;
byte scpRequestState;
byte scpFileState;
byte scpDirection; /* indicates sending TO (t) of FROM (f) */
int scpConfirm; /* confirmation state (OK|WARN|FATAL) */
char* scpConfirmMsg; /* dynamic, confirm message string */
word32 scpConfirmMsgSz; /* length of confirmMsg, not including \0 */
char* scpRecvMsg; /* reading up to newline delimiter */
int scpRecvMsgSz; /* current size of scp recv message */
const char* scpBasePath; /* base path, ptr into channelList->command */
/* alter base path instead of using chdir */
char* scpBasePathDynamic; /* dynamic base path */
word32 scpBasePathSz;
byte scpIsRecursive; /* recursive transfer requested */
byte scpRequestType; /* directory or single file */
byte scpMsgType;
int scpFileMode; /* mode/permission of file/dir */
word32 scpFileSz; /* total size of file/dir being transferred */
char* scpFileName; /* file name, dynamic */
char* scpFileReName; /* file rename case, points to scpFileName */
word32 scpFileNameSz; /* length of fileName, not including \0 */
byte scpTimestamp; /* did peer request timestamp? {0:1} */
word64 scpATime; /* scp file access time, secs since epoch */
word64 scpMTime; /* scp file modification time, secs epoch */
byte* scpFileBuffer; /* transfer buffer, dynamic */
word32 scpFileBufferSz; /* size of transfer buffer, octets */
word32 scpFileOffset; /* current offset into file transfer */
word32 scpBufferedSz; /* bytes buffered to send to peer */
#ifdef WOLFSSL_NUCLEUS
int scpFd; /* SCP receive callback context handle */
#endif
void* scpRecvCtx; /* SCP receive callback context handle */
void* scpSendCtx; /* SCP send callback context handle */
#if !defined(WOLFSSH_SCP_USER_CALLBACKS) && !defined(NO_FILESYSTEM)
ScpSendCtx scpSendCbCtx; /* used in default case to for send cb ctx */
#endif
#endif
byte connReset;
byte isClosed;
byte clientOpenSSH;
byte kexId;
byte blockSz;
byte encryptId;
byte macId;
byte macSz;
byte aeadMode;
byte peerBlockSz;
byte peerEncryptId;
byte peerMacId;
byte peerMacSz;
byte peerAeadMode;
#ifndef WOLFSSH_NO_DH
word32 primeGroupSz;
#endif
Ciphers encryptCipher;
Ciphers decryptCipher;
word32 nextChannel;
WOLFSSH_CHANNEL* channelList;
word32 channelListSz;
word32 defaultPeerChannelId;
word32 connectChannelId;
byte channelName[WOLFSSH_MAX_CHN_NAMESZ];
word32 channelNameSz;
word32 lastRxId;
WOLFSSH_BUFFER inputBuffer;
WOLFSSH_BUFFER outputBuffer;
WOLFSSH_BUFFER extDataBuffer; /* extended data ready to be read */
WC_RNG* rng;
byte h[WC_MAX_DIGEST_SIZE];
word32 hSz;
byte k[MAX_KEX_KEY_SZ+1]; /* May have a leading zero, for unsigned. */
word32 kSz;
byte sessionId[WC_MAX_DIGEST_SIZE];
word32 sessionIdSz;
Keys keys;
Keys peerKeys;
HandshakeInfo* handshake;
void* userAuthCtx;
void* userAuthResultCtx;
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
void* keyboardAuthCtx;
#endif
char* userName;
word32 userNameSz;
char* password;
word32 passwordSz;
byte* pkBlob;
word32 pkBlobSz;
byte* peerProtoId; /* Save for rekey */
word32 peerProtoIdSz;
void* publicKeyCheckCtx;
byte sendTerminalRequest;
byte userAuthPkDone;
byte sendExtInfo;
byte extInfoSent; /* track if the ext info has already been sent */
byte* peerSigId;
word32 peerSigIdSz;
#ifdef USE_WINDOWS_API
word32 defaultAttr; /* default windows attributes */
byte defaultAttrSet;
byte escBuf[WOLFSSL_MAX_ESCBUF]; /* console codes are about 3 byte and
* have max arguments of 16 */
byte escBufSz;
byte escState; /* current console translation state */
#endif
#ifdef WOLFSSH_SFTP
word32 reqId;
byte sftpState;
byte realState;
byte sftpInt;
word32 sftpExtSz; /* size of extension buffer (buffer not currently used) */
SFTP_OFST sftpOfst[WOLFSSH_MAX_SFTPOFST];
char* sftpDefaultPath;
#ifndef NO_WOLFSSH_DIR
WS_DIR_LIST* dirList;
word32 dirIdCount[2];
#endif
#ifdef WOLFSSH_STOREHANDLE
WS_HANDLE_LIST* handleList;
#endif
struct WS_SFTP_RECV_INIT_STATE* recvInitState;
struct WS_SFTP_RECV_STATE* recvState;
struct WS_SFTP_RMDIR_STATE* rmdirState;
struct WS_SFTP_MKDIR_STATE* mkdirState;
struct WS_SFTP_RM_STATE* rmState;
struct WS_SFTP_READDIR_STATE* readDirState;
struct WS_SFTP_SETATR_STATE* setatrState;
struct WS_SFTP_CHMOD_STATE* chmodState;
struct WS_SFTP_LS_STATE* lsState;
struct WS_SFTP_SEND_STATE* sendState;
struct WS_SFTP_NAME_STATE* nameState;
struct WS_SFTP_GET_STATE* getState;
struct WS_SFTP_PUT_STATE* putState;
struct WS_SFTP_LSTAT_STATE* lstatState;
struct WS_SFTP_OPEN_STATE* openState;
struct WS_SFTP_CLOSE_STATE* closeState;
struct WS_SFTP_SEND_READ_STATE* sendReadState;
struct WS_SFTP_SEND_WRITE_STATE* sendWriteState;
struct WS_SFTP_GET_HANDLE_STATE* getHandleState;
struct WS_SFTP_RENAME_STATE* renameState;
#ifdef USE_WINDOWS_API
char driveList[MAX_DRIVE_LETTER];
word16 driveListCount;
word16 driveIdx;
#endif
#endif
#ifdef WOLFSSH_AGENT
struct WOLFSSH_AGENT_CTX* agent;
void* agentCbCtx;
byte useAgent;
byte agentEnabled;
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_FWD
void* fwdCbCtx;
#endif /* WOLFSSH_FWD */
#ifdef WOLFSSH_TERM
WS_CallbackTerminalSize termResizeCb;
void* termCtx;
word32 widthChar; /* current terminal width */
word32 heightRows; /* current terminal height */
word32 widthPixels; /* pixel width */
word32 heightPixels; /* pixel height */
byte* modes;
word32 modesSz;
#endif
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
word32 exitStatus;
#endif
void* keyingCompletionCtx;
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
WS_UserAuthData_Keyboard kbAuth;
byte kbAuthAttempts;
#endif
};
struct WOLFSSH_CHANNEL {
byte channelType;
byte sessionType;
byte closeRxd : 1;
byte closeTxd : 1;
byte eofRxd : 1;
byte eofTxd : 1;
byte openConfirmed : 1;
byte ptyReq : 1; /* flag for if interactive pty request was received */
word32 channel;
word32 windowSz;
word32 maxPacketSz;
word32 peerChannel;
word32 peerWindowSz;
word32 peerMaxPacketSz;
#ifdef WOLFSSH_FWD
char* host;
word32 hostPort;
char* origin;
word32 originPort;
int fwdFd;
int isDirect;
#endif /* WOLFSSH_FWD */
WOLFSSH_BUFFER inputBuffer;
char* command;
struct WOLFSSH* ssh;
struct WOLFSSH_CHANNEL* next;
};
WOLFSSH_LOCAL WOLFSSH_CTX* CtxInit(WOLFSSH_CTX*, byte, void*);
WOLFSSH_LOCAL void CtxResourceFree(WOLFSSH_CTX*);
WOLFSSH_LOCAL WOLFSSH* SshInit(WOLFSSH*, WOLFSSH_CTX*);
WOLFSSH_LOCAL void SshResourceFree(WOLFSSH*, void*);
WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelNew(WOLFSSH*, byte, word32, word32);
WOLFSSH_LOCAL int ChannelUpdatePeer(WOLFSSH_CHANNEL*, word32, word32, word32);
WOLFSSH_LOCAL int ChannelUpdateForward(WOLFSSH_CHANNEL*,
const char*, word32, const char*, word32, int);
WOLFSSH_LOCAL int ChannelAppend(WOLFSSH* ssh, WOLFSSH_CHANNEL* channel);
WOLFSSH_LOCAL void ChannelDelete(WOLFSSH_CHANNEL*, void*);
WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelFind(WOLFSSH*, word32, byte);
WOLFSSH_LOCAL int ChannelRemove(WOLFSSH*, word32, byte);
WOLFSSH_LOCAL int ChannelPutData(WOLFSSH_CHANNEL*, byte*, word32);