@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
36
36
#include <ipxe/settings.h>
37
37
#include <ipxe/features.h>
38
38
#include <ipxe/base16.h>
39
+ #include <ipxe/base64.h>
39
40
#include <ipxe/iscsi.h>
40
41
41
42
/** @file
@@ -56,7 +57,7 @@ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
56
57
#define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 )
57
58
#define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 )
58
59
#define EPROTO_INVALID_CHAP_IDENTIFIER ( EPROTO | EUNIQ_02 )
59
- #define EPROTO_INVALID_CHAP_CHALLENGE ( EPROTO | EUNIQ_03 )
60
+ #define EPROTO_INVALID_LARGE_BINARY ( EPROTO | EUNIQ_03 )
60
61
#define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 )
61
62
62
63
/** iSCSI initiator name (explicitly specified) */
@@ -613,6 +614,41 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
613
614
return xfer_deliver_iob ( & iscsi -> socket , iobuf );
614
615
}
615
616
617
+ /**
618
+ * Calculate maximum length of decoded large binary value
619
+ *
620
+ * @v encoded Encoded large binary value
621
+ * @v max_raw_len Maximum length of raw data
622
+ */
623
+ static inline size_t
624
+ iscsi_large_binary_decoded_max_len ( const char * encoded ) {
625
+ return ( strlen ( encoded ) ); /* Decoding never expands data */
626
+ }
627
+
628
+ /**
629
+ * Decode large binary value
630
+ *
631
+ * @v encoded Encoded large binary value
632
+ * @v raw Raw data
633
+ * @ret len Length of raw data, or negative error
634
+ */
635
+ static int iscsi_large_binary_decode ( const char * encoded , uint8_t * raw ) {
636
+
637
+ if ( encoded [0 ] != '0' )
638
+ return - EPROTO_INVALID_LARGE_BINARY ;
639
+
640
+ switch ( encoded [1 ] ) {
641
+ case 'x' :
642
+ case 'X' :
643
+ return base16_decode ( ( encoded + 2 ), raw );
644
+ case 'b' :
645
+ case 'B' :
646
+ return base64_decode ( ( encoded + 2 ), raw );
647
+ default :
648
+ return - EPROTO_INVALID_LARGE_BINARY ;
649
+ }
650
+ }
651
+
616
652
/**
617
653
* Handle iSCSI TargetAddress text value
618
654
*
@@ -737,24 +773,19 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
737
773
*/
738
774
static int iscsi_handle_chap_c_value ( struct iscsi_session * iscsi ,
739
775
const char * value ) {
740
- uint8_t buf [ strlen ( value ) ]; /* Decoding never expands data */
776
+ uint8_t buf [ iscsi_large_binary_decoded_max_len ( value ) ];
741
777
unsigned int i ;
742
- int len ;
743
-
744
- /* Check and strip leading "0x" */
745
- if ( ( value [0 ] != '0' ) || ( value [1 ] != 'x' ) ) {
746
- DBGC ( iscsi , "iSCSI %p saw invalid CHAP challenge \"%s\"\n" ,
747
- iscsi , value );
748
- return - EPROTO_INVALID_CHAP_CHALLENGE ;
749
- }
778
+ size_t len ;
779
+ int rc ;
750
780
751
781
/* Process challenge */
752
- len = base16_decode ( ( value + 2 ) , buf );
753
- if ( len < 0 ) {
782
+ rc = iscsi_large_binary_decode ( value , buf );
783
+ if ( rc < 0 ) {
754
784
DBGC ( iscsi , "iSCSI %p invalid CHAP challenge \"%s\": %s\n" ,
755
- iscsi , value , strerror ( len ) );
756
- return len ;
785
+ iscsi , value , strerror ( rc ) );
786
+ return rc ;
757
787
}
788
+ len = rc ;
758
789
chap_update ( & iscsi -> chap , buf , len );
759
790
760
791
/* Build CHAP response */
@@ -812,7 +843,7 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
812
843
*/
813
844
static int iscsi_handle_chap_r_value ( struct iscsi_session * iscsi ,
814
845
const char * value ) {
815
- uint8_t buf [ strlen ( value ) ]; /* Decoding never expands data */
846
+ uint8_t buf [ iscsi_large_binary_decoded_max_len ( value ) ];
816
847
size_t len ;
817
848
int rc ;
818
849
@@ -832,15 +863,8 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
832
863
( sizeof ( iscsi -> chap_challenge ) - 1 ) );
833
864
chap_respond ( & iscsi -> chap );
834
865
835
- /* Check and strip leading "0x" */
836
- if ( ( value [0 ] != '0' ) || ( value [1 ] != 'x' ) ) {
837
- DBGC ( iscsi , "iSCSI %p saw invalid CHAP response \"%s\"\n" ,
838
- iscsi , value );
839
- return - EPROTO_INVALID_CHAP_RESPONSE ;
840
- }
841
-
842
866
/* Process response */
843
- rc = base16_decode ( ( value + 2 ) , buf );
867
+ rc = iscsi_large_binary_decode ( value , buf );
844
868
if ( rc < 0 ) {
845
869
DBGC ( iscsi , "iSCSI %p invalid CHAP response \"%s\": %s\n" ,
846
870
iscsi , value , strerror ( rc ) );
0 commit comments