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