- outpkt.len = inpkt->len;
- EVP_EncryptInit(cl->cipher_pktctx, cl->cipher_pkttype, cl->cipher_pktkey, NULL);
- EVP_EncryptUpdate(cl->cipher_pktctx, outpkt.data, &outlen, inpkt->data, inpkt->len);
- EVP_EncryptFinal(cl->cipher_pktctx, outpkt.data + outlen, &outpad);
- outlen += outpad;
+ /* Check the message authentication code */
+
+ if(myself->digest && myself->maclength)
+ {
+ inpkt->len -= myself->maclength;
+ HMAC(myself->digest, myself->key, myself->keylength, (char *)&inpkt->seqno, inpkt->len, hmac, NULL);
+ if(memcmp(hmac, (char *)&inpkt->seqno + inpkt->len, myself->maclength))
+ {
+ syslog(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"), n->name, n->hostname);
+ return;
+ }
+ }
+
+ /* Decrypt the packet */
+
+ if(myself->cipher)
+ {
+ outpkt = pkt[nextpkt++];
+
+ EVP_DecryptInit(&ctx, myself->cipher, myself->key, myself->key + myself->cipher->key_len);
+ EVP_DecryptUpdate(&ctx, (char *)&outpkt->seqno, &outlen, (char *)&inpkt->seqno, inpkt->len);
+ EVP_DecryptFinal(&ctx, (char *)&outpkt->seqno + outlen, &outpad);
+
+ outpkt->len = outlen + outpad;
+ inpkt = outpkt;
+ }
+
+ /* Check the sequence number */
+
+ inpkt->len -= sizeof(inpkt->seqno);
+ inpkt->seqno = ntohl(inpkt->seqno);
+
+ if(inpkt->seqno <= n->received_seqno)
+ {
+ syslog(LOG_DEBUG, _("Got late or replayed packet from %s (%s), seqno %d"), n->name, n->hostname, inpkt->seqno);
+ return;
+ }