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