diff --git a/lib/cache/nsec1.c b/lib/cache/nsec1.c
index 752871bf98d810b31e4457d9065ea5abc3f8f80a..c4229ddd3bcaaf99f60db3d85ec50c144fde3fc8 100644
--- a/lib/cache/nsec1.c
+++ b/lib/cache/nsec1.c
@@ -314,9 +314,8 @@ int nsec1_encloser(struct key *k, struct answer *ans,
 
 	/* Final checks, split for matching vs. covering our sname. */
 	const knot_rrset_t *nsec_rr = ans->rrsets[AR_NSEC].set.rr;
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec_bitmap(&nsec_rr->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata);
 	assert(bm);
 
 	if (exact_match) {
@@ -389,9 +388,8 @@ static bool nonexistence_ok(int cmp, const knot_rrset_t *rrs)
 	if (cmp != 2) {
 		return false;
 	}
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec_bitmap(&rrs->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(rrs->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(rrs->rrs.rdata);
 	return kr_nsec_children_in_zone_check(bm, bm_size) != 0;
 }
 
@@ -447,9 +445,8 @@ int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
 	assert(nsec_rr);
 	const uint32_t new_ttl_log =
 		kr_verbose_status ? nsec_rr->ttl : -1;
-	uint8_t *bm = NULL;
-	uint16_t bm_size;
-	knot_nsec_bitmap(&nsec_rr->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata);
 	int ret;
 	struct answer_rrset * const arw = &ans->rrsets[AR_WILD];
 	if (!bm) {
diff --git a/lib/cache/nsec3.c b/lib/cache/nsec3.c
index 27d065eac96fc0935246a99c8e31de87eec270da..8eb4e97106b3e854f0d9f44bb1f996420d155ed3 100644
--- a/lib/cache/nsec3.c
+++ b/lib/cache/nsec3.c
@@ -369,9 +369,8 @@ int nsec3_encloser(struct key *k, struct answer *ans,
 
 		/* Exactly matched NSEC3: two cases, one after another. */
 		const knot_rrset_t *nsec_rr = ans->rrsets[ans_id].set.rr;
-		uint8_t *bm = NULL;
-		uint16_t bm_size = 0;
-		knot_nsec3_bitmap(&nsec_rr->rrs, 0, &bm, &bm_size);
+		const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata);
+		uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata);
 		assert(bm);
 		if (name_labels == sname_labels) {
 			if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype,
@@ -478,9 +477,8 @@ int nsec3_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
 	}
 
 	/* The wildcard exists.  Find if it's NODATA - check type bitmap. */
-	uint8_t *bm = NULL;
-	uint16_t bm_size;
-	knot_nsec3_bitmap(&nsec_rr->rrs, 0, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata);
+	uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata);
 	assert(bm);
 	if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) {
 		/* NODATA proven; just need to add SOA+RRSIG later */
diff --git a/lib/dnssec/nsec.c b/lib/dnssec/nsec.c
index 1770cdeb2f5d0c17965c7a87ad87b4e3b6ad6b63..5fdba4fcab5657a1cd23280c2506c554354f9ec4 100644
--- a/lib/dnssec/nsec.c
+++ b/lib/dnssec/nsec.c
@@ -117,9 +117,9 @@ static int nsec_covers(const knot_rrset_t *nsec, const knot_dname_t *sname)
 	if (!knot_dname_is_sub(sname, nsec->owner)) {
 		return kr_ok();
 	}
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
+
 	return kr_nsec_children_in_zone_check(bm, bm_size);
 }
 
@@ -318,9 +318,8 @@ static int no_data_response_check_rrtype(int *flags, const knot_rrset_t *nsec,
 {
 	assert(flags && nsec);
 
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
 	int ret = kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec->owner);
 	if (ret == kr_ok()) {
 		*flags |= FLG_NOEXIST_RRTYPE;
@@ -490,8 +489,6 @@ int kr_nsec_existence_denial(const knot_pkt_t *pkt, knot_section_t section_id,
 int kr_nsec_ref_to_unsigned(const knot_pkt_t *pkt)
 {
 	int nsec_found = 0;
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
 	const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_AUTHORITY);
 	if (!sec) {
 		return kr_error(EINVAL);
@@ -521,7 +518,8 @@ int kr_nsec_ref_to_unsigned(const knot_pkt_t *pkt)
 				continue;
 			}
 			nsec_found = 1;
-			knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
+			const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+			uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
 			if (!bm) {
 				return kr_error(EINVAL);
 			}
@@ -563,9 +561,8 @@ int kr_nsec_matches_name_and_type(const knot_rrset_t *nsec,
 	if (!knot_dname_is_equal(nsec->owner, name)) {
 		return kr_error(ENOENT);
 	}
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+	uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
 	if (!bm) {
 		return kr_error(EINVAL);
 	}
diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c
index 6ed02068ab201bd7b58c773847688f0d6eac0143..eaf94aae72deb5b16fdc4477095a534cd3e50d40 100644
--- a/lib/dnssec/nsec3.c
+++ b/lib/dnssec/nsec3.c
@@ -395,9 +395,8 @@ static int closest_encloser_proof(const knot_pkt_t *pkt,
 		 * does not really exist (authoritatively in this zone,
 		 * even in case of opt-out).
 		 */
-		uint8_t *bm = NULL;
-		uint16_t bm_size;
-		knot_nsec3_bitmap(&rrset->rrs, 0, &bm, &bm_size);
+		const uint8_t *bm = knot_nsec3_bitmap(rrset->rrs.rdata);
+		uint16_t bm_size = knot_nsec3_bitmap_len(rrset->rrs.rdata);
 		if (kr_nsec_children_in_zone_check(bm, bm_size) != 0) {
 			continue; /* no fatal errors from bad RRs */
 		}
@@ -551,9 +550,8 @@ static int nodata_find(const knot_pkt_t *pkt, knot_section_t section_id,
 			/* LATER(optim.): we repeatedly recompute the hash of `name` */
 		}
 
-		uint8_t *bm = NULL;
-		uint16_t bm_size;
-		knot_nsec3_bitmap(&nsec3->rrs, 0, &bm, &bm_size);
+		const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+		uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
 		if (kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec3->owner) == kr_ok()) {
 			return kr_ok();
 		}
@@ -706,9 +704,8 @@ int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt)
 				continue;
 			}
 
-			uint8_t *bm = NULL;
-			uint16_t bm_size = 0;
-			knot_nsec3_bitmap(&nsec3->rrs, 0, &bm, &bm_size);
+			const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+			uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
 			if (!bm) {
 				return kr_error(EINVAL);
 			}
@@ -767,9 +764,8 @@ int kr_nsec3_matches_name_and_type(const knot_rrset_t *nsec3,
 	if (ret) {
 		return kr_error(ret);
 	}
-	uint8_t *bm = NULL;
-	uint16_t bm_size = 0;
-	knot_nsec3_bitmap(&nsec3->rrs, 0, &bm, &bm_size);
+	const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+	uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
 	if (!bm) {
 		return kr_error(EINVAL);
 	}