0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <crypto/hash.h>
0012 #include <linux/kernel.h>
0013 #include <linux/string.h>
0014 #include <linux/err.h>
0015 #include <linux/random.h>
0016 #include <linux/scatterlist.h>
0017 #include <target/iscsi/iscsi_target_core.h>
0018 #include "iscsi_target_nego.h"
0019 #include "iscsi_target_auth.h"
0020
0021 static char *chap_get_digest_name(const int digest_type)
0022 {
0023 switch (digest_type) {
0024 case CHAP_DIGEST_MD5:
0025 return "md5";
0026 case CHAP_DIGEST_SHA1:
0027 return "sha1";
0028 case CHAP_DIGEST_SHA256:
0029 return "sha256";
0030 case CHAP_DIGEST_SHA3_256:
0031 return "sha3-256";
0032 default:
0033 return NULL;
0034 }
0035 }
0036
0037 static int chap_gen_challenge(
0038 struct iscsit_conn *conn,
0039 int caller,
0040 char *c_str,
0041 unsigned int *c_len)
0042 {
0043 int ret;
0044 unsigned char *challenge_asciihex;
0045 struct iscsi_chap *chap = conn->auth_protocol;
0046
0047 challenge_asciihex = kzalloc(chap->challenge_len * 2 + 1, GFP_KERNEL);
0048 if (!challenge_asciihex)
0049 return -ENOMEM;
0050
0051 memset(chap->challenge, 0, MAX_CHAP_CHALLENGE_LEN);
0052
0053 ret = get_random_bytes_wait(chap->challenge, chap->challenge_len);
0054 if (unlikely(ret))
0055 goto out;
0056
0057 bin2hex(challenge_asciihex, chap->challenge,
0058 chap->challenge_len);
0059
0060
0061
0062 *c_len += sprintf(c_str + *c_len, "CHAP_C=0x%s", challenge_asciihex);
0063 *c_len += 1;
0064
0065 pr_debug("[%s] Sending CHAP_C=0x%s\n\n", (caller) ? "server" : "client",
0066 challenge_asciihex);
0067
0068 out:
0069 kfree(challenge_asciihex);
0070 return ret;
0071 }
0072
0073 static int chap_test_algorithm(const char *name)
0074 {
0075 struct crypto_shash *tfm;
0076
0077 tfm = crypto_alloc_shash(name, 0, 0);
0078 if (IS_ERR(tfm))
0079 return -1;
0080
0081 crypto_free_shash(tfm);
0082 return 0;
0083 }
0084
0085 static int chap_check_algorithm(const char *a_str)
0086 {
0087 char *tmp, *orig, *token, *digest_name;
0088 long digest_type;
0089 int r = CHAP_DIGEST_UNKNOWN;
0090
0091 tmp = kstrdup(a_str, GFP_KERNEL);
0092 if (!tmp) {
0093 pr_err("Memory allocation failed for CHAP_A temporary buffer\n");
0094 return CHAP_DIGEST_UNKNOWN;
0095 }
0096 orig = tmp;
0097
0098 token = strsep(&tmp, "=");
0099 if (!token)
0100 goto out;
0101
0102 if (strcmp(token, "CHAP_A")) {
0103 pr_err("Unable to locate CHAP_A key\n");
0104 goto out;
0105 }
0106 while (token) {
0107 token = strsep(&tmp, ",");
0108 if (!token)
0109 goto out;
0110
0111 if (kstrtol(token, 10, &digest_type))
0112 continue;
0113
0114 digest_name = chap_get_digest_name(digest_type);
0115 if (!digest_name)
0116 continue;
0117
0118 pr_debug("Selected %s Algorithm\n", digest_name);
0119 if (chap_test_algorithm(digest_name) < 0) {
0120 pr_err("failed to allocate %s algo\n", digest_name);
0121 } else {
0122 r = digest_type;
0123 goto out;
0124 }
0125 }
0126 out:
0127 kfree(orig);
0128 return r;
0129 }
0130
0131 static void chap_close(struct iscsit_conn *conn)
0132 {
0133 kfree(conn->auth_protocol);
0134 conn->auth_protocol = NULL;
0135 }
0136
0137 static struct iscsi_chap *chap_server_open(
0138 struct iscsit_conn *conn,
0139 struct iscsi_node_auth *auth,
0140 const char *a_str,
0141 char *aic_str,
0142 unsigned int *aic_len)
0143 {
0144 int digest_type;
0145 struct iscsi_chap *chap;
0146
0147 if (!(auth->naf_flags & NAF_USERID_SET) ||
0148 !(auth->naf_flags & NAF_PASSWORD_SET)) {
0149 pr_err("CHAP user or password not set for"
0150 " Initiator ACL\n");
0151 return NULL;
0152 }
0153
0154 conn->auth_protocol = kzalloc(sizeof(struct iscsi_chap), GFP_KERNEL);
0155 if (!conn->auth_protocol)
0156 return NULL;
0157
0158 chap = conn->auth_protocol;
0159 digest_type = chap_check_algorithm(a_str);
0160 switch (digest_type) {
0161 case CHAP_DIGEST_MD5:
0162 chap->digest_size = MD5_SIGNATURE_SIZE;
0163 break;
0164 case CHAP_DIGEST_SHA1:
0165 chap->digest_size = SHA1_SIGNATURE_SIZE;
0166 break;
0167 case CHAP_DIGEST_SHA256:
0168 chap->digest_size = SHA256_SIGNATURE_SIZE;
0169 break;
0170 case CHAP_DIGEST_SHA3_256:
0171 chap->digest_size = SHA3_256_SIGNATURE_SIZE;
0172 break;
0173 case CHAP_DIGEST_UNKNOWN:
0174 default:
0175 pr_err("Unsupported CHAP_A value\n");
0176 chap_close(conn);
0177 return NULL;
0178 }
0179
0180 chap->digest_name = chap_get_digest_name(digest_type);
0181
0182
0183 chap->challenge_len = chap->digest_size;
0184
0185 pr_debug("[server] Got CHAP_A=%d\n", digest_type);
0186 *aic_len = sprintf(aic_str, "CHAP_A=%d", digest_type);
0187 *aic_len += 1;
0188 pr_debug("[server] Sending CHAP_A=%d\n", digest_type);
0189
0190
0191
0192
0193 chap->id = conn->tpg->tpg_chap_id++;
0194 *aic_len += sprintf(aic_str + *aic_len, "CHAP_I=%d", chap->id);
0195 *aic_len += 1;
0196 pr_debug("[server] Sending CHAP_I=%d\n", chap->id);
0197
0198
0199
0200 if (chap_gen_challenge(conn, 1, aic_str, aic_len) < 0) {
0201 chap_close(conn);
0202 return NULL;
0203 }
0204
0205 return chap;
0206 }
0207
0208 static const char base64_lookup_table[] =
0209 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0210
0211 static int chap_base64_decode(u8 *dst, const char *src, size_t len)
0212 {
0213 int i, bits = 0, ac = 0;
0214 const char *p;
0215 u8 *cp = dst;
0216
0217 for (i = 0; i < len; i++) {
0218 if (src[i] == '=')
0219 return cp - dst;
0220
0221 p = strchr(base64_lookup_table, src[i]);
0222 if (p == NULL || src[i] == 0)
0223 return -2;
0224
0225 ac <<= 6;
0226 ac += (p - base64_lookup_table);
0227 bits += 6;
0228 if (bits >= 8) {
0229 *cp++ = (ac >> (bits - 8)) & 0xff;
0230 ac &= ~(BIT(16) - BIT(bits - 8));
0231 bits -= 8;
0232 }
0233 }
0234 if (ac)
0235 return -1;
0236
0237 return cp - dst;
0238 }
0239
0240 static int chap_server_compute_hash(
0241 struct iscsit_conn *conn,
0242 struct iscsi_node_auth *auth,
0243 char *nr_in_ptr,
0244 char *nr_out_ptr,
0245 unsigned int *nr_out_len)
0246 {
0247 unsigned long id;
0248 unsigned char id_as_uchar;
0249 unsigned char type;
0250 unsigned char identifier[10], *initiatorchg = NULL;
0251 unsigned char *initiatorchg_binhex = NULL;
0252 unsigned char *digest = NULL;
0253 unsigned char *response = NULL;
0254 unsigned char *client_digest = NULL;
0255 unsigned char *server_digest = NULL;
0256 unsigned char chap_n[MAX_CHAP_N_SIZE], chap_r[MAX_RESPONSE_LENGTH];
0257 size_t compare_len;
0258 struct iscsi_chap *chap = conn->auth_protocol;
0259 struct crypto_shash *tfm = NULL;
0260 struct shash_desc *desc = NULL;
0261 int auth_ret = -1, ret, initiatorchg_len;
0262
0263 digest = kzalloc(chap->digest_size, GFP_KERNEL);
0264 if (!digest) {
0265 pr_err("Unable to allocate the digest buffer\n");
0266 goto out;
0267 }
0268
0269 response = kzalloc(chap->digest_size * 2 + 2, GFP_KERNEL);
0270 if (!response) {
0271 pr_err("Unable to allocate the response buffer\n");
0272 goto out;
0273 }
0274
0275 client_digest = kzalloc(chap->digest_size, GFP_KERNEL);
0276 if (!client_digest) {
0277 pr_err("Unable to allocate the client_digest buffer\n");
0278 goto out;
0279 }
0280
0281 server_digest = kzalloc(chap->digest_size, GFP_KERNEL);
0282 if (!server_digest) {
0283 pr_err("Unable to allocate the server_digest buffer\n");
0284 goto out;
0285 }
0286
0287 memset(identifier, 0, 10);
0288 memset(chap_n, 0, MAX_CHAP_N_SIZE);
0289 memset(chap_r, 0, MAX_RESPONSE_LENGTH);
0290
0291 initiatorchg = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
0292 if (!initiatorchg) {
0293 pr_err("Unable to allocate challenge buffer\n");
0294 goto out;
0295 }
0296
0297 initiatorchg_binhex = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
0298 if (!initiatorchg_binhex) {
0299 pr_err("Unable to allocate initiatorchg_binhex buffer\n");
0300 goto out;
0301 }
0302
0303
0304
0305 if (extract_param(nr_in_ptr, "CHAP_N", MAX_CHAP_N_SIZE, chap_n,
0306 &type) < 0) {
0307 pr_err("Could not find CHAP_N.\n");
0308 goto out;
0309 }
0310 if (type == HEX) {
0311 pr_err("Could not find CHAP_N.\n");
0312 goto out;
0313 }
0314
0315
0316 compare_len = strlen(auth->userid) + 1;
0317 if (strncmp(chap_n, auth->userid, compare_len) != 0) {
0318 pr_err("CHAP_N values do not match!\n");
0319 goto out;
0320 }
0321 pr_debug("[server] Got CHAP_N=%s\n", chap_n);
0322
0323
0324
0325 if (extract_param(nr_in_ptr, "CHAP_R", MAX_RESPONSE_LENGTH, chap_r,
0326 &type) < 0) {
0327 pr_err("Could not find CHAP_R.\n");
0328 goto out;
0329 }
0330
0331 switch (type) {
0332 case HEX:
0333 if (strlen(chap_r) != chap->digest_size * 2) {
0334 pr_err("Malformed CHAP_R\n");
0335 goto out;
0336 }
0337 if (hex2bin(client_digest, chap_r, chap->digest_size) < 0) {
0338 pr_err("Malformed CHAP_R: invalid HEX\n");
0339 goto out;
0340 }
0341 break;
0342 case BASE64:
0343 if (chap_base64_decode(client_digest, chap_r, strlen(chap_r)) !=
0344 chap->digest_size) {
0345 pr_err("Malformed CHAP_R: invalid BASE64\n");
0346 goto out;
0347 }
0348 break;
0349 default:
0350 pr_err("Could not find CHAP_R\n");
0351 goto out;
0352 }
0353
0354 pr_debug("[server] Got CHAP_R=%s\n", chap_r);
0355
0356 tfm = crypto_alloc_shash(chap->digest_name, 0, 0);
0357 if (IS_ERR(tfm)) {
0358 tfm = NULL;
0359 pr_err("Unable to allocate struct crypto_shash\n");
0360 goto out;
0361 }
0362
0363 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
0364 if (!desc) {
0365 pr_err("Unable to allocate struct shash_desc\n");
0366 goto out;
0367 }
0368
0369 desc->tfm = tfm;
0370
0371 ret = crypto_shash_init(desc);
0372 if (ret < 0) {
0373 pr_err("crypto_shash_init() failed\n");
0374 goto out;
0375 }
0376
0377 ret = crypto_shash_update(desc, &chap->id, 1);
0378 if (ret < 0) {
0379 pr_err("crypto_shash_update() failed for id\n");
0380 goto out;
0381 }
0382
0383 ret = crypto_shash_update(desc, (char *)&auth->password,
0384 strlen(auth->password));
0385 if (ret < 0) {
0386 pr_err("crypto_shash_update() failed for password\n");
0387 goto out;
0388 }
0389
0390 ret = crypto_shash_finup(desc, chap->challenge,
0391 chap->challenge_len, server_digest);
0392 if (ret < 0) {
0393 pr_err("crypto_shash_finup() failed for challenge\n");
0394 goto out;
0395 }
0396
0397 bin2hex(response, server_digest, chap->digest_size);
0398 pr_debug("[server] %s Server Digest: %s\n",
0399 chap->digest_name, response);
0400
0401 if (memcmp(server_digest, client_digest, chap->digest_size) != 0) {
0402 pr_debug("[server] %s Digests do not match!\n\n",
0403 chap->digest_name);
0404 goto out;
0405 } else
0406 pr_debug("[server] %s Digests match, CHAP connection"
0407 " successful.\n\n", chap->digest_name);
0408
0409
0410
0411
0412 if (!auth->authenticate_target) {
0413 auth_ret = 0;
0414 goto out;
0415 }
0416
0417
0418
0419 ret = extract_param(nr_in_ptr, "CHAP_I", 10, identifier, &type);
0420 if (ret == -ENOENT) {
0421 pr_debug("Could not find CHAP_I. Initiator uses One way authentication.\n");
0422 auth_ret = 0;
0423 goto out;
0424 }
0425 if (ret < 0) {
0426 pr_err("Could not find CHAP_I.\n");
0427 goto out;
0428 }
0429
0430 if (type == HEX)
0431 ret = kstrtoul(&identifier[2], 0, &id);
0432 else
0433 ret = kstrtoul(identifier, 0, &id);
0434
0435 if (ret < 0) {
0436 pr_err("kstrtoul() failed for CHAP identifier: %d\n", ret);
0437 goto out;
0438 }
0439 if (id > 255) {
0440 pr_err("chap identifier: %lu greater than 255\n", id);
0441 goto out;
0442 }
0443
0444
0445
0446 pr_debug("[server] Got CHAP_I=%lu\n", id);
0447
0448
0449
0450 if (extract_param(nr_in_ptr, "CHAP_C", CHAP_CHALLENGE_STR_LEN,
0451 initiatorchg, &type) < 0) {
0452 pr_err("Could not find CHAP_C.\n");
0453 goto out;
0454 }
0455
0456 switch (type) {
0457 case HEX:
0458 initiatorchg_len = DIV_ROUND_UP(strlen(initiatorchg), 2);
0459 if (!initiatorchg_len) {
0460 pr_err("Unable to convert incoming challenge\n");
0461 goto out;
0462 }
0463 if (initiatorchg_len > 1024) {
0464 pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
0465 goto out;
0466 }
0467
0468 if (hex2bin(initiatorchg_binhex, initiatorchg,
0469 initiatorchg_len) < 0) {
0470 pr_err("Malformed CHAP_C: invalid HEX\n");
0471 goto out;
0472 }
0473 break;
0474 case BASE64:
0475 initiatorchg_len = chap_base64_decode(initiatorchg_binhex,
0476 initiatorchg,
0477 strlen(initiatorchg));
0478 if (initiatorchg_len < 0) {
0479 pr_err("Malformed CHAP_C: invalid BASE64\n");
0480 goto out;
0481 }
0482 if (!initiatorchg_len) {
0483 pr_err("Unable to convert incoming challenge\n");
0484 goto out;
0485 }
0486 if (initiatorchg_len > 1024) {
0487 pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
0488 goto out;
0489 }
0490 break;
0491 default:
0492 pr_err("Could not find CHAP_C.\n");
0493 goto out;
0494 }
0495
0496 pr_debug("[server] Got CHAP_C=%s\n", initiatorchg);
0497
0498
0499
0500
0501
0502 if (initiatorchg_len == chap->challenge_len &&
0503 !memcmp(initiatorchg_binhex, chap->challenge,
0504 initiatorchg_len)) {
0505 pr_err("initiator CHAP_C matches target CHAP_C, failing"
0506 " login attempt\n");
0507 goto out;
0508 }
0509
0510
0511
0512 ret = crypto_shash_init(desc);
0513 if (ret < 0) {
0514 pr_err("crypto_shash_init() failed\n");
0515 goto out;
0516 }
0517
0518
0519 id_as_uchar = id;
0520 ret = crypto_shash_update(desc, &id_as_uchar, 1);
0521 if (ret < 0) {
0522 pr_err("crypto_shash_update() failed for id\n");
0523 goto out;
0524 }
0525
0526 ret = crypto_shash_update(desc, auth->password_mutual,
0527 strlen(auth->password_mutual));
0528 if (ret < 0) {
0529 pr_err("crypto_shash_update() failed for"
0530 " password_mutual\n");
0531 goto out;
0532 }
0533
0534
0535
0536 ret = crypto_shash_finup(desc, initiatorchg_binhex, initiatorchg_len,
0537 digest);
0538 if (ret < 0) {
0539 pr_err("crypto_shash_finup() failed for ma challenge\n");
0540 goto out;
0541 }
0542
0543
0544
0545
0546 *nr_out_len = sprintf(nr_out_ptr, "CHAP_N=%s", auth->userid_mutual);
0547 *nr_out_len += 1;
0548 pr_debug("[server] Sending CHAP_N=%s\n", auth->userid_mutual);
0549
0550
0551
0552 bin2hex(response, digest, chap->digest_size);
0553 *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
0554 response);
0555 *nr_out_len += 1;
0556 pr_debug("[server] Sending CHAP_R=0x%s\n", response);
0557 auth_ret = 0;
0558 out:
0559 kfree_sensitive(desc);
0560 if (tfm)
0561 crypto_free_shash(tfm);
0562 kfree(initiatorchg);
0563 kfree(initiatorchg_binhex);
0564 kfree(digest);
0565 kfree(response);
0566 kfree(server_digest);
0567 kfree(client_digest);
0568 return auth_ret;
0569 }
0570
0571 u32 chap_main_loop(
0572 struct iscsit_conn *conn,
0573 struct iscsi_node_auth *auth,
0574 char *in_text,
0575 char *out_text,
0576 int *in_len,
0577 int *out_len)
0578 {
0579 struct iscsi_chap *chap = conn->auth_protocol;
0580
0581 if (!chap) {
0582 chap = chap_server_open(conn, auth, in_text, out_text, out_len);
0583 if (!chap)
0584 return 2;
0585 chap->chap_state = CHAP_STAGE_SERVER_AIC;
0586 return 0;
0587 } else if (chap->chap_state == CHAP_STAGE_SERVER_AIC) {
0588 convert_null_to_semi(in_text, *in_len);
0589 if (chap_server_compute_hash(conn, auth, in_text, out_text,
0590 out_len) < 0) {
0591 chap_close(conn);
0592 return 2;
0593 }
0594 if (auth->authenticate_target)
0595 chap->chap_state = CHAP_STAGE_SERVER_NR;
0596 else
0597 *out_len = 0;
0598 chap_close(conn);
0599 return 1;
0600 }
0601
0602 return 2;
0603 }