fix: usr: Fix rndc-confgen aborting on HMAC-SHA-384/512 keys above 512 bits

`rndc-confgen -A hmac-sha384` and `-A hmac-sha512` documented a `-b`
range of 1..1024, but any value above 512 aborted on hardened builds
instead of producing a key. The full advertised range now works.

Closes #5903

Merge branch '5903-hmac-generate-stack-overflow' into 'main'

See merge request isc-projects/bind9!11903
This commit is contained in:
Ondřej Surý 2026-04-29 20:34:31 +02:00
commit c137dcd1a4
3 changed files with 35 additions and 2 deletions

View file

@ -21,6 +21,7 @@
#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/file.h>
#include <isc/md.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
@ -117,7 +118,7 @@ generate_key(isc_mem_t *mctx, dns_secalg_t alg, int keysize,
isc_result_t result = ISC_R_SUCCESS;
isc_buffer_t key_rawbuffer;
isc_region_t key_rawregion;
char key_rawsecret[64];
char key_rawsecret[ISC_MAX_BLOCK_SIZE];
dst_key_t *key = NULL;
switch (alg) {

View file

@ -9,7 +9,9 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import base64
import os
import re
import subprocess
import pytest
@ -67,3 +69,33 @@ def test_ddns_confgen_default():
def test_ddns_confgen_rejects_injection(args):
with pytest.raises(subprocess.CalledProcessError):
isctest.run.cmd([DDNSCONFGEN, "-q", *args])
def _extract_secret(stdout: bytes) -> bytes:
match = re.search(rb'secret\s+"([^"]+)"', stdout)
assert match is not None, f"no secret in output: {stdout!r}"
return base64.b64decode(match.group(1))
@pytest.mark.parametrize(
"algorithm,bits",
[
("hmac-sha256", 1),
("hmac-sha256", 256),
("hmac-sha256", 512),
("hmac-sha384", 1),
("hmac-sha384", 384),
("hmac-sha384", 513),
("hmac-sha384", 768),
("hmac-sha384", 1024),
("hmac-sha512", 1),
("hmac-sha512", 512),
("hmac-sha512", 513),
("hmac-sha512", 1024),
],
)
def test_rndc_confgen_hmac_keysize(algorithm, bits):
cmd = isctest.run.cmd([os.environ["RNDCCONFGEN"], "-A", algorithm, "-b", str(bits)])
secret = _extract_secret(cmd.proc.stdout)
assert len(secret) == (bits + 7) // 8
assert f"algorithm {algorithm};".encode() in cmd.proc.stdout

View file

@ -249,7 +249,7 @@ hmac_generate(isc_md_type_t type, dst_key_t *key) {
isc_buffer_t b;
isc_result_t result;
unsigned int bytes, len;
unsigned char data[ISC_MAX_MD_SIZE] = { 0 };
unsigned char data[ISC_MAX_BLOCK_SIZE] = { 0 };
len = isc_md_type_get_block_size(type);