diff --git a/src/libknot/packet/pkt.c b/src/libknot/packet/pkt.c
index 56d053c8fcc8e290c7609ad96fdf59853c518235..c25757a4ebfa0dad43f38266b46267b9c019719d 100644
--- a/src/libknot/packet/pkt.c
+++ b/src/libknot/packet/pkt.c
@@ -725,10 +725,12 @@ int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags)
 		}
 
 		/* Strip TSIG RR from wireformat and decrease ARCOUNT. */
-		pkt->parsed -= rr_size;
-		pkt->size -= rr_size;
-		knot_wire_set_id(pkt->wire, tsig_rdata_orig_id(rr));
-		knot_wire_set_arcount(pkt->wire, knot_wire_get_arcount(pkt->wire) - 1);
+		if (!(flags & KNOT_PF_KEEPWIRE)) {
+			pkt->parsed -= rr_size;
+			pkt->size -= rr_size;
+			knot_wire_set_id(pkt->wire, tsig_rdata_orig_id(rr));
+			knot_wire_set_arcount(pkt->wire, knot_wire_get_arcount(pkt->wire) - 1);
+		}
 
 		/* Remember TSIG RR. */
 		pkt->tsig_rr = rr;
diff --git a/src/libknot/packet/pkt.h b/src/libknot/packet/pkt.h
index b5aefa0de3694a57af51efdaa537adaeba978698..ec4b16202de2da7ec24999b7f42677b3e851d5a8 100644
--- a/src/libknot/packet/pkt.h
+++ b/src/libknot/packet/pkt.h
@@ -71,7 +71,8 @@ enum {
 	KNOT_PF_NULL      = 0 << 0, /*!< No flags. */
 	KNOT_PF_FREE      = 1 << 1, /*!< Free with packet. */
 	KNOT_PF_NOTRUNC   = 1 << 2, /*!< Don't truncate. */
-	KNOT_PF_CHECKDUP  = 1 << 3  /*!< Check for duplicates. */
+	KNOT_PF_CHECKDUP  = 1 << 3, /*!< Check for duplicates. */
+	KNOT_PF_KEEPWIRE  = 1 << 4  /*!< Keep wireformat untouched when parsing. */
 };
 
 /*!
@@ -242,8 +243,10 @@ const knot_pktsection_t *knot_pkt_section(const knot_pkt_t *pkt, knot_section_t
  * Parses both QUESTION and all packet sections,
  * includes semantic checks over specific RRs (TSIG, OPT).
  *
+ * \note For KNOT_PF_KEEPWIRE see note for \fn knot_pkt_parse_rr
+ *
  * \param pkt Given packet.
- * \param flags Parsing flags (allowed KNOT_PACKET_DUPL_NO_MERGE )
+ * \param flags Parsing flags (allowed KNOT_PF_KEEPWIRE)
  * \return KNOT_EOK, KNOT_EMALF and other errors
  */
 int knot_pkt_parse(knot_pkt_t *pkt, unsigned flags);
@@ -256,16 +259,35 @@ int knot_pkt_parse_question(knot_pkt_t *pkt);
 /*!
  * \brief Parse single resource record.
  *
+ * \note When KNOT_PF_KEEPWIRE is set, TSIG RR is not stripped from the wire
+ *       and is processed as any other RR.
+ *
  * \param pkt
  * \param flags
  * \return KNOT_EOK, KNOT_EFEWDATA if not enough data or various errors
  */
 int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags);
 
-/*! \brief Parse current packet section. */
+/*!
+ * \brief Parse current packet section.
+ *
+ * \note For KNOT_PF_KEEPWIRE see note for \fn knot_pkt_parse_rr
+ *
+ * \param pkt
+ * \param flags
+ * \return KNOT_EOK, KNOT_EFEWDATA if not enough data or various errors
+ */
 int knot_pkt_parse_section(knot_pkt_t *pkt, unsigned flags);
 
-/*! \brief Parse whole packet payload */
+/*!
+ * \brief Parse whole packet payload.
+ *
+ * \note For KNOT_PF_KEEPWIRE see note for \fn knot_pkt_parse_rr
+ *
+ * \param pkt
+ * \param flags
+ * \return KNOT_EOK, KNOT_EFEWDATA if not enough data or various errors
+ */
 int knot_pkt_parse_payload(knot_pkt_t *pkt, unsigned flags);
 
 /*!