@@ -205,6 +205,38 @@ static struct iscsi_chap *chap_server_open(
205205 return chap ;
206206}
207207
208+ static const char base64_lookup_table [] =
209+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
210+
211+ static int chap_base64_decode (u8 * dst , const char * src , size_t len )
212+ {
213+ int i , bits = 0 , ac = 0 ;
214+ const char * p ;
215+ u8 * cp = dst ;
216+
217+ for (i = 0 ; i < len ; i ++ ) {
218+ if (src [i ] == '=' )
219+ return cp - dst ;
220+
221+ p = strchr (base64_lookup_table , src [i ]);
222+ if (p == NULL || src [i ] == 0 )
223+ return -2 ;
224+
225+ ac <<= 6 ;
226+ ac += (p - base64_lookup_table );
227+ bits += 6 ;
228+ if (bits >= 8 ) {
229+ * cp ++ = (ac >> (bits - 8 )) & 0xff ;
230+ ac &= ~(BIT (16 ) - BIT (bits - 8 ));
231+ bits -= 8 ;
232+ }
233+ }
234+ if (ac )
235+ return -1 ;
236+
237+ return cp - dst ;
238+ }
239+
208240static int chap_server_compute_hash (
209241 struct iscsit_conn * conn ,
210242 struct iscsi_node_auth * auth ,
@@ -295,16 +327,27 @@ static int chap_server_compute_hash(
295327 pr_err ("Could not find CHAP_R.\n" );
296328 goto out ;
297329 }
298- if (type != HEX ) {
299- pr_err ("Could not find CHAP_R.\n" );
300- goto out ;
301- }
302- if (strlen (chap_r ) != chap -> digest_size * 2 ) {
303- pr_err ("Malformed CHAP_R\n" );
304- goto out ;
305- }
306- if (hex2bin (client_digest , chap_r , chap -> digest_size ) < 0 ) {
307- pr_err ("Malformed CHAP_R\n" );
330+
331+ switch (type ) {
332+ case HEX :
333+ if (strlen (chap_r ) != chap -> digest_size * 2 ) {
334+ pr_err ("Malformed CHAP_R\n" );
335+ goto out ;
336+ }
337+ if (hex2bin (client_digest , chap_r , chap -> digest_size ) < 0 ) {
338+ pr_err ("Malformed CHAP_R: invalid HEX\n" );
339+ goto out ;
340+ }
341+ break ;
342+ case BASE64 :
343+ if (chap_base64_decode (client_digest , chap_r , strlen (chap_r )) !=
344+ chap -> digest_size ) {
345+ pr_err ("Malformed CHAP_R: invalid BASE64\n" );
346+ goto out ;
347+ }
348+ break ;
349+ default :
350+ pr_err ("Could not find CHAP_R\n" );
308351 goto out ;
309352 }
310353
@@ -404,23 +447,46 @@ static int chap_server_compute_hash(
404447 goto out ;
405448 }
406449
407- if (type != HEX ) {
450+ switch (type ) {
451+ case HEX :
452+ initiatorchg_len = DIV_ROUND_UP (strlen (initiatorchg ), 2 );
453+ if (!initiatorchg_len ) {
454+ pr_err ("Unable to convert incoming challenge\n" );
455+ goto out ;
456+ }
457+ if (initiatorchg_len > 1024 ) {
458+ pr_err ("CHAP_C exceeds maximum binary size of 1024 bytes\n" );
459+ goto out ;
460+ }
461+
462+ if (hex2bin (initiatorchg_binhex , initiatorchg ,
463+ initiatorchg_len ) < 0 ) {
464+ pr_err ("Malformed CHAP_C: invalid HEX\n" );
465+ goto out ;
466+ }
467+ break ;
468+ case BASE64 :
469+ initiatorchg_len = chap_base64_decode (initiatorchg_binhex ,
470+ initiatorchg ,
471+ strlen (initiatorchg ));
472+ if (initiatorchg_len < 0 ) {
473+ pr_err ("Malformed CHAP_C: invalid BASE64\n" );
474+ goto out ;
475+ }
476+ if (!initiatorchg_len ) {
477+ pr_err ("Unable to convert incoming challenge\n" );
478+ goto out ;
479+ }
480+ if (initiatorchg_len > 1024 ) {
481+ pr_err ("CHAP_C exceeds maximum binary size of 1024 bytes\n" );
482+ goto out ;
483+ }
484+ break ;
485+ default :
408486 pr_err ("Could not find CHAP_C.\n" );
409487 goto out ;
410488 }
411- initiatorchg_len = DIV_ROUND_UP (strlen (initiatorchg ), 2 );
412- if (!initiatorchg_len ) {
413- pr_err ("Unable to convert incoming challenge\n" );
414- goto out ;
415- }
416- if (initiatorchg_len > 1024 ) {
417- pr_err ("CHAP_C exceeds maximum binary size of 1024 bytes\n" );
418- goto out ;
419- }
420- if (hex2bin (initiatorchg_binhex , initiatorchg , initiatorchg_len ) < 0 ) {
421- pr_err ("Malformed CHAP_C\n" );
422- goto out ;
423- }
489+
424490 pr_debug ("[server] Got CHAP_C=%s\n" , initiatorchg );
425491 /*
426492 * During mutual authentication, the CHAP_C generated by the
0 commit comments