ex_next_record:
  415|    780|uint16_t ex_next_record(BufCtl* buf, int *length) {
  416|    780|	uint16_t *ptr = (uint16_t *)buf->next;
  417|    780|	uint16_t type = ntohs(*ptr++);
  418|    780|	*length = ntohs(*ptr++)-NTS_KE_HDR_LNG;
  ------------------
  |  |   71|    780|#define NTS_KE_HDR_LNG 4
  ------------------
  419|    780|	buf->next += NTS_KE_HDR_LNG;
  ------------------
  |  |   71|    780|#define NTS_KE_HDR_LNG 4
  ------------------
  420|    780|	buf->left -= NTS_KE_HDR_LNG;
  ------------------
  |  |   71|    780|#define NTS_KE_HDR_LNG 4
  ------------------
  421|    780|	return type;
  422|    780|}
next_bytes:
  434|    355|uint16_t next_bytes(BufCtl* buf, uint8_t *data, int length) {
  435|    355|	memcpy(data, buf->next, length);
  436|    355|	buf->next += length;
  437|    355|	buf->left -= length;
  438|    355|	return length;
  439|    355|}

nts_unpack_cookie:
  362|      5|  uint8_t *c2s, uint8_t *s2c, int *keylen) {
  363|      5|	uint8_t *finger;
  364|      5|	uint8_t plaintext[NTS_MAX_COOKIELEN];
  365|      5|	uint8_t *nonce;
  366|      5|	uint32_t temp;
  367|      5|	size_t plainlength;
  368|      5|	int cipherlength;
  369|      5|	bool ok;
  370|      5|	struct NTS_Key *key;
  371|      5|	int i;
  372|       |
  373|      5|	if (NULL == cookie_ctx)
  ------------------
  |  Branch (373:6): [True: 5, False: 0]
  ------------------
  374|      5|		return false;	/* We aren't initialized yet. */
  375|       |
  376|      0|	if (0 == nts_nKeys) {
  ------------------
  |  Branch (376:6): [True: 0, False: 0]
  ------------------
  377|      0|		nts_cnt.cookie_not_server++;
  378|      0|		return false;  /* We are not a NTS enabled server. */
  379|      0|	}
  380|       |
  381|       |	/* We may get garbage from the net */
  382|      0|	if (cookielen > NTS_MAX_COOKIELEN)
  ------------------
  |  |   97|      0|#define NTS_MAX_COOKIELEN	192	/* see nts_cookie.c */
  ------------------
  |  Branch (382:6): [True: 0, False: 0]
  ------------------
  383|      0|		return false;
  384|       |
  385|      0|	finger = cookie;
  386|      0|	key = NULL;		/* squash uninitialized warning */
  387|      0|	for (i=0; i<nts_nKeys; i++) {
  ------------------
  |  Branch (387:12): [True: 0, False: 0]
  ------------------
  388|      0|	  key = &nts_keys[i];
  389|      0|	  if (0 == memcmp(finger, &key->I, sizeof(key->I))) {
  ------------------
  |  Branch (389:8): [True: 0, False: 0]
  ------------------
  390|      0|		break;
  391|      0|	  }
  392|      0|	}
  393|      0|	nts_cnt.cookie_decode_total++;  /* total attempts, includes too old */
  394|      0|	if (nts_nKeys == i) {
  ------------------
  |  Branch (394:6): [True: 0, False: 0]
  ------------------
  395|      0|		nts_cnt.cookie_decode_too_old++;
  396|      0|		return false;
  397|      0|        }
  398|      0|	if (0 == i) {
  ------------------
  |  Branch (398:6): [True: 0, False: 0]
  ------------------
  399|      0|		nts_cnt.cookie_decode_current++;
  400|      0|	} else if (1 == i) {
  ------------------
  |  Branch (400:13): [True: 0, False: 0]
  ------------------
  401|      0|		nts_cnt.cookie_decode_old++;
  402|      0|	} else if (2 == i) {
  ------------------
  |  Branch (402:13): [True: 0, False: 0]
  ------------------
  403|      0|		nts_cnt.cookie_decode_old2++;
  404|      0|	} else {
  405|      0|		nts_cnt.cookie_decode_older++;
  406|      0|	}
  407|       |#if 0
  408|       |	if (1<i) {
  409|       |	  /* Hack for debugging */
  410|       |	  /* Beware: DoS possibility on a public server */
  411|       |	  msyslog(LOG_INFO, "NTS: Old cookie: %d days.", i);
  412|       |	}
  413|       |#endif
  414|       |
  415|      0|	finger += sizeof(key->I);
  416|      0|	nonce = finger;
  417|      0|	finger += NONCE_LENGTH;
  ------------------
  |  |  168|      0|#define NONCE_LENGTH 16
  ------------------
  418|       |
  419|       |	// require(AD_LENGTH==finger-cookie);
  420|       |
  421|      0|	cipherlength = cookielen - AD_LENGTH;
  ------------------
  |  |  109|      0|#define AD_LENGTH 20
  ------------------
  422|      0|	plainlength = NTS_MAX_COOKIELEN;
  ------------------
  |  |   97|      0|#define NTS_MAX_COOKIELEN	192	/* see nts_cookie.c */
  ------------------
  423|       |
  424|      0|	nts_lock_cookielock();
  425|       |
  426|      0|	ok = AES_SIV_Decrypt(cookie_ctx,
  427|      0|			     plaintext, &plainlength,
  428|      0|			     key->K, K_length,
  429|      0|			     nonce, NONCE_LENGTH,
  ------------------
  |  |  168|      0|#define NONCE_LENGTH 16
  ------------------
  430|      0|			     finger, cipherlength,
  431|      0|			     cookie, AD_LENGTH);
  ------------------
  |  |  109|      0|#define AD_LENGTH 20
  ------------------
  432|       |
  433|      0|	nts_unlock_cookielock();
  434|       |
  435|      0|	if (!ok) {
  ------------------
  |  Branch (435:6): [True: 0, False: 0]
  ------------------
  436|      0|		nts_cnt.cookie_decode_error++;
  437|      0|		return false;
  438|      0|	}
  439|       |
  440|      0|	*keylen = (plainlength-AEAD_LENGTH)/2;
  ------------------
  |  |  110|      0|#define AEAD_LENGTH 4
  ------------------
  441|      0|	finger = plaintext;
  442|      0|	memcpy(&temp, finger, AEAD_LENGTH);
  ------------------
  |  |  110|      0|#define AEAD_LENGTH 4
  ------------------
  443|      0|	*aead = temp;
  444|      0|	finger += AEAD_LENGTH;
  ------------------
  |  |  110|      0|#define AEAD_LENGTH 4
  ------------------
  445|      0|	memcpy(c2s, finger, *keylen);
  446|      0|	finger += *keylen;
  447|      0|	memcpy(s2c, finger, *keylen);
  448|      0|	finger += *keylen;
  449|       |
  450|      0|	return true;
  451|      0|}

extens_server_recv:
  120|    169|bool extens_server_recv(struct ntspacket_t *ntspacket, uint8_t *pkt, int lng) {
  121|    169|	struct BufCtl_t buf;
  122|    169|	uint16_t aead;
  123|    169|	int noncelen, cmaclen;
  124|    169|	bool sawcookie, sawAEEF;
  125|    169|	int cookielen;			/* cookie and placeholder(s) */
  126|       |
  127|    169|	nts_cnt.server_recv_bad++;		/* assume bad, undo if OK */
  128|       |
  129|    169|	buf.next = pkt+LEN_PKT_NOMAC;
  ------------------
  |  |  376|    169|#define	LEN_PKT_NOMAC	48	/* min header length */
  ------------------
  130|    169|	buf.left = lng-LEN_PKT_NOMAC;
  ------------------
  |  |  376|    169|#define	LEN_PKT_NOMAC	48	/* min header length */
  ------------------
  131|       |
  132|    169|	sawcookie = sawAEEF = false;
  133|    169|	cookielen = 0;
  134|    169|	ntspacket->uidlen = 0;
  135|    169|	ntspacket->needed = 0;
  136|       |
  137|    829|	while (buf.left >= NTS_KE_HDR_LNG) {
  ------------------
  |  |   71|    829|#define NTS_KE_HDR_LNG 4
  ------------------
  |  Branch (137:9): [True: 780, False: 49]
  ------------------
  138|    780|		uint16_t type;
  139|    780|		bool critical = false;
  140|    780|		int length, adlength;
  141|    780|		size_t outlen;
  142|    780|		uint8_t *nonce, *cmac;
  143|    780|		bool ok;
  144|       |
  145|    780|		type = ex_next_record(&buf, &length); /* length excludes header */
  146|    780|		if (length&3 || length > buf.left || length < 0) {
  ------------------
  |  Branch (146:7): [True: 8, False: 772]
  |  Branch (146:19): [True: 22, False: 750]
  |  Branch (146:40): [True: 14, False: 736]
  ------------------
  147|     44|			return false;
  148|     44|		}
  149|    736|		if (NTS_CRITICAL & type) {
  ------------------
  |  |  172|    736|#define NTS_CRITICAL 0x8000
  ------------------
  |  Branch (149:7): [True: 266, False: 470]
  ------------------
  150|    266|			critical = true;
  151|    266|			type &= ~NTS_CRITICAL;
  ------------------
  |  |  172|    266|#define NTS_CRITICAL 0x8000
  ------------------
  152|    266|		}
  153|    736|		switch (type) {
  154|    361|		    case Unique_Identifier:
  ------------------
  |  Branch (154:7): [True: 361, False: 375]
  ------------------
  155|    361|			if (length > NTS_UID_MAX_LENGTH) {
  ------------------
  |  |  100|    361|#define NTS_UID_MAX_LENGTH	64
  ------------------
  |  Branch (155:8): [True: 6, False: 355]
  ------------------
  156|      6|				return false;
  157|      6|			}
  158|    355|			ntspacket->uidlen = length;
  159|    355|			next_bytes(&buf, ntspacket->UID, length);
  160|    355|			break;
  161|     21|		    case NTS_Cookie:
  ------------------
  |  Branch (161:7): [True: 21, False: 715]
  ------------------
  162|       |			/* cookies and placeholders must be the same length
  163|       |			 * in order to avoid amplification attacks.
  164|       |			 */
  165|     21|			if (sawcookie) {
  ------------------
  |  Branch (165:8): [True: 0, False: 21]
  ------------------
  166|      0|				return false; /* second cookie */
  167|      0|			}
  168|     21|			if (0 == cookielen) {
  ------------------
  |  Branch (168:8): [True: 4, False: 17]
  ------------------
  169|      4|				cookielen = length;
  170|      4|			}
  171|     17|			else if (length != cookielen) {
  ------------------
  |  Branch (171:13): [True: 16, False: 1]
  ------------------
  172|     16|				return false;
  173|     16|			}
  174|      5|			ok = nts_unpack_cookie(buf.next, length, &aead, ntspacket->c2s,
  175|      5|					       ntspacket->s2c, &ntspacket->keylen);
  176|      5|			if (!ok) {
  ------------------
  |  Branch (176:8): [True: 5, False: 0]
  ------------------
  177|      5|				return false;
  178|      5|			}
  179|      0|			buf.next += length;
  180|      0|			buf.left -= length;
  181|      0|			sawcookie = true;
  182|      0|			ntspacket->needed++;
  183|      0|			ntspacket->aead = aead;
  184|      0|			break;
  185|    321|		    case NTS_Cookie_Placeholder:
  ------------------
  |  Branch (185:7): [True: 321, False: 415]
  ------------------
  186|    321|			if (0 == cookielen) {
  ------------------
  |  Branch (186:8): [True: 239, False: 82]
  ------------------
  187|    239|				cookielen = length;
  188|    239|			}
  189|     82|			else if (length != cookielen) {
  ------------------
  |  Branch (189:13): [True: 16, False: 66]
  ------------------
  190|     16|				return false;
  191|     16|			}
  192|    305|			ntspacket->needed++;
  193|    305|			buf.next += length;
  194|    305|			buf.left -= length;
  195|    305|			break;
  196|      1|		    case NTS_AEEF:
  ------------------
  |  Branch (196:7): [True: 1, False: 735]
  ------------------
  197|      1|			if (!sawcookie) {
  ------------------
  |  Branch (197:8): [True: 1, False: 0]
  ------------------
  198|      1|				return false; /* no cookie yet, no c2s */
  199|      1|			}
  200|      0|			if (length != NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH) {
  ------------------
  |  |   32|      0|#define NTP_EX_HDR_LNG 4
  ------------------
              			if (length != NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH) {
  ------------------
  |  |   29|      0|#define NONCE_LENGTH 16
  ------------------
              			if (length != NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH) {
  ------------------
  |  |   30|      0|#define CMAC_LENGTH 16
  ------------------
  |  Branch (200:8): [True: 0, False: 0]
  ------------------
  201|      0|				return false;
  202|      0|			}
  203|       |			/* Additional data is up to this exten. */
  204|       |			/* backup over header */
  205|      0|			adlength = buf.next-NTP_EX_HDR_LNG-pkt;
  ------------------
  |  |   32|      0|#define NTP_EX_HDR_LNG 4
  ------------------
  206|      0|			noncelen = next_uint16(&buf);
  207|      0|			cmaclen = next_uint16(&buf);
  208|      0|			if (noncelen & 3) {
  ------------------
  |  Branch (208:8): [True: 0, False: 0]
  ------------------
  209|      0|				return false; /* would require padding */
  210|      0|			}
  211|      0|			if (CMAC_LENGTH != cmaclen) {
  ------------------
  |  |   30|      0|#define CMAC_LENGTH 16
  ------------------
  |  Branch (211:8): [True: 0, False: 0]
  ------------------
  212|      0|				return false;
  213|      0|			}
  214|      0|			nonce = buf.next;
  215|      0|			cmac = nonce+NONCE_LENGTH;
  ------------------
  |  |   29|      0|#define NONCE_LENGTH 16
  ------------------
  216|      0|			outlen = 6;
  217|      0|			ok = AES_SIV_Decrypt(wire_ctx,
  218|      0|					     NULL, &outlen,
  219|      0|					     ntspacket->c2s, ntspacket->keylen,
  220|      0|					     nonce, noncelen,
  221|      0|					     cmac, CMAC_LENGTH,
  ------------------
  |  |   30|      0|#define CMAC_LENGTH 16
  ------------------
  222|      0|					     pkt, adlength);
  223|      0|			if (!ok) {
  ------------------
  |  Branch (223:8): [True: 0, False: 0]
  ------------------
  224|      0|				return false;
  225|      0|			}
  226|      0|			if (0 != outlen) {
  ------------------
  |  Branch (226:8): [True: 0, False: 0]
  ------------------
  227|      0|				return false;
  228|      0|			}
  229|       |			/* we already used 2 length slots way above*/
  230|      0|			length -= (NTP_EX_U16_LNG+NTP_EX_U16_LNG);
  ------------------
  |  |   33|      0|#define NTP_EX_U16_LNG 2
  ------------------
              			length -= (NTP_EX_U16_LNG+NTP_EX_U16_LNG);
  ------------------
  |  |   33|      0|#define NTP_EX_U16_LNG 2
  ------------------
  231|      0|			buf.next += length;
  232|      0|			buf.left -= length;
  233|      0|			if (0 != buf.left) {
  ------------------
  |  Branch (233:8): [True: 0, False: 0]
  ------------------
  234|      0|				return false; /* Reject extens after AEEF block */
  235|      0|			}
  236|      0|			sawAEEF = true;
  237|      0|			break;
  238|     32|		    default:
  ------------------
  |  Branch (238:7): [True: 32, False: 704]
  ------------------
  239|       |			/* Non NTS extensions on requests at server.
  240|       |			 * Call out when we get some that we want.
  241|       |			 * Until then, it's probably a bug. */
  242|     32|			if (critical) {
  ------------------
  |  Branch (242:8): [True: 26, False: 6]
  ------------------
  243|     26|				return false;
  244|     26|			}
  245|      6|			buf.next += length;
  246|      6|			buf.left -= length;
  247|      6|			return false;
  248|    736|		}
  249|    736|	}
  250|       |
  251|     49|	if (!sawAEEF) {
  ------------------
  |  Branch (251:6): [True: 49, False: 0]
  ------------------
  252|     49|		return false;
  253|     49|	}
  254|      0|	if (buf.left > 0)
  ------------------
  |  Branch (254:6): [True: 0, False: 0]
  ------------------
  255|      0|		return false;
  256|       |
  257|       |	//  printf("ESRx: %d, %d, %d\n",
  258|       |	//      lng-LEN_PKT_NOMAC, ntspacket->needed, ntspacket->keylen);
  259|      0|	ntspacket->valid = true;
  260|      0|	nts_cnt.server_recv_good++;
  261|      0|	nts_cnt.server_recv_bad--;
  262|      0|	return true;
  263|      0|}

LLVMFuzzerTestOneInput:
   22|    201|extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {//ntpsec/tests/ntpd/nts_extens.c
   23|       |	
   24|    201|	if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   19|    402|#define kMinInputLength 20
  ------------------
              	if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   20|    193|#define kMaxInputLength 1024
  ------------------
  |  Branch (24:6): [True: 8, False: 193]
  |  Branch (24:32): [True: 24, False: 169]
  ------------------
   25|     32|        return 0;
   26|     32|    }
   27|       |
   28|    169|	struct ntspacket_t ntspkt;
   29|    169|	memset(&ntspkt, 0, sizeof(ntspkt));
   30|       |
   31|    169|	return extens_server_recv(&ntspkt,(uint8_t*)Data, Size);
   32|    201|}

