|
31 | 31 | #include <unistd.h> |
32 | 32 | #include "sha1.h" |
33 | 33 | #include "md5.h" |
| 34 | +#include "af_alg.h" |
| 35 | +#include <sys/param.h> |
34 | 36 |
|
35 | 37 | #include "iscsid.h" |
36 | 38 |
|
|
39 | 41 |
|
40 | 42 | #define CHAP_DIGEST_ALG_MD5 5 |
41 | 43 | #define CHAP_DIGEST_ALG_SHA1 6 |
| 44 | +#define CHAP_DIGEST_ALG_SHA256 7 |
| 45 | +#define CHAP_DIGEST_ALG_SHA3_256 8 |
42 | 46 |
|
43 | 47 | #define CHAP_MD5_DIGEST_LEN 16 |
44 | 48 | #define CHAP_SHA1_DIGEST_LEN 20 |
| 49 | +#define CHAP_SHA256_DIGEST_LEN 32 |
| 50 | +#define CHAP_SHA3_256_DIGEST_LEN 32 |
45 | 51 |
|
46 | 52 | #define CHAP_INITIATOR_ERROR -1 |
47 | 53 | #define CHAP_AUTH_ERROR -2 |
@@ -338,6 +344,49 @@ static inline void chap_calc_digest_sha1(char chap_id, const char *secret, int s |
338 | 344 | sha1_final(&ctx, digest); |
339 | 345 | } |
340 | 346 |
|
| 347 | +static inline void |
| 348 | +chap_calc_digest_af_alg(char *alg, char chap_id, |
| 349 | + const char *secret, int secret_len, |
| 350 | + const u8 *challenge, int challenge_len, |
| 351 | + u8 *digest, int digest_len) |
| 352 | +{ |
| 353 | + int datafd = af_alg_init(alg); |
| 354 | + char buffer[1024]; |
| 355 | + int bytes; |
| 356 | + |
| 357 | + if (datafd < 0) { |
| 358 | + log_error("CHAP unable to use %s algorithm", alg); |
| 359 | + return; |
| 360 | + } |
| 361 | + |
| 362 | + af_alg_update(datafd, &chap_id, 1); |
| 363 | + af_alg_update(datafd, secret, secret_len); |
| 364 | + af_alg_update(datafd, challenge, challenge_len); |
| 365 | + bytes = af_alg_final(datafd, buffer, sizeof(buffer)); |
| 366 | + close(datafd); |
| 367 | + memcpy(digest, buffer, MIN(bytes, digest_len)); |
| 368 | +} |
| 369 | + |
| 370 | +static inline void |
| 371 | +chap_calc_digest_sha256(char chap_id, const char *secret, int secret_len, |
| 372 | + const u8 *challenge, int challenge_len, u8 *digest) |
| 373 | +{ |
| 374 | + chap_calc_digest_af_alg(SCST_AF_ALG_SHA256_NAME, |
| 375 | + chap_id, secret, secret_len, |
| 376 | + challenge, challenge_len, |
| 377 | + digest, CHAP_SHA256_DIGEST_LEN); |
| 378 | +} |
| 379 | + |
| 380 | +static inline void |
| 381 | +chap_calc_digest_sha3_256(char chap_id, const char *secret, int secret_len, |
| 382 | + const u8 *challenge, int challenge_len, u8 *digest) |
| 383 | +{ |
| 384 | + chap_calc_digest_af_alg(SCST_AF_ALG_SHA3_256_NAME, |
| 385 | + chap_id, secret, secret_len, |
| 386 | + challenge, challenge_len, |
| 387 | + digest, CHAP_SHA3_256_DIGEST_LEN); |
| 388 | +} |
| 389 | + |
341 | 390 | /* |
342 | 391 | * To generate challenge for CHAP, use stronger random number generator as |
343 | 392 | * opposed to simple rand(). |
@@ -374,7 +423,16 @@ static int chap_initiator_auth_create_challenge(struct connection *conn) |
374 | 423 | conn->auth.chap.digest_alg = CHAP_DIGEST_ALG_SHA1; |
375 | 424 | conn->auth_state = CHAP_AUTH_STATE_CHALLENGE; |
376 | 425 | break; |
| 426 | + } else if (!strcmp(p, "7") && af_alg_supported(SCST_AF_ALG_SHA256_NAME)) { |
| 427 | + conn->auth.chap.digest_alg = CHAP_DIGEST_ALG_SHA256; |
| 428 | + conn->auth_state = CHAP_AUTH_STATE_CHALLENGE; |
| 429 | + break; |
| 430 | + } else if (!strcmp(p, "8") && af_alg_supported(SCST_AF_ALG_SHA3_256_NAME)) { |
| 431 | + conn->auth.chap.digest_alg = CHAP_DIGEST_ALG_SHA3_256; |
| 432 | + conn->auth_state = CHAP_AUTH_STATE_CHALLENGE; |
| 433 | + break; |
377 | 434 | } |
| 435 | + |
378 | 436 | } |
379 | 437 | if (!p) |
380 | 438 | return CHAP_INITIATOR_ERROR; |
@@ -458,6 +516,12 @@ static int chap_initiator_auth_check_response(struct connection *conn) |
458 | 516 | case CHAP_DIGEST_ALG_SHA1: |
459 | 517 | digest_len = CHAP_SHA1_DIGEST_LEN; |
460 | 518 | break; |
| 519 | + case CHAP_DIGEST_ALG_SHA256: |
| 520 | + digest_len = CHAP_SHA256_DIGEST_LEN; |
| 521 | + break; |
| 522 | + case CHAP_DIGEST_ALG_SHA3_256: |
| 523 | + digest_len = CHAP_SHA3_256_DIGEST_LEN; |
| 524 | + break; |
461 | 525 | default: |
462 | 526 | retval = CHAP_TARGET_ERROR; |
463 | 527 | goto out; |
@@ -490,6 +554,18 @@ static int chap_initiator_auth_check_response(struct connection *conn) |
490 | 554 | conn->auth.chap.challenge_size, |
491 | 555 | our_digest); |
492 | 556 | break; |
| 557 | + case CHAP_DIGEST_ALG_SHA256: |
| 558 | + chap_calc_digest_sha256(conn->auth.chap.id, pass, strlen(pass), |
| 559 | + conn->auth.chap.challenge, |
| 560 | + conn->auth.chap.challenge_size, |
| 561 | + our_digest); |
| 562 | + break; |
| 563 | + case CHAP_DIGEST_ALG_SHA3_256: |
| 564 | + chap_calc_digest_sha3_256(conn->auth.chap.id, pass, strlen(pass), |
| 565 | + conn->auth.chap.challenge, |
| 566 | + conn->auth.chap.challenge_size, |
| 567 | + our_digest); |
| 568 | + break; |
493 | 569 | default: |
494 | 570 | retval = CHAP_TARGET_ERROR; |
495 | 571 | goto out; |
@@ -571,6 +647,12 @@ static int chap_target_auth_create_response(struct connection *conn) |
571 | 647 | case CHAP_DIGEST_ALG_SHA1: |
572 | 648 | digest_len = CHAP_SHA1_DIGEST_LEN; |
573 | 649 | break; |
| 650 | + case CHAP_DIGEST_ALG_SHA256: |
| 651 | + digest_len = CHAP_SHA256_DIGEST_LEN; |
| 652 | + break; |
| 653 | + case CHAP_DIGEST_ALG_SHA3_256: |
| 654 | + digest_len = CHAP_SHA3_256_DIGEST_LEN; |
| 655 | + break; |
574 | 656 | default: |
575 | 657 | retval = CHAP_TARGET_ERROR; |
576 | 658 | goto out; |
@@ -619,6 +701,16 @@ static int chap_target_auth_create_response(struct connection *conn) |
619 | 701 | chap_calc_digest_sha1(chap_id, ISCSI_USER_PASS(user), |
620 | 702 | strlen(ISCSI_USER_PASS(user)), challenge, challenge_len, digest); |
621 | 703 | break; |
| 704 | + case CHAP_DIGEST_ALG_SHA256: |
| 705 | + chap_calc_digest_sha256(chap_id, ISCSI_USER_PASS(user), |
| 706 | + strlen(ISCSI_USER_PASS(user)), |
| 707 | + challenge, challenge_len, digest); |
| 708 | + break; |
| 709 | + case CHAP_DIGEST_ALG_SHA3_256: |
| 710 | + chap_calc_digest_sha3_256(chap_id, ISCSI_USER_PASS(user), |
| 711 | + strlen(ISCSI_USER_PASS(user)), |
| 712 | + challenge, challenge_len, digest); |
| 713 | + break; |
622 | 714 | default: |
623 | 715 | retval = CHAP_TARGET_ERROR; |
624 | 716 | goto out; |
|
0 commit comments