2 * Copyright (C) 2021 Abhinay Ramesh
4 * This file is part of GNU Zebra.
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
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.
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
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"
41 unsigned char conf_debug_ospf6_auth
[2];
42 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_AUTH_HASH_XOR
, "OSPF6 auth hash xor");
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,
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,
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,
82 void ospf6_auth_hdr_dump_send(struct ospf6_header
*ospfh
, uint16_t length
)
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];
88 oh_len
= htons(ospfh
->length
);
89 at_len
= length
- oh_len
;
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
);
110 void ospf6_auth_hdr_dump_recv(struct ospf6_header
*ospfh
, uint16_t length
,
111 unsigned int lls_len
)
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];
117 oh_len
= ntohs(ospfh
->length
);
118 at_len
= length
- (oh_len
+ lls_len
);
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
);
139 unsigned char *ospf6_hash_message_xor(unsigned char *mes1
,
143 unsigned char *result
;
146 result
= XCALLOC(MTYPE_OSPF6_AUTH_HASH_XOR
, len
);
148 for (i
= 0; i
< len
; i
++)
149 result
[i
] = mes1
[i
] ^ mes2
[i
];
154 static void md5_digest(unsigned char *mes
, uint32_t len
,
155 unsigned char *digest
)
157 #ifdef CRYPTO_OPENSSL
158 unsigned int size
= KEYCHAIN_MD5_HASH_SIZE
;
160 #elif CRYPTO_INTERNAL
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
));
173 MD5Update(&ctx
, mes
, len
);
174 MD5Final(digest
, &ctx
);
178 static void sha256_digest(unsigned char *mes
, uint32_t len
,
179 unsigned char *digest
)
181 #ifdef CRYPTO_OPENSSL
182 unsigned int size
= KEYCHAIN_HMAC_SHA256_HASH_SIZE
;
184 #elif CRYPTO_INTERNAL
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
));
197 SHA256_Update(&ctx
, mes
, len
);
198 SHA256_Final(digest
, &ctx
);
202 #ifdef CRYPTO_OPENSSL
203 static void sha1_digest(unsigned char *mes
, uint32_t len
,
204 unsigned char *digest
)
207 unsigned int size
= KEYCHAIN_HMAC_SHA1_HASH_SIZE
;
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
);
216 static void sha384_digest(unsigned char *mes
, uint32_t len
,
217 unsigned char *digest
)
220 unsigned int size
= KEYCHAIN_HMAC_SHA384_HASH_SIZE
;
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
);
229 static void sha512_digest(unsigned char *mes
, uint32_t len
,
230 unsigned char *digest
)
233 unsigned int size
= KEYCHAIN_HMAC_SHA512_HASH_SIZE
;
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
);
241 #endif /* CRYPTO_OPENSSL */
243 static void ospf6_hash_hmac_sha_digest(enum keychain_hash_algo key
,
244 unsigned char *mes
, uint32_t len
,
245 unsigned char *digest
)
247 if ((key
< KEYCHAIN_ALGO_NULL
) || (key
> KEYCHAIN_ALGO_MAX
))
251 case KEYCHAIN_ALGO_MD5
:
252 md5_digest(mes
, len
, digest
);
254 case KEYCHAIN_ALGO_HMAC_SHA1
:
255 #ifdef CRYPTO_OPENSSL
256 sha1_digest(mes
, len
, digest
);
259 case KEYCHAIN_ALGO_HMAC_SHA256
:
260 sha256_digest(mes
, len
, digest
);
262 case KEYCHAIN_ALGO_HMAC_SHA384
:
263 #ifdef CRYPTO_OPENSSL
264 sha384_digest(mes
, len
, digest
);
267 case KEYCHAIN_ALGO_HMAC_SHA512
:
268 #ifdef CRYPTO_OPENSSL
269 sha512_digest(mes
, len
, digest
);
272 case KEYCHAIN_ALGO_NULL
:
273 case KEYCHAIN_ALGO_MAX
:
280 uint16_t ospf6_auth_len_get(struct ospf6_interface
*oi
)
283 char *keychain_name
= NULL
;
284 struct keychain
*keychain
= NULL
;
285 struct key
*key
= NULL
;
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
);
293 keychain_name
= oi
->at_data
.keychain
;
294 keychain
= keychain_lookup(keychain_name
);
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(
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
);
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
)
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
;
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",
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.
342 return OSPF6_AUTH_PROCESS_NORMAL
;
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
))
352 if (OSPF6_OPT_ISSET_EXT(hello
->options
, OSPF6_OPT_AT
))
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
))
361 if (OSPF6_OPT_ISSET_EXT(dbdesc
->options
, OSPF6_OPT_AT
))
364 case OSPF6_MESSAGE_TYPE_LSREQ
:
365 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
366 case OSPF6_MESSAGE_TYPE_LSACK
:
368 lls_present
= on
->lls_present
;
369 auth_present
= on
->auth_present
;
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
;
379 if ((oh
->type
== OSPF6_MESSAGE_TYPE_HELLO
)
380 || (oh
->type
== OSPF6_MESSAGE_TYPE_DBDESC
)) {
382 on
->auth_present
= auth_present
;
383 on
->lls_present
= lls_present
;
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",
392 ospf6_message_type(oh
->type
));
393 return OSPF6_AUTH_VALIDATE_FAILURE
;
397 lls_hdr
= (struct ospf6_lls_hdr
*)(oh
+ hdr_len
);
398 *lls_block_len
= ntohs(lls_hdr
->length
) * 4;
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",
405 ospf6_message_type(oh
->type
));
406 return OSPF6_AUTH_VALIDATE_FAILURE
;
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",
414 ospf6_message_type(oh
->type
));
415 return OSPF6_AUTH_VALIDATE_FAILURE
;
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",
424 ospf6_message_type(oh
->type
));
425 return OSPF6_AUTH_VALIDATE_FAILURE
;
428 /* after authentication header validation is done
429 * reduce the auth hdr size from the packet length
431 *at_len
= ntohs(ospf6_auth_info
.length
);
432 *pkt_len
= (*pkt_len
) - (*at_len
) - (*lls_block_len
);
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
;
443 if (IS_OSPF6_DEBUG_AUTH_RX
) {
445 "RECV[%s] : Nbr(%s) Auth Sequence number mismatch in %s ",
446 oi
->interface
->name
, on
->name
,
447 ospf6_message_type(oh
->type
));
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
,
455 return OSPF6_AUTH_VALIDATE_FAILURE
;
459 return OSPF6_AUTH_VALIDATE_SUCCESS
;
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
)
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
);
479 if (oi
->at_data
.flags
== 0)
480 return OSPF6_AUTH_PROCESS_NORMAL
;
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
);
487 if (IS_OSPF6_DEBUG_AUTH_RX
)
489 "RECV[%s]: Keychain doesn't exist for %s",
491 ospf6_message_type(oh
->type
));
492 return OSPF6_AUTH_VALIDATE_FAILURE
;
495 key
= key_lookup_for_accept(keychain
, ntohs(ospf6_auth
->id
));
497 if (IS_OSPF6_DEBUG_AUTH_RX
)
498 zlog_err("RECV[%s]: Auth, Invalid SA for %s",
500 ospf6_message_type(oh
->type
));
501 return OSPF6_AUTH_VALIDATE_FAILURE
;
504 if (key
&& key
->string
505 && key
->hash_algo
!= KEYCHAIN_ALGO_NULL
) {
506 auth_str
= key
->string
;
507 hash_algo
= key
->hash_algo
;
509 if (IS_OSPF6_DEBUG_AUTH_RX
)
511 "RECV[%s]: Incomplete keychain config for %s",
513 ospf6_message_type(oh
->type
));
514 return OSPF6_AUTH_VALIDATE_FAILURE
;
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
;
523 return OSPF6_AUTH_VALIDATE_FAILURE
;
525 hash_len
= keychain_get_hash_len(hash_algo
);
526 memset(apad
, 0, sizeof(apad
));
527 memset(temp_hash
, 0, sizeof(temp_hash
));
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
));
534 auth_len
= ntohs(ospf6_auth
->length
);
536 memcpy(temp_hash
, ospf6_auth
->data
, hash_len
);
537 memcpy(ospf6_auth
->data
, apad
, hash_len
);
539 ospf6_auth_update_digest(oi
, oh
, ospf6_auth
, auth_str
,
540 (oh_len
+ auth_len
+ lls_block_len
),
543 #ifdef CRYPTO_OPENSSL
544 ret
= CRYPTO_memcmp(temp_hash
, ospf6_auth
->data
, hash_len
);
546 ret
= memcmp(temp_hash
, ospf6_auth
->data
, hash_len
);
549 return OSPF6_AUTH_VALIDATE_SUCCESS
;
551 return OSPF6_AUTH_VALIDATE_FAILURE
;
554 void ospf6_auth_digest_send(struct in6_addr
*src
, struct ospf6_interface
*oi
,
555 struct ospf6_header
*oh
, uint16_t auth_len
,
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
;
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
;
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
;
577 keychain_name
= oi
->at_data
.keychain
;
578 keychain
= keychain_lookup(keychain_name
);
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
;
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
;
595 if (IS_OSPF6_DEBUG_AUTH_TX
)
596 zlog_warn("SEND[%s]: Authentication not configured for %s",
598 ospf6_message_type(oh
->type
));
603 if (IS_OSPF6_DEBUG_AUTH_TX
)
604 zlog_warn("SEND[%s]: Authentication key is not configured for %s",
606 ospf6_message_type(oh
->type
));
610 hash_len
= keychain_get_hash_len(hash_algo
);
611 if (oi
->area
&& oi
->area
->ospf6
)
612 ospf6
= oi
->area
->ospf6
;
617 if (ospf6
->seqnum_l
== 0xFFFFFFFF) {
620 ospf6_auth_seqno_nvm_update(ospf6
);
623 /* Key must be reset. which is not handled as of now. */
624 if ((ospf6
->seqnum_l
== 0xFFFFFFFF)
625 && (ospf6
->seqnum_h
== 0xFFFFFFFF)) {
629 "Both Higher and Lower sequence number has wrapped. Need to reset the key");
632 memset(apad
, 0, sizeof(apad
));
635 memcpy(apad
, src
, ipv6_addr_size
);
637 memcpy(apad
+ ipv6_addr_size
, ospf6_hash_apad_max
,
638 (hash_len
- ipv6_addr_size
));
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
);
650 ospf6_auth_update_digest(oi
, oh
, ospf6_auth
, auth_str
, pkt_len
,
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.
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
;
666 oi
->at_data
.key_id
= 0;
667 UNSET_FLAG(oi
->at_data
.flags
,
668 OSPF6_AUTH_TRAILER_KEYCHAIN_VALID
);
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
)
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
];
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
);
699 memcpy(ko
, ks
, ks_len
);
701 memcpy(ipad
, ospf6_hash_ipad_max
, block_s
);
702 memcpy(opad
, ospf6_hash_opad_max
, block_s
);
704 first
= ospf6_hash_message_xor((unsigned char *)&ipad
, ko
, block_s
);
705 second
= ospf6_hash_message_xor((unsigned char *)&opad
, ko
, block_s
);
707 memcpy(first_mes
, first
, block_s
);
708 memcpy(first_mes
+ block_s
, oh
, pkt_len
);
710 ospf6_hash_hmac_sha_digest(algo
, first_mes
, (block_s
+ pkt_len
),
713 memcpy(second_mes
, second
, block_s
);
714 memcpy(second_mes
+ block_s
, first_hash
, hash_len
);
716 ospf6_hash_hmac_sha_digest(algo
, second_mes
, (block_s
+ hash_len
),
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
);
724 DEFUN (debug_ospf6_auth
,
725 debug_ospf6_auth_cmd
,
726 "debug ospf6 authentication [<tx|rx>]",
729 "debug OSPF6 authentication\n"
730 "debug authentication tx\n"
731 "debug authentication rx\n")
733 int auth_opt_idx
= 3;
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();
741 OSPF6_DEBUG_AUTH_TX_ON();
742 OSPF6_DEBUG_AUTH_RX_ON();
748 DEFUN (no_debug_ospf6_auth
,
749 no_debug_ospf6_auth_cmd
,
750 "no debug ospf6 authentication [<tx|rx>]",
754 "debug OSPF6 authentication\n"
755 "debug authentication tx\n"
756 "debug authentication rx\n")
758 int auth_opt_idx
= 3;
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();
766 OSPF6_DEBUG_AUTH_TX_OFF();
767 OSPF6_DEBUG_AUTH_RX_OFF();
773 int config_write_ospf6_debug_auth(struct vty
*vty
)
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");
782 void install_element_ospf6_debug_auth(void)
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
);
790 /* Clear the specified interface structure */
791 static void ospf6_intf_auth_clear(struct vty
*vty
, struct interface
*ifp
)
793 struct ospf6_interface
*oi
;
795 if (!if_is_operative(ifp
))
798 if (ifp
->info
== NULL
)
801 oi
= (struct ospf6_interface
*)ifp
->info
;
803 if (IS_OSPF6_DEBUG_INTERFACE
)
805 "Interface %s: clear authentication rx/tx drop counters",
808 /* Reset the interface rx/tx drop counters */
809 oi
->at_data
.tx_drop
= 0;
810 oi
->at_data
.rx_drop
= 0;
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
)
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
;
828 if (argv_find(argv
, argc
, "vrf", &idx_vrf
))
829 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
831 if (vrf_name
&& strmatch(vrf_name
, VRF_DEFAULT_NAME
))
835 vrf
= vrf_lookup_by_name(vrf_name
);
837 vrf_id
= vrf
->vrf_id
;
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
)
847 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
848 FOR_ALL_INTERFACES (vrf
, ifp
)
849 ospf6_intf_auth_clear(vty
, ifp
);
852 /* Interface name is specified. */
853 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
855 vty_out(vty
, "No such interface name\n");
857 ospf6_intf_auth_clear(vty
, ifp
);
863 void install_element_ospf6_clear_intf_auth(void)
865 install_element(ENABLE_NODE
, &clear_ipv6_ospf6_intf_auth_cmd
);
868 enum ospf6_auth_err
ospf6_auth_nvm_file_exist(void)
873 exist
= stat(OSPF6_AUTH_SEQ_NUM_FILE
, &buffer
);
875 return OSPF6_AUTH_FILE_EXIST
;
877 return OSPF6_AUTH_FILE_DO_NOT_EXIST
;
881 * Record in non-volatile memory the given ospf6 process,
882 * authentication trailer higher order sequence number.
884 void ospf6_auth_seqno_nvm_update(struct ospf6
*ospf6
)
886 const char *inst_name
;
888 json_object
*json_instances
;
889 json_object
*json_instance
;
891 zlog_err("Higher order sequence number %d update for %s process",
892 ospf6
->seqnum_h
, ospf6
->name
);
894 inst_name
= ospf6
->name
? ospf6
->name
: VRF_DEFAULT_NAME
;
896 json
= json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE
);
898 json
= json_object_new_object();
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
);
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
,
914 * Record higher order sequence number in non volatile memory.
916 json_object_int_add(json_instance
, "sequence_number", ospf6
->seqnum_h
);
918 json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE
, json
,
919 JSON_C_TO_STRING_PRETTY
);
920 json_object_free(json
);
924 * Delete authentication sequence number for a given OSPF6 process
925 * from non-volatile memory.
927 void ospf6_auth_seqno_nvm_delete(struct ospf6
*ospf6
)
929 const char *inst_name
;
931 json_object
*json_instances
;
933 zlog_err("Higher order sequence number delete for %s process",
936 inst_name
= ospf6
->name
? ospf6
->name
: VRF_DEFAULT_NAME
;
938 json
= json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE
);
940 json
= json_object_new_object();
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
);
948 json_object_object_del(json_instances
, inst_name
);
950 json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE
, json
,
951 JSON_C_TO_STRING_PRETTY
);
952 json_object_free(json
);
957 * Fetch from non-volatile memory the stored ospf6 process
958 * authentication sequence number.
960 void ospf6_auth_seqno_nvm_read(struct ospf6
*ospf6
)
962 const char *inst_name
;
964 json_object
*json_instances
;
965 json_object
*json_instance
;
966 json_object
*json_seqnum
;
968 inst_name
= ospf6
->name
? ospf6
->name
: VRF_DEFAULT_NAME
;
970 json
= json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE
);
972 json
= json_object_new_object();
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
);
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
,
987 json_object_object_get_ex(json_instance
, "sequence_number",
989 ospf6
->seqnum_h
= json_object_get_int(json_seqnum
);
991 zlog_err("Higher order sequence number %d read for %s process %s",
992 ospf6
->seqnum_h
, ospf6
->name
, strerror(errno
));
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
);