/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2004-2011 Emulex. All rights reserved.
* Use is subject to license terms.
*/
#include <emlxs.h>
#ifdef DHCHAP_SUPPORT
#include <md5.h>
#include <sha1.h>
#include <sys/sha1_consts.h>
#include <bignum.h>
#define RAND
#ifndef ENABLE
#endif /* ENABLE */
#ifndef DISABLE
#define DISABLE 0
#endif /* DISABLE */
/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
union challenge_val un_cval);
static BIG_ERR_CODE
static BIG_ERR_CODE
static BIG_ERR_CODE
static uint32_t *
static uint32_t *
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
static uint32_t
{0, 0, 0, 0, 0, 0, 0, 0};
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned char dhgp1_pVal[] =
{0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8, 0x0A, 0xFA,
0x8F, 0xC5, 0xE8,
0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C,
0x25, 0x65, 0x76,
0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13, 0xD6,
0x92, 0xC6, 0xE0,
0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60,
0x89, 0xDA, 0xD1,
0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
0xB1, 0x5D, 0x49,
0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85, 0xC5, 0x29, 0xF5, 0x66, 0x66,
0x0E, 0x57, 0xEC,
0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97,
0x6E, 0xAA, 0x9A,
0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F, 0xC6, 0x1D, 0x2F, 0xC0,
0xEB, 0x06, 0xE3,
};
unsigned char dhgp2_pVal[] =
{0xD7, 0x79, 0x46, 0x82, 0x6E, 0x81, 0x19, 0x14, 0xB3, 0x94, 0x01, 0xD5, 0x6A,
0x0A, 0x78, 0x43,
0xA8, 0xE7, 0x57, 0x5D, 0x73, 0x8C, 0x67, 0x2A, 0x09, 0x0A, 0xB1, 0x18, 0x7D,
0x69, 0x0D, 0xC4,
0x38, 0x72, 0xFC, 0x06, 0xA7, 0xB6, 0xA4, 0x3F, 0x3B, 0x95, 0xBE, 0xAE, 0xC7,
0xDF, 0x04, 0xB9,
0xD2, 0x42, 0xEB, 0xDC, 0x48, 0x11, 0x11, 0x28, 0x32, 0x16, 0xCE, 0x81, 0x6E,
0x00, 0x4B, 0x78,
0x6C, 0x5F, 0xCE, 0x85, 0x67, 0x80, 0xD4, 0x18, 0x37, 0xD9, 0x5A, 0xD7, 0x87,
0xA5, 0x0B, 0xBE,
0x90, 0xBD, 0x3A, 0x9C, 0x98, 0xAC, 0x0F, 0x5F, 0xC0, 0xDE, 0x74, 0x4B, 0x1C,
0xDE, 0x18, 0x91,
0x69, 0x08, 0x94, 0xBC, 0x1F, 0x65, 0xE0, 0x0D, 0xE1, 0x5B, 0x4B, 0x2A, 0xA6,
0xD8, 0x71, 0x00,
0xC9, 0xEC, 0xC2, 0x52, 0x7E, 0x45, 0xEB, 0x84, 0x9D, 0xEB, 0x14, 0xBB, 0x20,
0x49, 0xB1, 0x63,
0xEA, 0x04, 0x18, 0x7F, 0xD2, 0x7C, 0x1B, 0xD9, 0xC7, 0x95, 0x8C, 0xD4, 0x0C,
0xE7, 0x06, 0x7A,
0x9C, 0x02, 0x4F, 0x9B, 0x7C, 0x5A, 0x0B, 0x4F, 0x50, 0x03, 0x68, 0x61, 0x61,
0xF0, 0x60, 0x5B
};
unsigned char dhgp3_pVal[] =
{0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1, 0xF1, 0x2A, 0x86, 0x17,
0xA4, 0x7B, 0xBB,
0xDB, 0xA5, 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9, 0x61, 0x4B,
0x19, 0xCC, 0x4D,
0x5F, 0x4F, 0x5F, 0x55, 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
0x60, 0x7A, 0x29,
0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0, 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A,
0x22, 0xE8, 0xDC,
0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0, 0x81, 0x34, 0xB1, 0xC8, 0xB9,
0x79, 0x89, 0x14,
0x9B, 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54, 0x83, 0x81, 0xDB,
0xC5, 0xB1, 0xFC,
0x76, 0x4E, 0x3F, 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E, 0x2B,
0x9C, 0x8C, 0xF5,
0x6E, 0xDF, 0x01, 0x95, 0x39, 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24,
0xB7, 0xC4, 0x86,
0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F, 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7,
0xCC, 0xB7, 0xAE,
0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F, 0x8A, 0x2F, 0xE9, 0xB8,
0xB5, 0x29, 0x2E,
0x5A, 0x02, 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2, 0x8C, 0x24,
0x42, 0xC6, 0xF3,
0x15, 0x18, 0x0F, 0x93, 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
0x35, 0xF9, 0xBB
};
unsigned char dhgp4_pVal[] =
{0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1, 0x66, 0xDE, 0x5E, 0x13,
0x89, 0x58, 0x2F,
0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92, 0x94, 0x3D,
0xB5, 0x60, 0x50,
0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
0x67, 0xA1, 0x3D,
0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA,
0x04, 0xFD, 0x50,
0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, 0xCF, 0x60, 0x95, 0x17, 0x9A,
0x16, 0x3A, 0xB3,
0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18, 0xA9, 0x96, 0x2F,
0x0B, 0x93, 0xB8,
0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A, 0xDB,
0xF4, 0xFF, 0x74,
0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B,
0x14, 0x77, 0x3B,
0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43,
0x6C, 0x64, 0x81,
0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B, 0x9D, 0x32, 0xE6, 0x88,
0xF8, 0x77, 0x48,
0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A, 0x27, 0x75,
0xD2, 0xEC, 0xFA,
0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
0xE5, 0x7A, 0xE6,
0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B,
0xC3, 0x08, 0xD8,
0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, 0x71, 0xAE, 0x35, 0xF8, 0xE9,
0xDB, 0xFB, 0xB6,
0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE, 0x23, 0x6D, 0x52,
0x5F, 0x54, 0x75,
0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E,
0x4A, 0xFF, 0x73
};
/*
* myrand is used for test only, eventually it should be replaced by the random
* number. AND it is basically the private key.
*/
/* #define MYRAND */
#ifdef MYRAND
unsigned char myrand[] =
{0x11, 0x11, 0x22, 0x22,
0x33, 0x33, 0x44, 0x44,
0x55, 0x55, 0x66, 0x66,
0x77, 0x77, 0x88, 0x88,
0x99, 0x99, 0x00, 0x00};
#endif /* MYRAND */
/* Node Events */
{
{NODE_EVENT_DEVICE_RM, "DEVICE_REMOVE"},
{NODE_EVENT_DEVICE_RECOVERY, "DEVICE_RECOVERY"},
{NODE_EVENT_RCV_AUTH_MSG, "AUTH_MSG_RCVD"},
{NODE_EVENT_CMPL_AUTH_MSG, "AUTH_MSG_CMPL"},
}; /* emlxs_event_table() */
{
{ELX_FABRIC_STATE_UNKNOWN, "FABRIC_STATE_UNKNOWN"},
{ELX_FABRIC_AUTH_DISABLED, "FABRIC_AUTH_DISABLED"},
{ELX_FABRIC_AUTH_FAILED, "FABRIC_AUTH_FAILED"},
{ELX_FABRIC_AUTH_SUCCESS, "FABRIC_AUTH_SUCCESS"},
{ELX_FABRIC_IN_AUTH, "FABRIC_IN_AUTH"},
{ELX_FABRIC_IN_REAUTH, "FABRIC_IN_REAUTH"},
}; /* emlxs_pstate_table() */
{
{NODE_STATE_UNKNOWN, "STATE_UNKNOWN"},
{NODE_STATE_AUTH_DISABLED, "AUTH_DISABLED"},
{NODE_STATE_AUTH_FAILED, "AUTH_FAILED"},
{NODE_STATE_AUTH_SUCCESS, "AUTH_SUCCESS"},
{NODE_STATE_AUTH_NEGOTIATE_ISSUE, "NEGOTIATE_ISSUE"},
{NODE_STATE_AUTH_NEGOTIATE_RCV, "NEGOTIATE_RCV"},
{NODE_STATE_AUTH_NEGOTIATE_CMPL_WAIT4NEXT, "NEGOTIATE_CMPL"},
{NODE_STATE_DHCHAP_CHALLENGE_ISSUE, "DHCHAP_CHALLENGE_ISSUE"},
{NODE_STATE_DHCHAP_REPLY_ISSUE, "DHCHAP_REPLY_ISSUE"},
{NODE_STATE_DHCHAP_CHALLENGE_CMPL_WAIT4NEXT, "DHCHAP_CHALLENGE_CMPL"},
{NODE_STATE_DHCHAP_REPLY_CMPL_WAIT4NEXT, "DHCHAP_REPLY_CMPL"},
{NODE_STATE_DHCHAP_SUCCESS_ISSUE, "DHCHAP_SUCCESS_ISSUE"},
{NODE_STATE_DHCHAP_SUCCESS_ISSUE_WAIT4NEXT, "DHCHAP_SUCCESS_ISSUE_WAIT"},
{NODE_STATE_DHCHAP_SUCCESS_CMPL_WAIT4NEXT, "DHCHAP_SUCCESS_CMPL"},
}; /* emlxs_nstate_table() */
extern char *
{
uint32_t i;
for (i = 0; i < count; i++) {
return (emlxs_event_table[i].string);
}
}
return (buffer);
} /* emlxs_dhc_event_xlate() */
extern void
{
/* Perform common functions based on state */
switch (state) {
case NODE_STATE_UNKNOWN:
case NODE_STATE_AUTH_DISABLED:
node_dhc->nlp_authrsp_tmo = 0;
node_dhc->nlp_authrsp_tmocnt = 0;
break;
case NODE_STATE_AUTH_SUCCESS:
/* Record auth time */
} else if (node_dhc->parent_auth_cfg) {
}
node_dhc->nlp_authrsp_tmo = 0;
}
break;
default:
break;
}
/* Check for switch port */
switch (state) {
case NODE_STATE_UNKNOWN:
break;
case NODE_STATE_AUTH_DISABLED:
break;
case NODE_STATE_AUTH_FAILED:
break;
case NODE_STATE_AUTH_SUCCESS:
break;
/* Auth active */
default:
}
break;
}
"Port: %s --> %s",
}
}
}
/* Update auth status */
return;
} /* emlxs_dhc_state() */
/* auth_lock must be held when calling this */
extern void
{
return;
}
/* Get auth status object */
} else if (node_dhc->parent_auth_cfg) {
} else {
/* No auth status to be updated */
return;
}
"Node:0x%x state=%s rsn=0x%x exp=0x%x (%x,%x)",
/* Set state and auth_failReason */
case NODE_STATE_UNKNOWN: /* Connection */
auth_status->auth_failReason = 0;
}
break;
case NODE_STATE_AUTH_DISABLED:
auth_status->auth_failReason = 0;
break;
case NODE_STATE_AUTH_FAILED:
/* Check failure reason and update if neccessary */
switch (reason) {
case AUTHRJT_FAILURE: /* 0x01 */
case AUTHRJT_LOGIC_ERR: /* 0x02 */
break;
case LSRJT_AUTH_REQUIRED: /* 0x03 */
switch (explaination) {
case LSEXP_AUTH_REQUIRED:
break;
default:
}
break;
case LSRJT_AUTH_LOGICAL_BSY: /* 0x05 */
break;
case LSRJT_AUTH_ELS_NOT_SUPPORTED: /* 0x0B */
break;
case LSRJT_AUTH_NOT_LOGGED_IN: /* 0x09 */
break;
}
/* Make sure the state is set to failed at this point */
}
break;
case NODE_STATE_AUTH_SUCCESS:
auth_status->auth_failReason = 0;
break;
/* Authentication currently active */
default:
/* Set defaults */
auth_status->auth_failReason = 0;
/* Check codes for exceptions */
switch (reason) {
case AUTHRJT_FAILURE: /* 0x01 */
switch (explaination) {
case AUTHEXP_AUTH_FAILED: /* 0x05 */
case AUTHEXP_BAD_PAYLOAD: /* 0x06 */
case AUTHEXP_BAD_PROTOCOL: /* 0x07 */
break;
}
break;
case AUTHRJT_LOGIC_ERR: /* 0x02 */
switch (explaination) {
case AUTHEXP_MECH_UNUSABLE: /* 0x01 */
case AUTHEXP_DHGROUP_UNUSABLE: /* 0x02 */
case AUTHEXP_HASHFUNC_UNUSABLE: /* 0x03 */
case AUTHEXP_CONCAT_UNSUPP: /* 0x09 */
case AUTHEXP_BAD_PROTOVERS: /* 0x0A */
break;
}
break;
case LSRJT_AUTH_REQUIRED: /* 0x03 */
switch (explaination) {
case LSEXP_AUTH_REQUIRED:
break;
}
break;
case LSRJT_AUTH_LOGICAL_BSY: /* 0x05 */
break;
case LSRJT_AUTH_ELS_NOT_SUPPORTED: /* 0x0B */
break;
case LSRJT_AUTH_NOT_LOGGED_IN: /* 0x09 */
break;
}
break;
}
auth_status->localAuth = 0;
auth_status->remoteAuth = 0;
auth_status->group_priority = 0;
auth_status->hash_priority = 0;
auth_status->type_priority = 0;
} else {
switch (node_dhc->nlp_reauth_status) {
case NLP_HOST_REAUTH_ENABLED:
} else {
}
break;
case NLP_HOST_REAUTH_DISABLED:
default:
break;
}
auth_status->localAuth = 0;
} else {
auth_status->remoteAuth = 0;
}
switch (node_dhc->nlp_auth_dhgpid) {
case GROUP_NULL:
break;
case GROUP_1024:
break;
case GROUP_1280:
break;
case GROUP_1536:
break;
case GROUP_2048:
break;
}
switch (node_dhc->nlp_auth_hashid) {
case 0:
auth_status->hash_priority = 0;
break;
case AUTH_SHA1:
break;
case AUTH_MD5:
break;
}
}
return;
} /* emlxs_dhc_status() */
static char *
{
uint32_t i;
for (i = 0; i < count; i++) {
return (emlxs_pstate_table[i].string);
}
}
return (buffer);
} /* emlxs_dhc_pstate_xlate() */
static char *
{
uint32_t i;
for (i = 0; i < count; i++) {
return (emlxs_nstate_table[i].string);
}
}
return (buffer);
} /* emlxs_dhc_nstate_xlate() */
static uint32_t
{
"dhgp: 0x%x, id[0..4]=0x%x 0x%x 0x%x 0x%x 0x%x pri[1]=0x%x",
/*
* Here are the rules, as the responder We always try to select ours
* highest setup
*/
/* Check to see if there is any repeated dhgp in initiator's list */
/* If available, it is a invalid payload */
if (cnt >= 2) {
for (i = 0; i <= cnt - 2; i++) {
rc = 2;
":Rpt dhid[%x]=%x dhid[%x]=%x",
break;
}
}
if (rc == 2) {
break;
}
}
rc = 1;
}
if (rc == 2) {
/* duplicate invalid payload */
return (rc);
}
}
/* Check how many dhgps the responder specified */
wnt = 0;
wnt++;
}
/* Determine the most suitable dhgp the responder should use */
for (i = 0; i < wnt; i++) {
for (j = 0; j < cnt; j++) {
dh_id[j]) {
rc = 0;
*dhgp_id =
break;
}
}
if (rc == 0) {
break;
}
}
if (i == wnt) {
/* no match */
rc = 1;
return (1);
}
"check_dhgp: dhgp_id=0x%x", *dhgp_id);
return (rc);
} /* emlxs_check_dhgp */
static void
{
sizeof (NAME_TYPE));
return;
} /* emlxs_get_random_bytes */
/* **************************** STATE MACHINE ************************** */
static void *emlxs_dhchap_action[] =
{
/* Action routine Event */
/* NODE_STATE_UNKNOWN 0x00 */
(void *) emlxs_disc_neverdev, /* DEVICE_RM */
(void *) emlxs_disc_neverdev, /* DEVICE_RECOVERY */
(void *) emlxs_disc_neverdev, /* RCV_AUTH_MSG */
(void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_DISABLED 0x01 */
(void *) emlxs_disc_neverdev, /* DEVICE_RM */
(void *) emlxs_disc_neverdev, /* DEVICE_RECOVERY */
(void *) emlxs_disc_neverdev, /* RCV_AUTH_MSG */
(void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_FAILED 0x02 */
(void *) emlxs_device_rm_npr_node, /* DEVICE_RM */
(void *) emlxs_device_recov_npr_node, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_npr_node, /* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_npr_node, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_SUCCESS 0x03 */
(void *) emlxs_disc_neverdev, /* DEVICE_RM */
(void *) emlxs_device_recov_unmapped_node, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_unmapped_node, /* RCV_AUTH_MSG */
(void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_NEGOTIATE_ISSUE 0x04 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_auth_negotiate_issue, /* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_auth_negotiate_issue, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_NEGOTIATE_RCV 0x05 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_auth_negotiate_rcv, /* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_auth_negotiate_rcv, /* CMPL_AUTH_MSG */
/* NODE_STATE_AUTH_NEGOTIATE_CMPL_WAIT4NEXT 0x06 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
/* RCV_AUTH_MSG */
/* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_CHALLENGE_ISSUE 0x07 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_dhchap_challenge_issue, /* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_dhchap_challenge_issue, /* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_REPLY_ISSUE 0x08 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_dhchap_reply_issue, /* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_dhchap_reply_issue, /* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_CHALLENGE_CMPL_WAIT4NEXT 0x09 */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
/* RCV_AUTH_MSG */
/* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_REPLY_CMPL_WAIT4NEXT 0x0A */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
/* RCV_AUTH_MSG */
/* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_SUCCESS_ISSUE 0x0B */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
(void *) emlxs_rcv_auth_msg_dhchap_success_issue,
/* RCV_AUTH_MSG */
(void *) emlxs_cmpl_auth_msg_dhchap_success_issue,
/* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_SUCCESS_ISSUE_WAIT4NEXT 0x0C */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
/* RCV_AUTH_MSG */
/* CMPL_AUTH_MSG */
/* NODE_STATE_DHCHAP_SUCCESS_CMPL_WAIT4NEXT 0x0D */
(void *) emlxs_device_rem_auth, /* DEVICE_RM */
(void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
/* RCV_AUTH_MSG */
/* CMPL_AUTH_MSG */
}; /* emlxs_dhchap_action[] */
extern int
{
"%s: did=0x%x",
node_dhc->disc_refcnt++;
node_dhc->disc_refcnt--;
return (rc);
} /* emlxs_dhchap_state_machine() */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"disc_neverdev: did=0x%x.",
} /* emlxs_disc_neverdev() */
/*
* ! emlxs_cmpl_dhchap_challenge_issue
*
* \pre \post \param cmdiocb \param rspiocb \return void
*
* \b Description: iocb_cmpl callback function. when the ELS DHCHAP_Challenge
*
*/
static void
{
if (!ndlp) {
}
"cmpl_dhchap_challenge_issue: did=0x%x state=%x",
} else {
"cmpl_dhchap_challenge_issue: did=0x%x. Succcess.",
did);
}
if (ndlp) {
}
}
return;
} /* emlxs_cmpl_dhchap_challenge_issue */
/*
* ! emlxs_cmpl_dhchap_success_issue
*
* \pre \post \param phba \param cmdiocb \param rspiocb \return void
*
* \b Description: iocb_cmpl callback function.
*
*/
static void
{
if (!ndlp) {
}
"cmpl_dhchap_success_issue: 0x%x %x. No retry.",
} else {
"cmpl_dhchap_success_issue: did=0x%x. Succcess.",
did);
}
if (ndlp) {
}
}
return;
} /* emlxs_cmpl_dhchap_success_issue */
/*
* if rsp == NULL, this is only the DHCHAP_Success msg
*
* if rsp != NULL, DHCHAP_Success contains rsp to the challenge.
*/
/* ARGSUSED */
int retry,
{
else
} else {
}
cmdsize = sizeof (DHCHAP_SUCCESS_HDR);
} else {
}
rsp_size = 4;
return (1);
}
/*
* In case of rsp == NULL meaning that this is DHCHAP_Success issued
* when Host is the initiator AND this DHCHAP_Success is issused in
* response to the bi-directional authentication, meaning Host
* authenticate another entity, therefore no more DHCHAP_Success
* expected. OR this DHCHAP_Success is issued by host when host is
* the responder BUT it is uni-directional auth, therefore no more
* DHCHAP_Success expected.
*
* In case of rsp != NULL it indicates this DHCHAP_Success is issued
* when host is the responder AND this DHCHAP_Success has reply
* embedded therefore the host expects DHCHAP_Success from other
* entity in transaction.
*/
"issue_dhchap_success: 0x%x 0x%x 0x%x 0x%x 0x%x %p",
} else {
}
} else {
} else {
"is_dhch_success: (1) 0x%x 0x%x 0x%x 0x%x",
return (1);
}
}
if (ret != FC_SUCCESS) {
"issue_dhchap_success: Unable to send packet. 0x%x",
ret);
return (1);
}
return (0);
} /* emlxs_issue_dhchap_success */
/*
* ! emlxs_cmpl_auth_reject_issue
*
* \pre \post \param phba \param cmdiocb \param rspiocb \return void
*
* \b Description: iocb_cmpl callback function.
*
*/
static void
{
if (!ndlp) {
}
"cmpl_auth_reject_issue: 0x%x %x. No retry.",
} else {
"cmpl_auth_reject_issue: did=0x%x. Succcess.",
did);
}
if (ndlp) {
/* setup the new state */
}
}
return;
} /* emlxs_cmpl_auth_reject_issue */
/*
* If Logical Error and Reason Code Explanation is "Restart Authentication
* Protocol" then the Transaction Identifier could be
* any value.
*/
/* ARGSUSED */
static uint32_t
int retry,
{
if (node_dhc->nlp_authrsp_tmo) {
node_dhc->nlp_authrsp_tmo = 0;
}
rsp_size = 4;
"Auth reject failed: Unable to allocate pkt. 0x%x %x %x",
return (1);
}
} else {
"Auth reject failed.Invalid flag=%d. 0x%x %x expl=%x",
return (1);
}
"Auth reject: did=0x%x reason=%x expl=%x",
"Auth reject failed. Unable to send pkt. 0x%x %x expl=%x",
return (1);
}
"Auth-Reject: ReasonCode=0x%x, ReasonCodeExplanation=0x%x",
return (0);
} /* emlxs_issue_auth_reject */
static fc_packet_t *
{
/* simulate the ULP stack's fc_packet send out */
return (NULL);
}
/* Build the fc header */
return ((fc_packet_t *)pkt);
} /* emlxs_prep_els_fc_pkt */
/*
* ! emlxs_issue_auth_negotiate
*
* \pre \post \param port \param ndlp \param retry \param flag \return
* int
*
* \b Description:
*
* The routine is invoked when host as the authentication initiator which
* issue the AUTH_ELS command AUTH_Negotiate to the other
* entity ndlp. When this Auth_Negotiate command is completed, the iocb_cmpl
* will get called as the solicited mbox cmd
* callback. Some switch only support NULL dhchap in which case negotiate
* should be modified to only have NULL DH specificed.
*
*/
/* ARGSUSED */
static int
{
/* Full DH group support limit:2, only NULL group support limit:1 */
/* first: determine the cmdsize based on the auth cfg parameters */
if (flag == 1) {
/* May be Full DH group + 2 hash may not be */
cmdsize = sizeof (AUTH_MSG_NEGOT_NULL);
para_len += 4;
para_len += 4;
/* only one hash func */
cmdsize += 4;
num_hs = 1;
para_len += 4;
hash_wcnt = 1;
} else {
/* two hash funcs */
num_hs = 2;
hash_wcnt = 2;
}
para_len += 4;
/* only one dhgp specified: could be NULL or non-NULL */
cmdsize += 4;
para_len += 4;
dhgp_wcnt = 1;
/* two dhgps specified */
dhgp_wcnt = 2;
/* three dhgps specified */
dhgp_wcnt = 3;
/* four dhgps specified */
dhgp_wcnt = 4;
dhgp_wcnt = 5;
}
} else {
cmdsize = sizeof (AUTH_MSG_NEGOT_NULL);
/*
* get the right payload size in byte: determined by config
* parameters
*/
/* value content:8 */
/* protocols:4 */
/* hash list infor */
num_hs = 1;
} else {
num_hs = 2;
}
/* dhgp list info */
/* since this is NULL DH group */
}
rsp_size = 4;
"issue_auth_negotiate: Unable to allocate pkt. 0x%x %d",
return (1);
}
/* Fill in AUTH_MSG_NEGOT payload */
if (flag == 1) {
if (hash_wcnt == 1) {
sizeof (AUTH_MSG_NEGOT_NULL));
} else {
sizeof (AUTH_MSG_NEGOT_NULL));
}
} else {
sizeof (AUTH_MSG_NEGOT_NULL));
} else {
sizeof (AUTH_MSG_NEGOT_NULL));
}
}
/*
* For host reauthentication heart beat, the tran_id is incremented
* by one for each heart beat being fired and round back to 1 when
* 0xffffffff is reached. tran_id 0 is reserved as the initial linkup
* authentication transaction id.
*/
/* responder flag:2, initiator flag:1 */
/* responder */
} else {
}
} else { /* !NLP_HOST_REAUTH_IN_PROGRESS */
node_dhc->nlp_auth_tranid_rsp = 0;
}
if (flag == 1) {
if (hash_wcnt == 1) {
switch (dhgp_wcnt) {
case 5:
break;
case 4:
break;
case 3:
break;
case 2:
break;
case 1:
break;
}
} else {
switch (dhgp_wcnt) {
case 5:
break;
case 4:
break;
case 3:
break;
case 2:
break;
case 1:
break;
}
}
} else {
if (num_hs == 1) {
sizeof (NAME_TYPE));
} else {
sizeof (NAME_TYPE));
}
}
"issue_auth_negotiate: %x flag=%d size=%d hash=%x,%x tid=%x,%x",
"issue_auth_negotiate: Unable to send pkt. did=0x%x",
return (1);
}
return (0);
} /* emlxs_issue_auth_negotiate() */
/*
* ! emlxs_cmpl_auth_negotiate_issue
*
* \pre \post \param phba \param cmdiocb \param rspiocb \return void
*
* \b Description: iocb_cmpl callback function.
*
*/
static void
{
if (!ndlp) {
}
"cmpl_dhchap_negotiate_issue: 0x%x %x. Noretry.",
} else {
"cmpl_dhchap_negotiate_issue: did=0x%x. Succcess.",
did);
}
if (ndlp) {
} else {
0, 0);
"Reauth disabled. did=0x%x state=%x",
}
}
return;
} /* emlxs_cmpl_auth_negotiate_issue */
/*
* ! emlxs_cmpl_auth_msg_auth_negotiate_issue
*
* \pre \post \param port \param CHANNEL * rp \param arg \param evt
* \return uint32_t \b Description:
*
* cmd from an NxPort or FxPort that has received the ELS
* AUTH Negotiate msg from the host. in case of RJT, Auth_Negotiate should
* be retried in emlxs_cmpl_auth_negotiate_issue
* call. in case of ACC, the host must be the initiator because its current
* state could be "AUTH_NEGOTIATE_RCV" if it is the
* responder. Then the next stat = AUTH_NEGOTIATE_CMPL_WAIT4NEXT
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp, */ void *arg4,
{
"cmpl_auth_msg_auth_negotiate_issue: did=0x%x",
/* start the emlxs_dhc_authrsp_timeout timer */
if (node_dhc->nlp_authrsp_tmo == 0) {
}
/*
* The next state should be
* emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next
*/
0, 0);
} /* emlxs_cmpl_auth_msg_auth_negotiate_issue */
/*
* ! emlxs_rcv_auth_msg_auth_negotiate_issue
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description:
*
* This routine is supported for HBA in either auth initiator mode or
* responder mode.
*
* This routine is invoked when the host receive an unsolicited ELS AUTH Msg
* from an NxPort or FxPort to which the host has just
* sent out an ELS AUTH negotiate msg. and the NxPort or FxPort also LS_ACC
* to the host's AUTH_Negotiate msg.
*
* If this unsolicited ELS auth msg is from the FxPort or a NxPort with a
* numerically lower WWPN, the host will be the winner in
* this authentication transaction initiation phase, the host as the
* initiator will send back ACC and then Auth_Reject message
* with the Reason Code 'Logical Error' and Reason Code Explanation'
* Authentication Transaction Already Started' and with the
* current state unchanged and mark itself as auth_initiator.
*
* Otherwise, the host will be the responder that will reply to the received
* AUTH_Negotiate message will ACC (or RJT?) and abort
* its own transaction upon receipt of the AUTH_Reject message. The new state
* will be "AUTH_NEGOTIATE_RCV" and mark the host as
* auth_responder.
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_auth_negotiate_issue: did=0x%x",
/* Anyway we accept it first and then send auth_reject */
/* host is always the initiator and it should win */
} /* emlxs_rcv_auth_msg_auth_negotiate_issue */
/*
* ! emlxs_cmpl_dhchap_reply_issue
*
* \pre \post \param phba \param cmdiocb \param rspiocb \return void
*
* \b Description: iocb_cmpl callback function.
*
*/
static void
{
if (!ndlp) {
}
"cmpl_dhchap_reply_issue: 0x%x %x. No retry.",
} else {
"cmpl_dhchap_reply_issue: did=0x%x. Succcess.",
did);
}
if (ndlp) {
}
}
return;
} /* emlxs_cmpl_dhchap_reply_issue */
/*
* arg: the AUTH_Negotiate payload from the initiator. payload_len: the
* payload length
*
* We always send out the challenge parameter based on our preference
* order configured on the host side no matter what perference
* order looks like from auth_negotiate . In other words, if the host issue
* the challenge the host will make the decision as to
* what hash function, what dhgp_id is to be used.
*
* This challenge value should not be confused with the challenge value for
* bi-dir as part of reply when host is the initiator.
*/
/* ARGSUSED */
int retry,
void *arg,
{
/*
* we assume the HBAnyware should configure the driver the right
* parameters for challenge. for now, we create our own challenge.
*/
"issue_dhchap_challenge: did=0x%x hashlist=[%x,%x,%x,%x]",
/*
* Here is my own challenge structure:
*
* 1: AUTH_MSG_HDR (12 bytes + 4 bytes + 8 bytes) 2: hasd_id (4
* bytes) 3: dhgp_id (4 bytes) 4: cval_len (4 bytes) 5: cval
* (20 bytes or 16 bytes: cval_len bytes) 6: dhval_len (4 bytes)
* 7: dhval (dhval_len bytes) all these information should be stored
* in port_dhc struct
*/
} else {
return (1);
}
switch (dhgp_id) {
case GROUP_NULL:
break;
case GROUP_1024:
cmdsize += 128;
break;
case GROUP_1280:
cmdsize += 160;
break;
case GROUP_1536:
cmdsize += 192;
break;
case GROUP_2048:
cmdsize += 256;
break;
default:
"issue_dhchap_challenge: Invalid dhgp_id=0x%x",
dhgp_id);
return (1);
}
rsp_size = 4;
0, KM_NOSLEEP)) == NULL) {
return (1);
}
tmp += 8;
/* collect tran_id: this tran_id is set by the initiator */
"issue_dhchap_challenge: 0x%x 0x%x 0x%x %d 0x%x 0x%x 0x%x",
/* store the tran_id : ndlp is the initiator */
tmp += sizeof (DHCHAP_CHALL_NULL);
#ifdef RAND
/* generate a random number as the challenge */
} else {
(void) random_get_pseudo_bytes(random_number,
}
/*
* the host should store the challenge for later usage when later on
* host get the reply msg, host needs to verify it by using its old
* challenge, its private key as the input to the hash function. the
* challenge as the random_number should be stored in
* node_dhc->hrsp_cval[]
*/
bcopy((void *) &random_number[0],
/* save another copy in partner's ndlp */
bcopy((void *) &random_number[0],
} else {
bcopy((void *) &random_number[0],
}
#endif /* RAND */
/* for test only hardcode the challenge value */
#ifdef MYRAND
/* save another copy in partner's ndlp */
} else {
}
#endif /* MYRAND */
} else {
}
/*
* we need another random number as the private key x which will be
* used to compute the public key i.e. g^x mod p we intentionally set
* the length of private key as the same length of challenge. we have
* to store the private key in node_dhc->hrsp_priv_key[20].
*/
#ifdef RAND
if (dhgp_id != GROUP_NULL) {
} else {
(void) random_get_pseudo_bytes(random_number,
}
bcopy((void *) &random_number[0],
(void *) node_dhc->hrsp_priv_key,
bcopy((void *) &random_number[0],
} else {
bcopy((void *) &random_number[0],
}
}
#endif /* RAND */
#ifdef MYRAND
if (dhgp_id != GROUP_NULL) {
/* For test only we hardcode the priv_key here */
(void *) node_dhc->hrsp_priv_key,
} else {
}
}
#endif /* MYRAND */
/* also store the hash function and dhgp_id being used in challenge. */
/* These information could be configurable through HBAnyware */
/*
* generate the DH value DH value is g^x mod p and it is also called
* public key in which g is 2, x is the random number ontained above.
* p is the dhgp3_pVal
*/
#ifdef MYRAND
/* to get (g^x mod p) with x private key */
if (dhgp_id != GROUP_NULL) {
"issue_dhchap_challenge: error. 0x%x",
err);
return (1);
}
/* we are not going to use dhval and dhval_len */
/* *(uint32_t *)tmp = dhval_len; */
} else {
}
"issue_dhchap_challenge: 0x%x: 0x%x 0x%x",
} else {
(void *)tmp,
}
} else {
/* NULL DHCHAP */
}
#endif /* MYRAND */
#ifdef RAND
/* to get (g^x mod p) with x private key */
if (dhgp_id != GROUP_NULL) {
"issue_dhchap_challenge: error. 0x%x",
err);
return (1);
}
/* we are not going to use dhval and dhval_len */
/* *(uint32_t *)tmp = dhval_len; */
} else {
}
"issue_dhchap_challenge: did=0x%x: pubkey_len=0x%x",
} else {
(void *)tmp,
}
} else {
/* NULL DHCHAP */
}
#endif /* RAND */
"issue_dhchap_challenge: 0x%x 0x%x 0x%x 0x%x 0x%x",
"issue_dhchap_challenge: 0x%x 0x%x 0x%x 0x%x",
"issue_dhchap_challenge: Unable to send fc packet.");
return (1);
}
return (0);
} /* emlxs_issue_dhchap_challenge */
/*
* DHCHAP_Reply msg
*/
/* ARGSUSED */
int retry,
{
/* Header size */
cmdsize = sizeof (DHCHAP_REPLY_HDR);
/* Rsp value len size (4) + Response value size */
}
}
} else {
}
}
}
/* DH value len size (4) + DH value size */
case GROUP_NULL:
break;
case GROUP_1024:
case GROUP_1280:
case GROUP_1536:
case GROUP_2048:
default:
break;
}
}
/* Challenge value len size (4) + Challenge value size */
cmdsize += 4;
} else {
} else {
cmdsize += 4 +
SHA1_LEN);
}
}
rsp_size = 4;
"issue_dhchap_reply failed: did=0x%x size=%x,%x",
return (1);
}
} else {
}
} else {
} else {
}
}
} else {
}
} else {
} else {
}
}
if (dhval_len != 0) {
case GROUP_NULL:
break;
case GROUP_1024:
case GROUP_1280:
case GROUP_1536:
case GROUP_2048:
default:
break;
}
/* elx_bcopy((void *)dhval, (void *)pCmd, dhval_len); */
/*
* The new DH parameter (g^y mod p) is stored in
* node_dhc->pub_key
*/
/* pubkey_len should be equal to dhval_len */
} else {
(void *)pCmd,
}
} else
} else {
/* store the challenge */
}
} else {
}
}
}
"issue_dhchap_reply: did=0x%x (%x,%x,%x,%x,%x,%x)",
"issue_dhchap_reply failed: Unable to send packet.");
return (1);
}
return (0);
} /* emlxs_issue_dhchap_reply */
/*
* ! emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description:
*
* This routine is invoked when the host received an unsolicted ELS AUTH MSG
* from an NxPort or FxPort which already replied (ACC)
* the ELS AUTH_Negotiate msg from the host. if msg is DHCHAP_Chellenge,
* based on the msg content (DHCHAP computation etc.,)
* the host send back ACC and 1. send back AUTH_Reject and set next state =
* NPR_NODE or 2. send back DHCHAP_Reply msg and set
* next state = DHCHAP_REPLY_ISSUE for bi-directional, the DHCHAP_Reply
* includes challenge from host. for uni-directional, no
* more challenge. if msg is AUTH_Reject or anything else, host send back
* ACC and set next state = NPR_NODE. And based on the
* reject code, host may need to retry negotiate with NULL DH only
*
* If the msg is AUTH_ELS cmd, cancel the nlp_authrsp_timeout timer immediately.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: did=0x%x",
/*
* 1. we process the DHCHAP_Challenge 2. ACC it first 3. based on the
* result of 1 we DHCHAP_Reply or AUTH_Reject
*/
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x",
goto AUTH_Reject;
}
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.%x,%x",
switch (ReasonCode) {
case AUTHRJT_LOGIC_ERR:
switch (ReasonCodeExplanation) {
case AUTHEXP_MECH_UNUSABLE:
case AUTHEXP_DHGROUP_UNUSABLE:
break;
case AUTHEXP_RESTART_AUTH:
/*
* Cancel the rsp timer if not cancelled yet.
* and restart auth tran now.
*/
if (node_dhc->nlp_authrsp_tmo != 0) {
node_dhc->nlp_authrsp_tmo = 0;
node_dhc->nlp_authrsp_tmocnt = 0;
}
NULL) != 0) {
"Reauth timeout. failed. 0x%x %x",
}
default:
break;
}
break;
case AUTHRJT_FAILURE:
default:
break;
}
goto AUTH_Reject;
}
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.%x",
goto AUTH_Reject;
}
"rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x %x!=%x",
goto AUTH_Reject;
}
node_dhc->nlp_authrsp_tmo = 0;
if (namelen == AUTH_NAME_LEN) {
/*
* AUTH_ELS cmd
*/
}
/* Collect the challenge value */
"rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x.%x!=%x",
goto AUTH_Reject;
}
sizeof (MD5_CVAL));
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x!=%x",
goto AUTH_Reject;
}
sizeof (SHA1_CVAL));
} else {
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x",
goto AUTH_Reject;
}
/*
* store hash_id for later usage : hash_id is set by responder in its
* dhchap_challenge
*/
/* always use this */
/* store another copy of the hash_id */
/* store dhgp_id for later usage */
/* store another copy of dhgp_id */
/* always use this */
/*
* ndlp->nlp_auth_hashid, nlp_auth_dhgpid store the hashid and dhgpid
* when this very ndlp is the auth transaction responder (in other
* words, responder means that this ndlp is send the host the
* challenge. ndlp could be fffffe or another initiator or target
* nport.
*/
case GROUP_NULL:
/* null DHCHAP only */
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x %x",
goto AUTH_Reject;
}
break;
case GROUP_1024:
case GROUP_1280:
case GROUP_1536:
case GROUP_2048:
/* Collect the DH Value */
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x %x",
goto AUTH_Reject;
}
break;
default:
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x.",
goto AUTH_Reject;
}
/*
* Calculate the hash value, hash function, DH group, secret etc.
* could be stored in port_dhc.
*/
/* arg5 has the response with NULL or Full DH group support */
/* Or should check ndlp->auth_cfg..... */
/* get arg2 here */
/*
* arg2 is the new challenge C2 from initiator if bi-dir auth
* is supported
*/
} else {
}
/* cache it for later verification usage */
bcopy((void *)&random_number[0],
/* save another copy in our partner's ndlp */
bcopy((void *)&random_number[0],
arg2len);
} else {
bcopy((void *)&random_number[0],
arg2len);
}
}
"rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x(%x,%x,%x,%x,%x)",
/* Issue ELS DHCHAP_Reply */
/*
* arg1 has the response, arg2 has the new challenge if needed (g^y
* mod p) is the pubkey: all are ready and to go
*/
/* return 0 success, otherwise failure */
random_number, arg2len)) {
"rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.failed.",
goto AUTH_Reject;
}
} /* emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next */
/*
* This routine should be set to emlxs_disc_neverdev
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_auth_msg_auth_negotiate_cmpl_wait4next.0x%x. Not iplted.",
return (0);
} /* emlxs_cmpl_auth_msg_auth_negotiate_cmpl_wait4next() */
/*
* ! emlxs_rcv_auth_msg_dhchap_reply_issue
*
* This routine is invoked when the host received an unsolicited ELS AUTH
* msg from an NxPort or FxPort into which the host has
* sent an ELS DHCHAP_Reply msg. since the host is the initiator and the
* AUTH transaction is in progress between host and the
* NxPort or FxPort, as a result, the host will send back ACC and AUTH_Reject
* and set the next state = NPR_NODE.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_dhchap_reply_issue called. 0x%x. Not implemented.",
return (0);
} /* emlxs_rcv_auth_msg_dhchap_reply_issue */
/*
* ! emlxs_cmpl_auth_msg_dhchap_reply_issue
*
* This routine is invoked when
* or FxPort that already received the ELS DHCHAP_Reply
* msg from the host. in case of ACC, next state = DHCHAP_REPLY_CMPL_WAIT4NEXT
* in case of RJT, next state = NPR_NODE
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_auth_msg_dhchap_reply_issue: did=0x%x",
/* start the emlxs_dhc_authrsp_timeout timer now */
if (node_dhc->nlp_authrsp_tmo == 0) {
}
/*
* The next state should be
* emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next
*/
} /* emlxs_cmpl_auth_msg_dhchap_reply_issue */
/*
* ! emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description: This rountine is invoked
* when the host received an unsolicited ELS AUTH Msg from the NxPort or
* FxPort that already sent ACC back to the host after
* receipt of DHCHAP_Reply msg. In normal case, this unsolicited msg could
* be DHCHAP_Success msg.
*
* if msg is ELS DHCHAP_Success, based on the payload, host send back ACC and 1.
* for uni-directional, and set next state =
* REG_LOGIN. 2. for bi-directional, and host do some computations
* (hash etc) and send back either DHCHAP_Success Msg and set
* next state = DHCHAP_SUCCESS_ISSUE_WAIT4NEXT or AUTH_Reject and set next
* state = NPR_NODE. if msg is ELS AUTH_Reject, then
* send back ACC and set next state = NPR_NODE if msg is anything else, then
* RJT and set next state = NPR_NODE
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/*
* 1. we process the DHCHAP_Success or AUTH_Reject 2. ACC it first 3.
* based on the result of 1 we goto the next stage SCR etc.
*/
/* sp = (SERV_PARM *)((uint8_t *)lp + sizeof(uint32_t)); */
"rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x 0x%x 0x%x",
node_dhc->nlp_authrsp_tmo = 0;
/* ACC it and retry etc. */
"rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x.(%x,%x)",
switch (ReasonCode) {
case AUTHRJT_LOGIC_ERR:
switch (ReasonCodeExplanation) {
case AUTHEXP_MECH_UNUSABLE:
case AUTHEXP_DHGROUP_UNUSABLE:
break;
case AUTHEXP_RESTART_AUTH:
/*
* Cancel the rsp timer if not cancelled yet.
* and restart auth tran now.
*/
if (node_dhc->nlp_authrsp_tmo != 0) {
node_dhc->nlp_authrsp_tmo = 0;
node_dhc->nlp_authrsp_tmocnt = 0;
}
"Reauth timeout.failed. 0x%x %x",
}
default:
break;
}
break;
case AUTHRJT_FAILURE:
default:
goto out;
}
goto AUTH_Reject;
}
/* Verify the tran_id */
"rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x 0x%x 0x%x 0x%x",
"rcv_auth_msg_dhchap_reply_cmpl_wait4next:0x%x %x!=%x",
goto AUTH_Reject;
}
NODE_STATE_AUTH_SUCCESS, 0, 0);
"rcv_auth_msg_dhchap_reply_cmpl_wait4next",
"Host-initiated-unidir-auth-success");
} else {
/* bidir auth needed */
/* if (LE_SWAP32(dh_success->msg_len) > 4) { */
tmp += 8;
tmp += 4;
tmp += 4;
/* tmp has the response from responder */
/*
* node_dhc->bi_cval has the bidir challenge value
* from initiator
*/
else
else
}
/* verify the response */
/* NULL DHCHAP works for now */
/* for DH group as well */
/*
* Cai2 = H (C2 || ((g^x mod p)^y mod p) ) = H (C2 ||
* (g^xy mod p) )
*
* R = H (Ti || Km || Cai2) R ?= R2
*/
/* not identical */
"rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x.failed. %x",
}
goto AUTH_Reject;
}
/* send out DHCHAP_SUCCESS */
}
}
out:
"Auth Failed: ReasonCode=0x%x, ReasonCodeExplanation=0x%x",
"rcv_auth_msg_dhchap_reply_cmpl_wait4next", info);
} /* emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next */
/*
* This routine should be set to emlxs_disc_neverdev as it shouldnot happen.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_auth_msg_dhchap_reply_cmpl_wait4next. 0x%x.Not ipleted.",
return (0);
} /* emlxs_cmpl_auth_msg_dhchap_reply_cmpl_wait4next */
/*
* emlxs_rcv_auth_msg_dhchap_success_issue_wait4next
*
* This routine is supported
* for HBA in either auth initiator mode or responder mode.
*
* This routine is invoked when the host as the auth responder received
* an unsolicited ELS AUTH msg from the NxPort as the auth
* initiator that already received the ELS DHCHAP_Success.
*
* If the host is the auth initiator and since the AUTH transction is
* already in progress, therefore, any auth els msg should not
* happen and if happened, RJT and move to NPR_NODE.
*
* If the host is the auth reponder, this unsolicited els auth msg should
* be DHCHAP_Success for this bi-directional auth
* transaction. In which case, the host should send ACC back and move state
* to REG_LOGIN. If this unsolicited els auth msg is
* DHCHAP_Reject, which could mean that the auth failed, then host should
* send back ACC and set the next state to NPR_NODE.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_dhchap_success_issue_wait4next. 0x%x. Not iplted.",
return (0);
} /* emlxs_rcv_auth_msg_dhchap_success_issue_wait4next */
/*
* ! emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next
*
* This routine is invoked when
* NxPort or FxPort that already received DHCHAP_Success
* Msg the host sent before. in case of ACC, set next state = REG_LOGIN.
* in case of RJT, set next state = NPR_NODE.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/*
* Either host is the initiator and auth or (reauth bi-direct) is
* done, so start host reauth heartbeat timer now if host side reauth
* heart beat never get started. Or host is the responder and the
* other entity is done with its reauth heart beat with
* uni-directional auth. Anyway we start host side reauth heart beat
* timer now.
*/
"cmpl_auth_msg_dhchap_success_issue_wait4next",
"Host-initiated-bidir-auth-success");
} /* emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next */
/*
* ! emlxs_cmpl_auth_msg_auth_negotiate_rcv
*
* This routine is invoked when
* NxPort that has received the ELS DHCHAP_Challenge.
* The host is the auth responder and the auth transaction is still in
* progress.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_auth_msg_auth_negotiate_rcv called. 0x%x. Not implemented.",
return (0);
} /* emlxs_cmpl_auth_msg_auth_negotiate_rcv */
/*
* ! emlxs_rcv_auth_msg_dhchap_challenge_issue
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description: This routine should be
* emlxs_disc_neverdev. The host is the auth responder and the auth
* transaction is still in progress, any unsolicited els auth
* msg is unexpected and should not happen in normal case.
*
* If DHCHAP_Reject, ACC and next state = NPR_NODE. anything else, RJT and
* next state = NPR_NODE.
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_dhchap_challenge_issue called. 0x%x. Not iplted.",
return (0);
} /* emlxs_rcv_auth_msg_dhchap_challenge_issue */
/*
* ! emlxs_cmpl_auth_msg_dhchap_challenge_issue
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description: This routine is invoked when
* the host as the responder received the solicited response (ACC or RJT)
* from initiator to the DHCHAP_Challenge msg sent from
* host. In case of ACC, the next state = DHCHAP_CHALLENGE_CMPL_WAIT4NEXT
* In case of RJT, the next state = NPR_NODE.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/*
* The next state should be
* emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next
*/
/* Start the fc_authrsp_timeout timer */
if (node_dhc->nlp_authrsp_tmo == 0) {
"cmpl_auth_msg_dhchap_challenge_issue: Starting authrsp timer.");
}
} /* emlxs_cmpl_auth_msg_dhchap_challenge_issue */
/*
* ! emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description: This routine is invoked when
* the host as the auth responder received an unsolicited auth msg from the
* FxPort or NxPort that already sent ACC to the DHCH_
* Challenge it received. In normal case this unsolicited auth msg should
* be DHCHAP_Reply msg from the initiator.
*
* For DHCHAP_Reply msg, the host send back ACC and then do verification
* (hash?) and send back DHCHAP_Success and next state as
* DHCHAP_SUCCESS_ISSUE or DHCHAP_Reject and next state as NPR_NODE based on
* the verification result.
*
* For bi-directional auth transaction, Reply msg should have the new
* challenge value from the initiator. thus the Success msg
* sent out should have the corresponding Reply from the responder.
*
* For uni-directional, Reply msg received does not contains the new
* challenge and therefore the Success msg does not include the
* Reply msg.
*
* For DHCHAP_Reject, send ACC and moved to the next state NPR_NODE. For
* anything else, send RJT and moved to NPR_NODE.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/* ACC the ELS DHCHAP_Reply msg first */
/*
* send back ELS AUTH_Reject or DHCHAP_Success msg based on the
* verification result. i.e., hash computation etc.
*/
"rcv_auth_msg_dhchap_challenge_cmpl_wait4next:0x%x 0x%x 0x%x",
goto Reject;
}
"rcv_a_m_dhch_chll_cmpl_wait4next:0x%x 0x%x 0x%x 0x%x 0x%x",
/* cancel the nlp_authrsp_timeout timer and send out Auth_Reject */
if (node_dhc->nlp_authrsp_tmo) {
node_dhc->nlp_authrsp_tmo = 0;
}
"rcv_a_msg_dhch_chall_cmpl_wait4next:RJT rcved:0x%x 0x%x",
switch (ReasonCode) {
case AUTHRJT_LOGIC_ERR:
switch (ReasonCodeExplanation) {
case AUTHEXP_MECH_UNUSABLE:
case AUTHEXP_DHGROUP_UNUSABLE:
break;
case AUTHEXP_RESTART_AUTH:
/*
* Cancel the rsp timer if not cancelled yet.
* and restart auth tran now.
*/
if (node_dhc->nlp_authrsp_tmo != 0) {
node_dhc->nlp_authrsp_tmo = 0;
node_dhc->nlp_authrsp_tmocnt = 0;
}
"Reauth timeout.Auth initfailed. 0x%x %x",
}
default:
break;
}
break;
case AUTHRJT_FAILURE:
default:
break;
}
goto Reject;
}
/* We must send out DHCHAP_Success msg and wait for ACC */
/* _AND_ if bi-dir auth, we have to wait for next */
/*
* Send back DHCHAP_Success or AUTH_Reject based on the
* verification result
*/
tmp += sizeof (DHCHAP_REPLY_HDR);
/* collect the response data */
if (dhval_len != 0) {
/* collect the DH value */
}
/*
* Check to see if there is any challenge for bi-dir auth in
* the reply msg
*/
if (cval_len != 0) {
/* collect challenge value */
} else {
}
} else {
node_dhc->nlp_auth_bidir = 0;
}
"rcv_a_m_dhchap_challenge_cmpl_wait4next:Reply:%x %lx %x %x %x\n",
/* Verify the response based on the hash func, dhgp_id etc. */
/*
* all the information needed are stored in
* node_dhc->hrsp_xxx or ndlp->nlp_auth_misc.
*/
/*
* Basically compare the rsp value with the computed hash
* value
*/
/* allocate hash_val first as rsp_len bytes */
/*
* we set bi-cval pointer as NULL because we are using
* node_dhc->hrsp_cval[]
*/
goto Reject;
}
/* not identical */
"rcv_auth_msg_dhchap_challenge_cmpl_wait4next: Not authted(1).");
goto Reject;
}
/* generate the reply based on the challenge received if any */
if ((cval_len) != 0) {
/*
* Cal R2 = H (Ti || Km || Ca2) Ca2 = H (C2 || ((g^y
* mod p)^x mod p) ) = H (C2 || (g^(x*y) mod p)) = H
* (C2 || seskey) Km is the password associated with
* responder. Here cval: C2 dhval: (g^y mod p)
*/
goto Reject;
}
}
NODE_STATE_DHCHAP_SUCCESS_ISSUE, 0, 0);
goto Reject;
}
}
out:
} /* emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next */
/*
* This routine should be emlxs_disc_neverdev.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_a_m_dhch_chall_cmpl_wait4next.0x%x. Not implemented.",
return (0);
} /* emlxs_cmpl_auth_msg_dhchap_challenge_cmpl_wait4next */
/*
* ! emlxs_rcv_auth_msg_dhchap_success_issue
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t \b Description:
*
* The host is the auth responder and the auth transaction is still in
* progress, any unsolicited els auth msg is unexpected and
* should not happen. If DHCHAP_Reject received, ACC back and move to next
* state NPR_NODE. anything else, RJT and move to
* NPR_NODE.
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_a_m_dhch_success_issue called. did=0x%x. Not implemented.",
return (0);
} /* emlxs_rcv_auth_msg_dhchap_success_issue */
/*
* emlxs_cmpl_auth_msg_dhchap_success_issue
*
* This routine is invoked when
* host as the auth responder received the solicited response (ACC or RJT)
* from the initiator that received DHCHAP_ Success.
*
* For uni-dirctional authentication, we are done so the next state =
* REG_LOGIN for bi-directional authentication, we will expect
* DHCHAP_Success msg. so the next state = DHCHAP_SUCCESS_CMPL_WAIT4NEXT
* and start the emlxs_dhc_authrsp_timeout timer
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"cmpl_a_m_dhch_success_issue: did=0x%x auth_bidir=0x%x",
/* we would expect the bi-dir authentication result */
/*
* the next state should be
* emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next
*/
/* start the emlxs_dhc_authrsp_timeout timer */
} else {
"cmpl_auth_msg_dhchap_success_issue",
"Node-initiated-unidir-reauth-success");
}
} /* emlxs_cmpl_auth_msg_dhchap_success_issue */
/* ARGSUSED */
static uint32_t
void *arg1,
void *arg2,
void *arg3,
void *arg4,
{
"device_recov_unmapped_node called. 0x%x. Not implemented.",
return (0);
} /* emlxs_device_recov_unmapped_node */
/* ARGSUSED */
static uint32_t
void *arg1,
void *arg2,
void *arg3,
void *arg4,
{
"device_rm_npr_node called. 0x%x. Not implemented.",
return (0);
} /* emlxs_device_rm_npr_node */
/* ARGSUSED */
static uint32_t
void *arg1,
void *arg2,
void *arg3,
void *arg4,
{
"device_recov_npr_node called. 0x%x. Not implemented.",
return (0);
} /* emlxs_device_recov_npr_node */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"device_rem_auth: 0x%x.",
} /* emlxs_device_rem_auth */
/*
* This routine is invoked when linkdown event happens during authentication
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"device_recov_auth: 0x%x.",
node_dhc->nlp_authrsp_tmo = 0;
} /* emlxs_device_recov_auth */
/*
* This routine is invoked when the host as the responder sent out the
* ELS DHCHAP_Success to the initiator, the initiator ACC
* it. AND then the host received an unsolicited auth msg from the initiator,
* this msg is supposed to be the ELS DHCHAP_Success
* msg for the bi-directional authentication.
*
* next state should be REG_LOGIN
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_auth_msg_dhchap_success_cmpl_wait4next: did=0x%x",
/* ACC it and retry etc. */
"rcv_a_m_dhch_success_cmpl_wait4next:REJECT rvd. 0x%x 0x%x 0x%x",
switch (ReasonCode) {
case AUTHRJT_LOGIC_ERR:
switch (ReasonCodeExplanation) {
case AUTHEXP_MECH_UNUSABLE:
case AUTHEXP_DHGROUP_UNUSABLE:
break;
case AUTHEXP_RESTART_AUTH:
/*
* Cancel the rsp timer if not cancelled yet.
* and restart auth tran now.
*/
if (node_dhc->nlp_authrsp_tmo != 0) {
node_dhc->nlp_authrsp_tmo = 0;
node_dhc->nlp_authrsp_tmocnt = 0;
}
"Reauth timeout. Auth initfailed. 0x%x %x",
}
default:
break;
}
break;
case AUTHRJT_FAILURE:
default:
break;
}
goto Reject;
"rcv_a_m_dhch_success_cmpl_wait4next: 0x%x 0x%lx, 0x%lx",
goto Reject;
}
"rcv_auth_msg_dhchap_success_cmpl_wait4next",
"Node-initiated-bidir-reauth-success");
} else {
goto Reject;
}
out:
} /* emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
return (0);
} /* emlxs_cmpl_auth_msg_dhchap_success_cmpl_wait4next */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
"rcv_a_m_auth_negotiate_rcv called. did=0x%x. Not implemented.",
return (0);
} /* emlxs_rcv_auth_msg_auth_negotiate_rcv */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/* from initiator */
"rcv_auth_msg_npr_node:");
/*
* 1. process the auth msg, should acc first no matter what. 2.
* return DHCHAP_Challenge for AUTH_Negotiate auth msg, AUTH_Reject
* for anything else.
*/
/* temp is used for error checking */
/* Check the auth_els_code */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(1)=0x%x",
goto AUTH_Reject;
}
/* Check name tag and name length */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(2)=0x%x",
goto AUTH_Reject;
}
/* Check proto_num */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(3)=0x%x",
goto AUTH_Reject;
}
/* Get para_len */
/* para_len = LE_SWAP32(*(uint32_t *)temp); */
/* Check proto_id */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL; */
"rcv_auth_msg_npr_node: payload(4)=0x%x",
goto AUTH_Reject;
}
/* Check hashlist tag */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(5)=0x%x",
goto AUTH_Reject;
}
/* Get num_hs */
/* Check HashList_value1 */
/* ReasonCode = AUTHRJT_LOGIC_ERR; */
/* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
"rcv_auth_msg_npr_node: payload(6)=0x%x",
goto AUTH_Reject;
}
if (num_hs == 1) {
hs_id[1] = 0;
} else if (num_hs == 2) {
/* ReasonCode = AUTHRJT_LOGIC_ERR; */
/* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
"rcv_auth_msg_npr_node: payload(7)=0x%x",
goto AUTH_Reject;
}
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(8)=0x%x",
goto AUTH_Reject;
}
} else {
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(9)=0x%x",
goto AUTH_Reject;
}
/* Which hash_id should we use */
if (num_hs == 1) {
/*
* We always use the highest priority specified by us if we
* match initiator's , Otherwise, we use the next higher we
* both have. CR 26238
*/
} else {
/* ReasonCode = AUTHRJT_LOGIC_ERR; */
/* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
"rcv_auth_msg_npr_node: payload(10)=0x%lx",
goto AUTH_Reject;
}
} else {
/*
* Since the initiator specified two hashs, we always select
* our first one.
*/
}
/* Check DHgIDList_tag */
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(11)=0x%lx",
goto AUTH_Reject;
}
/* Get num_dh */
if (num_dh == 0) {
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(12)=0x%lx",
goto AUTH_Reject;
}
for (i = 0; i < num_dh; i++) {
/* Check DHgIDList_g0 */
}
if (rc == 1) {
/* ReasonCode = AUTHRJT_LOGIC_ERR; */
/* ReasonCodeExplanation = AUTHEXP_DHGROUP_UNUSABLE; */
"rcv_auth_msg_npr_node: payload(13)=0x%lx",
goto AUTH_Reject;
} else if (rc == 2) {
/* ReasonCode = AUTHRJT_FAILURE; */
/* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
"rcv_auth_msg_npr_node: payload(14)=0x%lx",
goto AUTH_Reject;
}
/* We should update the tran_id */
/* Send back the DHCHAP_Challenge with the proper paramaters */
goto AUTH_Reject;
}
} else {
goto AUTH_Reject;
}
"rcv_auth_msg_npr_node: AUTH_Reject it.");
} /* emlxs_rcv_auth_msg_npr_node */
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/*
* we donot cancel the nodev timeout here because we donot know if we
* can get the authentication restarted from other side once we got
* the new auth transaction kicked off we cancel nodev tmo
* immediately.
*/
/* we goto change the hba state back to where it used to be */
"cmpl_auth_msg_npr_node: 0x%x 0x%x prev_state=0x%x\n",
} /* emlxs_cmpl_auth_msg_npr_node */
/*
* ! emlxs_rcv_auth_msg_unmapped_node
*
* \pre \post \param phba \param ndlp \param arg \param evt \return
* uint32_t
*
* \b Description: This routine is invoked when the host received an
* unsolicited els authentication msg from the Fx_Port which is
* wellknown port 0xFFFFFE in unmapped state, or from Nx_Port which is
* in the unmapped state meaning that it is either a target
* which there is no scsi id associated with it or it could be another
* initiator. (end-to-end)
*
* For the Fabric F_Port (FFFFFE) we mark the port to the state in re_auth
* state without disruppting the traffic. Then the fabric
* will go through the authentication processes until it is done.
*
* most of the cases, the fabric should send us AUTH_Negotiate ELS msg. Once
* host received this auth_negotiate els msg, host
* should sent back ACC first and then send random challenge, plus DH value
* (i.e., host's publick key)
*
* Host side needs to store the challenge value and public key for later
* verification usage. (i.e., to verify the response from
* initiator)
*
* If two FC_Ports start the reauthentication transaction at the same time,
* one of the two authentication transactions shall be
* aborted. In case of Host and Fabric the Nx_Port shall remain the
* authentication initiator, while the Fx_Port shall become
* the authentication responder.
*
*/
/* ARGSUSED */
static uint32_t
/* CHANNEL * rp, */ void *arg1,
/* IOCBQ * iocbq, */ void *arg2,
/* MATCHMAP * mp, */ void *arg3,
/* NODELIST * ndlp */ void *arg4,
{
/* from initiator */
/*
* 1. process the auth msg, should acc first no matter what. 2.
* return DHCHAP_Challenge for AUTH_Negotiate auth msg, AUTH_Reject
* for anything else.
*/
"rcv_auth_msg_unmapped_node: Sending ACC: did=0x%x",
/* temp is used for error checking */
/* Check the auth_els_code */
"rcv_auth_msg_unmapped_node: payload(1)=0x%x",
goto AUTH_Reject;
}
/* Check name tag and name length */
"rcv_auth_msg_unmapped_node: payload(2)=0x%x",
goto AUTH_Reject;
}
/* Check proto_num */
"rcv_auth_msg_unmapped_node: payload(3)=0x%x",
goto AUTH_Reject;
}
/* Get para_len */
/* para_len = *(uint32_t *)temp; */
/* Check proto_id */
"rcv_auth_msg_unmapped_node: payload(4)=0x%x",
goto AUTH_Reject;
}
/* Check hashlist tag */
"rcv_auth_msg_unmapped_node: payload(5)=0x%x",
goto AUTH_Reject;
}
/* Get num_hs */
/* Check HashList_value1 */
"rcv_auth_msg_unmapped_node: payload(6)=0x%x",
goto AUTH_Reject;
}
if (num_hs == 1) {
hs_id[1] = 0;
} else if (num_hs == 2) {
"rcv_auth_msg_unmapped_node: payload(7)=0x%x",
goto AUTH_Reject;
}
"rcv_auth_msg_unmapped_node: payload(8)=0x%x",
goto AUTH_Reject;
}
} else {
"rcv_auth_msg_unmapped_node: payload(9)=0x%x",
goto AUTH_Reject;
}
/* Which hash_id should we use */
if (num_hs == 1) {
/*
* We always use the highest priority specified by us if we
* match initiator's , Otherwise, we use the next higher we
* both have. CR 26238
*/
} else {
"rcv_auth_msg_unmapped_node: pload(10)=0x%x",
goto AUTH_Reject;
}
} else {
/*
* Since the initiator specified two hashs, we always select
* our first one.
*/
}
/* Check DHgIDList_tag */
"rcv_auth_msg_unmapped_node: payload(11)=0x%x",
goto AUTH_Reject;
}
/* Get num_dh */
if (num_dh == 0) {
"rcv_auth_msg_unmapped_node: payload(12)=0x%x",
goto AUTH_Reject;
}
for (i = 0; i < num_dh; i++) {
/* Check DHgIDList_g0 */
}
if (rc == 1) {
"rcv_auth_msg_unmapped_node: payload(13)=0x%x",
goto AUTH_Reject;
} else if (rc == 2) {
"rcv_auth_msg_unmapped_node: payload(14)=0x%x",
goto AUTH_Reject;
}
"rcv_auth_msg_unmapped_node: 0x%x 0x%x 0x%x 0x%x 0x%x",
/*
* since ndlp is the initiator, tran_id is store in
* nlp_auth_tranid_ini
*/
/*
* at this point, we know for sure we received the
* auth-negotiate msg from another entity, so cancel the
* auth-rsp timeout timer if we are expecting it. should
* never happen?
*/
if (node_dhc->nlp_authrsp_tmo) {
node_dhc->nlp_authrsp_tmo = 0;
}
/*
* If at this point, the host is doing reauthentication
* (reauth heart beat) to this ndlp, then Host should remain
* as the auth initiator, host should reply to the received
* AUTH_Negotiate message with an AUTH_Reject message with
* Reason Code 'Logical Error' and Reason Code Explanation
* 'Authentication Transaction Already Started'.
*/
if (node_dhc->nlp_reauth_status ==
"rcv_auth_msg_unmapped_node: Ht reauth inprgress.");
goto AUTH_Reject;
}
/* Send back the DHCHAP_Challenge with the proper paramaters */
goto AUTH_Reject;
}
/* setup the proper state */
} else {
goto AUTH_Reject;
}
} /* emlxs_rcv_auth_msg_unmapped_node */
/*
* emlxs_hash_vrf for verification only the host is the initiator in
* the routine.
*/
/* ARGSUSED */
static uint32_t *
union challenge_val un_cval)
{
char *remote_key;
} else {
}
"hash_vrf: 0x%x 0x%x 0x%x tran_id=0x%x",
if (dhgp_id == 0) {
/* NULL DHCHAP */
/* Transaction Identifier T */
/* Augmented challenge: NULL DHCHAP i.e., Challenge */
return (NULL);
} else {
bcopy((void *)&md5_digest,
}
/*
* emlxs_md5_digest_to_hex((uint8_t *)hash_val,
* output);
*/
}
/*
* emlxs_sha1_digest_to_hex((uint8_t *)hash_val,
* output);
*/
return (NULL);
} else {
bcopy((void *)&sha1_digest,
}
}
} else {
/* Verification of bi-dir auth for DH-CHAP group */
/* original challenge is node_dhc->bi_cval[] */
/* session key is node_dhc->ses_key[] */
/* That's IT */
/*
* H(bi_cval || ses_key) = C H(Ti || Km || C) = hash_val
*/
} else {
/* ses_key is obtained in emlxs_hash_rsp */
}
return (NULL);
} else {
bcopy((void *)&md5_digest,
}
}
} else {
/* ses_key was obtained in emlxs_hash_rsp */
}
return (NULL);
} else {
bcopy((void *)&sha1_digest,
}
}
}
} /* emlxs_hash_vrf */
/*
* If dhval == NULL, NULL DHCHAP else, DHCHAP group.
*
* This routine is used by the auth transaction initiator (Who does the
* auth-negotiate) to calculate the R1 (response) based on
* the dh value it received, its own random private key, the challenge it
* received, and Transaction id, as well as the password
* associated with this very initiator in the auth pair.
*/
uint32_t *
union challenge_val un_cval,
{
char *mykey;
} else {
}
"hash_rsp: 0x%x 0x%x 0x%x 0x%x dhvallen=0x%x",
} else {
}
/* NULL DHCHAP */
MD5_LEN);
return (NULL);
} else {
bcopy((void *)&md5_digest,
}
/*
* emlxs_md5_digest_to_hex((uint8_t *)hash_val,
* output);
*/
}
/*
* emlxs_sha1_digest_to_hex((uint8_t *)hash_val,
* output);
*/
return (NULL);
} else {
bcopy((void *)&sha1_digest,
}
}
} else {
/* process DH grops */
/*
* calculate interm hash value Ca1 Ca1 = H(C1 || (g^x mod
* p)^y mod p) in which C1 is the challenge received. g^x mod
* p is the dhval received y is the random number in 16 bytes
* for MD5, 20 bytes for SHA1 p is hardcoded value based on
* different DH groups.
*
* To calculate hash value R1 R1 = H (Ti || Kn || Cai) in which
* Ti is the transaction identifier Kn is the shared secret.
* Cai is the result from interm hash.
*
* g^y mod p is reserved in port_dhc as pubkey (public key).for
* bi-dir challenge is another random number. y is prikey
* (private key). ((g^x mod p)^y mod p) is sekey (session
* key)
*/
return (NULL);
}
return (NULL);
} else {
bcopy((void *)&md5_digest,
}
}
return (NULL);
} else {
bcopy((void *)&sha1_digest,
}
}
}
} /* emlxs_hash_rsp */
/*
* To get the augmented challenge Cai Stored in hash_val
*
* Cai = Hash (C1 || ((g^x mod p)^y mod p)) = Hash (C1 || (g^(x*y) mod p)
*
* C1:challenge received from the remote entity (g^x mod p): dh val
* received from the remote entity (remote entity's pubkey) y:
* random private key from the local entity Hash: hash function used in
* agreement. (g^(x*y) mod p): shared session key (aka
* shared secret) (g^y mod p): local entity's pubkey
*/
/* ARGSUSED */
void *hash_val,
union challenge_val un_cval,
{
} else {
}
/*
* get the pub key (g^y mod p) and session key (g^(x*y) mod
* p) and stored them in the partner's ndlp structure
*/
return (err);
}
} else {
}
}
/* get the pub key and session key */
return (err);
}
} else {
}
}
return (err);
} /* emlxs_interm_hash */
/*
* This routine get the pubkey and session key. these pubkey and session
* key are stored in the partner's ndlp structure.
*/
/* ARGSUSED */
{
#ifdef BIGNUM_CHUNK_32
#else
#endif /* BIGNUM_CHUNK_32 */
/*
* compute a^e mod n assume a < n, n odd, result->value at least as
* long as n->value.
*
* a is the public key received from responder. e is the private key
* generated by me. n is the wellknown modulus.
*/
"BIGNUM_get_pubkey: 0x%x 0x%x 0x%x 0x%x",
/* size should be in the unit of (BIG_CHUNK_TYPE) words */
"BIGNUM_get_pubkey: big_init failed. a size=%d",
err = BIG_NO_MEM;
return (err);
}
/* a: (g^x mod p) */
/*
* dhval is in big-endian format. This call converts from
* byte-big-endian format to big number format (words in little
* endian order, but bytes within the words big endian)
*/
"BIGNUM_get_pubkey: big_init failed. e size=%d",
err = BIG_NO_MEM;
goto ret1;
}
#ifdef RAND
/* to get random private key: y */
/* remember y is short lived private key */
} else {
}
/* e: y */
#endif /* RAND */
#ifdef MYRAND
printf("myrand random_number as Y ================\n");
for (i = 0; i < 5; i++) {
for (j = 0; j < 4; j++) {
}
printf("\n");
}
#endif /* MYRAND */
switch (dhgp_id) {
case GROUP_1024:
plen = 128;
tmp = dhgp1_pVal;
break;
case GROUP_1280:
plen = 160;
tmp = dhgp2_pVal;
break;
case GROUP_1536:
plen = 192;
tmp = dhgp3_pVal;
break;
case GROUP_2048:
plen = 256;
tmp = dhgp4_pVal;
break;
}
"BIGNUM_get_pubkey: big_init failed. n size=%d",
err = BIG_NO_MEM;
goto ret2;
}
"BIGNUM_get_pubkey: big_init failed. result size=%d",
CHARLEN2BIGNUMLEN(512));
err = BIG_NO_MEM;
goto ret3;
}
if (big_cmp_abs(&a, &n) > 0) {
"BIGNUM_get_pubkey: big_cmp_abs error.");
goto ret4;
}
/* perform computation on big numbers to get seskey */
/* a^e mod n */
/* i.e., (g^x mod p)^y mod p */
"BIGNUM_get_pubkey: big_modexp result error");
err = BIG_NO_MEM;
goto ret4;
}
/* convert big number ses_key to bytestring */
/*
* This call converts from big number format to
* byte-big-endian format. big number format is words in
* little endian order, but bytes within words in native byte
* order
*/
/* we can store another copy in ndlp */
} else {
/* for end-to-end auth */
}
"BIGNUM_get_pubkey: after seskey cal: 0x%x 0x%x 0x%x",
/* to get pub_key: g^y mod p, g is 2 */
"BIGNUM_get_pubkey: big_init failed. g size=1");
err = BIG_NO_MEM;
goto ret4;
}
"BIGNUM_get_pubkey: big_init failed. result1 size=%d",
CHARLEN2BIGNUMLEN(512));
err = BIG_NO_MEM;
goto ret5;
}
(unsigned char *)&gen, sizeof (BIG_CHUNK_TYPE));
"BIGNUM_get_pubkey: big_modexp result1 error");
err = BIG_NO_MEM;
goto ret6;
}
/* convert big number pub_key to bytestring */
/* save another copy in ndlp */
} else {
/* for end-to-end auth */
}
"BIGNUM_get_pubkey: after pubkey cal: 0x%x 0x%x 0x%x",
ret6:
ret5:
big_finish(&g);
ret4:
big_finish(&result);
ret3:
big_finish(&n);
ret2:
big_finish(&e);
ret1:
big_finish(&a);
return (err);
} /* emlxs_BIGNUM_get_pubkey */
/*
* g^x mod p x is the priv_key g and p are wellknow based on dhgp_id
*/
/* ARGSUSED */
static BIG_ERR_CODE
{
#ifdef BIGNUM_CHUNK_32
#else
#endif /* BIGNUM_CHUNK_32 */
"BIGNUM_get_dhval: did=0x%x privkey_len=0x%x dhgp_id=0x%x",
"BIGNUM_get_dhval: big_init failed. result1 size=%d",
CHARLEN2BIGNUMLEN(512));
err = BIG_NO_MEM;
return (err);
}
"BIGNUM_get_dhval: big_init failed. g size=1");
err = BIG_NO_MEM;
goto ret1;
}
/* get g */
"BIGNUM_get_dhval: big_init failed. e size=%d",
err = BIG_NO_MEM;
goto ret2;
}
/* get x */
switch (dhgp_id) {
case GROUP_1024:
plen = 128;
tmp = dhgp1_pVal;
break;
case GROUP_1280:
plen = 160;
tmp = dhgp2_pVal;
break;
case GROUP_1536:
plen = 192;
tmp = dhgp3_pVal;
break;
case GROUP_2048:
plen = 256;
tmp = dhgp4_pVal;
break;
}
"BIGNUM_get_dhval: big_init failed. n size=%d",
err = BIG_NO_MEM;
goto ret3;
}
/* get p */
/* to cal: (g^x mod p) */
"BIGNUM_get_dhval: big_modexp result1 error");
goto ret4;
}
/* convert big number pub_key to bytestring */
/* save another copy in partner's ndlp */
&result1,
} else {
&result1,
}
} else {
(void *)dhval,
}
ret4:
ret3:
big_finish(&e);
ret2:
big_finish(&n);
ret1:
big_finish(&g);
return (err);
} /* emlxs_BIGNUM_get_dhval */
/*
* to get ((g^y mod p)^x mod p) a^e mod n
*/
void *pubkey,
{
"BIGNUM_pubkey: dhvallen=0x%x dhgp_id=0x%x",
"BIGNUM_pubkey: big_init failed. a size=%d",
err = BIG_NO_MEM;
return (err);
}
/* get g^y mod p */
"BIGNUM_pubkey: big_init failed. e size=%d",
err = BIG_NO_MEM;
goto ret1;
}
/* get x */
switch (dhgp_id) {
case GROUP_1024:
plen = 128;
tmp = dhgp1_pVal;
break;
case GROUP_1280:
plen = 160;
tmp = dhgp2_pVal;
break;
case GROUP_1536:
plen = 192;
tmp = dhgp3_pVal;
break;
case GROUP_2048:
plen = 256;
tmp = dhgp4_pVal;
break;
}
"BIGNUM_pubkey: big_init failed. n size=%d",
err = BIG_NO_MEM;
goto ret2;
}
"BIGNUM_pubkey: big_init failed. result size=%d",
CHARLEN2BIGNUMLEN(512));
err = BIG_NO_MEM;
goto ret3;
}
if (big_cmp_abs(&a, &n) > 0) {
"BIGNUM_pubkey: big_cmp_abs error");
goto ret4;
}
"BIGNUM_pubkey: big_modexp result error");
err = BIG_NO_MEM;
goto ret4;
}
/* This pubkey is actually session key */
ret4:
big_finish(&result);
ret3:
big_finish(&n);
ret2:
big_finish(&e);
ret1:
big_finish(&a);
return (err);
} /* emlxs_BIGNUM_pubkey */
/*
* key: x dhval: (g^y mod p) tran_id: Ti bi_cval: C2 hash_id: H dhgp_id: p/g
*
* Cai = H (C2 || ((g^y mod p)^x mod p) )
*
*/
/* ARGSUSED */
void *Cai,
{
"hash_Cai: 0x%x 0x%x 0x%x 0x%x 0x%x",
/* this pubkey obtained is actually the session key */
/*
* pubkey: ((g^y mod p)^x mod p)
*/
"hash_Cai: MD5 BIGNUM_pubkey error: 0x%x",
err);
return (err);
}
if (pubkey_len == 0) {
"hash_Cai: MD5 BIGNUM_pubkey error: len=0");
return (err);
}
/* store extra copy */
} else {
}
}
"hash_Cai: SHA1 BIGNUM_pubkey error: 0x%x",
err);
return (err);
}
if (pubkey_len == 0) {
"hash_Cai: SA1 BUM_pubkey error: key_len=0");
return (err);
}
(void *)node_dhc->hrsp_ses_key,
/* store extra copy */
} else {
}
}
return (err);
} /* emlxs_hash_Cai */
/*
* This routine is to verify the DHCHAP_Reply from initiator by the host
* as the responder.
*
* flag: 1: if host is the responder 0: if host is the initiator
*
* if bi_cval != NULL, this routine is used to calculate the response based
* on the challenge from initiator as part of
* DHCHAP_Reply for bi-dirctional authentication.
*
*/
/* ARGSUSED */
static uint32_t *
{ /* always 0 for now */
/* union challenge_val un_cval; */
char *remote_key;
} else {
/*
* in case of end-to-end auth, this remote password should be
* the password associated with the remote entity. (i.e.,)
* for now it is actually local_password.
*/
}
if (flag == 0) {
} else {
}
"hash_verification: 0x%x 0x%x hash_id=0x%x dhgp_id=0x%x",
if (dhval_len == 0) {
/* NULL DHCHAP group */
(unsigned char *)remote_key,
} else {
(unsigned char *)remote_key,
}
MD5_LEN);
} else {
MD5_LEN);
}
"hash_verification: alloc failed");
return (NULL);
} else {
bcopy((void *)md5_digest,
}
}
} else {
}
SHA1_LEN);
} else {
SHA1_LEN);
}
"hash_verification: alloc failed");
return (NULL);
} else {
bcopy((void *)sha1_digest,
}
}
"hash_verification: hash_val=0x%x",
} else {
/* DHCHAP group 1,2,3,4 */
/*
* host received (g^x mod p) as dhval host has its own
* private key y as node_dhc->hrsp_priv_key[] host has its
* original challenge c as node_dhc->hrsp_cval[]
*
* H(c || (g^x mod p)^y mod p) = Cai H(Ti || Km || Cai) =
* hash_val returned. Ti : tran_id, Km : shared secret, Cai:
* obtained above.
*/
} else {
}
}
} else {
}
}
} else {
(void *)cval,
}
"hash_verification: N-Null gp. 0x%x 0x%x",
"hash_verification: Cai error. ret=0x%x",
err);
return (NULL);
}
(unsigned char *)remote_key,
} else {
(unsigned char *)remote_key,
}
"hash_vf: alloc failed(Non-NULL dh)");
return (NULL);
} else {
bcopy((void *)&md5_digest,
}
}
} else {
}
"hash_vf: val alloc failed (Non-NULL dh)");
return (NULL);
} else {
bcopy((void *)&sha1_digest,
}
}
"hash_verification: hash_val=0x%x",
}
} /* emlxs_hash_verification */
/*
* When DHCHAP_Success msg was sent from responder to the initiator,
* with bi-directional authentication requested, the
* DHCHAP_Success contains the response R2 to the challenge C2 received.
*
* DHCHAP response R2: The value of R2 is computed using the hash function
* H() selected by the HashID parameter of the
* DHCHAP_Challenge msg, and the augmented challenge Ca2.
*
* NULL DH group: Ca2 = C2 Non NULL DH group: Ca2 = H(C2 ||
* (g^y mod p)^x mod p)) x is selected by the authentication responder
* which is the node_dhc->hrsp_priv_key[] (g^y mod p) is dhval received
* from authentication initiator.
*
* R2 = H(Ti || Km || Ca2) Ti is the least significant byte of the
* transaction id. Km is the secret associated with the
* authentication responder.
*
* emlxs_hash_get_R2 and emlxs_hash_verification could be mergerd into one
* function later.
*
*/
static uint32_t *
{
/* union challenge_val un_cval; */
char *mykey;
} else {
if (flag == 0) {
} else {
}
}
"hash_get_R2:0x%x 0x%x dhgp_id=0x%x mytran_id=0x%x",
} else {
/* in case of end-to-end mykey should be remote_password */
}
if (dhval_len == 0) {
/* NULL DHCHAP group */
} else {
}
return (NULL);
} else {
bcopy((void *)md5_digest,
}
}
} else {
}
return (NULL);
} else {
bcopy((void *)sha1_digest,
}
}
} else {
/* NON-NULL DHCHAP */
}
}
} else {
}
}
}
/* use bi_cval here */
/*
* key: x dhval: (g^y mod p) tran_id: Ti bi_cval: C2 hash_id:
* H dhgp_id: p/g
*
* Cai = H (C2 || ((g^y mod p)^x mod p) )
*
* R2 = H (Ti || Km || Cai)
*/
"hash_get_R2: hash_Cai error. ret=0x%x",
err);
return (NULL);
}
/*
* Here we use the same key: mykey, note: this mykey
* should be the key associated with the
* authentication responder i.e. the remote key.
*/
else
"hash_get_R2: hash_val MD5 alloc failed.");
return (NULL);
} else {
bcopy((void *)md5_digest,
}
}
} else {
}
"hash_get_R2: hash_val SHA1 alloc failed.");
return (NULL);
} else {
bcopy((void *)sha1_digest,
}
}
}
} /* emlxs_hash_get_R2 */
static void
char *subclass,
char *info)
{
}
return;
}
lwwn[7]);
return;
}
rwwn[7]);
"EC_%s", DRIVER_NAME);
== DDI_SUCCESS) {
lwwn_str) == DDI_SUCCESS) &&
rwwn_str) == DDI_SUCCESS) &&
info) == DDI_SUCCESS) &&
ext_class) == DDI_SUCCESS) &&
ext_subclass) == DDI_SUCCESS)) {
(void) ddi_log_sysevent(dip,
NULL,
}
}
return;
} /* emlxs_log_auth_event() */
/* **************************** AUTH DHC INTERFACE ************************* */
extern int
{
uint32_t i;
/* The ubp represents an unsolicted PLOGI */
/* The sbp represents a solicted PLOGI */
/* Return is authentication is not enabled */
return (1);
}
return (1);
}
if (!fabric_switch && fabric) {
return (1);
}
/* Return if fcsp support to this node is not enabled */
return (1);
}
/* Clear previous authentication */
}
/* Intialize node */
/* Acquire auth configuration */
if (fabric_switch) {
(uint8_t *)emlxs_fabric_wwn);
(uint8_t *)emlxs_fabric_wwn);
} else {
}
if (!auth_cfg) {
"Not started. No auth cfg entry found. did=0x%x",
return (1);
}
if (fabric_switch) {
} else {
}
if (!auth_key) {
"Not started. No auth key entry found. did=0x%x",
return (1);
}
if (fabric_switch) {
} else {
}
/* Remote port does not support fcsp */
switch (auth_cfg->authentication_mode) {
case AUTH_MODE_PASSIVE:
"Not started. Auth unsupported. did=0x%x",
NODE_STATE_AUTH_DISABLED, 0, 0);
return (1);
case AUTH_MODE_ACTIVE:
"Failed. Auth unsupported. did=0x%x",
/*
* Save packet for deferred completion until
* authentication is complete
*/
goto failed;
case AUTH_MODE_DISABLED:
default:
"Not started. Auth mode=disabled. did=0x%x",
NODE_STATE_AUTH_DISABLED, 0, 0);
return (1);
}
} else { /* Remote port supports fcsp */
switch (auth_cfg->authentication_mode) {
case AUTH_MODE_PASSIVE:
case AUTH_MODE_ACTIVE:
/* start auth */
break;
case AUTH_MODE_DISABLED:
default:
"Failed. Auth mode=disabled. did=0x%x",
/*
* Save packet for deferred completion until
* authentication is complete
*/
goto failed;
}
}
/* We have a GO for authentication */
/*
* Save pointers for deferred completion until authentication is
* complete
*/
/* Program node's auth cfg */
/*
* If remote password type is "ignore", then only unidirectional auth
* is allowed
*/
} else {
}
for (i = 0; i < 4; i++) {
switch (auth_cfg->authentication_type_priority[i]) {
case ELX_DHCHAP:
break;
case ELX_FCAP:
break;
case ELX_FCPAP:
break;
case ELX_KERBEROS:
break;
default:
0;
break;
}
switch (auth_cfg->hash_priority[i]) {
case ELX_SHA1:
break;
case ELX_MD5:
break;
default:
break;
}
}
for (i = 0; i < 8; i++) {
switch (auth_cfg->dh_group_priority[i]) {
case ELX_GROUP_NULL:
break;
case ELX_GROUP_1024:
break;
case ELX_GROUP_1280:
break;
case ELX_GROUP_1536:
break;
case ELX_GROUP_2048:
break;
default:
break;
}
}
/* Program the node's key */
if (auth_key) {
sizeof (emlxs_auth_key_t));
8);
}
node_dhc->nlp_authrsp_tmocnt = 0;
node_dhc->nlp_authrsp_tmo = 0;
if (deferred_ubp) {
/* Acknowledge the unsolicited PLOGI */
/* This should trigger the other port to start authentication */
"Not started. Unable to send PLOGI ACC. did=0x%x",
goto failed;
}
/* Start the auth rsp timer */
"Authrsp timer activated. did=0x%x",
/* The next state should be emlxs_rcv_auth_msg_unmapped_node */
} else {
"Auth initiated. did=0x%x limit=%d sbp=%p",
"Failed. Auth initiation failed. did=0x%x",
goto failed;
}
}
return (0);
/* Complete authentication with failed status */
return (0);
} /* emlxs_dhc_auth_start() */
/* This is called to indicate the driver has lost connection with this node */
extern void
{
uint32_t i;
/* Nothing to stop */
return;
}
if (ndlp) {
/* Nothing to stop */
return;
}
}
} else { /* Lost connection to all nodes for this port */
for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
if (!ndlp) {
continue;
}
continue;
}
NODE_STATE_UNKNOWN, 0, 0);
}
}
}
return;
} /* emlxs_dhc_auth_stop */
/* state = 0 - Successful completion. Continue connection to node */
/* state = 1 - Failed completion. Do not continue with connection to node */
/* state = 2 - Stopped completion. Do not continue with connection to node */
static void
{
"did=0x%x status=%d sbp=%p ubp=%p",
if (status == 1) {
if (fabric_switch) {
/* Virtual link down */
} else if (!fabric) {
/* Port offline */
}
}
/* Send a LOGO if authentication was not successful */
if (status == 1) {
"Sending LOGO to did=0x%x...",
}
/* Process deferred cmpl now */
node_dhc->deferred_sbp = 0;
node_dhc->deferred_ubp = 0;
return;
} /* emlxs_dhc_auth_complete */
extern void
{
return;
} /* emlxs_dhc_attach() */
extern void
{
return;
} /* emlxs_dhc_detach() */
extern void
{
/* Return is authentication is not enabled */
sizeof ("fcsp:Disabled (0)"));
return;
}
sizeof ("fcsp:Disabled (npiv)"));
return;
}
if (!fabric_switch && fabric) {
sizeof ("fcsp:Disabled (fs)"));
return;
}
/* Return if fcsp support to this node is not enabled */
sizeof ("fcsp:Disabled (e2e)"));
return;
}
if (fabric_switch) {
(uint8_t *)emlxs_fabric_wwn);
(uint8_t *)emlxs_fabric_wwn);
sizeof ("fcsp:Disabled (1)"));
return;
}
}
return;
} /* emlxs_dhc_init_sp() */
extern uint32_t
{
/* Reject login */
return (1);
}
/* Remote host supports FCSP */
/* Continue login */
return (0);
}
/* Auth disabled in host */
/* Continue login */
return (0);
}
/* Auth disabled for npiv */
/* Continue login */
return (0);
}
if (!fabric_switch && fabric) {
/* Continue login */
return (0);
}
/* Auth disabled for p2p */
/* Continue login */
return (0);
}
/* Remote port does NOT support FCSP */
/* Host has FCSP enabled */
/* Now check to make sure auth mode for this port is also enabled */
/* Acquire auth configuration */
if (fabric_switch) {
(uint8_t *)emlxs_fabric_wwn);
(uint8_t *)emlxs_fabric_wwn);
} else {
}
/* Reject login */
return (1);
}
return (0);
} /* emlxs_dhc_verify_login() */
/*
* ! emlxs_dhc_reauth_timeout
*
* \pre \post \param phba \param arg1: \param arg2: ndlp to which the host
* is to be authenticated. \return void
*
* \b Description:
*
* Timeout handler for reauthentication heartbeat.
*
* The reauthentication heart beat will be triggered 1 min by default after
* the first authentication success. reauth_intval is
* configurable. if reauth_intval is set to zero, it means no reauth heart
* beat anymore.
*
* reauth heart beat will be triggered by IOCTL call from user space. Reauth
* heart beat will go through the authentication process
* all over again without causing IO traffic disruption. Initially it should
* be triggered after authentication success.
* HBAnyware or other utility.
*
*/
/* ARGSUSED */
extern void
void *arg1,
void *arg2)
{
"Reauth timeout. Reauth no longer enabled. 0x%x %x",
return;
}
/* This should not happen!! */
"Reauth timeout. Fabric in auth. Quiting. 0x%x %x",
return;
}
"Reauth timeout. Auth not done. Restarting. 0x%x %x",
goto restart;
}
/*
* This might happen, the ndlp is doing reauthencation. meaning ndlp
* is being re-authenticated to the host. Thus not necessary to have
* host re-authenticated to the ndlp at this point because ndlp might
* support bi-directional auth. we can just simply donothing and
* restart the timer.
*/
"Reauth timeout. Fabric in reauth. Restarting. 0x%x %x",
goto restart;
}
/*
* node's reauth heart beat is running already, cancel it first and
* then restart
*/
"Reauth timeout. Fabric in reauth. Restarting. 0x%x %x",
goto restart;
}
"Reauth timeout. Auth initiated. did=0x%x",
/* Attempt to restart authentication */
"Reauth timeout. Auth initiation failed. 0x%x %x",
return;
}
return;
return;
} /* emlxs_dhc_reauth_timeout */
static void
{
timeout =
/* Get last successful auth time */
} else if (node_dhc->parent_auth_cfg) {
} else {
last_auth_time = 0;
}
if (last_auth_time) {
/* Validate reauth_tmo */
if ((reauth_tmo < drv_time) ||
}
} else {
}
"Reauth enabled. did=0x%x state=%x tmo=%d,%d",
(reauth_tmo - drv_time));
} else {
node_dhc->nlp_reauth_tmo = 0;
"Reauth disabled. did=0x%x state=%x",
}
return;
} /* emlxs_dhc_set_reauth_time */
/* ARGSUSED */
extern void
void *arg1,
void *arg2)
{
node_dhc->nlp_authrsp_tmo = 0;
"Authrsp timeout. did=0x%x count=%d",
/*
* According to the FC-SP spec v1.8 pp76.
*
* When the AUTH_TMO error is detected, the entity may: 1. Act as if the
* authentication transaction has failed and terminate the
* communication; or 2. Restart a new authentication transaction, by
* sending an AUTH_Reject msg with Reason Code `Logical Error' and
* Reason Code Explanation 'Restart Authentication Protocol', The
* action performed by the entity receiving such a AUTH_Reject should
* restart the authentication Transaction by sending a new
* AUTH_Negotiate. We plan to use 2 as the action for now.
*
*/
/* Generate a remove event for the nodelist entry */
} else {
/* Generate a recovery event for the nodelist entry */
}
/*
* It is expected the other party should restart the authentication
* transaction
*/
return;
} /* emlxs_dhc_authrsp_timeout() */
/* **************************** AUTH CFG MANAGEMENT ************************ */
/* auth_lock must be held */
static emlxs_auth_cfg_t *
{
if (rwwpn) {
/* lwwpn, rwwpn */
if (auth_cfg) {
return (auth_cfg);
}
/* null, rwwpn */
if (auth_cfg) {
return (auth_cfg);
}
}
/* lwwpn, null */
if (auth_cfg) {
return (auth_cfg);
}
/* null, null */
} /* emlxs_auth_cfg_find() */
static void
{
/* Destroy old table if one exists */
/* Zero default entry */
/* Configure the default entry */
auth_cfg->hash_priority[0] =
auth_cfg->dh_group_priority[0] =
return;
} /* emlxs_auth_cfg_init() */
static void
{
}
return;
} /* emlxs_auth_cfg_fini() */
static void
{
/* Create and add new entry */
"%s:%s:%x:%x:%x:%x%x%x%x:%x%x%x%x:%x%x%x%x%x%x%x%x:%x",
auth_cfg->hash_priority[0],
} /* emlxs_auth_cfg_print() */
/* auth_lock must be held */
static emlxs_auth_cfg_t *
{
return (NULL);
}
/* Check for default entry */
}
/* Find pwd entry for this local port */
/* Check for exact wwpn match */
(void *)lwwpn, 8) != 0) {
continue;
}
/* Find pwd entry for remote port */
/* Check for exact wwpn match */
(void *)rwwpn, 8) != 0) {
continue;
}
return (auth_cfg);
}
return (NULL);
} /* emlxs_auth_cfg_get() */
/* auth_lock must be held */
static emlxs_auth_cfg_t *
{
/* First check if entry already exists */
if (auth_cfg) {
return (auth_cfg);
}
/* Allocate entry */
if (!auth_cfg) {
return (NULL);
}
/* Add to list */
hba->auth_cfg_count++;
/* Initialize name pair */
if (lwwpn) {
}
if (rwwpn) {
}
return (auth_cfg);
} /* emlxs_auth_cfg_create() */
/* auth_lock must be held */
static void
{
if (!auth_cfg) {
return;
}
return;
}
/* Remove from list */
hba->auth_cfg_count--;
/* Remove node binding */
}
return;
} /* emlxs_auth_cfg_destroy() */
/* auth_lock must be held */
static void
{
char **arrayp;
char *prop_str;
uint32_t i;
/* Check for the per adapter setting */
cnt = 0;
/* Check for the global setting */
cnt = 0;
}
return;
}
for (i = 0; i < cnt; i++) {
break;
}
/* parse the string */
"Error parsing auth_cfgs property. entry=%d", i);
continue;
}
if (!auth_cfg2) {
"Out of memory parsing auth_cfgs property. ey=%d",
i);
return;
}
sizeof (emlxs_auth_cfg_t));
}
return;
} /* emlxs_auth_cfg_read() */
/* auth_lock must be held */
static uint32_t
char *prop_str)
{
uint32_t j;
uint32_t i;
char *s;
s = prop_str;
/* Read local wwpn */
for (j = 0; j < 8; j++) {
c1 = *s++;
} else {
"Cfg err:Invalid LWWPN found. byte=%d hi_nibble=%c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid LWWPN found. %d %c",
j, c1);
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after LWWPN.");
goto out;
}
/* Read remote wwpn */
for (j = 0; j < 8; j++) {
c1 = *s++;
} else {
"Cfg err: Invalid RWWPN found.byte=%d hi_nibble=%c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid RWWPN found. %d %c",
j, c1);
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after RWWPN.");
goto out;
}
/* Read auth_tov (%x) */
sum = 0;
do {
c1 = *s++;
} else {
"Cfg err: Invalid auth_tov found. c=%c sum=%d",
errors++;
}
} while (*s != ':' && *s != 0);
if (*s++ != ':') {
"Cfg err: Invalid delimiter after auth_tov.");
goto out;
}
/* Read auth_mode */
sum = 0;
do {
c1 = *s++;
} else {
"Cfg err: Invalid auth_mode found. c=%c sum=%d",
errors++;
}
} while (*s != ':' && *s != 0);
if (*s++ != ':') {
"Config error: Invalid delimiter after auth_mode.");
goto out;
}
/* Read auth_bidir */
sum = 0;
do {
c1 = *s++;
} else {
"Cfg err: Invalid auth_bidir found. c=%c sum=%d",
errors++;
}
} while (*s != ':' && *s != 0);
if (*s++ != ':') {
"Cfg err: Invalid delimiter after auth_bidir.");
goto out;
}
/* Read type_priority[4] */
for (i = 0; i < 4; i++) {
c1 = *s++;
} else {
"Cfg err: Invalid type_pty[%d] found. c=%c sum=%d",
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after type_priority.");
goto out;
}
/* Read hash_priority[4] */
for (i = 0; i < 4; i++) {
c1 = *s++;
} else {
"Cfg err: Invalid hash_priority[%d] fd. %c %d",
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after hash_priority.");
goto out;
}
/* Read group_priority[8] */
for (i = 0; i < 8; i++) {
c1 = *s++;
} else {
"Cfg err: Invalid group_priority[%d] fd. %c %d",
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after group_priority.");
goto out;
}
/* Read reauth_tov */
sum = 0;
do {
c1 = *s++;
} else {
"Cfg err: Invalid reauth_tov found. c=%c sum=%d",
errors++;
}
} while (*s != ':' && *s != 0);
if (errors) {
goto out;
}
/* Verify values */
/* Check authentication_timeout */
}
/* Check authentication_mode */
}
/* Check bidirectional */
}
/* Check authentication_type_priority and hash_priority */
for (i = 0; i < 4; i++) {
if (auth_cfg->authentication_type_priority[i] >
/* Set to current default */
}
/* Set to current default */
auth_cfg->hash_priority[i] =
}
}
/* Check dh_group_priority */
for (i = 0; i < 8; i++) {
/* Set to current default */
auth_cfg->dh_group_priority[i] =
}
}
/* Check reauthenticate_time_interval */
} else if (auth_cfg->reauthenticate_time_interval >
}
out:
if (errors) {
return (0);
}
return (1);
} /* emlxs_auth_cfg_parse() */
/* **************************** AUTH KEY MANAGEMENT ************************* */
/* auth_lock must be held */
extern emlxs_auth_key_t *
{
if (rwwpn) {
/* lwwpn, rwwpn */
if (auth_key) {
return (auth_key);
}
/* null, rwwpn */
if (auth_key) {
return (auth_key);
}
}
/* lwwpn, null */
if (auth_key) {
return (auth_key);
}
return (NULL);
} /* emlxs_auth_key_find() */
static void
{
/* Destroy old table if one exists */
/* Zero default entry */
/* Configure the default entry */
return;
} /* emlxs_auth_key_init() */
static void
{
}
return;
} /* emlxs_auth_key_fini() */
static void
{
"auth-key> %s:%s:%x:*%d chars*:%x:*%d chars*",
return;
} /* emlxs_auth_key_print() */
/* auth_lock must be held */
static emlxs_auth_key_t *
{
return (NULL);
}
/* Check for default entry */
}
/* Find pwd entry for this local port */
/* Check for exact wwpn match */
(void *)lwwpn, 8) != 0) {
continue;
}
/* Find pwd entry for remote port */
/* Check for exact wwpn match */
(void *)rwwpn, 8) != 0) {
continue;
}
return (auth_key);
}
return (NULL);
} /* emlxs_auth_key_get() */
/* auth_lock must be held */
static emlxs_auth_key_t *
{
/* First check if entry already exists */
if (auth_key) {
return (auth_key);
}
/* Allocate entry */
if (!auth_key) {
return (NULL);
}
/* Initialize name pair */
if (lwwpn) {
}
if (rwwpn) {
}
/* Initialize type */
/* Add to list */
hba->auth_key_count++;
return (auth_key);
} /* emlxs_auth_key_create() */
/* auth_lock must be held */
static void
{
if (!auth_key) {
return;
}
return;
}
/* Remove from list */
hba->auth_key_count--;
/* Remove node binding */
}
return;
} /* emlxs_auth_key_destroy() */
/* auth_lock must be held */
static void
{
char **arrayp;
char *prop_str;
uint32_t i;
/* Check for the per adapter setting */
cnt = 0;
/* Check for the global setting */
cnt = 0;
}
return;
}
for (i = 0; i < cnt; i++) {
break;
}
/* parse the string */
"Error parsing auth_keys property. entry=%d", i);
continue;
}
if (!auth_key2) {
"Out of memory parsing auth_keys property. %d",
i);
return;
}
}
return;
} /* emlxs_auth_key_read() */
/* auth_lock must be held */
static uint32_t
char *prop_str)
{
uint32_t j;
char *s;
s = prop_str;
/* Read local wwpn */
for (j = 0; j < 8; j++) {
c1 = *s++;
} else {
"Cfg err: Invalid LWWPN found. %d %c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid LWWPN found. %d %c",
j, c1);
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after LWWPN.");
goto out;
}
/* Read remote wwpn */
for (j = 0; j < 8; j++) {
c1 = *s++;
} else {
"Cfg err: Invalid RWWPN found.%d %c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid RWWPN found. %d %c",
j, c1);
errors++;
}
}
if (*s++ != ':') {
"Cfg err: Invalid delimiter after RWWPN.");
goto out;
}
/* Read lpwd type (%x) */
sum = 0;
do {
c1 = *s++;
} else {
"Cfg err: Invalid lpwd type found. %c %d",
errors++;
}
} while (*s != ':' && *s != 0);
if (*s++ != ':') {
"Cfg err: Invalid delimiter after lpwd type.");
goto out;
}
/* Read lpwd */
j = 0;
switch (auth_key->local_password_type) {
case 1: /* ACSII */
while (*s != ':' && *s != 0) {
*np++ = *s++;
j++;
}
break;
case 2: /* Hex */
do {
c1 = *s++;
} else {
"Cfg err: Invalid lpwd found. %d %c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid lpwd found. %d %c",
j, c1);
errors++;
}
j++;
} while (*s != ':' && *s != 0);
break;
case 0: /* Ignore */
case 3: /* Ignore */
break;
default:
"Config error: Invalid lpwd type found. type=%x",
errors++;
goto out;
}
if (*s++ != ':') {
"Config error: Invalid delimiter after lpwd.");
goto out;
}
/* Read rpwd type (%x) */
sum = 0;
do {
c1 = *s++;
} else {
"Config error: Invalid rpwd type found. %c %d",
errors++;
}
} while (*s != ':' && *s != 0);
if (*s++ != ':') {
"Config error: Invalid delimiter after rpwd type.");
goto out;
}
/* Read rpwd */
j = 0;
switch (auth_key->remote_password_type) {
case 1: /* ACSII */
while (*s != ':' && *s != 0) {
*np++ = *s++;
j++;
}
break;
case 2: /* Hex */
do {
c1 = *s++;
} else {
"Cfg err: Invalid rpwd found. %d %c",
j, c1);
errors++;
}
c1 = *s++;
} else {
"Cfg err: Invalid rpwd found. %d %c",
j, c1);
errors++;
}
j++;
} while (*s != ':' && *s != 0);
break;
case 0: /* Ignore */
case 3: /* Ignore */
break;
default:
"Cfg error: Invalid rpwd type found. type=%x",
errors++;
goto out;
}
if (errors) {
goto out;
}
/* Verify values */
if (auth_key->local_password_type == 0 ||
auth_key->local_password_length == 0) {
sizeof (auth_key->local_password));
}
if (auth_key->remote_password_type == 0 ||
auth_key->remote_password_length == 0) {
sizeof (auth_key->remote_password));
}
/* Display entry */
out:
if (errors) {
return (0);
}
return (1);
} /* emlxs_auth_key_parse() */
/* ************************** AUTH DFCLIB SUPPORT *********************** */
/* Provides DFC support for emlxs_dfc_init_auth() */
extern uint32_t
{
/* Return is authentication is not enabled */
"dhc_init_auth. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
/* Scan for lwwpn match */
continue;
}
break;
}
}
if (vpi == MAX_VPORTS) {
"dhc_init_auth: lwwpn not found. %s",
return (DFC_AUTH_WWN_NOT_FOUND);
}
/* Scan for fabric node */
"dhc_init_auth: fabric node not found.");
return (DFC_AUTH_WWN_NOT_FOUND);
}
} else {
/* Scan for rwwpn match */
"dhc_init_auth: rwwpn not found. %s",
return (DFC_AUTH_WWN_NOT_FOUND);
}
}
return (DFC_IO_ERROR);
}
return (DFC_AUTH_AUTHENTICATION_GOINGON);
}
}
/* Attempt to start authentication */
return (DFC_IO_ERROR);
}
return (0);
} /* emlxs_dhc_init_auth() */
/* Provides DFC support for emlxs_dfc_get_auth_cfg() */
extern uint32_t
{
uint32_t i;
/* Return is authentication is not enabled */
"dhc_get_auth_cfg. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
if (!auth_cfg) {
"dhc_get_auth_cfg: entry not found. %s:%s",
return (DFC_AUTH_NOT_CONFIGURED);
}
for (i = 0; i < 4; i++) {
fcsp_cfg->type_priority[i] =
fcsp_cfg->hash_priority[i] =
auth_cfg->hash_priority[i];
}
for (i = 0; i < 8; i++) {
}
return (0);
} /* emlxs_dhc_get_auth_cfg() */
/* Provides DFC support for emlxs_dfc_set_auth_cfg() */
extern uint32_t
{
uint32_t i;
/* Return if authentication is not enabled */
"dhc_add_auth_cfg. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
if (auth_key &&
/* Verify local password */
"dhc_add_auth_cfg: Invalid local password.");
return (DFC_AUTH_COMPARE_FAILED);
}
}
/* Create entry */
if (!auth_cfg) {
"dhc_add_auth_cfg: Out of memory.");
return (DFC_SYSRES_ERROR);
}
/* Init entry */
for (i = 0; i < 4; i++) {
fcsp_cfg->type_priority[i];
auth_cfg->hash_priority[i] =
fcsp_cfg->hash_priority[i];
}
for (i = 0; i < 8; i++) {
}
/* Cancel old reauth to restart the new one if necessary */
/* Scan for lwwpn match */
for (i = 0; i < MAX_VPORTS; i++) {
continue;
}
continue;
}
/* Port match found */
emlxs_fabric_wwn, 8) == 0) {
/* Scan for fabric node */
break;
}
} else {
/* Scan for rwwpn match */
break;
}
}
break;
}
return (0);
} /* emlxs_dhc_add_auth_cfg() */
/* Provides DFC support for emlxs_dfc_set_auth_cfg() */
extern uint32_t
{
/* Return is authentication is not enabled */
"dhc_delete_auth_cfg. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
if (auth_key &&
/* Verify local password */
"dhc_delete_auth_cfg: Ivld local pwd.");
return (DFC_AUTH_COMPARE_FAILED);
}
}
if (!auth_cfg) {
"dhc_delete_auth_cfg: entry not found. %s:%s",
return (DFC_AUTH_WWN_NOT_FOUND);
}
/* Destroy cfg entry */
/* Destroy pwd entry */
return (0);
} /* emlxs_dhc_delete_auth_cfg() */
/* Provides DFC support for emlxs_dfc_get_auth_key() */
extern uint32_t
{
/* Return is authentication is not enabled */
"dhc_get_auth_key. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
if (!auth_key) {
"dhc_get_auth_key: entry not found. %s:%s",
return (DFC_AUTH_NOT_CONFIGURED);
}
/*
* bcopy(auth_key->local_password, dfc_auth_pwd->lpw.password,
* dfc_auth_pwd->lpw.length);
*/
/*
* bcopy(auth_key->remote_password, dfc_auth_pwd->rpw.password,
* dfc_auth_pwd->rpw.length);
*/
/*
* bcopy(auth_key->local_password, dfc_auth_pwd->lpw_new.password,
* dfc_auth_pwd->lpw_new.length);
*/
/*
* bcopy(auth_key->remote_password, dfc_auth_pwd->rpw_new.password,
* dfc_auth_pwd->rpw_new.length);
*/
return (0);
} /* emlxs_dhc_get_auth_key() */
/* Provides DFC support for emlxs_dfc_set_auth_key() */
extern uint32_t
{
/* Return is authentication is not enabled */
"dhc_set_auth_key. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
/* Check to make sure localpwd does not equal to remotepwd */
/* if they are given in the same time, if not, see below */
"dhc_set_auth_key. nlpwd==nrpwd");
return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
}
}
/* If entry does not exist, then create entry */
if (!auth_key) {
if (!auth_key) {
"dhc_set_auth_key: Out of memory.");
return (DFC_SYSRES_ERROR);
}
}
/* Check if a new local password is provided */
/* Check if current password should be checked */
/* Verify current local password */
if ((auth_key->local_password_length !=
"dhc_set_auth_key: Invalid local password.");
return (DFC_AUTH_COMPARE_FAILED);
}
}
/*
* Make sure the new local pwd is not equal to the current
* remote pwd if any
*/
if ((auth_key->remote_password_length ==
"dhc_set_auth_key: nlpwd==crpwd");
return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
}
}
/* Update local entry */
sizeof (auth_key->local_password));
sizeof (auth_key->local_password));
}
/* Check if a new remote password is provided */
/* Check if current password should be checked */
/* Verify current remote password */
if ((auth_key->remote_password_length !=
"dhc_set_auth_key: Invalid remote password.");
return (DFC_AUTH_COMPARE_FAILED);
}
}
/*
* Make sure the new remote pwd is not equal to the current
* local pwd if any
*/
if ((auth_key->local_password_length ==
"dhc_set_auth_key: nrpwd==clpwd");
return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
}
}
/* Update remote entry */
sizeof (auth_key->remote_password));
}
/* Update dfc local entry */
/* Update dfc remote entry */
return (0);
} /* emlxs_dhc_set_auth_key() */
/* Provides DFC support for emlxs_dfc_get_auth_status() */
extern uint32_t
{
/* Return is authentication is not enabled */
"dhc_get_auth_status. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
if (!auth_cfg) {
"dhc_get_auth_status: entry not found. %s:%s",
return (DFC_AUTH_NOT_CONFIGURED);
}
} else {
}
update = 0;
/* Check if node is still available */
update = 1;
} else {
}
if (update) {
rc = 0;
} else {
}
return (rc);
} /* emlxs_dhc_get_auth_status() */
/* Provides DFC support for emlxs_dfc_get_auth_list() */
/* auth_lock must be held when calling. */
/* fcsp_cfg must be large enough to hold hba->auth_cfg_count entries */
extern uint32_t
{
uint32_t i;
/* Return if authentication is not enabled */
"dhc_get_auth_cfg_table. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
for (i = 0; i < 4; i++) {
fcsp_cfg->type_priority[i] =
fcsp_cfg->hash_priority[i] =
auth_cfg->hash_priority[i];
}
for (i = 0; i < 8; i++) {
fcsp_cfg->group_priority[i] =
}
fcsp_cfg++;
}
return (0);
} /* emlxs_dhc_get_auth_cfg_table() */
/* Provides DFC support for emlxs_dfc_get_auth_list() */
/* auth_lock must be held when calling. */
/* auth_pwd must be large enough to hold hba->auth_key_count entries */
extern uint32_t
{
/* Return if authentication is not enabled */
"dhc_get_auth_key_table. Auth disabled.");
return (DFC_AUTH_AUTHENTICATION_DISABLED);
}
/*
* bcopy(auth_key->local_password, auth_pwd->lpw.password,
* auth_pwd->lpw.length);
*/
/*
* bcopy(auth_key->remote_password, auth_pwd->rpw.password,
* auth_pwd->rpw.length);
*/
/*
* bcopy(auth_key->local_password,
* auth_pwd->lpw_new.password, auth_pwd->lpw_new.length);
*/
/*
* bcopy(auth_key->remote_password,
* auth_pwd->rpw_new.password, auth_pwd->rpw_new.length);
*/
auth_pwd++;
}
return (0);
} /* emlxs_dhc_get_auth_key_table() */
#endif /* DHCHAP_SUPPORT */