Print this page
4786 emlxs shouldn't abuse ddi_get_time(9f)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dhchap.c
+++ new/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dhchap.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Emulex. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 +/*
27 + * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
28 + */
26 29
27 30
28 31 #include <emlxs.h>
29 32
30 33 #ifdef DHCHAP_SUPPORT
31 34
32 35 #include <md5.h>
33 36 #include <sha1.h>
34 37 #ifdef S10
35 38 #include <sha1_consts.h>
36 39 #else
37 40 #include <sys/sha1_consts.h>
38 41 #endif /* S10 */
39 42 #include <bignum.h>
40 43 #include <sys/time.h>
41 44
42 45 #ifdef S10
43 46 #define BIGNUM_CHUNK_32
44 47 #define BIG_CHUNK_TYPE uint32_t
45 48 #define CHARLEN2BIGNUMLEN(_val) (_val/4)
46 49 #endif /* S10 */
47 50
48 51 #define RAND
49 52
50 53 #ifndef ENABLE
51 54 #define ENABLE 1
52 55 #endif /* ENABLE */
53 56
54 57 #ifndef DISABLE
55 58 #define DISABLE 0
56 59 #endif /* DISABLE */
57 60
58 61
59 62 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
60 63 EMLXS_MSG_DEF(EMLXS_DHCHAP_C);
61 64
62 65 static char *emlxs_dhc_pstate_xlate(uint32_t state);
63 66 static char *emlxs_dhc_nstate_xlate(uint32_t state);
64 67 static uint32_t emlxs_check_dhgp(emlxs_port_t *port, NODELIST *ndlp,
65 68 uint32_t *dh_id, uint16_t cnt, uint32_t *dhgp_id);
66 69 static void emlxs_dhc_set_reauth_time(emlxs_port_t *port,
67 70 emlxs_node_t *ndlp, uint32_t status);
68 71
69 72 static void emlxs_auth_cfg_init(emlxs_hba_t *hba);
70 73 static void emlxs_auth_cfg_fini(emlxs_hba_t *hba);
71 74 static void emlxs_auth_cfg_read(emlxs_hba_t *hba);
72 75 static uint32_t emlxs_auth_cfg_parse(emlxs_hba_t *hba,
73 76 emlxs_auth_cfg_t *config, char *prop_str);
74 77 static emlxs_auth_cfg_t *emlxs_auth_cfg_get(emlxs_hba_t *hba,
75 78 uint8_t *lwwpn, uint8_t *rwwpn);
76 79 static emlxs_auth_cfg_t *emlxs_auth_cfg_create(emlxs_hba_t *hba,
77 80 uint8_t *lwwpn, uint8_t *rwwpn);
78 81 static void emlxs_auth_cfg_destroy(emlxs_hba_t *hba,
79 82 emlxs_auth_cfg_t *auth_cfg);
80 83 static void emlxs_auth_cfg_print(emlxs_hba_t *hba,
81 84 emlxs_auth_cfg_t *auth_cfg);
82 85
83 86 static void emlxs_auth_key_init(emlxs_hba_t *hba);
84 87 static void emlxs_auth_key_fini(emlxs_hba_t *hba);
85 88 static void emlxs_auth_key_read(emlxs_hba_t *hba);
86 89 static uint32_t emlxs_auth_key_parse(emlxs_hba_t *hba,
87 90 emlxs_auth_key_t *auth_key, char *prop_str);
88 91 static emlxs_auth_key_t *emlxs_auth_key_get(emlxs_hba_t *hba,
89 92 uint8_t *lwwpn, uint8_t *rwwpn);
90 93 static emlxs_auth_key_t *emlxs_auth_key_create(emlxs_hba_t *hba,
91 94 uint8_t *lwwpn, uint8_t *rwwpn);
92 95 static void emlxs_auth_key_destroy(emlxs_hba_t *hba,
93 96 emlxs_auth_key_t *auth_key);
94 97 static void emlxs_auth_key_print(emlxs_hba_t *hba,
95 98 emlxs_auth_key_t *auth_key);
96 99
97 100 static void emlxs_get_random_bytes(NODELIST *ndlp, uint8_t *rdn,
98 101 uint32_t len);
99 102 static emlxs_auth_cfg_t *emlxs_auth_cfg_find(emlxs_port_t *port,
100 103 uint8_t *rwwpn);
101 104 static emlxs_auth_key_t *emlxs_auth_key_find(emlxs_port_t *port,
102 105 uint8_t *rwwpn);
103 106 static void emlxs_dhc_auth_complete(emlxs_port_t *port,
104 107 emlxs_node_t *ndlp, uint32_t status);
105 108 static void emlxs_log_auth_event(emlxs_port_t *port, NODELIST *ndlp,
106 109 char *subclass, char *info);
107 110 static int emlxs_issue_auth_negotiate(emlxs_port_t *port,
108 111 emlxs_node_t *ndlp, uint8_t retry);
109 112 static void emlxs_cmpl_auth_negotiate_issue(fc_packet_t *pkt);
110 113 static uint32_t *emlxs_hash_rsp(emlxs_port_t *port,
111 114 emlxs_port_dhc_t *port_dhc, NODELIST *ndlp, uint32_t tran_id,
112 115 union challenge_val un_cval, uint8_t *dhval, uint32_t dhvallen);
113 116 static fc_packet_t *emlxs_prep_els_fc_pkt(emlxs_port_t *port,
114 117 uint32_t d_id, uint32_t cmd_size, uint32_t rsp_size,
115 118 uint32_t datalen, int32_t sleepflag);
116 119
117 120 static uint32_t *emlxs_hash_vrf(emlxs_port_t *port,
118 121 emlxs_port_dhc_t *port_dhc, NODELIST *ndlp, uint32_t tran_id,
119 122 union challenge_val un_cval);
120 123
121 124
122 125 static BIG_ERR_CODE
123 126 emlxs_interm_hash(emlxs_port_t *port, emlxs_port_dhc_t *port_dhc,
124 127 NODELIST *ndlp, void *hash_val, uint32_t tran_id,
125 128 union challenge_val un_cval, uint8_t *dhval, uint32_t *);
126 129
127 130 static BIG_ERR_CODE
128 131 emlxs_BIGNUM_get_pubkey(emlxs_port_t *port, emlxs_port_dhc_t *port_dhc,
129 132 NODELIST *ndlp, uint8_t *dhval, uint32_t *dhvallen,
130 133 uint32_t hash_size, uint32_t dhgp_id);
131 134 static BIG_ERR_CODE
132 135 emlxs_BIGNUM_get_dhval(emlxs_port_t *port, emlxs_port_dhc_t *port_dhc,
133 136 NODELIST *ndlp, uint8_t *dhval, uint32_t *dhval_len,
134 137 uint32_t dhgp_id, uint8_t *priv_key, uint32_t privkey_len);
135 138 static uint32_t *
136 139 emlxs_hash_verification(emlxs_port_t *port, emlxs_port_dhc_t *port_dhc,
137 140 NODELIST *ndlp, uint32_t tran_id, uint8_t *dhval,
138 141 uint32_t dhval_len, uint32_t flag, uint8_t *bi_cval);
139 142
140 143 static uint32_t *
141 144 emlxs_hash_get_R2(emlxs_port_t *port, emlxs_port_dhc_t *port_dhc,
142 145 NODELIST *ndlp, uint32_t tran_id, uint8_t *dhval,
143 146 uint32_t dhval_len, uint32_t flag, uint8_t *bi_cval);
144 147
145 148 static uint32_t emlxs_issue_auth_reject(emlxs_port_t *port,
146 149 NODELIST *ndlp, int retry, uint32_t *arg, uint8_t ReasonCode,
147 150 uint8_t ReasonCodeExplanation);
148 151
149 152 static uint32_t emlxs_disc_neverdev(emlxs_port_t *port, void *arg1,
150 153 void *arg2, void *arg3, void *arg4, uint32_t evt);
151 154 static uint32_t emlxs_rcv_auth_msg_unmapped_node(emlxs_port_t *port,
152 155 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
153 156 static uint32_t emlxs_rcv_auth_msg_npr_node(emlxs_port_t *port,
154 157 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
155 158 static uint32_t emlxs_cmpl_auth_msg_npr_node(emlxs_port_t *port,
156 159 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
157 160 static uint32_t emlxs_rcv_auth_msg_auth_negotiate_issue(emlxs_port_t *port,
158 161 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
159 162 static uint32_t emlxs_cmpl_auth_msg_auth_negotiate_issue(emlxs_port_t *port,
160 163 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
161 164 static uint32_t emlxs_rcv_auth_msg_auth_negotiate_rcv(emlxs_port_t *port,
162 165 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
163 166 static uint32_t emlxs_cmpl_auth_msg_auth_negotiate_rcv(emlxs_port_t *port,
164 167 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
165 168 static uint32_t
166 169 emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next(emlxs_port_t *port,
167 170 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
168 171 static uint32_t
169 172 emlxs_cmpl_auth_msg_auth_negotiate_cmpl_wait4next(emlxs_port_t *port,
170 173 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
171 174 static uint32_t
172 175 emlxs_rcv_auth_msg_dhchap_challenge_issue(emlxs_port_t *port, void *arg1,
173 176 void *arg2, void *arg3, void *arg4, uint32_t evt);
174 177 static uint32_t
175 178 emlxs_cmpl_auth_msg_dhchap_challenge_issue(emlxs_port_t *port, void *arg1,
176 179 void *arg2, void *arg3, void *arg4, uint32_t evt);
177 180 static uint32_t emlxs_rcv_auth_msg_dhchap_reply_issue(emlxs_port_t *port,
178 181 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
179 182 static uint32_t emlxs_cmpl_auth_msg_dhchap_reply_issue(emlxs_port_t *port,
180 183 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
181 184 static uint32_t
182 185 emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next(emlxs_port_t *port,
183 186 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
184 187 static uint32_t
185 188 emlxs_cmpl_auth_msg_dhchap_challenge_cmpl_wait4next(emlxs_port_t *port,
186 189 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
187 190 static uint32_t
188 191 emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next(emlxs_port_t *port,
189 192 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
190 193 static uint32_t
191 194 emlxs_cmpl_auth_msg_dhchap_reply_cmpl_wait4next(emlxs_port_t *port,
192 195 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
193 196 static uint32_t emlxs_rcv_auth_msg_dhchap_success_issue(emlxs_port_t *port,
194 197 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
195 198 static uint32_t
196 199 emlxs_cmpl_auth_msg_dhchap_success_issue(emlxs_port_t *port, void *arg1,
197 200 void *arg2, void *arg3, void *arg4, uint32_t evt);
198 201 static uint32_t
199 202 emlxs_rcv_auth_msg_dhchap_success_issue_wait4next(emlxs_port_t *port,
200 203 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
201 204 static uint32_t
202 205 emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next(emlxs_port_t *port,
203 206 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
204 207 static uint32_t
205 208 emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next(emlxs_port_t *port,
206 209 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
207 210 static uint32_t
208 211 emlxs_cmpl_auth_msg_dhchap_success_cmpl_wait4next(emlxs_port_t *port,
209 212 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
210 213
211 214
212 215 static uint32_t emlxs_device_recov_unmapped_node(emlxs_port_t *port,
213 216 void *arg1, void *arg2, void *arg3, void *arg4, uint32_t evt);
214 217 static uint32_t emlxs_device_rm_npr_node(emlxs_port_t *port, void *arg1,
215 218 void *arg2, void *arg3, void *arg4, uint32_t evt);
216 219 static uint32_t emlxs_device_recov_npr_node(emlxs_port_t *port, void *arg1,
217 220 void *arg2, void *arg3, void *arg4, uint32_t evt);
218 221 static uint32_t emlxs_device_rem_auth(emlxs_port_t *port, void *arg1,
219 222 void *arg2, void *arg3, void *arg4, uint32_t evt);
220 223 static uint32_t emlxs_device_recov_auth(emlxs_port_t *port, void *arg1,
221 224 void *arg2, void *arg3, void *arg4, uint32_t evt);
222 225
223 226 static uint8_t emlxs_null_wwn[8] =
224 227 {0, 0, 0, 0, 0, 0, 0, 0};
225 228 static uint8_t emlxs_fabric_wwn[8] =
226 229 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
227 230
228 231 unsigned char dhgp1_pVal[] =
229 232 {0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8, 0x0A, 0xFA,
230 233 0x8F, 0xC5, 0xE8,
231 234 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C,
232 235 0x25, 0x65, 0x76,
233 236 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13, 0xD6,
234 237 0x92, 0xC6, 0xE0,
235 238 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60,
236 239 0x89, 0xDA, 0xD1,
237 240 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
238 241 0xB1, 0x5D, 0x49,
239 242 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85, 0xC5, 0x29, 0xF5, 0x66, 0x66,
240 243 0x0E, 0x57, 0xEC,
241 244 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97,
242 245 0x6E, 0xAA, 0x9A,
243 246 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F, 0xC6, 0x1D, 0x2F, 0xC0,
244 247 0xEB, 0x06, 0xE3,
245 248 };
246 249
247 250 unsigned char dhgp2_pVal[] =
248 251 {0xD7, 0x79, 0x46, 0x82, 0x6E, 0x81, 0x19, 0x14, 0xB3, 0x94, 0x01, 0xD5, 0x6A,
249 252 0x0A, 0x78, 0x43,
250 253 0xA8, 0xE7, 0x57, 0x5D, 0x73, 0x8C, 0x67, 0x2A, 0x09, 0x0A, 0xB1, 0x18, 0x7D,
251 254 0x69, 0x0D, 0xC4,
252 255 0x38, 0x72, 0xFC, 0x06, 0xA7, 0xB6, 0xA4, 0x3F, 0x3B, 0x95, 0xBE, 0xAE, 0xC7,
253 256 0xDF, 0x04, 0xB9,
254 257 0xD2, 0x42, 0xEB, 0xDC, 0x48, 0x11, 0x11, 0x28, 0x32, 0x16, 0xCE, 0x81, 0x6E,
255 258 0x00, 0x4B, 0x78,
256 259 0x6C, 0x5F, 0xCE, 0x85, 0x67, 0x80, 0xD4, 0x18, 0x37, 0xD9, 0x5A, 0xD7, 0x87,
257 260 0xA5, 0x0B, 0xBE,
258 261 0x90, 0xBD, 0x3A, 0x9C, 0x98, 0xAC, 0x0F, 0x5F, 0xC0, 0xDE, 0x74, 0x4B, 0x1C,
259 262 0xDE, 0x18, 0x91,
260 263 0x69, 0x08, 0x94, 0xBC, 0x1F, 0x65, 0xE0, 0x0D, 0xE1, 0x5B, 0x4B, 0x2A, 0xA6,
261 264 0xD8, 0x71, 0x00,
262 265 0xC9, 0xEC, 0xC2, 0x52, 0x7E, 0x45, 0xEB, 0x84, 0x9D, 0xEB, 0x14, 0xBB, 0x20,
263 266 0x49, 0xB1, 0x63,
264 267 0xEA, 0x04, 0x18, 0x7F, 0xD2, 0x7C, 0x1B, 0xD9, 0xC7, 0x95, 0x8C, 0xD4, 0x0C,
265 268 0xE7, 0x06, 0x7A,
266 269 0x9C, 0x02, 0x4F, 0x9B, 0x7C, 0x5A, 0x0B, 0x4F, 0x50, 0x03, 0x68, 0x61, 0x61,
267 270 0xF0, 0x60, 0x5B
268 271 };
269 272
270 273 unsigned char dhgp3_pVal[] =
271 274 {0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1, 0xF1, 0x2A, 0x86, 0x17,
272 275 0xA4, 0x7B, 0xBB,
273 276 0xDB, 0xA5, 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9, 0x61, 0x4B,
274 277 0x19, 0xCC, 0x4D,
275 278 0x5F, 0x4F, 0x5F, 0x55, 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
276 279 0x60, 0x7A, 0x29,
277 280 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0, 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A,
278 281 0x22, 0xE8, 0xDC,
279 282 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0, 0x81, 0x34, 0xB1, 0xC8, 0xB9,
280 283 0x79, 0x89, 0x14,
281 284 0x9B, 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54, 0x83, 0x81, 0xDB,
282 285 0xC5, 0xB1, 0xFC,
283 286 0x76, 0x4E, 0x3F, 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E, 0x2B,
284 287 0x9C, 0x8C, 0xF5,
285 288 0x6E, 0xDF, 0x01, 0x95, 0x39, 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24,
286 289 0xB7, 0xC4, 0x86,
287 290 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F, 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7,
288 291 0xCC, 0xB7, 0xAE,
289 292 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F, 0x8A, 0x2F, 0xE9, 0xB8,
290 293 0xB5, 0x29, 0x2E,
291 294 0x5A, 0x02, 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2, 0x8C, 0x24,
292 295 0x42, 0xC6, 0xF3,
293 296 0x15, 0x18, 0x0F, 0x93, 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
294 297 0x35, 0xF9, 0xBB
295 298 };
296 299
297 300 unsigned char dhgp4_pVal[] =
298 301 {0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1, 0x66, 0xDE, 0x5E, 0x13,
299 302 0x89, 0x58, 0x2F,
300 303 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92, 0x94, 0x3D,
301 304 0xB5, 0x60, 0x50,
302 305 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
303 306 0x67, 0xA1, 0x3D,
304 307 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA,
305 308 0x04, 0xFD, 0x50,
306 309 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, 0xCF, 0x60, 0x95, 0x17, 0x9A,
307 310 0x16, 0x3A, 0xB3,
308 311 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18, 0xA9, 0x96, 0x2F,
309 312 0x0B, 0x93, 0xB8,
310 313 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A, 0xDB,
311 314 0xF4, 0xFF, 0x74,
312 315 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B,
313 316 0x14, 0x77, 0x3B,
314 317 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43,
315 318 0x6C, 0x64, 0x81,
316 319 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B, 0x9D, 0x32, 0xE6, 0x88,
317 320 0xF8, 0x77, 0x48,
318 321 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A, 0x27, 0x75,
319 322 0xD2, 0xEC, 0xFA,
320 323 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
321 324 0xE5, 0x7A, 0xE6,
322 325 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B,
323 326 0xC3, 0x08, 0xD8,
324 327 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, 0x71, 0xAE, 0x35, 0xF8, 0xE9,
325 328 0xDB, 0xFB, 0xB6,
326 329 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE, 0x23, 0x6D, 0x52,
327 330 0x5F, 0x54, 0x75,
328 331 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E,
329 332 0x4A, 0xFF, 0x73
330 333 };
331 334
332 335 /*
333 336 * myrand is used for test only, eventually it should be replaced by the random
334 337 * number. AND it is basically the private key.
335 338 */
336 339 /* #define MYRAND */
337 340 #ifdef MYRAND
338 341 unsigned char myrand[] =
339 342 {0x11, 0x11, 0x22, 0x22,
340 343 0x33, 0x33, 0x44, 0x44,
341 344 0x55, 0x55, 0x66, 0x66,
342 345 0x77, 0x77, 0x88, 0x88,
343 346 0x99, 0x99, 0x00, 0x00};
344 347 #endif /* MYRAND */
345 348
346 349
347 350
348 351
349 352 /* Node Events */
350 353 #define NODE_EVENT_DEVICE_RM 0x0 /* Auth response timeout & fail */
351 354 #define NODE_EVENT_DEVICE_RECOVERY 0x1 /* Auth response timeout & recovery */
352 355 #define NODE_EVENT_RCV_AUTH_MSG 0x2 /* Unsolicited Auth received */
353 356 #define NODE_EVENT_CMPL_AUTH_MSG 0x3
354 357 #define NODE_EVENT_MAX_EVENT 0x4
355 358
356 359 emlxs_table_t emlxs_event_table[] =
357 360 {
358 361 {NODE_EVENT_DEVICE_RM, "DEVICE_REMOVE"},
359 362 {NODE_EVENT_DEVICE_RECOVERY, "DEVICE_RECOVERY"},
360 363 {NODE_EVENT_RCV_AUTH_MSG, "AUTH_MSG_RCVD"},
361 364 {NODE_EVENT_CMPL_AUTH_MSG, "AUTH_MSG_CMPL"},
362 365
363 366 }; /* emlxs_event_table() */
364 367
365 368 emlxs_table_t emlxs_pstate_table[] =
366 369 {
367 370 {ELX_FABRIC_STATE_UNKNOWN, "FABRIC_STATE_UNKNOWN"},
368 371 {ELX_FABRIC_AUTH_DISABLED, "FABRIC_AUTH_DISABLED"},
369 372 {ELX_FABRIC_AUTH_FAILED, "FABRIC_AUTH_FAILED"},
370 373 {ELX_FABRIC_AUTH_SUCCESS, "FABRIC_AUTH_SUCCESS"},
371 374 {ELX_FABRIC_IN_AUTH, "FABRIC_IN_AUTH"},
372 375 {ELX_FABRIC_IN_REAUTH, "FABRIC_IN_REAUTH"},
373 376
374 377 }; /* emlxs_pstate_table() */
375 378
376 379 emlxs_table_t emlxs_nstate_table[] =
377 380 {
378 381 {NODE_STATE_UNKNOWN, "STATE_UNKNOWN"},
379 382 {NODE_STATE_AUTH_DISABLED, "AUTH_DISABLED"},
380 383 {NODE_STATE_AUTH_FAILED, "AUTH_FAILED"},
381 384 {NODE_STATE_AUTH_SUCCESS, "AUTH_SUCCESS"},
382 385 {NODE_STATE_AUTH_NEGOTIATE_ISSUE, "NEGOTIATE_ISSUE"},
383 386 {NODE_STATE_AUTH_NEGOTIATE_RCV, "NEGOTIATE_RCV"},
384 387 {NODE_STATE_AUTH_NEGOTIATE_CMPL_WAIT4NEXT, "NEGOTIATE_CMPL"},
385 388 {NODE_STATE_DHCHAP_CHALLENGE_ISSUE, "DHCHAP_CHALLENGE_ISSUE"},
386 389 {NODE_STATE_DHCHAP_REPLY_ISSUE, "DHCHAP_REPLY_ISSUE"},
387 390 {NODE_STATE_DHCHAP_CHALLENGE_CMPL_WAIT4NEXT, "DHCHAP_CHALLENGE_CMPL"},
388 391 {NODE_STATE_DHCHAP_REPLY_CMPL_WAIT4NEXT, "DHCHAP_REPLY_CMPL"},
389 392 {NODE_STATE_DHCHAP_SUCCESS_ISSUE, "DHCHAP_SUCCESS_ISSUE"},
390 393 {NODE_STATE_DHCHAP_SUCCESS_ISSUE_WAIT4NEXT, "DHCHAP_SUCCESS_ISSUE_WAIT"},
391 394 {NODE_STATE_DHCHAP_SUCCESS_CMPL_WAIT4NEXT, "DHCHAP_SUCCESS_CMPL"},
392 395 }; /* emlxs_nstate_table() */
393 396
394 397 extern char *
395 398 emlxs_dhc_event_xlate(uint32_t state)
396 399 {
397 400 static char buffer[32];
398 401 uint32_t i;
399 402 uint32_t count;
400 403
401 404 count = sizeof (emlxs_event_table) / sizeof (emlxs_table_t);
402 405 for (i = 0; i < count; i++) {
403 406 if (state == emlxs_event_table[i].code) {
404 407 return (emlxs_event_table[i].string);
405 408 }
406 409 }
407 410
408 411 (void) sprintf(buffer, "event=0x%x", state);
409 412 return (buffer);
410 413
411 414 } /* emlxs_dhc_event_xlate() */
412 415
413 416
414 417 extern void
415 418 emlxs_dhc_state(emlxs_port_t *port, emlxs_node_t *ndlp, uint32_t state,
416 419 uint32_t reason, uint32_t explaination)
417 420 {
418 421 emlxs_hba_t *hba = HBA;
419 422 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
420 423 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
421 424 uint32_t pstate;
422 425
423 426 if ((state != NODE_STATE_NOCHANGE) && (node_dhc->state != state)) {
424 427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_state_msg,
425 428 "Node:0x%x %s --> %s", ndlp->nlp_DID,
426 429 emlxs_dhc_nstate_xlate(node_dhc->state),
427 430 emlxs_dhc_nstate_xlate(state));
428 431
429 432 node_dhc->prev_state = node_dhc->state;
430 433 node_dhc->state = (uint16_t)state;
431 434
432 435 /* Perform common functions based on state */
433 436 switch (state) {
434 437 case NODE_STATE_UNKNOWN:
435 438 case NODE_STATE_AUTH_DISABLED:
436 439 node_dhc->nlp_authrsp_tmo = 0;
437 440 node_dhc->nlp_authrsp_tmocnt = 0;
438 441 emlxs_dhc_set_reauth_time(port, ndlp, DISABLE);
439 442 break;
440 443
441 444 case NODE_STATE_AUTH_SUCCESS:
442 445 /* Record auth time */
443 446 if (ndlp->nlp_DID == FABRIC_DID) {
444 447 port_dhc->auth_time = DRV_TIME;
445 448 } else if (node_dhc->parent_auth_cfg) {
446 449 node_dhc->parent_auth_cfg->auth_time = DRV_TIME;
447 450 }
448 451 hba->rdn_flag = 0;
449 452 node_dhc->nlp_authrsp_tmo = 0;
450 453
451 454 if (node_dhc->flag & NLP_SET_REAUTH_TIME) {
452 455 emlxs_dhc_set_reauth_time(port, ndlp, ENABLE);
453 456 }
454 457 break;
455 458
456 459 default:
457 460 break;
458 461 }
459 462
460 463 /* Check for switch port */
461 464 if (ndlp->nlp_DID == FABRIC_DID) {
462 465 switch (state) {
463 466 case NODE_STATE_UNKNOWN:
464 467 pstate = ELX_FABRIC_STATE_UNKNOWN;
465 468 break;
466 469
467 470 case NODE_STATE_AUTH_DISABLED:
468 471 pstate = ELX_FABRIC_AUTH_DISABLED;
469 472 break;
470 473
471 474 case NODE_STATE_AUTH_FAILED:
472 475 pstate = ELX_FABRIC_AUTH_FAILED;
473 476 break;
474 477
475 478 case NODE_STATE_AUTH_SUCCESS:
476 479 pstate = ELX_FABRIC_AUTH_SUCCESS;
477 480 break;
478 481
479 482 /* Auth active */
480 483 default:
481 484 if (port_dhc->state ==
482 485 ELX_FABRIC_AUTH_SUCCESS) {
483 486 pstate = ELX_FABRIC_IN_REAUTH;
484 487 } else if (port_dhc->state !=
485 488 ELX_FABRIC_IN_REAUTH) {
486 489 pstate = ELX_FABRIC_IN_AUTH;
487 490 }
488 491 break;
489 492 }
490 493
491 494 if (port_dhc->state != pstate) {
492 495 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_state_msg,
493 496 "Port: %s --> %s",
494 497 emlxs_dhc_pstate_xlate(port_dhc->state),
495 498 emlxs_dhc_pstate_xlate(pstate));
496 499
497 500 port_dhc->state = pstate;
498 501 }
499 502 }
500 503 }
501 504 /* Update auth status */
502 505 mutex_enter(&hba->auth_lock);
503 506 emlxs_dhc_status(port, ndlp, reason, explaination);
504 507 mutex_exit(&hba->auth_lock);
505 508
506 509 return;
507 510
508 511 } /* emlxs_dhc_state() */
509 512
510 513
511 514 /* auth_lock must be held when calling this */
512 515 extern void
513 516 emlxs_dhc_status(emlxs_port_t *port, emlxs_node_t *ndlp, uint32_t reason,
514 517 uint32_t explaination)
515 518 {
516 519 emlxs_port_dhc_t *port_dhc;
517 520 emlxs_node_dhc_t *node_dhc;
518 521 dfc_auth_status_t *auth_status;
519 522 uint32_t drv_time;
520 523
521 524 if (!ndlp || !ndlp->nlp_active || ndlp->node_dhc.state ==
522 525 NODE_STATE_UNKNOWN) {
523 526 return;
524 527 }
525 528 port_dhc = &port->port_dhc;
526 529 node_dhc = &ndlp->node_dhc;
527 530
528 531 /* Get auth status object */
529 532 if (ndlp->nlp_DID == FABRIC_DID) {
530 533 auth_status = &port_dhc->auth_status;
531 534 } else if (node_dhc->parent_auth_cfg) {
532 535 auth_status = &node_dhc->parent_auth_cfg->auth_status;
533 536 } else {
534 537 /* No auth status to be updated */
535 538 return;
536 539 }
537 540
538 541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_status_msg,
539 542 "Node:0x%x state=%s rsn=0x%x exp=0x%x (%x,%x)",
540 543 ndlp->nlp_DID, emlxs_dhc_nstate_xlate(node_dhc->state), reason,
541 544 explaination, auth_status->auth_state,
542 545 auth_status->auth_failReason);
543 546
544 547 /* Set state and auth_failReason */
545 548 switch (node_dhc->state) {
546 549 case NODE_STATE_UNKNOWN: /* Connection */
547 550 if (auth_status->auth_state != DFC_AUTH_STATE_FAILED) {
548 551 auth_status->auth_state = DFC_AUTH_STATE_OFF;
549 552 auth_status->auth_failReason = 0;
550 553 }
551 554 break;
552 555
553 556 case NODE_STATE_AUTH_DISABLED:
554 557 auth_status->auth_state = DFC_AUTH_STATE_OFF;
555 558 auth_status->auth_failReason = 0;
556 559 break;
557 560
558 561 case NODE_STATE_AUTH_FAILED:
559 562 /* Check failure reason and update if neccessary */
560 563 switch (reason) {
561 564 case AUTHRJT_FAILURE: /* 0x01 */
562 565 case AUTHRJT_LOGIC_ERR: /* 0x02 */
563 566 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
564 567 auth_status->auth_failReason = DFC_AUTH_FAIL_REJECTED;
565 568 break;
566 569
567 570 case LSRJT_AUTH_REQUIRED: /* 0x03 */
568 571 switch (explaination) {
569 572 case LSEXP_AUTH_REQUIRED:
570 573 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
571 574 auth_status->auth_failReason =
572 575 DFC_AUTH_FAIL_LS_RJT;
573 576 break;
574 577 default:
575 578 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
576 579 auth_status->auth_failReason =
577 580 DFC_AUTH_FAIL_REJECTED;
578 581 }
579 582 break;
580 583
581 584 case LSRJT_AUTH_LOGICAL_BSY: /* 0x05 */
582 585 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
583 586 auth_status->auth_failReason = DFC_AUTH_FAIL_BSY_LS_RJT;
584 587 break;
585 588
586 589 case LSRJT_AUTH_ELS_NOT_SUPPORTED: /* 0x0B */
587 590 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
588 591 auth_status->auth_failReason = DFC_AUTH_FAIL_LS_RJT;
589 592 break;
590 593
591 594 case LSRJT_AUTH_NOT_LOGGED_IN: /* 0x09 */
592 595 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
593 596 auth_status->auth_failReason = DFC_AUTH_FAIL_BSY_LS_RJT;
594 597 break;
595 598 }
596 599
597 600 /* Make sure the state is set to failed at this point */
598 601 if (auth_status->auth_state != DFC_AUTH_STATE_FAILED) {
599 602 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
600 603 auth_status->auth_failReason = DFC_AUTH_FAIL_GENERIC;
601 604 }
602 605 break;
603 606
604 607 case NODE_STATE_AUTH_SUCCESS:
605 608 auth_status->auth_state = DFC_AUTH_STATE_ON;
606 609 auth_status->auth_failReason = 0;
607 610 break;
608 611
609 612 /* Authentication currently active */
610 613 default:
611 614 /* Set defaults */
612 615 auth_status->auth_state = DFC_AUTH_STATE_INP;
613 616 auth_status->auth_failReason = 0;
614 617
615 618 /* Check codes for exceptions */
616 619 switch (reason) {
617 620 case AUTHRJT_FAILURE: /* 0x01 */
618 621 switch (explaination) {
619 622 case AUTHEXP_AUTH_FAILED: /* 0x05 */
620 623 case AUTHEXP_BAD_PAYLOAD: /* 0x06 */
621 624 case AUTHEXP_BAD_PROTOCOL: /* 0x07 */
622 625 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
623 626 auth_status->auth_failReason =
624 627 DFC_AUTH_FAIL_REJECTED;
625 628 break;
626 629 }
627 630 break;
628 631
629 632 case AUTHRJT_LOGIC_ERR: /* 0x02 */
630 633 switch (explaination) {
631 634 case AUTHEXP_MECH_UNUSABLE: /* 0x01 */
632 635 case AUTHEXP_DHGROUP_UNUSABLE: /* 0x02 */
633 636 case AUTHEXP_HASHFUNC_UNUSABLE: /* 0x03 */
634 637 case AUTHEXP_CONCAT_UNSUPP: /* 0x09 */
635 638 case AUTHEXP_BAD_PROTOVERS: /* 0x0A */
636 639 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
637 640 auth_status->auth_failReason =
638 641 DFC_AUTH_FAIL_REJECTED;
639 642 break;
640 643 }
641 644 break;
642 645
643 646 case LSRJT_AUTH_REQUIRED: /* 0x03 */
644 647 switch (explaination) {
645 648 case LSEXP_AUTH_REQUIRED:
646 649 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
647 650 auth_status->auth_failReason =
648 651 DFC_AUTH_FAIL_LS_RJT;
649 652 break;
650 653 }
651 654 break;
652 655
653 656 case LSRJT_AUTH_LOGICAL_BSY: /* 0x05 */
654 657 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
655 658 auth_status->auth_failReason = DFC_AUTH_FAIL_BSY_LS_RJT;
656 659 break;
657 660
658 661 case LSRJT_AUTH_ELS_NOT_SUPPORTED: /* 0x0B */
659 662 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
660 663 auth_status->auth_failReason = DFC_AUTH_FAIL_LS_RJT;
661 664 break;
662 665
663 666 case LSRJT_AUTH_NOT_LOGGED_IN: /* 0x09 */
664 667 auth_status->auth_state = DFC_AUTH_STATE_FAILED;
665 668 auth_status->auth_failReason = DFC_AUTH_FAIL_BSY_LS_RJT;
666 669 break;
667 670 }
668 671 break;
669 672 }
670 673
671 674 if (auth_status->auth_state != DFC_AUTH_STATE_ON) {
672 675 auth_status->time_until_next_auth = 0;
673 676 auth_status->localAuth = 0;
674 677 auth_status->remoteAuth = 0;
675 678 auth_status->group_priority = 0;
676 679 auth_status->hash_priority = 0;
677 680 auth_status->type_priority = 0;
678 681 } else {
679 682 switch (node_dhc->nlp_reauth_status) {
680 683 case NLP_HOST_REAUTH_ENABLED:
681 684 case NLP_HOST_REAUTH_IN_PROGRESS:
682 685 drv_time = DRV_TIME;
683 686
684 687 if (node_dhc->nlp_reauth_tmo > drv_time) {
685 688 auth_status->time_until_next_auth =
686 689 node_dhc->nlp_reauth_tmo - drv_time;
687 690 } else {
688 691 auth_status->time_until_next_auth = 0;
689 692 }
690 693 break;
691 694
692 695 case NLP_HOST_REAUTH_DISABLED:
693 696 default:
694 697 auth_status->time_until_next_auth = 0;
695 698 break;
696 699 }
697 700
698 701 if (node_dhc->flag & NLP_REMOTE_AUTH) {
699 702 auth_status->localAuth = 0;
700 703 auth_status->remoteAuth = 1;
701 704 } else {
702 705 auth_status->localAuth = 1;
703 706 auth_status->remoteAuth = 0;
704 707 }
705 708
706 709 auth_status->type_priority = DFC_AUTH_TYPE_DHCHAP;
707 710
708 711 switch (node_dhc->nlp_auth_dhgpid) {
709 712 case GROUP_NULL:
710 713 auth_status->group_priority = ELX_GROUP_NULL;
711 714 break;
712 715
713 716 case GROUP_1024:
714 717 auth_status->group_priority = ELX_GROUP_1024;
715 718 break;
716 719
717 720 case GROUP_1280:
718 721 auth_status->group_priority = ELX_GROUP_1280;
719 722 break;
720 723
721 724 case GROUP_1536:
722 725 auth_status->group_priority = ELX_GROUP_1536;
723 726 break;
724 727
725 728 case GROUP_2048:
726 729 auth_status->group_priority = ELX_GROUP_2048;
727 730 break;
728 731 }
729 732
730 733 switch (node_dhc->nlp_auth_hashid) {
731 734 case 0:
732 735 auth_status->hash_priority = 0;
733 736 break;
734 737
735 738 case AUTH_SHA1:
736 739 auth_status->hash_priority = ELX_SHA1;
737 740 break;
738 741
739 742 case AUTH_MD5:
740 743 auth_status->hash_priority = ELX_MD5;
741 744 break;
742 745 }
743 746 }
744 747
745 748 return;
746 749
747 750 } /* emlxs_dhc_status() */
748 751
749 752 static char *
750 753 emlxs_dhc_pstate_xlate(uint32_t state)
751 754 {
752 755 static char buffer[32];
753 756 uint32_t i;
754 757 uint32_t count;
755 758
756 759 count = sizeof (emlxs_pstate_table) / sizeof (emlxs_table_t);
757 760 for (i = 0; i < count; i++) {
758 761 if (state == emlxs_pstate_table[i].code) {
759 762 return (emlxs_pstate_table[i].string);
760 763 }
761 764 }
762 765
763 766 (void) sprintf(buffer, "state=0x%x", state);
764 767 return (buffer);
765 768
766 769 } /* emlxs_dhc_pstate_xlate() */
767 770
768 771
769 772 static char *
770 773 emlxs_dhc_nstate_xlate(uint32_t state)
771 774 {
772 775 static char buffer[32];
773 776 uint32_t i;
774 777 uint32_t count;
775 778
776 779 count = sizeof (emlxs_nstate_table) / sizeof (emlxs_table_t);
777 780 for (i = 0; i < count; i++) {
778 781 if (state == emlxs_nstate_table[i].code) {
779 782 return (emlxs_nstate_table[i].string);
780 783 }
781 784 }
782 785
783 786 (void) sprintf(buffer, "state=0x%x", state);
784 787 return (buffer);
785 788
786 789 } /* emlxs_dhc_nstate_xlate() */
787 790
788 791
789 792 static uint32_t
790 793 emlxs_check_dhgp(
791 794 emlxs_port_t *port,
792 795 NODELIST *ndlp,
793 796 uint32_t *dh_id,
794 797 uint16_t cnt,
795 798 uint32_t *dhgp_id)
796 799 {
797 800 uint32_t i, j, rc = 1;
798 801 uint32_t wnt;
799 802 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
800 803
801 804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
802 805 "dhgp: 0x%x, id[0..4]=0x%x 0x%x 0x%x 0x%x 0x%x pri[1]=0x%x",
803 806 cnt, dh_id[0], dh_id[1], dh_id[2], dh_id[3], dh_id[4],
804 807 node_dhc->auth_cfg.dh_group_priority[1]);
805 808
806 809 /*
807 810 * Here are the rules, as the responder We always try to select ours
808 811 * highest setup
809 812 */
810 813
811 814 /* Check to see if there is any repeated dhgp in initiator's list */
812 815 /* If available, it is a invalid payload */
813 816 if (cnt >= 2) {
814 817 for (i = 0; i <= cnt - 2; i++) {
815 818 for (j = i + 1; j <= cnt - 1; j++) {
816 819 if (dh_id[i] == dh_id[j]) {
817 820 rc = 2;
818 821 EMLXS_MSGF(EMLXS_CONTEXT,
819 822 &emlxs_fcsp_detail_msg,
820 823 ":Rpt dhid[%x]=%x dhid[%x]=%x",
821 824 i, dh_id[i], j, dh_id[j]);
822 825 break;
823 826 }
824 827 }
825 828
826 829 if (rc == 2) {
827 830 break;
828 831 }
829 832 }
830 833
831 834 if ((i == cnt - 1) && (j == cnt)) {
832 835 rc = 1;
833 836 }
834 837 if (rc == 2) {
835 838 /* duplicate invalid payload */
836 839 return (rc);
837 840 }
838 841 }
839 842 /* Check how many dhgps the responder specified */
840 843 wnt = 0;
841 844 while (node_dhc->auth_cfg.dh_group_priority[wnt] != 0xF) {
842 845 wnt++;
843 846 }
844 847
845 848 /* Determine the most suitable dhgp the responder should use */
846 849 for (i = 0; i < wnt; i++) {
847 850 for (j = 0; j < cnt; j++) {
848 851 if (node_dhc->auth_cfg.dh_group_priority[i] ==
849 852 dh_id[j]) {
850 853 rc = 0;
851 854 *dhgp_id =
852 855 node_dhc->auth_cfg.dh_group_priority[i];
853 856 break;
854 857 }
855 858 }
856 859
857 860 if (rc == 0) {
858 861 break;
859 862 }
860 863 }
861 864
862 865 if (i == wnt) {
863 866 /* no match */
864 867 rc = 1;
865 868 return (1);
866 869 }
867 870
868 871 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
869 872 "emlxs_check_dhgp: dhgp_id=0x%x", *dhgp_id);
870 873
871 874 return (rc);
872 875 } /* emlxs_check_dhgp */
873 876
874 877
875 878 static void
876 879 emlxs_get_random_bytes(
877 880 NODELIST *ndlp,
878 881 uint8_t *rdn,
879 882 uint32_t len)
880 883 {
881 884 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
882 885 hrtime_t now;
883 886 uint8_t sha1_digest[20];
884 887 SHA1_CTX sha1ctx;
885 888
886 889 now = gethrtime();
887 890
888 891 bzero(&sha1ctx, sizeof (SHA1_CTX));
889 892 SHA1Init(&sha1ctx);
890 893 SHA1Update(&sha1ctx, (void *) &node_dhc->auth_cfg.local_entity,
891 894 sizeof (NAME_TYPE));
892 895 SHA1Update(&sha1ctx, (void *) &now, sizeof (hrtime_t));
893 896 SHA1Final((void *) sha1_digest, &sha1ctx);
894 897 bcopy((void *) &sha1_digest[0], (void *) &rdn[0], len);
895 898
896 899 return;
897 900
898 901 } /* emlxs_get_random_bytes */
899 902
900 903
901 904 /* **************************** STATE MACHINE ************************** */
902 905
903 906 static void *emlxs_dhchap_action[] =
904 907 {
905 908 /* Action routine Event */
906 909
907 910 /* NODE_STATE_UNKNOWN 0x00 */
908 911 (void *) emlxs_disc_neverdev, /* DEVICE_RM */
909 912 (void *) emlxs_disc_neverdev, /* DEVICE_RECOVERY */
910 913 (void *) emlxs_disc_neverdev, /* RCV_AUTH_MSG */
911 914 (void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
912 915
913 916 /* NODE_STATE_AUTH_DISABLED 0x01 */
914 917 (void *) emlxs_disc_neverdev, /* DEVICE_RM */
915 918 (void *) emlxs_disc_neverdev, /* DEVICE_RECOVERY */
916 919 (void *) emlxs_disc_neverdev, /* RCV_AUTH_MSG */
917 920 (void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
918 921
919 922 /* NODE_STATE_AUTH_FAILED 0x02 */
920 923 (void *) emlxs_device_rm_npr_node, /* DEVICE_RM */
921 924 (void *) emlxs_device_recov_npr_node, /* DEVICE_RECOVERY */
922 925 (void *) emlxs_rcv_auth_msg_npr_node, /* RCV_AUTH_MSG */
923 926 (void *) emlxs_cmpl_auth_msg_npr_node, /* CMPL_AUTH_MSG */
924 927
925 928 /* NODE_STATE_AUTH_SUCCESS 0x03 */
926 929 (void *) emlxs_disc_neverdev, /* DEVICE_RM */
927 930 (void *) emlxs_device_recov_unmapped_node, /* DEVICE_RECOVERY */
928 931 (void *) emlxs_rcv_auth_msg_unmapped_node, /* RCV_AUTH_MSG */
929 932 (void *) emlxs_disc_neverdev, /* CMPL_AUTH_MSG */
930 933
931 934 /* NODE_STATE_AUTH_NEGOTIATE_ISSUE 0x04 */
932 935 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
933 936 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
934 937 (void *) emlxs_rcv_auth_msg_auth_negotiate_issue, /* RCV_AUTH_MSG */
935 938 (void *) emlxs_cmpl_auth_msg_auth_negotiate_issue, /* CMPL_AUTH_MSG */
936 939
937 940 /* NODE_STATE_AUTH_NEGOTIATE_RCV 0x05 */
938 941 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
939 942 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
940 943 (void *) emlxs_rcv_auth_msg_auth_negotiate_rcv, /* RCV_AUTH_MSG */
941 944 (void *) emlxs_cmpl_auth_msg_auth_negotiate_rcv, /* CMPL_AUTH_MSG */
942 945
943 946 /* NODE_STATE_AUTH_NEGOTIATE_CMPL_WAIT4NEXT 0x06 */
944 947 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
945 948 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
946 949 (void *) emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next,
947 950 /* RCV_AUTH_MSG */
948 951 (void *) emlxs_cmpl_auth_msg_auth_negotiate_cmpl_wait4next,
949 952 /* CMPL_AUTH_MSG */
950 953
951 954 /* NODE_STATE_DHCHAP_CHALLENGE_ISSUE 0x07 */
952 955 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
953 956 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
954 957 (void *) emlxs_rcv_auth_msg_dhchap_challenge_issue, /* RCV_AUTH_MSG */
955 958 (void *) emlxs_cmpl_auth_msg_dhchap_challenge_issue, /* CMPL_AUTH_MSG */
956 959
957 960 /* NODE_STATE_DHCHAP_REPLY_ISSUE 0x08 */
958 961 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
959 962 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
960 963 (void *) emlxs_rcv_auth_msg_dhchap_reply_issue, /* RCV_AUTH_MSG */
961 964 (void *) emlxs_cmpl_auth_msg_dhchap_reply_issue, /* CMPL_AUTH_MSG */
962 965
963 966 /* NODE_STATE_DHCHAP_CHALLENGE_CMPL_WAIT4NEXT 0x09 */
964 967 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
965 968 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
966 969 (void *) emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next,
967 970 /* RCV_AUTH_MSG */
968 971 (void *) emlxs_cmpl_auth_msg_dhchap_challenge_cmpl_wait4next,
969 972 /* CMPL_AUTH_MSG */
970 973
971 974 /* NODE_STATE_DHCHAP_REPLY_CMPL_WAIT4NEXT 0x0A */
972 975 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
973 976 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
974 977 (void *) emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next,
975 978 /* RCV_AUTH_MSG */
976 979 (void *) emlxs_cmpl_auth_msg_dhchap_reply_cmpl_wait4next,
977 980 /* CMPL_AUTH_MSG */
978 981
979 982 /* NODE_STATE_DHCHAP_SUCCESS_ISSUE 0x0B */
980 983 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
981 984 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
982 985 (void *) emlxs_rcv_auth_msg_dhchap_success_issue,
983 986 /* RCV_AUTH_MSG */
984 987 (void *) emlxs_cmpl_auth_msg_dhchap_success_issue,
985 988 /* CMPL_AUTH_MSG */
986 989
987 990 /* NODE_STATE_DHCHAP_SUCCESS_ISSUE_WAIT4NEXT 0x0C */
988 991 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
989 992 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
990 993 (void *) emlxs_rcv_auth_msg_dhchap_success_issue_wait4next,
991 994 /* RCV_AUTH_MSG */
992 995 (void *) emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next,
993 996 /* CMPL_AUTH_MSG */
994 997
995 998 /* NODE_STATE_DHCHAP_SUCCESS_CMPL_WAIT4NEXT 0x0D */
996 999 (void *) emlxs_device_rem_auth, /* DEVICE_RM */
997 1000 (void *) emlxs_device_recov_auth, /* DEVICE_RECOVERY */
998 1001 (void *) emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next,
999 1002 /* RCV_AUTH_MSG */
1000 1003 (void *) emlxs_cmpl_auth_msg_dhchap_success_cmpl_wait4next,
1001 1004 /* CMPL_AUTH_MSG */
1002 1005
1003 1006 }; /* emlxs_dhchap_action[] */
1004 1007
1005 1008
1006 1009 extern int
1007 1010 emlxs_dhchap_state_machine(emlxs_port_t *port, CHANNEL *cp,
1008 1011 IOCBQ *iocbq, MATCHMAP *mp,
1009 1012 NODELIST *ndlp, int evt)
1010 1013 {
1011 1014 emlxs_hba_t *hba = HBA;
1012 1015 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1013 1016 uint32_t rc;
1014 1017 uint32_t(*func) (emlxs_port_t *, CHANNEL *, IOCBQ *, MATCHMAP *,
1015 1018 NODELIST *, uint32_t);
1016 1019
1017 1020 mutex_enter(&hba->dhc_lock);
1018 1021
1019 1022 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_event_msg,
1020 1023 "%s: did=0x%x",
1021 1024 emlxs_dhc_event_xlate(evt), ndlp->nlp_DID);
1022 1025
1023 1026 node_dhc->disc_refcnt++;
1024 1027
1025 1028 func = (uint32_t(*) (emlxs_port_t *, CHANNEL *, IOCBQ *, MATCHMAP *,
1026 1029 NODELIST *, uint32_t))
1027 1030 emlxs_dhchap_action[(node_dhc->state * NODE_EVENT_MAX_EVENT) + evt];
1028 1031
1029 1032 rc = (func) (port, cp, iocbq, mp, ndlp, evt);
1030 1033
1031 1034 node_dhc->disc_refcnt--;
1032 1035
1033 1036 mutex_exit(&hba->dhc_lock);
1034 1037
1035 1038 return (rc);
1036 1039
1037 1040 } /* emlxs_dhchap_state_machine() */
1038 1041
1039 1042 /* ARGSUSED */
1040 1043 static uint32_t
1041 1044 emlxs_disc_neverdev(
1042 1045 emlxs_port_t *port,
1043 1046 /* CHANNEL * rp, */ void *arg1,
1044 1047 /* IOCBQ * iocbq, */ void *arg2,
1045 1048 /* MATCHMAP * mp, */ void *arg3,
1046 1049 /* NODELIST * ndlp */ void *arg4,
1047 1050 uint32_t evt)
1048 1051 {
1049 1052 NODELIST *ndlp = (NODELIST *) arg4;
1050 1053 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1051 1054
1052 1055 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1053 1056 "emlxs_disc_neverdev: did=0x%x.",
1054 1057 ndlp->nlp_DID);
1055 1058
1056 1059 emlxs_dhc_state(port, ndlp, NODE_STATE_UNKNOWN, 0, 0);
1057 1060
1058 1061 return (node_dhc->state);
1059 1062
1060 1063 } /* emlxs_disc_neverdev() */
1061 1064
1062 1065
1063 1066 /*
1064 1067 * ! emlxs_cmpl_dhchap_challenge_issue
1065 1068 *
1066 1069 * \pre \post \param cmdiocb \param rspiocb \return void
1067 1070 *
1068 1071 * \b Description: iocb_cmpl callback function. when the ELS DHCHAP_Challenge
1069 1072 * msg sent back got the ACC/RJT from initiator.
1070 1073 *
1071 1074 */
1072 1075 static void
1073 1076 emlxs_cmpl_dhchap_challenge_issue(fc_packet_t *pkt)
1074 1077 {
1075 1078 emlxs_port_t *port = pkt->pkt_ulp_private;
1076 1079 emlxs_buf_t *sbp;
1077 1080 NODELIST *ndlp;
1078 1081 uint32_t did;
1079 1082
1080 1083 did = pkt->pkt_cmd_fhdr.d_id;
1081 1084 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
1082 1085 ndlp = sbp->node;
1083 1086
1084 1087 if (!ndlp) {
1085 1088 ndlp = emlxs_node_find_did(port, did);
1086 1089 }
1087 1090 if (pkt->pkt_state != FC_PKT_SUCCESS) {
1088 1091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1089 1092 "emlxs_cmpl_dhchap_challenge_issue: did=0x%x state=%x",
1090 1093 did, pkt->pkt_state);
1091 1094 } else {
1092 1095 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1093 1096 "emlxs_cmpl_dhchap_challenge_issue: did=0x%x. Succcess.",
1094 1097 did);
1095 1098 }
1096 1099
1097 1100 if (ndlp) {
1098 1101 if (pkt->pkt_state == FC_PKT_SUCCESS) {
1099 1102 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
1100 1103 NULL, ndlp, NODE_EVENT_CMPL_AUTH_MSG);
1101 1104 }
1102 1105 }
1103 1106 emlxs_pkt_free(pkt);
1104 1107
1105 1108 return;
1106 1109
1107 1110 } /* emlxs_cmpl_dhchap_challenge_issue */
1108 1111
1109 1112
1110 1113
1111 1114
1112 1115 /*
1113 1116 * ! emlxs_cmpl_dhchap_success_issue
1114 1117 *
1115 1118 * \pre \post \param phba \param cmdiocb \param rspiocb \return void
1116 1119 *
1117 1120 * \b Description: iocb_cmpl callback function.
1118 1121 *
1119 1122 */
1120 1123 static void
1121 1124 emlxs_cmpl_dhchap_success_issue(fc_packet_t *pkt)
1122 1125 {
1123 1126 emlxs_port_t *port = pkt->pkt_ulp_private;
1124 1127 NODELIST *ndlp;
1125 1128 uint32_t did;
1126 1129 emlxs_buf_t *sbp;
1127 1130
1128 1131 did = pkt->pkt_cmd_fhdr.d_id;
1129 1132 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
1130 1133 ndlp = sbp->node;
1131 1134
1132 1135 if (!ndlp) {
1133 1136 ndlp = emlxs_node_find_did(port, did);
1134 1137 }
1135 1138 if (pkt->pkt_state != FC_PKT_SUCCESS) {
1136 1139 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1137 1140 "emlxs_cmpl_dhchap_success_issue: 0x%x %x. No retry.",
1138 1141 did, pkt->pkt_state);
1139 1142 } else {
1140 1143 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1141 1144 "emlxs_cmpl_dhchap_success_issue: did=0x%x. Succcess.",
1142 1145 did);
1143 1146 }
1144 1147
1145 1148 if (ndlp) {
1146 1149 if (pkt->pkt_state == FC_PKT_SUCCESS) {
1147 1150 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
1148 1151 NULL, ndlp, NODE_EVENT_CMPL_AUTH_MSG);
1149 1152 }
1150 1153 }
1151 1154 emlxs_pkt_free(pkt);
1152 1155
1153 1156 return;
1154 1157
1155 1158 } /* emlxs_cmpl_dhchap_success_issue */
1156 1159
1157 1160
1158 1161 /*
1159 1162 * if rsp == NULL, this is only the DHCHAP_Success msg
1160 1163 *
1161 1164 * if rsp != NULL, DHCHAP_Success contains rsp to the challenge.
1162 1165 */
1163 1166 /* ARGSUSED */
1164 1167 uint32_t
1165 1168 emlxs_issue_dhchap_success(
1166 1169 emlxs_port_t *port,
1167 1170 NODELIST *ndlp,
1168 1171 int retry,
1169 1172 uint8_t *rsp)
1170 1173 {
1171 1174 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1172 1175 fc_packet_t *pkt;
1173 1176 uint32_t cmd_size;
1174 1177 uint32_t rsp_size;
1175 1178 uint8_t *pCmd;
1176 1179 uint16_t cmdsize;
1177 1180 DHCHAP_SUCCESS_HDR *ap;
1178 1181 uint8_t *tmp;
1179 1182 uint32_t len;
1180 1183 uint32_t ret;
1181 1184
1182 1185 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1183 1186 "emlxs_issue_dhchap_success: did=0x%x", ndlp->nlp_DID);
1184 1187
1185 1188 if (ndlp->nlp_DID == FABRIC_DID) {
1186 1189 if (node_dhc->nlp_auth_hashid == AUTH_MD5)
1187 1190 len = MD5_LEN;
1188 1191 else
1189 1192 len = SHA1_LEN;
1190 1193 } else {
1191 1194 len = (node_dhc->nlp_auth_hashid == AUTH_MD5) ?
1192 1195 MD5_LEN : SHA1_LEN;
1193 1196 }
1194 1197
1195 1198 if (rsp == NULL) {
1196 1199 cmdsize = sizeof (DHCHAP_SUCCESS_HDR);
1197 1200 } else {
1198 1201
1199 1202 cmdsize = sizeof (DHCHAP_SUCCESS_HDR) + len;
1200 1203 }
1201 1204
1202 1205 cmd_size = cmdsize;
1203 1206 rsp_size = 4;
1204 1207
1205 1208 if ((pkt = emlxs_prep_els_fc_pkt(port, ndlp->nlp_DID, cmd_size,
1206 1209 rsp_size, 0, KM_NOSLEEP)) == NULL) {
1207 1210 return (1);
1208 1211 }
1209 1212 pCmd = (uint8_t *)pkt->pkt_cmd;
1210 1213
1211 1214 ap = (DHCHAP_SUCCESS_HDR *)pCmd;
1212 1215 tmp = (uint8_t *)pCmd;
1213 1216
1214 1217 ap->auth_els_code = ELS_CMD_AUTH_CODE;
1215 1218 ap->auth_els_flags = 0x0;
1216 1219 ap->auth_msg_code = DHCHAP_SUCCESS;
1217 1220 ap->proto_version = 0x01;
1218 1221
1219 1222 /*
1220 1223 * In case of rsp == NULL meaning that this is DHCHAP_Success issued
1221 1224 * when Host is the initiator AND this DHCHAP_Success is issused in
1222 1225 * response to the bi-directional authentication, meaning Host
1223 1226 * authenticate another entity, therefore no more DHCHAP_Success
1224 1227 * expected. OR this DHCHAP_Success is issued by host when host is
1225 1228 * the responder BUT it is uni-directional auth, therefore no more
1226 1229 * DHCHAP_Success expected.
1227 1230 *
1228 1231 * In case of rsp != NULL it indicates this DHCHAP_Success is issued
1229 1232 * when host is the responder AND this DHCHAP_Success has reply
1230 1233 * embedded therefore the host expects DHCHAP_Success from other
1231 1234 * entity in transaction.
1232 1235 */
1233 1236 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1234 1237 "emlxs_issue_dhchap_success: 0x%x 0x%x 0x%x 0x%x 0x%x %p",
1235 1238 ndlp->nlp_DID, node_dhc->nlp_auth_hashid,
1236 1239 node_dhc->nlp_auth_tranid_rsp,
1237 1240 node_dhc->nlp_auth_tranid_ini, cmdsize, rsp);
1238 1241
1239 1242 if (rsp == NULL) {
1240 1243 ap->msg_len = LE_SWAP32(0x00000004);
1241 1244 ap->RspVal_len = 0x0;
1242 1245
1243 1246 node_dhc->fc_dhchap_success_expected = 0;
1244 1247 } else {
1245 1248 node_dhc->fc_dhchap_success_expected = 1;
1246 1249
1247 1250 ap->msg_len = LE_SWAP32(4 + len);
1248 1251
1249 1252 tmp += sizeof (DHCHAP_SUCCESS_HDR) - sizeof (uint32_t);
1250 1253 *(uint32_t *)tmp = LE_SWAP32(len);
1251 1254 tmp += sizeof (uint32_t);
1252 1255 bcopy((void *)rsp, (void *)tmp, len);
1253 1256 }
1254 1257
1255 1258 if (node_dhc->nlp_reauth_status == NLP_HOST_REAUTH_IN_PROGRESS) {
1256 1259 ap->tran_id = LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1257 1260 } else {
1258 1261 if (node_dhc->nlp_auth_flag == 2) {
1259 1262 ap->tran_id =
1260 1263 LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1261 1264 } else if (node_dhc->nlp_auth_flag == 1) {
1262 1265 ap->tran_id =
1263 1266 LE_SWAP32(node_dhc->nlp_auth_tranid_ini);
1264 1267 } else {
1265 1268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
1266 1269 "emlxs_is_dhch_success: (1) 0x%x 0x%x 0x%x 0x%x",
1267 1270 ndlp->nlp_DID, node_dhc->nlp_auth_flag,
1268 1271 node_dhc->nlp_auth_tranid_rsp,
1269 1272 node_dhc->nlp_auth_tranid_ini);
1270 1273
1271 1274 return (1);
1272 1275 }
1273 1276 }
1274 1277
1275 1278 pkt->pkt_comp = emlxs_cmpl_dhchap_success_issue;
1276 1279
1277 1280 ret = emlxs_pkt_send(pkt, 1);
1278 1281
1279 1282 if (ret != FC_SUCCESS) {
1280 1283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1281 1284 "emlxs_issue_dhchap_success: Unable to send packet. 0x%x",
1282 1285 ret);
1283 1286
1284 1287 emlxs_pkt_free(pkt);
1285 1288
1286 1289 return (1);
1287 1290 }
1288 1291 return (0);
1289 1292
1290 1293 } /* emlxs_issue_dhchap_success */
1291 1294
1292 1295
1293 1296 /*
1294 1297 * ! emlxs_cmpl_auth_reject_issue
1295 1298 *
1296 1299 * \pre \post \param phba \param cmdiocb \param rspiocb \return void
1297 1300 *
1298 1301 * \b Description: iocb_cmpl callback function.
1299 1302 *
1300 1303 */
1301 1304 static void
1302 1305 emlxs_cmpl_auth_reject_issue(fc_packet_t *pkt)
1303 1306 {
1304 1307 emlxs_port_t *port = pkt->pkt_ulp_private;
1305 1308 emlxs_buf_t *sbp;
1306 1309 NODELIST *ndlp;
1307 1310 uint32_t did;
1308 1311
1309 1312 did = pkt->pkt_cmd_fhdr.d_id;
1310 1313 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
1311 1314 ndlp = sbp->node;
1312 1315
1313 1316 if (!ndlp) {
1314 1317 ndlp = emlxs_node_find_did(port, did);
1315 1318 }
1316 1319 if (pkt->pkt_state != FC_PKT_SUCCESS) {
1317 1320 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1318 1321 "emlxs_cmpl_auth_reject_issue: 0x%x %x. No retry.",
1319 1322 did, pkt->pkt_state);
1320 1323 } else {
1321 1324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1322 1325 "emlxs_cmpl_auth_reject_issue: did=0x%x. Succcess.",
1323 1326 did);
1324 1327 }
1325 1328
1326 1329 if (ndlp) {
1327 1330 /* setup the new state */
1328 1331 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED, 0, 0);
1329 1332
1330 1333 if (pkt->pkt_state == FC_PKT_SUCCESS) {
1331 1334 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
1332 1335 NULL, ndlp, NODE_EVENT_CMPL_AUTH_MSG);
1333 1336 }
1334 1337 }
1335 1338 emlxs_pkt_free(pkt);
1336 1339
1337 1340 return;
1338 1341
1339 1342 } /* emlxs_cmpl_auth_reject_issue */
1340 1343
1341 1344
1342 1345 /*
1343 1346 * If Logical Error and Reason Code Explanation is "Restart Authentication
1344 1347 * Protocol" then the Transaction Identifier could be
1345 1348 * any value.
1346 1349 */
1347 1350 /* ARGSUSED */
1348 1351 static uint32_t
1349 1352 emlxs_issue_auth_reject(
1350 1353 emlxs_port_t *port,
1351 1354 NODELIST *ndlp,
1352 1355 int retry,
1353 1356 uint32_t *arg,
1354 1357 uint8_t ReasonCode,
1355 1358 uint8_t ReasonCodeExplanation)
1356 1359 {
1357 1360 fc_packet_t *pkt;
1358 1361 uint32_t cmd_size;
1359 1362 uint32_t rsp_size;
1360 1363 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1361 1364 uint16_t cmdsize;
1362 1365 AUTH_RJT *ap;
1363 1366 char info[64];
1364 1367
1365 1368 if (node_dhc->nlp_authrsp_tmo) {
1366 1369 node_dhc->nlp_authrsp_tmo = 0;
1367 1370 }
1368 1371 cmdsize = sizeof (AUTH_RJT);
1369 1372 cmd_size = cmdsize;
1370 1373 rsp_size = 4;
1371 1374
1372 1375 if ((pkt = emlxs_prep_els_fc_pkt(port, ndlp->nlp_DID, cmd_size,
1373 1376 rsp_size, 0, KM_NOSLEEP)) == NULL) {
1374 1377 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
1375 1378 "Auth reject failed: Unable to allocate pkt. 0x%x %x %x",
1376 1379 ndlp->nlp_DID, ReasonCode, ReasonCodeExplanation);
1377 1380
1378 1381 return (1);
1379 1382 }
1380 1383 ap = (AUTH_RJT *) pkt->pkt_cmd;
1381 1384 ap->auth_els_code = ELS_CMD_AUTH_CODE;
1382 1385 ap->auth_els_flags = 0x0;
1383 1386 ap->auth_msg_code = AUTH_REJECT;
1384 1387 ap->proto_version = 0x01;
1385 1388 ap->msg_len = LE_SWAP32(4);
1386 1389
1387 1390 if (node_dhc->nlp_auth_flag == 2) {
1388 1391 ap->tran_id = LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1389 1392 } else if (node_dhc->nlp_auth_flag == 1) {
1390 1393 ap->tran_id = LE_SWAP32(node_dhc->nlp_auth_tranid_ini);
1391 1394 } else {
1392 1395 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
1393 1396 "Auth reject failed.Invalid flag=%d. 0x%x %x expl=%x",
1394 1397 ndlp->nlp_DID, node_dhc->nlp_auth_flag, ReasonCode,
1395 1398 ReasonCodeExplanation);
1396 1399
1397 1400 emlxs_pkt_free(pkt);
1398 1401
1399 1402 return (1);
1400 1403 }
1401 1404
1402 1405 ap->ReasonCode = ReasonCode;
1403 1406 ap->ReasonCodeExplanation = ReasonCodeExplanation;
1404 1407
1405 1408 pkt->pkt_comp = emlxs_cmpl_auth_reject_issue;
1406 1409
1407 1410 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
1408 1411 "Auth reject: did=0x%x reason=%x expl=%x",
1409 1412 ndlp->nlp_DID, ReasonCode, ReasonCodeExplanation);
1410 1413
1411 1414 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
1412 1415 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
1413 1416 "Auth reject failed. Unable to send pkt. 0x%x %x expl=%x",
1414 1417 ndlp->nlp_DID, node_dhc->nlp_auth_flag, ReasonCode,
1415 1418 ReasonCodeExplanation);
1416 1419
1417 1420 emlxs_pkt_free(pkt);
1418 1421
1419 1422 return (1);
1420 1423 }
1421 1424 (void) sprintf(info,
1422 1425 "Auth-Reject: ReasonCode=0x%x, ReasonCodeExplanation=0x%x",
1423 1426 ReasonCode, ReasonCodeExplanation);
1424 1427
1425 1428 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_28, info);
1426 1429
1427 1430 return (0);
1428 1431
1429 1432 } /* emlxs_issue_auth_reject */
1430 1433
1431 1434
1432 1435 static fc_packet_t *
1433 1436 emlxs_prep_els_fc_pkt(
1434 1437 emlxs_port_t *port,
1435 1438 uint32_t d_id,
1436 1439 uint32_t cmd_size,
1437 1440 uint32_t rsp_size,
1438 1441 uint32_t datalen,
1439 1442 int32_t sleepflag)
1440 1443 {
1441 1444 fc_packet_t *pkt;
1442 1445
1443 1446 /* simulate the ULP stack's fc_packet send out */
1444 1447 if (!(pkt = emlxs_pkt_alloc(port, cmd_size, rsp_size,
1445 1448 datalen, sleepflag))) {
1446 1449 return (NULL);
1447 1450 }
1448 1451 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
1449 1452 pkt->pkt_timeout = 35;
1450 1453
1451 1454 /* Build the fc header */
1452 1455 pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id);
1453 1456 pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ;
1454 1457 pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
1455 1458 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
1456 1459 pkt->pkt_cmd_fhdr.f_ctl =
1457 1460 F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
1458 1461 pkt->pkt_cmd_fhdr.seq_id = 0;
1459 1462 pkt->pkt_cmd_fhdr.df_ctl = 0;
1460 1463 pkt->pkt_cmd_fhdr.seq_cnt = 0;
1461 1464 pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
1462 1465 pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
1463 1466 pkt->pkt_cmd_fhdr.ro = 0;
1464 1467
1465 1468 return ((fc_packet_t *)pkt);
1466 1469
1467 1470 } /* emlxs_prep_els_fc_pkt */
1468 1471
1469 1472
1470 1473 /*
1471 1474 * ! emlxs_issue_auth_negotiate
1472 1475 *
1473 1476 * \pre \post \param port \param ndlp \param retry \param flag \return
1474 1477 * int
1475 1478 *
1476 1479 * \b Description:
1477 1480 *
1478 1481 * The routine is invoked when host as the authentication initiator which
1479 1482 * issue the AUTH_ELS command AUTH_Negotiate to the other
1480 1483 * entity ndlp. When this Auth_Negotiate command is completed, the iocb_cmpl
1481 1484 * will get called as the solicited mbox cmd
1482 1485 * callback. Some switch only support NULL dhchap in which case negotiate
1483 1486 * should be modified to only have NULL DH specificed.
1484 1487 *
1485 1488 */
1486 1489 /* ARGSUSED */
1487 1490 static int
1488 1491 emlxs_issue_auth_negotiate(
1489 1492 emlxs_port_t *port,
1490 1493 emlxs_node_t *ndlp,
1491 1494 uint8_t retry)
1492 1495 {
1493 1496 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1494 1497 fc_packet_t *pkt;
1495 1498 uint32_t cmd_size;
1496 1499 uint32_t rsp_size;
1497 1500 uint16_t cmdsize;
1498 1501 AUTH_MSG_NEGOT_NULL_1 *null_ap1;
1499 1502 AUTH_MSG_NEGOT_NULL_2 *null_ap2;
1500 1503 uint32_t num_hs = 0;
1501 1504 uint8_t flag;
1502 1505 AUTH_MSG_NEGOT_1 *ap1;
1503 1506 AUTH_MSG_NEGOT_2 *ap2;
1504 1507 uint16_t para_len = 0;
1505 1508 uint16_t hash_wcnt = 0;
1506 1509 uint16_t dhgp_wcnt = 0;
1507 1510
1508 1511
1509 1512 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_NEGOTIATE_ISSUE, 0, 0);
1510 1513
1511 1514 /* Full DH group support limit:2, only NULL group support limit:1 */
1512 1515 flag = (node_dhc->nlp_auth_limit == 2) ? 1 : 0;
1513 1516
1514 1517 /* first: determine the cmdsize based on the auth cfg parameters */
1515 1518 if (flag == 1) {
1516 1519 /* May be Full DH group + 2 hash may not be */
1517 1520 cmdsize = sizeof (AUTH_MSG_NEGOT_NULL);
1518 1521
1519 1522 cmdsize += 2 + 2; /* name tag: 2, name length: 2 */
1520 1523 cmdsize += 8; /* WWN: 8 */
1521 1524 cmdsize += 4; /* num of protocol: 4 */
1522 1525 cmdsize += 4; /* protocol parms length: 4 */
1523 1526 cmdsize += 4; /* protocol id: 4 */
1524 1527 para_len += 4;
1525 1528
1526 1529 cmdsize += 2 + 2; /* hashlist: tag: 2, count:2 */
1527 1530 para_len += 4;
1528 1531
1529 1532 if (node_dhc->auth_cfg.hash_priority[1] == 0x00) {
1530 1533 /* only one hash func */
1531 1534 cmdsize += 4;
1532 1535 num_hs = 1;
1533 1536 para_len += 4;
1534 1537 hash_wcnt = 1;
1535 1538 } else {
1536 1539 /* two hash funcs */
1537 1540 cmdsize += 4 + 4;
1538 1541 num_hs = 2;
1539 1542 para_len += 4 + 4;
1540 1543 hash_wcnt = 2;
1541 1544 }
1542 1545
1543 1546 cmdsize += 2 + 2;
1544 1547 para_len += 4;
1545 1548 if (node_dhc->auth_cfg.dh_group_priority[1] == 0xf) {
1546 1549 /* only one dhgp specified: could be NULL or non-NULL */
1547 1550 cmdsize += 4;
1548 1551 para_len += 4;
1549 1552 dhgp_wcnt = 1;
1550 1553
1551 1554 } else if (node_dhc->auth_cfg.dh_group_priority[2] == 0xf) {
1552 1555 /* two dhgps specified */
1553 1556 cmdsize += 4 + 4;
1554 1557 para_len += 4 + 4;
1555 1558 dhgp_wcnt = 2;
1556 1559
1557 1560 } else if (node_dhc->auth_cfg.dh_group_priority[3] == 0xf) {
1558 1561 /* three dhgps specified */
1559 1562 cmdsize += 4 + 4 + 4;
1560 1563 para_len += 4 + 4 + 4;
1561 1564 dhgp_wcnt = 3;
1562 1565
1563 1566 } else if (node_dhc->auth_cfg.dh_group_priority[4] == 0xf) {
1564 1567 /* four dhgps specified */
1565 1568 cmdsize += 4 + 4 + 4 + 4;
1566 1569 para_len += 4 + 4 + 4 + 4;
1567 1570 dhgp_wcnt = 4;
1568 1571
1569 1572 } else if (node_dhc->auth_cfg.dh_group_priority[5] == 0xf) {
1570 1573 cmdsize += 4 + 4 + 4 + 4 + 4;
1571 1574 para_len += 4 + 4 + 4 + 4 + 4;
1572 1575 dhgp_wcnt = 5;
1573 1576
1574 1577 }
1575 1578 } else {
1576 1579 cmdsize = sizeof (AUTH_MSG_NEGOT_NULL);
1577 1580
1578 1581 /*
1579 1582 * get the right payload size in byte: determined by config
1580 1583 * parameters
1581 1584 */
1582 1585 cmdsize += 2 + 2 + 8; /* name tag:2, name length:2, name */
1583 1586 /* value content:8 */
1584 1587 cmdsize += 4; /* number of usable authentication */
1585 1588 /* protocols:4 */
1586 1589 cmdsize += 4; /* auth protocol params length: 4 */
1587 1590 cmdsize += 4; /* auth protocol identifier: 4 */
1588 1591
1589 1592 /* hash list infor */
1590 1593 cmdsize += 4; /* hashlist: tag:2, count:2 */
1591 1594
1592 1595 if (node_dhc->auth_cfg.hash_priority[1] == 0x00) {
1593 1596 cmdsize += 4; /* only one hash function provided */
1594 1597 num_hs = 1;
1595 1598 } else {
1596 1599 num_hs = 2;
1597 1600 cmdsize += 4 + 4; /* sha1: 4, md5: 4 */
1598 1601 }
1599 1602
1600 1603 /* dhgp list info */
1601 1604 /* since this is NULL DH group */
1602 1605 cmdsize += 4; /* dhgroup: tag:2, count:2 */
1603 1606 cmdsize += 4; /* set it to zero */
1604 1607 }
1605 1608
1606 1609 cmd_size = cmdsize;
1607 1610 rsp_size = 4;
1608 1611
1609 1612 if ((pkt = emlxs_prep_els_fc_pkt(port, ndlp->nlp_DID, cmd_size,
1610 1613 rsp_size, 0, KM_NOSLEEP)) == NULL) {
1611 1614 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
1612 1615 "issue_auth_negotiate: Unable to allocate pkt. 0x%x %d",
1613 1616 ndlp->nlp_DID, cmd_size);
1614 1617
1615 1618 return (1);
1616 1619 }
1617 1620 /* Fill in AUTH_MSG_NEGOT payload */
1618 1621 if (flag == 1) {
1619 1622 if (hash_wcnt == 1) {
1620 1623 ap1 = (AUTH_MSG_NEGOT_1 *)pkt->pkt_cmd;
1621 1624 ap1->auth_els_code = ELS_CMD_AUTH_CODE;
1622 1625 ap1->auth_els_flags = 0x00;
1623 1626 ap1->auth_msg_code = AUTH_NEGOTIATE;
1624 1627 ap1->proto_version = 0x01;
1625 1628 ap1->msg_len = LE_SWAP32(cmdsize -
1626 1629 sizeof (AUTH_MSG_NEGOT_NULL));
1627 1630 } else {
1628 1631 ap2 = (AUTH_MSG_NEGOT_2 *)pkt->pkt_cmd;
1629 1632 ap2->auth_els_code = ELS_CMD_AUTH_CODE;
1630 1633 ap2->auth_els_flags = 0x00;
1631 1634 ap2->auth_msg_code = AUTH_NEGOTIATE;
1632 1635 ap2->proto_version = 0x01;
1633 1636 ap2->msg_len = LE_SWAP32(cmdsize -
1634 1637 sizeof (AUTH_MSG_NEGOT_NULL));
1635 1638 }
1636 1639 } else {
1637 1640 if (node_dhc->auth_cfg.hash_priority[1] == 0x00) {
1638 1641 null_ap1 = (AUTH_MSG_NEGOT_NULL_1 *)pkt->pkt_cmd;
1639 1642 null_ap1->auth_els_code = ELS_CMD_AUTH_CODE;
1640 1643 null_ap1->auth_els_flags = 0x0;
1641 1644 null_ap1->auth_msg_code = AUTH_NEGOTIATE;
1642 1645 null_ap1->proto_version = 0x01;
1643 1646 null_ap1->msg_len = LE_SWAP32(cmdsize -
1644 1647 sizeof (AUTH_MSG_NEGOT_NULL));
1645 1648
1646 1649 } else {
1647 1650 null_ap2 = (AUTH_MSG_NEGOT_NULL_2 *)pkt->pkt_cmd;
1648 1651 null_ap2->auth_els_code = ELS_CMD_AUTH_CODE;
1649 1652 null_ap2->auth_els_flags = 0x0;
1650 1653 null_ap2->auth_msg_code = AUTH_NEGOTIATE;
1651 1654 null_ap2->proto_version = 0x01;
1652 1655 null_ap2->msg_len = LE_SWAP32(cmdsize -
1653 1656 sizeof (AUTH_MSG_NEGOT_NULL));
1654 1657 }
1655 1658 }
1656 1659
1657 1660 /*
1658 1661 * For host reauthentication heart beat, the tran_id is incremented
1659 1662 * by one for each heart beat being fired and round back to 1 when
1660 1663 * 0xffffffff is reached. tran_id 0 is reserved as the initial linkup
1661 1664 * authentication transaction id.
1662 1665 */
1663 1666
1664 1667 /* responder flag:2, initiator flag:1 */
1665 1668 node_dhc->nlp_auth_flag = 2; /* ndlp is the always the auth */
1666 1669 /* responder */
1667 1670
1668 1671 if (node_dhc->nlp_reauth_status == NLP_HOST_REAUTH_IN_PROGRESS) {
1669 1672 if (node_dhc->nlp_auth_tranid_rsp == 0xffffffff) {
1670 1673 node_dhc->nlp_auth_tranid_rsp = 1;
1671 1674 } else {
1672 1675 node_dhc->nlp_auth_tranid_rsp++;
1673 1676 }
1674 1677 } else { /* !NLP_HOST_REAUTH_IN_PROGRESS */
1675 1678 node_dhc->nlp_auth_tranid_rsp = 0;
1676 1679 }
1677 1680
1678 1681 if (flag == 1) {
1679 1682 if (hash_wcnt == 1) {
1680 1683 ap1->tran_id =
1681 1684 LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1682 1685
1683 1686 ap1->params.name_tag = AUTH_NAME_ID;
1684 1687 ap1->params.name_len = AUTH_NAME_LEN;
1685 1688 bcopy((void *)&port->wwpn,
1686 1689 (void *) &ap1->params.nodeName, sizeof (NAME_TYPE));
1687 1690 ap1->params.proto_num = AUTH_PROTO_NUM;
1688 1691 ap1->params.para_len = LE_SWAP32(para_len);
1689 1692 ap1->params.proto_id = AUTH_DHCHAP;
1690 1693 ap1->params.HashList_tag = HASH_LIST_TAG;
1691 1694 ap1->params.HashList_wcnt = LE_SWAP16(hash_wcnt);
1692 1695 ap1->params.HashList_value1 =
1693 1696 node_dhc->auth_cfg.hash_priority[0];
1694 1697 ap1->params.DHgIDList_tag = DHGID_LIST_TAG;
1695 1698 ap1->params.DHgIDList_wnt = LE_SWAP16(dhgp_wcnt);
1696 1699
1697 1700 switch (dhgp_wcnt) {
1698 1701 case 5:
1699 1702 ap1->params.DHgIDList_g4 =
1700 1703 (node_dhc->auth_cfg.dh_group_priority[4]);
1701 1704 ap1->params.DHgIDList_g3 =
1702 1705 (node_dhc->auth_cfg.dh_group_priority[3]);
1703 1706 ap1->params.DHgIDList_g2 =
1704 1707 (node_dhc->auth_cfg.dh_group_priority[2]);
1705 1708 ap1->params.DHgIDList_g1 =
1706 1709 (node_dhc->auth_cfg.dh_group_priority[1]);
1707 1710 ap1->params.DHgIDList_g0 =
1708 1711 (node_dhc->auth_cfg.dh_group_priority[0]);
1709 1712 break;
1710 1713 case 4:
1711 1714 ap1->params.DHgIDList_g3 =
1712 1715 (node_dhc->auth_cfg.dh_group_priority[3]);
1713 1716 ap1->params.DHgIDList_g2 =
1714 1717 (node_dhc->auth_cfg.dh_group_priority[2]);
1715 1718 ap1->params.DHgIDList_g1 =
1716 1719 (node_dhc->auth_cfg.dh_group_priority[1]);
1717 1720 ap1->params.DHgIDList_g0 =
1718 1721 (node_dhc->auth_cfg.dh_group_priority[0]);
1719 1722 break;
1720 1723 case 3:
1721 1724 ap1->params.DHgIDList_g2 =
1722 1725 (node_dhc->auth_cfg.dh_group_priority[2]);
1723 1726 ap1->params.DHgIDList_g1 =
1724 1727 (node_dhc->auth_cfg.dh_group_priority[1]);
1725 1728 ap1->params.DHgIDList_g0 =
1726 1729 (node_dhc->auth_cfg.dh_group_priority[0]);
1727 1730 break;
1728 1731 case 2:
1729 1732 ap1->params.DHgIDList_g1 =
1730 1733 (node_dhc->auth_cfg.dh_group_priority[1]);
1731 1734 ap1->params.DHgIDList_g0 =
1732 1735 (node_dhc->auth_cfg.dh_group_priority[0]);
1733 1736 break;
1734 1737 case 1:
1735 1738 ap1->params.DHgIDList_g0 =
1736 1739 (node_dhc->auth_cfg.dh_group_priority[0]);
1737 1740 break;
1738 1741 }
1739 1742 } else {
1740 1743 ap2->tran_id =
1741 1744 LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1742 1745
1743 1746 ap2->params.name_tag = AUTH_NAME_ID;
1744 1747 ap2->params.name_len = AUTH_NAME_LEN;
1745 1748 bcopy((void *) &port->wwpn,
1746 1749 (void *) &ap2->params.nodeName, sizeof (NAME_TYPE));
1747 1750 ap2->params.proto_num = AUTH_PROTO_NUM;
1748 1751 ap2->params.para_len = LE_SWAP32(para_len);
1749 1752 ap2->params.proto_id = AUTH_DHCHAP;
1750 1753 ap2->params.HashList_tag = HASH_LIST_TAG;
1751 1754 ap2->params.HashList_wcnt = LE_SWAP16(hash_wcnt);
1752 1755 ap2->params.HashList_value1 =
1753 1756 (node_dhc->auth_cfg.hash_priority[0]);
1754 1757 ap2->params.HashList_value2 =
1755 1758 (node_dhc->auth_cfg.hash_priority[1]);
1756 1759
1757 1760 ap2->params.DHgIDList_tag = DHGID_LIST_TAG;
1758 1761 ap2->params.DHgIDList_wnt = LE_SWAP16(dhgp_wcnt);
1759 1762
1760 1763 switch (dhgp_wcnt) {
1761 1764 case 5:
1762 1765 ap2->params.DHgIDList_g4 =
1763 1766 (node_dhc->auth_cfg.dh_group_priority[4]);
1764 1767 ap2->params.DHgIDList_g3 =
1765 1768 (node_dhc->auth_cfg.dh_group_priority[3]);
1766 1769 ap2->params.DHgIDList_g2 =
1767 1770 (node_dhc->auth_cfg.dh_group_priority[2]);
1768 1771 ap2->params.DHgIDList_g1 =
1769 1772 (node_dhc->auth_cfg.dh_group_priority[1]);
1770 1773 ap2->params.DHgIDList_g0 =
1771 1774 (node_dhc->auth_cfg.dh_group_priority[0]);
1772 1775 break;
1773 1776 case 4:
1774 1777 ap2->params.DHgIDList_g3 =
1775 1778 (node_dhc->auth_cfg.dh_group_priority[3]);
1776 1779 ap2->params.DHgIDList_g2 =
1777 1780 (node_dhc->auth_cfg.dh_group_priority[2]);
1778 1781 ap2->params.DHgIDList_g1 =
1779 1782 (node_dhc->auth_cfg.dh_group_priority[1]);
1780 1783 ap2->params.DHgIDList_g0 =
1781 1784 (node_dhc->auth_cfg.dh_group_priority[0]);
1782 1785 break;
1783 1786 case 3:
1784 1787 ap2->params.DHgIDList_g2 =
1785 1788 (node_dhc->auth_cfg.dh_group_priority[2]);
1786 1789 ap2->params.DHgIDList_g1 =
1787 1790 (node_dhc->auth_cfg.dh_group_priority[1]);
1788 1791 ap2->params.DHgIDList_g0 =
1789 1792 (node_dhc->auth_cfg.dh_group_priority[0]);
1790 1793 break;
1791 1794 case 2:
1792 1795 ap2->params.DHgIDList_g1 =
1793 1796 (node_dhc->auth_cfg.dh_group_priority[1]);
1794 1797 ap2->params.DHgIDList_g0 =
1795 1798 (node_dhc->auth_cfg.dh_group_priority[0]);
1796 1799 break;
1797 1800 case 1:
1798 1801 ap2->params.DHgIDList_g0 =
1799 1802 (node_dhc->auth_cfg.dh_group_priority[0]);
1800 1803 break;
1801 1804 }
1802 1805 }
1803 1806 } else {
1804 1807 if (num_hs == 1) {
1805 1808 null_ap1->tran_id =
1806 1809 LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1807 1810
1808 1811 null_ap1->params.name_tag = AUTH_NAME_ID;
1809 1812 null_ap1->params.name_len = AUTH_NAME_LEN;
1810 1813 bcopy((void *) &port->wwpn,
1811 1814 (void *) &null_ap1->params.nodeName,
1812 1815 sizeof (NAME_TYPE));
1813 1816 null_ap1->params.proto_num = AUTH_PROTO_NUM;
1814 1817 null_ap1->params.para_len = LE_SWAP32(0x00000014);
1815 1818 null_ap1->params.proto_id = AUTH_DHCHAP;
1816 1819 null_ap1->params.HashList_tag = HASH_LIST_TAG;
1817 1820 null_ap1->params.HashList_wcnt = LE_SWAP16(0x0001);
1818 1821 null_ap1->params.HashList_value1 =
1819 1822 (node_dhc->auth_cfg.hash_priority[0]);
1820 1823 null_ap1->params.DHgIDList_tag = DHGID_LIST_TAG;
1821 1824 null_ap1->params.DHgIDList_wnt = LE_SWAP16(0x0001);
1822 1825 null_ap1->params.DHgIDList_g0 = 0x0;
1823 1826 } else {
1824 1827 null_ap2->tran_id =
1825 1828 LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
1826 1829
1827 1830 null_ap2->params.name_tag = AUTH_NAME_ID;
1828 1831 null_ap2->params.name_len = AUTH_NAME_LEN;
1829 1832 bcopy((void *) &port->wwpn,
1830 1833 (void *) &null_ap2->params.nodeName,
1831 1834 sizeof (NAME_TYPE));
1832 1835 null_ap2->params.proto_num = AUTH_PROTO_NUM;
1833 1836 null_ap2->params.para_len = LE_SWAP32(0x00000018);
1834 1837 null_ap2->params.proto_id = AUTH_DHCHAP;
1835 1838
1836 1839 null_ap2->params.HashList_tag = HASH_LIST_TAG;
1837 1840 null_ap2->params.HashList_wcnt = LE_SWAP16(0x0002);
1838 1841 null_ap2->params.HashList_value1 =
1839 1842 (node_dhc->auth_cfg.hash_priority[0]);
1840 1843 null_ap2->params.HashList_value2 =
1841 1844 (node_dhc->auth_cfg.hash_priority[1]);
1842 1845
1843 1846 null_ap2->params.DHgIDList_tag = DHGID_LIST_TAG;
1844 1847 null_ap2->params.DHgIDList_wnt = LE_SWAP16(0x0001);
1845 1848 null_ap2->params.DHgIDList_g0 = 0x0;
1846 1849 }
1847 1850 }
1848 1851
1849 1852 pkt->pkt_comp = emlxs_cmpl_auth_negotiate_issue;
1850 1853
1851 1854 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
1852 1855 "issue_auth_negotiate: %x flag=%d size=%d hash=%x,%x tid=%x,%x",
1853 1856 ndlp->nlp_DID, flag, cmd_size,
1854 1857 node_dhc->auth_cfg.hash_priority[0],
1855 1858 node_dhc->auth_cfg.hash_priority[1],
1856 1859 node_dhc->nlp_auth_tranid_rsp, node_dhc->nlp_auth_tranid_ini);
1857 1860
1858 1861 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
1859 1862 emlxs_pkt_free(pkt);
1860 1863
1861 1864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
1862 1865 "issue_auth_negotiate: Unable to send pkt. did=0x%x",
1863 1866 ndlp->nlp_DID);
1864 1867
1865 1868 return (1);
1866 1869 }
1867 1870 return (0);
1868 1871
1869 1872 } /* emlxs_issue_auth_negotiate() */
1870 1873
1871 1874
1872 1875
1873 1876 /*
1874 1877 * ! emlxs_cmpl_auth_negotiate_issue
1875 1878 *
1876 1879 * \pre \post \param phba \param cmdiocb \param rspiocb \return void
1877 1880 *
1878 1881 * \b Description: iocb_cmpl callback function.
1879 1882 *
1880 1883 */
1881 1884 static void
1882 1885 emlxs_cmpl_auth_negotiate_issue(fc_packet_t *pkt)
1883 1886 {
1884 1887 emlxs_port_t *port = pkt->pkt_ulp_private;
1885 1888 emlxs_buf_t *sbp;
1886 1889 NODELIST *ndlp;
1887 1890 emlxs_node_dhc_t *node_dhc;
1888 1891 uint32_t did;
1889 1892
1890 1893 did = pkt->pkt_cmd_fhdr.d_id;
1891 1894 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
1892 1895 ndlp = sbp->node;
1893 1896 node_dhc = &ndlp->node_dhc;
1894 1897
1895 1898 if (!ndlp) {
1896 1899 ndlp = emlxs_node_find_did(port, did);
1897 1900 }
1898 1901 if (pkt->pkt_state != FC_PKT_SUCCESS) {
1899 1902 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1900 1903 "emlxs_cmpl_dhchap_negotiate_issue: 0x%x %x. Noretry.",
1901 1904 did, pkt->pkt_state);
1902 1905 } else {
1903 1906 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1904 1907 "emlxs_cmpl_dhchap_negotiate_issue: did=0x%x. Succcess.",
1905 1908 did);
1906 1909 }
1907 1910
1908 1911 if (ndlp) {
1909 1912 if (pkt->pkt_state == FC_PKT_SUCCESS) {
1910 1913 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
1911 1914 NULL, ndlp, NODE_EVENT_CMPL_AUTH_MSG);
1912 1915 } else {
1913 1916 emlxs_dhc_set_reauth_time(port, ndlp, DISABLE);
1914 1917
1915 1918 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
1916 1919 0, 0);
1917 1920
1918 1921 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
1919 1922 "Reauth disabled. did=0x%x state=%x",
1920 1923 ndlp->nlp_DID, node_dhc->state);
1921 1924
1922 1925 emlxs_dhc_auth_complete(port, ndlp, 1);
1923 1926 }
1924 1927 }
1925 1928 emlxs_pkt_free(pkt);
1926 1929
1927 1930 return;
1928 1931
1929 1932 } /* emlxs_cmpl_auth_negotiate_issue */
1930 1933
1931 1934
1932 1935 /*
1933 1936 * ! emlxs_cmpl_auth_msg_auth_negotiate_issue
1934 1937 *
1935 1938 * \pre \post \param port \param CHANNEL * rp \param arg \param evt
1936 1939 * \return uint32_t \b Description:
1937 1940 *
1938 1941 * This routine is invoked when the host receive the solicited ACC/RJT ELS
1939 1942 * cmd from an NxPort or FxPort that has received the ELS
1940 1943 * AUTH Negotiate msg from the host. in case of RJT, Auth_Negotiate should
1941 1944 * be retried in emlxs_cmpl_auth_negotiate_issue
1942 1945 * call. in case of ACC, the host must be the initiator because its current
1943 1946 * state could be "AUTH_NEGOTIATE_RCV" if it is the
1944 1947 * responder. Then the next stat = AUTH_NEGOTIATE_CMPL_WAIT4NEXT
1945 1948 */
1946 1949 /* ARGSUSED */
1947 1950 static uint32_t
1948 1951 emlxs_cmpl_auth_msg_auth_negotiate_issue(
1949 1952 emlxs_port_t *port,
1950 1953 /* CHANNEL * rp, */ void *arg1,
1951 1954 /* IOCBQ * iocbq, */ void *arg2,
1952 1955 /* MATCHMAP * mp, */ void *arg3,
1953 1956 /* NODELIST * ndlp, */ void *arg4,
1954 1957 uint32_t evt)
1955 1958 {
1956 1959 NODELIST *ndlp = (NODELIST *)arg4;
1957 1960 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
1958 1961
1959 1962 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
1960 1963 "emlxs_cmpl_auth_msg_auth_negotiate_issue: did=0x%x",
1961 1964 ndlp->nlp_DID);
1962 1965
1963 1966 /* start the emlxs_dhc_authrsp_timeout timer */
1964 1967 if (node_dhc->nlp_authrsp_tmo == 0) {
1965 1968 node_dhc->nlp_authrsp_tmo = DRV_TIME +
1966 1969 node_dhc->auth_cfg.authentication_timeout;
1967 1970 }
1968 1971 /*
1969 1972 * The next state should be
1970 1973 * emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next
1971 1974 */
1972 1975 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_NEGOTIATE_CMPL_WAIT4NEXT,
1973 1976 0, 0);
1974 1977
1975 1978 return (node_dhc->state);
1976 1979
1977 1980 } /* emlxs_cmpl_auth_msg_auth_negotiate_issue */
1978 1981
1979 1982
1980 1983
1981 1984 /*
1982 1985 * ! emlxs_rcv_auth_msg_auth_negotiate_issue
1983 1986 *
1984 1987 * \pre \post \param phba \param ndlp \param arg \param evt \return
1985 1988 * uint32_t \b Description:
1986 1989 *
1987 1990 * This routine is supported for HBA in either auth initiator mode or
1988 1991 * responder mode.
1989 1992 *
1990 1993 * This routine is invoked when the host receive an unsolicited ELS AUTH Msg
1991 1994 * from an NxPort or FxPort to which the host has just
1992 1995 * sent out an ELS AUTH negotiate msg. and the NxPort or FxPort also LS_ACC
1993 1996 * to the host's AUTH_Negotiate msg.
1994 1997 *
1995 1998 * If this unsolicited ELS auth msg is from the FxPort or a NxPort with a
1996 1999 * numerically lower WWPN, the host will be the winner in
1997 2000 * this authentication transaction initiation phase, the host as the
1998 2001 * initiator will send back ACC and then Auth_Reject message
1999 2002 * with the Reason Code 'Logical Error' and Reason Code Explanation'
2000 2003 * Authentication Transaction Already Started' and with the
2001 2004 * current state unchanged and mark itself as auth_initiator.
2002 2005 *
2003 2006 * Otherwise, the host will be the responder that will reply to the received
2004 2007 * AUTH_Negotiate message will ACC (or RJT?) and abort
2005 2008 * its own transaction upon receipt of the AUTH_Reject message. The new state
2006 2009 * will be "AUTH_NEGOTIATE_RCV" and mark the host as
2007 2010 * auth_responder.
2008 2011 */
2009 2012 /* ARGSUSED */
2010 2013 static uint32_t
2011 2014 emlxs_rcv_auth_msg_auth_negotiate_issue(
2012 2015 emlxs_port_t *port,
2013 2016 /* CHANNEL * rp, */ void *arg1,
2014 2017 /* IOCBQ * iocbq, */ void *arg2,
2015 2018 /* MATCHMAP * mp, */ void *arg3,
2016 2019 /* NODELIST * ndlp */ void *arg4,
2017 2020 uint32_t evt)
2018 2021 {
2019 2022 NODELIST *ndlp = (NODELIST *)arg4;
2020 2023 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
2021 2024 IOCBQ *iocbq = (IOCBQ *) arg2;
2022 2025 uint8_t ReasonCode;
2023 2026 uint8_t ReasonCodeExplanation;
2024 2027
2025 2028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2026 2029 "emlxs_rcv_auth_msg_auth_negotiate_issue: did=0x%x",
2027 2030 ndlp->nlp_DID);
2028 2031
2029 2032 /* Anyway we accept it first and then send auth_reject */
2030 2033 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
2031 2034
2032 2035 /* host is always the initiator and it should win */
2033 2036 ReasonCode = AUTHRJT_LOGIC_ERR;
2034 2037 ReasonCodeExplanation = AUTHEXP_AUTHTRAN_STARTED;
2035 2038
2036 2039 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_NEGOTIATE_ISSUE,
2037 2040 ReasonCode, ReasonCodeExplanation);
2038 2041 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
2039 2042 ReasonCodeExplanation);
2040 2043
2041 2044 return (node_dhc->state);
2042 2045
2043 2046 } /* emlxs_rcv_auth_msg_auth_negotiate_issue */
2044 2047
2045 2048
2046 2049 /*
2047 2050 * ! emlxs_cmpl_dhchap_reply_issue
2048 2051 *
2049 2052 * \pre \post \param phba \param cmdiocb \param rspiocb \return void
2050 2053 *
2051 2054 * \b Description: iocb_cmpl callback function.
2052 2055 *
2053 2056 */
2054 2057 static void
2055 2058 emlxs_cmpl_dhchap_reply_issue(fc_packet_t *pkt)
2056 2059 {
2057 2060 emlxs_port_t *port = pkt->pkt_ulp_private;
2058 2061 emlxs_buf_t *sbp;
2059 2062 NODELIST *ndlp;
2060 2063 uint32_t did;
2061 2064
2062 2065 did = pkt->pkt_cmd_fhdr.d_id;
2063 2066 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
2064 2067 ndlp = sbp->node;
2065 2068
2066 2069 if (!ndlp) {
2067 2070 ndlp = emlxs_node_find_did(port, did);
2068 2071 }
2069 2072 if (pkt->pkt_state != FC_PKT_SUCCESS) {
2070 2073 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2071 2074 "emlxs_cmpl_dhchap_reply_issue: 0x%x %x. No retry.",
2072 2075 did, pkt->pkt_state);
2073 2076 } else {
2074 2077 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2075 2078 "emlxs_cmpl_dhchap_reply_issue: did=0x%x. Succcess.",
2076 2079 did);
2077 2080 }
2078 2081
2079 2082 if (ndlp) {
2080 2083 if (pkt->pkt_state == FC_PKT_SUCCESS) {
2081 2084 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
2082 2085 NULL, ndlp, NODE_EVENT_CMPL_AUTH_MSG);
2083 2086 }
2084 2087 }
2085 2088 emlxs_pkt_free(pkt);
2086 2089
2087 2090 return;
2088 2091
2089 2092 } /* emlxs_cmpl_dhchap_reply_issue */
2090 2093
2091 2094
2092 2095 /*
2093 2096 * arg: the AUTH_Negotiate payload from the initiator. payload_len: the
2094 2097 * payload length
2095 2098 *
2096 2099 * We always send out the challenge parameter based on our preference
2097 2100 * order configured on the host side no matter what perference
2098 2101 * order looks like from auth_negotiate . In other words, if the host issue
2099 2102 * the challenge the host will make the decision as to
2100 2103 * what hash function, what dhgp_id is to be used.
2101 2104 *
2102 2105 * This challenge value should not be confused with the challenge value for
2103 2106 * bi-dir as part of reply when host is the initiator.
2104 2107 */
2105 2108 /* ARGSUSED */
2106 2109 uint32_t
2107 2110 emlxs_issue_dhchap_challenge(
2108 2111 emlxs_port_t *port,
2109 2112 NODELIST *ndlp,
2110 2113 int retry,
2111 2114 void *arg,
2112 2115 uint32_t payload_len,
2113 2116 uint32_t hash_id,
2114 2117 uint32_t dhgp_id)
2115 2118 {
2116 2119 emlxs_hba_t *hba = HBA;
2117 2120 fc_packet_t *pkt;
2118 2121 uint32_t cmd_size;
2119 2122 uint32_t rsp_size;
2120 2123 uint16_t cmdsize = 0;
2121 2124 uint8_t *pCmd;
2122 2125 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
2123 2126 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
2124 2127 DHCHAP_CHALL *chal;
2125 2128 uint8_t *tmp;
2126 2129 uint8_t random_number[20];
2127 2130 uint8_t dhval[256];
2128 2131 uint32_t dhval_len;
2129 2132 uint32_t tran_id;
2130 2133 BIG_ERR_CODE err = BIG_OK;
2131 2134
2132 2135 /*
2133 2136 * we assume the HBAnyware should configure the driver the right
2134 2137 * parameters for challenge. for now, we create our own challenge.
2135 2138 */
2136 2139 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2137 2140 "emlxs_issue_dhchap_challenge: did=0x%x hashlist=[%x,%x,%x,%x]",
2138 2141 ndlp->nlp_DID, node_dhc->auth_cfg.hash_priority[0],
2139 2142 node_dhc->auth_cfg.hash_priority[1],
2140 2143 node_dhc->auth_cfg.hash_priority[2],
2141 2144 node_dhc->auth_cfg.hash_priority[3]);
2142 2145
2143 2146 /*
2144 2147 * Here is my own challenge structure:
2145 2148 *
2146 2149 * 1: AUTH_MSG_HDR (12 bytes + 4 bytes + 8 bytes) 2: hasd_id (4
2147 2150 * bytes) 3: dhgp_id (4 bytes) 4: cval_len (4 bytes) 5: cval
2148 2151 * (20 bytes or 16 bytes: cval_len bytes) 6: dhval_len (4 bytes)
2149 2152 * 7: dhval (dhval_len bytes) all these information should be stored
2150 2153 * in port_dhc struct
2151 2154 */
2152 2155 if (hash_id == AUTH_SHA1) {
2153 2156 cmdsize = (12 + 4 + 8) + (4 + 4 + 4) + 20 + 4;
2154 2157 } else if (hash_id == AUTH_MD5) {
2155 2158 cmdsize = (12 + 4 + 8) + (4 + 4 + 4) + 16 + 4;
2156 2159 } else {
2157 2160 return (1);
2158 2161 }
2159 2162
2160 2163
2161 2164 switch (dhgp_id) {
2162 2165 case GROUP_NULL:
2163 2166 break;
2164 2167
2165 2168 case GROUP_1024:
2166 2169 cmdsize += 128;
2167 2170 break;
2168 2171
2169 2172 case GROUP_1280:
2170 2173 cmdsize += 160;
2171 2174 break;
2172 2175
2173 2176 case GROUP_1536:
2174 2177 cmdsize += 192;
2175 2178 break;
2176 2179
2177 2180 case GROUP_2048:
2178 2181 cmdsize += 256;
2179 2182 break;
2180 2183
2181 2184 default:
2182 2185 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2183 2186 "emlxs_issue_dhchap_challenge: Invalid dhgp_id=0x%x",
2184 2187 dhgp_id);
2185 2188 return (1);
2186 2189 }
2187 2190
2188 2191 cmd_size = cmdsize;
2189 2192 rsp_size = 4;
2190 2193
2191 2194 if ((pkt = emlxs_prep_els_fc_pkt(port, ndlp->nlp_DID, cmd_size,
2192 2195 rsp_size,
2193 2196 0, KM_NOSLEEP)) == NULL) {
2194 2197 return (1);
2195 2198 }
2196 2199 pCmd = (uint8_t *)pkt->pkt_cmd;
2197 2200
2198 2201 tmp = (uint8_t *)arg;
2199 2202 tmp += 8;
2200 2203 /* collect tran_id: this tran_id is set by the initiator */
2201 2204 tran_id = *(uint32_t *)tmp;
2202 2205
2203 2206 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2204 2207 "emlxs_issue_dhchap_challenge: 0x%x 0x%x 0x%x %d 0x%x 0x%x 0x%x",
2205 2208 ndlp->nlp_DID, node_dhc->nlp_auth_tranid_ini,
2206 2209 node_dhc->nlp_auth_tranid_rsp,
2207 2210 cmdsize, tran_id, hash_id, dhgp_id);
2208 2211
2209 2212 /* store the tran_id : ndlp is the initiator */
2210 2213 node_dhc->nlp_auth_tranid_ini = LE_SWAP32(tran_id);
2211 2214
2212 2215 tmp += sizeof (uint32_t);
2213 2216
2214 2217 chal = (DHCHAP_CHALL *)pCmd;
2215 2218 chal->cnul.msg_hdr.auth_els_code = ELS_CMD_AUTH_CODE;
2216 2219 chal->cnul.msg_hdr.auth_els_flags = 0x0;
2217 2220 chal->cnul.msg_hdr.auth_msg_code = DHCHAP_CHALLENGE;
2218 2221 chal->cnul.msg_hdr.proto_version = 0x01;
2219 2222 chal->cnul.msg_hdr.msg_len = LE_SWAP32(cmdsize - 12);
2220 2223 chal->cnul.msg_hdr.tran_id = tran_id;
2221 2224 chal->cnul.msg_hdr.name_tag = (AUTH_NAME_ID);
2222 2225 chal->cnul.msg_hdr.name_len = (AUTH_NAME_LEN);
2223 2226
2224 2227 bcopy((void *) &port->wwpn,
2225 2228 (void *) &chal->cnul.msg_hdr.nodeName, sizeof (NAME_TYPE));
2226 2229
2227 2230 chal->cnul.hash_id = hash_id;
2228 2231 chal->cnul.dhgp_id = dhgp_id;
2229 2232
2230 2233 chal->cnul.cval_len = ((chal->cnul.hash_id == AUTH_SHA1) ?
2231 2234 LE_SWAP32(SHA1_LEN) : LE_SWAP32(MD5_LEN));
2232 2235
2233 2236 tmp = (uint8_t *)pCmd;
2234 2237 tmp += sizeof (DHCHAP_CHALL_NULL);
2235 2238
2236 2239 #ifdef RAND
2237 2240 /* generate a random number as the challenge */
2238 2241 bzero(random_number, LE_SWAP32(chal->cnul.cval_len));
2239 2242
2240 2243 if (hba->rdn_flag == 1) {
2241 2244 emlxs_get_random_bytes(ndlp, random_number, 20);
2242 2245 } else {
2243 2246 (void) random_get_pseudo_bytes(random_number,
2244 2247 LE_SWAP32(chal->cnul.cval_len));
2245 2248 }
2246 2249
2247 2250 /*
2248 2251 * the host should store the challenge for later usage when later on
2249 2252 * host get the reply msg, host needs to verify it by using its old
2250 2253 * challenge, its private key as the input to the hash function. the
2251 2254 * challenge as the random_number should be stored in
2252 2255 * node_dhc->hrsp_cval[]
2253 2256 */
2254 2257 if (ndlp->nlp_DID == FABRIC_DID) {
2255 2258 bcopy((void *) &random_number[0],
2256 2259 (void *) &node_dhc->hrsp_cval[0],
2257 2260 LE_SWAP32(chal->cnul.cval_len));
2258 2261 /* save another copy in partner's ndlp */
2259 2262 bcopy((void *) &random_number[0],
2260 2263 (void *) &node_dhc->nlp_auth_misc.hrsp_cval[0],
2261 2264 LE_SWAP32(chal->cnul.cval_len));
2262 2265 } else {
2263 2266 bcopy((void *) &random_number[0],
2264 2267 (void *) &node_dhc->nlp_auth_misc.hrsp_cval[0],
2265 2268 LE_SWAP32(chal->cnul.cval_len));
2266 2269 }
2267 2270 bcopy((void *) &random_number[0], (void *) tmp,
2268 2271 LE_SWAP32(chal->cnul.cval_len));
2269 2272
2270 2273 #endif /* RAND */
2271 2274
2272 2275 /* for test only hardcode the challenge value */
2273 2276 #ifdef MYRAND
2274 2277 if (ndlp->nlp_DID == FABRIC_DID) {
2275 2278 bcopy((void *) myrand, (void *) &node_dhc->hrsp_cval[0],
2276 2279 LE_SWAP32(chal->cnul.cval_len));
2277 2280 /* save another copy in partner's ndlp */
2278 2281 bcopy((void *) myrand,
2279 2282 (void *) &node_dhc->nlp_auth_misc.hrsp_cval[0],
2280 2283 LE_SWAP32(chal->cnul.cval_len));
2281 2284 } else {
2282 2285 bcopy((void *) myrand,
2283 2286 (void *) &node_dhc->nlp_auth_misc.hrsp_cval[0],
2284 2287 LE_SWAP32(chal->cnul.cval_len));
2285 2288 }
2286 2289 bcopy((void *) myrand, (void *) tmp,
2287 2290 LE_SWAP32(chal->cnul.cval_len));
2288 2291
2289 2292 #endif /* MYRAND */
2290 2293
2291 2294 if (ndlp->nlp_DID == FABRIC_DID) {
2292 2295 node_dhc->hrsp_cval_len = LE_SWAP32(chal->cnul.cval_len);
2293 2296 node_dhc->nlp_auth_misc.hrsp_cval_len =
2294 2297 LE_SWAP32(chal->cnul.cval_len);
2295 2298 } else {
2296 2299 node_dhc->nlp_auth_misc.hrsp_cval_len =
2297 2300 LE_SWAP32(chal->cnul.cval_len);
2298 2301 }
2299 2302
2300 2303 tmp += LE_SWAP32(chal->cnul.cval_len);
2301 2304
2302 2305 /*
2303 2306 * we need another random number as the private key x which will be
2304 2307 * used to compute the public key i.e. g^x mod p we intentionally set
2305 2308 * the length of private key as the same length of challenge. we have
2306 2309 * to store the private key in node_dhc->hrsp_priv_key[20].
2307 2310 */
2308 2311 #ifdef RAND
2309 2312
2310 2313 if (dhgp_id != GROUP_NULL) {
2311 2314
2312 2315 bzero(random_number, LE_SWAP32(chal->cnul.cval_len));
2313 2316
2314 2317 if (hba->rdn_flag == 1) {
2315 2318 emlxs_get_random_bytes(ndlp, random_number, 20);
2316 2319 } else {
2317 2320 (void) random_get_pseudo_bytes(random_number,
2318 2321 LE_SWAP32(chal->cnul.cval_len));
2319 2322 }
2320 2323
2321 2324 if (ndlp->nlp_DID == FABRIC_DID) {
2322 2325 bcopy((void *) &random_number[0],
2323 2326 (void *) node_dhc->hrsp_priv_key,
2324 2327 LE_SWAP32(chal->cnul.cval_len));
2325 2328 bcopy((void *) &random_number[0],
2326 2329 (void *) node_dhc->nlp_auth_misc.hrsp_priv_key,
2327 2330 LE_SWAP32(chal->cnul.cval_len));
2328 2331 } else {
2329 2332 bcopy((void *) &random_number[0],
2330 2333 (void *) node_dhc->nlp_auth_misc.hrsp_priv_key,
2331 2334 LE_SWAP32(chal->cnul.cval_len));
2332 2335 }
2333 2336 }
2334 2337 #endif /* RAND */
2335 2338
2336 2339 #ifdef MYRAND
2337 2340 if (dhgp_id != GROUP_NULL) {
2338 2341 /* For test only we hardcode the priv_key here */
2339 2342 bcopy((void *) myrand, (void *) node_dhc->hrsp_priv_key,
2340 2343 LE_SWAP32(chal->cnul.cval_len));
2341 2344
2342 2345 if (ndlp->nlp_DID == FABRIC_DID) {
2343 2346 bcopy((void *) myrand,
2344 2347 (void *) node_dhc->hrsp_priv_key,
2345 2348 LE_SWAP32(chal->cnul.cval_len));
2346 2349 bcopy((void *) myrand,
2347 2350 (void *) node_dhc->nlp_auth_misc.hrsp_priv_key,
2348 2351 LE_SWAP32(chal->cnul.cval_len));
2349 2352 } else {
2350 2353 bcopy((void *) myrand,
2351 2354 (void *) node_dhc->nlp_auth_misc.hrsp_priv_key,
2352 2355 LE_SWAP32(chal->cnul.cval_len));
2353 2356 }
2354 2357 }
2355 2358 #endif /* MYRAND */
2356 2359
2357 2360 /* also store the hash function and dhgp_id being used in challenge. */
2358 2361 /* These information could be configurable through HBAnyware */
2359 2362 node_dhc->nlp_auth_hashid = hash_id;
2360 2363 node_dhc->nlp_auth_dhgpid = dhgp_id;
2361 2364
2362 2365 /*
2363 2366 * generate the DH value DH value is g^x mod p and it is also called
2364 2367 * public key in which g is 2, x is the random number ontained above.
2365 2368 * p is the dhgp3_pVal
2366 2369 */
2367 2370
2368 2371 #ifdef MYRAND
2369 2372
2370 2373 /* to get (g^x mod p) with x private key */
2371 2374 if (dhgp_id != GROUP_NULL) {
2372 2375
2373 2376 err = emlxs_BIGNUM_get_dhval(port, port_dhc, ndlp, dhval,
2374 2377 &dhval_len, chal->cnul.dhgp_id,
2375 2378 myrand, LE_SWAP32(chal->cnul.cval_len));
2376 2379
2377 2380 if (err != BIG_OK) {
2378 2381 emlxs_pkt_free(pkt);
2379 2382
2380 2383 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2381 2384 "emlxs_issue_dhchap_challenge: error. 0x%x",
2382 2385 err);
2383 2386
2384 2387 return (1);
2385 2388 }
2386 2389 /* we are not going to use dhval and dhval_len */
2387 2390
2388 2391 /* *(uint32_t *)tmp = dhval_len; */
2389 2392 if (ndlp->nlp_DID == FABRIC_DID) {
2390 2393 *(uint32_t *)tmp =
2391 2394 LE_SWAP32(node_dhc->hrsp_pubkey_len);
2392 2395 } else {
2393 2396 *(uint32_t *)tmp =
2394 2397 LE_SWAP32(
2395 2398 node_dhc->nlp_auth_misc.hrsp_pubkey_len);
2396 2399 }
2397 2400
2398 2401 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2399 2402 "emlxs_issue_dhchap_challenge: 0x%x: 0x%x 0x%x",
2400 2403 ndlp->nlp_DID, *(uint32_t *)tmp, dhval_len);
2401 2404
2402 2405 tmp += sizeof (uint32_t);
2403 2406
2404 2407 if (ndlp->nlp_DID == FABRIC_DID) {
2405 2408 bcopy((void *) node_dhc->hrsp_pub_key, (void *)tmp,
2406 2409 node_dhc->hrsp_pubkey_len);
2407 2410 } else {
2408 2411 bcopy((void *) node_dhc->nlp_auth_misc.hrsp_pub_key,
2409 2412 (void *)tmp,
2410 2413 node_dhc->nlp_auth_misc.hrsp_pubkey_len);
2411 2414 }
2412 2415 } else {
2413 2416 /* NULL DHCHAP */
2414 2417 *(uint32_t *)tmp = 0;
2415 2418 }
2416 2419
2417 2420 #endif /* MYRAND */
2418 2421
2419 2422 #ifdef RAND
2420 2423
2421 2424 /* to get (g^x mod p) with x private key */
2422 2425 if (dhgp_id != GROUP_NULL) {
2423 2426
2424 2427 err = emlxs_BIGNUM_get_dhval(port, port_dhc, ndlp, dhval,
2425 2428 &dhval_len, chal->cnul.dhgp_id,
2426 2429 random_number, LE_SWAP32(chal->cnul.cval_len));
2427 2430
2428 2431 if (err != BIG_OK) {
2429 2432 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2430 2433 "emlxs_issue_dhchap_challenge: error. 0x%x",
2431 2434 err);
2432 2435
2433 2436 emlxs_pkt_free(pkt);
2434 2437 return (1);
2435 2438 }
2436 2439 /* we are not going to use dhval and dhval_len */
2437 2440
2438 2441 /* *(uint32_t *)tmp = dhval_len; */
2439 2442 if (ndlp->nlp_DID == FABRIC_DID) {
2440 2443 *(uint32_t *)tmp =
2441 2444 LE_SWAP32(node_dhc->hrsp_pubkey_len);
2442 2445 } else {
2443 2446 *(uint32_t *)tmp =
2444 2447 LE_SWAP32(
2445 2448 node_dhc->nlp_auth_misc.hrsp_pubkey_len);
2446 2449 }
2447 2450
2448 2451 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2449 2452 "emlxs_issue_dhchap_challenge: did=0x%x: pubkey_len=0x%x",
2450 2453 ndlp->nlp_DID, *(uint32_t *)tmp);
2451 2454
2452 2455 tmp += sizeof (uint32_t);
2453 2456
2454 2457 if (ndlp->nlp_DID == FABRIC_DID) {
2455 2458 bcopy((void *) node_dhc->hrsp_pub_key, (void *)tmp,
2456 2459 node_dhc->hrsp_pubkey_len);
2457 2460 } else {
2458 2461 bcopy((void *) node_dhc->nlp_auth_misc.hrsp_pub_key,
2459 2462 (void *)tmp,
2460 2463 node_dhc->nlp_auth_misc.hrsp_pubkey_len);
2461 2464 }
2462 2465 } else {
2463 2466 /* NULL DHCHAP */
2464 2467 *(uint32_t *)tmp = 0;
2465 2468 }
2466 2469
2467 2470 #endif /* RAND */
2468 2471
2469 2472 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2470 2473 "emlxs_issue_dhchap_challenge: 0x%x 0x%x 0x%x 0x%x 0x%x",
2471 2474 ndlp->nlp_DID, node_dhc->nlp_auth_tranid_ini,
2472 2475 node_dhc->nlp_auth_tranid_rsp,
2473 2476 chal->cnul.hash_id, chal->cnul.dhgp_id);
2474 2477
2475 2478 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2476 2479 "emlxs_issue_dhchap_challenge: 0x%x 0x%x 0x%x 0x%x",
2477 2480 ndlp->nlp_DID, tran_id, node_dhc->nlp_auth_hashid,
2478 2481 node_dhc->nlp_auth_dhgpid);
2479 2482
2480 2483 pkt->pkt_comp = emlxs_cmpl_dhchap_challenge_issue;
2481 2484
2482 2485 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2483 2486 emlxs_pkt_free(pkt);
2484 2487
2485 2488 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2486 2489 "emlxs_issue_dhchap_challenge: Unable to send fc packet.");
2487 2490
2488 2491 return (1);
2489 2492 }
2490 2493 return (0);
2491 2494
2492 2495 } /* emlxs_issue_dhchap_challenge */
2493 2496
2494 2497
2495 2498 /*
2496 2499 * DHCHAP_Reply msg
2497 2500 */
2498 2501 /* ARGSUSED */
2499 2502 uint32_t
2500 2503 emlxs_issue_dhchap_reply(
2501 2504 emlxs_port_t *port,
2502 2505 NODELIST *ndlp,
2503 2506 int retry,
2504 2507 uint32_t *arg1, /* response */
2505 2508 uint8_t *dhval,
2506 2509 uint32_t dhval_len,
2507 2510 uint8_t *arg2, /* random number */
2508 2511 uint32_t arg2_len)
2509 2512 {
2510 2513 fc_packet_t *pkt;
2511 2514 uint32_t cmd_size;
2512 2515 uint32_t rsp_size;
2513 2516 uint16_t cmdsize = 0;
2514 2517 DHCHAP_REPLY_HDR *ap;
2515 2518 uint8_t *pCmd;
2516 2519 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
2517 2520
2518 2521 /* Header size */
2519 2522 cmdsize = sizeof (DHCHAP_REPLY_HDR);
2520 2523
2521 2524 /* Rsp value len size (4) + Response value size */
2522 2525 if (ndlp->nlp_DID == FABRIC_DID) {
2523 2526 if (node_dhc->hash_id == AUTH_MD5) {
2524 2527 cmdsize += 4 + MD5_LEN;
2525 2528 }
2526 2529 if (node_dhc->hash_id == AUTH_SHA1) {
2527 2530 cmdsize += 4 + SHA1_LEN;
2528 2531 }
2529 2532 } else {
2530 2533 if (node_dhc->nlp_auth_hashid == AUTH_MD5) {
2531 2534 cmdsize += 4 + MD5_LEN;
2532 2535 }
2533 2536 if (node_dhc->nlp_auth_hashid == AUTH_SHA1) {
2534 2537 cmdsize += 4 + SHA1_LEN;
2535 2538 }
2536 2539 }
2537 2540
2538 2541 /* DH value len size (4) + DH value size */
2539 2542 if (ndlp->nlp_DID == FABRIC_DID) {
2540 2543 switch (node_dhc->dhgp_id) {
2541 2544 case GROUP_NULL:
2542 2545
2543 2546 break;
2544 2547
2545 2548 case GROUP_1024:
2546 2549 case GROUP_1280:
2547 2550 case GROUP_1536:
2548 2551 case GROUP_2048:
2549 2552 default:
2550 2553 break;
2551 2554 }
2552 2555 }
2553 2556
2554 2557 cmdsize += 4 + dhval_len;
2555 2558
2556 2559 /* Challenge value len size (4) + Challenge value size */
2557 2560 if (node_dhc->auth_cfg.bidirectional == 0) {
2558 2561 cmdsize += 4;
2559 2562 } else {
2560 2563 if (ndlp->nlp_DID == FABRIC_DID) {
2561 2564 cmdsize += 4 + ((node_dhc->hash_id == AUTH_MD5) ?
2562 2565 MD5_LEN : SHA1_LEN);
2563 2566 } else {
2564 2567 cmdsize += 4 +
2565 2568 ((node_dhc->nlp_auth_hashid == AUTH_MD5) ? MD5_LEN :
2566 2569 SHA1_LEN);
2567 2570 }
2568 2571 }
2569 2572
2570 2573 cmd_size = cmdsize;
2571 2574 rsp_size = 4;
2572 2575
2573 2576 if ((pkt = emlxs_prep_els_fc_pkt(port, ndlp->nlp_DID, cmd_size,
2574 2577 rsp_size, 0, KM_NOSLEEP)) == NULL) {
2575 2578 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2576 2579 "emlxs_issue_dhchap_reply failed: did=0x%x size=%x,%x",
2577 2580 ndlp->nlp_DID, cmd_size, rsp_size);
2578 2581
2579 2582 return (1);
2580 2583 }
2581 2584 pCmd = (uint8_t *)pkt->pkt_cmd;
2582 2585
2583 2586 ap = (DHCHAP_REPLY_HDR *)pCmd;
2584 2587 ap->auth_els_code = ELS_CMD_AUTH_CODE;
2585 2588 ap->auth_els_flags = 0x0;
2586 2589 ap->auth_msg_code = DHCHAP_REPLY;
2587 2590 ap->proto_version = 0x01;
2588 2591 ap->msg_len = LE_SWAP32(cmdsize - sizeof (DHCHAP_REPLY_HDR));
2589 2592 ap->tran_id = LE_SWAP32(node_dhc->nlp_auth_tranid_rsp);
2590 2593
2591 2594 pCmd = (uint8_t *)(pCmd + sizeof (DHCHAP_REPLY_HDR));
2592 2595
2593 2596 if (ndlp->nlp_DID == FABRIC_DID) {
2594 2597 if (node_dhc->hash_id == AUTH_MD5) {
2595 2598 *(uint32_t *)pCmd = LE_SWAP32(MD5_LEN);
2596 2599 } else {
2597 2600 *(uint32_t *)pCmd = LE_SWAP32(SHA1_LEN);
2598 2601 }
2599 2602 } else {
2600 2603 if (node_dhc->nlp_auth_hashid == AUTH_MD5) {
2601 2604 *(uint32_t *)pCmd = LE_SWAP32(MD5_LEN);
2602 2605 } else {
2603 2606 *(uint32_t *)pCmd = LE_SWAP32(SHA1_LEN);
2604 2607 }
2605 2608 }
2606 2609
2607 2610 pCmd = (uint8_t *)(pCmd + 4);
2608 2611
2609 2612 if (ndlp->nlp_DID == FABRIC_DID) {
2610 2613 if (node_dhc->hash_id == AUTH_MD5) {
2611 2614 bcopy((void *)arg1, pCmd, MD5_LEN);
2612 2615 pCmd = (uint8_t *)(pCmd + MD5_LEN);
2613 2616 } else {
2614 2617 bcopy((void *)arg1, (void *)pCmd, SHA1_LEN);
2615 2618
2616 2619 pCmd = (uint8_t *)(pCmd + SHA1_LEN);
2617 2620 }
2618 2621 } else {
2619 2622 if (node_dhc->nlp_auth_hashid == AUTH_MD5) {
2620 2623 bcopy((void *)arg1, pCmd, MD5_LEN);
2621 2624 pCmd = (uint8_t *)(pCmd + MD5_LEN);
2622 2625 } else {
2623 2626 bcopy((void *)arg1, (void *)pCmd, SHA1_LEN);
2624 2627 pCmd = (uint8_t *)(pCmd + SHA1_LEN);
2625 2628 }
2626 2629 }
2627 2630
2628 2631 *(uint32_t *)pCmd = LE_SWAP32(dhval_len);
2629 2632
2630 2633 if (dhval_len != 0) {
2631 2634 pCmd = (uint8_t *)(pCmd + 4);
2632 2635
2633 2636 switch (node_dhc->dhgp_id) {
2634 2637 case GROUP_NULL:
2635 2638
2636 2639 break;
2637 2640
2638 2641 case GROUP_1024:
2639 2642 case GROUP_1280:
2640 2643 case GROUP_1536:
2641 2644 case GROUP_2048:
2642 2645 default:
2643 2646 break;
2644 2647 }
2645 2648 /* elx_bcopy((void *)dhval, (void *)pCmd, dhval_len); */
2646 2649 /*
2647 2650 * The new DH parameter (g^y mod p) is stored in
2648 2651 * node_dhc->pub_key
2649 2652 */
2650 2653 /* pubkey_len should be equal to dhval_len */
2651 2654
2652 2655 if (ndlp->nlp_DID == FABRIC_DID) {
2653 2656 bcopy((void *) node_dhc->pub_key, (void *)pCmd,
2654 2657 node_dhc->pubkey_len);
2655 2658 } else {
2656 2659 bcopy((void *) node_dhc->nlp_auth_misc.pub_key,
2657 2660 (void *)pCmd,
2658 2661 node_dhc->nlp_auth_misc.pubkey_len);
2659 2662 }
2660 2663 pCmd = (uint8_t *)(pCmd + dhval_len);
2661 2664 } else
2662 2665 pCmd = (uint8_t *)(pCmd + 4);
2663 2666
2664 2667 if (node_dhc->auth_cfg.bidirectional == 0) {
2665 2668 *(uint32_t *)pCmd = 0x0;
2666 2669 } else {
2667 2670 if (ndlp->nlp_DID == FABRIC_DID) {
2668 2671 if (node_dhc->hash_id == AUTH_MD5) {
2669 2672 *(uint32_t *)pCmd = LE_SWAP32(MD5_LEN);
2670 2673 pCmd = (uint8_t *)(pCmd + 4);
2671 2674 bcopy((void *)arg2, (void *)pCmd, arg2_len);
2672 2675 } else if (node_dhc->hash_id == AUTH_SHA1) {
2673 2676 *(uint32_t *)pCmd = LE_SWAP32(SHA1_LEN);
2674 2677 pCmd = (uint8_t *)(pCmd + 4);
2675 2678 /* store the challenge */
2676 2679 bcopy((void *)arg2, (void *)pCmd, arg2_len);
2677 2680 }
2678 2681 } else {
2679 2682 if (node_dhc->nlp_auth_hashid == AUTH_MD5) {
2680 2683 *(uint32_t *)pCmd = LE_SWAP32(MD5_LEN);
2681 2684 pCmd = (uint8_t *)(pCmd + 4);
2682 2685 bcopy((void *)arg2, (void *)pCmd, arg2_len);
2683 2686 } else if (node_dhc->nlp_auth_hashid == AUTH_SHA1) {
2684 2687 *(uint32_t *)pCmd = LE_SWAP32(SHA1_LEN);
2685 2688 pCmd = (uint8_t *)(pCmd + 4);
2686 2689 bcopy((void *)arg2, (void *)pCmd, arg2_len);
2687 2690 }
2688 2691 }
2689 2692 }
2690 2693
2691 2694 pkt->pkt_comp = emlxs_cmpl_dhchap_reply_issue;
2692 2695
2693 2696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2694 2697 "emlxs_issue_dhchap_reply: did=0x%x (%x,%x,%x,%x,%x,%x)",
2695 2698 ndlp->nlp_DID, dhval_len, arg2_len, cmdsize,
2696 2699 node_dhc->hash_id, node_dhc->nlp_auth_hashid,
2697 2700 LE_SWAP32(ap->tran_id));
2698 2701
2699 2702 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2700 2703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2701 2704 "emlxs_issue_dhchap_reply failed: Unable to send packet.");
2702 2705
2703 2706 emlxs_pkt_free(pkt);
2704 2707
2705 2708 return (1);
2706 2709 }
2707 2710 return (0);
2708 2711
2709 2712 } /* emlxs_issue_dhchap_reply */
2710 2713
2711 2714
2712 2715
2713 2716 /*
2714 2717 * ! emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next
2715 2718 *
2716 2719 * \pre \post \param phba \param ndlp \param arg \param evt \return
2717 2720 * uint32_t \b Description:
2718 2721 *
2719 2722 * This routine is invoked when the host received an unsolicted ELS AUTH MSG
2720 2723 * from an NxPort or FxPort which already replied (ACC)
2721 2724 * the ELS AUTH_Negotiate msg from the host. if msg is DHCHAP_Chellenge,
2722 2725 * based on the msg content (DHCHAP computation etc.,)
2723 2726 * the host send back ACC and 1. send back AUTH_Reject and set next state =
2724 2727 * NPR_NODE or 2. send back DHCHAP_Reply msg and set
2725 2728 * next state = DHCHAP_REPLY_ISSUE for bi-directional, the DHCHAP_Reply
2726 2729 * includes challenge from host. for uni-directional, no
2727 2730 * more challenge. if msg is AUTH_Reject or anything else, host send back
2728 2731 * ACC and set next state = NPR_NODE. And based on the
2729 2732 * reject code, host may need to retry negotiate with NULL DH only
2730 2733 *
2731 2734 * If the msg is AUTH_ELS cmd, cancel the nlp_authrsp_timeout timer immediately.
2732 2735 *
2733 2736 */
2734 2737 /* ARGSUSED */
2735 2738 static uint32_t
2736 2739 emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next(
2737 2740 emlxs_port_t *port,
2738 2741 /* CHANNEL * rp, */ void *arg1,
2739 2742 /* IOCBQ * iocbq, */ void *arg2,
2740 2743 /* MATCHMAP * mp, */ void *arg3,
2741 2744 /* NODELIST * ndlp */ void *arg4,
2742 2745 uint32_t evt)
2743 2746 {
2744 2747 emlxs_hba_t *hba = HBA;
2745 2748 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
2746 2749 IOCBQ *iocbq = (IOCBQ *)arg2;
2747 2750 MATCHMAP *mp = (MATCHMAP *)arg3;
2748 2751 NODELIST *ndlp = (NODELIST *)arg4;
2749 2752 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
2750 2753 uint8_t *bp;
2751 2754 uint32_t *lp;
2752 2755 DHCHAP_CHALL_NULL *ncval;
2753 2756 uint16_t namelen;
2754 2757 uint32_t dhvallen;
2755 2758 uint8_t *tmp;
2756 2759 uint8_t ReasonCode;
2757 2760 uint8_t ReasonCodeExplanation;
2758 2761
2759 2762 union challenge_val un_cval;
2760 2763
2761 2764 uint8_t *dhval = NULL;
2762 2765 uint8_t random_number[20]; /* for both SHA1 and MD5 */
2763 2766 uint32_t *arg5 = NULL; /* response */
2764 2767 uint32_t tran_id; /* Transaction Identifier */
2765 2768 uint32_t arg2len = 0; /* len of new challenge for bidir auth */
2766 2769
2767 2770 AUTH_RJT *rjt;
2768 2771
2769 2772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2770 2773 "emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next: did=0x%x",
2771 2774 ndlp->nlp_DID);
2772 2775
2773 2776 emlxs_dhc_state(port, ndlp, NODE_STATE_DHCHAP_REPLY_ISSUE, 0, 0);
2774 2777
2775 2778 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
2776 2779
2777 2780 bp = mp->virt;
2778 2781 lp = (uint32_t *)bp;
2779 2782
2780 2783 /*
2781 2784 * 1. we process the DHCHAP_Challenge 2. ACC it first 3. based on the
2782 2785 * result of 1 we DHCHAP_Reply or AUTH_Reject
2783 2786 */
2784 2787 ncval = (DHCHAP_CHALL_NULL *)((uint8_t *)lp);
2785 2788
2786 2789 if (ncval->msg_hdr.auth_els_code != ELS_CMD_AUTH_CODE) {
2787 2790 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2788 2791 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x",
2789 2792 ndlp->nlp_DID, ncval->msg_hdr.auth_els_code);
2790 2793
2791 2794 /* need to setup reason code/reason explanation code */
2792 2795 ReasonCode = AUTHRJT_FAILURE;
2793 2796 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
2794 2797 goto AUTH_Reject;
2795 2798 }
2796 2799 if (ncval->msg_hdr.auth_msg_code == AUTH_REJECT) {
2797 2800 rjt = (AUTH_RJT *)((uint8_t *)lp);
2798 2801 ReasonCode = rjt->ReasonCode;
2799 2802 ReasonCodeExplanation = rjt->ReasonCodeExplanation;
2800 2803
2801 2804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
2802 2805 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.%x,%x",
2803 2806 ndlp->nlp_DID, ReasonCode, ReasonCodeExplanation);
2804 2807
2805 2808 switch (ReasonCode) {
2806 2809 case AUTHRJT_LOGIC_ERR:
2807 2810 switch (ReasonCodeExplanation) {
2808 2811 case AUTHEXP_MECH_UNUSABLE:
2809 2812 case AUTHEXP_DHGROUP_UNUSABLE:
2810 2813 case AUTHEXP_HASHFUNC_UNUSABLE:
2811 2814 ReasonCode = AUTHRJT_LOGIC_ERR;
2812 2815 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
2813 2816 break;
2814 2817
2815 2818 case AUTHEXP_RESTART_AUTH:
2816 2819 /*
2817 2820 * Cancel the rsp timer if not cancelled yet.
2818 2821 * and restart auth tran now.
2819 2822 */
2820 2823 if (node_dhc->nlp_authrsp_tmo != 0) {
2821 2824 node_dhc->nlp_authrsp_tmo = 0;
2822 2825 node_dhc->nlp_authrsp_tmocnt = 0;
2823 2826 }
2824 2827 if (emlxs_dhc_auth_start(port, ndlp, NULL,
2825 2828 NULL) != 0) {
2826 2829 EMLXS_MSGF(EMLXS_CONTEXT,
2827 2830 &emlxs_fcsp_debug_msg,
2828 2831 "Reauth timeout. failed. 0x%x %x",
2829 2832 ndlp->nlp_DID, node_dhc->state);
2830 2833 }
2831 2834 return (node_dhc->state);
2832 2835
2833 2836 default:
2834 2837 ReasonCode = AUTHRJT_FAILURE;
2835 2838 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
2836 2839 break;
2837 2840 }
2838 2841 break;
2839 2842
2840 2843 case AUTHRJT_FAILURE:
2841 2844 default:
2842 2845 ReasonCode = AUTHRJT_FAILURE;
2843 2846 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
2844 2847 break;
2845 2848 }
2846 2849
2847 2850 goto AUTH_Reject;
2848 2851 }
2849 2852 if (ncval->msg_hdr.auth_msg_code != DHCHAP_CHALLENGE) {
2850 2853 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2851 2854 "emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.%x",
2852 2855 ndlp->nlp_DID, ncval->msg_hdr.auth_msg_code);
2853 2856
2854 2857 ReasonCode = AUTHRJT_FAILURE;
2855 2858 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
2856 2859 goto AUTH_Reject;
2857 2860 }
2858 2861 tran_id = ncval->msg_hdr.tran_id;
2859 2862
2860 2863 if (LE_SWAP32(tran_id) != node_dhc->nlp_auth_tranid_rsp) {
2861 2864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2862 2865 "rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x %x!=%x",
2863 2866 ndlp->nlp_DID, LE_SWAP32(tran_id),
2864 2867 node_dhc->nlp_auth_tranid_rsp);
2865 2868
2866 2869 ReasonCode = AUTHRJT_FAILURE;
2867 2870 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2868 2871 goto AUTH_Reject;
2869 2872 }
2870 2873 node_dhc->nlp_authrsp_tmo = 0;
2871 2874
2872 2875 namelen = ncval->msg_hdr.name_len;
2873 2876
2874 2877 if (namelen == AUTH_NAME_LEN) {
2875 2878 /*
2876 2879 * store another copy of wwn of fabric/or nport used in
2877 2880 * AUTH_ELS cmd
2878 2881 */
2879 2882 bcopy((void *)&ncval->msg_hdr.nodeName,
2880 2883 (void *)&node_dhc->nlp_auth_wwn, sizeof (NAME_TYPE));
2881 2884 }
2882 2885 /* Collect the challenge value */
2883 2886 tmp = (uint8_t *)((uint8_t *)lp + sizeof (DHCHAP_CHALL_NULL));
2884 2887
2885 2888 if (ncval->hash_id == AUTH_MD5) {
2886 2889 if (ncval->cval_len != LE_SWAP32(MD5_LEN)) {
2887 2890 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2888 2891 "rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x.%x!=%x",
2889 2892 ndlp->nlp_DID, ncval->cval_len, LE_SWAP32(MD5_LEN));
2890 2893
2891 2894 ReasonCode = AUTHRJT_FAILURE;
2892 2895 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2893 2896 goto AUTH_Reject;
2894 2897 }
2895 2898 bzero(un_cval.md5.val, sizeof (MD5_CVAL));
2896 2899 bcopy((void *)tmp, (void *)un_cval.md5.val,
2897 2900 sizeof (MD5_CVAL));
2898 2901 tmp += sizeof (MD5_CVAL);
2899 2902
2900 2903 arg2len = MD5_LEN;
2901 2904
2902 2905 } else if (ncval->hash_id == AUTH_SHA1) {
2903 2906 if (ncval->cval_len != LE_SWAP32(SHA1_LEN)) {
2904 2907 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2905 2908 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x!=%x",
2906 2909 ndlp->nlp_DID, ncval->cval_len, LE_SWAP32(MD5_LEN));
2907 2910
2908 2911 ReasonCode = AUTHRJT_FAILURE;
2909 2912 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2910 2913 goto AUTH_Reject;
2911 2914 }
2912 2915 bzero(un_cval.sha1.val, sizeof (SHA1_CVAL));
2913 2916 bcopy((void *)tmp, (void *)un_cval.sha1.val,
2914 2917 sizeof (SHA1_CVAL));
2915 2918 tmp += sizeof (SHA1_CVAL);
2916 2919
2917 2920 arg2len = SHA1_LEN;
2918 2921
2919 2922 } else {
2920 2923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2921 2924 "emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x",
2922 2925 ndlp->nlp_DID, ncval->hash_id);
2923 2926
2924 2927 ReasonCode = AUTHRJT_FAILURE;
2925 2928 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2926 2929 goto AUTH_Reject;
2927 2930 }
2928 2931
2929 2932 /*
2930 2933 * store hash_id for later usage : hash_id is set by responder in its
2931 2934 * dhchap_challenge
2932 2935 */
2933 2936 node_dhc->hash_id = ncval->hash_id;
2934 2937
2935 2938 /* always use this */
2936 2939 /* store another copy of the hash_id */
2937 2940 node_dhc->nlp_auth_hashid = ncval->hash_id;
2938 2941
2939 2942 /* store dhgp_id for later usage */
2940 2943 node_dhc->dhgp_id = ncval->dhgp_id;
2941 2944
2942 2945 /* store another copy of dhgp_id */
2943 2946 /* always use this */
2944 2947 node_dhc->nlp_auth_dhgpid = ncval->dhgp_id;
2945 2948
2946 2949 /*
2947 2950 * ndlp->nlp_auth_hashid, nlp_auth_dhgpid store the hashid and dhgpid
2948 2951 * when this very ndlp is the auth transaction responder (in other
2949 2952 * words, responder means that this ndlp is send the host the
2950 2953 * challenge. ndlp could be fffffe or another initiator or target
2951 2954 * nport.
2952 2955 */
2953 2956
2954 2957 dhvallen = *((uint32_t *)(tmp));
2955 2958
2956 2959 switch (ncval->dhgp_id) {
2957 2960 case GROUP_NULL:
2958 2961 /* null DHCHAP only */
2959 2962 if (LE_SWAP32(dhvallen) != 0) {
2960 2963 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2961 2964 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x %x",
2962 2965 ndlp->nlp_DID, ncval->dhgp_id, LE_SWAP32(dhvallen));
2963 2966
2964 2967 ReasonCode = AUTHRJT_FAILURE;
2965 2968 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2966 2969 goto AUTH_Reject;
2967 2970 }
2968 2971 break;
2969 2972
2970 2973 case GROUP_1024:
2971 2974 case GROUP_1280:
2972 2975 case GROUP_1536:
2973 2976 case GROUP_2048:
2974 2977 /* Collect the DH Value */
2975 2978 tmp += sizeof (uint32_t);
2976 2979
2977 2980 dhval = (uint8_t *)kmem_zalloc(LE_SWAP32(dhvallen),
2978 2981 KM_NOSLEEP);
2979 2982 if (dhval == NULL) {
2980 2983 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2981 2984 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x %x",
2982 2985 ndlp->nlp_DID, ncval->dhgp_id, dhval);
2983 2986
2984 2987 ReasonCode = AUTHRJT_LOGIC_ERR;
2985 2988 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
2986 2989 goto AUTH_Reject;
2987 2990 }
2988 2991 bcopy((void *)tmp, (void *)dhval, LE_SWAP32(dhvallen));
2989 2992 break;
2990 2993
2991 2994 default:
2992 2995 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
2993 2996 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x %x.",
2994 2997 ndlp->nlp_DID, ncval->dhgp_id);
2995 2998
2996 2999 ReasonCode = AUTHRJT_FAILURE;
2997 3000 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
2998 3001 goto AUTH_Reject;
2999 3002 }
3000 3003
3001 3004 /*
3002 3005 * Calculate the hash value, hash function, DH group, secret etc.
3003 3006 * could be stored in port_dhc.
3004 3007 */
3005 3008
3006 3009 /* arg5 has the response with NULL or Full DH group support */
3007 3010 arg5 = (uint32_t *)emlxs_hash_rsp(port, port_dhc,
3008 3011 ndlp, tran_id, un_cval, dhval, LE_SWAP32(dhvallen));
3009 3012
3010 3013 /* Or should check ndlp->auth_cfg..... */
3011 3014 if (node_dhc->auth_cfg.bidirectional == 1) {
3012 3015 /* get arg2 here */
3013 3016 /*
3014 3017 * arg2 is the new challenge C2 from initiator if bi-dir auth
3015 3018 * is supported
3016 3019 */
3017 3020 bzero(&random_number, sizeof (random_number));
3018 3021
3019 3022 if (hba->rdn_flag == 1) {
3020 3023 emlxs_get_random_bytes(ndlp, random_number, 20);
3021 3024 } else {
3022 3025 (void) random_get_pseudo_bytes(random_number, arg2len);
3023 3026 }
3024 3027
3025 3028 /* cache it for later verification usage */
3026 3029 if (ndlp->nlp_DID == FABRIC_DID) {
3027 3030 bcopy((void *)&random_number[0],
3028 3031 (void *)&node_dhc->bi_cval[0], arg2len);
3029 3032 node_dhc->bi_cval_len = arg2len;
3030 3033
3031 3034 /* save another copy in our partner's ndlp */
3032 3035 bcopy((void *)&random_number[0],
3033 3036 (void *)&node_dhc->nlp_auth_misc.bi_cval[0],
3034 3037 arg2len);
3035 3038 node_dhc->nlp_auth_misc.bi_cval_len = arg2len;
3036 3039 } else {
3037 3040 bcopy((void *)&random_number[0],
3038 3041 (void *)&node_dhc->nlp_auth_misc.bi_cval[0],
3039 3042 arg2len);
3040 3043 node_dhc->nlp_auth_misc.bi_cval_len = arg2len;
3041 3044 }
3042 3045 }
3043 3046 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3044 3047 "rcv_auth_msg_auth_negotiate_cmpl_wait4next:0x%x(%x,%x,%x,%x,%x)",
3045 3048 ndlp->nlp_DID, node_dhc->nlp_auth_tranid_rsp,
3046 3049 node_dhc->nlp_auth_tranid_ini,
3047 3050 ncval->hash_id, ncval->dhgp_id, dhvallen);
3048 3051
3049 3052 /* Issue ELS DHCHAP_Reply */
3050 3053 /*
3051 3054 * arg1 has the response, arg2 has the new challenge if needed (g^y
3052 3055 * mod p) is the pubkey: all are ready and to go
3053 3056 */
3054 3057
3055 3058 /* return 0 success, otherwise failure */
3056 3059 if (emlxs_issue_dhchap_reply(port, ndlp, 0, arg5, dhval,
3057 3060 LE_SWAP32(dhvallen),
3058 3061 random_number, arg2len)) {
3059 3062 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3060 3063 "rcv_auth_msg_auth_negotiate_cmpl_wait4next: 0x%x.failed.",
3061 3064 ndlp->nlp_DID);
3062 3065
3063 3066 kmem_free(dhval, LE_SWAP32(dhvallen));
3064 3067 ReasonCode = AUTHRJT_LOGIC_ERR;
3065 3068 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
3066 3069 goto AUTH_Reject;
3067 3070 }
3068 3071 return (node_dhc->state);
3069 3072
3070 3073 AUTH_Reject:
3071 3074
3072 3075 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED, ReasonCode,
3073 3076 ReasonCodeExplanation);
3074 3077 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
3075 3078 ReasonCodeExplanation);
3076 3079 emlxs_dhc_auth_complete(port, ndlp, 1);
3077 3080
3078 3081 return (node_dhc->state);
3079 3082
3080 3083 } /* emlxs_rcv_auth_msg_auth_negotiate_cmpl_wait4next */
3081 3084
3082 3085
3083 3086 /*
3084 3087 * This routine should be set to emlxs_disc_neverdev
3085 3088 *
3086 3089 */
3087 3090 /* ARGSUSED */
3088 3091 static uint32_t
3089 3092 emlxs_cmpl_auth_msg_auth_negotiate_cmpl_wait4next(
3090 3093 emlxs_port_t *port,
3091 3094 /* CHANNEL * rp, */ void *arg1,
3092 3095 /* IOCBQ * iocbq, */ void *arg2,
3093 3096 /* MATCHMAP * mp, */ void *arg3,
3094 3097 /* NODELIST * ndlp */ void *arg4,
3095 3098 uint32_t evt)
3096 3099 {
3097 3100 NODELIST *ndlp = (NODELIST *)arg4;
3098 3101
3099 3102 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3100 3103 "cmpl_auth_msg_auth_negotiate_cmpl_wait4next.0x%x. Not iplted.",
3101 3104 ndlp->nlp_DID);
3102 3105
3103 3106 return (0);
3104 3107 } /* emlxs_cmpl_auth_msg_auth_negotiate_cmpl_wait4next() */
3105 3108
3106 3109
3107 3110 /*
3108 3111 * ! emlxs_rcv_auth_msg_dhchap_reply_issue
3109 3112 *
3110 3113 * This routine is invoked when the host received an unsolicited ELS AUTH
3111 3114 * msg from an NxPort or FxPort into which the host has
3112 3115 * sent an ELS DHCHAP_Reply msg. since the host is the initiator and the
3113 3116 * AUTH transaction is in progress between host and the
3114 3117 * NxPort or FxPort, as a result, the host will send back ACC and AUTH_Reject
3115 3118 * and set the next state = NPR_NODE.
3116 3119 *
3117 3120 */
3118 3121 /* ARGSUSED */
3119 3122 static uint32_t
3120 3123 emlxs_rcv_auth_msg_dhchap_reply_issue(
3121 3124 emlxs_port_t *port,
3122 3125 /* CHANNEL * rp, */ void *arg1,
3123 3126 /* IOCBQ * iocbq, */ void *arg2,
3124 3127 /* MATCHMAP * mp, */ void *arg3,
3125 3128 /* NODELIST * ndlp */ void *arg4,
3126 3129 uint32_t evt)
3127 3130 {
3128 3131 NODELIST *ndlp = (NODELIST *)arg4;
3129 3132
3130 3133 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3131 3134 "rcv_auth_msg_dhchap_reply_issue called. 0x%x. Not implemented.",
3132 3135 ndlp->nlp_DID);
3133 3136
3134 3137 return (0);
3135 3138
3136 3139 } /* emlxs_rcv_auth_msg_dhchap_reply_issue */
3137 3140
3138 3141
3139 3142
3140 3143 /*
3141 3144 * ! emlxs_cmpl_auth_msg_dhchap_reply_issue
3142 3145 *
3143 3146 * This routine is invoked when
3144 3147 * the host received a solicited ACC/RJT from ELS command from an NxPort
3145 3148 * or FxPort that already received the ELS DHCHAP_Reply
3146 3149 * msg from the host. in case of ACC, next state = DHCHAP_REPLY_CMPL_WAIT4NEXT
3147 3150 * in case of RJT, next state = NPR_NODE
3148 3151 */
3149 3152 /* ARGSUSED */
3150 3153 static uint32_t
3151 3154 emlxs_cmpl_auth_msg_dhchap_reply_issue(
3152 3155 emlxs_port_t *port,
3153 3156 /* CHANNEL * rp, */ void *arg1,
3154 3157 /* IOCBQ * iocbq, */ void *arg2,
3155 3158 /* MATCHMAP * mp, */ void *arg3,
3156 3159 /* NODELIST * ndlp */ void *arg4,
3157 3160 uint32_t evt)
3158 3161 {
3159 3162 NODELIST *ndlp = (NODELIST *) arg4;
3160 3163 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
3161 3164
3162 3165 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3163 3166 "emlxs_cmpl_auth_msg_dhchap_reply_issue: did=0x%x",
3164 3167 ndlp->nlp_DID);
3165 3168
3166 3169 /* start the emlxs_dhc_authrsp_timeout timer now */
3167 3170 if (node_dhc->nlp_authrsp_tmo == 0) {
3168 3171 node_dhc->nlp_authrsp_tmo = DRV_TIME +
3169 3172 node_dhc->auth_cfg.authentication_timeout;
3170 3173 }
3171 3174 /*
3172 3175 * The next state should be
3173 3176 * emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next
3174 3177 */
3175 3178 emlxs_dhc_state(port, ndlp,
3176 3179 NODE_STATE_DHCHAP_REPLY_CMPL_WAIT4NEXT, 0, 0);
3177 3180
3178 3181 return (node_dhc->state);
3179 3182
3180 3183 } /* emlxs_cmpl_auth_msg_dhchap_reply_issue */
3181 3184
3182 3185
3183 3186
3184 3187 /*
3185 3188 * ! emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next
3186 3189 *
3187 3190 * \pre \post \param phba \param ndlp \param arg \param evt \return
3188 3191 * uint32_t \b Description: This rountine is invoked
3189 3192 * when the host received an unsolicited ELS AUTH Msg from the NxPort or
3190 3193 * FxPort that already sent ACC back to the host after
3191 3194 * receipt of DHCHAP_Reply msg. In normal case, this unsolicited msg could
3192 3195 * be DHCHAP_Success msg.
3193 3196 *
3194 3197 * if msg is ELS DHCHAP_Success, based on the payload, host send back ACC and 1.
3195 3198 * for uni-directional, and set next state =
3196 3199 * REG_LOGIN. 2. for bi-directional, and host do some computations
3197 3200 * (hash etc) and send back either DHCHAP_Success Msg and set
3198 3201 * next state = DHCHAP_SUCCESS_ISSUE_WAIT4NEXT or AUTH_Reject and set next
3199 3202 * state = NPR_NODE. if msg is ELS AUTH_Reject, then
3200 3203 * send back ACC and set next state = NPR_NODE if msg is anything else, then
3201 3204 * RJT and set next state = NPR_NODE
3202 3205 */
3203 3206 /* ARGSUSED */
3204 3207 static uint32_t
3205 3208 emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next(
3206 3209 emlxs_port_t *port,
3207 3210 /* CHANNEL * rp, */ void *arg1,
3208 3211 /* IOCBQ * iocbq, */ void *arg2,
3209 3212 /* MATCHMAP * mp, */ void *arg3,
3210 3213 /* NODELIST * ndlp */ void *arg4,
3211 3214 uint32_t evt)
3212 3215 {
3213 3216 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
3214 3217 IOCBQ *iocbq = (IOCBQ *)arg2;
3215 3218 MATCHMAP *mp = (MATCHMAP *)arg3;
3216 3219 NODELIST *ndlp = (NODELIST *)arg4;
3217 3220 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
3218 3221 uint8_t *bp;
3219 3222 uint32_t *lp;
3220 3223 DHCHAP_SUCCESS_HDR *dh_success;
3221 3224 uint8_t *tmp;
3222 3225 uint8_t rsp_size;
3223 3226 AUTH_RJT *auth_rjt;
3224 3227 uint32_t tran_id;
3225 3228 uint32_t *hash_val;
3226 3229 union challenge_val un_cval;
3227 3230 uint8_t ReasonCode;
3228 3231 uint8_t ReasonCodeExplanation;
3229 3232 char info[64];
3230 3233
3231 3234 bp = mp->virt;
3232 3235 lp = (uint32_t *)bp;
3233 3236
3234 3237 /*
3235 3238 * 1. we process the DHCHAP_Success or AUTH_Reject 2. ACC it first 3.
3236 3239 * based on the result of 1 we goto the next stage SCR etc.
3237 3240 */
3238 3241
3239 3242 /* sp = (SERV_PARM *)((uint8_t *)lp + sizeof(uint32_t)); */
3240 3243 dh_success = (DHCHAP_SUCCESS_HDR *)((uint8_t *)lp);
3241 3244
3242 3245 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3243 3246 "rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x 0x%x 0x%x",
3244 3247 ndlp->nlp_DID, dh_success->auth_els_code,
3245 3248 dh_success->auth_msg_code);
3246 3249
3247 3250 node_dhc->nlp_authrsp_tmo = 0;
3248 3251
3249 3252 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
3250 3253
3251 3254 if (dh_success->auth_msg_code == AUTH_REJECT) {
3252 3255 /* ACC it and retry etc. */
3253 3256 auth_rjt = (AUTH_RJT *) dh_success;
3254 3257 ReasonCode = auth_rjt->ReasonCode;
3255 3258 ReasonCodeExplanation = auth_rjt->ReasonCodeExplanation;
3256 3259
3257 3260 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3258 3261 "emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x.(%x,%x)",
3259 3262 ndlp->nlp_DID, ReasonCode, ReasonCodeExplanation);
3260 3263
3261 3264 switch (ReasonCode) {
3262 3265 case AUTHRJT_LOGIC_ERR:
3263 3266 switch (ReasonCodeExplanation) {
3264 3267 case AUTHEXP_MECH_UNUSABLE:
3265 3268 case AUTHEXP_DHGROUP_UNUSABLE:
3266 3269 case AUTHEXP_HASHFUNC_UNUSABLE:
3267 3270 ReasonCode = AUTHRJT_LOGIC_ERR;
3268 3271 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
3269 3272 break;
3270 3273
3271 3274 case AUTHEXP_RESTART_AUTH:
3272 3275 /*
3273 3276 * Cancel the rsp timer if not cancelled yet.
3274 3277 * and restart auth tran now.
3275 3278 */
3276 3279 if (node_dhc->nlp_authrsp_tmo != 0) {
3277 3280 node_dhc->nlp_authrsp_tmo = 0;
3278 3281 node_dhc->nlp_authrsp_tmocnt = 0;
3279 3282 }
3280 3283 if (emlxs_dhc_auth_start(port, ndlp,
3281 3284 NULL, NULL) != 0) {
3282 3285 EMLXS_MSGF(EMLXS_CONTEXT,
3283 3286 &emlxs_fcsp_debug_msg,
3284 3287 "Reauth timeout.failed. 0x%x %x",
3285 3288 ndlp->nlp_DID, node_dhc->state);
3286 3289 }
3287 3290 return (node_dhc->state);
3288 3291
3289 3292 default:
3290 3293 ReasonCode = AUTHRJT_FAILURE;
3291 3294 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3292 3295 break;
3293 3296 }
3294 3297 break;
3295 3298
3296 3299 case AUTHRJT_FAILURE:
3297 3300 default:
3298 3301 ReasonCode = AUTHRJT_FAILURE;
3299 3302 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3300 3303 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
3301 3304 ReasonCode, ReasonCodeExplanation);
3302 3305 goto out;
3303 3306 }
3304 3307
3305 3308 goto AUTH_Reject;
3306 3309 }
3307 3310 if (dh_success->auth_msg_code == DHCHAP_SUCCESS) {
3308 3311
3309 3312 /* Verify the tran_id */
3310 3313 tran_id = dh_success->tran_id;
3311 3314
3312 3315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3313 3316 "rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x 0x%x 0x%x 0x%x",
3314 3317 ndlp->nlp_DID, LE_SWAP32(tran_id),
3315 3318 node_dhc->nlp_auth_tranid_rsp,
3316 3319 node_dhc->nlp_auth_tranid_ini);
3317 3320
3318 3321 if (LE_SWAP32(tran_id) != node_dhc->nlp_auth_tranid_rsp) {
3319 3322 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3320 3323 "rcv_auth_msg_dhchap_reply_cmpl_wait4next:0x%x %x!=%x",
3321 3324 ndlp->nlp_DID, LE_SWAP32(tran_id),
3322 3325 node_dhc->nlp_auth_tranid_rsp);
3323 3326
3324 3327 ReasonCode = AUTHRJT_FAILURE;
3325 3328 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
3326 3329 goto AUTH_Reject;
3327 3330 }
3328 3331 if (node_dhc->auth_cfg.bidirectional == 0) {
3329 3332 node_dhc->flag |=
3330 3333 (NLP_REMOTE_AUTH | NLP_SET_REAUTH_TIME);
3331 3334
3332 3335 emlxs_dhc_state(port, ndlp,
3333 3336 NODE_STATE_AUTH_SUCCESS, 0, 0);
3334 3337 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_20,
3335 3338 "Host-initiated-unidir-auth-success");
3336 3339 emlxs_dhc_auth_complete(port, ndlp, 0);
3337 3340 } else {
3338 3341 /* bidir auth needed */
3339 3342 /* if (LE_SWAP32(dh_success->msg_len) > 4) { */
3340 3343
3341 3344 tmp = (uint8_t *)((uint8_t *)lp);
3342 3345 tmp += 8;
3343 3346 tran_id = *(uint32_t *)tmp;
3344 3347 tmp += 4;
3345 3348 rsp_size = *(uint32_t *)tmp;
3346 3349 tmp += 4;
3347 3350
3348 3351 /* tmp has the response from responder */
3349 3352
3350 3353 /*
3351 3354 * node_dhc->bi_cval has the bidir challenge value
3352 3355 * from initiator
3353 3356 */
3354 3357
3355 3358 if (LE_SWAP32(rsp_size) == 16) {
3356 3359 bzero(un_cval.md5.val, LE_SWAP32(rsp_size));
3357 3360 if (ndlp->nlp_DID == FABRIC_DID)
3358 3361 bcopy((void *)node_dhc->bi_cval,
3359 3362 (void *)un_cval.md5.val,
3360 3363 LE_SWAP32(rsp_size));
3361 3364 else
3362 3365 bcopy(
3363 3366 (void *)node_dhc->nlp_auth_misc.bi_cval,
3364 3367 (void *)un_cval.md5.val,
3365 3368 LE_SWAP32(rsp_size));
3366 3369
3367 3370 } else if (LE_SWAP32(rsp_size) == 20) {
3368 3371
3369 3372 bzero(un_cval.sha1.val, LE_SWAP32(rsp_size));
3370 3373 if (ndlp->nlp_DID == FABRIC_DID)
3371 3374 bcopy((void *)node_dhc->bi_cval,
3372 3375 (void *)un_cval.sha1.val,
3373 3376 LE_SWAP32(rsp_size));
3374 3377 else
3375 3378 bcopy(
3376 3379 (void *)node_dhc->nlp_auth_misc.bi_cval,
3377 3380 (void *)un_cval.sha1.val,
3378 3381 LE_SWAP32(rsp_size));
3379 3382 }
3380 3383 /* verify the response */
3381 3384 /* NULL DHCHAP works for now */
3382 3385 /* for DH group as well */
3383 3386
3384 3387 /*
3385 3388 * Cai2 = H (C2 || ((g^x mod p)^y mod p) ) = H (C2 ||
3386 3389 * (g^xy mod p) )
3387 3390 *
3388 3391 * R = H (Ti || Km || Cai2) R ?= R2
3389 3392 */
3390 3393 hash_val = emlxs_hash_vrf(port, port_dhc, ndlp,
3391 3394 tran_id, un_cval);
3392 3395
3393 3396 if (bcmp((void *)tmp, (void *)hash_val,
3394 3397 LE_SWAP32(rsp_size))) {
3395 3398 if (hash_val != NULL) {
3396 3399 /* not identical */
3397 3400 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3398 3401 "emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next: 0x%x.failed. %x",
3399 3402 ndlp->nlp_DID, *(uint32_t *)hash_val);
3400 3403 }
3401 3404 ReasonCode = AUTHRJT_FAILURE;
3402 3405 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3403 3406 goto AUTH_Reject;
3404 3407 }
3405 3408 emlxs_dhc_state(port, ndlp,
3406 3409 NODE_STATE_DHCHAP_SUCCESS_ISSUE_WAIT4NEXT, 0, 0);
3407 3410
3408 3411 /* send out DHCHAP_SUCCESS */
3409 3412 (void) emlxs_issue_dhchap_success(port, ndlp, 0, 0);
3410 3413 }
3411 3414 }
3412 3415 return (node_dhc->state);
3413 3416
3414 3417 AUTH_Reject:
3415 3418
3416 3419 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
3417 3420 ReasonCode, ReasonCodeExplanation);
3418 3421 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
3419 3422 ReasonCodeExplanation);
3420 3423 emlxs_dhc_auth_complete(port, ndlp, 1);
3421 3424
3422 3425 return (node_dhc->state);
3423 3426 out:
3424 3427 (void) sprintf(info,
3425 3428 "Auth Failed: ReasonCode=0x%x, ReasonCodeExplanation=0x%x",
3426 3429 ReasonCode, ReasonCodeExplanation);
3427 3430
3428 3431 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_20, info);
3429 3432 emlxs_dhc_auth_complete(port, ndlp, 1);
3430 3433
3431 3434 return (node_dhc->state);
3432 3435
3433 3436 } /* emlxs_rcv_auth_msg_dhchap_reply_cmpl_wait4next */
3434 3437
3435 3438
3436 3439
3437 3440 /*
3438 3441 * This routine should be set to emlxs_disc_neverdev as it shouldnot happen.
3439 3442 *
3440 3443 */
3441 3444 /* ARGSUSED */
3442 3445 static uint32_t
3443 3446 emlxs_cmpl_auth_msg_dhchap_reply_cmpl_wait4next(
3444 3447 emlxs_port_t *port,
3445 3448 /* CHANNEL * rp, */ void *arg1,
3446 3449 /* IOCBQ * iocbq, */ void *arg2,
3447 3450 /* MATCHMAP * mp, */ void *arg3,
3448 3451 /* NODELIST * ndlp */ void *arg4,
3449 3452 uint32_t evt)
3450 3453 {
3451 3454 NODELIST *ndlp = (NODELIST *)arg4;
3452 3455
3453 3456 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3454 3457 "cmpl_auth_msg_dhchap_reply_cmpl_wait4next. 0x%x.Not ipleted.",
3455 3458 ndlp->nlp_DID);
3456 3459
3457 3460 return (0);
3458 3461
3459 3462 } /* emlxs_cmpl_auth_msg_dhchap_reply_cmpl_wait4next */
3460 3463
3461 3464
3462 3465 /*
3463 3466 * emlxs_rcv_auth_msg_dhchap_success_issue_wait4next
3464 3467 *
3465 3468 * This routine is supported
3466 3469 * for HBA in either auth initiator mode or responder mode.
3467 3470 *
3468 3471 * This routine is invoked when the host as the auth responder received
3469 3472 * an unsolicited ELS AUTH msg from the NxPort as the auth
3470 3473 * initiator that already received the ELS DHCHAP_Success.
3471 3474 *
3472 3475 * If the host is the auth initiator and since the AUTH transction is
3473 3476 * already in progress, therefore, any auth els msg should not
3474 3477 * happen and if happened, RJT and move to NPR_NODE.
3475 3478 *
3476 3479 * If the host is the auth reponder, this unsolicited els auth msg should
3477 3480 * be DHCHAP_Success for this bi-directional auth
3478 3481 * transaction. In which case, the host should send ACC back and move state
3479 3482 * to REG_LOGIN. If this unsolicited els auth msg is
3480 3483 * DHCHAP_Reject, which could mean that the auth failed, then host should
3481 3484 * send back ACC and set the next state to NPR_NODE.
3482 3485 *
3483 3486 */
3484 3487 /* ARGSUSED */
3485 3488 static uint32_t
3486 3489 emlxs_rcv_auth_msg_dhchap_success_issue_wait4next(
3487 3490 emlxs_port_t *port,
3488 3491 /* CHANNEL * rp, */ void *arg1,
3489 3492 /* IOCBQ * iocbq, */ void *arg2,
3490 3493 /* MATCHMAP * mp, */ void *arg3,
3491 3494 /* NODELIST * ndlp */ void *arg4,
3492 3495 uint32_t evt)
3493 3496 {
3494 3497 NODELIST *ndlp = (NODELIST *) arg4;
3495 3498
3496 3499 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3497 3500 "rcv_auth_msg_dhchap_success_issue_wait4next. 0x%x. Not iplted.",
3498 3501 ndlp->nlp_DID);
3499 3502
3500 3503 return (0);
3501 3504
3502 3505 } /* emlxs_rcv_auth_msg_dhchap_success_issue_wait4next */
3503 3506
3504 3507
3505 3508
3506 3509 /*
3507 3510 * ! emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next
3508 3511 *
3509 3512 * This routine is invoked when
3510 3513 * the host as the auth initiator received an solicited ACC/RJT from the
3511 3514 * NxPort or FxPort that already received DHCHAP_Success
3512 3515 * Msg the host sent before. in case of ACC, set next state = REG_LOGIN.
3513 3516 * in case of RJT, set next state = NPR_NODE.
3514 3517 *
3515 3518 */
3516 3519 /* ARGSUSED */
3517 3520 static uint32_t
3518 3521 emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next(
3519 3522 emlxs_port_t *port,
3520 3523 /* CHANNEL * rp, */ void *arg1,
3521 3524 /* IOCBQ * iocbq, */ void *arg2,
3522 3525 /* MATCHMAP * mp, */ void *arg3,
3523 3526 /* NODELIST * ndlp */ void *arg4,
3524 3527 uint32_t evt)
3525 3528 {
3526 3529 NODELIST *ndlp = (NODELIST *)arg4;
3527 3530 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
3528 3531
3529 3532 /*
3530 3533 * Either host is the initiator and auth or (reauth bi-direct) is
3531 3534 * done, so start host reauth heartbeat timer now if host side reauth
3532 3535 * heart beat never get started. Or host is the responder and the
3533 3536 * other entity is done with its reauth heart beat with
3534 3537 * uni-directional auth. Anyway we start host side reauth heart beat
3535 3538 * timer now.
3536 3539 */
3537 3540
3538 3541 node_dhc->flag &= ~NLP_REMOTE_AUTH;
3539 3542 node_dhc->flag |= NLP_SET_REAUTH_TIME;
3540 3543
3541 3544 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_SUCCESS, 0, 0);
3542 3545 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_25,
3543 3546 "Host-initiated-bidir-auth-success");
3544 3547 emlxs_dhc_auth_complete(port, ndlp, 0);
3545 3548
3546 3549 return (node_dhc->state);
3547 3550
3548 3551 } /* emlxs_cmpl_auth_msg_dhchap_success_issue_wait4next */
3549 3552
3550 3553
3551 3554 /*
3552 3555 * ! emlxs_cmpl_auth_msg_auth_negotiate_rcv
3553 3556 *
3554 3557 * This routine is invoked when
3555 3558 * the host received the solicited ACC/RJT ELS cmd from an FxPort or an
3556 3559 * NxPort that has received the ELS DHCHAP_Challenge.
3557 3560 * The host is the auth responder and the auth transaction is still in
3558 3561 * progress.
3559 3562 *
3560 3563 */
3561 3564 /* ARGSUSED */
3562 3565 static uint32_t
3563 3566 emlxs_cmpl_auth_msg_auth_negotiate_rcv(
3564 3567 emlxs_port_t *port,
3565 3568 /* CHANNEL * rp, */ void *arg1,
3566 3569 /* IOCBQ * iocbq, */ void *arg2,
3567 3570 /* MATCHMAP * mp, */ void *arg3,
3568 3571 /* NODELIST * ndlp */ void *arg4,
3569 3572 uint32_t evt)
3570 3573 {
3571 3574 NODELIST *ndlp = (NODELIST *)arg4;
3572 3575
3573 3576 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3574 3577 "cmpl_auth_msg_auth_negotiate_rcv called. 0x%x. Not implemented.",
3575 3578 ndlp->nlp_DID);
3576 3579
3577 3580 return (0);
3578 3581
3579 3582 } /* emlxs_cmpl_auth_msg_auth_negotiate_rcv */
3580 3583
3581 3584
3582 3585
3583 3586 /*
3584 3587 * ! emlxs_rcv_auth_msg_dhchap_challenge_issue
3585 3588 *
3586 3589 * \pre \post \param phba \param ndlp \param arg \param evt \return
3587 3590 * uint32_t \b Description: This routine should be
3588 3591 * emlxs_disc_neverdev. The host is the auth responder and the auth
3589 3592 * transaction is still in progress, any unsolicited els auth
3590 3593 * msg is unexpected and should not happen in normal case.
3591 3594 *
3592 3595 * If DHCHAP_Reject, ACC and next state = NPR_NODE. anything else, RJT and
3593 3596 * next state = NPR_NODE.
3594 3597 */
3595 3598 /* ARGSUSED */
3596 3599 static uint32_t
3597 3600 emlxs_rcv_auth_msg_dhchap_challenge_issue(
3598 3601 emlxs_port_t *port,
3599 3602 /* CHANNEL * rp, */ void *arg1,
3600 3603 /* IOCBQ * iocbq, */ void *arg2,
3601 3604 /* MATCHMAP * mp, */ void *arg3,
3602 3605 /* NODELIST * ndlp */ void *arg4,
3603 3606 uint32_t evt)
3604 3607 {
3605 3608 NODELIST *ndlp = (NODELIST *)arg4;
3606 3609
3607 3610 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3608 3611 "rcv_auth_msg_dhchap_challenge_issue called. 0x%x. Not iplted.",
3609 3612 ndlp->nlp_DID);
3610 3613
3611 3614 return (0);
3612 3615
3613 3616 } /* emlxs_rcv_auth_msg_dhchap_challenge_issue */
3614 3617
3615 3618
3616 3619
3617 3620 /*
3618 3621 * ! emlxs_cmpl_auth_msg_dhchap_challenge_issue
3619 3622 *
3620 3623 * \pre \post \param phba \param ndlp \param arg \param evt \return
3621 3624 * uint32_t \b Description: This routine is invoked when
3622 3625 * the host as the responder received the solicited response (ACC or RJT)
3623 3626 * from initiator to the DHCHAP_Challenge msg sent from
3624 3627 * host. In case of ACC, the next state = DHCHAP_CHALLENGE_CMPL_WAIT4NEXT
3625 3628 * In case of RJT, the next state = NPR_NODE.
3626 3629 *
3627 3630 */
3628 3631 /* ARGSUSED */
3629 3632 static uint32_t
3630 3633 emlxs_cmpl_auth_msg_dhchap_challenge_issue(
3631 3634 emlxs_port_t *port,
3632 3635 /* CHANNEL * rp, */ void *arg1,
3633 3636 /* IOCBQ * iocbq, */ void *arg2,
3634 3637 /* MATCHMAP * mp, */ void *arg3,
3635 3638 /* NODELIST * ndlp */ void *arg4,
3636 3639 uint32_t evt)
3637 3640 {
3638 3641 NODELIST *ndlp = (NODELIST *)arg4;
3639 3642 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
3640 3643
3641 3644 /*
3642 3645 * The next state should be
3643 3646 * emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next
3644 3647 */
3645 3648 emlxs_dhc_state(port, ndlp,
3646 3649 NODE_STATE_DHCHAP_CHALLENGE_CMPL_WAIT4NEXT, 0, 0);
3647 3650
3648 3651 /* Start the fc_authrsp_timeout timer */
3649 3652 if (node_dhc->nlp_authrsp_tmo == 0) {
3650 3653 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3651 3654 "cmpl_auth_msg_dhchap_challenge_issue: Starting authrsp timer.");
3652 3655
3653 3656 node_dhc->nlp_authrsp_tmo = DRV_TIME +
3654 3657 node_dhc->auth_cfg.authentication_timeout;
3655 3658 }
3656 3659 return (node_dhc->state);
3657 3660
3658 3661 } /* emlxs_cmpl_auth_msg_dhchap_challenge_issue */
3659 3662
3660 3663
3661 3664 /*
3662 3665 * ! emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next
3663 3666 *
3664 3667 * \pre \post \param phba \param ndlp \param arg \param evt \return
3665 3668 * uint32_t \b Description: This routine is invoked when
3666 3669 * the host as the auth responder received an unsolicited auth msg from the
3667 3670 * FxPort or NxPort that already sent ACC to the DHCH_
3668 3671 * Challenge it received. In normal case this unsolicited auth msg should
3669 3672 * be DHCHAP_Reply msg from the initiator.
3670 3673 *
3671 3674 * For DHCHAP_Reply msg, the host send back ACC and then do verification
3672 3675 * (hash?) and send back DHCHAP_Success and next state as
3673 3676 * DHCHAP_SUCCESS_ISSUE or DHCHAP_Reject and next state as NPR_NODE based on
3674 3677 * the verification result.
3675 3678 *
3676 3679 * For bi-directional auth transaction, Reply msg should have the new
3677 3680 * challenge value from the initiator. thus the Success msg
3678 3681 * sent out should have the corresponding Reply from the responder.
3679 3682 *
3680 3683 * For uni-directional, Reply msg received does not contains the new
3681 3684 * challenge and therefore the Success msg does not include the
3682 3685 * Reply msg.
3683 3686 *
3684 3687 * For DHCHAP_Reject, send ACC and moved to the next state NPR_NODE. For
3685 3688 * anything else, send RJT and moved to NPR_NODE.
3686 3689 *
3687 3690 */
3688 3691 /* ARGSUSED */
3689 3692 static uint32_t
3690 3693 emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next(
3691 3694 emlxs_port_t *port,
3692 3695 /* CHANNEL * rp, */ void *arg1,
3693 3696 /* IOCBQ * iocbq, */ void *arg2,
3694 3697 /* MATCHMAP * mp, */ void *arg3,
3695 3698 /* NODELIST * ndlp */ void *arg4,
3696 3699 uint32_t evt)
3697 3700 {
3698 3701 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
3699 3702 IOCBQ *iocbq = (IOCBQ *)arg2;
3700 3703 MATCHMAP *mp = (MATCHMAP *)arg3;
3701 3704 NODELIST *ndlp = (NODELIST *)arg4;
3702 3705 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
3703 3706 uint8_t *bp;
3704 3707 uint32_t *lp;
3705 3708 DHCHAP_REPLY_HDR *dh_reply;
3706 3709 uint8_t *tmp;
3707 3710 uint32_t rsp_len;
3708 3711 uint8_t rsp[20]; /* should cover SHA-1 and MD5's rsp */
3709 3712 uint32_t dhval_len;
3710 3713 uint8_t dhval[512];
3711 3714 uint32_t cval_len;
3712 3715 uint8_t cval[20];
3713 3716 uint32_t tran_id;
3714 3717 uint32_t *hash_val = NULL;
3715 3718 uint8_t ReasonCode;
3716 3719 uint8_t ReasonCodeExplanation;
3717 3720 AUTH_RJT *rjt;
3718 3721
3719 3722 /* ACC the ELS DHCHAP_Reply msg first */
3720 3723
3721 3724 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
3722 3725
3723 3726 bp = mp->virt;
3724 3727 lp = (uint32_t *)bp;
3725 3728
3726 3729 /*
3727 3730 * send back ELS AUTH_Reject or DHCHAP_Success msg based on the
3728 3731 * verification result. i.e., hash computation etc.
3729 3732 */
3730 3733 dh_reply = (DHCHAP_REPLY_HDR *)((uint8_t *)lp);
3731 3734 tmp = (uint8_t *)((uint8_t *)lp);
3732 3735
3733 3736 tran_id = dh_reply->tran_id;
3734 3737
3735 3738 if (LE_SWAP32(tran_id) != node_dhc->nlp_auth_tranid_ini) {
3736 3739
3737 3740 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3738 3741 "rcv_auth_msg_dhchap_challenge_cmpl_wait4next:0x%x 0x%x 0x%x",
3739 3742 ndlp->nlp_DID, tran_id, node_dhc->nlp_auth_tranid_ini);
3740 3743
3741 3744 ReasonCode = AUTHRJT_FAILURE;
3742 3745 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
3743 3746 goto Reject;
3744 3747 }
3745 3748
3746 3749 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3747 3750 "rcv_a_m_dhch_chll_cmpl_wait4next:0x%x 0x%x 0x%x 0x%x 0x%x",
3748 3751 ndlp->nlp_DID, tran_id, node_dhc->nlp_auth_tranid_ini,
3749 3752 node_dhc->nlp_auth_tranid_rsp, dh_reply->auth_msg_code);
3750 3753
3751 3754 /* cancel the nlp_authrsp_timeout timer and send out Auth_Reject */
3752 3755 if (node_dhc->nlp_authrsp_tmo) {
3753 3756 node_dhc->nlp_authrsp_tmo = 0;
3754 3757 }
3755 3758 if (dh_reply->auth_msg_code == AUTH_REJECT) {
3756 3759
3757 3760 rjt = (AUTH_RJT *)((uint8_t *)lp);
3758 3761 ReasonCode = rjt->ReasonCode;
3759 3762 ReasonCodeExplanation = rjt->ReasonCodeExplanation;
3760 3763
3761 3764 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3762 3765 "rcv_a_msg_dhch_chall_cmpl_wait4next:RJT rcved:0x%x 0x%x",
3763 3766 ReasonCode, ReasonCodeExplanation);
3764 3767
3765 3768 switch (ReasonCode) {
3766 3769 case AUTHRJT_LOGIC_ERR:
3767 3770 switch (ReasonCodeExplanation) {
3768 3771 case AUTHEXP_MECH_UNUSABLE:
3769 3772 case AUTHEXP_DHGROUP_UNUSABLE:
3770 3773 case AUTHEXP_HASHFUNC_UNUSABLE:
3771 3774 ReasonCode = AUTHRJT_LOGIC_ERR;
3772 3775 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
3773 3776 break;
3774 3777
3775 3778 case AUTHEXP_RESTART_AUTH:
3776 3779 /*
3777 3780 * Cancel the rsp timer if not cancelled yet.
3778 3781 * and restart auth tran now.
3779 3782 */
3780 3783 if (node_dhc->nlp_authrsp_tmo != 0) {
3781 3784 node_dhc->nlp_authrsp_tmo = 0;
3782 3785 node_dhc->nlp_authrsp_tmocnt = 0;
3783 3786 }
3784 3787 if (emlxs_dhc_auth_start(port, ndlp,
3785 3788 NULL, NULL) != 0) {
3786 3789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
3787 3790 "Reauth timeout.Auth initfailed. 0x%x %x",
3788 3791 ndlp->nlp_DID, node_dhc->state);
3789 3792 }
3790 3793 return (node_dhc->state);
3791 3794
3792 3795 default:
3793 3796 ReasonCode = AUTHRJT_FAILURE;
3794 3797 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3795 3798 break;
3796 3799 }
3797 3800 break;
3798 3801
3799 3802 case AUTHRJT_FAILURE:
3800 3803 default:
3801 3804 ReasonCode = AUTHRJT_FAILURE;
3802 3805 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3803 3806 break;
3804 3807 }
3805 3808
3806 3809 goto Reject;
3807 3810
3808 3811 }
3809 3812 if (dh_reply->auth_msg_code == DHCHAP_REPLY) {
3810 3813
3811 3814 /* We must send out DHCHAP_Success msg and wait for ACC */
3812 3815 /* _AND_ if bi-dir auth, we have to wait for next */
3813 3816
3814 3817 /*
3815 3818 * Send back DHCHAP_Success or AUTH_Reject based on the
3816 3819 * verification result
3817 3820 */
3818 3821 tmp += sizeof (DHCHAP_REPLY_HDR);
3819 3822 rsp_len = LE_SWAP32(*(uint32_t *)tmp);
3820 3823 tmp += sizeof (uint32_t);
3821 3824
3822 3825 /* collect the response data */
3823 3826 bcopy((void *)tmp, (void *)rsp, rsp_len);
3824 3827
3825 3828 tmp += rsp_len;
3826 3829 dhval_len = LE_SWAP32(*(uint32_t *)tmp);
3827 3830
3828 3831 tmp += sizeof (uint32_t);
3829 3832
3830 3833
3831 3834
3832 3835 if (dhval_len != 0) {
3833 3836 /* collect the DH value */
3834 3837 bcopy((void *)tmp, (void *)dhval, dhval_len);
3835 3838 tmp += dhval_len;
3836 3839 }
3837 3840 /*
3838 3841 * Check to see if there is any challenge for bi-dir auth in
3839 3842 * the reply msg
3840 3843 */
3841 3844 cval_len = LE_SWAP32(*(uint32_t *)tmp);
3842 3845 if (cval_len != 0) {
3843 3846 /* collect challenge value */
3844 3847 tmp += sizeof (uint32_t);
3845 3848 bcopy((void *)tmp, (void *)cval, cval_len);
3846 3849
3847 3850 if (ndlp->nlp_DID == FABRIC_DID) {
3848 3851 node_dhc->nlp_auth_bidir = 1;
3849 3852 } else {
3850 3853 node_dhc->nlp_auth_bidir = 1;
3851 3854 }
3852 3855 } else {
3853 3856 node_dhc->nlp_auth_bidir = 0;
3854 3857 }
3855 3858
3856 3859 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
3857 3860 "rcv_a_m_dhchap_challenge_cmpl_wait4next:Reply:%x %lx %x %x %x\n",
3858 3861 ndlp->nlp_DID, *(uint32_t *)rsp, rsp_len, dhval_len, cval_len);
3859 3862
3860 3863 /* Verify the response based on the hash func, dhgp_id etc. */
3861 3864 /*
3862 3865 * all the information needed are stored in
3863 3866 * node_dhc->hrsp_xxx or ndlp->nlp_auth_misc.
3864 3867 */
3865 3868 /*
3866 3869 * Basically compare the rsp value with the computed hash
3867 3870 * value
3868 3871 */
3869 3872
3870 3873 /* allocate hash_val first as rsp_len bytes */
3871 3874 /*
3872 3875 * we set bi-cval pointer as NULL because we are using
3873 3876 * node_dhc->hrsp_cval[]
3874 3877 */
3875 3878 hash_val = emlxs_hash_verification(port, port_dhc, ndlp,
3876 3879 (tran_id), dhval, (dhval_len), 1, 0);
3877 3880
3878 3881 if (hash_val == NULL) {
3879 3882 ReasonCode = AUTHRJT_FAILURE;
3880 3883 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3881 3884 goto Reject;
3882 3885 }
3883 3886 if (bcmp((void *) rsp, (void *)hash_val, rsp_len)) {
3884 3887 /* not identical */
3885 3888 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3886 3889 "rcv_auth_msg_dhchap_challenge_cmpl_wait4next: Not authted(1).");
3887 3890
3888 3891 ReasonCode = AUTHRJT_FAILURE;
3889 3892 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3890 3893 goto Reject;
3891 3894 }
3892 3895 kmem_free(hash_val, rsp_len);
3893 3896 hash_val = NULL;
3894 3897
3895 3898 /* generate the reply based on the challenge received if any */
3896 3899 if ((cval_len) != 0) {
3897 3900 /*
3898 3901 * Cal R2 = H (Ti || Km || Ca2) Ca2 = H (C2 || ((g^y
3899 3902 * mod p)^x mod p) ) = H (C2 || (g^(x*y) mod p)) = H
3900 3903 * (C2 || seskey) Km is the password associated with
3901 3904 * responder. Here cval: C2 dhval: (g^y mod p)
3902 3905 */
3903 3906 hash_val = emlxs_hash_get_R2(port, port_dhc,
3904 3907 ndlp, (tran_id), dhval,
3905 3908 (dhval_len), 1, cval);
3906 3909
3907 3910 if (hash_val == NULL) {
3908 3911 ReasonCode = AUTHRJT_FAILURE;
3909 3912 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3910 3913 goto Reject;
3911 3914 }
3912 3915 }
3913 3916 emlxs_dhc_state(port, ndlp,
3914 3917 NODE_STATE_DHCHAP_SUCCESS_ISSUE, 0, 0);
3915 3918
3916 3919 if (emlxs_issue_dhchap_success(port, ndlp, 0,
3917 3920 (uint8_t *)hash_val)) {
3918 3921 ReasonCode = AUTHRJT_FAILURE;
3919 3922 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
3920 3923 goto Reject;
3921 3924 }
3922 3925 }
3923 3926 return (node_dhc->state);
3924 3927
3925 3928 Reject:
3926 3929
3927 3930 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
3928 3931 ReasonCode, ReasonCodeExplanation);
3929 3932 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
3930 3933 ReasonCodeExplanation);
3931 3934 emlxs_dhc_auth_complete(port, ndlp, 1);
3932 3935
3933 3936 out:
3934 3937
3935 3938 return (node_dhc->state);
3936 3939
3937 3940 } /* emlxs_rcv_auth_msg_dhchap_challenge_cmpl_wait4next */
3938 3941
3939 3942
3940 3943
3941 3944 /*
3942 3945 * This routine should be emlxs_disc_neverdev.
3943 3946 *
3944 3947 */
3945 3948 /* ARGSUSED */
3946 3949 static uint32_t
3947 3950 emlxs_cmpl_auth_msg_dhchap_challenge_cmpl_wait4next(
3948 3951 emlxs_port_t *port,
3949 3952 /* CHANNEL * rp, */ void *arg1,
3950 3953 /* IOCBQ * iocbq, */ void *arg2,
3951 3954 /* MATCHMAP * mp, */ void *arg3,
3952 3955 /* NODELIST * ndlp */ void *arg4,
3953 3956 uint32_t evt)
3954 3957 {
3955 3958 NODELIST *ndlp = (NODELIST *)arg4;
3956 3959
3957 3960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3958 3961 "cmpl_a_m_dhch_chall_cmpl_wait4next.0x%x. Not implemented.",
3959 3962 ndlp->nlp_DID);
3960 3963
3961 3964 return (0);
3962 3965
3963 3966 } /* emlxs_cmpl_auth_msg_dhchap_challenge_cmpl_wait4next */
3964 3967
3965 3968
3966 3969 /*
3967 3970 * ! emlxs_rcv_auth_msg_dhchap_success_issue
3968 3971 *
3969 3972 * \pre \post \param phba \param ndlp \param arg \param evt \return
3970 3973 * uint32_t \b Description:
3971 3974 *
3972 3975 * The host is the auth responder and the auth transaction is still in
3973 3976 * progress, any unsolicited els auth msg is unexpected and
3974 3977 * should not happen. If DHCHAP_Reject received, ACC back and move to next
3975 3978 * state NPR_NODE. anything else, RJT and move to
3976 3979 * NPR_NODE.
3977 3980 */
3978 3981 /* ARGSUSED */
3979 3982 static uint32_t
3980 3983 emlxs_rcv_auth_msg_dhchap_success_issue(
3981 3984 emlxs_port_t *port,
3982 3985 /* CHANNEL * rp, */ void *arg1,
3983 3986 /* IOCBQ * iocbq, */ void *arg2,
3984 3987 /* MATCHMAP * mp, */ void *arg3,
3985 3988 /* NODELIST * ndlp */ void *arg4,
3986 3989 uint32_t evt)
3987 3990 {
3988 3991 NODELIST *ndlp = (NODELIST *)arg4;
3989 3992
3990 3993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
3991 3994 "rcv_a_m_dhch_success_issue called. did=0x%x. Not implemented.",
3992 3995 ndlp->nlp_DID);
3993 3996
3994 3997 return (0);
3995 3998
3996 3999 } /* emlxs_rcv_auth_msg_dhchap_success_issue */
3997 4000
3998 4001
3999 4002
4000 4003 /*
4001 4004 * emlxs_cmpl_auth_msg_dhchap_success_issue
4002 4005 *
4003 4006 * This routine is invoked when
4004 4007 * host as the auth responder received the solicited response (ACC or RJT)
4005 4008 * from the initiator that received DHCHAP_ Success.
4006 4009 *
4007 4010 * For uni-dirctional authentication, we are done so the next state =
4008 4011 * REG_LOGIN for bi-directional authentication, we will expect
4009 4012 * DHCHAP_Success msg. so the next state = DHCHAP_SUCCESS_CMPL_WAIT4NEXT
4010 4013 * and start the emlxs_dhc_authrsp_timeout timer
4011 4014 */
4012 4015 /* ARGSUSED */
4013 4016 static uint32_t
4014 4017 emlxs_cmpl_auth_msg_dhchap_success_issue(
4015 4018 emlxs_port_t *port,
4016 4019 /* CHANNEL * rp, */ void *arg1,
4017 4020 /* IOCBQ * iocbq, */ void *arg2,
4018 4021 /* MATCHMAP * mp, */ void *arg3,
4019 4022 /* NODELIST * ndlp */ void *arg4,
4020 4023 uint32_t evt)
4021 4024 {
4022 4025 NODELIST *ndlp = (NODELIST *)arg4;
4023 4026 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4024 4027
4025 4028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4026 4029 "cmpl_a_m_dhch_success_issue: did=0x%x auth_bidir=0x%x",
4027 4030 ndlp->nlp_DID, node_dhc->nlp_auth_bidir);
4028 4031
4029 4032 if (node_dhc->nlp_auth_bidir == 1) {
4030 4033 /* we would expect the bi-dir authentication result */
4031 4034
4032 4035 /*
4033 4036 * the next state should be
4034 4037 * emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next
4035 4038 */
4036 4039 emlxs_dhc_state(port, ndlp,
4037 4040 NODE_STATE_DHCHAP_SUCCESS_CMPL_WAIT4NEXT, 0, 0);
4038 4041
4039 4042 /* start the emlxs_dhc_authrsp_timeout timer */
4040 4043 node_dhc->nlp_authrsp_tmo = DRV_TIME +
4041 4044 node_dhc->auth_cfg.authentication_timeout;
4042 4045 } else {
4043 4046 node_dhc->flag &= ~NLP_REMOTE_AUTH;
4044 4047
4045 4048 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_SUCCESS, 0, 0);
4046 4049 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_22,
4047 4050 "Node-initiated-unidir-reauth-success");
4048 4051 emlxs_dhc_auth_complete(port, ndlp, 0);
4049 4052 }
4050 4053
4051 4054 return (node_dhc->state);
4052 4055
4053 4056 } /* emlxs_cmpl_auth_msg_dhchap_success_issue */
4054 4057
4055 4058
4056 4059 /* ARGSUSED */
4057 4060 static uint32_t
4058 4061 emlxs_device_recov_unmapped_node(
4059 4062 emlxs_port_t *port,
4060 4063 void *arg1,
4061 4064 void *arg2,
4062 4065 void *arg3,
4063 4066 void *arg4,
4064 4067 uint32_t evt)
4065 4068 {
4066 4069 NODELIST *ndlp = (NODELIST *)arg4;
4067 4070
4068 4071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4069 4072 "emlxs_device_recov_unmapped_node called. 0x%x. Not implemented.",
4070 4073 ndlp->nlp_DID);
4071 4074
4072 4075 return (0);
4073 4076
4074 4077 } /* emlxs_device_recov_unmapped_node */
4075 4078
4076 4079
4077 4080
4078 4081 /* ARGSUSED */
4079 4082 static uint32_t
4080 4083 emlxs_device_rm_npr_node(
4081 4084 emlxs_port_t *port,
4082 4085 void *arg1,
4083 4086 void *arg2,
4084 4087 void *arg3,
4085 4088 void *arg4,
4086 4089 uint32_t evt)
4087 4090 {
4088 4091 NODELIST *ndlp = (NODELIST *)arg4;
4089 4092
4090 4093 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4091 4094 "emlxs_device_rm_npr_node called. 0x%x. Not implemented.",
4092 4095 ndlp->nlp_DID);
4093 4096
4094 4097 return (0);
4095 4098
4096 4099 } /* emlxs_device_rm_npr_node */
4097 4100
4098 4101
4099 4102 /* ARGSUSED */
4100 4103 static uint32_t
4101 4104 emlxs_device_recov_npr_node(
4102 4105 emlxs_port_t *port,
4103 4106 void *arg1,
4104 4107 void *arg2,
4105 4108 void *arg3,
4106 4109 void *arg4,
4107 4110 uint32_t evt)
4108 4111 {
4109 4112 NODELIST *ndlp = (NODELIST *)arg4;
4110 4113
4111 4114 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4112 4115 "emlxs_device_recov_npr_node called. 0x%x. Not implemented.",
4113 4116 ndlp->nlp_DID);
4114 4117
4115 4118 return (0);
4116 4119
4117 4120 } /* emlxs_device_recov_npr_node */
4118 4121
4119 4122
4120 4123 /* ARGSUSED */
4121 4124 static uint32_t
4122 4125 emlxs_device_rem_auth(
4123 4126 emlxs_port_t *port,
4124 4127 /* CHANNEL * rp, */ void *arg1,
4125 4128 /* IOCBQ * iocbq, */ void *arg2,
4126 4129 /* MATCHMAP * mp, */ void *arg3,
4127 4130 /* NODELIST * ndlp */ void *arg4,
4128 4131 uint32_t evt)
4129 4132 {
4130 4133 NODELIST *ndlp = (NODELIST *)arg4;
4131 4134 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4132 4135
4133 4136 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4134 4137 "emlxs_device_rem_auth: 0x%x.",
4135 4138 ndlp->nlp_DID);
4136 4139
4137 4140 emlxs_dhc_state(port, ndlp, NODE_STATE_UNKNOWN, 0, 0);
4138 4141
4139 4142 return (node_dhc->state);
4140 4143
4141 4144 } /* emlxs_device_rem_auth */
4142 4145
4143 4146
4144 4147 /*
4145 4148 * This routine is invoked when linkdown event happens during authentication
4146 4149 */
4147 4150 /* ARGSUSED */
4148 4151 static uint32_t
4149 4152 emlxs_device_recov_auth(
4150 4153 emlxs_port_t *port,
4151 4154 /* CHANNEL * rp, */ void *arg1,
4152 4155 /* IOCBQ * iocbq, */ void *arg2,
4153 4156 /* MATCHMAP * mp, */ void *arg3,
4154 4157 /* NODELIST * ndlp */ void *arg4,
4155 4158 uint32_t evt)
4156 4159 {
4157 4160 NODELIST *ndlp = (NODELIST *)arg4;
4158 4161 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4159 4162
4160 4163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4161 4164 "emlxs_device_recov_auth: 0x%x.",
4162 4165 ndlp->nlp_DID);
4163 4166
4164 4167 node_dhc->nlp_authrsp_tmo = 0;
4165 4168
4166 4169 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED, 0, 0);
4167 4170
4168 4171 return (node_dhc->state);
4169 4172
4170 4173 } /* emlxs_device_recov_auth */
4171 4174
4172 4175
4173 4176
4174 4177 /*
4175 4178 * This routine is invoked when the host as the responder sent out the
4176 4179 * ELS DHCHAP_Success to the initiator, the initiator ACC
4177 4180 * it. AND then the host received an unsolicited auth msg from the initiator,
4178 4181 * this msg is supposed to be the ELS DHCHAP_Success
4179 4182 * msg for the bi-directional authentication.
4180 4183 *
4181 4184 * next state should be REG_LOGIN
4182 4185 */
4183 4186 /* ARGSUSED */
4184 4187 static uint32_t
4185 4188 emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next(
4186 4189 emlxs_port_t *port,
4187 4190 /* CHANNEL * rp, */ void *arg1,
4188 4191 /* IOCBQ * iocbq, */ void *arg2,
4189 4192 /* MATCHMAP * mp, */ void *arg3,
4190 4193 /* NODELIST * ndlp */ void *arg4,
4191 4194 uint32_t evt)
4192 4195 {
4193 4196 IOCBQ *iocbq = (IOCBQ *)arg2;
4194 4197 MATCHMAP *mp = (MATCHMAP *)arg3;
4195 4198 NODELIST *ndlp = (NODELIST *)arg4;
4196 4199 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4197 4200 uint8_t *bp;
4198 4201 uint32_t *lp;
4199 4202 DHCHAP_SUCCESS_HDR *dh_success;
4200 4203 AUTH_RJT *auth_rjt;
4201 4204 uint8_t ReasonCode;
4202 4205 uint8_t ReasonCodeExplanation;
4203 4206
4204 4207 bp = mp->virt;
4205 4208 lp = (uint32_t *)bp;
4206 4209
4207 4210 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4208 4211 "emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next: did=0x%x",
4209 4212 ndlp->nlp_DID);
4210 4213
4211 4214 dh_success = (DHCHAP_SUCCESS_HDR *)((uint8_t *)lp);
4212 4215
4213 4216 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
4214 4217
4215 4218 if (dh_success->auth_msg_code == AUTH_REJECT) {
4216 4219 /* ACC it and retry etc. */
4217 4220 auth_rjt = (AUTH_RJT *)dh_success;
4218 4221 ReasonCode = auth_rjt->ReasonCode;
4219 4222 ReasonCodeExplanation = auth_rjt->ReasonCodeExplanation;
4220 4223
4221 4224 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4222 4225 "rcv_a_m_dhch_success_cmpl_wait4next:REJECT rvd. 0x%x 0x%x 0x%x",
4223 4226 ndlp->nlp_DID, ReasonCode, ReasonCodeExplanation);
4224 4227
4225 4228 switch (ReasonCode) {
4226 4229 case AUTHRJT_LOGIC_ERR:
4227 4230 switch (ReasonCodeExplanation) {
4228 4231 case AUTHEXP_MECH_UNUSABLE:
4229 4232 case AUTHEXP_DHGROUP_UNUSABLE:
4230 4233 case AUTHEXP_HASHFUNC_UNUSABLE:
4231 4234 ReasonCode = AUTHRJT_LOGIC_ERR;
4232 4235 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
4233 4236 break;
4234 4237
4235 4238 case AUTHEXP_RESTART_AUTH:
4236 4239 /*
4237 4240 * Cancel the rsp timer if not cancelled yet.
4238 4241 * and restart auth tran now.
4239 4242 */
4240 4243 if (node_dhc->nlp_authrsp_tmo != 0) {
4241 4244 node_dhc->nlp_authrsp_tmo = 0;
4242 4245 node_dhc->nlp_authrsp_tmocnt = 0;
4243 4246 }
4244 4247 if (emlxs_dhc_auth_start(port, ndlp,
4245 4248 NULL, NULL) != 0) {
4246 4249 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
4247 4250 "Reauth timeout. Auth initfailed. 0x%x %x",
4248 4251 ndlp->nlp_DID, node_dhc->state);
4249 4252 }
4250 4253 return (node_dhc->state);
4251 4254
4252 4255 default:
4253 4256 ReasonCode = AUTHRJT_FAILURE;
4254 4257 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
4255 4258 break;
4256 4259
4257 4260 }
4258 4261 break;
4259 4262
4260 4263 case AUTHRJT_FAILURE:
4261 4264 default:
4262 4265 ReasonCode = AUTHRJT_FAILURE;
4263 4266 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
4264 4267 break;
4265 4268
4266 4269 }
4267 4270
4268 4271 goto Reject;
4269 4272
4270 4273 } else if (dh_success->auth_msg_code == DHCHAP_SUCCESS) {
4271 4274 if (LE_SWAP32(dh_success->tran_id) !=
4272 4275 node_dhc->nlp_auth_tranid_ini) {
4273 4276 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4274 4277 "rcv_a_m_dhch_success_cmpl_wait4next: 0x%x 0x%lx, 0x%lx",
4275 4278 ndlp->nlp_DID, dh_success->tran_id, node_dhc->nlp_auth_tranid_ini);
4276 4279
4277 4280 ReasonCode = AUTHRJT_FAILURE;
4278 4281 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
4279 4282 goto Reject;
4280 4283 }
4281 4284 node_dhc->flag |= NLP_REMOTE_AUTH;
4282 4285
4283 4286 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_SUCCESS, 0, 0);
4284 4287 emlxs_log_auth_event(port, ndlp, ESC_EMLXS_26,
4285 4288 "Node-initiated-bidir-reauth-success");
4286 4289 emlxs_dhc_auth_complete(port, ndlp, 0);
4287 4290 } else {
4288 4291 ReasonCode = AUTHRJT_FAILURE;
4289 4292 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
4290 4293 goto Reject;
4291 4294 }
4292 4295
4293 4296 return (node_dhc->state);
4294 4297
4295 4298 Reject:
4296 4299
4297 4300 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
4298 4301 ReasonCode, ReasonCodeExplanation);
4299 4302 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
4300 4303 ReasonCodeExplanation);
4301 4304 emlxs_dhc_auth_complete(port, ndlp, 1);
4302 4305
4303 4306 out:
4304 4307
4305 4308 return (node_dhc->state);
4306 4309
4307 4310 } /* emlxs_rcv_auth_msg_dhchap_success_cmpl_wait4next */
4308 4311
4309 4312
4310 4313 /* ARGSUSED */
4311 4314 static uint32_t
4312 4315 emlxs_cmpl_auth_msg_dhchap_success_cmpl_wait4next(
4313 4316 emlxs_port_t *port,
4314 4317 /* CHANNEL * rp, */ void *arg1,
4315 4318 /* IOCBQ * iocbq, */ void *arg2,
4316 4319 /* MATCHMAP * mp, */ void *arg3,
4317 4320 /* NODELIST * ndlp */ void *arg4,
4318 4321 uint32_t evt)
4319 4322 {
4320 4323
4321 4324 return (0);
4322 4325
4323 4326 } /* emlxs_cmpl_auth_msg_dhchap_success_cmpl_wait4next */
4324 4327
4325 4328
4326 4329 /* ARGSUSED */
4327 4330 static uint32_t
4328 4331 emlxs_rcv_auth_msg_auth_negotiate_rcv(
4329 4332 emlxs_port_t *port,
4330 4333 /* CHANNEL * rp, */ void *arg1,
4331 4334 /* IOCBQ * iocbq, */ void *arg2,
4332 4335 /* MATCHMAP * mp, */ void *arg3,
4333 4336 /* NODELIST * ndlp */ void *arg4,
4334 4337 uint32_t evt)
4335 4338 {
4336 4339 NODELIST *ndlp = (NODELIST *)arg4;
4337 4340
4338 4341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4339 4342 "rcv_a_m_auth_negotiate_rcv called. did=0x%x. Not implemented.",
4340 4343 ndlp->nlp_DID);
4341 4344
4342 4345 return (0);
4343 4346
4344 4347 } /* emlxs_rcv_auth_msg_auth_negotiate_rcv */
4345 4348
4346 4349
4347 4350 /* ARGSUSED */
4348 4351 static uint32_t
4349 4352 emlxs_rcv_auth_msg_npr_node(
4350 4353 emlxs_port_t *port,
4351 4354 /* CHANNEL * rp, */ void *arg1,
4352 4355 /* IOCBQ * iocbq, */ void *arg2,
4353 4356 /* MATCHMAP * mp, */ void *arg3,
4354 4357 /* NODELIST * ndlp */ void *arg4,
4355 4358 uint32_t evt)
4356 4359 {
4357 4360 IOCBQ *iocbq = (IOCBQ *)arg2;
4358 4361 MATCHMAP *mp = (MATCHMAP *)arg3;
4359 4362 NODELIST *ndlp = (NODELIST *)arg4;
4360 4363 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4361 4364 uint8_t *bp;
4362 4365
4363 4366 uint32_t *lp;
4364 4367 uint32_t msglen;
4365 4368 uint8_t *tmp;
4366 4369
4367 4370 AUTH_MSG_HDR *msg;
4368 4371
4369 4372 uint8_t *temp;
4370 4373 uint32_t rc, i, hs_id[2], dh_id[5];
4371 4374 /* from initiator */
4372 4375 uint32_t hash_id, dhgp_id; /* to be used by responder */
4373 4376 uint16_t num_hs = 0;
4374 4377 uint16_t num_dh = 0;
4375 4378
4376 4379 bp = mp->virt;
4377 4380 lp = (uint32_t *)bp;
4378 4381
4379 4382 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4380 4383 "emlxs_rcv_auth_msg_npr_node:");
4381 4384
4382 4385 /*
4383 4386 * 1. process the auth msg, should acc first no matter what. 2.
4384 4387 * return DHCHAP_Challenge for AUTH_Negotiate auth msg, AUTH_Reject
4385 4388 * for anything else.
4386 4389 */
4387 4390 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
4388 4391
4389 4392 msg = (AUTH_MSG_HDR *)((uint8_t *)lp);
4390 4393 msglen = msg->msg_len;
4391 4394 tmp = ((uint8_t *)lp);
4392 4395
4393 4396 /* temp is used for error checking */
4394 4397 temp = (uint8_t *)((uint8_t *)lp);
4395 4398 /* Check the auth_els_code */
4396 4399 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x90000B01)) {
4397 4400 /* ReasonCode = AUTHRJT_FAILURE; */
4398 4401 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4399 4402
4400 4403 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4401 4404 "emlxs_rcv_auth_msg_npr_node: payload(1)=0x%x",
4402 4405 (*(uint32_t *)temp));
4403 4406
4404 4407 goto AUTH_Reject;
4405 4408 }
4406 4409 temp += 3 * sizeof (uint32_t);
4407 4410 /* Check name tag and name length */
4408 4411 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x00010008)) {
4409 4412 /* ReasonCode = AUTHRJT_FAILURE; */
4410 4413 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4411 4414
4412 4415 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4413 4416 "emlxs_rcv_auth_msg_npr_node: payload(2)=0x%x",
4414 4417 (*(uint32_t *)temp));
4415 4418
4416 4419 goto AUTH_Reject;
4417 4420 }
4418 4421 temp += sizeof (uint32_t) + 8;
4419 4422 /* Check proto_num */
4420 4423 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x00000001)) {
4421 4424 /* ReasonCode = AUTHRJT_FAILURE; */
4422 4425 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4423 4426
4424 4427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4425 4428 "emlxs_rcv_auth_msg_npr_node: payload(3)=0x%x",
4426 4429 (*(uint32_t *)temp));
4427 4430
4428 4431 goto AUTH_Reject;
4429 4432 }
4430 4433 temp += sizeof (uint32_t);
4431 4434 /* Get para_len */
4432 4435 /* para_len = LE_SWAP32(*(uint32_t *)temp); */
4433 4436
4434 4437 temp += sizeof (uint32_t);
4435 4438 /* Check proto_id */
4436 4439 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != AUTH_DHCHAP) {
4437 4440 /* ReasonCode = AUTHRJT_FAILURE; */
4438 4441 /* ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL; */
4439 4442
4440 4443 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4441 4444 "emlxs_rcv_auth_msg_npr_node: payload(4)=0x%x",
4442 4445 (*(uint32_t *)temp));
4443 4446
4444 4447 goto AUTH_Reject;
4445 4448 }
4446 4449 temp += sizeof (uint32_t);
4447 4450 /* Check hashlist tag */
4448 4451 if ((LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16 !=
4449 4452 LE_SWAP16(HASH_LIST_TAG)) {
4450 4453 /* ReasonCode = AUTHRJT_FAILURE; */
4451 4454 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4452 4455
4453 4456 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4454 4457 "emlxs_rcv_auth_msg_npr_node: payload(5)=0x%x",
4455 4458 (LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16);
4456 4459
4457 4460 goto AUTH_Reject;
4458 4461 }
4459 4462 /* Get num_hs */
4460 4463 num_hs = LE_SWAP32(*(uint32_t *)temp) & 0x0000FFFF;
4461 4464
4462 4465 temp += sizeof (uint32_t);
4463 4466 /* Check HashList_value1 */
4464 4467 hs_id[0] = *(uint32_t *)temp;
4465 4468
4466 4469 if ((hs_id[0] != AUTH_MD5) && (hs_id[0] != AUTH_SHA1)) {
4467 4470 /* ReasonCode = AUTHRJT_LOGIC_ERR; */
4468 4471 /* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
4469 4472
4470 4473 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4471 4474 "emlxs_rcv_auth_msg_npr_node: payload(6)=0x%x",
4472 4475 (*(uint32_t *)temp));
4473 4476
4474 4477 goto AUTH_Reject;
4475 4478 }
4476 4479 if (num_hs == 1) {
4477 4480 hs_id[1] = 0;
4478 4481 } else if (num_hs == 2) {
4479 4482 temp += sizeof (uint32_t);
4480 4483 hs_id[1] = *(uint32_t *)temp;
4481 4484
4482 4485 if ((hs_id[1] != AUTH_MD5) && (hs_id[1] != AUTH_SHA1)) {
4483 4486 /* ReasonCode = AUTHRJT_LOGIC_ERR; */
4484 4487 /* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
4485 4488
4486 4489 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4487 4490 "emlxs_rcv_auth_msg_npr_node: payload(7)=0x%x",
4488 4491 (*(uint32_t *)temp));
4489 4492
4490 4493 goto AUTH_Reject;
4491 4494 }
4492 4495 if (hs_id[0] == hs_id[1]) {
4493 4496 /* ReasonCode = AUTHRJT_FAILURE; */
4494 4497 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4495 4498
4496 4499 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4497 4500 "emlxs_rcv_auth_msg_npr_node: payload(8)=0x%x",
4498 4501 (*(uint32_t *)temp));
4499 4502
4500 4503 goto AUTH_Reject;
4501 4504 }
4502 4505 } else {
4503 4506 /* ReasonCode = AUTHRJT_FAILURE; */
4504 4507 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4505 4508
4506 4509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4507 4510 "emlxs_rcv_auth_msg_npr_node: payload(9)=0x%x",
4508 4511 (*(uint32_t *)(temp - sizeof (uint32_t))));
4509 4512
4510 4513 goto AUTH_Reject;
4511 4514 }
4512 4515
4513 4516 /* Which hash_id should we use */
4514 4517 if (num_hs == 1) {
4515 4518 /*
4516 4519 * We always use the highest priority specified by us if we
4517 4520 * match initiator's , Otherwise, we use the next higher we
4518 4521 * both have. CR 26238
4519 4522 */
4520 4523 if (node_dhc->auth_cfg.hash_priority[0] == hs_id[0]) {
4521 4524 hash_id = node_dhc->auth_cfg.hash_priority[0];
4522 4525 } else if (node_dhc->auth_cfg.hash_priority[1] == hs_id[0]) {
4523 4526 hash_id = node_dhc->auth_cfg.hash_priority[1];
4524 4527 } else {
4525 4528 /* ReasonCode = AUTHRJT_LOGIC_ERR; */
4526 4529 /* ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE; */
4527 4530
4528 4531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4529 4532 "emlxs_rcv_auth_msg_npr_node: payload(10)=0x%lx",
4530 4533 (*(uint32_t *)temp));
4531 4534
4532 4535 goto AUTH_Reject;
4533 4536 }
4534 4537 } else {
4535 4538 /*
4536 4539 * Since the initiator specified two hashs, we always select
4537 4540 * our first one.
4538 4541 */
4539 4542 hash_id = node_dhc->auth_cfg.hash_priority[0];
4540 4543 }
4541 4544
4542 4545 temp += sizeof (uint32_t);
4543 4546 /* Check DHgIDList_tag */
4544 4547 if ((LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16 !=
4545 4548 LE_SWAP16(DHGID_LIST_TAG)) {
4546 4549 /* ReasonCode = AUTHRJT_FAILURE; */
4547 4550 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4548 4551
4549 4552 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4550 4553 "emlxs_rcv_auth_msg_npr_node: payload(11)=0x%lx",
4551 4554 (*(uint32_t *)temp));
4552 4555
4553 4556 goto AUTH_Reject;
4554 4557 }
4555 4558 /* Get num_dh */
4556 4559 num_dh = LE_SWAP32(*(uint32_t *)temp) & 0x0000FFFF;
4557 4560
4558 4561 if (num_dh == 0) {
4559 4562 /* ReasonCode = AUTHRJT_FAILURE; */
4560 4563 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4561 4564
4562 4565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4563 4566 "emlxs_rcv_auth_msg_npr_node: payload(12)=0x%lx",
4564 4567 (*(uint32_t *)temp));
4565 4568
4566 4569 goto AUTH_Reject;
4567 4570 }
4568 4571 for (i = 0; i < num_dh; i++) {
4569 4572 temp += sizeof (uint32_t);
4570 4573 /* Check DHgIDList_g0 */
4571 4574 dh_id[i] = (*(uint32_t *)temp);
4572 4575 }
4573 4576
4574 4577 rc = emlxs_check_dhgp(port, ndlp, dh_id, num_dh, &dhgp_id);
4575 4578
4576 4579 if (rc == 1) {
4577 4580 /* ReasonCode = AUTHRJT_LOGIC_ERR; */
4578 4581 /* ReasonCodeExplanation = AUTHEXP_DHGROUP_UNUSABLE; */
4579 4582
4580 4583 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4581 4584 "emlxs_rcv_auth_msg_npr_node: payload(13)=0x%lx",
4582 4585 (*(uint32_t *)temp));
4583 4586
4584 4587 goto AUTH_Reject;
4585 4588 } else if (rc == 2) {
4586 4589 /* ReasonCode = AUTHRJT_FAILURE; */
4587 4590 /* ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD; */
4588 4591
4589 4592 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
4590 4593 "emlxs_rcv_auth_msg_npr_node: payload(14)=0x%lx",
4591 4594 (*(uint32_t *)temp));
4592 4595
4593 4596 goto AUTH_Reject;
4594 4597 }
4595 4598 /* We should update the tran_id */
4596 4599 node_dhc->nlp_auth_tranid_ini = msg->tran_id;
4597 4600
4598 4601 if (msg->auth_msg_code == AUTH_NEGOTIATE) {
4599 4602 node_dhc->nlp_auth_flag = 1; /* ndlp is the initiator */
4600 4603
4601 4604 /* Send back the DHCHAP_Challenge with the proper paramaters */
4602 4605 if (emlxs_issue_dhchap_challenge(port, ndlp, 0, tmp,
4603 4606 LE_SWAP32(msglen),
4604 4607 hash_id, dhgp_id)) {
4605 4608 goto AUTH_Reject;
4606 4609 }
4607 4610 emlxs_dhc_state(port, ndlp,
4608 4611 NODE_STATE_DHCHAP_CHALLENGE_ISSUE, 0, 0);
4609 4612
4610 4613 } else {
4611 4614 goto AUTH_Reject;
4612 4615 }
4613 4616
4614 4617 return (node_dhc->state);
4615 4618
4616 4619 AUTH_Reject:
4617 4620
4618 4621 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4619 4622 "emlxs_rcv_auth_msg_npr_node: AUTH_Reject it.");
4620 4623
4621 4624 return (node_dhc->state);
4622 4625
4623 4626 } /* emlxs_rcv_auth_msg_npr_node */
4624 4627
4625 4628
4626 4629 /* ARGSUSED */
4627 4630 static uint32_t
4628 4631 emlxs_cmpl_auth_msg_npr_node(
4629 4632 emlxs_port_t *port,
4630 4633 /* CHANNEL * rp, */ void *arg1,
4631 4634 /* IOCBQ * iocbq, */ void *arg2,
4632 4635 /* MATCHMAP * mp, */ void *arg3,
4633 4636 /* NODELIST * ndlp */ void *arg4,
4634 4637 uint32_t evt)
4635 4638 {
4636 4639 NODELIST *ndlp = (NODELIST *)arg4;
4637 4640 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4638 4641
4639 4642 /*
4640 4643 * we donot cancel the nodev timeout here because we donot know if we
4641 4644 * can get the authentication restarted from other side once we got
4642 4645 * the new auth transaction kicked off we cancel nodev tmo
4643 4646 * immediately.
4644 4647 */
4645 4648 /* we goto change the hba state back to where it used to be */
4646 4649 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4647 4650 "emlxs_cmpl_auth_msg_npr_node: 0x%x 0x%x prev_state=0x%x\n",
4648 4651 ndlp->nlp_DID, node_dhc->state, node_dhc->prev_state);
4649 4652
4650 4653 return (node_dhc->state);
4651 4654
4652 4655 } /* emlxs_cmpl_auth_msg_npr_node */
4653 4656
4654 4657
4655 4658 /*
4656 4659 * ! emlxs_rcv_auth_msg_unmapped_node
4657 4660 *
4658 4661 * \pre \post \param phba \param ndlp \param arg \param evt \return
4659 4662 * uint32_t
4660 4663 *
4661 4664 * \b Description: This routine is invoked when the host received an
4662 4665 * unsolicited els authentication msg from the Fx_Port which is
4663 4666 * wellknown port 0xFFFFFE in unmapped state, or from Nx_Port which is
4664 4667 * in the unmapped state meaning that it is either a target
4665 4668 * which there is no scsi id associated with it or it could be another
4666 4669 * initiator. (end-to-end)
4667 4670 *
4668 4671 * For the Fabric F_Port (FFFFFE) we mark the port to the state in re_auth
4669 4672 * state without disruppting the traffic. Then the fabric
4670 4673 * will go through the authentication processes until it is done.
4671 4674 *
4672 4675 * most of the cases, the fabric should send us AUTH_Negotiate ELS msg. Once
4673 4676 * host received this auth_negotiate els msg, host
4674 4677 * should sent back ACC first and then send random challenge, plus DH value
4675 4678 * (i.e., host's publick key)
4676 4679 *
4677 4680 * Host side needs to store the challenge value and public key for later
4678 4681 * verification usage. (i.e., to verify the response from
4679 4682 * initiator)
4680 4683 *
4681 4684 * If two FC_Ports start the reauthentication transaction at the same time,
4682 4685 * one of the two authentication transactions shall be
4683 4686 * aborted. In case of Host and Fabric the Nx_Port shall remain the
4684 4687 * authentication initiator, while the Fx_Port shall become
4685 4688 * the authentication responder.
4686 4689 *
4687 4690 */
4688 4691 /* ARGSUSED */
4689 4692 static uint32_t
4690 4693 emlxs_rcv_auth_msg_unmapped_node(
4691 4694 emlxs_port_t *port,
4692 4695 /* CHANNEL * rp, */ void *arg1,
4693 4696 /* IOCBQ * iocbq, */ void *arg2,
4694 4697 /* MATCHMAP * mp, */ void *arg3,
4695 4698 /* NODELIST * ndlp */ void *arg4,
4696 4699 uint32_t evt)
4697 4700 {
4698 4701 IOCBQ *iocbq = (IOCBQ *)arg2;
4699 4702 MATCHMAP *mp = (MATCHMAP *)arg3;
4700 4703 NODELIST *ndlp = (NODELIST *)arg4;
4701 4704 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
4702 4705 uint8_t *bp;
4703 4706 uint32_t *lp;
4704 4707 uint32_t msglen;
4705 4708 uint8_t *tmp;
4706 4709
4707 4710 uint8_t ReasonCode;
4708 4711 uint8_t ReasonCodeExplanation;
4709 4712 AUTH_MSG_HDR *msg;
4710 4713 uint8_t *temp;
4711 4714 uint32_t rc, i, hs_id[2], dh_id[5];
4712 4715 /* from initiator */
4713 4716 uint32_t hash_id, dhgp_id; /* to be used by responder */
4714 4717 uint16_t num_hs = 0;
4715 4718 uint16_t num_dh = 0;
4716 4719
4717 4720 /*
4718 4721 * 1. process the auth msg, should acc first no matter what. 2.
4719 4722 * return DHCHAP_Challenge for AUTH_Negotiate auth msg, AUTH_Reject
4720 4723 * for anything else.
4721 4724 */
4722 4725 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4723 4726 "emlxs_rcv_auth_msg_unmapped_node: Sending ACC: did=0x%x",
4724 4727 ndlp->nlp_DID);
4725 4728
4726 4729 (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_AUTH, 0, 0);
4727 4730
4728 4731 bp = mp->virt;
4729 4732 lp = (uint32_t *)bp;
4730 4733
4731 4734 msg = (AUTH_MSG_HDR *)((uint8_t *)lp);
4732 4735 msglen = msg->msg_len;
4733 4736
4734 4737 tmp = ((uint8_t *)lp);
4735 4738
4736 4739 /* temp is used for error checking */
4737 4740 temp = (uint8_t *)((uint8_t *)lp);
4738 4741 /* Check the auth_els_code */
4739 4742 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x90000B01)) {
4740 4743 ReasonCode = AUTHRJT_FAILURE;
4741 4744 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4742 4745
4743 4746 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4744 4747 "emlxs_rcv_auth_msg_unmapped_node: payload(1)=0x%x",
4745 4748 (*(uint32_t *)temp));
4746 4749
4747 4750 goto AUTH_Reject;
4748 4751 }
4749 4752 temp += 3 * sizeof (uint32_t);
4750 4753 /* Check name tag and name length */
4751 4754 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x00010008)) {
4752 4755 ReasonCode = AUTHRJT_FAILURE;
4753 4756 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4754 4757
4755 4758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4756 4759 "emlxs_rcv_auth_msg_unmapped_node: payload(2)=0x%x",
4757 4760 (*(uint32_t *)temp));
4758 4761
4759 4762 goto AUTH_Reject;
4760 4763 }
4761 4764 temp += sizeof (uint32_t) + 8;
4762 4765 /* Check proto_num */
4763 4766 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != LE_SWAP32(0x00000001)) {
4764 4767 ReasonCode = AUTHRJT_FAILURE;
4765 4768 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4766 4769
4767 4770 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4768 4771 "emlxs_rcv_auth_msg_unmapped_node: payload(3)=0x%x",
4769 4772 (*(uint32_t *)temp));
4770 4773
4771 4774 goto AUTH_Reject;
4772 4775 }
4773 4776 temp += sizeof (uint32_t);
4774 4777
4775 4778 /* Get para_len */
4776 4779 /* para_len = *(uint32_t *)temp; */
4777 4780 temp += sizeof (uint32_t);
4778 4781
4779 4782 /* Check proto_id */
4780 4783 if (((*(uint32_t *)temp) & 0xFFFFFFFF) != AUTH_DHCHAP) {
4781 4784 ReasonCode = AUTHRJT_FAILURE;
4782 4785 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
4783 4786
4784 4787 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4785 4788 "emlxs_rcv_auth_msg_unmapped_node: payload(4)=0x%x",
4786 4789 (*(uint32_t *)temp));
4787 4790
4788 4791 goto AUTH_Reject;
4789 4792 }
4790 4793 temp += sizeof (uint32_t);
4791 4794 /* Check hashlist tag */
4792 4795 if ((LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16 !=
4793 4796 LE_SWAP16(HASH_LIST_TAG)) {
4794 4797 ReasonCode = AUTHRJT_FAILURE;
4795 4798 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4796 4799
4797 4800 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4798 4801 "emlxs_rcv_auth_msg_unmapped_node: payload(5)=0x%x",
4799 4802 (LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16);
4800 4803
4801 4804 goto AUTH_Reject;
4802 4805 }
4803 4806 /* Get num_hs */
4804 4807 num_hs = LE_SWAP32(*(uint32_t *)temp) & 0x0000FFFF;
4805 4808
4806 4809 temp += sizeof (uint32_t);
4807 4810 /* Check HashList_value1 */
4808 4811 hs_id[0] = *(uint32_t *)temp;
4809 4812
4810 4813 if ((hs_id[0] != AUTH_MD5) && (hs_id[0] != AUTH_SHA1)) {
4811 4814 ReasonCode = AUTHRJT_LOGIC_ERR;
4812 4815 ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE;
4813 4816
4814 4817 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4815 4818 "emlxs_rcv_auth_msg_unmapped_node: payload(6)=0x%x",
4816 4819 (*(uint32_t *)temp));
4817 4820
4818 4821 goto AUTH_Reject;
4819 4822 }
4820 4823 if (num_hs == 1) {
4821 4824 hs_id[1] = 0;
4822 4825 } else if (num_hs == 2) {
4823 4826 temp += sizeof (uint32_t);
4824 4827 hs_id[1] = *(uint32_t *)temp;
4825 4828
4826 4829 if ((hs_id[1] != AUTH_MD5) && (hs_id[1] != AUTH_SHA1)) {
4827 4830 ReasonCode = AUTHRJT_LOGIC_ERR;
4828 4831 ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE;
4829 4832
4830 4833 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4831 4834 "emlxs_rcv_auth_msg_unmapped_node: payload(7)=0x%x",
4832 4835 (*(uint32_t *)temp));
4833 4836
4834 4837 goto AUTH_Reject;
4835 4838 }
4836 4839 if (hs_id[0] == hs_id[1]) {
4837 4840 ReasonCode = AUTHRJT_FAILURE;
4838 4841 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4839 4842
4840 4843 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4841 4844 "emlxs_rcv_auth_msg_unmapped_node: payload(8)=0x%x",
4842 4845 (*(uint32_t *)temp));
4843 4846
4844 4847 goto AUTH_Reject;
4845 4848 }
4846 4849 } else {
4847 4850 ReasonCode = AUTHRJT_FAILURE;
4848 4851 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4849 4852
4850 4853 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4851 4854 "emlxs_rcv_auth_msg_unmapped_node: payload(9)=0x%x",
4852 4855 (*(uint32_t *)(temp - sizeof (uint32_t))));
4853 4856
4854 4857 goto AUTH_Reject;
4855 4858 }
4856 4859
4857 4860 /* Which hash_id should we use */
4858 4861 if (num_hs == 1) {
4859 4862 /*
4860 4863 * We always use the highest priority specified by us if we
4861 4864 * match initiator's , Otherwise, we use the next higher we
4862 4865 * both have. CR 26238
4863 4866 */
4864 4867 if (node_dhc->auth_cfg.hash_priority[0] == hs_id[0]) {
4865 4868 hash_id = node_dhc->auth_cfg.hash_priority[0];
4866 4869 } else if (node_dhc->auth_cfg.hash_priority[1] == hs_id[0]) {
4867 4870 hash_id = node_dhc->auth_cfg.hash_priority[1];
4868 4871 } else {
4869 4872 ReasonCode = AUTHRJT_LOGIC_ERR;
4870 4873 ReasonCodeExplanation = AUTHEXP_HASHFUNC_UNUSABLE;
4871 4874
4872 4875 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4873 4876 "emlxs_rcv_auth_msg_unmapped_node: pload(10)=0x%x",
4874 4877 (*(uint32_t *)temp));
4875 4878
4876 4879 goto AUTH_Reject;
4877 4880 }
4878 4881 } else {
4879 4882 /*
4880 4883 * Since the initiator specified two hashs, we always select
4881 4884 * our first one.
4882 4885 */
4883 4886 hash_id = node_dhc->auth_cfg.hash_priority[0];
4884 4887 }
4885 4888
4886 4889 temp += sizeof (uint32_t);
4887 4890 /* Check DHgIDList_tag */
4888 4891 if ((LE_SWAP32(*(uint32_t *)temp) & 0xFFFF0000) >> 16 !=
4889 4892 LE_SWAP16(DHGID_LIST_TAG)) {
4890 4893 ReasonCode = AUTHRJT_FAILURE;
4891 4894 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4892 4895
4893 4896 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4894 4897 "emlxs_rcv_auth_msg_unmapped_node: payload(11)=0x%x",
4895 4898 (*(uint32_t *)temp));
4896 4899
4897 4900 goto AUTH_Reject;
4898 4901 }
4899 4902 /* Get num_dh */
4900 4903 num_dh = LE_SWAP32(*(uint32_t *)temp) & 0x0000FFFF;
4901 4904
4902 4905 if (num_dh == 0) {
4903 4906 ReasonCode = AUTHRJT_FAILURE;
4904 4907 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4905 4908
4906 4909 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4907 4910 "emlxs_rcv_auth_msg_unmapped_node: payload(12)=0x%x",
4908 4911 (*(uint32_t *)temp));
4909 4912
4910 4913 goto AUTH_Reject;
4911 4914 }
4912 4915 for (i = 0; i < num_dh; i++) {
4913 4916 temp += sizeof (uint32_t);
4914 4917 /* Check DHgIDList_g0 */
4915 4918 dh_id[i] = (*(uint32_t *)temp);
4916 4919 }
4917 4920
4918 4921 rc = emlxs_check_dhgp(port, ndlp, dh_id, num_dh, &dhgp_id);
4919 4922
4920 4923 if (rc == 1) {
4921 4924 ReasonCode = AUTHRJT_LOGIC_ERR;
4922 4925 ReasonCodeExplanation = AUTHEXP_DHGROUP_UNUSABLE;
4923 4926
4924 4927 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4925 4928 "emlxs_rcv_auth_msg_unmapped_node: payload(13)=0x%x",
4926 4929 (*(uint32_t *)temp));
4927 4930
4928 4931 goto AUTH_Reject;
4929 4932 } else if (rc == 2) {
4930 4933 ReasonCode = AUTHRJT_FAILURE;
4931 4934 ReasonCodeExplanation = AUTHEXP_BAD_PAYLOAD;
4932 4935
4933 4936 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4934 4937 "emlxs_rcv_auth_msg_unmapped_node: payload(14)=0x%x",
4935 4938 (*(uint32_t *)temp));
4936 4939
4937 4940 goto AUTH_Reject;
4938 4941 }
4939 4942 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4940 4943 "emlxs_rcv_auth_msg_unmapped_node: 0x%x 0x%x 0x%x 0x%x 0x%x",
4941 4944 hash_id, dhgp_id, msg->auth_msg_code, msglen, msg->tran_id);
4942 4945
4943 4946 /*
4944 4947 * since ndlp is the initiator, tran_id is store in
4945 4948 * nlp_auth_tranid_ini
4946 4949 */
4947 4950 node_dhc->nlp_auth_tranid_ini = LE_SWAP32(msg->tran_id);
4948 4951
4949 4952 if (msg->auth_msg_code == AUTH_NEGOTIATE) {
4950 4953
4951 4954 /*
4952 4955 * at this point, we know for sure we received the
4953 4956 * auth-negotiate msg from another entity, so cancel the
4954 4957 * auth-rsp timeout timer if we are expecting it. should
4955 4958 * never happen?
4956 4959 */
4957 4960 node_dhc->nlp_auth_flag = 1;
4958 4961
4959 4962 if (node_dhc->nlp_authrsp_tmo) {
4960 4963 node_dhc->nlp_authrsp_tmo = 0;
4961 4964 }
4962 4965 /*
4963 4966 * If at this point, the host is doing reauthentication
4964 4967 * (reauth heart beat) to this ndlp, then Host should remain
4965 4968 * as the auth initiator, host should reply to the received
4966 4969 * AUTH_Negotiate message with an AUTH_Reject message with
4967 4970 * Reason Code 'Logical Error' and Reason Code Explanation
4968 4971 * 'Authentication Transaction Already Started'.
4969 4972 */
4970 4973 if (node_dhc->nlp_reauth_status ==
4971 4974 NLP_HOST_REAUTH_IN_PROGRESS) {
4972 4975 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
4973 4976 "emlxs_rcv_auth_msg_unmapped_node: Ht reauth inprgress.");
4974 4977
4975 4978 ReasonCode = AUTHRJT_LOGIC_ERR;
4976 4979 ReasonCodeExplanation = AUTHEXP_AUTHTRAN_STARTED;
4977 4980
4978 4981 goto AUTH_Reject;
4979 4982 }
4980 4983 /* Send back the DHCHAP_Challenge with the proper paramaters */
4981 4984 if (emlxs_issue_dhchap_challenge(port, ndlp, 0, tmp,
4982 4985 LE_SWAP32(msglen),
4983 4986 hash_id, dhgp_id)) {
4984 4987
4985 4988 goto AUTH_Reject;
4986 4989 }
4987 4990 /* setup the proper state */
4988 4991 emlxs_dhc_state(port, ndlp,
4989 4992 NODE_STATE_DHCHAP_CHALLENGE_ISSUE, 0, 0);
4990 4993
4991 4994 } else {
4992 4995 ReasonCode = AUTHRJT_FAILURE;
4993 4996 ReasonCodeExplanation = AUTHEXP_BAD_PROTOCOL;
4994 4997
4995 4998 goto AUTH_Reject;
4996 4999 }
4997 5000
4998 5001 return (node_dhc->state);
4999 5002
5000 5003 AUTH_Reject:
5001 5004
5002 5005 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED,
5003 5006 ReasonCode, ReasonCodeExplanation);
5004 5007 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
5005 5008 ReasonCodeExplanation);
5006 5009 emlxs_dhc_auth_complete(port, ndlp, 1);
5007 5010
5008 5011 return (node_dhc->state);
5009 5012
5010 5013 } /* emlxs_rcv_auth_msg_unmapped_node */
5011 5014
5012 5015
5013 5016
5014 5017
5015 5018 /*
5016 5019 * emlxs_hash_vrf for verification only the host is the initiator in
5017 5020 * the routine.
5018 5021 */
5019 5022 /* ARGSUSED */
5020 5023 static uint32_t *
5021 5024 emlxs_hash_vrf(
5022 5025 emlxs_port_t *port,
5023 5026 emlxs_port_dhc_t *port_dhc,
5024 5027 NODELIST *ndlp,
5025 5028 uint32_t tran_id,
5026 5029 union challenge_val un_cval)
5027 5030 {
5028 5031 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
5029 5032 uint32_t dhgp_id;
5030 5033 uint32_t hash_id;
5031 5034 uint32_t *hash_val;
5032 5035 uint32_t hash_size;
5033 5036 MD5_CTX mdctx;
5034 5037 SHA1_CTX sha1ctx;
5035 5038 uint8_t sha1_digest[20];
5036 5039 uint8_t md5_digest[16];
5037 5040 uint8_t mytran_id = 0x00;
5038 5041
5039 5042 char *remote_key;
5040 5043
5041 5044 tran_id = (AUTH_TRAN_ID_MASK & tran_id);
5042 5045 mytran_id = (uint8_t)(LE_SWAP32(tran_id));
5043 5046
5044 5047
5045 5048 if (ndlp->nlp_DID == FABRIC_DID) {
5046 5049 remote_key = (char *)node_dhc->auth_key.remote_password;
5047 5050 hash_id = node_dhc->hash_id;
5048 5051 dhgp_id = node_dhc->dhgp_id;
5049 5052 } else {
5050 5053 remote_key = (char *)node_dhc->auth_key.remote_password;
5051 5054 hash_id = node_dhc->nlp_auth_hashid;
5052 5055 dhgp_id = node_dhc->nlp_auth_dhgpid;
5053 5056 }
5054 5057
5055 5058 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5056 5059 "emlxs_hash_vrf: 0x%x 0x%x 0x%x tran_id=0x%x",
5057 5060 ndlp->nlp_DID, hash_id, dhgp_id, mytran_id);
5058 5061
5059 5062 if (dhgp_id == 0) {
5060 5063 /* NULL DHCHAP */
5061 5064 if (hash_id == AUTH_MD5) {
5062 5065 bzero(&mdctx, sizeof (MD5_CTX));
5063 5066
5064 5067 hash_size = MD5_LEN;
5065 5068
5066 5069 MD5Init(&mdctx);
5067 5070
5068 5071 /* Transaction Identifier T */
5069 5072 MD5Update(&mdctx, (unsigned char *) &mytran_id, 1);
5070 5073
5071 5074 MD5Update(&mdctx, (unsigned char *) remote_key,
5072 5075 node_dhc->auth_key.remote_password_length);
5073 5076
5074 5077 /* Augmented challenge: NULL DHCHAP i.e., Challenge */
5075 5078 MD5Update(&mdctx,
5076 5079 (unsigned char *)&(un_cval.md5.val[0]), MD5_LEN);
5077 5080
5078 5081 MD5Final((uint8_t *)md5_digest, &mdctx);
5079 5082
5080 5083 hash_val = (uint32_t *)kmem_alloc(hash_size,
5081 5084 KM_NOSLEEP);
5082 5085 if (hash_val == NULL) {
5083 5086 return (NULL);
5084 5087 } else {
5085 5088 bcopy((void *)&md5_digest,
5086 5089 (void *)hash_val, MD5_LEN);
5087 5090 }
5088 5091 /*
5089 5092 * emlxs_md5_digest_to_hex((uint8_t *)hash_val,
5090 5093 * output);
5091 5094 */
5092 5095 }
5093 5096 if (hash_id == AUTH_SHA1) {
5094 5097 bzero(&sha1ctx, sizeof (SHA1_CTX));
5095 5098 hash_size = SHA1_LEN;
5096 5099 SHA1Init(&sha1ctx);
5097 5100
5098 5101 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
5099 5102
5100 5103 SHA1Update(&sha1ctx, (void *)remote_key,
5101 5104 node_dhc->auth_key.remote_password_length);
5102 5105
5103 5106 SHA1Update(&sha1ctx,
5104 5107 (void *)&(un_cval.sha1.val[0]), SHA1_LEN);
5105 5108
5106 5109 SHA1Final((void *)sha1_digest, &sha1ctx);
5107 5110
5108 5111 /*
5109 5112 * emlxs_sha1_digest_to_hex((uint8_t *)hash_val,
5110 5113 * output);
5111 5114 */
5112 5115
5113 5116 hash_val = (uint32_t *)kmem_alloc(hash_size,
5114 5117 KM_NOSLEEP);
5115 5118 if (hash_val == NULL) {
5116 5119 return (NULL);
5117 5120 } else {
5118 5121 bcopy((void *)&sha1_digest,
5119 5122 (void *)hash_val, SHA1_LEN);
5120 5123 }
5121 5124 }
5122 5125 return ((uint32_t *)hash_val);
5123 5126 } else {
5124 5127 /* Verification of bi-dir auth for DH-CHAP group */
5125 5128 /* original challenge is node_dhc->bi_cval[] */
5126 5129 /* session key is node_dhc->ses_key[] */
5127 5130 /* That's IT */
5128 5131 /*
5129 5132 * H(bi_cval || ses_key) = C H(Ti || Km || C) = hash_val
5130 5133 */
5131 5134 if (hash_id == AUTH_MD5) {
5132 5135 bzero(&mdctx, sizeof (MD5_CTX));
5133 5136 hash_size = MD5_LEN;
5134 5137
5135 5138 MD5Init(&mdctx);
5136 5139
5137 5140 MD5Update(&mdctx,
5138 5141 (void *)&(un_cval.md5.val[0]), MD5_LEN);
5139 5142
5140 5143 if (ndlp->nlp_DID == FABRIC_DID) {
5141 5144 MD5Update(&mdctx,
5142 5145 (void *)&node_dhc->ses_key[0],
5143 5146 node_dhc->seskey_len);
5144 5147 } else {
5145 5148 /* ses_key is obtained in emlxs_hash_rsp */
5146 5149 MD5Update(&mdctx,
5147 5150 (void *)&node_dhc->nlp_auth_misc.ses_key[0],
5148 5151 node_dhc->nlp_auth_misc.seskey_len);
5149 5152 }
5150 5153
5151 5154 MD5Final((void *)md5_digest, &mdctx);
5152 5155
5153 5156 MD5Init(&mdctx);
5154 5157
5155 5158 MD5Update(&mdctx, (void *)&mytran_id, 1);
5156 5159
5157 5160 MD5Update(&mdctx, (void *)remote_key,
5158 5161 node_dhc->auth_key.remote_password_length);
5159 5162
5160 5163 MD5Update(&mdctx, (void *)md5_digest, MD5_LEN);
5161 5164
5162 5165 MD5Final((void *)md5_digest, &mdctx);
5163 5166
5164 5167 hash_val = (uint32_t *)kmem_alloc(hash_size,
5165 5168 KM_NOSLEEP);
5166 5169 if (hash_val == NULL) {
5167 5170 return (NULL);
5168 5171 } else {
5169 5172 bcopy((void *)&md5_digest,
5170 5173 (void *)hash_val, MD5_LEN);
5171 5174 }
5172 5175 }
5173 5176 if (hash_id == AUTH_SHA1) {
5174 5177 bzero(&sha1ctx, sizeof (SHA1_CTX));
5175 5178 hash_size = SHA1_LEN;
5176 5179
5177 5180 SHA1Init(&sha1ctx);
5178 5181
5179 5182 SHA1Update(&sha1ctx,
5180 5183 (void *)&(un_cval.sha1.val[0]), SHA1_LEN);
5181 5184
5182 5185 if (ndlp->nlp_DID == FABRIC_DID) {
5183 5186 SHA1Update(&sha1ctx,
5184 5187 (void *)&node_dhc->ses_key[0],
5185 5188 node_dhc->seskey_len);
5186 5189 } else {
5187 5190 /* ses_key was obtained in emlxs_hash_rsp */
5188 5191 SHA1Update(&sha1ctx,
5189 5192 (void *)&node_dhc->nlp_auth_misc.ses_key[0],
5190 5193 node_dhc->nlp_auth_misc.seskey_len);
5191 5194 }
5192 5195
5193 5196 SHA1Final((void *)sha1_digest, &sha1ctx);
5194 5197
5195 5198 SHA1Init(&sha1ctx);
5196 5199
5197 5200 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
5198 5201
5199 5202 SHA1Update(&sha1ctx, (void *)remote_key,
5200 5203 node_dhc->auth_key.remote_password_length);
5201 5204
5202 5205 SHA1Update(&sha1ctx, (void *)sha1_digest, SHA1_LEN);
5203 5206
5204 5207 SHA1Final((void *)sha1_digest, &sha1ctx);
5205 5208
5206 5209 hash_val = (uint32_t *)kmem_alloc(hash_size,
5207 5210 KM_NOSLEEP);
5208 5211 if (hash_val == NULL) {
5209 5212 return (NULL);
5210 5213 } else {
5211 5214 bcopy((void *)&sha1_digest,
5212 5215 (void *)hash_val, SHA1_LEN);
5213 5216 }
5214 5217 }
5215 5218 return ((uint32_t *)hash_val);
5216 5219 }
5217 5220
5218 5221 } /* emlxs_hash_vrf */
5219 5222
5220 5223
5221 5224 /*
5222 5225 * If dhval == NULL, NULL DHCHAP else, DHCHAP group.
5223 5226 *
5224 5227 * This routine is used by the auth transaction initiator (Who does the
5225 5228 * auth-negotiate) to calculate the R1 (response) based on
5226 5229 * the dh value it received, its own random private key, the challenge it
5227 5230 * received, and Transaction id, as well as the password
5228 5231 * associated with this very initiator in the auth pair.
5229 5232 */
5230 5233 uint32_t *
5231 5234 emlxs_hash_rsp(
5232 5235 emlxs_port_t *port,
5233 5236 emlxs_port_dhc_t *port_dhc,
5234 5237 NODELIST *ndlp,
5235 5238 uint32_t tran_id,
5236 5239 union challenge_val un_cval,
5237 5240 uint8_t *dhval,
5238 5241 uint32_t dhvallen)
5239 5242 {
5240 5243 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
5241 5244 uint32_t dhgp_id;
5242 5245 uint32_t hash_id;
5243 5246 uint32_t *hash_val;
5244 5247 uint32_t hash_size;
5245 5248 MD5_CTX mdctx;
5246 5249 SHA1_CTX sha1ctx;
5247 5250 uint8_t sha1_digest[20];
5248 5251 uint8_t md5_digest[16];
5249 5252 uint8_t Cai[20];
5250 5253 uint8_t mytran_id = 0x00;
5251 5254 char *mykey;
5252 5255 BIG_ERR_CODE err = BIG_OK;
5253 5256
5254 5257 if (ndlp->nlp_DID == FABRIC_DID) {
5255 5258 hash_id = node_dhc->hash_id;
5256 5259 dhgp_id = node_dhc->dhgp_id;
5257 5260 } else {
5258 5261 hash_id = node_dhc->nlp_auth_hashid;
5259 5262 dhgp_id = node_dhc->nlp_auth_dhgpid;
5260 5263 }
5261 5264
5262 5265 tran_id = (AUTH_TRAN_ID_MASK & tran_id);
5263 5266 mytran_id = (uint8_t)(LE_SWAP32(tran_id));
5264 5267
5265 5268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5266 5269 "emlxs_hash_rsp: 0x%x 0x%x 0x%x 0x%x dhvallen=0x%x",
5267 5270 ndlp->nlp_DID, hash_id, dhgp_id, mytran_id, dhvallen);
5268 5271
5269 5272 if (ndlp->nlp_DID == FABRIC_DID) {
5270 5273 mykey = (char *)node_dhc->auth_key.local_password;
5271 5274
5272 5275 } else {
5273 5276 mykey = (char *)node_dhc->auth_key.local_password;
5274 5277 }
5275 5278
5276 5279 if (dhval == NULL) {
5277 5280 /* NULL DHCHAP */
5278 5281 if (hash_id == AUTH_MD5) {
5279 5282 bzero(&mdctx, sizeof (MD5_CTX));
5280 5283 hash_size = MD5_LEN;
5281 5284
5282 5285 MD5Init(&mdctx);
5283 5286
5284 5287 MD5Update(&mdctx, (unsigned char *)&mytran_id, 1);
5285 5288
5286 5289 MD5Update(&mdctx, (unsigned char *)mykey,
5287 5290 node_dhc->auth_key.local_password_length);
5288 5291
5289 5292 MD5Update(&mdctx,
5290 5293 (unsigned char *)&(un_cval.md5.val[0]),
5291 5294 MD5_LEN);
5292 5295
5293 5296 MD5Final((uint8_t *)md5_digest, &mdctx);
5294 5297
5295 5298 hash_val = (uint32_t *)kmem_alloc(hash_size,
5296 5299 KM_NOSLEEP);
5297 5300 if (hash_val == NULL) {
5298 5301 return (NULL);
5299 5302 } else {
5300 5303 bcopy((void *)&md5_digest,
5301 5304 (void *)hash_val, MD5_LEN);
5302 5305 }
5303 5306
5304 5307 /*
5305 5308 * emlxs_md5_digest_to_hex((uint8_t *)hash_val,
5306 5309 * output);
5307 5310 */
5308 5311
5309 5312 }
5310 5313 if (hash_id == AUTH_SHA1) {
5311 5314 bzero(&sha1ctx, sizeof (SHA1_CTX));
5312 5315 hash_size = SHA1_LEN;
5313 5316 SHA1Init(&sha1ctx);
5314 5317
5315 5318 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
5316 5319
5317 5320 SHA1Update(&sha1ctx, (void *)mykey,
5318 5321 node_dhc->auth_key.local_password_length);
5319 5322
5320 5323 SHA1Update(&sha1ctx,
5321 5324 (void *)&(un_cval.sha1.val[0]), SHA1_LEN);
5322 5325
5323 5326 SHA1Final((void *)sha1_digest, &sha1ctx);
5324 5327
5325 5328 /*
5326 5329 * emlxs_sha1_digest_to_hex((uint8_t *)hash_val,
5327 5330 * output);
5328 5331 */
5329 5332
5330 5333 hash_val = (uint32_t *)kmem_alloc(hash_size,
5331 5334 KM_NOSLEEP);
5332 5335 if (hash_val == NULL) {
5333 5336 return (NULL);
5334 5337 } else {
5335 5338 bcopy((void *)&sha1_digest,
5336 5339 (void *)hash_val, SHA1_LEN);
5337 5340 }
5338 5341 }
5339 5342 return ((uint32_t *)hash_val);
5340 5343 } else {
5341 5344
5342 5345 /* process DH grops */
5343 5346 /*
5344 5347 * calculate interm hash value Ca1 Ca1 = H(C1 || (g^x mod
5345 5348 * p)^y mod p) in which C1 is the challenge received. g^x mod
5346 5349 * p is the dhval received y is the random number in 16 bytes
5347 5350 * for MD5, 20 bytes for SHA1 p is hardcoded value based on
5348 5351 * different DH groups.
5349 5352 *
5350 5353 * To calculate hash value R1 R1 = H (Ti || Kn || Cai) in which
5351 5354 * Ti is the transaction identifier Kn is the shared secret.
5352 5355 * Cai is the result from interm hash.
5353 5356 *
5354 5357 * g^y mod p is reserved in port_dhc as pubkey (public key).for
5355 5358 * bi-dir challenge is another random number. y is prikey
5356 5359 * (private key). ((g^x mod p)^y mod p) is sekey (session
5357 5360 * key)
5358 5361 */
5359 5362 err = emlxs_interm_hash(port, port_dhc, ndlp,
5360 5363 (void *)&Cai, tran_id,
5361 5364 un_cval, dhval, &dhvallen);
5362 5365
5363 5366 if (err != BIG_OK) {
5364 5367 return (NULL);
5365 5368 }
5366 5369 if (hash_id == AUTH_MD5) {
5367 5370 bzero(&mdctx, sizeof (MD5_CTX));
5368 5371 hash_size = MD5_LEN;
5369 5372
5370 5373 MD5Init(&mdctx);
5371 5374
5372 5375 MD5Update(&mdctx, (unsigned char *)&mytran_id, 1);
5373 5376
5374 5377 MD5Update(&mdctx, (unsigned char *)mykey,
5375 5378 node_dhc->auth_key.local_password_length);
5376 5379
5377 5380 MD5Update(&mdctx, (unsigned char *)Cai, MD5_LEN);
5378 5381
5379 5382 MD5Final((uint8_t *)md5_digest, &mdctx);
5380 5383
5381 5384 hash_val = (uint32_t *)kmem_alloc(hash_size,
5382 5385 KM_NOSLEEP);
5383 5386 if (hash_val == NULL) {
5384 5387 return (NULL);
5385 5388 } else {
5386 5389 bcopy((void *)&md5_digest,
5387 5390 (void *)hash_val, MD5_LEN);
5388 5391 }
5389 5392 }
5390 5393 if (hash_id == AUTH_SHA1) {
5391 5394 bzero(&sha1ctx, sizeof (SHA1_CTX));
5392 5395 hash_size = SHA1_LEN;
5393 5396
5394 5397 SHA1Init(&sha1ctx);
5395 5398
5396 5399 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
5397 5400
5398 5401 SHA1Update(&sha1ctx, (void *)mykey,
5399 5402 node_dhc->auth_key.local_password_length);
5400 5403
5401 5404 SHA1Update(&sha1ctx, (void *)&Cai[0], SHA1_LEN);
5402 5405
5403 5406 SHA1Final((void *)sha1_digest, &sha1ctx);
5404 5407
5405 5408 hash_val = (uint32_t *)kmem_alloc(hash_size,
5406 5409 KM_NOSLEEP);
5407 5410 if (hash_val == NULL) {
5408 5411 return (NULL);
5409 5412 } else {
5410 5413 bcopy((void *)&sha1_digest,
5411 5414 (void *)hash_val, SHA1_LEN);
5412 5415 }
5413 5416 }
5414 5417 return ((uint32_t *)hash_val);
5415 5418 }
5416 5419
5417 5420 } /* emlxs_hash_rsp */
5418 5421
5419 5422
5420 5423 /*
5421 5424 * To get the augmented challenge Cai Stored in hash_val
5422 5425 *
5423 5426 * Cai = Hash (C1 || ((g^x mod p)^y mod p)) = Hash (C1 || (g^(x*y) mod p)
5424 5427 *
5425 5428 * C1:challenge received from the remote entity (g^x mod p): dh val
5426 5429 * received from the remote entity (remote entity's pubkey) y:
5427 5430 * random private key from the local entity Hash: hash function used in
5428 5431 * agreement. (g^(x*y) mod p): shared session key (aka
5429 5432 * shared secret) (g^y mod p): local entity's pubkey
5430 5433 */
5431 5434 /* ARGSUSED */
5432 5435 BIG_ERR_CODE
5433 5436 emlxs_interm_hash(
5434 5437 emlxs_port_t *port,
5435 5438 emlxs_port_dhc_t *port_dhc,
5436 5439 NODELIST *ndlp,
5437 5440 void *hash_val,
5438 5441 uint32_t tran_id,
5439 5442 union challenge_val un_cval,
5440 5443 uint8_t *dhval,
5441 5444 uint32_t *dhvallen)
5442 5445 {
5443 5446 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
5444 5447 uint32_t dhgp_id;
5445 5448 uint32_t hash_id;
5446 5449 MD5_CTX mdctx;
5447 5450 SHA1_CTX sha1ctx;
5448 5451 uint8_t sha1_digest[20];
5449 5452 uint8_t md5_digest[16];
5450 5453 uint32_t hash_size;
5451 5454 BIG_ERR_CODE err = BIG_OK;
5452 5455
5453 5456 if (ndlp->nlp_DID == FABRIC_DID) {
5454 5457 hash_id = node_dhc->hash_id;
5455 5458 dhgp_id = node_dhc->dhgp_id;
5456 5459 } else {
5457 5460 hash_id = node_dhc->nlp_auth_hashid;
5458 5461 dhgp_id = node_dhc->nlp_auth_dhgpid;
5459 5462 }
5460 5463
5461 5464 if (hash_id == AUTH_MD5) {
5462 5465 bzero(&mdctx, sizeof (MD5_CTX));
5463 5466 hash_size = MD5_LEN;
5464 5467 MD5Init(&mdctx);
5465 5468 MD5Update(&mdctx,
5466 5469 (unsigned char *)&(un_cval.md5.val[0]), MD5_LEN);
5467 5470
5468 5471 /*
5469 5472 * get the pub key (g^y mod p) and session key (g^(x*y) mod
5470 5473 * p) and stored them in the partner's ndlp structure
5471 5474 */
5472 5475 err = emlxs_BIGNUM_get_pubkey(port, port_dhc, ndlp,
5473 5476 dhval, dhvallen, hash_size, dhgp_id);
5474 5477
5475 5478 if (err != BIG_OK) {
5476 5479 return (err);
5477 5480 }
5478 5481 if (ndlp->nlp_DID == FABRIC_DID) {
5479 5482 MD5Update(&mdctx,
5480 5483 (unsigned char *)&node_dhc->ses_key[0],
5481 5484 node_dhc->seskey_len);
5482 5485 } else {
5483 5486 MD5Update(&mdctx,
5484 5487 (unsigned char *)&node_dhc->nlp_auth_misc.ses_key[0],
5485 5488 node_dhc->nlp_auth_misc.seskey_len);
5486 5489 }
5487 5490
5488 5491 MD5Final((uint8_t *)md5_digest, &mdctx);
5489 5492
5490 5493 bcopy((void *)&md5_digest, (void *)hash_val, MD5_LEN);
5491 5494 }
5492 5495 if (hash_id == AUTH_SHA1) {
5493 5496 bzero(&sha1ctx, sizeof (SHA1_CTX));
5494 5497
5495 5498 hash_size = SHA1_LEN;
5496 5499
5497 5500 SHA1Init(&sha1ctx);
5498 5501
5499 5502 SHA1Update(&sha1ctx, (void *)&(un_cval.sha1.val[0]), SHA1_LEN);
5500 5503
5501 5504 /* get the pub key and session key */
5502 5505 err = emlxs_BIGNUM_get_pubkey(port, port_dhc, ndlp,
5503 5506 dhval, dhvallen, hash_size, dhgp_id);
5504 5507
5505 5508 if (err != BIG_OK) {
5506 5509 return (err);
5507 5510 }
5508 5511 if (ndlp->nlp_DID == FABRIC_DID) {
5509 5512 SHA1Update(&sha1ctx, (void *)&node_dhc->ses_key[0],
5510 5513 node_dhc->seskey_len);
5511 5514 } else {
5512 5515 SHA1Update(&sha1ctx,
5513 5516 (void *)&node_dhc->nlp_auth_misc.ses_key[0],
5514 5517 node_dhc->nlp_auth_misc.seskey_len);
5515 5518 }
5516 5519
5517 5520 SHA1Final((void *)sha1_digest, &sha1ctx);
5518 5521
5519 5522 bcopy((void *)&sha1_digest, (void *)hash_val, SHA1_LEN);
5520 5523 }
5521 5524 return (err);
5522 5525
5523 5526 } /* emlxs_interm_hash */
5524 5527
5525 5528 /*
5526 5529 * This routine get the pubkey and session key. these pubkey and session
5527 5530 * key are stored in the partner's ndlp structure.
5528 5531 */
5529 5532 /* ARGSUSED */
5530 5533 BIG_ERR_CODE
5531 5534 emlxs_BIGNUM_get_pubkey(
5532 5535 emlxs_port_t *port,
5533 5536 emlxs_port_dhc_t *port_dhc,
5534 5537 NODELIST *ndlp,
5535 5538 uint8_t *dhval,
5536 5539 uint32_t *dhvallen,
5537 5540 uint32_t hash_size,
5538 5541 uint32_t dhgp_id)
5539 5542 {
5540 5543 emlxs_hba_t *hba = HBA;
5541 5544
5542 5545 BIGNUM a, e, n, result;
5543 5546 uint32_t plen;
5544 5547 uint8_t random_number[20];
5545 5548 unsigned char *tmp = NULL;
5546 5549 BIGNUM g, result1;
5547 5550
5548 5551 #ifdef BIGNUM_CHUNK_32
5549 5552 uint8_t gen[] = {0x00, 0x00, 0x00, 0x02};
5550 5553 #else
5551 5554 uint8_t gen[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
5552 5555 #endif /* BIGNUM_CHUNK_32 */
5553 5556
5554 5557 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
5555 5558 BIG_ERR_CODE err = BIG_OK;
5556 5559
5557 5560 /*
5558 5561 * compute a^e mod n assume a < n, n odd, result->value at least as
5559 5562 * long as n->value.
5560 5563 *
5561 5564 * a is the public key received from responder. e is the private key
5562 5565 * generated by me. n is the wellknown modulus.
5563 5566 */
5564 5567
5565 5568 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5566 5569 "emlxs_BIGNUM_get_pubkey: 0x%x 0x%x 0x%x 0x%x",
5567 5570 ndlp->nlp_DID, *dhvallen, hash_size, dhgp_id);
5568 5571
5569 5572 /* size should be in the unit of (BIG_CHUNK_TYPE) words */
5570 5573 if (big_init(&a, CHARLEN2BIGNUMLEN(*dhvallen)) != BIG_OK) {
5571 5574 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5572 5575 "emlxs_BIGNUM_get_pubkey: big_init failed. a size=%d",
5573 5576 CHARLEN2BIGNUMLEN(*dhvallen));
5574 5577
5575 5578 err = BIG_NO_MEM;
5576 5579 return (err);
5577 5580 }
5578 5581 /* a: (g^x mod p) */
5579 5582 /*
5580 5583 * dhval is in big-endian format. This call converts from
5581 5584 * byte-big-endian format to big number format (words in little
5582 5585 * endian order, but bytes within the words big endian)
5583 5586 */
5584 5587 bytestring2bignum(&a, (unsigned char *)dhval, *dhvallen);
5585 5588
5586 5589 if (big_init(&e, CHARLEN2BIGNUMLEN(hash_size)) != BIG_OK) {
5587 5590 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5588 5591 "emlxs_BIGNUM_get_pubkey: big_init failed. e size=%d",
5589 5592 CHARLEN2BIGNUMLEN(hash_size));
5590 5593
5591 5594 err = BIG_NO_MEM;
5592 5595 goto ret1;
5593 5596 }
5594 5597 #ifdef RAND
5595 5598
5596 5599 bzero(&random_number, hash_size);
5597 5600
5598 5601 /* to get random private key: y */
5599 5602 /* remember y is short lived private key */
5600 5603 if (hba->rdn_flag == 1) {
5601 5604 emlxs_get_random_bytes(ndlp, random_number, 20);
5602 5605 } else {
5603 5606 (void) random_get_pseudo_bytes(random_number, hash_size);
5604 5607 }
5605 5608
5606 5609 /* e: y */
5607 5610 bytestring2bignum(&e, (unsigned char *)random_number, hash_size);
5608 5611
5609 5612 #endif /* RAND */
5610 5613
5611 5614 #ifdef MYRAND
5612 5615 bytestring2bignum(&e, (unsigned char *)myrand, hash_size);
5613 5616
5614 5617 printf("myrand random_number as Y ================\n");
5615 5618 for (i = 0; i < 5; i++) {
5616 5619 for (j = 0; j < 4; j++) {
5617 5620 printf("%x", myrand[(i * 4) + j]);
5618 5621 }
5619 5622 printf("\n");
5620 5623 }
5621 5624 #endif /* MYRAND */
5622 5625
5623 5626 switch (dhgp_id) {
5624 5627 case GROUP_1024:
5625 5628 plen = 128;
5626 5629 tmp = dhgp1_pVal;
5627 5630 break;
5628 5631
5629 5632 case GROUP_1280:
5630 5633 plen = 160;
5631 5634 tmp = dhgp2_pVal;
5632 5635 break;
5633 5636
5634 5637 case GROUP_1536:
5635 5638 plen = 192;
5636 5639 tmp = dhgp3_pVal;
5637 5640 break;
5638 5641
5639 5642 case GROUP_2048:
5640 5643 plen = 256;
5641 5644 tmp = dhgp4_pVal;
5642 5645 break;
5643 5646 }
5644 5647
5645 5648 if (big_init(&n, CHARLEN2BIGNUMLEN(plen)) != BIG_OK) {
5646 5649 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5647 5650 "emlxs_BIGNUM_get_pubkey: big_init failed. n size=%d",
5648 5651 CHARLEN2BIGNUMLEN(plen));
5649 5652 err = BIG_NO_MEM;
5650 5653 goto ret2;
5651 5654 }
5652 5655 bytestring2bignum(&n, (unsigned char *)tmp, plen);
5653 5656
5654 5657 if (big_init(&result, CHARLEN2BIGNUMLEN(512)) != BIG_OK) {
5655 5658 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5656 5659 "emlxs_BIGNUM_get_pubkey: big_init failed. result size=%d",
5657 5660 CHARLEN2BIGNUMLEN(512));
5658 5661
5659 5662 err = BIG_NO_MEM;
5660 5663 goto ret3;
5661 5664 }
5662 5665 if (big_cmp_abs(&a, &n) > 0) {
5663 5666 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5664 5667 "emlxs_BIGNUM_get_pubkey: big_cmp_abs error.");
5665 5668 err = BIG_GENERAL_ERR;
5666 5669 goto ret4;
5667 5670 }
5668 5671 /* perform computation on big numbers to get seskey */
5669 5672 /* a^e mod n */
5670 5673 /* i.e., (g^x mod p)^y mod p */
5671 5674
5672 5675 if (big_modexp(&result, &a, &e, &n, NULL) != BIG_OK) {
5673 5676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5674 5677 "emlxs_BIGNUM_get_pubkey: big_modexp result error");
5675 5678 err = BIG_NO_MEM;
5676 5679 goto ret4;
5677 5680 }
5678 5681 /* convert big number ses_key to bytestring */
5679 5682 if (ndlp->nlp_DID == FABRIC_DID) {
5680 5683 /*
5681 5684 * This call converts from big number format to
5682 5685 * byte-big-endian format. big number format is words in
5683 5686 * little endian order, but bytes within words in native byte
5684 5687 * order
5685 5688 */
5686 5689 bignum2bytestring(node_dhc->ses_key, &result,
5687 5690 sizeof (BIG_CHUNK_TYPE) * (result.len));
5688 5691 node_dhc->seskey_len = sizeof (BIG_CHUNK_TYPE) * (result.len);
5689 5692
5690 5693 /* we can store another copy in ndlp */
5691 5694 bignum2bytestring(node_dhc->nlp_auth_misc.ses_key, &result,
5692 5695 sizeof (BIG_CHUNK_TYPE) * (result.len));
5693 5696 node_dhc->nlp_auth_misc.seskey_len =
5694 5697 sizeof (BIG_CHUNK_TYPE) * (result.len);
5695 5698 } else {
5696 5699 /* for end-to-end auth */
5697 5700 bignum2bytestring(node_dhc->nlp_auth_misc.ses_key, &result,
5698 5701 sizeof (BIG_CHUNK_TYPE) * (result.len));
5699 5702 node_dhc->nlp_auth_misc.seskey_len =
5700 5703 sizeof (BIG_CHUNK_TYPE) * (result.len);
5701 5704 }
5702 5705
5703 5706 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5704 5707 "emlxs_BIGNUM_get_pubkey: after seskey cal: 0x%x 0x%x 0x%x",
5705 5708 node_dhc->nlp_auth_misc.seskey_len, result.size, result.len);
5706 5709
5707 5710
5708 5711 /* to get pub_key: g^y mod p, g is 2 */
5709 5712
5710 5713 if (big_init(&g, 1) != BIG_OK) {
5711 5714 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5712 5715 "emlxs_BIGNUM_get_pubkey: big_init failed. g size=1");
5713 5716
5714 5717 err = BIG_NO_MEM;
5715 5718 goto ret4;
5716 5719 }
5717 5720 if (big_init(&result1, CHARLEN2BIGNUMLEN(512)) != BIG_OK) {
5718 5721 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5719 5722 "emlxs_BIGNUM_get_pubkey: big_init failed. result1 size=%d",
5720 5723 CHARLEN2BIGNUMLEN(512));
5721 5724 err = BIG_NO_MEM;
5722 5725 goto ret5;
5723 5726 }
5724 5727
5725 5728 bytestring2bignum(&g,
5726 5729 (unsigned char *)&gen, sizeof (BIG_CHUNK_TYPE));
5727 5730
5728 5731 if (big_modexp(&result1, &g, &e, &n, NULL) != BIG_OK) {
5729 5732 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5730 5733 "emlxs_BIGNUM_get_pubkey: big_modexp result1 error");
5731 5734 err = BIG_NO_MEM;
5732 5735 goto ret6;
5733 5736 }
5734 5737 /* convert big number pub_key to bytestring */
5735 5738 if (ndlp->nlp_DID == FABRIC_DID) {
5736 5739
5737 5740 bignum2bytestring(node_dhc->pub_key, &result1,
5738 5741 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5739 5742 node_dhc->pubkey_len = (result1.len) * sizeof (BIG_CHUNK_TYPE);
5740 5743
5741 5744 /* save another copy in ndlp */
5742 5745 bignum2bytestring(node_dhc->nlp_auth_misc.pub_key, &result1,
5743 5746 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5744 5747 node_dhc->nlp_auth_misc.pubkey_len =
5745 5748 (result1.len) * sizeof (BIG_CHUNK_TYPE);
5746 5749
5747 5750 } else {
5748 5751 /* for end-to-end auth */
5749 5752 bignum2bytestring(node_dhc->nlp_auth_misc.pub_key, &result1,
5750 5753 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5751 5754 node_dhc->nlp_auth_misc.pubkey_len =
5752 5755 (result1.len) * sizeof (BIG_CHUNK_TYPE);
5753 5756 }
5754 5757
5755 5758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5756 5759 "emlxs_BIGNUM_get_pubkey: after pubkey cal: 0x%x 0x%x 0x%x",
5757 5760 node_dhc->nlp_auth_misc.pubkey_len, result1.size, result1.len);
5758 5761
5759 5762
5760 5763 ret6:
5761 5764 big_finish(&result1);
5762 5765 ret5:
5763 5766 big_finish(&g);
5764 5767 ret4:
5765 5768 big_finish(&result);
5766 5769 ret3:
5767 5770 big_finish(&n);
5768 5771 ret2:
5769 5772 big_finish(&e);
5770 5773 ret1:
5771 5774 big_finish(&a);
5772 5775
5773 5776 return (err);
5774 5777
5775 5778 } /* emlxs_BIGNUM_get_pubkey */
5776 5779
5777 5780
5778 5781 /*
5779 5782 * g^x mod p x is the priv_key g and p are wellknow based on dhgp_id
5780 5783 */
5781 5784 /* ARGSUSED */
5782 5785 static BIG_ERR_CODE
5783 5786 emlxs_BIGNUM_get_dhval(
5784 5787 emlxs_port_t *port,
5785 5788 emlxs_port_dhc_t *port_dhc,
5786 5789 NODELIST *ndlp,
5787 5790 uint8_t *dhval,
5788 5791 uint32_t *dhval_len,
5789 5792 uint32_t dhgp_id,
5790 5793 uint8_t *priv_key,
5791 5794 uint32_t privkey_len)
5792 5795 {
5793 5796 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
5794 5797 BIGNUM g, e, n, result1;
5795 5798 uint32_t plen;
5796 5799 unsigned char *tmp = NULL;
5797 5800
5798 5801 #ifdef BIGNUM_CHUNK_32
5799 5802 uint8_t gen[] = {0x00, 0x00, 0x00, 0x02};
5800 5803 #else
5801 5804 uint8_t gen[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
5802 5805 #endif /* BIGNUM_CHUNK_32 */
5803 5806
5804 5807 BIG_ERR_CODE err = BIG_OK;
5805 5808
5806 5809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5807 5810 "emlxs_BIGNUM_get_dhval: did=0x%x privkey_len=0x%x dhgp_id=0x%x",
5808 5811 ndlp->nlp_DID, privkey_len, dhgp_id);
5809 5812
5810 5813 if (big_init(&result1, CHARLEN2BIGNUMLEN(512)) != BIG_OK) {
5811 5814 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5812 5815 "emlxs_BIGNUM_get_dhval: big_init failed. result1 size=%d",
5813 5816 CHARLEN2BIGNUMLEN(512));
5814 5817
5815 5818 err = BIG_NO_MEM;
5816 5819 return (err);
5817 5820 }
5818 5821 if (big_init(&g, 1) != BIG_OK) {
5819 5822 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5820 5823 "emlxs_BIGNUM_get_dhval: big_init failed. g size=1");
5821 5824
5822 5825 err = BIG_NO_MEM;
5823 5826 goto ret1;
5824 5827 }
5825 5828 /* get g */
5826 5829 bytestring2bignum(&g, (unsigned char *)gen, sizeof (BIG_CHUNK_TYPE));
5827 5830
5828 5831 if (big_init(&e, CHARLEN2BIGNUMLEN(privkey_len)) != BIG_OK) {
5829 5832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5830 5833 "emlxs_BIGNUM_get_dhval: big_init failed. e size=%d",
5831 5834 CHARLEN2BIGNUMLEN(privkey_len));
5832 5835
5833 5836 err = BIG_NO_MEM;
5834 5837 goto ret2;
5835 5838 }
5836 5839 /* get x */
5837 5840 bytestring2bignum(&e, (unsigned char *)priv_key, privkey_len);
5838 5841
5839 5842 switch (dhgp_id) {
5840 5843 case GROUP_1024:
5841 5844 plen = 128;
5842 5845 tmp = dhgp1_pVal;
5843 5846 break;
5844 5847
5845 5848 case GROUP_1280:
5846 5849 plen = 160;
5847 5850 tmp = dhgp2_pVal;
5848 5851 break;
5849 5852
5850 5853 case GROUP_1536:
5851 5854 plen = 192;
5852 5855 tmp = dhgp3_pVal;
5853 5856 break;
5854 5857
5855 5858 case GROUP_2048:
5856 5859 plen = 256;
5857 5860 tmp = dhgp4_pVal;
5858 5861 break;
5859 5862 }
5860 5863
5861 5864 if (big_init(&n, CHARLEN2BIGNUMLEN(plen)) != BIG_OK) {
5862 5865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5863 5866 "emlxs_BIGNUM_get_dhval: big_init failed. n size=%d",
5864 5867 CHARLEN2BIGNUMLEN(plen));
5865 5868
5866 5869 err = BIG_NO_MEM;
5867 5870 goto ret3;
5868 5871 }
5869 5872 /* get p */
5870 5873 bytestring2bignum(&n, (unsigned char *)tmp, plen);
5871 5874
5872 5875 /* to cal: (g^x mod p) */
5873 5876 if (big_modexp(&result1, &g, &e, &n, NULL) != BIG_OK) {
5874 5877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5875 5878 "emlxs_BIGNUM_get_dhval: big_modexp result1 error");
5876 5879
5877 5880 err = BIG_GENERAL_ERR;
5878 5881 goto ret4;
5879 5882 }
5880 5883 /* convert big number pub_key to bytestring */
5881 5884 if (ndlp->nlp_DID == FABRIC_DID) {
5882 5885 bignum2bytestring(node_dhc->hrsp_pub_key, &result1,
5883 5886 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5884 5887 node_dhc->hrsp_pubkey_len =
5885 5888 (result1.len) * sizeof (BIG_CHUNK_TYPE);
5886 5889
5887 5890 /* save another copy in partner's ndlp */
5888 5891 bignum2bytestring(node_dhc->nlp_auth_misc.hrsp_pub_key,
5889 5892 &result1,
5890 5893 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5891 5894
5892 5895 node_dhc->nlp_auth_misc.hrsp_pubkey_len =
5893 5896 (result1.len) * sizeof (BIG_CHUNK_TYPE);
5894 5897 } else {
5895 5898 bignum2bytestring(node_dhc->nlp_auth_misc.hrsp_pub_key,
5896 5899 &result1,
5897 5900 sizeof (BIG_CHUNK_TYPE) * (result1.len));
5898 5901 node_dhc->nlp_auth_misc.hrsp_pubkey_len =
5899 5902 (result1.len) * sizeof (BIG_CHUNK_TYPE);
5900 5903 }
5901 5904
5902 5905
5903 5906 if (ndlp->nlp_DID == FABRIC_DID) {
5904 5907 bcopy((void *)node_dhc->hrsp_pub_key, (void *)dhval,
5905 5908 node_dhc->hrsp_pubkey_len);
5906 5909 } else {
5907 5910 bcopy((void *)node_dhc->nlp_auth_misc.hrsp_pub_key,
5908 5911 (void *)dhval,
5909 5912 node_dhc->nlp_auth_misc.hrsp_pubkey_len);
5910 5913 }
5911 5914
5912 5915 *(uint32_t *)dhval_len = (result1.len) * sizeof (BIG_CHUNK_TYPE);
5913 5916
5914 5917
5915 5918 ret4:
5916 5919 big_finish(&result1);
5917 5920 ret3:
5918 5921 big_finish(&e);
5919 5922 ret2:
5920 5923 big_finish(&n);
5921 5924 ret1:
5922 5925 big_finish(&g);
5923 5926
5924 5927 return (err);
5925 5928
5926 5929 } /* emlxs_BIGNUM_get_dhval */
5927 5930
5928 5931
5929 5932 /*
5930 5933 * to get ((g^y mod p)^x mod p) a^e mod n
5931 5934 */
5932 5935 BIG_ERR_CODE
5933 5936 emlxs_BIGNUM_pubkey(
5934 5937 emlxs_port_t *port,
5935 5938 void *pubkey,
5936 5939 uint8_t *dhval, /* g^y mod p */
5937 5940 uint32_t dhvallen,
5938 5941 uint8_t *key, /* x */
5939 5942 uint32_t key_size,
5940 5943 uint32_t dhgp_id,
5941 5944 uint32_t *pubkeylen)
5942 5945 {
5943 5946 BIGNUM a, e, n, result;
5944 5947 uint32_t plen;
5945 5948 unsigned char *tmp = NULL;
5946 5949 BIG_ERR_CODE err = BIG_OK;
5947 5950
5948 5951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
5949 5952 "emlxs_BIGNUM_pubkey: dhvallen=0x%x dhgp_id=0x%x",
5950 5953 dhvallen, dhgp_id);
5951 5954
5952 5955 if (big_init(&a, CHARLEN2BIGNUMLEN(dhvallen)) != BIG_OK) {
5953 5956 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5954 5957 "emlxs_BIGNUM_pubkey: big_init failed. a size=%d",
5955 5958 CHARLEN2BIGNUMLEN(dhvallen));
5956 5959
5957 5960 err = BIG_NO_MEM;
5958 5961 return (err);
5959 5962 }
5960 5963 /* get g^y mod p */
5961 5964 bytestring2bignum(&a, (unsigned char *)dhval, dhvallen);
5962 5965
5963 5966 if (big_init(&e, CHARLEN2BIGNUMLEN(key_size)) != BIG_OK) {
5964 5967 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5965 5968 "emlxs_BIGNUM_pubkey: big_init failed. e size=%d",
5966 5969 CHARLEN2BIGNUMLEN(key_size));
5967 5970
5968 5971 err = BIG_NO_MEM;
5969 5972 goto ret1;
5970 5973 }
5971 5974 /* get x */
5972 5975 bytestring2bignum(&e, (unsigned char *)key, key_size);
5973 5976
5974 5977 switch (dhgp_id) {
5975 5978 case GROUP_1024:
5976 5979 plen = 128;
5977 5980 tmp = dhgp1_pVal;
5978 5981 break;
5979 5982
5980 5983 case GROUP_1280:
5981 5984 plen = 160;
5982 5985 tmp = dhgp2_pVal;
5983 5986 break;
5984 5987
5985 5988 case GROUP_1536:
5986 5989 plen = 192;
5987 5990 tmp = dhgp3_pVal;
5988 5991 break;
5989 5992
5990 5993 case GROUP_2048:
5991 5994 plen = 256;
5992 5995 tmp = dhgp4_pVal;
5993 5996 break;
5994 5997 }
5995 5998
5996 5999 if (big_init(&n, CHARLEN2BIGNUMLEN(plen)) != BIG_OK) {
5997 6000 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
5998 6001 "emlxs_BIGNUM_pubkey: big_init failed. n size=%d",
5999 6002 CHARLEN2BIGNUMLEN(plen));
6000 6003
6001 6004 err = BIG_NO_MEM;
6002 6005 goto ret2;
6003 6006 }
6004 6007 bytestring2bignum(&n, (unsigned char *)tmp, plen);
6005 6008
6006 6009 if (big_init(&result, CHARLEN2BIGNUMLEN(512)) != BIG_OK) {
6007 6010 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6008 6011 "emlxs_BIGNUM_pubkey: big_init failed. result size=%d",
6009 6012 CHARLEN2BIGNUMLEN(512));
6010 6013
6011 6014 err = BIG_NO_MEM;
6012 6015 goto ret3;
6013 6016 }
6014 6017 if (big_cmp_abs(&a, &n) > 0) {
6015 6018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6016 6019 "emlxs_BIGNUM_pubkey: big_cmp_abs error");
6017 6020
6018 6021 err = BIG_GENERAL_ERR;
6019 6022 goto ret4;
6020 6023 }
6021 6024 if (big_modexp(&result, &a, &e, &n, NULL) != BIG_OK) {
6022 6025 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6023 6026 "emlxs_BIGNUM_pubkey: big_modexp result error");
6024 6027
6025 6028 err = BIG_NO_MEM;
6026 6029 goto ret4;
6027 6030 }
6028 6031 bignum2bytestring(pubkey, &result,
6029 6032 sizeof (BIG_CHUNK_TYPE) * (result.len));
6030 6033 *pubkeylen = sizeof (BIG_CHUNK_TYPE) * (result.len);
6031 6034
6032 6035 /* This pubkey is actually session key */
6033 6036
6034 6037 ret4:
6035 6038 big_finish(&result);
6036 6039 ret3:
6037 6040 big_finish(&n);
6038 6041 ret2:
6039 6042 big_finish(&e);
6040 6043 ret1:
6041 6044 big_finish(&a);
6042 6045
6043 6046 return (err);
6044 6047
6045 6048 } /* emlxs_BIGNUM_pubkey */
6046 6049
6047 6050
6048 6051 /*
6049 6052 * key: x dhval: (g^y mod p) tran_id: Ti bi_cval: C2 hash_id: H dhgp_id: p/g
6050 6053 *
6051 6054 * Cai = H (C2 || ((g^y mod p)^x mod p) )
6052 6055 *
6053 6056 */
6054 6057 /* ARGSUSED */
6055 6058 BIG_ERR_CODE
6056 6059 emlxs_hash_Cai(
6057 6060 emlxs_port_t *port,
6058 6061 emlxs_port_dhc_t *port_dhc,
6059 6062 NODELIST *ndlp,
6060 6063 void *Cai,
6061 6064 uint32_t hash_id,
6062 6065 uint32_t dhgp_id,
6063 6066 uint32_t tran_id,
6064 6067 uint8_t *cval,
6065 6068 uint32_t cval_len,
6066 6069 uint8_t *key,
6067 6070 uint8_t *dhval,
6068 6071 uint32_t dhvallen)
6069 6072 {
6070 6073 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
6071 6074 MD5_CTX mdctx;
6072 6075 SHA1_CTX sha1ctx;
6073 6076 uint8_t sha1_digest[20];
6074 6077 uint8_t md5_digest[16];
6075 6078 uint8_t pubkey[512];
6076 6079 uint32_t pubkey_len = 0;
6077 6080 uint32_t key_size;
6078 6081 BIG_ERR_CODE err = BIG_OK;
6079 6082
6080 6083 key_size = cval_len;
6081 6084 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6082 6085 "emlxs_hash_Cai: 0x%x 0x%x 0x%x 0x%x 0x%x",
6083 6086 ndlp->nlp_DID, hash_id, dhgp_id, tran_id, dhvallen);
6084 6087
6085 6088 if (hash_id == AUTH_MD5) {
6086 6089 bzero(&mdctx, sizeof (MD5_CTX));
6087 6090 MD5Init(&mdctx);
6088 6091 MD5Update(&mdctx, (unsigned char *)cval, cval_len);
6089 6092
6090 6093 /* this pubkey obtained is actually the session key */
6091 6094 /*
6092 6095 * pubkey: ((g^y mod p)^x mod p)
6093 6096 */
6094 6097 err = emlxs_BIGNUM_pubkey(port, pubkey, dhval, dhvallen,
6095 6098 key, key_size, dhgp_id, &pubkey_len);
6096 6099
6097 6100 if (err != BIG_OK) {
6098 6101 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6099 6102 "emlxs_hash_Cai: MD5 BIGNUM_pubkey error: 0x%x",
6100 6103 err);
6101 6104
6102 6105 err = BIG_GENERAL_ERR;
6103 6106 return (err);
6104 6107 }
6105 6108 if (pubkey_len == 0) {
6106 6109 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6107 6110 "emlxs_hash_Cai: MD5 BIGNUM_pubkey error: len=0");
6108 6111
6109 6112 err = BIG_GENERAL_ERR;
6110 6113 return (err);
6111 6114 }
6112 6115 if (ndlp->nlp_DID == FABRIC_DID) {
6113 6116 bcopy((void *)pubkey,
6114 6117 (void *)node_dhc->hrsp_ses_key, pubkey_len);
6115 6118 node_dhc->hrsp_seskey_len = pubkey_len;
6116 6119
6117 6120 /* store extra copy */
6118 6121 bcopy((void *)pubkey,
6119 6122 (void *)node_dhc->nlp_auth_misc.hrsp_ses_key,
6120 6123 pubkey_len);
6121 6124 node_dhc->nlp_auth_misc.hrsp_seskey_len = pubkey_len;
6122 6125
6123 6126 } else {
6124 6127 bcopy((void *)pubkey,
6125 6128 (void *)node_dhc->nlp_auth_misc.hrsp_ses_key,
6126 6129 pubkey_len);
6127 6130 node_dhc->nlp_auth_misc.hrsp_seskey_len = pubkey_len;
6128 6131 }
6129 6132
6130 6133 MD5Update(&mdctx, (unsigned char *)pubkey, pubkey_len);
6131 6134 MD5Final((uint8_t *)md5_digest, &mdctx);
6132 6135 bcopy((void *)&md5_digest, (void *)Cai, MD5_LEN);
6133 6136 }
6134 6137 if (hash_id == AUTH_SHA1) {
6135 6138 bzero(&sha1ctx, sizeof (SHA1_CTX));
6136 6139 SHA1Init(&sha1ctx);
6137 6140
6138 6141 SHA1Update(&sha1ctx, (void *)cval, cval_len);
6139 6142
6140 6143 err = emlxs_BIGNUM_pubkey(port, pubkey, dhval, dhvallen,
6141 6144 key, key_size, dhgp_id, &pubkey_len);
6142 6145
6143 6146 if (err != BIG_OK) {
6144 6147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6145 6148 "emlxs_hash_Cai: SHA1 BIGNUM_pubkey error: 0x%x",
6146 6149 err);
6147 6150
6148 6151 err = BIG_GENERAL_ERR;
6149 6152 return (err);
6150 6153 }
6151 6154 if (pubkey_len == 0) {
6152 6155 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6153 6156 "emlxs_hash_Cai: SA1 BUM_pubkey error: key_len=0");
6154 6157
6155 6158 err = BIG_GENERAL_ERR;
6156 6159 return (err);
6157 6160 }
6158 6161 if (ndlp->nlp_DID == FABRIC_DID) {
6159 6162 bcopy((void *)pubkey,
6160 6163 (void *)node_dhc->hrsp_ses_key,
6161 6164 pubkey_len);
6162 6165 node_dhc->hrsp_seskey_len = pubkey_len;
6163 6166
6164 6167 /* store extra copy */
6165 6168 bcopy((void *)pubkey,
6166 6169 (void *)node_dhc->nlp_auth_misc.hrsp_ses_key,
6167 6170 pubkey_len);
6168 6171 node_dhc->nlp_auth_misc.hrsp_seskey_len = pubkey_len;
6169 6172
6170 6173 } else {
6171 6174 bcopy((void *)pubkey,
6172 6175 (void *)node_dhc->nlp_auth_misc.hrsp_ses_key,
6173 6176 pubkey_len);
6174 6177 node_dhc->nlp_auth_misc.hrsp_seskey_len = pubkey_len;
6175 6178 }
6176 6179
6177 6180 SHA1Update(&sha1ctx, (void *)pubkey, pubkey_len);
6178 6181 SHA1Final((void *)sha1_digest, &sha1ctx);
6179 6182 bcopy((void *)&sha1_digest, (void *)Cai, SHA1_LEN);
6180 6183 }
6181 6184 return (err);
6182 6185
6183 6186 } /* emlxs_hash_Cai */
6184 6187
6185 6188
6186 6189 /*
6187 6190 * This routine is to verify the DHCHAP_Reply from initiator by the host
6188 6191 * as the responder.
6189 6192 *
6190 6193 * flag: 1: if host is the responder 0: if host is the initiator
6191 6194 *
6192 6195 * if bi_cval != NULL, this routine is used to calculate the response based
6193 6196 * on the challenge from initiator as part of
6194 6197 * DHCHAP_Reply for bi-dirctional authentication.
6195 6198 *
6196 6199 */
6197 6200 /* ARGSUSED */
6198 6201 static uint32_t *
6199 6202 emlxs_hash_verification(
6200 6203 emlxs_port_t *port,
6201 6204 emlxs_port_dhc_t *port_dhc,
6202 6205 NODELIST *ndlp,
6203 6206 uint32_t tran_id,
6204 6207 uint8_t *dhval,
6205 6208 uint32_t dhval_len,
6206 6209 uint32_t flag, /* always 1 for now */
6207 6210 uint8_t *bi_cval)
6208 6211 { /* always 0 for now */
6209 6212 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
6210 6213 uint32_t dhgp_id;
6211 6214 uint32_t hash_id;
6212 6215 uint32_t *hash_val = NULL;
6213 6216 uint32_t hash_size;
6214 6217 MD5_CTX mdctx;
6215 6218 SHA1_CTX sha1ctx;
6216 6219 uint8_t sha1_digest[20];
6217 6220 uint8_t md5_digest[16];
6218 6221 uint8_t Cai[20];
6219 6222 /* union challenge_val un_cval; */
6220 6223 uint8_t key[20];
6221 6224 uint8_t cval[20];
6222 6225 uint32_t cval_len;
6223 6226 uint8_t mytran_id = 0x00;
6224 6227 char *remote_key;
6225 6228 BIG_ERR_CODE err = BIG_OK;
6226 6229
6227 6230 tran_id = (AUTH_TRAN_ID_MASK & tran_id);
6228 6231 mytran_id = (uint8_t)(LE_SWAP32(tran_id));
6229 6232
6230 6233 if (ndlp->nlp_DID == FABRIC_DID) {
6231 6234 remote_key = (char *)node_dhc->auth_key.remote_password;
6232 6235 } else {
6233 6236 /*
6234 6237 * in case of end-to-end auth, this remote password should be
6235 6238 * the password associated with the remote entity. (i.e.,)
6236 6239 * for now it is actually local_password.
6237 6240 */
6238 6241 remote_key = (char *)node_dhc->auth_key.remote_password;
6239 6242 }
6240 6243
6241 6244 if (flag == 0) {
6242 6245 dhgp_id = node_dhc->dhgp_id;
6243 6246 hash_id = node_dhc->hash_id;
6244 6247 } else {
6245 6248 dhgp_id = node_dhc->nlp_auth_dhgpid;
6246 6249 hash_id = node_dhc->nlp_auth_hashid;
6247 6250 }
6248 6251
6249 6252 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6250 6253 "emlxs_hash_verification: 0x%x 0x%x hash_id=0x%x dhgp_id=0x%x",
6251 6254 ndlp->nlp_DID, mytran_id, hash_id, dhgp_id);
6252 6255
6253 6256 if (dhval_len == 0) {
6254 6257 /* NULL DHCHAP group */
6255 6258 if (hash_id == AUTH_MD5) {
6256 6259 bzero(&mdctx, sizeof (MD5_CTX));
6257 6260 hash_size = MD5_LEN;
6258 6261 MD5Init(&mdctx);
6259 6262
6260 6263 MD5Update(&mdctx, (unsigned char *)&mytran_id, 1);
6261 6264
6262 6265 if (ndlp->nlp_DID == FABRIC_DID) {
6263 6266 MD5Update(&mdctx,
6264 6267 (unsigned char *)remote_key,
6265 6268 node_dhc->auth_key.remote_password_length);
6266 6269 } else {
6267 6270 MD5Update(&mdctx,
6268 6271 (unsigned char *)remote_key,
6269 6272 node_dhc->auth_key.remote_password_length);
6270 6273 }
6271 6274
6272 6275 if (ndlp->nlp_DID == FABRIC_DID) {
6273 6276 MD5Update(&mdctx,
6274 6277 (unsigned char *)&node_dhc->hrsp_cval[0],
6275 6278 MD5_LEN);
6276 6279 } else {
6277 6280 MD5Update(&mdctx,
6278 6281 (unsigned char *)&node_dhc->nlp_auth_misc.hrsp_cval[0],
6279 6282 MD5_LEN);
6280 6283 }
6281 6284
6282 6285 MD5Final((uint8_t *)md5_digest, &mdctx);
6283 6286
6284 6287 hash_val = (uint32_t *)kmem_alloc(hash_size,
6285 6288 KM_NOSLEEP);
6286 6289 if (hash_val == NULL) {
6287 6290 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6288 6291 "emlxs_hash_verification: alloc failed");
6289 6292
6290 6293 return (NULL);
6291 6294 } else {
6292 6295 bcopy((void *)md5_digest,
6293 6296 (void *)hash_val, MD5_LEN);
6294 6297 }
6295 6298 }
6296 6299 if (hash_id == AUTH_SHA1) {
6297 6300 bzero(&sha1ctx, sizeof (SHA1_CTX));
6298 6301 hash_size = SHA1_LEN;
6299 6302 SHA1Init(&sha1ctx);
6300 6303 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
6301 6304
6302 6305 if (ndlp->nlp_DID == FABRIC_DID) {
6303 6306 SHA1Update(&sha1ctx, (void *)remote_key,
6304 6307 node_dhc->auth_key.remote_password_length);
6305 6308 } else {
6306 6309 SHA1Update(&sha1ctx, (void *)remote_key,
6307 6310 node_dhc->auth_key.remote_password_length);
6308 6311 }
6309 6312
6310 6313 if (ndlp->nlp_DID == FABRIC_DID) {
6311 6314 SHA1Update(&sha1ctx,
6312 6315 (void *)&node_dhc->hrsp_cval[0],
6313 6316 SHA1_LEN);
6314 6317 } else {
6315 6318 SHA1Update(&sha1ctx,
6316 6319 (void *)&node_dhc->nlp_auth_misc.hrsp_cval[0],
6317 6320 SHA1_LEN);
6318 6321 }
6319 6322
6320 6323 SHA1Final((void *)sha1_digest, &sha1ctx);
6321 6324 hash_val = (uint32_t *)kmem_zalloc(hash_size,
6322 6325 KM_NOSLEEP);
6323 6326 if (hash_val == NULL) {
6324 6327 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6325 6328 "emlxs_hash_verification: alloc failed");
6326 6329
6327 6330 return (NULL);
6328 6331 } else {
6329 6332 bcopy((void *)sha1_digest,
6330 6333 (void *)hash_val, SHA1_LEN);
6331 6334 }
6332 6335 }
6333 6336 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6334 6337 "emlxs_hash_verification: hash_val=0x%x",
6335 6338 *(uint32_t *)hash_val);
6336 6339
6337 6340 return ((uint32_t *)hash_val);
6338 6341 } else {
6339 6342
6340 6343 /* DHCHAP group 1,2,3,4 */
6341 6344 /*
6342 6345 * host received (g^x mod p) as dhval host has its own
6343 6346 * private key y as node_dhc->hrsp_priv_key[] host has its
6344 6347 * original challenge c as node_dhc->hrsp_cval[]
6345 6348 *
6346 6349 * H(c || (g^x mod p)^y mod p) = Cai H(Ti || Km || Cai) =
6347 6350 * hash_val returned. Ti : tran_id, Km : shared secret, Cai:
6348 6351 * obtained above.
6349 6352 */
6350 6353 if (hash_id == AUTH_MD5) {
6351 6354 if (ndlp->nlp_DID == FABRIC_DID) {
6352 6355 bcopy((void *)node_dhc->hrsp_priv_key,
6353 6356 (void *)key, MD5_LEN);
6354 6357 } else {
6355 6358 bcopy(
6356 6359 (void *)node_dhc->nlp_auth_misc.hrsp_priv_key,
6357 6360 (void *)key, MD5_LEN);
6358 6361 }
6359 6362 }
6360 6363 if (hash_id == AUTH_SHA1) {
6361 6364 if (ndlp->nlp_DID == FABRIC_DID) {
6362 6365 bcopy((void *)node_dhc->hrsp_priv_key,
6363 6366 (void *)key, SHA1_LEN);
6364 6367 } else {
6365 6368 bcopy(
6366 6369 (void *)node_dhc->nlp_auth_misc.hrsp_priv_key,
6367 6370 (void *)key, SHA1_LEN);
6368 6371 }
6369 6372 }
6370 6373 if (ndlp->nlp_DID == FABRIC_DID) {
6371 6374 bcopy((void *)node_dhc->hrsp_cval,
6372 6375 (void *)cval, node_dhc->hrsp_cval_len);
6373 6376 cval_len = node_dhc->hrsp_cval_len;
6374 6377 } else {
6375 6378 bcopy((void *)node_dhc->nlp_auth_misc.hrsp_cval,
6376 6379 (void *)cval,
6377 6380 node_dhc->nlp_auth_misc.hrsp_cval_len);
6378 6381 cval_len = node_dhc->nlp_auth_misc.hrsp_cval_len;
6379 6382 }
6380 6383
6381 6384 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6382 6385 "emlxs_hash_verification: N-Null gp. 0x%x 0x%x",
6383 6386 ndlp->nlp_DID, cval_len);
6384 6387
6385 6388 err = emlxs_hash_Cai(port, port_dhc, ndlp, (void *)Cai,
6386 6389 hash_id, dhgp_id,
6387 6390 tran_id, cval, cval_len,
6388 6391 key, dhval, dhval_len);
6389 6392
6390 6393 if (err != BIG_OK) {
6391 6394 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6392 6395 "emlxs_hash_verification: Cai error. ret=0x%x",
6393 6396 err);
6394 6397
6395 6398 return (NULL);
6396 6399 }
6397 6400 if (hash_id == AUTH_MD5) {
6398 6401 bzero(&mdctx, sizeof (MD5_CTX));
6399 6402 hash_size = MD5_LEN;
6400 6403
6401 6404 MD5Init(&mdctx);
6402 6405 MD5Update(&mdctx, (unsigned char *)&mytran_id, 1);
6403 6406
6404 6407 if (ndlp->nlp_DID == FABRIC_DID) {
6405 6408 MD5Update(&mdctx,
6406 6409 (unsigned char *)remote_key,
6407 6410 node_dhc->auth_key.remote_password_length);
6408 6411 } else {
6409 6412 MD5Update(&mdctx,
6410 6413 (unsigned char *)remote_key,
6411 6414 node_dhc->auth_key.remote_password_length);
6412 6415 }
6413 6416
6414 6417 MD5Update(&mdctx, (unsigned char *)Cai, MD5_LEN);
6415 6418 MD5Final((uint8_t *)md5_digest, &mdctx);
6416 6419
6417 6420 hash_val = (uint32_t *)kmem_zalloc(hash_size,
6418 6421 KM_NOSLEEP);
6419 6422 if (hash_val == NULL) {
6420 6423 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6421 6424 "emlxs_hash_vf: alloc failed(Non-NULL dh)");
6422 6425
6423 6426 return (NULL);
6424 6427 } else {
6425 6428 bcopy((void *)&md5_digest,
6426 6429 (void *)hash_val, MD5_LEN);
6427 6430 }
6428 6431 }
6429 6432 if (hash_id == AUTH_SHA1) {
6430 6433 bzero(&sha1ctx, sizeof (SHA1_CTX));
6431 6434 hash_size = SHA1_LEN;
6432 6435
6433 6436 SHA1Init(&sha1ctx);
6434 6437 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
6435 6438
6436 6439 if (ndlp->nlp_DID == FABRIC_DID) {
6437 6440 SHA1Update(&sha1ctx, (void *)remote_key,
6438 6441 node_dhc->auth_key.remote_password_length);
6439 6442 } else {
6440 6443 SHA1Update(&sha1ctx, (void *)remote_key,
6441 6444 node_dhc->auth_key.remote_password_length);
6442 6445 }
6443 6446
6444 6447 SHA1Update(&sha1ctx, (void *)Cai, SHA1_LEN);
6445 6448 SHA1Final((void *)sha1_digest, &sha1ctx);
6446 6449
6447 6450 hash_val = (uint32_t *)kmem_zalloc(hash_size,
6448 6451 KM_NOSLEEP);
6449 6452 if (hash_val == NULL) {
6450 6453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6451 6454 "emlxs_hash_vf: val alloc failed (Non-NULL dh)");
6452 6455
6453 6456 return (NULL);
6454 6457 } else {
6455 6458 bcopy((void *)&sha1_digest,
6456 6459 (void *)hash_val, SHA1_LEN);
6457 6460 }
6458 6461 }
6459 6462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6460 6463 "emlxs_hash_verification: hash_val=0x%x",
6461 6464 *(uint32_t *)hash_val);
6462 6465
6463 6466 return ((uint32_t *)hash_val);
6464 6467 }
6465 6468
6466 6469 } /* emlxs_hash_verification */
6467 6470
6468 6471
6469 6472
6470 6473 /*
6471 6474 * When DHCHAP_Success msg was sent from responder to the initiator,
6472 6475 * with bi-directional authentication requested, the
6473 6476 * DHCHAP_Success contains the response R2 to the challenge C2 received.
6474 6477 *
6475 6478 * DHCHAP response R2: The value of R2 is computed using the hash function
6476 6479 * H() selected by the HashID parameter of the
6477 6480 * DHCHAP_Challenge msg, and the augmented challenge Ca2.
6478 6481 *
6479 6482 * NULL DH group: Ca2 = C2 Non NULL DH group: Ca2 = H(C2 ||
6480 6483 * (g^y mod p)^x mod p)) x is selected by the authentication responder
6481 6484 * which is the node_dhc->hrsp_priv_key[] (g^y mod p) is dhval received
6482 6485 * from authentication initiator.
6483 6486 *
6484 6487 * R2 = H(Ti || Km || Ca2) Ti is the least significant byte of the
6485 6488 * transaction id. Km is the secret associated with the
6486 6489 * authentication responder.
6487 6490 *
6488 6491 * emlxs_hash_get_R2 and emlxs_hash_verification could be mergerd into one
6489 6492 * function later.
6490 6493 *
6491 6494 */
6492 6495 static uint32_t *
6493 6496 emlxs_hash_get_R2(
6494 6497 emlxs_port_t *port,
6495 6498 emlxs_port_dhc_t *port_dhc,
6496 6499 NODELIST *ndlp,
6497 6500 uint32_t tran_id,
6498 6501 uint8_t *dhval,
6499 6502 uint32_t dhval_len,
6500 6503 uint32_t flag, /* flag 1 rsponder or 0 initiator */
6501 6504 uint8_t *bi_cval)
6502 6505 {
6503 6506 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
6504 6507
6505 6508 uint32_t dhgp_id;
6506 6509 uint32_t hash_id;
6507 6510 uint32_t *hash_val = NULL;
6508 6511 uint32_t hash_size;
6509 6512 MD5_CTX mdctx;
6510 6513 SHA1_CTX sha1ctx;
6511 6514 uint8_t sha1_digest[20];
6512 6515 uint8_t md5_digest[16];
6513 6516 uint8_t Cai[20];
6514 6517 /* union challenge_val un_cval; */
6515 6518 uint8_t key[20];
6516 6519 uint32_t cval_len;
6517 6520 uint8_t mytran_id = 0x00;
6518 6521
6519 6522 char *mykey;
6520 6523 BIG_ERR_CODE err = BIG_OK;
6521 6524
6522 6525 if (ndlp->nlp_DID == FABRIC_DID) {
6523 6526 dhgp_id = node_dhc->nlp_auth_dhgpid;
6524 6527 hash_id = node_dhc->nlp_auth_hashid;
6525 6528 } else {
6526 6529 if (flag == 0) {
6527 6530 dhgp_id = node_dhc->dhgp_id;
6528 6531 hash_id = node_dhc->hash_id;
6529 6532 } else {
6530 6533 dhgp_id = node_dhc->nlp_auth_dhgpid;
6531 6534 hash_id = node_dhc->nlp_auth_hashid;
6532 6535 }
6533 6536 }
6534 6537
6535 6538 tran_id = (AUTH_TRAN_ID_MASK & tran_id);
6536 6539 mytran_id = (uint8_t)(LE_SWAP32(tran_id));
6537 6540
6538 6541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_detail_msg,
6539 6542 "emlxs_hash_get_R2:0x%x 0x%x dhgp_id=0x%x mytran_id=0x%x",
6540 6543 ndlp->nlp_DID, hash_id, dhgp_id, mytran_id);
6541 6544
6542 6545 if (ndlp->nlp_DID == FABRIC_DID) {
6543 6546 mykey = (char *)node_dhc->auth_key.local_password;
6544 6547
6545 6548 } else {
6546 6549 /* in case of end-to-end mykey should be remote_password */
6547 6550 mykey = (char *)node_dhc->auth_key.remote_password;
6548 6551 }
6549 6552
6550 6553 if (dhval_len == 0) {
6551 6554 /* NULL DHCHAP group */
6552 6555 if (hash_id == AUTH_MD5) {
6553 6556 bzero(&mdctx, sizeof (MD5_CTX));
6554 6557 hash_size = MD5_LEN;
6555 6558 MD5Init(&mdctx);
6556 6559
6557 6560 MD5Update(&mdctx, (unsigned char *)&mytran_id, 1);
6558 6561
6559 6562 if (ndlp->nlp_DID == FABRIC_DID) {
6560 6563 MD5Update(&mdctx, (unsigned char *)mykey,
6561 6564 node_dhc->auth_key.local_password_length);
6562 6565 } else {
6563 6566 MD5Update(&mdctx, (unsigned char *)mykey,
6564 6567 node_dhc->auth_key.remote_password_length);
6565 6568 }
6566 6569
6567 6570 MD5Update(&mdctx, (unsigned char *)bi_cval, MD5_LEN);
6568 6571
6569 6572 MD5Final((uint8_t *)md5_digest, &mdctx);
6570 6573
6571 6574 hash_val = (uint32_t *)kmem_alloc(hash_size,
6572 6575 KM_NOSLEEP);
6573 6576 if (hash_val == NULL) {
6574 6577 return (NULL);
6575 6578 } else {
6576 6579 bcopy((void *)md5_digest,
6577 6580 (void *)hash_val, MD5_LEN);
6578 6581 }
6579 6582 }
6580 6583 if (hash_id == AUTH_SHA1) {
6581 6584 bzero(&sha1ctx, sizeof (SHA1_CTX));
6582 6585 hash_size = SHA1_LEN;
6583 6586 SHA1Init(&sha1ctx);
6584 6587 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
6585 6588
6586 6589 if (ndlp->nlp_DID == FABRIC_DID) {
6587 6590 SHA1Update(&sha1ctx, (void *)mykey,
6588 6591 node_dhc->auth_key.local_password_length);
6589 6592 } else {
6590 6593 SHA1Update(&sha1ctx, (void *)mykey,
6591 6594 node_dhc->auth_key.remote_password_length);
6592 6595 }
6593 6596
6594 6597 SHA1Update(&sha1ctx, (void *)bi_cval, SHA1_LEN);
6595 6598 SHA1Final((void *)sha1_digest, &sha1ctx);
6596 6599 hash_val = (uint32_t *)kmem_alloc(hash_size,
6597 6600 KM_NOSLEEP);
6598 6601 if (hash_val == NULL) {
6599 6602 return (NULL);
6600 6603 } else {
6601 6604 bcopy((void *)sha1_digest,
6602 6605 (void *)hash_val, SHA1_LEN);
6603 6606 }
6604 6607 }
6605 6608 } else {
6606 6609 /* NON-NULL DHCHAP */
6607 6610 if (ndlp->nlp_DID == FABRIC_DID) {
6608 6611 if (hash_id == AUTH_MD5) {
6609 6612 bcopy((void *)node_dhc->hrsp_priv_key,
6610 6613 (void *)key, MD5_LEN);
6611 6614 }
6612 6615 if (hash_id == AUTH_SHA1) {
6613 6616 bcopy((void *)node_dhc->hrsp_priv_key,
6614 6617 (void *)key, SHA1_LEN);
6615 6618 }
6616 6619 cval_len = node_dhc->hrsp_cval_len;
6617 6620 } else {
6618 6621 if (hash_id == AUTH_MD5) {
6619 6622 bcopy(
6620 6623 (void *)node_dhc->nlp_auth_misc.hrsp_priv_key,
6621 6624 (void *)key, MD5_LEN);
6622 6625 }
6623 6626 if (hash_id == AUTH_SHA1) {
6624 6627 bcopy(
6625 6628 (void *)node_dhc->nlp_auth_misc.hrsp_priv_key,
6626 6629 (void *)key, SHA1_LEN);
6627 6630 }
6628 6631 cval_len = node_dhc->nlp_auth_misc.hrsp_cval_len;
6629 6632 }
6630 6633
6631 6634 /* use bi_cval here */
6632 6635 /*
6633 6636 * key: x dhval: (g^y mod p) tran_id: Ti bi_cval: C2 hash_id:
6634 6637 * H dhgp_id: p/g
6635 6638 *
6636 6639 * Cai = H (C2 || ((g^y mod p)^x mod p) )
6637 6640 *
6638 6641 * R2 = H (Ti || Km || Cai)
6639 6642 */
6640 6643 err = emlxs_hash_Cai(port, port_dhc, ndlp, (void *)Cai,
6641 6644 hash_id, dhgp_id, tran_id, bi_cval, cval_len,
6642 6645 key, dhval, dhval_len);
6643 6646
6644 6647 if (err != BIG_OK) {
6645 6648 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6646 6649 "emlxs_hash_get_R2: emlxs_hash_Cai error. ret=0x%x",
6647 6650 err);
6648 6651
6649 6652 return (NULL);
6650 6653 }
6651 6654 if (hash_id == AUTH_MD5) {
6652 6655 bzero(&mdctx, sizeof (MD5_CTX));
6653 6656 hash_size = MD5_LEN;
6654 6657
6655 6658 MD5Init(&mdctx);
6656 6659 MD5Update(&mdctx, (unsigned char *) &mytran_id, 1);
6657 6660
6658 6661 /*
6659 6662 * Here we use the same key: mykey, note: this mykey
6660 6663 * should be the key associated with the
6661 6664 * authentication responder i.e. the remote key.
6662 6665 */
6663 6666 if (ndlp->nlp_DID == FABRIC_DID)
6664 6667 MD5Update(&mdctx, (unsigned char *)mykey,
6665 6668 node_dhc->auth_key.local_password_length);
6666 6669 else
6667 6670 MD5Update(&mdctx, (unsigned char *)mykey,
6668 6671 node_dhc->auth_key.remote_password_length);
6669 6672
6670 6673 MD5Update(&mdctx, (unsigned char *)Cai, MD5_LEN);
6671 6674 MD5Final((uint8_t *)md5_digest, &mdctx);
6672 6675
6673 6676 hash_val = (uint32_t *)kmem_alloc(hash_size,
6674 6677 KM_NOSLEEP);
6675 6678 if (hash_val == NULL) {
6676 6679 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6677 6680 "emlxs_hash_get_R2: hash_val MD5 alloc failed.");
6678 6681
6679 6682 return (NULL);
6680 6683 } else {
6681 6684 bcopy((void *)md5_digest,
6682 6685 (void *)hash_val, MD5_LEN);
6683 6686 }
6684 6687 }
6685 6688 if (hash_id == AUTH_SHA1) {
6686 6689 bzero(&sha1ctx, sizeof (SHA1_CTX));
6687 6690 hash_size = SHA1_LEN;
6688 6691
6689 6692 SHA1Init(&sha1ctx);
6690 6693 SHA1Update(&sha1ctx, (void *)&mytran_id, 1);
6691 6694
6692 6695 if (ndlp->nlp_DID == FABRIC_DID) {
6693 6696 SHA1Update(&sha1ctx, (void *)mykey,
6694 6697 node_dhc->auth_key.local_password_length);
6695 6698 } else {
6696 6699 SHA1Update(&sha1ctx, (void *)mykey,
6697 6700 node_dhc->auth_key.remote_password_length);
6698 6701 }
6699 6702
6700 6703 SHA1Update(&sha1ctx, (void *)Cai, SHA1_LEN);
6701 6704 SHA1Final((void *)sha1_digest, &sha1ctx);
6702 6705
6703 6706 hash_val = (uint32_t *)kmem_alloc(hash_size,
6704 6707 KM_NOSLEEP);
6705 6708 if (hash_val == NULL) {
6706 6709 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_error_msg,
6707 6710 "emlxs_hash_get_R2: hash_val SHA1 alloc failed.");
6708 6711
6709 6712 return (NULL);
6710 6713 } else {
6711 6714 bcopy((void *)sha1_digest,
6712 6715 (void *)hash_val, SHA1_LEN);
6713 6716 }
6714 6717 }
6715 6718 }
6716 6719
6717 6720 return ((uint32_t *)hash_val);
6718 6721
6719 6722 } /* emlxs_hash_get_R2 */
6720 6723
6721 6724
6722 6725
6723 6726 /*
6724 6727 */
6725 6728 static void
6726 6729 emlxs_log_auth_event(
6727 6730 emlxs_port_t *port,
6728 6731 NODELIST *ndlp,
6729 6732 char *subclass,
6730 6733 char *info)
6731 6734 {
6732 6735 emlxs_hba_t *hba = HBA;
6733 6736 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
6734 6737 nvlist_t *attr_list = NULL;
6735 6738 dev_info_t *dip = hba->dip;
6736 6739 emlxs_auth_cfg_t *auth_cfg;
6737 6740 char *tmp = "No_more_logging_information_available";
6738 6741
6739 6742 uint8_t lwwn[8];
6740 6743 uint8_t rwwn[8];
6741 6744 char *lwwn_tmp = NULL;
6742 6745 char *rwwn_tmp = NULL;
6743 6746 char *mytmp_lwwn, *mytmp_rwwn;
6744 6747 int i;
6745 6748
6746 6749 auth_cfg = &(node_dhc->auth_cfg);
6747 6750
6748 6751 if (info == NULL) {
6749 6752 info = tmp;
6750 6753 }
6751 6754 bcopy((void *) &auth_cfg->local_entity, (void *)lwwn, 8);
6752 6755 lwwn_tmp = (char *)kmem_zalloc(32, KM_NOSLEEP);
6753 6756 if (lwwn_tmp == NULL) {
6754 6757 return;
6755 6758 }
6756 6759 mytmp_lwwn = lwwn_tmp;
6757 6760
6758 6761 for (i = 0; i < 8; i++) {
6759 6762 lwwn_tmp = (char *)sprintf((char *)lwwn_tmp, "%02X", lwwn[i]);
6760 6763 lwwn_tmp += 2;
6761 6764 }
6762 6765 mytmp_lwwn[16] = '\0';
6763 6766
6764 6767 bcopy((void *)&auth_cfg->remote_entity, (void *)rwwn, 8);
6765 6768 rwwn_tmp = (char *)kmem_zalloc(32, KM_NOSLEEP);
6766 6769
6767 6770 mytmp_rwwn = rwwn_tmp;
6768 6771
6769 6772 if (rwwn_tmp == NULL) {
6770 6773 kmem_free(mytmp_lwwn, 32);
6771 6774 return;
6772 6775 }
6773 6776 for (i = 0; i < 8; i++) {
6774 6777 rwwn_tmp = (char *)sprintf((char *)rwwn_tmp, "%02X", rwwn[i]);
6775 6778 rwwn_tmp += 2;
6776 6779 }
6777 6780 mytmp_rwwn[16] = '\0';
6778 6781
6779 6782 if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, KM_NOSLEEP)
6780 6783 == DDI_SUCCESS) {
6781 6784 if ((nvlist_add_uint32(attr_list, "instance",
6782 6785 ddi_get_instance(dip)) == DDI_SUCCESS) &&
6783 6786 (nvlist_add_string(attr_list, "lwwn",
6784 6787 (char *)mytmp_lwwn) == DDI_SUCCESS) &&
6785 6788 (nvlist_add_string(attr_list, "rwwn",
6786 6789 (char *)mytmp_rwwn) == DDI_SUCCESS) &&
6787 6790 (nvlist_add_string(attr_list, "Info",
6788 6791 info) == DDI_SUCCESS) &&
6789 6792 (nvlist_add_string(attr_list, "Class",
6790 6793 "EC_emlx") == DDI_SUCCESS) &&
6791 6794 (nvlist_add_string(attr_list, "SubClass",
6792 6795 subclass) == DDI_SUCCESS)) {
6793 6796
6794 6797 (void) ddi_log_sysevent(dip,
6795 6798 DDI_VENDOR_EMLX,
6796 6799 EC_EMLXS,
6797 6800 subclass,
6798 6801 attr_list,
6799 6802 NULL,
6800 6803 DDI_NOSLEEP);
6801 6804 }
6802 6805 nvlist_free(attr_list);
6803 6806 attr_list = NULL;
6804 6807 }
6805 6808 kmem_free(mytmp_lwwn, 32);
6806 6809 kmem_free(mytmp_rwwn, 32);
6807 6810
6808 6811 return;
6809 6812
6810 6813 } /* emlxs_log_auth_event() */
6811 6814
6812 6815
6813 6816 /* **************************** AUTH DHC INTERFACE ************************* */
6814 6817
6815 6818 extern int
6816 6819 emlxs_dhc_auth_start(
6817 6820 emlxs_port_t *port,
6818 6821 emlxs_node_t *ndlp,
6819 6822 uint8_t *deferred_sbp,
6820 6823 uint8_t *deferred_ubp)
6821 6824 {
6822 6825 emlxs_hba_t *hba = HBA;
6823 6826 emlxs_config_t *cfg = &CFG;
6824 6827 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
6825 6828 emlxs_auth_cfg_t *auth_cfg;
6826 6829 emlxs_auth_key_t *auth_key;
6827 6830 uint32_t i;
6828 6831 uint32_t fabric;
6829 6832 uint32_t fabric_switch;
6830 6833
6831 6834 /* The ubp represents an unsolicted PLOGI */
6832 6835 /* The sbp represents a solicted PLOGI */
6833 6836
6834 6837 fabric = ((ndlp->nlp_DID & FABRIC_DID_MASK) == FABRIC_DID_MASK) ? 1 : 0;
6835 6838 fabric_switch = ((ndlp->nlp_DID == FABRIC_DID) ? 1 : 0);
6836 6839
6837 6840 /* Return is authentication is not enabled */
6838 6841 if (cfg[CFG_AUTH_ENABLE].current == 0) {
6839 6842 EMLXS_MSGF(EMLXS_CONTEXT,
6840 6843 &emlxs_fcsp_start_msg,
6841 6844 "Not started. Auth disabled. did=0x%x", ndlp->nlp_DID);
6842 6845
6843 6846 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6844 6847
6845 6848 return (1);
6846 6849 }
6847 6850 if (port->vpi != 0 && cfg[CFG_AUTH_NPIV].current == 0) {
6848 6851 EMLXS_MSGF(EMLXS_CONTEXT,
6849 6852 &emlxs_fcsp_start_msg,
6850 6853 "Not started. NPIV auth disabled. did=0x%x", ndlp->nlp_DID);
6851 6854
6852 6855 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6853 6856
6854 6857 return (1);
6855 6858 }
6856 6859 if (!fabric_switch && fabric) {
6857 6860 EMLXS_MSGF(EMLXS_CONTEXT,
6858 6861 &emlxs_fcsp_start_msg,
6859 6862 "Not started. FS auth disabled. did=0x%x", ndlp->nlp_DID);
6860 6863
6861 6864 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6862 6865
6863 6866 return (1);
6864 6867 }
6865 6868 /* Return if fcsp support to this node is not enabled */
6866 6869 if (!fabric_switch && cfg[CFG_AUTH_E2E].current == 0) {
6867 6870 EMLXS_MSGF(EMLXS_CONTEXT,
6868 6871 &emlxs_fcsp_start_msg,
6869 6872 "Not started. E2E auth disabled. did=0x%x", ndlp->nlp_DID);
6870 6873
6871 6874 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6872 6875
6873 6876 return (1);
6874 6877 }
6875 6878 if ((deferred_sbp && node_dhc->deferred_sbp) ||
6876 6879 (deferred_ubp && node_dhc->deferred_ubp)) {
6877 6880 /* Clear previous authentication */
6878 6881 emlxs_dhc_auth_stop(port, ndlp);
6879 6882 }
6880 6883 mutex_enter(&hba->auth_lock);
6881 6884
6882 6885 /* Intialize node */
6883 6886 node_dhc->parent_auth_cfg = NULL;
6884 6887 node_dhc->parent_auth_key = NULL;
6885 6888
6886 6889 /* Acquire auth configuration */
6887 6890 if (fabric_switch) {
6888 6891 auth_cfg = emlxs_auth_cfg_find(port,
6889 6892 (uint8_t *)emlxs_fabric_wwn);
6890 6893 auth_key = emlxs_auth_key_find(port,
6891 6894 (uint8_t *)emlxs_fabric_wwn);
6892 6895 } else {
6893 6896 auth_cfg = emlxs_auth_cfg_find(port,
6894 6897 (uint8_t *)&ndlp->nlp_portname);
6895 6898 auth_key = emlxs_auth_key_find(port,
6896 6899 (uint8_t *)&ndlp->nlp_portname);
6897 6900 }
6898 6901
6899 6902 if (!auth_cfg) {
6900 6903 mutex_exit(&hba->auth_lock);
6901 6904
6902 6905 EMLXS_MSGF(EMLXS_CONTEXT,
6903 6906 &emlxs_fcsp_start_msg,
6904 6907 "Not started. No auth cfg entry found. did=0x%x",
6905 6908 ndlp->nlp_DID);
6906 6909
6907 6910 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6908 6911
6909 6912 return (1);
6910 6913 }
6911 6914 if (fabric_switch) {
6912 6915 auth_cfg->node = NULL;
6913 6916 } else {
6914 6917 node_dhc->parent_auth_cfg = auth_cfg;
6915 6918 auth_cfg->node = ndlp;
6916 6919 }
6917 6920
6918 6921 if (!auth_key) {
6919 6922 mutex_exit(&hba->auth_lock);
6920 6923
6921 6924 EMLXS_MSGF(EMLXS_CONTEXT,
6922 6925 &emlxs_fcsp_start_msg,
6923 6926 "Not started. No auth key entry found. did=0x%x",
6924 6927 ndlp->nlp_DID);
6925 6928
6926 6929 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_DISABLED, 0, 0);
6927 6930
6928 6931 return (1);
6929 6932 }
6930 6933 if (fabric_switch) {
6931 6934 auth_key->node = NULL;
6932 6935 } else {
6933 6936 node_dhc->parent_auth_key = auth_key;
6934 6937 auth_key->node = ndlp;
6935 6938 }
6936 6939
6937 6940 /* Remote port does not support fcsp */
6938 6941 if (ndlp->sparm.cmn.fcsp_support == 0) {
6939 6942 switch (auth_cfg->authentication_mode) {
6940 6943 case AUTH_MODE_PASSIVE:
6941 6944 mutex_exit(&hba->auth_lock);
6942 6945
6943 6946 EMLXS_MSGF(EMLXS_CONTEXT,
6944 6947 &emlxs_fcsp_start_msg,
6945 6948 "Not started. Auth unsupported. did=0x%x",
6946 6949 ndlp->nlp_DID);
6947 6950
6948 6951 emlxs_dhc_state(port, ndlp,
6949 6952 NODE_STATE_AUTH_DISABLED, 0, 0);
6950 6953 return (1);
6951 6954
6952 6955 case AUTH_MODE_ACTIVE:
6953 6956 mutex_exit(&hba->auth_lock);
6954 6957
6955 6958 EMLXS_MSGF(EMLXS_CONTEXT,
6956 6959 &emlxs_fcsp_start_msg,
6957 6960 "Failed. Auth unsupported. did=0x%x",
6958 6961 ndlp->nlp_DID);
6959 6962
6960 6963 /*
6961 6964 * Save packet for deferred completion until
6962 6965 * authentication is complete
6963 6966 */
6964 6967 ndlp->node_dhc.deferred_sbp = deferred_sbp;
6965 6968 ndlp->node_dhc.deferred_ubp = deferred_ubp;
6966 6969
6967 6970 goto failed;
6968 6971
6969 6972 case AUTH_MODE_DISABLED:
6970 6973 default:
6971 6974 mutex_exit(&hba->auth_lock);
6972 6975
6973 6976 EMLXS_MSGF(EMLXS_CONTEXT,
6974 6977 &emlxs_fcsp_start_msg,
6975 6978 "Not started. Auth mode=disabled. did=0x%x",
6976 6979 ndlp->nlp_DID);
6977 6980
6978 6981 emlxs_dhc_state(port, ndlp,
6979 6982 NODE_STATE_AUTH_DISABLED, 0, 0);
6980 6983 return (1);
6981 6984 }
6982 6985 } else { /* Remote port supports fcsp */
6983 6986 switch (auth_cfg->authentication_mode) {
6984 6987 case AUTH_MODE_PASSIVE:
6985 6988 case AUTH_MODE_ACTIVE:
6986 6989 /* start auth */
6987 6990 break;
6988 6991
6989 6992 case AUTH_MODE_DISABLED:
6990 6993 default:
6991 6994 mutex_exit(&hba->auth_lock);
6992 6995
6993 6996 EMLXS_MSGF(EMLXS_CONTEXT,
6994 6997 &emlxs_fcsp_start_msg,
6995 6998 "Failed. Auth mode=disabled. did=0x%x",
6996 6999 ndlp->nlp_DID);
6997 7000
6998 7001 /*
6999 7002 * Save packet for deferred completion until
7000 7003 * authentication is complete
7001 7004 */
7002 7005 ndlp->node_dhc.deferred_sbp = deferred_sbp;
7003 7006 ndlp->node_dhc.deferred_ubp = deferred_ubp;
7004 7007
7005 7008 goto failed;
7006 7009 }
7007 7010 }
7008 7011
7009 7012 /* We have a GO for authentication */
7010 7013
7011 7014 /*
7012 7015 * Save pointers for deferred completion until authentication is
7013 7016 * complete
7014 7017 */
7015 7018 node_dhc->deferred_sbp = deferred_sbp;
7016 7019 node_dhc->deferred_ubp = deferred_ubp;
7017 7020
7018 7021 bzero(&node_dhc->auth_cfg, sizeof (node_dhc->auth_cfg));
7019 7022 bzero(&node_dhc->auth_key, sizeof (node_dhc->auth_key));
7020 7023
7021 7024 /* Program node's auth cfg */
7022 7025 bcopy((uint8_t *)&port->wwpn,
7023 7026 (uint8_t *)&node_dhc->auth_cfg.local_entity, 8);
7024 7027 bcopy((uint8_t *)&ndlp->nlp_portname,
7025 7028 (uint8_t *)&node_dhc->auth_cfg.remote_entity, 8);
7026 7029
7027 7030 node_dhc->auth_cfg.authentication_timeout =
7028 7031 auth_cfg->authentication_timeout;
7029 7032 node_dhc->auth_cfg.authentication_mode =
7030 7033 auth_cfg->authentication_mode;
7031 7034
7032 7035 /*
7033 7036 * If remote password type is "ignore", then only unidirectional auth
7034 7037 * is allowed
7035 7038 */
7036 7039 if (auth_key->remote_password_type == 3) {
7037 7040 node_dhc->auth_cfg.bidirectional = 0;
7038 7041 } else {
7039 7042 node_dhc->auth_cfg.bidirectional = auth_cfg->bidirectional;
7040 7043 }
7041 7044
7042 7045 node_dhc->auth_cfg.reauthenticate_time_interval =
7043 7046 auth_cfg->reauthenticate_time_interval;
7044 7047
7045 7048 for (i = 0; i < 4; i++) {
7046 7049 switch (auth_cfg->authentication_type_priority[i]) {
7047 7050 case ELX_DHCHAP:
7048 7051 node_dhc->auth_cfg.authentication_type_priority[i] =
7049 7052 AUTH_DHCHAP;
7050 7053 break;
7051 7054
7052 7055 case ELX_FCAP:
7053 7056 node_dhc->auth_cfg.authentication_type_priority[i] =
7054 7057 AUTH_FCAP;
7055 7058 break;
7056 7059
7057 7060 case ELX_FCPAP:
7058 7061 node_dhc->auth_cfg.authentication_type_priority[i] =
7059 7062 AUTH_FCPAP;
7060 7063 break;
7061 7064
7062 7065 case ELX_KERBEROS:
7063 7066 node_dhc->auth_cfg.authentication_type_priority[i] =
7064 7067 AUTH_KERBEROS;
7065 7068 break;
7066 7069
7067 7070 default:
7068 7071 node_dhc->auth_cfg.authentication_type_priority[i] =
7069 7072 0;
7070 7073 break;
7071 7074 }
7072 7075
7073 7076 switch (auth_cfg->hash_priority[i]) {
7074 7077 case ELX_SHA1:
7075 7078 node_dhc->auth_cfg.hash_priority[i] = AUTH_SHA1;
7076 7079 break;
7077 7080
7078 7081 case ELX_MD5:
7079 7082 node_dhc->auth_cfg.hash_priority[i] = AUTH_MD5;
7080 7083 break;
7081 7084
7082 7085 default:
7083 7086 node_dhc->auth_cfg.hash_priority[i] = 0;
7084 7087 break;
7085 7088 }
7086 7089 }
7087 7090
7088 7091 for (i = 0; i < 8; i++) {
7089 7092 switch (auth_cfg->dh_group_priority[i]) {
7090 7093 case ELX_GROUP_NULL:
7091 7094 node_dhc->auth_cfg.dh_group_priority[i] = GROUP_NULL;
7092 7095 break;
7093 7096
7094 7097 case ELX_GROUP_1024:
7095 7098 node_dhc->auth_cfg.dh_group_priority[i] = GROUP_1024;
7096 7099 break;
7097 7100
7098 7101 case ELX_GROUP_1280:
7099 7102 node_dhc->auth_cfg.dh_group_priority[i] = GROUP_1280;
7100 7103 break;
7101 7104
7102 7105 case ELX_GROUP_1536:
7103 7106 node_dhc->auth_cfg.dh_group_priority[i] = GROUP_1536;
7104 7107 break;
7105 7108
7106 7109 case ELX_GROUP_2048:
7107 7110 node_dhc->auth_cfg.dh_group_priority[i] = GROUP_2048;
7108 7111 break;
7109 7112
7110 7113 default:
7111 7114 node_dhc->auth_cfg.dh_group_priority[i] = 0xF;
7112 7115 break;
7113 7116 }
7114 7117 }
7115 7118
7116 7119 /* Program the node's key */
7117 7120 if (auth_key) {
7118 7121 bcopy((uint8_t *)auth_key,
7119 7122 (uint8_t *)&node_dhc->auth_key,
7120 7123 sizeof (emlxs_auth_key_t));
7121 7124 node_dhc->auth_key.next = NULL;
7122 7125 node_dhc->auth_key.prev = NULL;
7123 7126
7124 7127 bcopy((uint8_t *)&port->wwpn,
7125 7128 (uint8_t *)&node_dhc->auth_key.local_entity, 8);
7126 7129 bcopy((uint8_t *)&ndlp->nlp_portname,
7127 7130 (uint8_t *)&node_dhc->auth_key.remote_entity,
7128 7131 8);
7129 7132 }
7130 7133 mutex_exit(&hba->auth_lock);
7131 7134
7132 7135 node_dhc->nlp_auth_limit = 2;
7133 7136 node_dhc->nlp_fb_vendor = 1;
7134 7137
7135 7138 node_dhc->nlp_authrsp_tmocnt = 0;
7136 7139 node_dhc->nlp_authrsp_tmo = 0;
7137 7140
7138 7141 if (deferred_ubp) {
7139 7142 /* Acknowledge the unsolicited PLOGI */
7140 7143 /* This should trigger the other port to start authentication */
7141 7144 if (emlxs_ub_send_login_acc(port,
7142 7145 (fc_unsol_buf_t *)deferred_ubp) != FC_SUCCESS) {
7143 7146 EMLXS_MSGF(EMLXS_CONTEXT,
7144 7147 &emlxs_fcsp_start_msg,
7145 7148 "Not started. Unable to send PLOGI ACC. did=0x%x",
7146 7149 ndlp->nlp_DID);
7147 7150
7148 7151 goto failed;
7149 7152 }
7150 7153 /* Start the auth rsp timer */
7151 7154 node_dhc->nlp_authrsp_tmo = DRV_TIME +
7152 7155 node_dhc->auth_cfg.authentication_timeout;
7153 7156
7154 7157 EMLXS_MSGF(EMLXS_CONTEXT,
7155 7158 &emlxs_fcsp_start_msg,
7156 7159 "Authrsp timer activated. did=0x%x",
7157 7160 ndlp->nlp_DID);
7158 7161
7159 7162 /* The next state should be emlxs_rcv_auth_msg_unmapped_node */
7160 7163 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_SUCCESS, 0, 0);
7161 7164 } else {
7162 7165 node_dhc->nlp_auth_flag = 1; /* host is the initiator */
7163 7166
7164 7167 EMLXS_MSGF(EMLXS_CONTEXT,
7165 7168 &emlxs_fcsp_start_msg,
7166 7169 "Auth initiated. did=0x%x limit=%d sbp=%p",
7167 7170 ndlp->nlp_DID, node_dhc->nlp_auth_limit, deferred_sbp);
7168 7171
7169 7172 if (emlxs_issue_auth_negotiate(port, ndlp, 0)) {
7170 7173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_start_msg,
7171 7174 "Failed. Auth initiation failed. did=0x%x",
7172 7175 ndlp->nlp_DID);
7173 7176
7174 7177 goto failed;
7175 7178 }
7176 7179 }
7177 7180
7178 7181 return (0);
7179 7182
7180 7183 failed:
7181 7184
7182 7185 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED, 0, 0);
7183 7186
7184 7187 /* Complete authentication with failed status */
7185 7188 emlxs_dhc_auth_complete(port, ndlp, 1);
7186 7189
7187 7190 return (0);
7188 7191
7189 7192 } /* emlxs_dhc_auth_start() */
7190 7193
7191 7194
7192 7195
7193 7196 /* This is called to indicate the driver has lost connection with this node */
7194 7197 extern void
7195 7198 emlxs_dhc_auth_stop(
7196 7199 emlxs_port_t *port,
7197 7200 emlxs_node_t *ndlp)
7198 7201 {
7199 7202 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
7200 7203 emlxs_node_dhc_t *node_dhc;
7201 7204 uint32_t i;
7202 7205
7203 7206 if (port_dhc->state == ELX_FABRIC_STATE_UNKNOWN) {
7204 7207 /* Nothing to stop */
7205 7208 return;
7206 7209 }
7207 7210 if (ndlp) {
7208 7211 node_dhc = &ndlp->node_dhc;
7209 7212
7210 7213 if (node_dhc->state == NODE_STATE_UNKNOWN) {
7211 7214 /* Nothing to stop */
7212 7215 return;
7213 7216 }
7214 7217 if (ndlp->nlp_DID != FABRIC_DID) {
7215 7218 emlxs_dhc_state(port, ndlp, NODE_STATE_UNKNOWN, 0, 0);
7216 7219 }
7217 7220 emlxs_dhc_auth_complete(port, ndlp, 2);
7218 7221 } else { /* Lost connection to all nodes for this port */
7219 7222 rw_enter(&port->node_rwlock, RW_READER);
7220 7223 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
7221 7224 ndlp = port->node_table[i];
7222 7225
7223 7226 if (!ndlp) {
7224 7227 continue;
7225 7228 }
7226 7229 node_dhc = &ndlp->node_dhc;
7227 7230
7228 7231 if (node_dhc->state == NODE_STATE_UNKNOWN) {
7229 7232 continue;
7230 7233 }
7231 7234 if (ndlp->nlp_DID != FABRIC_DID) {
7232 7235 emlxs_dhc_state(port, ndlp,
7233 7236 NODE_STATE_UNKNOWN, 0, 0);
7234 7237 }
7235 7238 emlxs_dhc_auth_complete(port, ndlp, 2);
7236 7239 }
7237 7240 rw_exit(&port->node_rwlock);
7238 7241 }
7239 7242
7240 7243 return;
7241 7244
7242 7245 } /* emlxs_dhc_auth_stop */
7243 7246
7244 7247
7245 7248 /* state = 0 - Successful completion. Continue connection to node */
7246 7249 /* state = 1 - Failed completion. Do not continue with connection to node */
7247 7250 /* state = 2 - Stopped completion. Do not continue with connection to node */
7248 7251
7249 7252 static void
7250 7253 emlxs_dhc_auth_complete(
7251 7254 emlxs_port_t *port,
7252 7255 emlxs_node_t *ndlp,
7253 7256 uint32_t status)
7254 7257 {
7255 7258 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
7256 7259 uint32_t fabric;
7257 7260 uint32_t fabric_switch;
7258 7261
7259 7262 fabric = ((ndlp->nlp_DID & FABRIC_DID_MASK) == FABRIC_DID_MASK) ? 1 : 0;
7260 7263 fabric_switch = ((ndlp->nlp_DID == FABRIC_DID) ? 1 : 0);
7261 7264
7262 7265 EMLXS_MSGF(EMLXS_CONTEXT,
7263 7266 &emlxs_fcsp_complete_msg,
7264 7267 "did=0x%x status=%d sbp=%p ubp=%p",
7265 7268 ndlp->nlp_DID, status, node_dhc->deferred_sbp,
7266 7269 node_dhc->deferred_ubp);
7267 7270
7268 7271 if (status == 1) {
7269 7272 if (fabric_switch) {
7270 7273 /* Virtual link down */
7271 7274 (void) emlxs_port_offline(port, 0xfeffffff);
7272 7275 } else if (!fabric) {
7273 7276 /* Port offline */
7274 7277 (void) emlxs_port_offline(port, ndlp->nlp_DID);
7275 7278 }
7276 7279 }
7277 7280 /* Send a LOGO if authentication was not successful */
7278 7281 if (status == 1) {
7279 7282 EMLXS_MSGF(EMLXS_CONTEXT,
7280 7283 &emlxs_fcsp_complete_msg,
7281 7284 "Sending LOGO to did=0x%x...",
7282 7285 ndlp->nlp_DID);
7283 7286 emlxs_send_logo(port, ndlp->nlp_DID);
7284 7287 }
7285 7288
7286 7289 /* Process deferred cmpl now */
7287 7290 emlxs_mb_deferred_cmpl(port, status,
7288 7291 (emlxs_buf_t *)node_dhc->deferred_sbp,
7289 7292 (fc_unsol_buf_t *)node_dhc->deferred_ubp, 0);
7290 7293
7291 7294 node_dhc->deferred_sbp = 0;
7292 7295 node_dhc->deferred_ubp = 0;
7293 7296
7294 7297 return;
7295 7298
7296 7299 } /* emlxs_dhc_auth_complete */
7297 7300
7298 7301
7299 7302 extern void
7300 7303 emlxs_dhc_attach(emlxs_hba_t *hba)
7301 7304 {
7302 7305 char buf[32];
7303 7306
7304 7307 (void) sprintf(buf, "%s_auth_lock mutex", DRIVER_NAME);
7305 7308 mutex_init(&hba->auth_lock, buf, MUTEX_DRIVER, NULL);
7306 7309
7307 7310 (void) sprintf(buf, "%s_dhc_lock mutex", DRIVER_NAME);
7308 7311 mutex_init(&hba->dhc_lock, buf, MUTEX_DRIVER, NULL);
7309 7312
7310 7313 emlxs_auth_cfg_init(hba);
7311 7314
7312 7315 emlxs_auth_key_init(hba);
7313 7316
7314 7317 hba->rdn_flag = 1;
7315 7318
7316 7319 return;
7317 7320
7318 7321 } /* emlxs_dhc_attach() */
7319 7322
7320 7323
7321 7324 extern void
7322 7325 emlxs_dhc_detach(emlxs_hba_t *hba)
7323 7326 {
7324 7327 emlxs_auth_cfg_fini(hba);
7325 7328
7326 7329 emlxs_auth_key_fini(hba);
7327 7330
7328 7331 mutex_destroy(&hba->dhc_lock);
7329 7332 mutex_destroy(&hba->auth_lock);
7330 7333
7331 7334 return;
7332 7335
7333 7336 } /* emlxs_dhc_detach() */
7334 7337
7335 7338
7336 7339 extern void
7337 7340 emlxs_dhc_init_sp(emlxs_port_t *port, uint32_t did, SERV_PARM *sp, char **msg)
7338 7341 {
7339 7342 emlxs_hba_t *hba = HBA;
7340 7343 emlxs_config_t *cfg = &CFG;
7341 7344 uint32_t fabric;
7342 7345 uint32_t fabric_switch;
7343 7346 emlxs_auth_cfg_t *auth_cfg = NULL;
7344 7347 emlxs_auth_key_t *auth_key = NULL;
7345 7348
7346 7349 fabric = ((did & FABRIC_DID_MASK) == FABRIC_DID_MASK) ? 1 : 0;
7347 7350 fabric_switch = ((did == FABRIC_DID) ? 1 : 0);
7348 7351
7349 7352 /* Return is authentication is not enabled */
7350 7353 if (cfg[CFG_AUTH_ENABLE].current == 0) {
7351 7354 sp->cmn.fcsp_support = 0;
7352 7355 bcopy("fcsp:Disabled (0)", (void *) &msg[0],
7353 7356 sizeof ("fcsp:Disabled (0)"));
7354 7357 return;
7355 7358 }
7356 7359
7357 7360 if (port->vpi != 0 && cfg[CFG_AUTH_NPIV].current == 0) {
7358 7361 sp->cmn.fcsp_support = 0;
7359 7362 bcopy("fcsp:Disabled (npiv)", (void *) &msg[0],
7360 7363 sizeof ("fcsp:Disabled (npiv)"));
7361 7364 return;
7362 7365 }
7363 7366 if (!fabric_switch && fabric) {
7364 7367 sp->cmn.fcsp_support = 0;
7365 7368 bcopy("fcsp:Disabled (fs)", (void *) &msg[0],
7366 7369 sizeof ("fcsp:Disabled (fs)"));
7367 7370 return;
7368 7371 }
7369 7372 /* Return if fcsp support to this node is not enabled */
7370 7373 if (!fabric_switch && cfg[CFG_AUTH_E2E].current == 0) {
7371 7374 sp->cmn.fcsp_support = 0;
7372 7375 bcopy("fcsp:Disabled (e2e)", (void *) &msg[0],
7373 7376 sizeof ("fcsp:Disabled (e2e)"));
7374 7377 return;
7375 7378 }
7376 7379
7377 7380 mutex_enter(&hba->auth_lock);
7378 7381 if (fabric_switch) {
7379 7382 auth_cfg = emlxs_auth_cfg_find(port,
7380 7383 (uint8_t *)emlxs_fabric_wwn);
7381 7384 auth_key = emlxs_auth_key_find(port,
7382 7385 (uint8_t *)emlxs_fabric_wwn);
7383 7386 if ((!auth_cfg) || (!auth_key)) {
7384 7387 sp->cmn.fcsp_support = 0;
7385 7388 bcopy("fcsp:Disabled (1)", (void *) &msg[0],
7386 7389 sizeof ("fcsp:Disabled (1)"));
7387 7390 mutex_exit(&hba->auth_lock);
7388 7391 return;
7389 7392 }
7390 7393 }
7391 7394 mutex_exit(&hba->auth_lock);
7392 7395
7393 7396 sp->cmn.fcsp_support = 1;
7394 7397
7395 7398 return;
7396 7399
7397 7400 } /* emlxs_dhc_init_sp() */
7398 7401
7399 7402
7400 7403 extern uint32_t
7401 7404 emlxs_dhc_verify_login(emlxs_port_t *port, uint32_t sid, SERV_PARM *sp)
7402 7405 {
7403 7406 emlxs_hba_t *hba = HBA;
7404 7407 emlxs_config_t *cfg = &CFG;
7405 7408 emlxs_auth_cfg_t *auth_cfg;
7406 7409 emlxs_auth_key_t *auth_key;
7407 7410 uint32_t fabric;
7408 7411 uint32_t fabric_switch;
7409 7412
7410 7413 fabric = ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) ? 1 : 0;
7411 7414 fabric_switch = ((sid == FABRIC_DID) ? 1 : 0);
7412 7415
7413 7416 if (port->port_dhc.state == ELX_FABRIC_AUTH_FAILED) {
7414 7417 /* Reject login */
7415 7418 return (1);
7416 7419 }
7417 7420 /* Remote host supports FCSP */
7418 7421 if (sp->cmn.fcsp_support) {
7419 7422 /* Continue login */
7420 7423 return (0);
7421 7424 }
7422 7425 /* Auth disabled in host */
7423 7426 if (cfg[CFG_AUTH_ENABLE].current == 0) {
7424 7427 /* Continue login */
7425 7428 return (0);
7426 7429 }
7427 7430 /* Auth disabled for npiv */
7428 7431 if (port->vpi != 0 && cfg[CFG_AUTH_NPIV].current == 0) {
7429 7432 /* Continue login */
7430 7433 return (0);
7431 7434 }
7432 7435 if (!fabric_switch && fabric) {
7433 7436 /* Continue login */
7434 7437 return (0);
7435 7438 }
7436 7439 /* Auth disabled for p2p */
7437 7440 if (!fabric_switch && cfg[CFG_AUTH_E2E].current == 0) {
7438 7441 /* Continue login */
7439 7442 return (0);
7440 7443 }
7441 7444
7442 7445 /* Remote port does NOT support FCSP */
7443 7446 /* Host has FCSP enabled */
7444 7447 /* Now check to make sure auth mode for this port is also enabled */
7445 7448
7446 7449 mutex_enter(&hba->auth_lock);
7447 7450
7448 7451 /* Acquire auth configuration */
7449 7452 if (fabric_switch) {
7450 7453 auth_cfg = emlxs_auth_cfg_find(port,
7451 7454 (uint8_t *)emlxs_fabric_wwn);
7452 7455 auth_key = emlxs_auth_key_find(port,
7453 7456 (uint8_t *)emlxs_fabric_wwn);
7454 7457 } else {
7455 7458 auth_cfg = emlxs_auth_cfg_find(port,
7456 7459 (uint8_t *)&sp->portName);
7457 7460 auth_key = emlxs_auth_key_find(port,
7458 7461 (uint8_t *)&sp->portName);
7459 7462 }
7460 7463
7461 7464 if (auth_key && auth_cfg &&
7462 7465 (auth_cfg->authentication_mode == AUTH_MODE_ACTIVE)) {
7463 7466 mutex_exit(&hba->auth_lock);
7464 7467
7465 7468 /* Reject login */
7466 7469 return (1);
7467 7470 }
7468 7471 mutex_exit(&hba->auth_lock);
7469 7472
7470 7473 return (0);
7471 7474
7472 7475 } /* emlxs_dhc_verify_login() */
7473 7476
7474 7477
7475 7478 /*
7476 7479 * ! emlxs_dhc_reauth_timeout
7477 7480 *
7478 7481 * \pre \post \param phba \param arg1: \param arg2: ndlp to which the host
7479 7482 * is to be authenticated. \return void
7480 7483 *
7481 7484 * \b Description:
7482 7485 *
7483 7486 * Timeout handler for reauthentication heartbeat.
7484 7487 *
7485 7488 * The reauthentication heart beat will be triggered 1 min by default after
7486 7489 * the first authentication success. reauth_intval is
7487 7490 * configurable. if reauth_intval is set to zero, it means no reauth heart
7488 7491 * beat anymore.
7489 7492 *
7490 7493 * reauth heart beat will be triggered by IOCTL call from user space. Reauth
7491 7494 * heart beat will go through the authentication process
7492 7495 * all over again without causing IO traffic disruption. Initially it should
7493 7496 * be triggered after authentication success.
7494 7497 * Subsequently disable/enable reauth heart beat will be performed by
7495 7498 * HBAnyware or other utility.
7496 7499 *
7497 7500 */
7498 7501 /* ARGSUSED */
7499 7502 extern void
7500 7503 emlxs_dhc_reauth_timeout(
7501 7504 emlxs_port_t *port,
7502 7505 void *arg1,
7503 7506 void *arg2)
7504 7507 {
7505 7508 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
7506 7509 NODELIST *ndlp = (NODELIST *) arg2;
7507 7510 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
7508 7511
7509 7512 if (node_dhc->auth_cfg.reauthenticate_time_interval == 0) {
7510 7513 EMLXS_MSGF(EMLXS_CONTEXT,
7511 7514 &emlxs_fcsp_debug_msg,
7512 7515 "Reauth timeout. Reauth no longer enabled. 0x%x %x",
7513 7516 ndlp->nlp_DID, node_dhc->state);
7514 7517
7515 7518 emlxs_dhc_set_reauth_time(port, ndlp, DISABLE);
7516 7519
7517 7520 return;
7518 7521 }
7519 7522 /* This should not happen!! */
7520 7523 if (port_dhc->state == ELX_FABRIC_IN_AUTH) {
7521 7524 EMLXS_MSGF(EMLXS_CONTEXT,
7522 7525 &emlxs_fcsp_error_msg,
7523 7526 "Reauth timeout. Fabric in auth. Quiting. 0x%x %x",
7524 7527 ndlp->nlp_DID, node_dhc->state);
7525 7528
7526 7529 emlxs_dhc_set_reauth_time(port, ndlp, DISABLE);
7527 7530
7528 7531 return;
7529 7532 }
7530 7533 if (node_dhc->state != NODE_STATE_AUTH_SUCCESS) {
7531 7534 EMLXS_MSGF(EMLXS_CONTEXT,
7532 7535 &emlxs_fcsp_debug_msg,
7533 7536 "Reauth timeout. Auth not done. Restarting. 0x%x %x",
7534 7537 ndlp->nlp_DID, node_dhc->state);
7535 7538
7536 7539 goto restart;
7537 7540 }
7538 7541 /*
7539 7542 * This might happen, the ndlp is doing reauthencation. meaning ndlp
7540 7543 * is being re-authenticated to the host. Thus not necessary to have
7541 7544 * host re-authenticated to the ndlp at this point because ndlp might
7542 7545 * support bi-directional auth. we can just simply donothing and
7543 7546 * restart the timer.
7544 7547 */
7545 7548 if (port_dhc->state == ELX_FABRIC_IN_REAUTH) {
7546 7549 EMLXS_MSGF(EMLXS_CONTEXT,
7547 7550 &emlxs_fcsp_debug_msg,
7548 7551 "Reauth timeout. Fabric in reauth. Restarting. 0x%x %x",
7549 7552 ndlp->nlp_DID, node_dhc->state);
7550 7553
7551 7554 goto restart;
7552 7555 }
7553 7556 /*
7554 7557 * node's reauth heart beat is running already, cancel it first and
7555 7558 * then restart
7556 7559 */
7557 7560 if (node_dhc->nlp_reauth_status == NLP_HOST_REAUTH_IN_PROGRESS) {
7558 7561 EMLXS_MSGF(EMLXS_CONTEXT,
7559 7562 &emlxs_fcsp_debug_msg,
7560 7563 "Reauth timeout. Fabric in reauth. Restarting. 0x%x %x",
7561 7564 ndlp->nlp_DID, node_dhc->state);
7562 7565
7563 7566 goto restart;
7564 7567 }
7565 7568 EMLXS_MSGF(EMLXS_CONTEXT,
7566 7569 &emlxs_fcsp_debug_msg,
7567 7570 "Reauth timeout. Auth initiated. did=0x%x",
7568 7571 ndlp->nlp_DID);
7569 7572
7570 7573 emlxs_dhc_set_reauth_time(port, ndlp, ENABLE);
7571 7574 node_dhc->nlp_reauth_status = NLP_HOST_REAUTH_IN_PROGRESS;
7572 7575
7573 7576 /* Attempt to restart authentication */
7574 7577 if (emlxs_dhc_auth_start(port, ndlp, NULL, NULL) != 0) {
7575 7578 EMLXS_MSGF(EMLXS_CONTEXT,
7576 7579 &emlxs_fcsp_debug_msg,
7577 7580 "Reauth timeout. Auth initiation failed. 0x%x %x",
7578 7581 ndlp->nlp_DID, node_dhc->state);
7579 7582
7580 7583 return;
7581 7584 }
7582 7585 return;
7583 7586
7584 7587 restart:
7585 7588
7586 7589 emlxs_dhc_set_reauth_time(port, ndlp, ENABLE);
7587 7590
7588 7591 return;
7589 7592
7590 7593 } /* emlxs_dhc_reauth_timeout */
7591 7594
7592 7595
7593 7596 static void
↓ open down ↓ |
7558 lines elided |
↑ open up ↑ |
7594 7597 emlxs_dhc_set_reauth_time(
7595 7598 emlxs_port_t *port,
7596 7599 emlxs_node_t *ndlp,
7597 7600 uint32_t status)
7598 7601 {
7599 7602 emlxs_port_dhc_t *port_dhc = &port->port_dhc;
7600 7603 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
7601 7604 uint32_t drv_time;
7602 7605 uint32_t timeout;
7603 7606 uint32_t reauth_tmo;
7604 - time_t last_auth_time;
7607 + uint32_t last_auth_time;
7605 7608
7606 7609 node_dhc->flag &= ~NLP_SET_REAUTH_TIME;
7607 7610
7608 7611 if ((status == ENABLE) &&
7609 7612 node_dhc->auth_cfg.reauthenticate_time_interval) {
7610 7613
7611 7614 timeout =
7612 7615 (60 * node_dhc->auth_cfg.reauthenticate_time_interval);
7613 7616 drv_time = DRV_TIME;
7614 7617
7615 7618 /* Get last successful auth time */
7616 7619 if (ndlp->nlp_DID == FABRIC_DID) {
7617 7620 last_auth_time = port_dhc->auth_time;
7618 7621 } else if (node_dhc->parent_auth_cfg) {
7619 7622 last_auth_time = node_dhc->parent_auth_cfg->auth_time;
7620 7623 } else {
7621 7624 last_auth_time = 0;
7622 7625 }
7623 7626
7624 7627 if (last_auth_time) {
7625 7628 reauth_tmo = last_auth_time + timeout;
7626 7629
7627 7630 /* Validate reauth_tmo */
7628 7631 if ((reauth_tmo < drv_time) ||
7629 7632 (reauth_tmo > drv_time + timeout)) {
7630 7633 reauth_tmo = drv_time + timeout;
7631 7634 }
7632 7635 } else {
7633 7636 reauth_tmo = drv_time + timeout;
7634 7637 }
7635 7638
7636 7639 node_dhc->nlp_reauth_tmo = reauth_tmo;
7637 7640 node_dhc->nlp_reauth_status = NLP_HOST_REAUTH_ENABLED;
7638 7641
7639 7642 EMLXS_MSGF(EMLXS_CONTEXT,
7640 7643 &emlxs_fcsp_debug_msg,
7641 7644 "Reauth enabled. did=0x%x state=%x tmo=%d,%d",
7642 7645 ndlp->nlp_DID, node_dhc->state,
7643 7646 node_dhc->auth_cfg.reauthenticate_time_interval,
7644 7647 (reauth_tmo - drv_time));
7645 7648
7646 7649 } else {
7647 7650 node_dhc->nlp_reauth_tmo = 0;
7648 7651 node_dhc->nlp_reauth_status = NLP_HOST_REAUTH_DISABLED;
7649 7652
7650 7653 EMLXS_MSGF(EMLXS_CONTEXT,
7651 7654 &emlxs_fcsp_debug_msg,
7652 7655 "Reauth disabled. did=0x%x state=%x",
7653 7656 ndlp->nlp_DID, node_dhc->state);
7654 7657 }
7655 7658
7656 7659 return;
7657 7660
7658 7661 } /* emlxs_dhc_set_reauth_time */
7659 7662
7660 7663
7661 7664 /* ARGSUSED */
7662 7665 extern void
7663 7666 emlxs_dhc_authrsp_timeout(
7664 7667 emlxs_port_t *port,
7665 7668 void *arg1,
7666 7669 void *arg2)
7667 7670 {
7668 7671 NODELIST *ndlp = (NODELIST *)arg1;
7669 7672 emlxs_node_dhc_t *node_dhc = &ndlp->node_dhc;
7670 7673 uint8_t ReasonCode;
7671 7674 uint8_t ReasonCodeExplanation;
7672 7675
7673 7676 node_dhc->nlp_authrsp_tmo = 0;
7674 7677 node_dhc->nlp_authrsp_tmocnt++;
7675 7678
7676 7679 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
7677 7680 "Authrsp timeout. did=0x%x count=%d",
7678 7681 ndlp->nlp_DID, node_dhc->nlp_authrsp_tmocnt);
7679 7682
7680 7683 /*
7681 7684 * According to the FC-SP spec v1.8 pp76.
7682 7685 *
7683 7686 * When the AUTH_TMO error is detected, the entity may: 1. Act as if the
7684 7687 * authentication transaction has failed and terminate the
7685 7688 * communication; or 2. Restart a new authentication transaction, by
7686 7689 * sending an AUTH_Reject msg with Reason Code `Logical Error' and
7687 7690 * Reason Code Explanation 'Restart Authentication Protocol', The
7688 7691 * action performed by the entity receiving such a AUTH_Reject should
7689 7692 * restart the authentication Transaction by sending a new
7690 7693 * AUTH_Negotiate. We plan to use 2 as the action for now.
7691 7694 *
7692 7695 */
7693 7696
7694 7697 if (node_dhc->nlp_authrsp_tmocnt > 3) {
7695 7698 /* Generate a remove event for the nodelist entry */
7696 7699 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
7697 7700 NULL, ndlp, NODE_EVENT_DEVICE_RM);
7698 7701
7699 7702 ReasonCode = AUTHRJT_FAILURE;
7700 7703 ReasonCodeExplanation = AUTHEXP_AUTH_FAILED;
7701 7704 } else {
7702 7705 /* Generate a recovery event for the nodelist entry */
7703 7706 (void) emlxs_dhchap_state_machine(port, NULL, NULL,
7704 7707 NULL, ndlp, NODE_EVENT_DEVICE_RECOVERY);
7705 7708
7706 7709 ReasonCode = AUTHRJT_LOGIC_ERR;
7707 7710 ReasonCodeExplanation = AUTHEXP_RESTART_AUTH;
7708 7711 }
7709 7712
7710 7713 emlxs_dhc_state(port, ndlp, NODE_STATE_AUTH_FAILED, ReasonCode,
7711 7714 ReasonCodeExplanation);
7712 7715 (void) emlxs_issue_auth_reject(port, ndlp, 0, 0, ReasonCode,
7713 7716 ReasonCodeExplanation);
7714 7717 emlxs_dhc_auth_complete(port, ndlp, 1);
7715 7718
7716 7719 /*
7717 7720 * It is expected the other party should restart the authentication
7718 7721 * transaction
7719 7722 */
7720 7723
7721 7724 return;
7722 7725
7723 7726 } /* emlxs_dhc_authrsp_timeout() */
7724 7727
7725 7728
7726 7729 /* **************************** AUTH CFG MANAGEMENT ************************ */
7727 7730
7728 7731 /* auth_lock must be held */
7729 7732 static emlxs_auth_cfg_t *
7730 7733 emlxs_auth_cfg_find(emlxs_port_t *port, uint8_t *rwwpn)
7731 7734 {
7732 7735 emlxs_hba_t *hba = HBA;
7733 7736 emlxs_auth_cfg_t *auth_cfg;
7734 7737
7735 7738 if (rwwpn) {
7736 7739 /* lwwpn, rwwpn */
7737 7740 auth_cfg = emlxs_auth_cfg_get(hba,
7738 7741 (uint8_t *)&port->wwpn, (uint8_t *)rwwpn);
7739 7742
7740 7743 if (auth_cfg) {
7741 7744 emlxs_auth_cfg_print(hba, auth_cfg);
7742 7745 return (auth_cfg);
7743 7746 }
7744 7747 /* null, rwwpn */
7745 7748 auth_cfg = emlxs_auth_cfg_get(hba,
7746 7749 (uint8_t *)emlxs_null_wwn, (uint8_t *)rwwpn);
7747 7750
7748 7751 if (auth_cfg) {
7749 7752 emlxs_auth_cfg_print(hba, auth_cfg);
7750 7753 return (auth_cfg);
7751 7754 }
7752 7755 }
7753 7756 /* lwwpn, null */
7754 7757 auth_cfg = emlxs_auth_cfg_get(hba,
7755 7758 (uint8_t *)&port->wwpn, (uint8_t *)emlxs_null_wwn);
7756 7759
7757 7760 if (auth_cfg) {
7758 7761 emlxs_auth_cfg_print(hba, auth_cfg);
7759 7762 return (auth_cfg);
7760 7763 }
7761 7764 /* null, null */
7762 7765 return (&hba->auth_cfg);
7763 7766
7764 7767 } /* emlxs_auth_cfg_find() */
7765 7768
7766 7769 static void
7767 7770 emlxs_auth_cfg_init(emlxs_hba_t *hba)
7768 7771 {
7769 7772 emlxs_config_t *cfg = &CFG;
7770 7773 emlxs_auth_cfg_t *auth_cfg;
7771 7774
7772 7775 /* Destroy old table if one exists */
7773 7776 emlxs_auth_cfg_fini(hba);
7774 7777
7775 7778 mutex_enter(&hba->auth_lock);
7776 7779
7777 7780 /* Zero default entry */
7778 7781 auth_cfg = &hba->auth_cfg;
7779 7782 bzero(auth_cfg, sizeof (emlxs_auth_cfg_t));
7780 7783 auth_cfg->next = auth_cfg;
7781 7784 auth_cfg->prev = auth_cfg;
7782 7785
7783 7786 /* Configure the default entry */
7784 7787 auth_cfg->authentication_timeout =
7785 7788 cfg[CFG_AUTH_TMO].current;
7786 7789 auth_cfg->authentication_mode =
7787 7790 cfg[CFG_AUTH_MODE].current;
7788 7791 auth_cfg->bidirectional =
7789 7792 cfg[CFG_AUTH_BIDIR].current;
7790 7793 auth_cfg->authentication_type_priority[0] =
7791 7794 (cfg[CFG_AUTH_TYPE].current & 0xF000) >> 12;
7792 7795 auth_cfg->authentication_type_priority[1] =
7793 7796 (cfg[CFG_AUTH_TYPE].current & 0x0F00) >> 8;
7794 7797 auth_cfg->authentication_type_priority[2] =
7795 7798 (cfg[CFG_AUTH_TYPE].current & 0x00F0) >> 4;
7796 7799 auth_cfg->authentication_type_priority[3] =
7797 7800 (cfg[CFG_AUTH_TYPE].current & 0x000F);
7798 7801 auth_cfg->hash_priority[0] =
7799 7802 (cfg[CFG_AUTH_HASH].current & 0xF000) >> 12;
7800 7803 auth_cfg->hash_priority[1] =
7801 7804 (cfg[CFG_AUTH_HASH].current & 0x0F00) >> 8;
7802 7805 auth_cfg->hash_priority[2] =
7803 7806 (cfg[CFG_AUTH_HASH].current & 0x00F0) >> 4;
7804 7807 auth_cfg->hash_priority[3] =
7805 7808 (cfg[CFG_AUTH_HASH].current & 0x000F);
7806 7809 auth_cfg->dh_group_priority[0] =
7807 7810 (cfg[CFG_AUTH_GROUP].current & 0xF0000000) >> 28;
7808 7811 auth_cfg->dh_group_priority[1] =
7809 7812 (cfg[CFG_AUTH_GROUP].current & 0x0F000000) >> 24;
7810 7813 auth_cfg->dh_group_priority[2] =
7811 7814 (cfg[CFG_AUTH_GROUP].current & 0x00F00000) >> 20;
7812 7815 auth_cfg->dh_group_priority[3] =
7813 7816 (cfg[CFG_AUTH_GROUP].current & 0x000F0000) >> 16;
7814 7817 auth_cfg->dh_group_priority[4] =
7815 7818 (cfg[CFG_AUTH_GROUP].current & 0x0000F000) >> 12;
7816 7819 auth_cfg->dh_group_priority[5] =
7817 7820 (cfg[CFG_AUTH_GROUP].current & 0x00000F00) >> 8;
7818 7821 auth_cfg->dh_group_priority[6] =
7819 7822 (cfg[CFG_AUTH_GROUP].current & 0x000000F0) >> 4;
7820 7823 auth_cfg->dh_group_priority[7] =
7821 7824 (cfg[CFG_AUTH_GROUP].current & 0x0000000F);
7822 7825 auth_cfg->reauthenticate_time_interval =
7823 7826 cfg[CFG_AUTH_INTERVAL].current;
7824 7827
7825 7828 emlxs_auth_cfg_read(hba);
7826 7829
7827 7830 mutex_exit(&hba->auth_lock);
7828 7831
7829 7832 return;
7830 7833
7831 7834 } /* emlxs_auth_cfg_init() */
7832 7835
7833 7836
7834 7837 static void
7835 7838 emlxs_auth_cfg_fini(emlxs_hba_t *hba)
7836 7839 {
7837 7840 emlxs_auth_cfg_t *auth_cfg = hba->auth_cfg.next;
7838 7841 emlxs_auth_cfg_t *next;
7839 7842
7840 7843 mutex_enter(&hba->auth_lock);
7841 7844
7842 7845 while (auth_cfg && auth_cfg != &hba->auth_cfg) {
7843 7846 next = auth_cfg->next;
7844 7847 emlxs_auth_cfg_destroy(hba, auth_cfg);
7845 7848 auth_cfg = next;
7846 7849 }
7847 7850
7848 7851 mutex_exit(&hba->auth_lock);
7849 7852
7850 7853 return;
7851 7854
7852 7855 } /* emlxs_auth_cfg_fini() */
7853 7856
7854 7857
7855 7858 static void
7856 7859 emlxs_auth_cfg_print(emlxs_hba_t *hba, emlxs_auth_cfg_t *auth_cfg)
7857 7860 {
7858 7861 emlxs_port_t *port = &PPORT;
7859 7862
7860 7863 char s_lwwpn[32];
7861 7864 char s_rwwpn[32];
7862 7865
7863 7866 /* Create and add new entry */
7864 7867 EMLXS_MSGF(EMLXS_CONTEXT,
7865 7868 &emlxs_fcsp_detail_msg,
7866 7869 "%s:%s:%x:%x:%x:%x%x%x%x:%x%x%x%x:%x%x%x%x%x%x%x%x:%x",
7867 7870 emlxs_wwn_xlate(s_lwwpn, (uint8_t *)&auth_cfg->local_entity),
7868 7871 emlxs_wwn_xlate(s_rwwpn, (uint8_t *)&auth_cfg->remote_entity),
7869 7872 auth_cfg->authentication_timeout,
7870 7873 auth_cfg->authentication_mode,
7871 7874 auth_cfg->bidirectional,
7872 7875 auth_cfg->authentication_type_priority[0],
7873 7876 auth_cfg->authentication_type_priority[1],
7874 7877 auth_cfg->authentication_type_priority[2],
7875 7878 auth_cfg->authentication_type_priority[3],
7876 7879 auth_cfg->hash_priority[0],
7877 7880 auth_cfg->hash_priority[1],
7878 7881 auth_cfg->hash_priority[2],
7879 7882 auth_cfg->hash_priority[3],
7880 7883 auth_cfg->dh_group_priority[0],
7881 7884 auth_cfg->dh_group_priority[1],
7882 7885 auth_cfg->dh_group_priority[2],
7883 7886 auth_cfg->dh_group_priority[3],
7884 7887 auth_cfg->dh_group_priority[4],
7885 7888 auth_cfg->dh_group_priority[5],
7886 7889 auth_cfg->dh_group_priority[6],
7887 7890 auth_cfg->dh_group_priority[7],
7888 7891 auth_cfg->reauthenticate_time_interval);
7889 7892
7890 7893 } /* emlxs_auth_cfg_print() */
7891 7894
7892 7895
7893 7896 /* auth_lock must be held */
7894 7897 static emlxs_auth_cfg_t *
7895 7898 emlxs_auth_cfg_get(emlxs_hba_t *hba, uint8_t *lwwpn, uint8_t *rwwpn)
7896 7899 {
7897 7900 emlxs_auth_cfg_t *auth_cfg;
7898 7901
7899 7902 if (!lwwpn || !rwwpn) {
7900 7903 return (NULL);
7901 7904 }
7902 7905
7903 7906 /* Check for default entry */
7904 7907 if ((bcmp(lwwpn, emlxs_null_wwn, 8) == 0) &&
7905 7908 (bcmp(rwwpn, emlxs_null_wwn, 8) == 0)) {
7906 7909 return (&hba->auth_cfg);
7907 7910 }
7908 7911
7909 7912 for (auth_cfg = hba->auth_cfg.next;
7910 7913 auth_cfg != &hba->auth_cfg; auth_cfg = auth_cfg->next) {
7911 7914 /* Find pwd entry for this local port */
7912 7915
7913 7916 /* Check for exact wwpn match */
7914 7917 if (bcmp((void *)&auth_cfg->local_entity,
7915 7918 (void *)lwwpn, 8) != 0) {
7916 7919 continue;
7917 7920 }
7918 7921 /* Find pwd entry for remote port */
7919 7922
7920 7923 /* Check for exact wwpn match */
7921 7924 if (bcmp((void *)&auth_cfg->remote_entity,
7922 7925 (void *)rwwpn, 8) != 0) {
7923 7926 continue;
7924 7927 }
7925 7928 return (auth_cfg);
7926 7929 }
7927 7930
7928 7931 return (NULL);
7929 7932
7930 7933 } /* emlxs_auth_cfg_get() */
7931 7934
7932 7935
7933 7936 /* auth_lock must be held */
7934 7937 static emlxs_auth_cfg_t *
7935 7938 emlxs_auth_cfg_create(emlxs_hba_t *hba, uint8_t *lwwpn, uint8_t *rwwpn)
7936 7939 {
7937 7940 emlxs_auth_cfg_t *auth_cfg;
7938 7941
7939 7942 /* First check if entry already exists */
7940 7943 auth_cfg = emlxs_auth_cfg_get(hba, lwwpn, rwwpn);
7941 7944
7942 7945 if (auth_cfg) {
7943 7946 return (auth_cfg);
7944 7947 }
7945 7948 /* Allocate entry */
7946 7949 auth_cfg = (emlxs_auth_cfg_t *)kmem_zalloc(sizeof (emlxs_auth_cfg_t),
7947 7950 KM_NOSLEEP);
7948 7951
7949 7952 if (!auth_cfg) {
7950 7953 return (NULL);
7951 7954 }
7952 7955 /* Add to list */
7953 7956 auth_cfg->next = &hba->auth_cfg;
7954 7957 auth_cfg->prev = hba->auth_cfg.prev;
7955 7958 hba->auth_cfg.prev->next = auth_cfg;
7956 7959 hba->auth_cfg.prev = auth_cfg;
7957 7960 hba->auth_cfg_count++;
7958 7961
7959 7962 /* Initialize name pair */
7960 7963 if (lwwpn) {
7961 7964 bcopy((void *)lwwpn, (void *)&auth_cfg->local_entity, 8);
7962 7965 }
7963 7966 if (rwwpn) {
7964 7967 bcopy((void *)rwwpn, (void *)&auth_cfg->remote_entity, 8);
7965 7968 }
7966 7969 auth_cfg->auth_status.auth_state = DFC_AUTH_STATE_OFF;
7967 7970
7968 7971 return (auth_cfg);
7969 7972
7970 7973 } /* emlxs_auth_cfg_create() */
7971 7974
7972 7975
7973 7976 /* auth_lock must be held */
7974 7977 static void
7975 7978 emlxs_auth_cfg_destroy(emlxs_hba_t *hba, emlxs_auth_cfg_t *auth_cfg)
7976 7979 {
7977 7980
7978 7981 if (!auth_cfg) {
7979 7982 return;
7980 7983 }
7981 7984 if (auth_cfg == &hba->auth_cfg) {
7982 7985 return;
7983 7986 }
7984 7987 /* Remove from list */
7985 7988 auth_cfg->next->prev = auth_cfg->prev;
7986 7989 auth_cfg->prev->next = auth_cfg->next;
7987 7990 hba->auth_cfg_count--;
7988 7991
7989 7992 /* Remove node binding */
7990 7993 if (auth_cfg->node &&
7991 7994 auth_cfg->node->nlp_active &&
7992 7995 (auth_cfg->node->node_dhc.parent_auth_cfg == auth_cfg)) {
7993 7996 auth_cfg->node->node_dhc.parent_auth_cfg = NULL;
7994 7997 }
7995 7998 bzero(auth_cfg, sizeof (emlxs_auth_cfg_t));
7996 7999 kmem_free(auth_cfg, sizeof (emlxs_auth_cfg_t));
7997 8000
7998 8001 return;
7999 8002
8000 8003 } /* emlxs_auth_cfg_destroy() */
8001 8004
8002 8005
8003 8006 /* auth_lock must be held */
8004 8007 static void
8005 8008 emlxs_auth_cfg_read(emlxs_hba_t *hba)
8006 8009 {
8007 8010 emlxs_port_t *port = &PPORT;
8008 8011 char **arrayp;
8009 8012 emlxs_auth_cfg_t auth_cfg;
8010 8013 emlxs_auth_cfg_t *auth_cfg2;
8011 8014 uint32_t cnt;
8012 8015 uint32_t rval;
8013 8016 char buffer[64];
8014 8017 char *prop_str;
8015 8018 uint32_t i;
8016 8019
8017 8020 /* Check for the per adapter setting */
8018 8021 (void) sprintf(buffer, "%s%d-auth-cfgs", DRIVER_NAME, hba->ddiinst);
8019 8022 cnt = 0;
8020 8023 arrayp = NULL;
8021 8024 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
8022 8025 (DDI_PROP_DONTPASS),
8023 8026 buffer, &arrayp, &cnt);
8024 8027
8025 8028 if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
8026 8029 /* Check for the global setting */
8027 8030 cnt = 0;
8028 8031 arrayp = NULL;
8029 8032 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY,
8030 8033 hba->dip, (DDI_PROP_DONTPASS),
8031 8034 "auth-cfgs", &arrayp, &cnt);
8032 8035 }
8033 8036 if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
8034 8037 return;
8035 8038 }
8036 8039 for (i = 0; i < cnt; i++) {
8037 8040 prop_str = arrayp[i];
8038 8041 if (prop_str == NULL) {
8039 8042 break;
8040 8043 }
8041 8044 /* parse the string */
8042 8045 if (emlxs_auth_cfg_parse(hba, &auth_cfg, prop_str) == 0) {
8043 8046 EMLXS_MSGF(EMLXS_CONTEXT,
8044 8047 &emlxs_attach_msg,
8045 8048 "Error parsing auth_cfgs property. entry=%d", i);
8046 8049 continue;
8047 8050 }
8048 8051 auth_cfg2 = emlxs_auth_cfg_create(hba,
8049 8052 (uint8_t *)&auth_cfg.local_entity,
8050 8053 (uint8_t *)&auth_cfg.remote_entity);
8051 8054
8052 8055 if (!auth_cfg2) {
8053 8056 EMLXS_MSGF(EMLXS_CONTEXT,
8054 8057 &emlxs_attach_msg,
8055 8058 "Out of memory parsing auth_cfgs property. ey=%d",
8056 8059 i);
8057 8060 return;
8058 8061 }
8059 8062 auth_cfg.next = auth_cfg2->next;
8060 8063 auth_cfg.prev = auth_cfg2->prev;
8061 8064 bcopy((uint8_t *)&auth_cfg,
8062 8065 (uint8_t *)auth_cfg2,
8063 8066 sizeof (emlxs_auth_cfg_t));
8064 8067 }
8065 8068
8066 8069 return;
8067 8070
8068 8071 } /* emlxs_auth_cfg_read() */
8069 8072
8070 8073
8071 8074 /* auth_lock must be held */
8072 8075 static uint32_t
8073 8076 emlxs_auth_cfg_parse(
8074 8077 emlxs_hba_t *hba,
8075 8078 emlxs_auth_cfg_t *auth_cfg,
8076 8079 char *prop_str)
8077 8080 {
8078 8081 emlxs_port_t *port = &PPORT;
8079 8082 emlxs_config_t *cfg = &CFG;
8080 8083 uint32_t errors = 0;
8081 8084 uint32_t c1;
8082 8085 uint8_t *np;
8083 8086 uint32_t j;
8084 8087 uint32_t i;
8085 8088 uint32_t sum;
8086 8089 char *s;
8087 8090
8088 8091 s = prop_str;
8089 8092 bzero(auth_cfg, sizeof (emlxs_auth_cfg_t));
8090 8093
8091 8094 /* Read local wwpn */
8092 8095 np = (uint8_t *)&auth_cfg->local_entity;
8093 8096 for (j = 0; j < 8; j++) {
8094 8097 c1 = *s++;
8095 8098 if ((c1 >= '0') && (c1 <= '9')) {
8096 8099 sum = ((c1 - '0') << 4);
8097 8100 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8098 8101 sum = ((c1 - 'a' + 10) << 4);
8099 8102 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8100 8103 sum = ((c1 - 'A' + 10) << 4);
8101 8104 } else {
8102 8105 EMLXS_MSGF(EMLXS_CONTEXT,
8103 8106 &emlxs_attach_debug_msg,
8104 8107 "Cfg err:Invalid LWWPN found. byte=%d hi_nibble=%c",
8105 8108 j, c1);
8106 8109 errors++;
8107 8110 }
8108 8111
8109 8112 c1 = *s++;
8110 8113 if ((c1 >= '0') && (c1 <= '9')) {
8111 8114 sum |= (c1 - '0');
8112 8115 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8113 8116 sum |= (c1 - 'a' + 10);
8114 8117 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8115 8118 sum |= (c1 - 'A' + 10);
8116 8119 } else {
8117 8120 EMLXS_MSGF(EMLXS_CONTEXT,
8118 8121 &emlxs_attach_debug_msg,
8119 8122 "Cfg err: Invalid LWWPN found. %d %c",
8120 8123 j, c1);
8121 8124 errors++;
8122 8125 }
8123 8126
8124 8127 *np++ = (uint8_t)sum;
8125 8128 }
8126 8129
8127 8130 if (*s++ != ':') {
8128 8131 EMLXS_MSGF(EMLXS_CONTEXT,
8129 8132 &emlxs_attach_debug_msg,
8130 8133 "Cfg err: Invalid delimiter after LWWPN.");
8131 8134 goto out;
8132 8135 }
8133 8136 /* Read remote wwpn */
8134 8137 np = (uint8_t *)&auth_cfg->remote_entity;
8135 8138 for (j = 0; j < 8; j++) {
8136 8139 c1 = *s++;
8137 8140 if ((c1 >= '0') && (c1 <= '9')) {
8138 8141 sum = ((c1 - '0') << 4);
8139 8142 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8140 8143 sum = ((c1 - 'a' + 10) << 4);
8141 8144 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8142 8145 sum = ((c1 - 'A' + 10) << 4);
8143 8146 } else {
8144 8147 EMLXS_MSGF(EMLXS_CONTEXT,
8145 8148 &emlxs_attach_debug_msg,
8146 8149 "Cfg err: Invalid RWWPN found.byte=%d hi_nibble=%c",
8147 8150 j, c1);
8148 8151 errors++;
8149 8152 }
8150 8153
8151 8154 c1 = *s++;
8152 8155 if ((c1 >= '0') && (c1 <= '9')) {
8153 8156 sum |= (c1 - '0');
8154 8157 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8155 8158 sum |= (c1 - 'a' + 10);
8156 8159 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8157 8160 sum |= (c1 - 'A' + 10);
8158 8161 } else {
8159 8162 EMLXS_MSGF(EMLXS_CONTEXT,
8160 8163 &emlxs_attach_debug_msg,
8161 8164 "Cfg err: Invalid RWWPN found. %d %c",
8162 8165 j, c1);
8163 8166 errors++;
8164 8167 }
8165 8168
8166 8169 *np++ = (uint8_t)sum;
8167 8170 }
8168 8171
8169 8172 if (*s++ != ':') {
8170 8173 EMLXS_MSGF(EMLXS_CONTEXT,
8171 8174 &emlxs_attach_debug_msg,
8172 8175 "Cfg err: Invalid delimiter after RWWPN.");
8173 8176 goto out;
8174 8177 }
8175 8178 /* Read auth_tov (%x) */
8176 8179 sum = 0;
8177 8180 do {
8178 8181 c1 = *s++;
8179 8182 if ((c1 >= '0') && (c1 <= '9')) {
8180 8183 sum = (sum << 4) + (c1 - '0');
8181 8184 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8182 8185 sum = (sum << 4) + (c1 - 'a' + 10);
8183 8186 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8184 8187 sum = (sum << 4) + (c1 - 'A' + 10);
8185 8188 } else {
8186 8189 EMLXS_MSGF(EMLXS_CONTEXT,
8187 8190 &emlxs_attach_debug_msg,
8188 8191 "Cfg err: Invalid auth_tov found. c=%c sum=%d",
8189 8192 c1, sum);
8190 8193
8191 8194 errors++;
8192 8195 }
8193 8196
8194 8197 } while (*s != ':' && *s != 0);
8195 8198 auth_cfg->authentication_timeout = sum;
8196 8199
8197 8200 if (*s++ != ':') {
8198 8201 EMLXS_MSGF(EMLXS_CONTEXT,
8199 8202 &emlxs_attach_debug_msg,
8200 8203 "Cfg err: Invalid delimiter after auth_tov.");
8201 8204 goto out;
8202 8205 }
8203 8206 /* Read auth_mode */
8204 8207 sum = 0;
8205 8208 do {
8206 8209 c1 = *s++;
8207 8210 if ((c1 >= '0') && (c1 <= '9')) {
8208 8211 sum = (sum << 4) + (c1 - '0');
8209 8212 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8210 8213 sum = (sum << 4) + (c1 - 'a' + 10);
8211 8214 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8212 8215 sum = (sum << 4) + (c1 - 'A' + 10);
8213 8216 } else {
8214 8217 EMLXS_MSGF(EMLXS_CONTEXT,
8215 8218 &emlxs_attach_debug_msg,
8216 8219 "Cfg err: Invalid auth_mode found. c=%c sum=%d",
8217 8220 c1, sum);
8218 8221
8219 8222 errors++;
8220 8223 }
8221 8224
8222 8225 } while (*s != ':' && *s != 0);
8223 8226 auth_cfg->authentication_mode = sum;
8224 8227
8225 8228 if (*s++ != ':') {
8226 8229 EMLXS_MSGF(EMLXS_CONTEXT,
8227 8230 &emlxs_attach_debug_msg,
8228 8231 "Config error: Invalid delimiter after auth_mode.");
8229 8232 goto out;
8230 8233 }
8231 8234 /* Read auth_bidir */
8232 8235 sum = 0;
8233 8236 do {
8234 8237 c1 = *s++;
8235 8238 if ((c1 >= '0') && (c1 <= '9')) {
8236 8239 sum = (sum << 4) + (c1 - '0');
8237 8240 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8238 8241 sum = (sum << 4) + (c1 - 'a' + 10);
8239 8242 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8240 8243 sum = (sum << 4) + (c1 - 'A' + 10);
8241 8244 } else {
8242 8245 EMLXS_MSGF(EMLXS_CONTEXT,
8243 8246 &emlxs_attach_debug_msg,
8244 8247 "Cfg err: Invalid auth_bidir found. c=%c sum=%d",
8245 8248 c1, sum);
8246 8249
8247 8250 errors++;
8248 8251 }
8249 8252
8250 8253 } while (*s != ':' && *s != 0);
8251 8254 auth_cfg->bidirectional = sum;
8252 8255
8253 8256 if (*s++ != ':') {
8254 8257 EMLXS_MSGF(EMLXS_CONTEXT,
8255 8258 &emlxs_attach_debug_msg,
8256 8259 "Cfg err: Invalid delimiter after auth_bidir.");
8257 8260 goto out;
8258 8261 }
8259 8262 /* Read type_priority[4] */
8260 8263 for (i = 0; i < 4; i++) {
8261 8264 c1 = *s++;
8262 8265 if ((c1 >= '0') && (c1 <= '9')) {
8263 8266 sum = (c1 - '0');
8264 8267 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8265 8268 sum = (c1 - 'a' + 10);
8266 8269 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8267 8270 sum = (c1 - 'A' + 10);
8268 8271 } else {
8269 8272 EMLXS_MSGF(EMLXS_CONTEXT,
8270 8273 &emlxs_attach_debug_msg,
8271 8274 "Cfg err: Invalid type_pty[%d] found. c=%c sum=%d",
8272 8275 i, c1, sum);
8273 8276
8274 8277 errors++;
8275 8278 }
8276 8279
8277 8280 auth_cfg->authentication_type_priority[i] = sum;
8278 8281 }
8279 8282
8280 8283 if (*s++ != ':') {
8281 8284 EMLXS_MSGF(EMLXS_CONTEXT,
8282 8285 &emlxs_attach_debug_msg,
8283 8286 "Cfg err: Invalid delimiter after type_priority.");
8284 8287
8285 8288 goto out;
8286 8289 }
8287 8290 /* Read hash_priority[4] */
8288 8291 for (i = 0; i < 4; i++) {
8289 8292 c1 = *s++;
8290 8293 if ((c1 >= '0') && (c1 <= '9')) {
8291 8294 sum = (c1 - '0');
8292 8295 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8293 8296 sum = (c1 - 'a' + 10);
8294 8297 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8295 8298 sum = (c1 - 'A' + 10);
8296 8299 } else {
8297 8300 EMLXS_MSGF(EMLXS_CONTEXT,
8298 8301 &emlxs_attach_debug_msg,
8299 8302 "Cfg err: Invalid hash_priority[%d] fd. %c %d",
8300 8303 i, c1, sum);
8301 8304
8302 8305 errors++;
8303 8306 }
8304 8307
8305 8308 auth_cfg->hash_priority[i] = sum;
8306 8309 }
8307 8310
8308 8311 if (*s++ != ':') {
8309 8312 EMLXS_MSGF(EMLXS_CONTEXT,
8310 8313 &emlxs_attach_debug_msg,
8311 8314 "Cfg err: Invalid delimiter after hash_priority.");
8312 8315
8313 8316 goto out;
8314 8317 }
8315 8318 /* Read group_priority[8] */
8316 8319 for (i = 0; i < 8; i++) {
8317 8320 c1 = *s++;
8318 8321 if ((c1 >= '0') && (c1 <= '9')) {
8319 8322 sum = (c1 - '0');
8320 8323 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8321 8324 sum = (c1 - 'a' + 10);
8322 8325 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8323 8326 sum = (c1 - 'A' + 10);
8324 8327 } else {
8325 8328 EMLXS_MSGF(EMLXS_CONTEXT,
8326 8329 &emlxs_attach_debug_msg,
8327 8330 "Cfg err: Invalid group_priority[%d] fd. %c %d",
8328 8331 i, c1, sum);
8329 8332
8330 8333 errors++;
8331 8334 }
8332 8335
8333 8336 auth_cfg->dh_group_priority[i] = sum;
8334 8337 }
8335 8338
8336 8339 if (*s++ != ':') {
8337 8340 EMLXS_MSGF(EMLXS_CONTEXT,
8338 8341 &emlxs_attach_debug_msg,
8339 8342 "Cfg err: Invalid delimiter after group_priority.");
8340 8343 goto out;
8341 8344 }
8342 8345 /* Read reauth_tov */
8343 8346 sum = 0;
8344 8347 do {
8345 8348 c1 = *s++;
8346 8349 if ((c1 >= '0') && (c1 <= '9')) {
8347 8350 sum = (sum << 4) + (c1 - '0');
8348 8351 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8349 8352 sum = (sum << 4) + (c1 - 'a' + 10);
8350 8353 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8351 8354 sum = (sum << 4) + (c1 - 'A' + 10);
8352 8355 } else {
8353 8356 EMLXS_MSGF(EMLXS_CONTEXT,
8354 8357 &emlxs_attach_debug_msg,
8355 8358 "Cfg err: Invalid reauth_tov found. c=%c sum=%d",
8356 8359 c1, sum);
8357 8360
8358 8361 errors++;
8359 8362 }
8360 8363
8361 8364 } while (*s != ':' && *s != 0);
8362 8365 auth_cfg->reauthenticate_time_interval = sum;
8363 8366
8364 8367 if (errors) {
8365 8368 goto out;
8366 8369 }
8367 8370 /* Verify values */
8368 8371
8369 8372 /* Check authentication_timeout */
8370 8373 if (auth_cfg->authentication_timeout < cfg[CFG_AUTH_TMO].low) {
8371 8374 auth_cfg->authentication_timeout = cfg[CFG_AUTH_TMO].current;
8372 8375 } else if (auth_cfg->authentication_timeout > cfg[CFG_AUTH_TMO].hi) {
8373 8376 auth_cfg->authentication_timeout = cfg[CFG_AUTH_TMO].current;
8374 8377 }
8375 8378 /* Check authentication_mode */
8376 8379 if (auth_cfg->authentication_mode < cfg[CFG_AUTH_MODE].low) {
8377 8380 auth_cfg->authentication_mode = cfg[CFG_AUTH_MODE].current;
8378 8381 } else if (auth_cfg->authentication_mode > cfg[CFG_AUTH_MODE].hi) {
8379 8382 auth_cfg->authentication_mode = cfg[CFG_AUTH_MODE].current;
8380 8383 }
8381 8384 /* Check bidirectional */
8382 8385 if (auth_cfg->bidirectional < cfg[CFG_AUTH_BIDIR].low) {
8383 8386 auth_cfg->bidirectional = cfg[CFG_AUTH_BIDIR].current;
8384 8387 } else if (auth_cfg->bidirectional > cfg[CFG_AUTH_BIDIR].hi) {
8385 8388 auth_cfg->bidirectional = cfg[CFG_AUTH_BIDIR].current;
8386 8389 }
8387 8390 /* Check authentication_type_priority and hash_priority */
8388 8391 for (i = 0; i < 4; i++) {
8389 8392 if (auth_cfg->authentication_type_priority[i] >
8390 8393 DFC_AUTH_TYPE_MAX) {
8391 8394 /* Set to current default */
8392 8395 auth_cfg->authentication_type_priority[i] =
8393 8396 hba->auth_cfg.authentication_type_priority[i];
8394 8397 }
8395 8398 if (auth_cfg->hash_priority[i] > DFC_AUTH_HASH_MAX) {
8396 8399 /* Set to current default */
8397 8400 auth_cfg->hash_priority[i] =
8398 8401 hba->auth_cfg.hash_priority[i];
8399 8402 }
8400 8403 }
8401 8404
8402 8405 /* Check dh_group_priority */
8403 8406 for (i = 0; i < 8; i++) {
8404 8407 if (auth_cfg->dh_group_priority[i] > DFC_AUTH_GROUP_MAX) {
8405 8408 /* Set to current default */
8406 8409 auth_cfg->dh_group_priority[i] =
8407 8410 hba->auth_cfg.dh_group_priority[i];
8408 8411 }
8409 8412 }
8410 8413
8411 8414 /* Check reauthenticate_time_interval */
8412 8415 if (auth_cfg->reauthenticate_time_interval <
8413 8416 cfg[CFG_AUTH_INTERVAL].low) {
8414 8417 auth_cfg->reauthenticate_time_interval =
8415 8418 cfg[CFG_AUTH_INTERVAL].current;
8416 8419 } else if (auth_cfg->reauthenticate_time_interval >
8417 8420 cfg[CFG_AUTH_INTERVAL].hi) {
8418 8421 auth_cfg->reauthenticate_time_interval =
8419 8422 cfg[CFG_AUTH_INTERVAL].current;
8420 8423 }
8421 8424 emlxs_auth_cfg_print(hba, auth_cfg);
8422 8425
8423 8426 out:
8424 8427
8425 8428 if (errors) {
8426 8429 bzero(auth_cfg, sizeof (emlxs_auth_cfg_t));
8427 8430 return (0);
8428 8431 }
8429 8432 return (1);
8430 8433
8431 8434 } /* emlxs_auth_cfg_parse() */
8432 8435
8433 8436
8434 8437 /* **************************** AUTH KEY MANAGEMENT ************************* */
8435 8438
8436 8439 /* auth_lock must be held */
8437 8440 extern emlxs_auth_key_t *
8438 8441 emlxs_auth_key_find(emlxs_port_t *port, uint8_t *rwwpn)
8439 8442 {
8440 8443 emlxs_hba_t *hba = HBA;
8441 8444 emlxs_auth_key_t *auth_key;
8442 8445
8443 8446 if (rwwpn) {
8444 8447 /* lwwpn, rwwpn */
8445 8448 auth_key = emlxs_auth_key_get(hba,
8446 8449 (uint8_t *)&port->wwpn, (uint8_t *)rwwpn);
8447 8450
8448 8451 if (auth_key) {
8449 8452 emlxs_auth_key_print(hba, auth_key);
8450 8453 return (auth_key);
8451 8454 }
8452 8455 /* null, rwwpn */
8453 8456 auth_key = emlxs_auth_key_get(hba,
8454 8457 (uint8_t *)emlxs_null_wwn, (uint8_t *)rwwpn);
8455 8458
8456 8459 if (auth_key) {
8457 8460 emlxs_auth_key_print(hba, auth_key);
8458 8461 return (auth_key);
8459 8462 }
8460 8463 }
8461 8464 /* lwwpn, null */
8462 8465 auth_key = emlxs_auth_key_get(hba,
8463 8466 (uint8_t *)&port->wwpn, (uint8_t *)emlxs_null_wwn);
8464 8467
8465 8468 if (auth_key) {
8466 8469 emlxs_auth_key_print(hba, auth_key);
8467 8470 return (auth_key);
8468 8471 }
8469 8472 return (NULL);
8470 8473
8471 8474 } /* emlxs_auth_key_find() */
8472 8475
8473 8476
8474 8477 static void
8475 8478 emlxs_auth_key_init(emlxs_hba_t *hba)
8476 8479 {
8477 8480 emlxs_auth_key_t *auth_key;
8478 8481
8479 8482 /* Destroy old table if one exists */
8480 8483 emlxs_auth_key_fini(hba);
8481 8484
8482 8485 mutex_enter(&hba->auth_lock);
8483 8486
8484 8487 /* Zero default entry */
8485 8488 auth_key = &hba->auth_key;
8486 8489 bzero(auth_key, sizeof (emlxs_auth_key_t));
8487 8490 auth_key->next = auth_key;
8488 8491 auth_key->prev = auth_key;
8489 8492
8490 8493 /* Configure the default entry */
8491 8494 auth_key->local_password_type = PASSWORD_TYPE_IGNORE;
8492 8495 auth_key->remote_password_type = PASSWORD_TYPE_IGNORE;
8493 8496
8494 8497 emlxs_auth_key_read(hba);
8495 8498
8496 8499 mutex_exit(&hba->auth_lock);
8497 8500
8498 8501 return;
8499 8502
8500 8503 } /* emlxs_auth_key_init() */
8501 8504
8502 8505
8503 8506 static void
8504 8507 emlxs_auth_key_fini(emlxs_hba_t *hba)
8505 8508 {
8506 8509 emlxs_auth_key_t *auth_key = hba->auth_key.next;
8507 8510 emlxs_auth_key_t *next;
8508 8511
8509 8512 mutex_enter(&hba->auth_lock);
8510 8513
8511 8514 while (auth_key && auth_key != &hba->auth_key) {
8512 8515 next = auth_key->next;
8513 8516 emlxs_auth_key_destroy(hba, auth_key);
8514 8517 auth_key = next;
8515 8518 }
8516 8519
8517 8520 mutex_exit(&hba->auth_lock);
8518 8521
8519 8522 return;
8520 8523
8521 8524 } /* emlxs_auth_key_fini() */
8522 8525
8523 8526
8524 8527 static void
8525 8528 emlxs_auth_key_print(emlxs_hba_t *hba, emlxs_auth_key_t *auth_key)
8526 8529 {
8527 8530 emlxs_port_t *port = &PPORT;
8528 8531 char s_lwwpn[32];
8529 8532 char s_rwwpn[32];
8530 8533
8531 8534 EMLXS_MSGF(EMLXS_CONTEXT,
8532 8535 &emlxs_fcsp_detail_msg,
8533 8536 "auth-key> %s:%s:%x:*%d chars*:%x:*%d chars*",
8534 8537 emlxs_wwn_xlate(s_lwwpn, (uint8_t *)&auth_key->local_entity),
8535 8538 emlxs_wwn_xlate(s_rwwpn, (uint8_t *)&auth_key->remote_entity),
8536 8539 auth_key->local_password_type, auth_key->local_password_length,
8537 8540 auth_key->remote_password_type, auth_key->remote_password_length);
8538 8541
8539 8542 return;
8540 8543
8541 8544 } /* emlxs_auth_key_print() */
8542 8545
8543 8546
8544 8547 /* auth_lock must be held */
8545 8548 static emlxs_auth_key_t *
8546 8549 emlxs_auth_key_get(emlxs_hba_t *hba, uint8_t *lwwpn, uint8_t *rwwpn)
8547 8550 {
8548 8551 emlxs_auth_key_t *auth_key;
8549 8552
8550 8553 if (!lwwpn || !rwwpn) {
8551 8554 return (NULL);
8552 8555 }
8553 8556 /* Check for default entry */
8554 8557 if ((bcmp(lwwpn, emlxs_null_wwn, 8) == 0) &&
8555 8558 (bcmp(rwwpn, emlxs_null_wwn, 8) == 0)) {
8556 8559 return (&hba->auth_key);
8557 8560 }
8558 8561 for (auth_key = hba->auth_key.next; auth_key !=
8559 8562 &hba->auth_key; auth_key = auth_key->next) {
8560 8563 /* Find pwd entry for this local port */
8561 8564
8562 8565 /* Check for exact wwpn match */
8563 8566 if (bcmp((void *)&auth_key->local_entity,
8564 8567 (void *)lwwpn, 8) != 0) {
8565 8568 continue;
8566 8569 }
8567 8570 /* Find pwd entry for remote port */
8568 8571
8569 8572 /* Check for exact wwpn match */
8570 8573 if (bcmp((void *)&auth_key->remote_entity,
8571 8574 (void *)rwwpn, 8) != 0) {
8572 8575 continue;
8573 8576 }
8574 8577 return (auth_key);
8575 8578 }
8576 8579
8577 8580 return (NULL);
8578 8581
8579 8582 } /* emlxs_auth_key_get() */
8580 8583
8581 8584
8582 8585 /* auth_lock must be held */
8583 8586 static emlxs_auth_key_t *
8584 8587 emlxs_auth_key_create(emlxs_hba_t *hba, uint8_t *lwwpn, uint8_t *rwwpn)
8585 8588 {
8586 8589 emlxs_auth_key_t *auth_key;
8587 8590
8588 8591 /* First check if entry already exists */
8589 8592 auth_key = emlxs_auth_key_get(hba, lwwpn, rwwpn);
8590 8593
8591 8594 if (auth_key) {
8592 8595 return (auth_key);
8593 8596 }
8594 8597 /* Allocate entry */
8595 8598 auth_key = (emlxs_auth_key_t *)kmem_zalloc(sizeof (emlxs_auth_key_t),
8596 8599 KM_NOSLEEP);
8597 8600
8598 8601 if (!auth_key) {
8599 8602 return (NULL);
8600 8603 }
8601 8604 /* Initialize name pair */
8602 8605 if (lwwpn) {
8603 8606 bcopy((void *)lwwpn, (void *)&auth_key->local_entity, 8);
8604 8607 }
8605 8608 if (rwwpn) {
8606 8609 bcopy((void *)rwwpn, (void *)&auth_key->remote_entity, 8);
8607 8610 }
8608 8611 /* Initialize type */
8609 8612 auth_key->local_password_type = PASSWORD_TYPE_IGNORE;
8610 8613 auth_key->remote_password_type = PASSWORD_TYPE_IGNORE;
8611 8614
8612 8615 /* Add to list */
8613 8616 auth_key->next = &hba->auth_key;
8614 8617 auth_key->prev = hba->auth_key.prev;
8615 8618 hba->auth_key.prev->next = auth_key;
8616 8619 hba->auth_key.prev = auth_key;
8617 8620 hba->auth_key_count++;
8618 8621
8619 8622 return (auth_key);
8620 8623
8621 8624 } /* emlxs_auth_key_create() */
8622 8625
8623 8626
8624 8627 /* auth_lock must be held */
8625 8628 static void
8626 8629 emlxs_auth_key_destroy(emlxs_hba_t *hba, emlxs_auth_key_t *auth_key)
8627 8630 {
8628 8631
8629 8632 if (!auth_key) {
8630 8633 return;
8631 8634 }
8632 8635 if (auth_key == &hba->auth_key) {
8633 8636 return;
8634 8637 }
8635 8638 /* Remove from list */
8636 8639 auth_key->next->prev = auth_key->prev;
8637 8640 auth_key->prev->next = auth_key->next;
8638 8641 hba->auth_key_count--;
8639 8642
8640 8643 /* Remove node binding */
8641 8644 if (auth_key->node &&
8642 8645 auth_key->node->nlp_active &&
8643 8646 (auth_key->node->node_dhc.parent_auth_key == auth_key)) {
8644 8647 auth_key->node->node_dhc.parent_auth_key = NULL;
8645 8648 }
8646 8649 bzero(auth_key, sizeof (emlxs_auth_key_t));
8647 8650 kmem_free(auth_key, sizeof (emlxs_auth_key_t));
8648 8651
8649 8652 return;
8650 8653
8651 8654 } /* emlxs_auth_key_destroy() */
8652 8655
8653 8656
8654 8657 /* auth_lock must be held */
8655 8658 static void
8656 8659 emlxs_auth_key_read(emlxs_hba_t *hba)
8657 8660 {
8658 8661 emlxs_port_t *port = &PPORT;
8659 8662 char **arrayp;
8660 8663 emlxs_auth_key_t auth_key;
8661 8664 emlxs_auth_key_t *auth_key2;
8662 8665 uint32_t cnt;
8663 8666 uint32_t rval;
8664 8667 char buffer[64];
8665 8668 char *prop_str;
8666 8669 uint32_t i;
8667 8670
8668 8671 /* Check for the per adapter setting */
8669 8672 (void) sprintf(buffer, "%s%d-auth-keys", DRIVER_NAME, hba->ddiinst);
8670 8673 cnt = 0;
8671 8674 arrayp = NULL;
8672 8675 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
8673 8676 (DDI_PROP_DONTPASS),
8674 8677 buffer, &arrayp, &cnt);
8675 8678
8676 8679 if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
8677 8680 /* Check for the global setting */
8678 8681 cnt = 0;
8679 8682 arrayp = NULL;
8680 8683 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
8681 8684 (DDI_PROP_DONTPASS),
8682 8685 "auth-keys", &arrayp, &cnt);
8683 8686 }
8684 8687 if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
8685 8688 return;
8686 8689 }
8687 8690 for (i = 0; i < cnt; i++) {
8688 8691 prop_str = arrayp[i];
8689 8692 if (prop_str == NULL) {
8690 8693 break;
8691 8694 }
8692 8695 /* parse the string */
8693 8696 if (emlxs_auth_key_parse(hba, &auth_key, prop_str) == 0) {
8694 8697 EMLXS_MSGF(EMLXS_CONTEXT,
8695 8698 &emlxs_attach_msg,
8696 8699 "Error parsing auth_keys property. entry=%d", i);
8697 8700 continue;
8698 8701 }
8699 8702 auth_key2 = emlxs_auth_key_create(hba,
8700 8703 (uint8_t *)&auth_key.local_entity,
8701 8704 (uint8_t *)&auth_key.remote_entity);
8702 8705
8703 8706 if (!auth_key2) {
8704 8707 EMLXS_MSGF(EMLXS_CONTEXT,
8705 8708 &emlxs_attach_msg,
8706 8709 "Out of memory parsing auth_keys property. %d",
8707 8710 i);
8708 8711 return;
8709 8712 }
8710 8713 auth_key.next = auth_key2->next;
8711 8714 auth_key.prev = auth_key2->prev;
8712 8715 bcopy((uint8_t *)&auth_key,
8713 8716 (uint8_t *)auth_key2, sizeof (emlxs_auth_key_t));
8714 8717 }
8715 8718
8716 8719 return;
8717 8720
8718 8721 } /* emlxs_auth_key_read() */
8719 8722
8720 8723
8721 8724 /* auth_lock must be held */
8722 8725 static uint32_t
8723 8726 emlxs_auth_key_parse(
8724 8727 emlxs_hba_t *hba,
8725 8728 emlxs_auth_key_t *auth_key,
8726 8729 char *prop_str)
8727 8730 {
8728 8731 emlxs_port_t *port = &PPORT;
8729 8732 uint32_t errors = 0;
8730 8733 uint32_t c1;
8731 8734 uint8_t *np;
8732 8735 uint32_t j;
8733 8736 uint32_t sum;
8734 8737 char *s;
8735 8738
8736 8739 s = prop_str;
8737 8740 bzero(auth_key, sizeof (emlxs_auth_key_t));
8738 8741
8739 8742 /* Read local wwpn */
8740 8743 np = (uint8_t *)&auth_key->local_entity;
8741 8744 for (j = 0; j < 8; j++) {
8742 8745 c1 = *s++;
8743 8746 if ((c1 >= '0') && (c1 <= '9')) {
8744 8747 sum = ((c1 - '0') << 4);
8745 8748 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8746 8749 sum = ((c1 - 'a' + 10) << 4);
8747 8750 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8748 8751 sum = ((c1 - 'A' + 10) << 4);
8749 8752 } else {
8750 8753 EMLXS_MSGF(EMLXS_CONTEXT,
8751 8754 &emlxs_attach_debug_msg,
8752 8755 "Cfg err: Invalid LWWPN found. %d %c",
8753 8756 j, c1);
8754 8757 errors++;
8755 8758 }
8756 8759
8757 8760 c1 = *s++;
8758 8761 if ((c1 >= '0') && (c1 <= '9')) {
8759 8762 sum |= (c1 - '0');
8760 8763 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8761 8764 sum |= (c1 - 'a' + 10);
8762 8765 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8763 8766 sum |= (c1 - 'A' + 10);
8764 8767 } else {
8765 8768 EMLXS_MSGF(EMLXS_CONTEXT,
8766 8769 &emlxs_attach_debug_msg,
8767 8770 "Cfg err: Invalid LWWPN found. %d %c",
8768 8771 j, c1);
8769 8772 errors++;
8770 8773 }
8771 8774
8772 8775 *np++ = (uint8_t)sum;
8773 8776 }
8774 8777
8775 8778 if (*s++ != ':') {
8776 8779 EMLXS_MSGF(EMLXS_CONTEXT,
8777 8780 &emlxs_attach_debug_msg,
8778 8781 "Cfg err: Invalid delimiter after LWWPN.");
8779 8782 goto out;
8780 8783 }
8781 8784 /* Read remote wwpn */
8782 8785 np = (uint8_t *)&auth_key->remote_entity;
8783 8786 for (j = 0; j < 8; j++) {
8784 8787 c1 = *s++;
8785 8788 if ((c1 >= '0') && (c1 <= '9')) {
8786 8789 sum = ((c1 - '0') << 4);
8787 8790 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8788 8791 sum = ((c1 - 'a' + 10) << 4);
8789 8792 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8790 8793 sum = ((c1 - 'A' + 10) << 4);
8791 8794 } else {
8792 8795 EMLXS_MSGF(EMLXS_CONTEXT,
8793 8796 &emlxs_attach_debug_msg,
8794 8797 "Cfg err: Invalid RWWPN found.%d %c",
8795 8798 j, c1);
8796 8799 errors++;
8797 8800 }
8798 8801
8799 8802 c1 = *s++;
8800 8803 if ((c1 >= '0') && (c1 <= '9')) {
8801 8804 sum |= (c1 - '0');
8802 8805 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8803 8806 sum |= (c1 - 'a' + 10);
8804 8807 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8805 8808 sum |= (c1 - 'A' + 10);
8806 8809 } else {
8807 8810 EMLXS_MSGF(EMLXS_CONTEXT,
8808 8811 &emlxs_attach_debug_msg,
8809 8812 "Cfg err: Invalid RWWPN found. %d %c",
8810 8813 j, c1);
8811 8814 errors++;
8812 8815 }
8813 8816
8814 8817 *np++ = (uint8_t)sum;
8815 8818 }
8816 8819
8817 8820 if (*s++ != ':') {
8818 8821 EMLXS_MSGF(EMLXS_CONTEXT,
8819 8822 &emlxs_attach_debug_msg,
8820 8823 "Cfg err: Invalid delimiter after RWWPN.");
8821 8824 goto out;
8822 8825 }
8823 8826 /* Read lpwd type (%x) */
8824 8827 sum = 0;
8825 8828 do {
8826 8829 c1 = *s++;
8827 8830 if ((c1 >= '0') && (c1 <= '9')) {
8828 8831 sum = (sum << 4) + (c1 - '0');
8829 8832 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8830 8833 sum = (sum << 4) + (c1 - 'a' + 10);
8831 8834 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8832 8835 sum = (sum << 4) + (c1 - 'A' + 10);
8833 8836 } else {
8834 8837 EMLXS_MSGF(EMLXS_CONTEXT,
8835 8838 &emlxs_attach_debug_msg,
8836 8839 "Cfg err: Invalid lpwd type found. %c %d",
8837 8840 c1, sum);
8838 8841
8839 8842 errors++;
8840 8843 }
8841 8844
8842 8845 } while (*s != ':' && *s != 0);
8843 8846 auth_key->local_password_type = (uint16_t)sum;
8844 8847
8845 8848 if (*s++ != ':') {
8846 8849 EMLXS_MSGF(EMLXS_CONTEXT,
8847 8850 &emlxs_attach_debug_msg,
8848 8851 "Cfg err: Invalid delimiter after lpwd type.");
8849 8852 goto out;
8850 8853 }
8851 8854 /* Read lpwd */
8852 8855 np = (uint8_t *)&auth_key->local_password;
8853 8856 j = 0;
8854 8857 switch (auth_key->local_password_type) {
8855 8858 case 1: /* ACSII */
8856 8859 while (*s != ':' && *s != 0) {
8857 8860 *np++ = *s++;
8858 8861 j++;
8859 8862 }
8860 8863 break;
8861 8864
8862 8865 case 2: /* Hex */
8863 8866 do {
8864 8867 c1 = *s++;
8865 8868 if ((c1 >= '0') && (c1 <= '9')) {
8866 8869 sum = ((c1 - '0') << 4);
8867 8870 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8868 8871 sum = ((c1 - 'a' + 10) << 4);
8869 8872 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8870 8873 sum = ((c1 - 'A' + 10) << 4);
8871 8874 } else {
8872 8875 EMLXS_MSGF(EMLXS_CONTEXT,
8873 8876 &emlxs_attach_debug_msg,
8874 8877 "Cfg err: Invalid lpwd found. %d %c",
8875 8878 j, c1);
8876 8879 errors++;
8877 8880 }
8878 8881
8879 8882 c1 = *s++;
8880 8883 if ((c1 >= '0') && (c1 <= '9')) {
8881 8884 sum |= (c1 - '0');
8882 8885 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8883 8886 sum |= (c1 - 'a' + 10);
8884 8887 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8885 8888 sum |= (c1 - 'A' + 10);
8886 8889 } else {
8887 8890 EMLXS_MSGF(EMLXS_CONTEXT,
8888 8891 &emlxs_attach_debug_msg,
8889 8892 "Cfg err: Invalid lpwd found. %d %c",
8890 8893 j, c1);
8891 8894 errors++;
8892 8895 }
8893 8896
8894 8897 *np++ = (uint8_t)sum;
8895 8898 j++;
8896 8899
8897 8900 } while (*s != ':' && *s != 0);
8898 8901
8899 8902 break;
8900 8903
8901 8904 case 0: /* Ignore */
8902 8905 case 3: /* Ignore */
8903 8906 break;
8904 8907
8905 8908 default:
8906 8909 EMLXS_MSGF(EMLXS_CONTEXT,
8907 8910 &emlxs_attach_debug_msg,
8908 8911 "Config error: Invalid lpwd type found. type=%x",
8909 8912 auth_key->local_password_type);
8910 8913
8911 8914 errors++;
8912 8915 goto out;
8913 8916 }
8914 8917 auth_key->local_password_length = (uint16_t)j;
8915 8918
8916 8919 if (*s++ != ':') {
8917 8920 EMLXS_MSGF(EMLXS_CONTEXT,
8918 8921 &emlxs_attach_debug_msg,
8919 8922 "Config error: Invalid delimiter after lpwd.");
8920 8923 goto out;
8921 8924 }
8922 8925 /* Read rpwd type (%x) */
8923 8926 sum = 0;
8924 8927 do {
8925 8928 c1 = *s++;
8926 8929 if ((c1 >= '0') && (c1 <= '9')) {
8927 8930 sum = (sum << 4) + (c1 - '0');
8928 8931 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8929 8932 sum = (sum << 4) + (c1 - 'a' + 10);
8930 8933 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8931 8934 sum = (sum << 4) + (c1 - 'A' + 10);
8932 8935 } else {
8933 8936 EMLXS_MSGF(EMLXS_CONTEXT,
8934 8937 &emlxs_attach_debug_msg,
8935 8938 "Config error: Invalid rpwd type found. %c %d",
8936 8939 c1, sum);
8937 8940
8938 8941 errors++;
8939 8942 }
8940 8943
8941 8944 } while (*s != ':' && *s != 0);
8942 8945 auth_key->remote_password_type = (uint16_t)sum;
8943 8946
8944 8947 if (*s++ != ':') {
8945 8948 EMLXS_MSGF(EMLXS_CONTEXT,
8946 8949 &emlxs_attach_debug_msg,
8947 8950 "Config error: Invalid delimiter after rpwd type.");
8948 8951 goto out;
8949 8952 }
8950 8953 /* Read rpwd */
8951 8954 np = (uint8_t *)&auth_key->remote_password;
8952 8955 j = 0;
8953 8956 switch (auth_key->remote_password_type) {
8954 8957 case 1: /* ACSII */
8955 8958 while (*s != ':' && *s != 0) {
8956 8959 *np++ = *s++;
8957 8960 j++;
8958 8961 }
8959 8962 break;
8960 8963
8961 8964 case 2: /* Hex */
8962 8965 do {
8963 8966 c1 = *s++;
8964 8967 if ((c1 >= '0') && (c1 <= '9')) {
8965 8968 sum = ((c1 - '0') << 4);
8966 8969 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8967 8970 sum = ((c1 - 'a' + 10) << 4);
8968 8971 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8969 8972 sum = ((c1 - 'A' + 10) << 4);
8970 8973 } else {
8971 8974 EMLXS_MSGF(EMLXS_CONTEXT,
8972 8975 &emlxs_attach_debug_msg,
8973 8976 "Cfg err: Invalid rpwd found. %d %c",
8974 8977 j, c1);
8975 8978 errors++;
8976 8979 }
8977 8980
8978 8981 c1 = *s++;
8979 8982 if ((c1 >= '0') && (c1 <= '9')) {
8980 8983 sum |= (c1 - '0');
8981 8984 } else if ((c1 >= 'a') && (c1 <= 'f')) {
8982 8985 sum |= (c1 - 'a' + 10);
8983 8986 } else if ((c1 >= 'A') && (c1 <= 'F')) {
8984 8987 sum |= (c1 - 'A' + 10);
8985 8988 } else {
8986 8989 EMLXS_MSGF(EMLXS_CONTEXT,
8987 8990 &emlxs_attach_debug_msg,
8988 8991 "Cfg err: Invalid rpwd found. %d %c",
8989 8992 j, c1);
8990 8993 errors++;
8991 8994 }
8992 8995
8993 8996 *np++ = (uint8_t)sum;
8994 8997 j++;
8995 8998
8996 8999 } while (*s != ':' && *s != 0);
8997 9000
8998 9001 break;
8999 9002
9000 9003 case 0: /* Ignore */
9001 9004 case 3: /* Ignore */
9002 9005 break;
9003 9006
9004 9007 default:
9005 9008 EMLXS_MSGF(EMLXS_CONTEXT,
9006 9009 &emlxs_attach_debug_msg,
9007 9010 "Cfg error: Invalid rpwd type found. type=%x",
9008 9011 auth_key->remote_password_type);
9009 9012
9010 9013 errors++;
9011 9014 goto out;
9012 9015 }
9013 9016 auth_key->remote_password_length = (uint16_t)j;
9014 9017
9015 9018 if (errors) {
9016 9019 goto out;
9017 9020 }
9018 9021 /* Verify values */
9019 9022 if (auth_key->local_password_type == 0 ||
9020 9023 auth_key->local_password_type > 3 ||
9021 9024 auth_key->local_password_length == 0) {
9022 9025
9023 9026 auth_key->local_password_type = 3;
9024 9027 auth_key->local_password_length = 0;
9025 9028 bzero(auth_key->local_password,
9026 9029 sizeof (auth_key->local_password));
9027 9030 }
9028 9031 if (auth_key->remote_password_type == 0 ||
9029 9032 auth_key->remote_password_type > 3 ||
9030 9033 auth_key->remote_password_length == 0) {
9031 9034
9032 9035 auth_key->remote_password_type = 3;
9033 9036 auth_key->remote_password_length = 0;
9034 9037 bzero(auth_key->remote_password,
9035 9038 sizeof (auth_key->remote_password));
9036 9039 }
9037 9040 /* Display entry */
9038 9041 emlxs_auth_key_print(hba, auth_key);
9039 9042
9040 9043 out:
9041 9044 if (errors) {
9042 9045 bzero(auth_key, sizeof (emlxs_auth_key_t));
9043 9046 return (0);
9044 9047 }
9045 9048 return (1);
9046 9049
9047 9050 } /* emlxs_auth_key_parse() */
9048 9051
9049 9052
9050 9053 /* ************************** AUTH DFCLIB SUPPORT *********************** */
9051 9054
9052 9055 /* Provides DFC support for emlxs_dfc_init_auth() */
9053 9056 extern uint32_t
9054 9057 emlxs_dhc_init_auth(emlxs_hba_t *hba, uint8_t *lwwpn, uint8_t *rwwpn)
9055 9058 {
9056 9059 emlxs_port_t *port = &PPORT;
9057 9060 emlxs_config_t *cfg = &CFG;
9058 9061 NODELIST *ndlp;
9059 9062 uint32_t vpi;
9060 9063 char s_wwpn[64];
9061 9064
9062 9065 /* Return is authentication is not enabled */
9063 9066 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9064 9067 EMLXS_MSGF(EMLXS_CONTEXT,
9065 9068 &emlxs_fcsp_debug_msg,
9066 9069 "emlxs_dhc_init_auth. Auth disabled.");
9067 9070
9068 9071 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9069 9072 }
9070 9073 /* Scan for lwwpn match */
9071 9074 for (vpi = 0; vpi < MAX_VPORTS; vpi++) {
9072 9075 port = &VPORT(vpi);
9073 9076
9074 9077 if (!(port->flag & EMLXS_PORT_BOUND)) {
9075 9078 continue;
9076 9079 }
9077 9080 if (bcmp((uint8_t *)&port->wwpn, lwwpn, 8) == 0) {
9078 9081 break;
9079 9082 }
9080 9083 }
9081 9084
9082 9085 if (vpi == MAX_VPORTS) {
9083 9086 EMLXS_MSGF(EMLXS_CONTEXT,
9084 9087 &emlxs_dfc_error_msg,
9085 9088 "emlxs_dhc_init_auth: lwwpn not found. %s",
9086 9089 emlxs_wwn_xlate(s_wwpn, lwwpn));
9087 9090
9088 9091 return (DFC_AUTH_WWN_NOT_FOUND);
9089 9092 }
9090 9093 if (bcmp(rwwpn, emlxs_fabric_wwn, 8) == 0) {
9091 9094 /* Scan for fabric node */
9092 9095 if ((ndlp = emlxs_node_find_did(port, FABRIC_DID)) == NULL) {
9093 9096 EMLXS_MSGF(EMLXS_CONTEXT,
9094 9097 &emlxs_dfc_error_msg,
9095 9098 "emlxs_dhc_init_auth: fabric node not found.");
9096 9099
9097 9100 return (DFC_AUTH_WWN_NOT_FOUND);
9098 9101 }
9099 9102 } else {
9100 9103 /* Scan for rwwpn match */
9101 9104 if ((ndlp = emlxs_node_find_wwpn(port, rwwpn)) == NULL) {
9102 9105 EMLXS_MSGF(EMLXS_CONTEXT,
9103 9106 &emlxs_dfc_error_msg,
9104 9107 "emlxs_dhc_init_auth: rwwpn not found. %s",
9105 9108 emlxs_wwn_xlate(s_wwpn, rwwpn));
9106 9109
9107 9110 return (DFC_AUTH_WWN_NOT_FOUND);
9108 9111 }
9109 9112 }
9110 9113
9111 9114 if ((ndlp->nlp_DID != FABRIC_DID) &&
9112 9115 ((port->port_dhc.state != ELX_FABRIC_AUTH_SUCCESS))) {
9113 9116 return (DFC_IO_ERROR);
9114 9117 }
9115 9118 if (ndlp->node_dhc.state >= NODE_STATE_AUTH_NEGOTIATE_ISSUE) {
9116 9119 return (DFC_AUTH_AUTHENTICATION_GOINGON);
9117 9120 }
9118 9121 if (ndlp->node_dhc.state == NODE_STATE_AUTH_SUCCESS) {
9119 9122 ndlp->node_dhc.nlp_reauth_status = NLP_HOST_REAUTH_IN_PROGRESS;
9120 9123 }
9121 9124 /* Attempt to start authentication */
9122 9125 if (emlxs_dhc_auth_start(port, ndlp, NULL, NULL) != 0) {
9123 9126 return (DFC_IO_ERROR);
9124 9127 }
9125 9128 return (0);
9126 9129
9127 9130 } /* emlxs_dhc_init_auth() */
9128 9131
9129 9132
9130 9133 /* Provides DFC support for emlxs_dfc_get_auth_cfg() */
9131 9134 extern uint32_t
9132 9135 emlxs_dhc_get_auth_cfg(emlxs_hba_t *hba, dfc_fcsp_config_t *fcsp_cfg)
9133 9136 {
9134 9137 emlxs_port_t *port = &PPORT;
9135 9138 emlxs_config_t *cfg = &CFG;
9136 9139 char s_lwwpn[64];
9137 9140 char s_rwwpn[64];
9138 9141 emlxs_auth_cfg_t *auth_cfg;
9139 9142 uint32_t i;
9140 9143
9141 9144 /* Return is authentication is not enabled */
9142 9145 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9143 9146 EMLXS_MSGF(EMLXS_CONTEXT,
9144 9147 &emlxs_fcsp_debug_msg,
9145 9148 "emlxs_dhc_get_auth_cfg. Auth disabled.");
9146 9149
9147 9150 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9148 9151 }
9149 9152 mutex_enter(&hba->auth_lock);
9150 9153
9151 9154 auth_cfg = emlxs_auth_cfg_get(hba,
9152 9155 (uint8_t *)&fcsp_cfg->lwwpn, (uint8_t *)&fcsp_cfg->rwwpn);
9153 9156
9154 9157 if (!auth_cfg) {
9155 9158 EMLXS_MSGF(EMLXS_CONTEXT,
9156 9159 &emlxs_dfc_error_msg,
9157 9160 "emlxs_dhc_get_auth_cfg: entry not found. %s:%s",
9158 9161 emlxs_wwn_xlate(s_lwwpn,
9159 9162 (uint8_t *)&fcsp_cfg->lwwpn),
9160 9163 emlxs_wwn_xlate(s_rwwpn,
9161 9164 (uint8_t *)&fcsp_cfg->rwwpn));
9162 9165
9163 9166 mutex_exit(&hba->auth_lock);
9164 9167
9165 9168 return (DFC_AUTH_NOT_CONFIGURED);
9166 9169 }
9167 9170 fcsp_cfg->auth_tov = auth_cfg->authentication_timeout;
9168 9171 fcsp_cfg->auth_mode = auth_cfg->authentication_mode;
9169 9172 fcsp_cfg->auth_bidir = auth_cfg->bidirectional;
9170 9173
9171 9174 for (i = 0; i < 4; i++) {
9172 9175 fcsp_cfg->type_priority[i] =
9173 9176 auth_cfg->authentication_type_priority[i];
9174 9177 fcsp_cfg->hash_priority[i] =
9175 9178 auth_cfg->hash_priority[i];
9176 9179 }
9177 9180
9178 9181 for (i = 0; i < 8; i++) {
9179 9182 fcsp_cfg->group_priority[i] = auth_cfg->dh_group_priority[i];
9180 9183 }
9181 9184
9182 9185 fcsp_cfg->reauth_tov = auth_cfg->reauthenticate_time_interval;
9183 9186
9184 9187 mutex_exit(&hba->auth_lock);
9185 9188
9186 9189 return (0);
9187 9190
9188 9191 } /* emlxs_dhc_get_auth_cfg() */
9189 9192
9190 9193
9191 9194 /* Provides DFC support for emlxs_dfc_set_auth_cfg() */
9192 9195 extern uint32_t
9193 9196 emlxs_dhc_add_auth_cfg(
9194 9197 emlxs_hba_t *hba,
9195 9198 dfc_fcsp_config_t *fcsp_cfg,
9196 9199 dfc_password_t *dfc_pwd)
9197 9200 {
9198 9201 emlxs_port_t *port = &PPORT;
9199 9202 emlxs_config_t *cfg = &CFG;
9200 9203 emlxs_auth_cfg_t *auth_cfg;
9201 9204 emlxs_auth_key_t *auth_key;
9202 9205 uint32_t i;
9203 9206 NODELIST *ndlp;
9204 9207
9205 9208 /* Return if authentication is not enabled */
9206 9209 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9207 9210 EMLXS_MSGF(EMLXS_CONTEXT,
9208 9211 &emlxs_fcsp_debug_msg,
9209 9212 "emlxs_dhc_add_auth_cfg. Auth disabled.");
9210 9213
9211 9214 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9212 9215 }
9213 9216 mutex_enter(&hba->auth_lock);
9214 9217
9215 9218 auth_key = emlxs_auth_key_get(hba,
9216 9219 (uint8_t *)&fcsp_cfg->lwwpn, (uint8_t *)&fcsp_cfg->rwwpn);
9217 9220
9218 9221 if (auth_key &&
9219 9222 (auth_key->local_password_type == PASSWORD_TYPE_ASCII ||
9220 9223 auth_key->local_password_type == PASSWORD_TYPE_BINARY)) {
9221 9224
9222 9225 /* Verify local password */
9223 9226 if ((auth_key->local_password_length != dfc_pwd->length) ||
9224 9227 (auth_key->local_password_type != dfc_pwd->type) ||
9225 9228 bcmp(dfc_pwd->password, auth_key->local_password,
9226 9229 dfc_pwd->length)) {
9227 9230 EMLXS_MSGF(EMLXS_CONTEXT,
9228 9231 &emlxs_dfc_error_msg,
9229 9232 "emlxs_dhc_add_auth_cfg: Invalid local password.");
9230 9233
9231 9234 mutex_exit(&hba->auth_lock);
9232 9235
9233 9236 return (DFC_AUTH_COMPARE_FAILED);
9234 9237 }
9235 9238 }
9236 9239 /* Create entry */
9237 9240 auth_cfg = emlxs_auth_cfg_create(hba,
9238 9241 (uint8_t *)&fcsp_cfg->lwwpn,
9239 9242 (uint8_t *)&fcsp_cfg->rwwpn);
9240 9243
9241 9244 if (!auth_cfg) {
9242 9245 EMLXS_MSGF(EMLXS_CONTEXT,
9243 9246 &emlxs_dfc_error_msg,
9244 9247 "emlxs_dhc_add_auth_cfg: Out of memory.");
9245 9248
9246 9249 mutex_exit(&hba->auth_lock);
9247 9250
9248 9251 return (DFC_SYSRES_ERROR);
9249 9252 }
9250 9253 /* Init entry */
9251 9254 auth_cfg->authentication_timeout = fcsp_cfg->auth_tov;
9252 9255 auth_cfg->authentication_mode = fcsp_cfg->auth_mode;
9253 9256 auth_cfg->bidirectional = fcsp_cfg->auth_bidir;
9254 9257
9255 9258 for (i = 0; i < 4; i++) {
9256 9259 auth_cfg->authentication_type_priority[i] =
9257 9260 fcsp_cfg->type_priority[i];
9258 9261 auth_cfg->hash_priority[i] =
9259 9262 fcsp_cfg->hash_priority[i];
9260 9263 }
9261 9264
9262 9265 for (i = 0; i < 8; i++) {
9263 9266 auth_cfg->dh_group_priority[i] = fcsp_cfg->group_priority[i];
9264 9267 }
9265 9268
9266 9269 auth_cfg->reauthenticate_time_interval = fcsp_cfg->reauth_tov;
9267 9270
9268 9271 emlxs_auth_cfg_print(hba, auth_cfg);
9269 9272
9270 9273 /* Cancel old reauth to restart the new one if necessary */
9271 9274
9272 9275 /* Scan for lwwpn match */
9273 9276 for (i = 0; i < MAX_VPORTS; i++) {
9274 9277 port = &VPORT(i);
9275 9278
9276 9279 if (!(port->flag & EMLXS_PORT_BOUND)) {
9277 9280 continue;
9278 9281 }
9279 9282 if (bcmp((uint8_t *)&fcsp_cfg->lwwpn,
9280 9283 (uint8_t *)&port->wwpn, 8)) {
9281 9284 continue;
9282 9285 }
9283 9286 /* Port match found */
9284 9287
9285 9288 if (bcmp((uint8_t *)&fcsp_cfg->rwwpn,
9286 9289 emlxs_fabric_wwn, 8) == 0) {
9287 9290 /* Scan for fabric node */
9288 9291 if ((ndlp = emlxs_node_find_did(port,
9289 9292 FABRIC_DID)) == NULL) {
9290 9293 break;
9291 9294 }
9292 9295 } else {
9293 9296 /* Scan for rwwpn match */
9294 9297 if ((ndlp = emlxs_node_find_wwpn(port,
9295 9298 (uint8_t *)&fcsp_cfg->rwwpn)) == NULL) {
9296 9299 break;
9297 9300 }
9298 9301 }
9299 9302
9300 9303 emlxs_dhc_set_reauth_time(port, ndlp, ENABLE);
9301 9304
9302 9305 break;
9303 9306 }
9304 9307
9305 9308 mutex_exit(&hba->auth_lock);
9306 9309
9307 9310 return (0);
9308 9311
9309 9312 } /* emlxs_dhc_add_auth_cfg() */
9310 9313
9311 9314
9312 9315 /* Provides DFC support for emlxs_dfc_set_auth_cfg() */
9313 9316 extern uint32_t
9314 9317 emlxs_dhc_delete_auth_cfg(
9315 9318 emlxs_hba_t *hba,
9316 9319 dfc_fcsp_config_t *fcsp_cfg,
9317 9320 dfc_password_t *dfc_pwd)
9318 9321 {
9319 9322 emlxs_port_t *port = &PPORT;
9320 9323 emlxs_config_t *cfg = &CFG;
9321 9324 char s_lwwpn[64];
9322 9325 char s_rwwpn[64];
9323 9326 emlxs_auth_key_t *auth_key;
9324 9327 emlxs_auth_cfg_t *auth_cfg;
9325 9328
9326 9329 /* Return is authentication is not enabled */
9327 9330 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9328 9331 EMLXS_MSGF(EMLXS_CONTEXT,
9329 9332 &emlxs_fcsp_debug_msg,
9330 9333 "emlxs_dhc_delete_auth_cfg. Auth disabled.");
9331 9334
9332 9335 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9333 9336 }
9334 9337 mutex_enter(&hba->auth_lock);
9335 9338
9336 9339 auth_key = emlxs_auth_key_get(hba,
9337 9340 (uint8_t *)&fcsp_cfg->lwwpn,
9338 9341 (uint8_t *)&fcsp_cfg->rwwpn);
9339 9342
9340 9343 if (auth_key &&
9341 9344 (auth_key->local_password_type == PASSWORD_TYPE_ASCII ||
9342 9345 auth_key->local_password_type ==
9343 9346 PASSWORD_TYPE_BINARY)) {
9344 9347 /* Verify local password */
9345 9348 if ((auth_key->local_password_length != dfc_pwd->length) ||
9346 9349 (auth_key->local_password_type != dfc_pwd->type) ||
9347 9350 bcmp(dfc_pwd->password,
9348 9351 auth_key->local_password,
9349 9352 dfc_pwd->length)) {
9350 9353
9351 9354 EMLXS_MSGF(EMLXS_CONTEXT,
9352 9355 &emlxs_dfc_error_msg,
9353 9356 "emlxs_dhc_delete_auth_cfg: Ivld local pwd.");
9354 9357
9355 9358 mutex_exit(&hba->auth_lock);
9356 9359
9357 9360 return (DFC_AUTH_COMPARE_FAILED);
9358 9361 }
9359 9362 }
9360 9363 auth_cfg = emlxs_auth_cfg_get(hba,
9361 9364 (uint8_t *)&fcsp_cfg->lwwpn, (uint8_t *)&fcsp_cfg->rwwpn);
9362 9365
9363 9366 if (!auth_cfg) {
9364 9367 EMLXS_MSGF(EMLXS_CONTEXT,
9365 9368 &emlxs_dfc_error_msg,
9366 9369 "emlxs_dhc_delete_auth_cfg: entry not found. %s:%s",
9367 9370 emlxs_wwn_xlate(s_lwwpn, (uint8_t *)&fcsp_cfg->lwwpn),
9368 9371 emlxs_wwn_xlate(s_rwwpn, (uint8_t *)&fcsp_cfg->rwwpn));
9369 9372
9370 9373 mutex_exit(&hba->auth_lock);
9371 9374
9372 9375 return (DFC_AUTH_WWN_NOT_FOUND);
9373 9376 }
9374 9377 /* Destroy cfg entry */
9375 9378 emlxs_auth_cfg_destroy(hba, auth_cfg);
9376 9379
9377 9380 /* Destroy pwd entry */
9378 9381 emlxs_auth_key_destroy(hba, auth_key);
9379 9382
9380 9383 mutex_exit(&hba->auth_lock);
9381 9384
9382 9385 return (0);
9383 9386
9384 9387 } /* emlxs_dhc_delete_auth_cfg() */
9385 9388
9386 9389
9387 9390 /* Provides DFC support for emlxs_dfc_get_auth_key() */
9388 9391 extern uint32_t
9389 9392 emlxs_dhc_get_auth_key(emlxs_hba_t *hba, dfc_auth_password_t *dfc_auth_pwd)
9390 9393 {
9391 9394 emlxs_port_t *port = &PPORT;
9392 9395 emlxs_config_t *cfg = &CFG;
9393 9396 char s_lwwpn[64];
9394 9397 char s_rwwpn[64];
9395 9398 emlxs_auth_key_t *auth_key;
9396 9399
9397 9400 /* Return is authentication is not enabled */
9398 9401 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9399 9402 EMLXS_MSGF(EMLXS_CONTEXT,
9400 9403 &emlxs_fcsp_debug_msg,
9401 9404 "emlxs_dhc_get_auth_key. Auth disabled.");
9402 9405
9403 9406 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9404 9407 }
9405 9408 mutex_enter(&hba->auth_lock);
9406 9409
9407 9410 auth_key = emlxs_auth_key_get(hba,
9408 9411 (uint8_t *)&dfc_auth_pwd->lwwpn,
9409 9412 (uint8_t *)&dfc_auth_pwd->rwwpn);
9410 9413
9411 9414 if (!auth_key) {
9412 9415 EMLXS_MSGF(EMLXS_CONTEXT,
9413 9416 &emlxs_dfc_error_msg,
9414 9417 "emlxs_dhc_get_auth_key: entry not found. %s:%s",
9415 9418 emlxs_wwn_xlate(s_lwwpn, (uint8_t *)&dfc_auth_pwd->lwwpn),
9416 9419 emlxs_wwn_xlate(s_rwwpn, (uint8_t *)&dfc_auth_pwd->rwwpn));
9417 9420
9418 9421 mutex_exit(&hba->auth_lock);
9419 9422
9420 9423 return (DFC_AUTH_NOT_CONFIGURED);
9421 9424 }
9422 9425 dfc_auth_pwd->lpw.length = auth_key->local_password_length;
9423 9426 dfc_auth_pwd->lpw.type = auth_key->local_password_type;
9424 9427 /*
9425 9428 * bcopy(auth_key->local_password, dfc_auth_pwd->lpw.password,
9426 9429 * dfc_auth_pwd->lpw.length);
9427 9430 */
9428 9431
9429 9432 dfc_auth_pwd->rpw.length = auth_key->remote_password_length;
9430 9433 dfc_auth_pwd->rpw.type = auth_key->remote_password_type;
9431 9434 /*
9432 9435 * bcopy(auth_key->remote_password, dfc_auth_pwd->rpw.password,
9433 9436 * dfc_auth_pwd->rpw.length);
9434 9437 */
9435 9438
9436 9439 dfc_auth_pwd->lpw_new.length = auth_key->local_password_length;
9437 9440 dfc_auth_pwd->lpw_new.type = auth_key->local_password_type;
9438 9441 /*
9439 9442 * bcopy(auth_key->local_password, dfc_auth_pwd->lpw_new.password,
9440 9443 * dfc_auth_pwd->lpw_new.length);
9441 9444 */
9442 9445
9443 9446 dfc_auth_pwd->rpw_new.length = auth_key->remote_password_length;
9444 9447 dfc_auth_pwd->rpw_new.type = auth_key->remote_password_type;
9445 9448 /*
9446 9449 * bcopy(auth_key->remote_password, dfc_auth_pwd->rpw_new.password,
9447 9450 * dfc_auth_pwd->rpw_new.length);
9448 9451 */
9449 9452
9450 9453 mutex_exit(&hba->auth_lock);
9451 9454
9452 9455 return (0);
9453 9456
9454 9457 } /* emlxs_dhc_get_auth_key() */
9455 9458
9456 9459
9457 9460 /* Provides DFC support for emlxs_dfc_set_auth_key() */
9458 9461 extern uint32_t
9459 9462 emlxs_dhc_set_auth_key(emlxs_hba_t *hba, dfc_auth_password_t *dfc_pwd)
9460 9463 {
9461 9464 emlxs_port_t *port = &PPORT;
9462 9465 emlxs_config_t *cfg = &CFG;
9463 9466 emlxs_auth_key_t *auth_key;
9464 9467 uint32_t length;
9465 9468
9466 9469 /* Return is authentication is not enabled */
9467 9470 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9468 9471 EMLXS_MSGF(EMLXS_CONTEXT,
9469 9472 &emlxs_fcsp_debug_msg,
9470 9473 "emlxs_dhc_set_auth_key. Auth disabled.");
9471 9474
9472 9475 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9473 9476 }
9474 9477
9475 9478 /* Check to make sure localpwd does not equal to remotepwd */
9476 9479 /* if they are given in the same time, if not, see below */
9477 9480 if ((dfc_pwd->lpw_new.type == PASSWORD_TYPE_ASCII ||
9478 9481 dfc_pwd->lpw_new.type == PASSWORD_TYPE_BINARY) &&
9479 9482 (dfc_pwd->rpw_new.type == PASSWORD_TYPE_ASCII ||
9480 9483 dfc_pwd->rpw_new.type == PASSWORD_TYPE_BINARY)) {
9481 9484 if (bcmp(dfc_pwd->lpw_new.password,
9482 9485 dfc_pwd->rpw_new.password,
9483 9486 dfc_pwd->lpw_new.length) == 0) {
9484 9487 EMLXS_MSGF(EMLXS_CONTEXT,
9485 9488 &emlxs_fcsp_debug_msg,
9486 9489 "emlxs_dhc_set_auth_key. nlpwd==nrpwd");
9487 9490
9488 9491 return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
9489 9492 }
9490 9493 }
9491 9494
9492 9495 mutex_enter(&hba->auth_lock);
9493 9496
9494 9497 auth_key = emlxs_auth_key_get(hba,
9495 9498 (uint8_t *)&dfc_pwd->lwwpn,
9496 9499 (uint8_t *)&dfc_pwd->rwwpn);
9497 9500
9498 9501 /* If entry does not exist, then create entry */
9499 9502 if (!auth_key) {
9500 9503 auth_key = emlxs_auth_key_create(hba,
9501 9504 (uint8_t *)&dfc_pwd->lwwpn,
9502 9505 (uint8_t *)&dfc_pwd->rwwpn);
9503 9506
9504 9507 if (!auth_key) {
9505 9508 EMLXS_MSGF(EMLXS_CONTEXT,
9506 9509 &emlxs_dfc_error_msg,
9507 9510 "emlxs_dhc_set_auth_key: Out of memory.");
9508 9511
9509 9512 mutex_exit(&hba->auth_lock);
9510 9513
9511 9514 return (DFC_SYSRES_ERROR);
9512 9515 }
9513 9516 }
9514 9517
9515 9518 /* Check if a new local password is provided */
9516 9519 if (dfc_pwd->lpw_new.type == PASSWORD_TYPE_ASCII ||
9517 9520 dfc_pwd->lpw_new.type == PASSWORD_TYPE_BINARY) {
9518 9521 /* Check if current password should be checked */
9519 9522 if (auth_key->local_password_type == PASSWORD_TYPE_ASCII ||
9520 9523 auth_key->local_password_type == PASSWORD_TYPE_BINARY) {
9521 9524 /* Verify current local password */
9522 9525 if ((auth_key->local_password_length !=
9523 9526 dfc_pwd->lpw.length) ||
9524 9527 (auth_key->local_password_type !=
9525 9528 dfc_pwd->lpw.type) ||
9526 9529 bcmp(dfc_pwd->lpw.password,
9527 9530 auth_key->local_password,
9528 9531 dfc_pwd->lpw.length)) {
9529 9532 EMLXS_MSGF(EMLXS_CONTEXT,
9530 9533 &emlxs_dfc_error_msg,
9531 9534 "emlxs_dhc_set_auth_key: Invalid local password.");
9532 9535
9533 9536 mutex_exit(&hba->auth_lock);
9534 9537
9535 9538 return (DFC_AUTH_COMPARE_FAILED);
9536 9539 }
9537 9540 }
9538 9541
9539 9542 /*
9540 9543 * Make sure the new local pwd is not equal to the current
9541 9544 * remote pwd if any
9542 9545 */
9543 9546 if (auth_key->remote_password_type == PASSWORD_TYPE_ASCII ||
9544 9547 auth_key->remote_password_type == PASSWORD_TYPE_BINARY) {
9545 9548 if ((auth_key->remote_password_length ==
9546 9549 dfc_pwd->lpw_new.length) &&
9547 9550 (bcmp(dfc_pwd->lpw_new.password,
9548 9551 auth_key->remote_password,
9549 9552 dfc_pwd->lpw_new.length) == 0)) {
9550 9553 EMLXS_MSGF(EMLXS_CONTEXT,
9551 9554 &emlxs_dfc_error_msg,
9552 9555 "emlxs_dhc_set_auth_key: nlpwd==crpwd");
9553 9556
9554 9557 mutex_exit(&hba->auth_lock);
9555 9558
9556 9559 return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
9557 9560 }
9558 9561 }
9559 9562 /* Update local entry */
9560 9563 auth_key->local_password_length = dfc_pwd->lpw_new.length;
9561 9564 auth_key->local_password_type = dfc_pwd->lpw_new.type;
9562 9565 bzero(auth_key->local_password,
9563 9566 sizeof (auth_key->local_password));
9564 9567 length = min(dfc_pwd->lpw_new.length,
9565 9568 sizeof (auth_key->local_password));
9566 9569 bcopy(dfc_pwd->lpw_new.password,
9567 9570 auth_key->local_password, length);
9568 9571 }
9569 9572 /* Check if a new remote password is provided */
9570 9573 if (dfc_pwd->rpw_new.type == PASSWORD_TYPE_ASCII ||
9571 9574 dfc_pwd->rpw_new.type == PASSWORD_TYPE_BINARY) {
9572 9575 /* Check if current password should be checked */
9573 9576 if (auth_key->remote_password_type == PASSWORD_TYPE_ASCII ||
9574 9577 auth_key->remote_password_type == PASSWORD_TYPE_BINARY) {
9575 9578 /* Verify current remote password */
9576 9579 if ((auth_key->remote_password_length !=
9577 9580 dfc_pwd->rpw.length) ||
9578 9581 (auth_key->remote_password_type !=
9579 9582 dfc_pwd->rpw.type) ||
9580 9583 bcmp(dfc_pwd->rpw.password,
9581 9584 auth_key->remote_password,
9582 9585 dfc_pwd->rpw.length)) {
9583 9586 EMLXS_MSGF(EMLXS_CONTEXT,
9584 9587 &emlxs_dfc_error_msg,
9585 9588 "emlxs_dhc_set_auth_key: Invalid remote password.");
9586 9589
9587 9590 mutex_exit(&hba->auth_lock);
9588 9591
9589 9592 return (DFC_AUTH_COMPARE_FAILED);
9590 9593 }
9591 9594 }
9592 9595
9593 9596 /*
9594 9597 * Make sure the new remote pwd is not equal to the current
9595 9598 * local pwd if any
9596 9599 */
9597 9600 if (auth_key->local_password_type == PASSWORD_TYPE_ASCII ||
9598 9601 auth_key->local_password_type == PASSWORD_TYPE_BINARY) {
9599 9602 if ((auth_key->local_password_length ==
9600 9603 dfc_pwd->rpw_new.length) &&
9601 9604 (bcmp(dfc_pwd->rpw_new.password,
9602 9605 auth_key->local_password,
9603 9606 dfc_pwd->rpw_new.length) == 0)) {
9604 9607 EMLXS_MSGF(EMLXS_CONTEXT,
9605 9608 &emlxs_dfc_error_msg,
9606 9609 "emlxs_dhc_set_auth_key: nrpwd==clpwd");
9607 9610
9608 9611 mutex_exit(&hba->auth_lock);
9609 9612
9610 9613 return (DFC_AUTH_LOCAL_REMOTE_PWD_EQUAL);
9611 9614 }
9612 9615 }
9613 9616 /* Update remote entry */
9614 9617 auth_key->remote_password_length = dfc_pwd->rpw_new.length;
9615 9618 auth_key->remote_password_type = dfc_pwd->rpw_new.type;
9616 9619 bzero(auth_key->remote_password,
9617 9620 sizeof (auth_key->remote_password));
9618 9621 length = min(dfc_pwd->rpw_new.length, 128);
9619 9622 bcopy(dfc_pwd->rpw_new.password,
9620 9623 auth_key->remote_password, length);
9621 9624 }
9622 9625 /* Update dfc local entry */
9623 9626 dfc_pwd->lpw.length = auth_key->local_password_length;
9624 9627 dfc_pwd->lpw.type = auth_key->local_password_type;
9625 9628 bzero(dfc_pwd->lpw.password, sizeof (dfc_pwd->lpw.password));
9626 9629 length = min(auth_key->local_password_length,
9627 9630 sizeof (dfc_pwd->lpw.password));
9628 9631 bcopy(auth_key->local_password, dfc_pwd->lpw.password, length);
9629 9632
9630 9633 /* Update dfc remote entry */
9631 9634 dfc_pwd->rpw.length = auth_key->remote_password_length;
9632 9635 dfc_pwd->rpw.type = auth_key->remote_password_type;
9633 9636 bzero(dfc_pwd->rpw.password, sizeof (dfc_pwd->rpw.password));
9634 9637 length = min(auth_key->remote_password_length,
9635 9638 sizeof (dfc_pwd->rpw.password));
9636 9639 bcopy(auth_key->remote_password, dfc_pwd->rpw.password, length);
9637 9640
9638 9641 emlxs_auth_key_print(hba, auth_key);
9639 9642
9640 9643 mutex_exit(&hba->auth_lock);
9641 9644
9642 9645 return (0);
9643 9646
9644 9647 } /* emlxs_dhc_set_auth_key() */
9645 9648
9646 9649
9647 9650 /* Provides DFC support for emlxs_dfc_get_auth_status() */
9648 9651 extern uint32_t
↓ open down ↓ |
2034 lines elided |
↑ open up ↑ |
9649 9652 emlxs_dhc_get_auth_status(emlxs_hba_t *hba, dfc_auth_status_t *fcsp_status)
9650 9653 {
9651 9654 emlxs_port_t *port = &PPORT;
9652 9655 emlxs_config_t *cfg = &CFG;
9653 9656 char s_lwwpn[64];
9654 9657 char s_rwwpn[64];
9655 9658 emlxs_auth_cfg_t *auth_cfg;
9656 9659 dfc_auth_status_t *auth_status;
9657 9660 NODELIST *ndlp;
9658 9661 uint32_t rc;
9659 - time_t auth_time;
9662 + uint32_t auth_time;
9660 9663 uint32_t update;
9661 9664
9662 9665 /* Return is authentication is not enabled */
9663 9666 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9664 9667 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcsp_debug_msg,
9665 9668 "emlxs_dhc_get_auth_status. Auth disabled.");
9666 9669
9667 9670 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9668 9671 }
9669 9672 mutex_enter(&hba->auth_lock);
9670 9673
9671 9674 auth_cfg = emlxs_auth_cfg_get(hba, (uint8_t *)&fcsp_status->lwwpn,
9672 9675 (uint8_t *)&fcsp_status->rwwpn);
9673 9676
9674 9677 if (!auth_cfg) {
9675 9678 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
9676 9679 "emlxs_dhc_get_auth_status: entry not found. %s:%s",
9677 9680 emlxs_wwn_xlate(s_lwwpn, (uint8_t *)&fcsp_status->lwwpn),
9678 9681 emlxs_wwn_xlate(s_rwwpn, (uint8_t *)&fcsp_status->rwwpn));
9679 9682
9680 9683 mutex_exit(&hba->auth_lock);
9681 9684
9682 9685 return (DFC_AUTH_NOT_CONFIGURED);
9683 9686 }
9684 9687 if (bcmp((uint8_t *)&fcsp_status->rwwpn,
9685 9688 (uint8_t *)emlxs_fabric_wwn, 8) == 0) {
9686 9689 auth_status = &port->port_dhc.auth_status;
9687 9690 auth_time = port->port_dhc.auth_time;
9688 9691 ndlp = emlxs_node_find_did(port, FABRIC_DID);
9689 9692 } else {
9690 9693 auth_status = &auth_cfg->auth_status;
9691 9694 auth_time = auth_cfg->auth_time;
9692 9695 ndlp = auth_cfg->node;
9693 9696 }
9694 9697
9695 9698 update = 0;
9696 9699
9697 9700 /* Check if node is still available */
9698 9701 if (ndlp && ndlp->nlp_active) {
9699 9702 emlxs_dhc_status(port, ndlp, 0, 0);
9700 9703 update = 1;
9701 9704 } else {
9702 9705 rc = DFC_AUTH_WWN_NOT_FOUND;
9703 9706 }
9704 9707
9705 9708
9706 9709 if (update) {
9707 9710 fcsp_status->auth_state = auth_status->auth_state;
9708 9711 fcsp_status->auth_failReason = auth_status->auth_failReason;
9709 9712 fcsp_status->type_priority = auth_status->type_priority;
9710 9713 fcsp_status->group_priority = auth_status->group_priority;
9711 9714 fcsp_status->hash_priority = auth_status->hash_priority;
9712 9715 fcsp_status->localAuth = auth_status->localAuth;
9713 9716 fcsp_status->remoteAuth = auth_status->remoteAuth;
9714 9717 fcsp_status->time_from_last_auth = DRV_TIME - auth_time;
9715 9718 fcsp_status->time_until_next_auth =
9716 9719 auth_status->time_until_next_auth;
9717 9720
9718 9721 rc = 0;
9719 9722 } else {
9720 9723 rc = DFC_AUTH_WWN_NOT_FOUND;
9721 9724 }
9722 9725
9723 9726 mutex_exit(&hba->auth_lock);
9724 9727
9725 9728 return (rc);
9726 9729
9727 9730 } /* emlxs_dhc_get_auth_status() */
9728 9731
9729 9732
9730 9733 /* Provides DFC support for emlxs_dfc_get_auth_list() */
9731 9734 /* auth_lock must be held when calling. */
9732 9735 /* fcsp_cfg must be large enough to hold hba->auth_cfg_count entries */
9733 9736 extern uint32_t
9734 9737 emlxs_dhc_get_auth_cfg_table(emlxs_hba_t *hba, dfc_fcsp_config_t *fcsp_cfg)
9735 9738 {
9736 9739 emlxs_port_t *port = &PPORT;
9737 9740 emlxs_config_t *cfg = &CFG;
9738 9741 emlxs_auth_cfg_t *auth_cfg;
9739 9742 uint32_t i;
9740 9743
9741 9744 /* Return if authentication is not enabled */
9742 9745 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9743 9746 EMLXS_MSGF(EMLXS_CONTEXT,
9744 9747 &emlxs_fcsp_debug_msg,
9745 9748 "emlxs_dhc_get_auth_cfg_table. Auth disabled.");
9746 9749
9747 9750 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9748 9751 }
9749 9752 for (auth_cfg = hba->auth_cfg.next;
9750 9753 auth_cfg != &hba->auth_cfg;
9751 9754 auth_cfg = auth_cfg->next) {
9752 9755 bcopy((uint8_t *)&auth_cfg->local_entity,
9753 9756 (uint8_t *)&fcsp_cfg->lwwpn, 8);
9754 9757 bcopy((uint8_t *)&auth_cfg->remote_entity,
9755 9758 (uint8_t *)&fcsp_cfg->rwwpn, 8);
9756 9759
9757 9760 fcsp_cfg->auth_tov = auth_cfg->authentication_timeout;
9758 9761 fcsp_cfg->auth_mode = auth_cfg->authentication_mode;
9759 9762 fcsp_cfg->auth_bidir = auth_cfg->bidirectional;
9760 9763
9761 9764 for (i = 0; i < 4; i++) {
9762 9765 fcsp_cfg->type_priority[i] =
9763 9766 auth_cfg->authentication_type_priority[i];
9764 9767 fcsp_cfg->hash_priority[i] =
9765 9768 auth_cfg->hash_priority[i];
9766 9769 }
9767 9770
9768 9771 for (i = 0; i < 8; i++) {
9769 9772 fcsp_cfg->group_priority[i] =
9770 9773 auth_cfg->dh_group_priority[i];
9771 9774 }
9772 9775
9773 9776 fcsp_cfg->reauth_tov = auth_cfg->reauthenticate_time_interval;
9774 9777
9775 9778 fcsp_cfg++;
9776 9779 }
9777 9780
9778 9781 return (0);
9779 9782
9780 9783 } /* emlxs_dhc_get_auth_cfg_table() */
9781 9784
9782 9785
9783 9786
9784 9787 /* Provides DFC support for emlxs_dfc_get_auth_list() */
9785 9788 /* auth_lock must be held when calling. */
9786 9789 /* auth_pwd must be large enough to hold hba->auth_key_count entries */
9787 9790 extern uint32_t
9788 9791 emlxs_dhc_get_auth_key_table(emlxs_hba_t *hba, dfc_auth_password_t *auth_pwd)
9789 9792 {
9790 9793 emlxs_port_t *port = &PPORT;
9791 9794 emlxs_config_t *cfg = &CFG;
9792 9795 emlxs_auth_key_t *auth_key;
9793 9796
9794 9797 /* Return if authentication is not enabled */
9795 9798 if (cfg[CFG_AUTH_ENABLE].current == 0) {
9796 9799 EMLXS_MSGF(EMLXS_CONTEXT,
9797 9800 &emlxs_fcsp_debug_msg,
9798 9801 "emlxs_dhc_get_auth_key_table. Auth disabled.");
9799 9802
9800 9803 return (DFC_AUTH_AUTHENTICATION_DISABLED);
9801 9804 }
9802 9805 for (auth_key = hba->auth_key.next;
9803 9806 auth_key != &hba->auth_key;
9804 9807 auth_key = auth_key->next) {
9805 9808 bcopy((uint8_t *)&auth_key->local_entity,
9806 9809 (uint8_t *)&auth_pwd->lwwpn, 8);
9807 9810 bcopy((uint8_t *)&auth_key->remote_entity,
9808 9811 (uint8_t *)&auth_pwd->rwwpn, 8);
9809 9812
9810 9813 auth_pwd->lpw.length = auth_key->local_password_length;
9811 9814 auth_pwd->lpw.type = auth_key->local_password_type;
9812 9815 /*
9813 9816 * bcopy(auth_key->local_password, auth_pwd->lpw.password,
9814 9817 * auth_pwd->lpw.length);
9815 9818 */
9816 9819
9817 9820 auth_pwd->rpw.length = auth_key->remote_password_length;
9818 9821 auth_pwd->rpw.type = auth_key->remote_password_type;
9819 9822 /*
9820 9823 * bcopy(auth_key->remote_password, auth_pwd->rpw.password,
9821 9824 * auth_pwd->rpw.length);
9822 9825 */
9823 9826
9824 9827 auth_pwd->lpw_new.length = auth_key->local_password_length;
9825 9828 auth_pwd->lpw_new.type = auth_key->local_password_type;
9826 9829 /*
9827 9830 * bcopy(auth_key->local_password,
9828 9831 * auth_pwd->lpw_new.password, auth_pwd->lpw_new.length);
9829 9832 */
9830 9833
9831 9834 auth_pwd->rpw_new.length = auth_key->remote_password_length;
9832 9835 auth_pwd->rpw_new.type = auth_key->remote_password_type;
9833 9836 /*
9834 9837 * bcopy(auth_key->remote_password,
9835 9838 * auth_pwd->rpw_new.password, auth_pwd->rpw_new.length);
9836 9839 */
9837 9840
9838 9841 auth_pwd++;
9839 9842 }
9840 9843
9841 9844 return (0);
9842 9845
9843 9846 } /* emlxs_dhc_get_auth_key_table() */
9844 9847
9845 9848 #endif /* DHCHAP_SUPPORT */
↓ open down ↓ |
176 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX