Commit 331499c3d7 for bind
commit 331499c3d78fcea9584f6de5092db0a9c99b002d
Author: Alessio Podda <alessio@isc.org>
Date: Mon Aug 31 12:52:52 2026 +0200
Add base32hexnp_encode specialization
Add a specialized base32-to-text conversion function for statically
known output locations and hash size.
diff --git a/lib/dns/fixedname.c b/lib/dns/fixedname.c
index f8d9a49480..70ad467816 100644
--- a/lib/dns/fixedname.c
+++ b/lib/dns/fixedname.c
@@ -13,11 +13,54 @@
/*! \file */
-#include <isc/base32.h>
+#include <string.h>
+
+#include <isc/endian.h>
#include <isc/util.h>
#include <dns/fixedname.h>
+static const unsigned char base32hex[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+
+static inline void
+base32hexnp_encode_block(uint64_t block, unsigned char *dst) {
+ dst[0] = base32hex[(block >> 59) & 0x1fU];
+ dst[1] = base32hex[(block >> 54) & 0x1fU];
+ dst[2] = base32hex[(block >> 49) & 0x1fU];
+ dst[3] = base32hex[(block >> 44) & 0x1fU];
+ dst[4] = base32hex[(block >> 39) & 0x1fU];
+ dst[5] = base32hex[(block >> 34) & 0x1fU];
+ dst[6] = base32hex[(block >> 29) & 0x1fU];
+ dst[7] = base32hex[(block >> 24) & 0x1fU];
+}
+
+static isc_result_t
+base32hexnp_encode(const dns_nsec3hash_t *hash, isc_buffer_t *target) {
+ const unsigned char *src = *hash;
+ unsigned char *dst;
+ uint64_t block;
+
+ if (isc_buffer_availablelength(target) < 32U) {
+ return ISC_R_NOSPACE;
+ }
+ dst = isc_buffer_used(target);
+
+ for (size_t offset = 0; offset < 15U; offset += 5U) {
+ memmove(&block, src, sizeof(block));
+ base32hexnp_encode_block(be64toh(block), dst);
+
+ src += 5;
+ dst += 8;
+ }
+
+ /* Load bytes 12..19, then discard the first three bytes. */
+ memmove(&block, (*hash) + 12, sizeof(block));
+ base32hexnp_encode_block(be64toh(block) << 24, dst);
+
+ isc_buffer_add(target, 32U);
+ return ISC_R_SUCCESS;
+}
+
void
dns_fixedname_init(dns_fixedname_t *fixed) {
dns_name_init(&fixed->name);
@@ -42,22 +85,17 @@ dns_fixedname_initname(dns_fixedname_t *fixed) {
}
isc_result_t
-dns_fixedname_fromnsec3hash(dns_fixedname_t *fixed, const unsigned char *hash,
- size_t hash_length, const dns_name_t *origin) {
+dns_fixedname_fromnsec3hash(dns_fixedname_t *fixed, const dns_nsec3hash_t *hash,
+ const dns_name_t *origin) {
isc_region_t origin_region;
- isc_region_t source = {
- .base = UNCONST(hash),
- .length = (unsigned int)hash_length,
- };
REQUIRE(fixed != NULL);
REQUIRE(hash != NULL);
REQUIRE(DNS_NAME_VALID(origin));
isc_buffer_clear(&fixed->buffer);
- isc_buffer_putuint8(&fixed->buffer,
- (uint8_t)((hash_length * 8U + 4U) / 5U));
- RETERR(isc_base32hexnp_totext(&source, -1, "", &fixed->buffer));
+ isc_buffer_putuint8(&fixed->buffer, 32U);
+ RETERR(base32hexnp_encode(hash, &fixed->buffer));
dns_name_toregion(origin, &origin_region);
RETERR(isc_buffer_copyregion(&fixed->buffer, &origin_region));
diff --git a/lib/dns/include/dns/fixedname.h b/lib/dns/include/dns/fixedname.h
index 2b5d7da3e8..814b82b9e0 100644
--- a/lib/dns/include/dns/fixedname.h
+++ b/lib/dns/include/dns/fixedname.h
@@ -50,6 +50,7 @@
*****/
#include <isc/buffer.h>
+#include <isc/md.h>
#include <dns/name.h>
@@ -63,6 +64,8 @@ struct dns_fixedname {
unsigned char data[DNS_NAME_MAXWIRE];
};
+typedef unsigned char dns_nsec3hash_t[ISC_SHA1_DIGESTLENGTH];
+
void
dns_fixedname_init(dns_fixedname_t *fixed);
@@ -76,8 +79,8 @@ dns_name_t *
dns_fixedname_initname(dns_fixedname_t *fixed);
isc_result_t
-dns_fixedname_fromnsec3hash(dns_fixedname_t *fixed, const unsigned char *hash,
- size_t hash_length, const dns_name_t *origin);
+dns_fixedname_fromnsec3hash(dns_fixedname_t *fixed, const dns_nsec3hash_t *hash,
+ const dns_name_t *origin);
/*%<
* Initialize 'fixed' with an NSEC3 owner name made from the base32hex
* encoding of 'hash', followed by 'origin'.
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index 9211026387..bfbb235aec 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -255,7 +255,8 @@ dns_nsec3_hashname(dns_fixedname_t *result,
SET_IF_NOT_NULL(hash_length, len);
- return dns_fixedname_fromnsec3hash(result, rethash, len, origin);
+ return dns_fixedname_fromnsec3hash(
+ result, (const dns_nsec3hash_t *)rethash, origin);
}
unsigned int