1/*	$NetBSD: iscsi_text.c,v 1.15 2024/02/08 19:44:08 andvar Exp $	*/
2
3/*-
4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "iscsi_globals.h"
33#include "base64.h"
34#include <sys/md5.h>
35#include <sys/cprng.h>
36
37#define isdigit(x) ((x) >= '0' && (x) <= '9')
38#define toupper(x) ((x) & ~0x20)
39
40/*****************************************************************************/
41
42#define MAX_STRING   255	/* Maximum length of parameter value */
43#define MAX_LIST     4		/* Maximum number of list elements we'll ever send */
44
45/* Maximum number of negotiation parameters in the operational negotiation phase */
46/* 48 should be more than enough even with the target defining its own keys */
47#define MAX_NEG      48
48
49#define CHAP_CHALLENGE_LEN    32	/* Number of bytes to send in challenge */
50#define CHAP_MD5_SIZE         16	/* Number of bytes in MD5 hash */
51
52/*****************************************************************************/
53
54/* authentication states */
55
56typedef enum
57{
58	AUTH_INITIAL,				/* sending choice of algorithms */
59	AUTH_METHOD_SELECTED,		/* received choice, sending first parameter */
60	/* from here it's alg dependent */
61	AUTH_CHAP_ALG_SENT,			/* CHAP: Algorithm selected */
62	AUTH_CHAP_RSP_SENT,			/* CHAP: Response sent */
63	/* for all algorithms */
64	AUTH_DONE					/* in parameter negotiation stage */
65} auth_state_t;
66
67
68/* enumeration of all the keys we know, and a place for the ones we don't */
69
70typedef enum
71{
72	K_AuthMethod,
73	K_Auth_CHAP_Algorithm,
74	K_Auth_CHAP_Challenge,
75	K_Auth_CHAP_Identifier,
76	K_Auth_CHAP_Name,
77	K_Auth_CHAP_Response,
78	K_DataDigest,
79	K_DataPDUInOrder,
80	K_DataSequenceInOrder,
81	K_DefaultTime2Retain,
82	K_DefaultTime2Wait,
83	K_ErrorRecoveryLevel,
84	K_FirstBurstLength,
85	K_HeaderDigest,
86	K_IFMarker,
87	K_IFMarkInt,
88	K_ImmediateData,
89	K_InitialR2T,
90	K_InitiatorAlias,
91	K_InitiatorName,
92	K_MaxBurstLength,
93	K_MaxConnections,
94	K_MaxOutstandingR2T,
95	K_MaxRecvDataSegmentLength,
96	K_OFMarker,
97	K_OFMarkInt,
98	K_SendTargets,
99	K_SessionType,
100	K_TargetAddress,
101	K_TargetAlias,
102	K_TargetName,
103	K_TargetPortalGroupTag,
104	K_NotUnderstood
105} text_key_t;
106
107/* maximum known key */
108#define MAX_KEY   K_TargetPortalGroupTag
109
110/* value types */
111typedef enum
112{						/* Value is... */
113	T_NUM,					/* numeric */
114	T_BIGNUM,				/* large numeric */
115	T_STRING,				/* string */
116	T_YESNO,				/* boolean (Yes or No) */
117	T_AUTH,					/* authentication type (CHAP or None for now) */
118	T_DIGEST,				/* digest (None or CRC32C) */
119	T_RANGE,				/* numeric range */
120	T_SENDT,				/* send target options (ALL, target-name, empty) */
121	T_SESS					/* session type (Discovery or Normal) */
122} val_kind_t;
123
124
125/* table of negotiation key strings with value type and default */
126
127typedef struct
128{
129	const uint8_t *name;				/* the key name */
130	val_kind_t val;				/* the value type */
131	uint32_t defval;			/* default value */
132} key_entry_t;
133
134STATIC key_entry_t entries[] = {
135	{"AuthMethod", T_AUTH, 0},
136	{"CHAP_A", T_NUM, ISCSI_CHAP_MD5},
137	{"CHAP_C", T_BIGNUM, 0},
138	{"CHAP_I", T_NUM, 0},
139	{"CHAP_N", T_STRING, 0},
140	{"CHAP_R", T_BIGNUM, 0},
141	{"DataDigest", T_DIGEST, 0},
142	{"DataPDUInOrder", T_YESNO, 1},
143	{"DataSequenceInOrder", T_YESNO, 1},
144	{"DefaultTime2Retain", T_NUM, 20},
145	{"DefaultTime2Wait", T_NUM, 2},
146	{"ErrorRecoveryLevel", T_NUM, 0},
147	{"FirstBurstLength", T_NUM, 64 * 1024},
148	{"HeaderDigest", T_DIGEST, 0},
149	{"IFMarker", T_YESNO, 0},
150	{"IFMarkInt", T_RANGE, 2048},
151	{"ImmediateData", T_YESNO, 1},
152	{"InitialR2T", T_YESNO, 1},
153	{"InitiatorAlias", T_STRING, 0},
154	{"InitiatorName", T_STRING, 0},
155	{"MaxBurstLength", T_NUM, 256 * 1024},
156	{"MaxConnections", T_NUM, 1},
157	{"MaxOutstandingR2T", T_NUM, 1},
158	{"MaxRecvDataSegmentLength", T_NUM, 8192},
159	{"OFMarker", T_YESNO, 0},
160	{"OFMarkInt", T_RANGE, 2048},
161	{"SendTargets", T_SENDT, 0},
162	{"SessionType", T_SESS, 0},
163	{"TargetAddress", T_STRING, 0},
164	{"TargetAlias", T_STRING, 0},
165	{"TargetName", T_STRING, 0},
166	{"TargetPortalGroupTag", T_NUM, 0},
167	{NULL, T_STRING, 0}
168};
169
170/* a negotiation parameter: key and values (there may be more than 1 for lists) */
171typedef struct
172{
173	text_key_t key;		/* the key */
174	int list_num;		/* number of elements in list, doubles as */
175				/* data size for large numeric values */
176	bool hex_bignums;	/* whether to encode in hex or base64 */
177	union
178	{
179		uint32_t nval[MAX_LIST];/* numeric or enumeration values */
180		uint8_t *sval;		/* string or data pointer */
181	} val;
182} negotiation_parameter_t;
183
184
185/* Negotiation state flags */
186#define NS_SENT      0x01		/* key was sent to target */
187#define NS_RECEIVED  0x02		/* key was received from target */
188
189typedef struct
190{
191	negotiation_parameter_t pars[MAX_NEG];	/* the parameters to send */
192	negotiation_parameter_t *cpar;			/* the last parameter set */
193	uint16_t num_pars;						/* number of parameters to send */
194	auth_state_t auth_state;				/* authentication state */
195	iscsi_auth_types_t auth_alg;			/* authentication algorithm */
196	uint8_t kflags[MAX_KEY + 2];			/* negotiation flags for each key */
197	uint8_t password[MAX_STRING + 1];		/* authentication secret */
198	uint8_t target_password[MAX_STRING + 1];	/* target authentication secret */
199	uint8_t user_name[MAX_STRING + 1];		/* authentication user ID */
200	uint8_t temp_buf[MAX_STRING + 1];		/* scratch buffer */
201
202	bool HeaderDigest;
203	bool DataDigest;
204	bool InitialR2T;
205	bool ImmediateData;
206	uint32_t ErrorRecoveryLevel;
207	uint32_t MaxRecvDataSegmentLength;
208	uint32_t MaxConnections;
209	uint32_t DefaultTime2Wait;
210	uint32_t DefaultTime2Retain;
211	uint32_t MaxBurstLength;
212	uint32_t FirstBurstLength;
213	uint32_t MaxOutstandingR2T;
214
215} negotiation_state_t;
216
217
218#define TX(state, key) (state->kflags [key] & NS_SENT)
219#define RX(state, key) (state->kflags [key] & NS_RECEIVED)
220
221/*****************************************************************************/
222
223STATIC void
224chap_md5_response(uint8_t *buffer, uint8_t identifier, uint8_t *secret,
225				  uint8_t *challenge, int challenge_size)
226{
227	MD5_CTX md5;
228
229	MD5Init(&md5);
230	MD5Update(&md5, &identifier, 1);
231	MD5Update(&md5, secret, strlen(secret));
232	MD5Update(&md5, challenge, challenge_size);
233	MD5Final(buffer, &md5);
234}
235
236/*****************************************************************************/
237
238/*
239 * hexdig:
240 *    Return value of hex digit.
241 *    Note: a null character is acceptable, and returns 0.
242 *
243 *    Parameter:
244 *          c     The character
245 *
246 *    Returns:    The value, -1 on error.
247 */
248
249static __inline int
250hexdig(uint8_t c)
251{
252
253	if (!c) {
254		return 0;
255	}
256	if (isdigit(c)) {
257		return c - '0';
258	}
259	c = toupper(c);
260	if (c >= 'A' && c <= 'F') {
261		return c - 'A' + 10;
262	}
263	return -1;
264}
265
266/*
267 * skiptozero:
268 *    Skip to next zero character in buffer.
269 *
270 *    Parameter:
271 *          buf      The buffer pointer
272 *
273 *    Returns:    The pointer to the character after the zero character.
274 */
275
276static __inline uint8_t *
277skiptozero(uint8_t *buf)
278{
279
280	while (*buf) {
281		buf++;
282	}
283	return buf + 1;
284}
285
286
287/*
288 * get_bignumval:
289 *    Get a large numeric value.
290 *    NOTE: Overwrites source string.
291 *
292 *    Parameter:
293 *          buf      The buffer pointer
294 *          par      The parameter
295 *
296 *    Returns:    The pointer to the next parameter, NULL on error.
297 */
298
299STATIC uint8_t *
300get_bignumval(uint8_t *buf, negotiation_parameter_t *par)
301{
302	int val;
303	char c;
304	uint8_t *dp = buf;
305
306	par->val.sval = buf;
307
308	if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
309		buf += 2;
310		while ((c = *buf) != 0x0) {
311			buf++;
312			val = (hexdig(c) << 4) | hexdig(*buf);
313			if (val < 0) {
314				return NULL;
315			}
316			*dp++ = (uint8_t) val;
317			if (*buf) {
318				buf++;
319			}
320		}
321		buf++;
322		par->list_num = dp - par->val.sval;
323		par->hex_bignums = true;
324	} else if (buf[0] == '0' && (buf[1] == 'b' || buf[1] == 'B')) {
325		buf = base64_decode(&buf[2], par->val.sval, &par->list_num);
326	} else {
327		DEBOUT(("Ill-formatted large number <%s>\n", buf));
328		return NULL;
329	}
330
331	return buf;
332}
333
334
335/*
336 * get_numval:
337 *    Get a numeric value.
338 *
339 *    Parameter:
340 *          buf      The buffer pointer
341 *          pval     The pointer to the result.
342 *          sep      Separator to next value.
343 *
344 *    Returns:    The pointer to the next parameter, NULL on error.
345 */
346
347STATIC uint8_t *
348get_numval(uint8_t *buf, uint32_t *pval, const uint8_t sep)
349{
350	uint32_t val = 0;
351	char c;
352
353	if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
354		buf += 2;
355		while (*buf && *buf != '~') {
356			int n;
357
358			if ((n = hexdig(*buf++)) < 0)
359				return NULL;
360			val = (val << 4) | n;
361		}
362	} else
363		while (*buf && *buf != '~') {
364			c = *buf++;
365			if (!isdigit(c))
366				return NULL;
367			val = val * 10 + (c - '0');
368		}
369
370	*pval = val;
371
372	return buf + 1;
373}
374
375
376/*
377 * get_range:
378 *    Get a numeric range.
379 *
380 *    Parameter:
381 *          buf      The buffer pointer
382 *          pval1    The pointer to the first result.
383 *          pval2    The pointer to the second result.
384 *
385 *    Returns:    The pointer to the next parameter, NULL on error.
386 */
387
388STATIC uint8_t *
389get_range(uint8_t *buf, uint32_t *pval1, uint32_t *pval2)
390{
391
392	if ((buf = get_numval(buf, pval1, '~')) == NULL)
393		return NULL;
394	if (!*buf)
395		return NULL;
396	if ((buf = get_numval(buf, pval2, '~')) == NULL)
397		return NULL;
398	return buf;
399}
400
401
402/*
403 * get_ynval:
404 *    Get a yes/no selection.
405 *
406 *    Parameter:
407 *          buf      The buffer pointer
408 *          pval     The pointer to the result.
409 *
410 *    Returns:    The pointer to the next parameter, NULL on error.
411 */
412
413STATIC uint8_t *
414get_ynval(uint8_t *buf, uint32_t *pval)
415{
416
417	if (strcmp(buf, "Yes") == 0)
418		*pval = 1;
419	else if (strcmp(buf, "No") == 0)
420		*pval = 0;
421	else
422		return NULL;
423
424	return skiptozero(buf);
425}
426
427
428/*
429 * get_digestval:
430 *    Get a digest selection.
431 *
432 *    Parameter:
433 *          buf      The buffer pointer
434 *          pval     The pointer to the result.
435 *
436 *    Returns:    The pointer to the next parameter, NULL on error.
437 */
438
439STATIC uint8_t *
440get_digestval(uint8_t *buf, uint32_t *pval)
441{
442
443	if (strcmp(buf, "CRC32C") == 0)
444		*pval = 1;
445	else if (strcmp(buf, "None") == 0)
446		*pval = 0;
447	else
448		return NULL;
449
450	return skiptozero(buf);
451}
452
453
454/*
455 * get_authval:
456 *    Get an authentication method.
457 *
458 *    Parameter:
459 *          buf      The buffer pointer
460 *          pval     The pointer to the result.
461 *
462 *    Returns:    The pointer to the next parameter, NULL on error.
463 */
464
465STATIC uint8_t *
466get_authval(uint8_t *buf, uint32_t *pval)
467{
468
469	if (strcmp(buf, "None") == 0)
470		*pval = ISCSI_AUTH_None;
471	else if (strcmp(buf, "CHAP") == 0)
472		*pval = ISCSI_AUTH_CHAP;
473	else if (strcmp(buf, "KRB5") == 0)
474		*pval = ISCSI_AUTH_KRB5;
475	else if (strcmp(buf, "SRP") == 0)
476		*pval = ISCSI_AUTH_SRP;
477	else
478		return NULL;
479
480	return skiptozero(buf);
481}
482
483
484/*
485 * get_strval:
486 *    Get a string value (returns pointer to original buffer, not a copy).
487 *
488 *    Parameter:
489 *          buf      The buffer pointer
490 *          pval     The pointer to the result pointer.
491 *
492 *    Returns:    The pointer to the next parameter, NULL on error.
493 */
494
495STATIC uint8_t *
496get_strval(uint8_t *buf, uint8_t **pval)
497{
498
499	if (strlen(buf) > MAX_STRING)
500		return NULL;
501
502	*pval = buf;
503
504	return skiptozero(buf);
505}
506
507
508/*
509 * get_parameter:
510 *    Analyze a key=value string.
511 *    NOTE: The string is modified in the process.
512 *
513 *    Parameter:
514 *          buf      The buffer pointer
515 *          par      The parameter descriptor to be filled in
516 *
517 *    Returns:    The pointer to the next parameter, NULL on error.
518 */
519
520STATIC uint8_t *
521get_parameter(uint8_t *buf, negotiation_parameter_t *par)
522{
523	uint8_t *bp = buf;
524	int i;
525
526	while (*bp && *bp != '=') {
527		bp++;
528	}
529	if (!*bp) {
530		DEBOUT(("get_parameter: Premature end of parameter\n"));
531		return NULL;
532	}
533
534	*bp++ = 0;
535
536	for (i = 0; i <= MAX_KEY; i++)
537		if (!strcmp(buf, entries[i].name))
538			break;
539
540	par->key = i;
541	par->list_num = 1;
542	par->hex_bignums = false; /* set by get_bignumval */
543
544	if (i > MAX_KEY) {
545		DEBOUT(("get_parameter: unrecognized key <%s>\n", buf));
546		if (strlen(buf) > MAX_STRING) {
547			DEBOUT(("get_parameter: key name > MAX_STRING\n"));
548			return NULL;
549		}
550		par->val.sval = buf;
551		return skiptozero(bp);
552	}
553
554	DEB(10, ("get_par: key <%s>=%d, val=%d, ret %p\n",
555			buf, i, entries[i].val, bp));
556	DEB(10, ("get_par: value '%s'\n",bp));
557
558	switch (entries[i].val) {
559	case T_NUM:
560		bp = get_numval(bp, &par->val.nval[0], '\0');
561		break;
562
563	case T_BIGNUM:
564		bp = get_bignumval(bp, par);
565		break;
566
567	case T_STRING:
568		bp = get_strval(bp, &par->val.sval);
569		break;
570
571	case T_YESNO:
572		bp = get_ynval(bp, &par->val.nval[0]);
573		break;
574
575	case T_AUTH:
576		bp = get_authval(bp, &par->val.nval[0]);
577		break;
578
579	case T_DIGEST:
580		bp = get_digestval(bp, &par->val.nval[0]);
581		break;
582
583	case T_RANGE:
584		bp = get_range(bp, &par->val.nval[0], &par->val.nval[1]);
585		break;
586
587	default:
588		/* Target sending any other types is wrong */
589		bp = NULL;
590		break;
591	}
592	return bp;
593}
594
595/*****************************************************************************/
596
597/*
598 * my_strcpy:
599 *    Replacement for strcpy that returns the end of the result string
600 *
601 *    Parameter:
602 *          dest     The destination buffer pointer
603 *          src      The source string
604 *
605 *    Returns:    A pointer to the terminating zero of the result.
606 */
607
608static __inline unsigned
609my_strcpy(uint8_t *dest, const uint8_t *src)
610{
611	unsigned	cc;
612
613	for (cc = 0 ; (*dest = *src) != 0x0 ; cc++) {
614		dest++;
615		src++;
616	}
617	return cc;
618}
619
620/*
621 * put_bignumval:
622 *    Write a large numeric value.
623 *    NOTE: Overwrites source string.
624 *
625 *    Parameter:
626 *          buf      The buffer pointer
627 *          par      The parameter
628 *
629 *    Returns:    The pointer to the next parameter, NULL on error.
630 */
631
632STATIC unsigned
633put_bignumval(negotiation_parameter_t *par, uint8_t *buf)
634{
635	int k, c;
636
637	if (par->hex_bignums) {
638		my_strcpy(buf, "0x");
639		for (k=0; k<par->list_num; ++k) {
640			c = par->val.sval[k] >> 4;
641			buf[2+2*k] = c < 10 ? '0' + c : 'a' + (c-10);
642			c = par->val.sval[k] & 0xf;
643			buf[2+2*k+1] = c < 10 ? '0' + c : 'a' + (c-10);
644		}
645		buf[2+2*k] = '\0';
646
647		return 2+2*par->list_num;
648	}
649	return base64_encode(par->val.sval, par->list_num, buf);
650}
651
652/*
653 * put_parameter:
654 *    Create a key=value string.
655 *
656 *    Parameter:
657 *          buf      The buffer pointer
658 *          par      The parameter descriptor
659 *
660 *    Returns:    The pointer to the next free buffer space, NULL on error.
661 */
662
663STATIC unsigned
664put_parameter(uint8_t *buf, unsigned len, negotiation_parameter_t *par)
665{
666	int i;
667	unsigned	cc, cl;
668	const uint8_t *sp;
669
670	DEB(10, ("put_par: key <%s>=%d, val=%d\n",
671		entries[par->key].name, par->key, entries[par->key].val));
672
673	if (par->key > MAX_KEY) {
674		return snprintf(buf, len, "%s=NotUnderstood", par->val.sval);
675	}
676
677	cc = snprintf(buf, len, "%s=", entries[par->key].name);
678	if (cc >= len)
679		return len;
680
681	for (i = 0; i < par->list_num; i++) {
682		switch (entries[par->key].val) {
683		case T_NUM:
684			cl = snprintf(&buf[cc], len - cc, "%d",
685			               par->val.nval[i]);
686			break;
687
688		case T_BIGNUM:
689			cl = put_bignumval(par, &buf[cc]);
690			i = par->list_num;
691			break;
692
693		case T_STRING:
694			cl =  my_strcpy(&buf[cc], par->val.sval);
695			break;
696
697		case T_YESNO:
698			cl = my_strcpy(&buf[cc],
699				(par->val.nval[i]) ? "Yes" : "No");
700			break;
701
702		case T_AUTH:
703			switch (par->val.nval[i]) {
704			case ISCSI_AUTH_CHAP:
705				sp = "CHAP";
706				break;
707			case ISCSI_AUTH_KRB5:
708				sp = "KRB5";
709				break;
710			case ISCSI_AUTH_SRP:
711				sp = "SRP";
712				break;
713			default:
714				sp = "None";
715				break;
716			}
717			cl = my_strcpy(&buf[cc], sp);
718			break;
719
720		case T_DIGEST:
721			cl = my_strcpy(&buf[cc],
722				(par->val.nval[i]) ? "CRC32C" : "None");
723			break;
724
725		case T_RANGE:
726			if ((i + 1) >= par->list_num) {
727				cl = my_strcpy(&buf[cc], "Reject");
728			} else {
729				cl = snprintf(&buf[cc], len - cc,
730						"%d~%d", par->val.nval[i],
731						par->val.nval[i + 1]);
732				i++;
733			}
734			break;
735
736		case T_SENDT:
737			cl = my_strcpy(&buf[cc], par->val.sval);
738			break;
739
740		case T_SESS:
741			cl = my_strcpy(&buf[cc],
742				(par->val.nval[i]) ? "Normal" : "Discovery");
743			break;
744
745		default:
746			cl = 0;
747			/* We shouldn't be here... */
748			DEBOUT(("Invalid type %d in put_parameter!\n",
749					entries[par->key].val));
750			break;
751		}
752
753		DEB(10, ("put_par: value '%s'\n",&buf[cc]));
754
755		cc += cl;
756		if (cc >= len)
757			return len;
758		if ((i + 1) < par->list_num) {
759			if (cc >= len)
760				return len;
761			buf[cc++] = ',';
762		}
763	}
764
765	if (cc >= len)
766		return len;
767	buf[cc] = 0x0;				/* make sure it's terminated */
768	return cc + 1;				/* return next place in list */
769}
770
771
772/*
773 * put_par_block:
774 *    Fill a parameter block
775 *
776 *    Parameter:
777 *          buf      The buffer pointer
778 *          pars     The parameter descriptor array
779 *          n        The number of elements
780 *
781 *    Returns:    result from put_parameter (ptr to buffer, NULL on error)
782 */
783
784static __inline unsigned
785put_par_block(uint8_t *buf, unsigned len, negotiation_parameter_t *pars, int n)
786{
787	unsigned	cc;
788	int i;
789
790	for (cc = 0, i = 0; i < n; i++) {
791		cc += put_parameter(&buf[cc], len - cc, pars++);
792		if (cc >= len) {
793			break;
794		}
795	}
796	return cc;
797}
798
799/*
800 * parameter_size:
801 *    Determine the size of a key=value string.
802 *
803 *    Parameter:
804 *          par      The parameter descriptor
805 *
806 *    Returns:    The size of the resulting string.
807 */
808
809STATIC int
810parameter_size(negotiation_parameter_t *par)
811{
812	int i, size;
813	char buf[24];	/* max. 2 10-digit numbers + sep. */
814
815	if (par->key > MAX_KEY) {
816		return strlen(par->val.sval) + 15;
817	}
818	/* count '=' and terminal zero */
819	size = strlen(entries[par->key].name) + 2;
820
821	for (i = 0; i < par->list_num; i++) {
822		switch (entries[par->key].val) {
823		case T_NUM:
824			size += snprintf(buf, sizeof(buf), "%d",
825					par->val.nval[i]);
826			break;
827
828		case T_BIGNUM:
829			/* list_num holds value size */
830			if (par->hex_bignums)
831				size += 2 + 2*par->list_num;
832			else
833				size += base64_enclen(par->list_num);
834			i = par->list_num;
835			break;
836
837		case T_STRING:
838		case T_SENDT:
839			size += strlen(par->val.sval);
840			break;
841
842		case T_YESNO:
843			size += (par->val.nval[i]) ? 3 : 2;
844			break;
845
846		case T_AUTH:
847			size += (par->val.nval[i] == ISCSI_AUTH_SRP) ? 3 : 4;
848			break;
849
850		case T_DIGEST:
851			size += (par->val.nval[i]) ? 6 : 4;
852			break;
853
854		case T_RANGE:
855			if (i+1 < par->list_num) {
856				size += snprintf(buf, sizeof(buf), "%d~%d",
857					par->val.nval[i],
858					par->val.nval[i + 1]);
859				i++;
860			} else
861				DEBOUT(("Incomplete range parameter\n"));
862			break;
863
864		case T_SESS:
865			size += (par->val.nval[i]) ? 6 : 9;
866			break;
867
868		default:
869			/* We shouldn't be here... */
870			DEBOUT(("Invalid type %d in parameter_size!\n",
871					entries[par->key].val));
872			break;
873		}
874		if ((i + 1) < par->list_num) {
875			size++;
876		}
877	}
878
879	return size;
880}
881
882
883/*
884 * total_size:
885 *    Determine the size of a negotiation data block
886 *
887 *    Parameter:
888 *          pars     The parameter descriptor array
889 *          n        The number of elements
890 *
891 *    Returns:    The size of the block
892 */
893
894static __inline int
895total_size(negotiation_parameter_t *pars, int n)
896{
897	int i, size;
898
899	for (i = 0, size = 0; i < n; i++) {
900		size += parameter_size(pars++);
901	}
902	return size;
903}
904
905/*****************************************************************************/
906
907
908/*
909 * complete_pars:
910 *    Allocate space for text parameters, translate parameter values into
911 *    text.
912 *
913 *    Parameter:
914 *          state    Negotiation state
915 *          pdu      The transmit PDU
916 *
917 *    Returns:    0     On success
918 *                > 0   (an ISCSI error code) if an error occurred.
919 */
920
921STATIC int
922complete_pars(negotiation_state_t *state, pdu_t *pdu)
923{
924	int len;
925	uint8_t *bp;
926
927	len = total_size(state->pars, state->num_pars);
928
929	DEB(10, ("complete_pars: n=%d, len=%d\n", state->num_pars, len));
930
931	if (len == 0) {
932		pdu->pdu_temp_data = NULL;
933		pdu->pdu_temp_data_len = 0;
934		return 0;
935	}
936
937	if ((bp = malloc(len, M_TEMP, M_WAITOK)) == NULL) {
938		DEBOUT(("*** Out of memory in complete_pars\n"));
939		return ISCSI_STATUS_NO_RESOURCES;
940	}
941	pdu->pdu_temp_data = bp;
942
943	if (put_par_block(pdu->pdu_temp_data, len, state->pars,
944			state->num_pars) == 0) {
945		DEBOUT(("Bad parameter in complete_pars\n"));
946		return ISCSI_STATUS_PARAMETER_INVALID;
947	}
948
949	pdu->pdu_temp_data_len = len;
950	return 0;
951}
952
953
954/*
955 * set_key_n:
956 *    Initialize a key and its numeric value.
957 *
958 *    Parameter:
959 *          state    Negotiation state
960 *          key      The key
961 *          val      The value
962 */
963
964STATIC negotiation_parameter_t *
965set_key_n(negotiation_state_t *state, text_key_t key, uint32_t val)
966{
967	negotiation_parameter_t *par;
968
969	if (state->num_pars >= MAX_NEG) {
970		DEBOUT(("set_key_n: num_pars (%d) >= MAX_NEG (%d)\n",
971				state->num_pars, MAX_NEG));
972		return NULL;
973	}
974	par = &state->pars[state->num_pars];
975	par->key = key;
976	par->list_num = 1;
977	par->val.nval[0] = val;
978	state->num_pars++;
979	state->kflags[key] |= NS_SENT;
980
981	return par;
982}
983
984/*
985 * set_key_s:
986 *    Initialize a key and its string value.
987 *
988 *    Parameter:
989 *          state    Negotiation state
990 *          key      The key
991 *          val      The value
992 */
993
994STATIC negotiation_parameter_t *
995set_key_s(negotiation_state_t *state, text_key_t key, uint8_t *val)
996{
997	negotiation_parameter_t *par;
998
999	if (state->num_pars >= MAX_NEG) {
1000		DEBOUT(("set_key_s: num_pars (%d) >= MAX_NEG (%d)\n",
1001				state->num_pars, MAX_NEG));
1002		return NULL;
1003	}
1004	par = &state->pars[state->num_pars];
1005	par->key = key;
1006	par->list_num = 1;
1007	par->val.sval = val;
1008	par->hex_bignums = iscsi_hex_bignums;
1009	state->num_pars++;
1010	state->kflags[key] |= NS_SENT;
1011
1012	return par;
1013}
1014
1015
1016/*****************************************************************************/
1017
1018/*
1019 * eval_parameter:
1020 *    Evaluate a received negotiation value.
1021 *
1022 *    Parameter:
1023 *          conn     The connection
1024 *          state    The negotiation state
1025 *          par      The parameter
1026 *
1027 *    Returns:    0 on success, else an ISCSI status value.
1028 */
1029
1030STATIC int
1031eval_parameter(connection_t *conn, negotiation_state_t *state,
1032			   negotiation_parameter_t *par)
1033{
1034	uint32_t n = par->val.nval[0];
1035	size_t sz;
1036	text_key_t key = par->key;
1037	bool sent = (state->kflags[key] & NS_SENT) != 0;
1038
1039	state->kflags[key] |= NS_RECEIVED;
1040
1041	switch (key) {
1042		/*
1043		 *  keys connected to security negotiation
1044		 */
1045	case K_AuthMethod:
1046		if (n) {
1047			DEBOUT(("eval_par: AuthMethod nonzero (%d)\n", n));
1048			return ISCSI_STATUS_NEGOTIATION_ERROR;
1049		}
1050		break;
1051
1052	case K_Auth_CHAP_Algorithm:
1053	case K_Auth_CHAP_Challenge:
1054	case K_Auth_CHAP_Identifier:
1055	case K_Auth_CHAP_Name:
1056	case K_Auth_CHAP_Response:
1057		DEBOUT(("eval_par: Authorization Key in Operational Phase\n"));
1058		return ISCSI_STATUS_NEGOTIATION_ERROR;
1059
1060		/*
1061		 * keys we always send
1062		 */
1063	case K_DataDigest:
1064		state->DataDigest = n;
1065		if (!sent)
1066			set_key_n(state, key, n);
1067		break;
1068
1069	case K_HeaderDigest:
1070		state->HeaderDigest = n;
1071		if (!sent)
1072			set_key_n(state, key, n);
1073		break;
1074
1075	case K_ErrorRecoveryLevel:
1076		state->ErrorRecoveryLevel = n;
1077		if (!sent)
1078			set_key_n(state, key, n);
1079		break;
1080
1081	case K_ImmediateData:
1082		state->ImmediateData = n;
1083		if (!sent)
1084			set_key_n(state, key, n);
1085		break;
1086
1087	case K_InitialR2T:
1088		state->InitialR2T = n;
1089		if (!sent)
1090			set_key_n(state, key, n);
1091		break;
1092
1093	case K_MaxRecvDataSegmentLength:
1094		state->MaxRecvDataSegmentLength = n;
1095		/* this is basically declarative, not negotiated */
1096		/* (each side has its own value) */
1097		break;
1098
1099		/*
1100		 * keys we don't always send, so we may have to reflect the value
1101		 */
1102	case K_DefaultTime2Retain:
1103		state->DefaultTime2Retain = n = min(state->DefaultTime2Retain, n);
1104		if (!sent)
1105			set_key_n(state, key, n);
1106		break;
1107
1108	case K_DefaultTime2Wait:
1109		state->DefaultTime2Wait = n = min(state->DefaultTime2Wait, n);
1110		if (!sent)
1111			set_key_n(state, key, n);
1112		break;
1113
1114	case K_MaxConnections:
1115		if (state->MaxConnections)
1116			state->MaxConnections = n = min(state->MaxConnections, n);
1117		else
1118			state->MaxConnections = n;
1119
1120		if (!sent)
1121			set_key_n(state, key, n);
1122		break;
1123
1124	case K_MaxOutstandingR2T:
1125		state->MaxOutstandingR2T = n;
1126		if (!sent)
1127			set_key_n(state, key, n);
1128		break;
1129
1130	case K_FirstBurstLength:
1131		state->FirstBurstLength = n;
1132		if (!sent)
1133			set_key_n(state, key, n);
1134		break;
1135
1136	case K_MaxBurstLength:
1137		state->MaxBurstLength = n;
1138		if (!sent)
1139			set_key_n(state, key, n);
1140		break;
1141
1142	case K_IFMarker:
1143	case K_OFMarker:
1144		/* not (yet) supported */
1145		if (!sent)
1146			set_key_n(state, key, 0);
1147		break;
1148
1149	case K_IFMarkInt:
1150	case K_OFMarkInt:
1151		/* it's a range, and list_num will be 1, so this will reply "Reject" */
1152		if (!sent)
1153			set_key_n(state, key, 0);
1154		break;
1155
1156	case K_DataPDUInOrder:
1157	case K_DataSequenceInOrder:
1158		/* values are don't care */
1159		if (!sent)
1160			set_key_n(state, key, n);
1161		break;
1162
1163	case K_NotUnderstood:
1164		/* return "NotUnderstood" */
1165		set_key_s(state, key, par->val.sval);
1166		break;
1167
1168		/*
1169		 * Declarative keys (no response required)
1170		 */
1171	case K_TargetAddress:
1172		/* ignore for now... */
1173		break;
1174
1175	case K_TargetAlias:
1176		if (conn->c_login_par->is_present.TargetAlias) {
1177			copyoutstr(par->val.sval, conn->c_login_par->TargetAlias,
1178				ISCSI_STRING_LENGTH - 1, &sz);
1179			/* do anything with return code?? */
1180		}
1181		break;
1182
1183	case K_TargetPortalGroupTag:
1184		/* ignore for now... */
1185		break;
1186
1187	default:
1188		DEBOUT(("eval_par: Invalid parameter type %d\n", par->key));
1189		return ISCSI_STATUS_NEGOTIATION_ERROR;
1190	}
1191	return 0;
1192}
1193
1194/*****************************************************************************/
1195
1196
1197/*
1198 * init_session_parameters:
1199 *    Initialize session-related negotiation parameters from existing session
1200 *
1201 *    Parameter:
1202 *          sess     The session
1203 *          state    The negotiation state
1204 */
1205
1206STATIC void
1207init_session_parameters(session_t *sess, negotiation_state_t *state)
1208{
1209
1210	state->ErrorRecoveryLevel = sess->s_ErrorRecoveryLevel;
1211	state->InitialR2T = sess->s_InitialR2T;
1212	state->ImmediateData = sess->s_ImmediateData;
1213	state->MaxConnections = sess->s_MaxConnections;
1214	state->DefaultTime2Wait = sess->s_DefaultTime2Wait;
1215	state->DefaultTime2Retain = sess->s_DefaultTime2Retain;
1216	state->MaxBurstLength = sess->s_MaxBurstLength;
1217	state->FirstBurstLength = sess->s_FirstBurstLength;
1218	state->MaxOutstandingR2T = sess->s_MaxOutstandingR2T;
1219}
1220
1221
1222
1223/*
1224 * assemble_login_parameters:
1225 *    Assemble the initial login negotiation parameters.
1226 *
1227 *    Parameter:
1228 *          conn     The connection
1229 *          ccb      The CCB for the login exchange
1230 *          pdu      The PDU to use for sending
1231 *
1232 *    Returns:    < 0   if more security negotiation is required
1233 *                0     if this is the last security negotiation block
1234 *                > 0   (an ISCSI error code) if an error occurred.
1235 */
1236
1237int
1238assemble_login_parameters(connection_t *conn, ccb_t *ccb, pdu_t *pdu)
1239{
1240	iscsi_login_parameters_t *par = conn->c_login_par;
1241	size_t sz;
1242	int rc, i, next;
1243	negotiation_state_t *state;
1244	negotiation_parameter_t *cpar;
1245
1246	state = malloc(sizeof(*state), M_TEMP, M_WAITOK | M_ZERO);
1247	if (state == NULL) {
1248		DEBOUT(("*** Out of memory in assemble_login_params\n"));
1249		return ISCSI_STATUS_NO_RESOURCES;
1250	}
1251	ccb->ccb_temp_data = state;
1252
1253	if (!iscsi_InitiatorName[0]) {
1254		DEBOUT(("No InitiatorName\n"));
1255		return ISCSI_STATUS_PARAMETER_MISSING;
1256	}
1257	set_key_s(state, K_InitiatorName, iscsi_InitiatorName);
1258
1259	if (iscsi_InitiatorAlias[0])
1260		set_key_s(state, K_InitiatorAlias, iscsi_InitiatorAlias);
1261
1262	conn->c_Our_MaxRecvDataSegmentLength =
1263		(par->is_present.MaxRecvDataSegmentLength)
1264		? par->MaxRecvDataSegmentLength : DEFAULT_MaxRecvDataSegmentLength;
1265
1266	/* setup some values for authentication */
1267	if (par->is_present.password)
1268		copyinstr(par->password, state->password, MAX_STRING, &sz);
1269	if (par->is_present.target_password)
1270		copyinstr(par->target_password, state->target_password,
1271			MAX_STRING, &sz);
1272	if (par->is_present.user_name)
1273		copyinstr(par->user_name, state->user_name, MAX_STRING, &sz);
1274	else
1275		strlcpy(state->user_name, iscsi_InitiatorName,
1276			sizeof(state->user_name));
1277
1278	next = TRUE;
1279
1280	set_key_n(state, K_SessionType,
1281			  par->login_type > ISCSI_LOGINTYPE_DISCOVERY);
1282
1283	cpar = set_key_n(state, K_AuthMethod, ISCSI_AUTH_None);
1284
1285	if (cpar != NULL && par->is_present.auth_info &&
1286		par->auth_info.auth_number > 0) {
1287		if (par->auth_info.auth_number > ISCSI_AUTH_OPTIONS) {
1288			DEBOUT(("Auth number too big in asm_login\n"));
1289			return ISCSI_STATUS_PARAMETER_INVALID;
1290		}
1291		cpar->list_num = par->auth_info.auth_number;
1292		for (i = 0; i < cpar->list_num; i++) {
1293			cpar->val.nval[i] = par->auth_info.auth_type[i];
1294			if (par->auth_info.auth_type[i])
1295				next = FALSE;
1296		}
1297	}
1298
1299	if (par->is_present.TargetName)
1300		copyinstr(par->TargetName, state->temp_buf, ISCSI_STRING_LENGTH - 1,
1301				  &sz);
1302	else {
1303		state->temp_buf[0] = 0;
1304		sz = 0;
1305	}
1306
1307	if ((!sz || !state->temp_buf[0]) &&
1308		par->login_type != ISCSI_LOGINTYPE_DISCOVERY) {
1309		DEBOUT(("No TargetName\n"));
1310		return ISCSI_STATUS_PARAMETER_MISSING;
1311	}
1312
1313	if (state->temp_buf[0]) {
1314		set_key_s(state, K_TargetName, state->temp_buf);
1315	}
1316
1317	if ((rc = complete_pars(state, pdu)) != 0)
1318		return rc;
1319
1320	return (next) ? 0 : -1;
1321}
1322
1323/*
1324 * assemble_security_parameters:
1325 *    Assemble the security negotiation parameters.
1326 *
1327 *    Parameter:
1328 *          conn     The connection
1329 *          rx_pdu   The received login response PDU
1330 *          tx_pdu   The transmit PDU
1331 *
1332 *    Returns:    < 0   if more security negotiation is required
1333 *                0     if this is the last security negotiation block
1334 *                > 0   (an ISCSI error code) if an error occurred.
1335 */
1336
1337int
1338assemble_security_parameters(connection_t *conn, ccb_t *ccb, pdu_t *rx_pdu,
1339							 pdu_t *tx_pdu)
1340{
1341	negotiation_state_t *state = (negotiation_state_t *) ccb->ccb_temp_data;
1342	iscsi_login_parameters_t *par = conn->c_login_par;
1343	negotiation_parameter_t rxp, *cpar;
1344	uint8_t *rxpars;
1345	int rc, next;
1346	uint8_t identifier = 0;
1347	uint8_t *challenge = NULL;
1348	int challenge_size = 0;
1349	uint8_t *response = NULL;
1350	int response_size = 0;
1351	bool challenge_hex = iscsi_hex_bignums;
1352
1353	state->num_pars = 0;
1354	next = 0;
1355
1356	rxpars = (uint8_t *) rx_pdu->pdu_temp_data;
1357	if (rxpars == NULL) {
1358		DEBOUT(("No received parameters!\n"));
1359		return ISCSI_STATUS_NEGOTIATION_ERROR;
1360	}
1361	/* Note: There are always at least 2 extra bytes past temp_data_len */
1362	rxpars[rx_pdu->pdu_temp_data_len] = '\0';
1363	rxpars[rx_pdu->pdu_temp_data_len + 1] = '\0';
1364
1365	while (*rxpars) {
1366		if ((rxpars = get_parameter(rxpars, &rxp)) == NULL) {
1367			DEBOUT(("get_parameter returned error\n"));
1368			return ISCSI_STATUS_NEGOTIATION_ERROR;
1369		}
1370
1371		state->kflags[rxp.key] |= NS_RECEIVED;
1372
1373		switch (rxp.key) {
1374		case K_AuthMethod:
1375			if (state->auth_state != AUTH_INITIAL) {
1376				DEBOUT(("AuthMethod received, auth_state = %d\n",
1377						state->auth_state));
1378				return ISCSI_STATUS_NEGOTIATION_ERROR;
1379			}
1380
1381			/* Note: if the selection is None, we shouldn't be here,
1382			 * the target should have transited the state to op-neg.
1383			 */
1384			if (rxp.val.nval[0] != ISCSI_AUTH_CHAP) {
1385				DEBOUT(("AuthMethod isn't CHAP (%d)\n", rxp.val.nval[0]));
1386				return ISCSI_STATUS_NEGOTIATION_ERROR;
1387			}
1388
1389			state->auth_state = AUTH_METHOD_SELECTED;
1390			state->auth_alg = rxp.val.nval[0];
1391			break;
1392
1393		case K_Auth_CHAP_Algorithm:
1394			if (state->auth_state != AUTH_CHAP_ALG_SENT ||
1395			    rxp.val.nval[0] != ISCSI_CHAP_MD5) {
1396				DEBOUT(("Bad algorithm, auth_state = %d, alg %d\n",
1397						state->auth_state, rxp.val.nval[0]));
1398				return ISCSI_STATUS_NEGOTIATION_ERROR;
1399			}
1400			break;
1401
1402		case K_Auth_CHAP_Challenge:
1403			if (state->auth_state != AUTH_CHAP_ALG_SENT || !rxp.list_num) {
1404				DEBOUT(("Bad Challenge, auth_state = %d, len %d\n",
1405						state->auth_state, rxp.list_num));
1406				return ISCSI_STATUS_NEGOTIATION_ERROR;
1407			}
1408			challenge = rxp.val.sval;
1409			challenge_size = rxp.list_num;
1410			/* respond in the same format as the challenge */
1411			challenge_hex = rxp.hex_bignums;
1412			break;
1413
1414		case K_Auth_CHAP_Identifier:
1415			if (state->auth_state != AUTH_CHAP_ALG_SENT) {
1416				DEBOUT(("Bad ID, auth_state = %d, id %d\n",
1417						state->auth_state, rxp.val.nval[0]));
1418				return ISCSI_STATUS_NEGOTIATION_ERROR;
1419			}
1420			identifier = (uint8_t) rxp.val.nval[0];
1421			break;
1422
1423		case K_Auth_CHAP_Name:
1424			if (state->auth_state != AUTH_CHAP_RSP_SENT) {
1425				DEBOUT(("Bad Name, auth_state = %d, name <%s>\n",
1426						state->auth_state, rxp.val.sval));
1427				return ISCSI_STATUS_NEGOTIATION_ERROR;
1428			}
1429			/* what do we do with the name?? */
1430			break;
1431
1432		case K_Auth_CHAP_Response:
1433			if (state->auth_state != AUTH_CHAP_RSP_SENT) {
1434				DEBOUT(("Bad Response, auth_state = %d, size %d\n",
1435						state->auth_state, rxp.list_num));
1436				return ISCSI_STATUS_NEGOTIATION_ERROR;
1437			}
1438			response = rxp.val.sval;
1439			response_size = rxp.list_num;
1440			if (response_size != CHAP_MD5_SIZE) {
1441				DEBOUT(("CHAP Response, bad size %d\n",
1442						response_size));
1443				return ISCSI_STATUS_NEGOTIATION_ERROR;
1444			}
1445			break;
1446
1447		default:
1448			rc = eval_parameter(conn, state, &rxp);
1449			if (rc)
1450				return rc;
1451			break;
1452		}
1453	}
1454
1455	switch (state->auth_state) {
1456	case AUTH_INITIAL:
1457		DEBOUT(("Didn't receive Method\n"));
1458		return ISCSI_STATUS_NEGOTIATION_ERROR;
1459
1460	case AUTH_METHOD_SELECTED:
1461		set_key_n(state, K_Auth_CHAP_Algorithm, ISCSI_CHAP_MD5);
1462		state->auth_state = AUTH_CHAP_ALG_SENT;
1463		next = -1;
1464		break;
1465
1466	case AUTH_CHAP_ALG_SENT:
1467		if (!RX(state, K_Auth_CHAP_Algorithm) ||
1468			!RX(state, K_Auth_CHAP_Identifier) ||
1469			!RX(state, K_Auth_CHAP_Challenge)) {
1470			DEBOUT(("Didn't receive all parameters\n"));
1471			return ISCSI_STATUS_NEGOTIATION_ERROR;
1472		}
1473
1474		set_key_s(state, K_Auth_CHAP_Name, state->user_name);
1475
1476		chap_md5_response(state->temp_buf, identifier,
1477		    state->password, challenge, challenge_size);
1478
1479		cpar = set_key_s(state, K_Auth_CHAP_Response, state->temp_buf);
1480		if (cpar != NULL) {
1481			cpar->list_num = CHAP_MD5_SIZE;
1482			/* respond in same format as challenge */
1483			cpar->hex_bignums = challenge_hex;
1484		}
1485
1486		if (par->auth_info.mutual_auth) {
1487			if (!state->target_password[0]) {
1488				DEBOUT(("No target password with mutual authentication!\n"));
1489				return ISCSI_STATUS_PARAMETER_MISSING;
1490			}
1491
1492			cprng_strong(kern_cprng,
1493				     &state->temp_buf[CHAP_MD5_SIZE],
1494				     CHAP_CHALLENGE_LEN + 1, 0);
1495			set_key_n(state, K_Auth_CHAP_Identifier,
1496					  state->temp_buf[CHAP_MD5_SIZE]);
1497			cpar = set_key_s(state, K_Auth_CHAP_Challenge,
1498							 &state->temp_buf[CHAP_MD5_SIZE + 1]);
1499			if (cpar != NULL) {
1500				cpar->list_num = CHAP_CHALLENGE_LEN;
1501				/* use same format as target challenge */
1502				cpar->hex_bignums = challenge_hex;
1503			}
1504
1505			/* transitional state */
1506			conn->c_state = ST_SEC_FIN;
1507		}
1508		state->auth_state = AUTH_CHAP_RSP_SENT;
1509		break;
1510
1511	case AUTH_CHAP_RSP_SENT:
1512		/* we can only be here for mutual authentication */
1513		if (!par->auth_info.mutual_auth || response == NULL) {
1514			DEBOUT(("Mutual authentication not requested\n"));
1515			return ISCSI_STATUS_NEGOTIATION_ERROR;
1516		}
1517
1518		chap_md5_response(state->temp_buf,
1519			state->temp_buf[CHAP_MD5_SIZE],
1520			state->target_password,
1521			&state->temp_buf[CHAP_MD5_SIZE + 1],
1522			CHAP_CHALLENGE_LEN);
1523
1524		if (response_size > sizeof(state->temp_buf) ||
1525		    memcmp(state->temp_buf, response, response_size)) {
1526			DEBOUT(("Mutual authentication mismatch\n"));
1527			return ISCSI_STATUS_AUTHENTICATION_FAILED;
1528		}
1529		break;
1530
1531	default:
1532		break;
1533	}
1534
1535	complete_pars(state, tx_pdu);
1536
1537	return next;
1538}
1539
1540
1541/*
1542 * set_first_opnegs:
1543 *    Set the operational negotiation parameters we want to negotiate in
1544 *    the first login request in op_neg phase.
1545 *
1546 *    Parameter:
1547 *          conn     The connection
1548 *          state    Negotiation state
1549 */
1550
1551STATIC void
1552set_first_opnegs(connection_t *conn, negotiation_state_t *state)
1553{
1554	iscsi_login_parameters_t *lpar = conn->c_login_par;
1555	negotiation_parameter_t *cpar;
1556
1557	/* Digests - suggest None,CRC32C unless the user forces a value */
1558	cpar = set_key_n(state, K_HeaderDigest,
1559	    (lpar->is_present.HeaderDigest) ? lpar->HeaderDigest : 0);
1560	if (cpar != NULL && !lpar->is_present.HeaderDigest) {
1561		cpar->list_num = 2;
1562		cpar->val.nval[1] = 1;
1563	}
1564
1565	cpar = set_key_n(state, K_DataDigest, (lpar->is_present.DataDigest)
1566		? lpar->DataDigest : 0);
1567	if (cpar != NULL && !lpar->is_present.DataDigest) {
1568		cpar->list_num = 2;
1569		cpar->val.nval[1] = 1;
1570	}
1571
1572	set_key_n(state, K_MaxRecvDataSegmentLength,
1573		conn->c_Our_MaxRecvDataSegmentLength);
1574	/* This is direction-specific, we may have a different default */
1575	state->MaxRecvDataSegmentLength =
1576		entries[K_MaxRecvDataSegmentLength].defval;
1577
1578	/* First connection only */
1579	if (!conn->c_session->s_TSIH) {
1580		state->ErrorRecoveryLevel =
1581		    (lpar->is_present.ErrorRecoveryLevel) ?
1582		    lpar->ErrorRecoveryLevel : 2;
1583		/*
1584		 * Negotiate InitialR2T to FALSE and ImmediateData to
1585		 * TRUE, should be slightly more efficient than the
1586		 * default InitialR2T=TRUE.
1587		 */
1588		state->InitialR2T = FALSE;
1589		state->ImmediateData = TRUE;
1590
1591		/* We don't really care about this, so don't negotiate
1592		 * by default
1593		 */
1594		state->MaxBurstLength = entries[K_MaxBurstLength].defval;
1595		state->FirstBurstLength = entries[K_FirstBurstLength].defval;
1596		state->MaxOutstandingR2T = entries[K_MaxOutstandingR2T].defval;
1597
1598		set_key_n(state, K_ErrorRecoveryLevel, state->ErrorRecoveryLevel);
1599		set_key_n(state, K_InitialR2T, state->InitialR2T);
1600		set_key_n(state, K_ImmediateData, state->ImmediateData);
1601
1602		if (lpar->is_present.MaxConnections) {
1603			state->MaxConnections = lpar->MaxConnections;
1604			set_key_n(state, K_MaxConnections, lpar->MaxConnections);
1605		}
1606
1607		if (lpar->is_present.DefaultTime2Wait)
1608			set_key_n(state, K_DefaultTime2Wait, lpar->DefaultTime2Wait);
1609		else
1610			state->DefaultTime2Wait = entries[K_DefaultTime2Wait].defval;
1611
1612		if (lpar->is_present.DefaultTime2Retain)
1613			set_key_n(state, K_DefaultTime2Retain, lpar->DefaultTime2Retain);
1614		else
1615			state->DefaultTime2Retain = entries[K_DefaultTime2Retain].defval;
1616	} else
1617		init_session_parameters(conn->c_session, state);
1618
1619	DEBC(conn, 10, ("SetFirstOpnegs: recover=%d, MRDSL=%d\n",
1620		conn->c_recover, state->MaxRecvDataSegmentLength));
1621}
1622
1623
1624/*
1625 * assemble_negotiation_parameters:
1626 *    Assemble any negotiation parameters requested by the other side.
1627 *
1628 *    Parameter:
1629 *          conn     The connection
1630 *          ccb      The login ccb
1631 *          rx_pdu   The received login response PDU
1632 *          tx_pdu   The transmit PDU
1633 *
1634 *    Returns:    0     On success
1635 *                > 0   (an ISCSI error code) if an error occurred.
1636 */
1637
1638int
1639assemble_negotiation_parameters(connection_t *conn, ccb_t *ccb, pdu_t *rx_pdu,
1640							    pdu_t *tx_pdu)
1641{
1642	negotiation_state_t *state = (negotiation_state_t *) ccb->ccb_temp_data;
1643	negotiation_parameter_t rxp;
1644	uint8_t *rxpars;
1645	int rc;
1646
1647	state->num_pars = 0;
1648
1649	DEBC(conn, 10, ("AsmNegParams: connState=%d, MRDSL=%d\n",
1650		conn->c_state, state->MaxRecvDataSegmentLength));
1651
1652	if (conn->c_state == ST_SEC_NEG || conn->c_state == ST_SEC_FIN) {
1653		conn->c_state = ST_OP_NEG;
1654		set_first_opnegs(conn, state);
1655	}
1656
1657	rxpars = (uint8_t *) rx_pdu->pdu_temp_data;
1658	if (rxpars != NULL) {
1659		/* Note: There are always at least 2 extra bytes past temp_data_len */
1660		rxpars[rx_pdu->pdu_temp_data_len] = '\0';
1661		rxpars[rx_pdu->pdu_temp_data_len + 1] = '\0';
1662
1663		while (*rxpars) {
1664			if ((rxpars = get_parameter(rxpars, &rxp)) == NULL)
1665				return ISCSI_STATUS_NEGOTIATION_ERROR;
1666
1667			rc = eval_parameter(conn, state, &rxp);
1668			if (rc)
1669				return rc;
1670		}
1671	}
1672
1673	if (tx_pdu == NULL)
1674		return 0;
1675
1676	complete_pars(state, tx_pdu);
1677
1678	return 0;
1679}
1680
1681/*
1682 * init_text_parameters:
1683 *    Initialize text negotiation.
1684 *
1685 *    Parameter:
1686 *          conn     The connection
1687 *          tx_pdu   The transmit PDU
1688 *
1689 *    Returns:    0     On success
1690 *                > 0   (an ISCSI error code) if an error occurred.
1691 */
1692
1693int
1694init_text_parameters(connection_t *conn, ccb_t *ccb)
1695{
1696	negotiation_state_t *state;
1697
1698	state = malloc(sizeof(*state), M_TEMP, M_WAITOK | M_ZERO);
1699	if (state == NULL) {
1700		DEBOUT(("*** Out of memory in init_text_params\n"));
1701		return ISCSI_STATUS_NO_RESOURCES;
1702	}
1703	ccb->ccb_temp_data = state;
1704
1705	state->HeaderDigest = conn->c_HeaderDigest;
1706	state->DataDigest = conn->c_DataDigest;
1707	state->MaxRecvDataSegmentLength = conn->c_MaxRecvDataSegmentLength;
1708	init_session_parameters(conn->c_session, state);
1709
1710	return 0;
1711}
1712
1713
1714/*
1715 * assemble_send_targets:
1716 *    Assemble send targets request
1717 *
1718 *    Parameter:
1719 *          pdu      The transmit PDU
1720 *          val      The SendTargets key value
1721 *
1722 *    Returns:    0     On success
1723 *                > 0   (an ISCSI error code) if an error occurred.
1724 */
1725
1726int
1727assemble_send_targets(pdu_t *pdu, uint8_t *val)
1728{
1729	negotiation_parameter_t par;
1730	uint8_t *buf;
1731	int len;
1732
1733	par.key = K_SendTargets;
1734	par.list_num = 1;
1735	par.val.sval = val;
1736	par.hex_bignums = false;
1737
1738	len = parameter_size(&par);
1739
1740	if ((buf = malloc(len, M_TEMP, M_WAITOK)) == NULL) {
1741		DEBOUT(("*** Out of memory in assemble_send_targets\n"));
1742		return ISCSI_STATUS_NO_RESOURCES;
1743	}
1744	pdu->pdu_temp_data = buf;
1745	pdu->pdu_temp_data_len = len;
1746
1747	if (put_parameter(buf, len, &par) == 0) {
1748		DEBOUT(("trying to put zero sized buffer\n"));
1749		return ISCSI_STATUS_PARAMETER_INVALID;
1750	}
1751
1752	return 0;
1753}
1754
1755
1756/*
1757 * set_negotiated_parameters:
1758 *    Copy the negotiated parameters into the connection and session structure.
1759 *
1760 *    Parameter:
1761 *          ccb      The ccb containing the state information
1762 */
1763
1764void
1765set_negotiated_parameters(ccb_t *ccb)
1766{
1767	negotiation_state_t *state = (negotiation_state_t *) ccb->ccb_temp_data;
1768	connection_t *conn = ccb->ccb_connection;
1769	session_t *sess = ccb->ccb_session;
1770
1771	conn->c_HeaderDigest = state->HeaderDigest;
1772	conn->c_DataDigest = state->DataDigest;
1773	sess->s_ErrorRecoveryLevel = state->ErrorRecoveryLevel;
1774	sess->s_InitialR2T = state->InitialR2T;
1775	sess->s_ImmediateData = state->ImmediateData;
1776	conn->c_MaxRecvDataSegmentLength = state->MaxRecvDataSegmentLength;
1777	sess->s_MaxConnections = state->MaxConnections;
1778	sess->s_DefaultTime2Wait = conn->c_Time2Wait = state->DefaultTime2Wait;
1779	sess->s_DefaultTime2Retain = conn->c_Time2Retain =
1780		state->DefaultTime2Retain;
1781
1782	/* set idle connection timeout to half the Time2Retain window so we */
1783	/* don't miss it, unless Time2Retain is ridiculously small. */
1784	conn->c_idle_timeout_val = (conn->c_Time2Retain >= 10) ?
1785		(conn->c_Time2Retain / 2) * hz : CONNECTION_IDLE_TIMEOUT;
1786
1787	sess->s_MaxBurstLength = state->MaxBurstLength;
1788	sess->s_FirstBurstLength = state->FirstBurstLength;
1789	sess->s_MaxOutstandingR2T = state->MaxOutstandingR2T;
1790
1791	DEBC(conn, 10,("SetNegPar: MRDSL=%d, MBL=%d, FBL=%d, IR2T=%d, ImD=%d\n",
1792		state->MaxRecvDataSegmentLength, state->MaxBurstLength,
1793		state->FirstBurstLength, state->InitialR2T,
1794		state->ImmediateData));
1795
1796	conn->c_max_transfer = min(sess->s_MaxBurstLength, conn->c_MaxRecvDataSegmentLength);
1797
1798	conn->c_max_firstimmed = (!sess->s_ImmediateData) ? 0 :
1799				min(sess->s_FirstBurstLength, conn->c_max_transfer);
1800
1801	conn->c_max_firstdata = (sess->s_InitialR2T || sess->s_FirstBurstLength < conn->c_max_firstimmed) ? 0 :
1802				min(sess->s_FirstBurstLength - conn->c_max_firstimmed, conn->c_max_transfer);
1803
1804}
1805