21 #include <linux/kernel.h>
22 #include <linux/string.h>
31 static int chap_string_to_hex(
unsigned char *
dst,
unsigned char *
src,
int len)
37 pr_debug(
"CHAP string contains non hex digit symbols\n");
43 static void chap_binaryhex_to_asciihex(
char *dst,
char *src,
int src_len)
47 for (i = 0; i < src_len; i++) {
48 sprintf(&dst[i*2],
"%02x", (
int) src[i] & 0xff);
52 static void chap_set_random(
char *
data,
int length)
66 n = (n << 3) | (r & 0x7);
71 n = (n << 2) | (r & 0x3);
78 static void chap_gen_challenge(
90 chap_binaryhex_to_asciihex(challenge_asciihex, chap->
challenge,
95 *c_len +=
sprintf(c_str + *c_len,
"CHAP_C=0x%s", challenge_asciihex);
98 pr_debug(
"[%s] Sending CHAP_C=0x%s\n\n", (caller) ?
"server" :
"client",
108 unsigned int *aic_len)
114 pr_err(
"CHAP user or password not set for"
127 if (
strncmp(a_str,
"CHAP_A=5", 8)) {
128 pr_err(
"CHAP_A is not MD5.\n");
131 pr_debug(
"[server] Got CHAP_A=5\n");
135 *aic_len =
sprintf(aic_str,
"CHAP_A=5");
143 *aic_len +=
sprintf(aic_str + *aic_len,
"CHAP_I=%d", chap->
id);
145 pr_debug(
"[server] Sending CHAP_I=%d\n", chap->
id);
149 chap_gen_challenge(conn, 1, aic_str, aic_len);
154 static void chap_close(
struct iscsi_conn *conn)
160 static int chap_server_compute_md5(
165 unsigned int *nr_out_len)
172 unsigned char *challenge_binhex =
NULL;
180 int auth_ret = -1,
ret, challenge_len;
182 memset(identifier, 0, 10);
192 pr_err(
"Unable to allocate challenge buffer\n");
197 if (!challenge_binhex) {
198 pr_err(
"Unable to allocate challenge_binhex buffer\n");
206 pr_err(
"Could not find CHAP_N.\n");
210 pr_err(
"Could not find CHAP_N.\n");
215 pr_err(
"CHAP_N values do not match!\n");
218 pr_debug(
"[server] Got CHAP_N=%s\n", chap_n);
224 pr_err(
"Could not find CHAP_R.\n");
228 pr_err(
"Could not find CHAP_R.\n");
232 pr_debug(
"[server] Got CHAP_R=%s\n", chap_r);
233 chap_string_to_hex(client_digest, chap_r,
strlen(chap_r));
237 pr_err(
"Unable to allocate struct crypto_hash\n");
245 pr_err(
"crypto_hash_init() failed\n");
246 crypto_free_hash(tfm);
253 pr_err(
"crypto_hash_update() failed for id\n");
254 crypto_free_hash(tfm);
261 pr_err(
"crypto_hash_update() failed for password\n");
262 crypto_free_hash(tfm);
269 pr_err(
"crypto_hash_update() failed for challenge\n");
270 crypto_free_hash(tfm);
274 ret = crypto_hash_final(&
desc, server_digest);
276 pr_err(
"crypto_hash_final() failed for server digest\n");
277 crypto_free_hash(tfm);
280 crypto_free_hash(tfm);
283 pr_debug(
"[server] MD5 Server Digest: %s\n", response);
286 pr_debug(
"[server] MD5 Digests do not match!\n\n");
289 pr_debug(
"[server] MD5 Digests match, CHAP connetication"
297 kfree(challenge_binhex);
303 if (
extract_param(nr_in_ptr,
"CHAP_I", 10, identifier, &type) < 0) {
304 pr_err(
"Could not find CHAP_I.\n");
313 pr_err(
"chap identifier: %lu greater than 255\n",
id);
319 pr_debug(
"[server] Got CHAP_I=%lu\n",
id);
324 challenge, &type) < 0) {
325 pr_err(
"Could not find CHAP_C.\n");
330 pr_err(
"Could not find CHAP_C.\n");
333 pr_debug(
"[server] Got CHAP_C=%s\n", challenge);
334 challenge_len = chap_string_to_hex(challenge_binhex, challenge,
336 if (!challenge_len) {
337 pr_err(
"Unable to convert incoming challenge\n");
345 pr_err(
"Unable to allocate struct crypto_hash\n");
353 pr_err(
"crypto_hash_init() failed\n");
354 crypto_free_hash(tfm);
361 pr_err(
"crypto_hash_update() failed for id\n");
362 crypto_free_hash(tfm);
370 pr_err(
"crypto_hash_update() failed for"
371 " password_mutual\n");
372 crypto_free_hash(tfm);
379 ret = crypto_hash_update(&
desc, &
sg, challenge_len);
381 pr_err(
"crypto_hash_update() failed for ma challenge\n");
382 crypto_free_hash(tfm);
386 ret = crypto_hash_final(&
desc, digest);
388 pr_err(
"crypto_hash_final() failed for ma digest\n");
389 crypto_free_hash(tfm);
392 crypto_free_hash(tfm);
403 *nr_out_len +=
sprintf(nr_out_ptr + *nr_out_len,
"CHAP_R=0x%s",
406 pr_debug(
"[server] Sending CHAP_R=0x%s\n", response);
410 kfree(challenge_binhex);
414 static int chap_got_response(
419 unsigned int *nr_out_len)
425 if (chap_server_compute_md5(conn, auth, nr_in_ptr,
426 nr_out_ptr, nr_out_len) < 0)
430 pr_err(
"Unknown CHAP digest type %d!\n",
447 chap = chap_server_open(conn, auth, in_text, out_text, out_len);
454 if (chap_got_response(conn, auth, in_text, out_text,