]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_auth_trailer.c
1f3f87751a90fb0146d3e51bfaa66a10be4e6f5a
[mirror_frr.git] / ospf6d / ospf6_auth_trailer.c
1 /*
2 * Copyright (C) 2021 Abhinay Ramesh
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "zebra.h"
22 #include "config.h"
23 #include "memory.h"
24 #include "ospf6d.h"
25 #include "vty.h"
26 #include "command.h"
27 #include "md5.h"
28 #include "sha256.h"
29 #include "lib/zlog.h"
30 #include "ospf6_message.h"
31 #include "ospf6_interface.h"
32 #include "ospf6_neighbor.h"
33 #include "ospf6_proto.h"
34 #include "ospf6_top.h"
35 #include "ospf6_area.h"
36 #include "ospf6_auth_trailer.h"
37 #include "ospf6_route.h"
38 #include "ospf6_zebra.h"
39 #include "lib/keychain.h"
40
41 unsigned char conf_debug_ospf6_auth[2];
42 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AUTH_HASH_XOR, "OSPF6 auth hash xor");
43
44 /*Apad is the hexadecimal value 0x878FE1F3. */
45 const uint8_t ospf6_hash_apad_max[KEYCHAIN_MAX_HASH_SIZE] = {
46 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1,
47 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f,
48 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87,
49 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3,
50 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1,
51 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3,
52 };
53
54 const uint8_t ospf6_hash_ipad_max[KEYCHAIN_ALGO_MAX_INTERNAL_BLK_SIZE] = {
55 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
56 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
57 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
58 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
59 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
60 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
61 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
62 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
63 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
64 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
65 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
66 };
67
68 const uint8_t ospf6_hash_opad_max[KEYCHAIN_ALGO_MAX_INTERNAL_BLK_SIZE] = {
69 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
70 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
71 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
72 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
73 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
74 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
75 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
76 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
77 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
78 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
79 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
80 };
81
82 void ospf6_auth_hdr_dump_send(struct ospf6_header *ospfh, uint16_t length)
83 {
84 struct ospf6_auth_hdr *ospf6_at_hdr;
85 uint16_t at_len, oh_len, at_hdr_len, hash_len;
86 unsigned char temp[KEYCHAIN_MAX_HASH_SIZE + 1];
87
88 oh_len = htons(ospfh->length);
89 at_len = length - oh_len;
90 if (at_len > 0) {
91 ospf6_at_hdr = (struct ospf6_auth_hdr *)
92 ((uint8_t *)ospfh + oh_len);
93 at_hdr_len = htons(ospf6_at_hdr->length);
94 hash_len = at_hdr_len - OSPF6_AUTH_HDR_MIN_SIZE;
95 memcpy(temp, ospf6_at_hdr->data, hash_len);
96 temp[hash_len] = '\0';
97 zlog_debug("OSPF6 Authentication Trailer");
98 zlog_debug(" Type %d", htons(ospf6_at_hdr->type));
99 zlog_debug(" Length %d", at_hdr_len);
100 zlog_debug(" Reserved %d", ospf6_at_hdr->reserved);
101 zlog_debug(" SA ID %d", htons(ospf6_at_hdr->id));
102 zlog_debug(" seqnum high 0x%08x",
103 htonl(ospf6_at_hdr->seqnum_h));
104 zlog_debug(" seqnum high 0x%08x",
105 htonl(ospf6_at_hdr->seqnum_l));
106 zlog_debug(" Data %s", temp);
107 }
108 }
109
110 void ospf6_auth_hdr_dump_recv(struct ospf6_header *ospfh, uint16_t length,
111 unsigned int lls_len)
112 {
113 struct ospf6_auth_hdr *ospf6_at_hdr;
114 uint16_t at_len, oh_len, at_hdr_len, hash_len;
115 unsigned char temp[KEYCHAIN_MAX_HASH_SIZE + 1];
116
117 oh_len = ntohs(ospfh->length);
118 at_len = length - (oh_len + lls_len);
119 if (at_len > 0) {
120 ospf6_at_hdr =
121 (struct ospf6_auth_hdr *)((uint8_t *)ospfh + oh_len);
122 at_hdr_len = ntohs(ospf6_at_hdr->length);
123 hash_len = at_hdr_len - OSPF6_AUTH_HDR_MIN_SIZE;
124 memcpy(temp, ospf6_at_hdr->data, hash_len);
125 temp[hash_len] = '\0';
126 zlog_debug("OSPF6 Authentication Trailer");
127 zlog_debug(" Type %d", ntohs(ospf6_at_hdr->type));
128 zlog_debug(" Length %d", at_hdr_len);
129 zlog_debug(" Reserved %d", ospf6_at_hdr->reserved);
130 zlog_debug(" SA ID %d", ntohs(ospf6_at_hdr->id));
131 zlog_debug(" seqnum high 0x%08x",
132 ntohl(ospf6_at_hdr->seqnum_h));
133 zlog_debug(" seqnum high 0x%08x",
134 ntohl(ospf6_at_hdr->seqnum_l));
135 zlog_debug(" Data %s", temp);
136 }
137 }
138
139 unsigned char *ospf6_hash_message_xor(unsigned char *mes1,
140 unsigned char *mes2,
141 uint32_t len)
142 {
143 unsigned char *result;
144 uint32_t i;
145
146 result = XCALLOC(MTYPE_OSPF6_AUTH_HASH_XOR, len);
147
148 for (i = 0; i < len; i++)
149 result[i] = mes1[i] ^ mes2[i];
150
151 return result;
152 }
153
154 static void md5_digest(unsigned char *mes, uint32_t len,
155 unsigned char *digest)
156 {
157 #ifdef CRYPTO_OPENSSL
158 unsigned int size = KEYCHAIN_MD5_HASH_SIZE;
159 EVP_MD_CTX *ctx;
160 #elif CRYPTO_INTERNAL
161 MD5_CTX ctx;
162 #endif
163
164 #ifdef CRYPTO_OPENSSL
165 ctx = EVP_MD_CTX_new();
166 EVP_DigestInit(ctx, EVP_md5());
167 EVP_DigestUpdate(ctx, mes, len);
168 EVP_DigestFinal(ctx, digest, &size);
169 EVP_MD_CTX_free(ctx);
170 #elif CRYPTO_INTERNAL
171 memset(&ctx, 0, sizeof(ctx));
172 MD5Init(&ctx);
173 MD5Update(&ctx, mes, len);
174 MD5Final(digest, &ctx);
175 #endif
176 }
177
178 static void sha256_digest(unsigned char *mes, uint32_t len,
179 unsigned char *digest)
180 {
181 #ifdef CRYPTO_OPENSSL
182 unsigned int size = KEYCHAIN_HMAC_SHA256_HASH_SIZE;
183 EVP_MD_CTX *ctx;
184 #elif CRYPTO_INTERNAL
185 SHA256_CTX ctx;
186 #endif
187
188 #ifdef CRYPTO_OPENSSL
189 ctx = EVP_MD_CTX_new();
190 EVP_DigestInit(ctx, EVP_sha256());
191 EVP_DigestUpdate(ctx, mes, len);
192 EVP_DigestFinal(ctx, digest, &size);
193 EVP_MD_CTX_free(ctx);
194 #elif CRYPTO_INTERNAL
195 memset(&ctx, 0, sizeof(ctx));
196 SHA256_Init(&ctx);
197 SHA256_Update(&ctx, mes, len);
198 SHA256_Final(digest, &ctx);
199 #endif
200 }
201
202 #ifdef CRYPTO_OPENSSL
203 static void sha1_digest(unsigned char *mes, uint32_t len,
204 unsigned char *digest)
205 {
206 EVP_MD_CTX *ctx;
207 unsigned int size = KEYCHAIN_HMAC_SHA1_HASH_SIZE;
208
209 ctx = EVP_MD_CTX_new();
210 EVP_DigestInit(ctx, EVP_sha1());
211 EVP_DigestUpdate(ctx, mes, len);
212 EVP_DigestFinal(ctx, digest, &size);
213 EVP_MD_CTX_free(ctx);
214 }
215
216 static void sha384_digest(unsigned char *mes, uint32_t len,
217 unsigned char *digest)
218 {
219 EVP_MD_CTX *ctx;
220 unsigned int size = KEYCHAIN_HMAC_SHA384_HASH_SIZE;
221
222 ctx = EVP_MD_CTX_new();
223 EVP_DigestInit(ctx, EVP_sha384());
224 EVP_DigestUpdate(ctx, mes, len);
225 EVP_DigestFinal(ctx, digest, &size);
226 EVP_MD_CTX_free(ctx);
227 }
228
229 static void sha512_digest(unsigned char *mes, uint32_t len,
230 unsigned char *digest)
231 {
232 EVP_MD_CTX *ctx;
233 unsigned int size = KEYCHAIN_HMAC_SHA512_HASH_SIZE;
234
235 ctx = EVP_MD_CTX_new();
236 EVP_DigestInit(ctx, EVP_sha512());
237 EVP_DigestUpdate(ctx, mes, len);
238 EVP_DigestFinal(ctx, digest, &size);
239 EVP_MD_CTX_free(ctx);
240 }
241 #endif /* CRYPTO_OPENSSL */
242
243 static void ospf6_hash_hmac_sha_digest(enum keychain_hash_algo key,
244 unsigned char *mes, uint32_t len,
245 unsigned char *digest)
246 {
247 if ((key < KEYCHAIN_ALGO_NULL) || (key > KEYCHAIN_ALGO_MAX))
248 return;
249
250 switch (key) {
251 case KEYCHAIN_ALGO_MD5:
252 md5_digest(mes, len, digest);
253 break;
254 case KEYCHAIN_ALGO_HMAC_SHA1:
255 #ifdef CRYPTO_OPENSSL
256 sha1_digest(mes, len, digest);
257 #endif
258 break;
259 case KEYCHAIN_ALGO_HMAC_SHA256:
260 sha256_digest(mes, len, digest);
261 break;
262 case KEYCHAIN_ALGO_HMAC_SHA384:
263 #ifdef CRYPTO_OPENSSL
264 sha384_digest(mes, len, digest);
265 #endif
266 break;
267 case KEYCHAIN_ALGO_HMAC_SHA512:
268 #ifdef CRYPTO_OPENSSL
269 sha512_digest(mes, len, digest);
270 #endif
271 break;
272 case KEYCHAIN_ALGO_NULL:
273 case KEYCHAIN_ALGO_MAX:
274 default:
275 /* no action */
276 break;
277 }
278 }
279
280 uint16_t ospf6_auth_len_get(struct ospf6_interface *oi)
281 {
282 uint16_t at_len = 0;
283 char *keychain_name = NULL;
284 struct keychain *keychain = NULL;
285 struct key *key = NULL;
286
287 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN)) {
288 if (CHECK_FLAG(oi->at_data.flags,
289 OSPF6_AUTH_TRAILER_KEYCHAIN_VALID)) {
290 at_len = OSPF6_AUTH_HDR_MIN_SIZE
291 + keychain_get_hash_len(oi->at_data.hash_algo);
292 } else {
293 keychain_name = oi->at_data.keychain;
294 keychain = keychain_lookup(keychain_name);
295 if (keychain) {
296 key = key_lookup_for_send(keychain);
297 if (key && key->string
298 && key->hash_algo != KEYCHAIN_ALGO_NULL) {
299 at_len = OSPF6_AUTH_HDR_MIN_SIZE
300 + keychain_get_hash_len(
301 key->hash_algo);
302 }
303 }
304 }
305 } else if (CHECK_FLAG(oi->at_data.flags,
306 OSPF6_AUTH_TRAILER_MANUAL_KEY)) {
307 at_len = OSPF6_AUTH_HDR_MIN_SIZE
308 + keychain_get_hash_len(oi->at_data.hash_algo);
309 }
310
311 return at_len;
312 }
313
314 int ospf6_auth_validate_pkt(struct ospf6_interface *oi, unsigned int *pkt_len,
315 struct ospf6_header *oh, unsigned int *at_len,
316 unsigned int *lls_block_len)
317 {
318 struct ospf6_hello *hello = NULL;
319 struct ospf6_dbdesc *dbdesc = NULL;
320 struct ospf6_neighbor *on = NULL;
321 struct ospf6_auth_hdr ospf6_auth_info;
322 uint16_t hdr_len = 0;
323 uint32_t oh_seqnum_h = 0;
324 uint32_t oh_seqnum_l = 0;
325 bool auth_present = false;
326 bool lls_present = false;
327 struct ospf6_lls_hdr *lls_hdr = NULL;
328
329 on = ospf6_neighbor_lookup(oh->router_id, oi);
330 hdr_len = ntohs(oh->length);
331 if (*pkt_len < hdr_len) {
332 if (IS_OSPF6_DEBUG_AUTH_RX)
333 zlog_err("RECV[%s] Received incomplete %s packet",
334 oi->interface->name,
335 ospf6_message_type(oh->type));
336 return OSPF6_AUTH_VALIDATE_FAILURE;
337 } else if (*pkt_len == hdr_len) {
338 if (oi->at_data.flags != 0)
339 return OSPF6_AUTH_VALIDATE_FAILURE;
340 /* No auth info to be considered.
341 */
342 return OSPF6_AUTH_PROCESS_NORMAL;
343 }
344
345 switch (oh->type) {
346 case OSPF6_MESSAGE_TYPE_HELLO:
347 hello = (struct ospf6_hello *)((uint8_t *)oh
348 + sizeof(struct ospf6_header));
349 if (OSPF6_OPT_ISSET_EXT(hello->options, OSPF6_OPT_L))
350 lls_present = true;
351
352 if (OSPF6_OPT_ISSET_EXT(hello->options, OSPF6_OPT_AT))
353 auth_present = true;
354 break;
355 case OSPF6_MESSAGE_TYPE_DBDESC:
356 dbdesc = (struct ospf6_dbdesc *)((uint8_t *)oh
357 + sizeof(struct ospf6_header));
358 if (OSPF6_OPT_ISSET_EXT(dbdesc->options, OSPF6_OPT_L))
359 lls_present = true;
360
361 if (OSPF6_OPT_ISSET_EXT(dbdesc->options, OSPF6_OPT_AT))
362 auth_present = true;
363 break;
364 case OSPF6_MESSAGE_TYPE_LSREQ:
365 case OSPF6_MESSAGE_TYPE_LSUPDATE:
366 case OSPF6_MESSAGE_TYPE_LSACK:
367 if (on) {
368 lls_present = on->lls_present;
369 auth_present = on->auth_present;
370 }
371 break;
372 default:
373 if (IS_OSPF6_DEBUG_AUTH_RX)
374 zlog_err("RECV[%s] : Wrong packet type %d",
375 oi->interface->name, oh->type);
376 return OSPF6_AUTH_VALIDATE_FAILURE;
377 }
378
379 if ((oh->type == OSPF6_MESSAGE_TYPE_HELLO)
380 || (oh->type == OSPF6_MESSAGE_TYPE_DBDESC)) {
381 if (on) {
382 on->auth_present = auth_present;
383 on->lls_present = lls_present;
384 }
385 }
386
387 if ((!auth_present && (oi->at_data.flags != 0))
388 || (auth_present && (oi->at_data.flags == 0))) {
389 if (IS_OSPF6_DEBUG_AUTH_RX)
390 zlog_err("RECV[%s] : Auth option miss-match in %s pkt",
391 oi->interface->name,
392 ospf6_message_type(oh->type));
393 return OSPF6_AUTH_VALIDATE_FAILURE;
394 }
395
396 if (lls_present) {
397 lls_hdr = (struct ospf6_lls_hdr *)(oh + hdr_len);
398 *lls_block_len = ntohs(lls_hdr->length) * 4;
399 }
400
401 if (*lls_block_len > (*pkt_len - hdr_len)) {
402 if (IS_OSPF6_DEBUG_AUTH_RX)
403 zlog_err("RECV[%s] : Wrong lls data in %s packet",
404 oi->interface->name,
405 ospf6_message_type(oh->type));
406 return OSPF6_AUTH_VALIDATE_FAILURE;
407 }
408
409 memset(&ospf6_auth_info, 0, sizeof(struct ospf6_auth_hdr));
410 if ((*pkt_len - hdr_len - (*lls_block_len)) > sizeof(ospf6_auth_info)) {
411 if (IS_OSPF6_DEBUG_AUTH_RX)
412 zlog_err("RECV[%s] : Wrong auth data in %s packet",
413 oi->interface->name,
414 ospf6_message_type(oh->type));
415 return OSPF6_AUTH_VALIDATE_FAILURE;
416 }
417
418 memcpy(&ospf6_auth_info, ((uint8_t *)oh + hdr_len + (*lls_block_len)),
419 (*pkt_len - hdr_len - (*lls_block_len)));
420 if (ntohs(ospf6_auth_info.length) > OSPF6_AUTH_HDR_FULL) {
421 if (IS_OSPF6_DEBUG_AUTH_RX)
422 zlog_err("RECV[%s] : Wrong auth header length in %s",
423 oi->interface->name,
424 ospf6_message_type(oh->type));
425 return OSPF6_AUTH_VALIDATE_FAILURE;
426 }
427
428 /* after authentication header validation is done
429 * reduce the auth hdr size from the packet length
430 */
431 *at_len = ntohs(ospf6_auth_info.length);
432 *pkt_len = (*pkt_len) - (*at_len) - (*lls_block_len);
433
434 if (on) {
435 oh_seqnum_h = ntohl(ospf6_auth_info.seqnum_h);
436 oh_seqnum_l = ntohl(ospf6_auth_info.seqnum_l);
437 if ((oh_seqnum_h >= on->seqnum_h[oh->type])
438 && (oh_seqnum_l > on->seqnum_l[oh->type])) {
439 /* valid sequence number received */
440 on->seqnum_h[oh->type] = oh_seqnum_h;
441 on->seqnum_l[oh->type] = oh_seqnum_l;
442 } else {
443 if (IS_OSPF6_DEBUG_AUTH_RX) {
444 zlog_err(
445 "RECV[%s] : Nbr(%s) Auth Sequence number mismatch in %s ",
446 oi->interface->name, on->name,
447 ospf6_message_type(oh->type));
448 zlog_err(
449 "nbr_seq_l %u, nbr_seq_h %u, hdr_seq_l %u, hdr_seq_h %u",
450 on->seqnum_l[oh->type],
451 on->seqnum_h[oh->type], oh_seqnum_l,
452 oh_seqnum_h);
453 }
454
455 return OSPF6_AUTH_VALIDATE_FAILURE;
456 }
457 }
458
459 return OSPF6_AUTH_VALIDATE_SUCCESS;
460 }
461
462 /* Starting point of packet process function. */
463 int ospf6_auth_check_digest(struct ospf6_header *oh, struct ospf6_interface *oi,
464 struct in6_addr *src, unsigned int lls_block_len)
465 {
466 uint32_t hash_len = KEYCHAIN_MAX_HASH_SIZE;
467 unsigned char apad[hash_len];
468 unsigned char temp_hash[hash_len];
469 struct ospf6_auth_hdr *ospf6_auth;
470 uint32_t ipv6_addr_size = sizeof(struct in6_addr);
471 struct keychain *keychain = NULL;
472 struct key *key = NULL;
473 char *auth_str = NULL;
474 uint16_t auth_len = 0;
475 uint8_t hash_algo = 0;
476 uint16_t oh_len = ntohs(oh->length);
477 int ret = 0;
478
479 if (oi->at_data.flags == 0)
480 return OSPF6_AUTH_PROCESS_NORMAL;
481
482 ospf6_auth = (struct ospf6_auth_hdr *)((uint8_t *)oh +
483 (oh_len + lls_block_len));
484 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN)) {
485 keychain = keychain_lookup(oi->at_data.keychain);
486 if (!keychain) {
487 if (IS_OSPF6_DEBUG_AUTH_RX)
488 zlog_err(
489 "RECV[%s]: Keychain doesn't exist for %s",
490 oi->interface->name,
491 ospf6_message_type(oh->type));
492 return OSPF6_AUTH_VALIDATE_FAILURE;
493 }
494
495 key = key_lookup_for_accept(keychain, ntohs(ospf6_auth->id));
496 if (!key) {
497 if (IS_OSPF6_DEBUG_AUTH_RX)
498 zlog_err("RECV[%s]: Auth, Invalid SA for %s",
499 oi->interface->name,
500 ospf6_message_type(oh->type));
501 return OSPF6_AUTH_VALIDATE_FAILURE;
502 }
503
504 if (key && key->string
505 && key->hash_algo != KEYCHAIN_ALGO_NULL) {
506 auth_str = key->string;
507 hash_algo = key->hash_algo;
508 } else {
509 if (IS_OSPF6_DEBUG_AUTH_RX)
510 zlog_err(
511 "RECV[%s]: Incomplete keychain config for %s",
512 oi->interface->name,
513 ospf6_message_type(oh->type));
514 return OSPF6_AUTH_VALIDATE_FAILURE;
515 }
516 } else if (CHECK_FLAG(oi->at_data.flags,
517 OSPF6_AUTH_TRAILER_MANUAL_KEY)) {
518 auth_str = oi->at_data.auth_key;
519 hash_algo = oi->at_data.hash_algo;
520 }
521
522 if (!auth_str)
523 return OSPF6_AUTH_VALIDATE_FAILURE;
524
525 hash_len = keychain_get_hash_len(hash_algo);
526 memset(apad, 0, sizeof(apad));
527 memset(temp_hash, 0, sizeof(temp_hash));
528
529 /* start digest verification */
530 memcpy(apad, src, ipv6_addr_size);
531 memcpy(apad + ipv6_addr_size, ospf6_hash_apad_max,
532 (hash_len - ipv6_addr_size));
533
534 auth_len = ntohs(ospf6_auth->length);
535
536 memcpy(temp_hash, ospf6_auth->data, hash_len);
537 memcpy(ospf6_auth->data, apad, hash_len);
538
539 ospf6_auth_update_digest(oi, oh, ospf6_auth, auth_str,
540 (oh_len + auth_len + lls_block_len),
541 hash_algo);
542
543 #ifdef CRYPTO_OPENSSL
544 ret = CRYPTO_memcmp(temp_hash, ospf6_auth->data, hash_len);
545 #else
546 ret = memcmp(temp_hash, ospf6_auth->data, hash_len);
547 #endif
548 if (ret == 0)
549 return OSPF6_AUTH_VALIDATE_SUCCESS;
550
551 return OSPF6_AUTH_VALIDATE_FAILURE;
552 }
553
554 void ospf6_auth_digest_send(struct in6_addr *src, struct ospf6_interface *oi,
555 struct ospf6_header *oh, uint16_t auth_len,
556 uint32_t pkt_len)
557 {
558 struct ospf6_auth_hdr *ospf6_auth;
559 char *keychain_name = NULL;
560 struct keychain *keychain = NULL;
561 struct key *key = NULL;
562 char *auth_str = NULL;
563 uint16_t key_id = 0;
564 enum keychain_hash_algo hash_algo = KEYCHAIN_ALGO_NULL;
565 uint32_t hash_len = KEYCHAIN_MAX_HASH_SIZE;
566 unsigned char apad[hash_len];
567 int ipv6_addr_size = sizeof(struct in6_addr);
568 struct ospf6 *ospf6 = NULL;
569
570 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN)) {
571 if (CHECK_FLAG(oi->at_data.flags,
572 OSPF6_AUTH_TRAILER_KEYCHAIN_VALID)) {
573 auth_str = oi->at_data.auth_key;
574 hash_algo = oi->at_data.hash_algo;
575 key_id = oi->at_data.key_id;
576 } else {
577 keychain_name = oi->at_data.keychain;
578 keychain = keychain_lookup(keychain_name);
579 if (keychain) {
580 key = key_lookup_for_send(keychain);
581 if (key && key->string
582 && key->hash_algo != KEYCHAIN_ALGO_NULL) {
583 auth_str = key->string;
584 hash_algo = key->hash_algo;
585 key_id = key->index;
586 }
587 }
588 }
589 } else if (CHECK_FLAG(oi->at_data.flags,
590 OSPF6_AUTH_TRAILER_MANUAL_KEY)) {
591 auth_str = oi->at_data.auth_key;
592 hash_algo = oi->at_data.hash_algo;
593 key_id = oi->at_data.key_id;
594 } else {
595 if (IS_OSPF6_DEBUG_AUTH_TX)
596 zlog_warn("SEND[%s]: Authentication not configured for %s",
597 oi->interface->name,
598 ospf6_message_type(oh->type));
599 return;
600 }
601
602 if (!auth_str) {
603 if (IS_OSPF6_DEBUG_AUTH_TX)
604 zlog_warn("SEND[%s]: Authentication key is not configured for %s",
605 oi->interface->name,
606 ospf6_message_type(oh->type));
607 return;
608 }
609
610 hash_len = keychain_get_hash_len(hash_algo);
611 if (oi->area && oi->area->ospf6)
612 ospf6 = oi->area->ospf6;
613 else
614 return;
615
616 ospf6->seqnum_l++;
617 if (ospf6->seqnum_l == 0xFFFFFFFF) {
618 ospf6->seqnum_h++;
619 ospf6->seqnum_l = 0;
620 ospf6_auth_seqno_nvm_update(ospf6);
621 }
622
623 /* Key must be reset. which is not handled as of now. */
624 if ((ospf6->seqnum_l == 0xFFFFFFFF)
625 && (ospf6->seqnum_h == 0xFFFFFFFF)) {
626 ospf6->seqnum_l = 0;
627 ospf6->seqnum_h = 0;
628 zlog_err(
629 "Both Higher and Lower sequence number has wrapped. Need to reset the key");
630 }
631
632 memset(apad, 0, sizeof(apad));
633
634 if (src)
635 memcpy(apad, src, ipv6_addr_size);
636
637 memcpy(apad + ipv6_addr_size, ospf6_hash_apad_max,
638 (hash_len - ipv6_addr_size));
639
640 ospf6_auth =
641 (struct ospf6_auth_hdr *)((uint8_t *)oh + ntohs(oh->length));
642 ospf6_auth->type = htons(OSPF6_AUTHENTICATION_CRYPTOGRAPHIC);
643 ospf6_auth->length = htons(auth_len);
644 ospf6_auth->reserved = 0;
645 ospf6_auth->id = htons(key_id);
646 ospf6_auth->seqnum_h = htonl(ospf6->seqnum_h);
647 ospf6_auth->seqnum_l = htonl(ospf6->seqnum_l);
648 memcpy(ospf6_auth->data, apad, hash_len);
649
650 ospf6_auth_update_digest(oi, oh, ospf6_auth, auth_str, pkt_len,
651 hash_algo);
652
653 /* There is a optimisation that is done to ensure that
654 * for every packet flow keychain lib API are called
655 * only once and the result are stored in oi->at_data.
656 * So, After processing the flow it is reset back here.
657 */
658 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN_VALID)) {
659 oi->at_data.hash_algo = KEYCHAIN_ALGO_NULL;
660 if (oi->at_data.auth_key) {
661 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY,
662 oi->at_data.auth_key);
663 oi->at_data.auth_key = NULL;
664 }
665
666 oi->at_data.key_id = 0;
667 UNSET_FLAG(oi->at_data.flags,
668 OSPF6_AUTH_TRAILER_KEYCHAIN_VALID);
669 }
670 }
671
672 void ospf6_auth_update_digest(struct ospf6_interface *oi,
673 struct ospf6_header *oh,
674 struct ospf6_auth_hdr *ospf6_auth, char *auth_str,
675 uint32_t pkt_len, enum keychain_hash_algo algo)
676 {
677 static const uint16_t cpid = 1;
678 uint32_t hash_len = keychain_get_hash_len(algo);
679 uint32_t block_s = keychain_get_block_size(algo);
680 uint32_t k_len = strlen(auth_str);
681 uint32_t ks_len = strlen(auth_str) + sizeof(cpid);
682 unsigned char ipad[block_s];
683 unsigned char opad[block_s];
684 unsigned char ko[block_s], ks[ks_len], tmp[hash_len];
685 unsigned char *first = NULL;
686 unsigned char *second = NULL;
687 unsigned char first_mes[block_s + pkt_len];
688 unsigned char second_mes[block_s + pkt_len];
689 unsigned char first_hash[hash_len];
690 unsigned char second_hash[hash_len];
691
692 memset(ko, 0, sizeof(ko));
693 memcpy(ks, auth_str, k_len);
694 memcpy(ks + k_len, &cpid, sizeof(cpid));
695 if (ks_len > hash_len) {
696 ospf6_hash_hmac_sha_digest(algo, ks, ks_len, tmp);
697 memcpy(ko, tmp, hash_len);
698 } else
699 memcpy(ko, ks, ks_len);
700
701 memcpy(ipad, ospf6_hash_ipad_max, block_s);
702 memcpy(opad, ospf6_hash_opad_max, block_s);
703
704 first = ospf6_hash_message_xor((unsigned char *)&ipad, ko, block_s);
705 second = ospf6_hash_message_xor((unsigned char *)&opad, ko, block_s);
706
707 memcpy(first_mes, first, block_s);
708 memcpy(first_mes + block_s, oh, pkt_len);
709
710 ospf6_hash_hmac_sha_digest(algo, first_mes, (block_s + pkt_len),
711 first_hash);
712
713 memcpy(second_mes, second, block_s);
714 memcpy(second_mes + block_s, first_hash, hash_len);
715
716 ospf6_hash_hmac_sha_digest(algo, second_mes, (block_s + hash_len),
717 second_hash);
718
719 memcpy(ospf6_auth->data, second_hash, hash_len);
720 XFREE(MTYPE_OSPF6_AUTH_HASH_XOR, first);
721 XFREE(MTYPE_OSPF6_AUTH_HASH_XOR, second);
722 }
723
724 DEFUN (debug_ospf6_auth,
725 debug_ospf6_auth_cmd,
726 "debug ospf6 authentication [<tx|rx>]",
727 DEBUG_STR
728 OSPF6_STR
729 "debug OSPF6 authentication\n"
730 "debug authentication tx\n"
731 "debug authentication rx\n")
732 {
733 int auth_opt_idx = 3;
734
735 if (argc == 4) {
736 if (!strncmp(argv[auth_opt_idx]->arg, "t", 1))
737 OSPF6_DEBUG_AUTH_TX_ON();
738 else if (!strncmp(argv[auth_opt_idx]->arg, "r", 1))
739 OSPF6_DEBUG_AUTH_RX_ON();
740 } else {
741 OSPF6_DEBUG_AUTH_TX_ON();
742 OSPF6_DEBUG_AUTH_RX_ON();
743 }
744
745 return CMD_SUCCESS;
746 }
747
748 DEFUN (no_debug_ospf6_auth,
749 no_debug_ospf6_auth_cmd,
750 "no debug ospf6 authentication [<tx|rx>]",
751 NO_STR
752 DEBUG_STR
753 OSPF6_STR
754 "debug OSPF6 authentication\n"
755 "debug authentication tx\n"
756 "debug authentication rx\n")
757 {
758 int auth_opt_idx = 3;
759
760 if (argc == 5) {
761 if (!strncmp(argv[auth_opt_idx]->arg, "t", 1))
762 OSPF6_DEBUG_AUTH_TX_OFF();
763 else if (!strncmp(argv[auth_opt_idx]->arg, "r", 1))
764 OSPF6_DEBUG_AUTH_RX_OFF();
765 } else {
766 OSPF6_DEBUG_AUTH_TX_OFF();
767 OSPF6_DEBUG_AUTH_RX_OFF();
768 }
769
770 return CMD_SUCCESS;
771 }
772
773 int config_write_ospf6_debug_auth(struct vty *vty)
774 {
775 if (IS_OSPF6_DEBUG_AUTH_TX)
776 vty_out(vty, "debug ospf6 authentication tx\n");
777 if (IS_OSPF6_DEBUG_AUTH_RX)
778 vty_out(vty, "debug ospf6 authentication rx\n");
779 return 0;
780 }
781
782 void install_element_ospf6_debug_auth(void)
783 {
784 install_element(ENABLE_NODE, &debug_ospf6_auth_cmd);
785 install_element(ENABLE_NODE, &no_debug_ospf6_auth_cmd);
786 install_element(CONFIG_NODE, &debug_ospf6_auth_cmd);
787 install_element(CONFIG_NODE, &no_debug_ospf6_auth_cmd);
788 }
789
790 /* Clear the specified interface structure */
791 static void ospf6_intf_auth_clear(struct vty *vty, struct interface *ifp)
792 {
793 struct ospf6_interface *oi;
794
795 if (!if_is_operative(ifp))
796 return;
797
798 if (ifp->info == NULL)
799 return;
800
801 oi = (struct ospf6_interface *)ifp->info;
802
803 if (IS_OSPF6_DEBUG_INTERFACE)
804 zlog_debug(
805 "Interface %s: clear authentication rx/tx drop counters",
806 ifp->name);
807
808 /* Reset the interface rx/tx drop counters */
809 oi->at_data.tx_drop = 0;
810 oi->at_data.rx_drop = 0;
811 }
812
813 /* Clear interface */
814 DEFUN(clear_ipv6_ospf6_intf_auth, clear_ipv6_ospf6_intf_auth_cmd,
815 "clear ipv6 ospf6 [vrf VRF] auth-counters interface [IFNAME]",
816 CLEAR_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
817 "authentication rx/tx drop counters\n" INTERFACE_STR IFNAME_STR)
818 {
819 int idx_ifname = 0;
820 int idx_vrf = 0;
821 struct interface *ifp;
822 struct listnode *node;
823 struct ospf6 *ospf6 = NULL;
824 char *vrf_name = NULL;
825 vrf_id_t vrf_id = VRF_DEFAULT;
826 struct vrf *vrf = NULL;
827
828 if (argv_find(argv, argc, "vrf", &idx_vrf))
829 vrf_name = argv[idx_vrf + 1]->arg;
830
831 if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
832 vrf_name = NULL;
833
834 if (vrf_name) {
835 vrf = vrf_lookup_by_name(vrf_name);
836 if (vrf)
837 vrf_id = vrf->vrf_id;
838 }
839
840 if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
841 /* Clear all the ospfv3 interfaces auth data. */
842 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
843 if (vrf_id != ospf6->vrf_id)
844 continue;
845
846 if (!vrf)
847 vrf = vrf_lookup_by_id(ospf6->vrf_id);
848 FOR_ALL_INTERFACES (vrf, ifp)
849 ospf6_intf_auth_clear(vty, ifp);
850 }
851 } else {
852 /* Interface name is specified. */
853 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
854 if (ifp == NULL)
855 vty_out(vty, "No such interface name\n");
856 else
857 ospf6_intf_auth_clear(vty, ifp);
858 }
859
860 return CMD_SUCCESS;
861 }
862
863 void install_element_ospf6_clear_intf_auth(void)
864 {
865 install_element(ENABLE_NODE, &clear_ipv6_ospf6_intf_auth_cmd);
866 }
867
868 enum ospf6_auth_err ospf6_auth_nvm_file_exist(void)
869 {
870 struct stat buffer;
871 int exist;
872
873 exist = stat(OSPF6_AUTH_SEQ_NUM_FILE, &buffer);
874 if (exist == 0)
875 return OSPF6_AUTH_FILE_EXIST;
876 else
877 return OSPF6_AUTH_FILE_DO_NOT_EXIST;
878 }
879
880 /*
881 * Record in non-volatile memory the given ospf6 process,
882 * authentication trailer higher order sequence number.
883 */
884 void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
885 {
886 const char *inst_name;
887 json_object *json;
888 json_object *json_instances;
889 json_object *json_instance;
890
891 zlog_err("Higher order sequence number %d update for %s process",
892 ospf6->seqnum_h, ospf6->name);
893
894 inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
895
896 json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
897 if (json == NULL)
898 json = json_object_new_object();
899
900 json_object_object_get_ex(json, "instances", &json_instances);
901 if (!json_instances) {
902 json_instances = json_object_new_object();
903 json_object_object_add(json, "instances", json_instances);
904 }
905
906 json_object_object_get_ex(json_instances, inst_name, &json_instance);
907 if (!json_instance) {
908 json_instance = json_object_new_object();
909 json_object_object_add(json_instances, inst_name,
910 json_instance);
911 }
912
913 /*
914 * Record higher order sequence number in non volatile memory.
915 */
916 json_object_int_add(json_instance, "sequence_number", ospf6->seqnum_h);
917
918 json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
919 JSON_C_TO_STRING_PRETTY);
920 json_object_free(json);
921 }
922
923 /*
924 * Delete authentication sequence number for a given OSPF6 process
925 * from non-volatile memory.
926 */
927 void ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6)
928 {
929 const char *inst_name;
930 json_object *json;
931 json_object *json_instances;
932
933 zlog_err("Higher order sequence number delete for %s process",
934 ospf6->name);
935
936 inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
937
938 json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
939 if (json == NULL)
940 json = json_object_new_object();
941
942 json_object_object_get_ex(json, "instances", &json_instances);
943 if (!json_instances) {
944 json_instances = json_object_new_object();
945 json_object_object_add(json, "instances", json_instances);
946 }
947
948 json_object_object_del(json_instances, inst_name);
949
950 json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
951 JSON_C_TO_STRING_PRETTY);
952 json_object_free(json);
953 }
954
955
956 /*
957 * Fetch from non-volatile memory the stored ospf6 process
958 * authentication sequence number.
959 */
960 void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
961 {
962 const char *inst_name;
963 json_object *json;
964 json_object *json_instances;
965 json_object *json_instance;
966 json_object *json_seqnum;
967
968 inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
969
970 json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
971 if (json == NULL)
972 json = json_object_new_object();
973
974 json_object_object_get_ex(json, "instances", &json_instances);
975 if (!json_instances) {
976 json_instances = json_object_new_object();
977 json_object_object_add(json, "instances", json_instances);
978 }
979
980 json_object_object_get_ex(json_instances, inst_name, &json_instance);
981 if (!json_instance) {
982 json_instance = json_object_new_object();
983 json_object_object_add(json_instances, inst_name,
984 json_instance);
985 }
986
987 json_object_object_get_ex(json_instance, "sequence_number",
988 &json_seqnum);
989 ospf6->seqnum_h = json_object_get_int(json_seqnum);
990
991 zlog_err("Higher order sequence number %d read for %s process %s",
992 ospf6->seqnum_h, ospf6->name, strerror(errno));
993
994 json_object_object_del(json_instances, inst_name);
995 json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
996 JSON_C_TO_STRING_PRETTY);
997 json_object_free(json);
998 }