|
|
230545 |
From e8b7be1e1ff3e11bc8d592c3c8d6a0f0d69e9947 Mon Sep 17 00:00:00 2001
|
|
|
230545 |
From: Petr Mensik <pemensik@redhat.com>
|
|
|
230545 |
Date: Tue, 18 Aug 2020 10:54:39 +0200
|
|
|
230545 |
Subject: [PATCH] Fix CVE-2020-8623
|
|
|
230545 |
|
|
|
230545 |
5480. [security] When BIND 9 was compiled with native PKCS#11 support, it
|
|
|
230545 |
was possible to trigger an assertion failure in code
|
|
|
230545 |
determining the number of bits in the PKCS#11 RSA public
|
|
|
230545 |
key with a specially crafted packet. (CVE-2020-8623)
|
|
|
230545 |
[GL #2037]
|
|
|
230545 |
---
|
|
|
230545 |
lib/dns/pkcs11dh_link.c | 15 ++++++-
|
|
|
230545 |
lib/dns/pkcs11dsa_link.c | 8 +++-
|
|
|
230545 |
lib/dns/pkcs11rsa_link.c | 79 +++++++++++++++++++++++++--------
|
|
|
230545 |
lib/isc/include/pk11/internal.h | 3 +-
|
|
|
230545 |
lib/isc/pk11.c | 61 ++++++++++++++++---------
|
|
|
230545 |
5 files changed, 121 insertions(+), 45 deletions(-)
|
|
|
230545 |
|
|
|
230545 |
diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c
|
|
|
230545 |
index e2b60ea..4cd8e32 100644
|
|
|
230545 |
--- a/lib/dns/pkcs11dh_link.c
|
|
|
230545 |
+++ b/lib/dns/pkcs11dh_link.c
|
|
|
230545 |
@@ -748,6 +748,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
CK_BYTE *prime = NULL, *base = NULL, *pub = NULL;
|
|
|
230545 |
CK_ATTRIBUTE *attr;
|
|
|
230545 |
int special = 0;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
isc_result_t result;
|
|
|
230545 |
|
|
|
230545 |
isc_buffer_remainingregion(data, &r);
|
|
|
230545 |
@@ -852,7 +853,11 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
pub = r.base;
|
|
|
230545 |
isc_region_consume(&r, publen);
|
|
|
230545 |
|
|
|
230545 |
- key->key_size = pk11_numbits(prime, plen_);
|
|
|
230545 |
+ result = pk11_numbits(prime, plen_, &bits);
|
|
|
230545 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto cleanup;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3);
|
|
|
230545 |
if (dh->repr == NULL)
|
|
|
230545 |
@@ -1012,6 +1017,7 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
dst_private_t priv;
|
|
|
230545 |
isc_result_t ret;
|
|
|
230545 |
int i;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
pk11_object_t *dh = NULL;
|
|
|
230545 |
CK_ATTRIBUTE *attr;
|
|
|
230545 |
isc_mem_t *mctx;
|
|
|
230545 |
@@ -1082,7 +1088,12 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(dh, CKA_PRIME);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
|
|
|
230545 |
+
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
return (ISC_R_SUCCESS);
|
|
|
230545 |
|
|
|
230545 |
diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c
|
|
|
230545 |
index 12d707a..24d4c14 100644
|
|
|
230545 |
--- a/lib/dns/pkcs11dsa_link.c
|
|
|
230545 |
+++ b/lib/dns/pkcs11dsa_link.c
|
|
|
230545 |
@@ -983,6 +983,7 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
dst_private_t priv;
|
|
|
230545 |
isc_result_t ret;
|
|
|
230545 |
int i;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
pk11_object_t *dsa = NULL;
|
|
|
230545 |
CK_ATTRIBUTE *attr;
|
|
|
230545 |
isc_mem_t *mctx = key->mctx;
|
|
|
230545 |
@@ -1072,7 +1073,12 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(dsa, CKA_PRIME);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
|
|
|
230545 |
+
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
return (ISC_R_SUCCESS);
|
|
|
230545 |
|
|
|
230545 |
diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c
|
|
|
230545 |
index 6c280bf..86e136a 100644
|
|
|
230545 |
--- a/lib/dns/pkcs11rsa_link.c
|
|
|
230545 |
+++ b/lib/dns/pkcs11rsa_link.c
|
|
|
230545 |
@@ -337,6 +337,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
|
|
|
230545 |
key->key_alg == DST_ALG_RSASHA256 ||
|
|
|
230545 |
key->key_alg == DST_ALG_RSASHA512);
|
|
|
230545 |
#endif
|
|
|
230545 |
+ REQUIRE(maxbits <= RSA_MAX_PUBEXP_BITS);
|
|
|
230545 |
|
|
|
230545 |
/*
|
|
|
230545 |
* Reject incorrect RSA key lengths.
|
|
|
230545 |
@@ -381,6 +382,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
|
|
|
230545 |
for (attr = pk11_attribute_first(rsa);
|
|
|
230545 |
attr != NULL;
|
|
|
230545 |
attr = pk11_attribute_next(rsa, attr))
|
|
|
230545 |
+ {
|
|
|
230545 |
switch (attr->type) {
|
|
|
230545 |
case CKA_MODULUS:
|
|
|
230545 |
INSIST(keyTemplate[5].type == attr->type);
|
|
|
230545 |
@@ -401,12 +403,16 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
|
|
|
230545 |
memmove(keyTemplate[6].pValue, attr->pValue,
|
|
|
230545 |
attr->ulValueLen);
|
|
|
230545 |
keyTemplate[6].ulValueLen = attr->ulValueLen;
|
|
|
230545 |
- if (pk11_numbits(attr->pValue,
|
|
|
230545 |
- attr->ulValueLen) > maxbits &&
|
|
|
230545 |
- maxbits != 0)
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen,
|
|
|
230545 |
+ &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS ||
|
|
|
230545 |
+ (bits > maxbits && maxbits != 0)) {
|
|
|
230545 |
DST_RET(DST_R_VERIFYFAILURE);
|
|
|
230545 |
+ }
|
|
|
230545 |
break;
|
|
|
230545 |
}
|
|
|
230545 |
+ }
|
|
|
230545 |
pk11_ctx->object = CK_INVALID_HANDLE;
|
|
|
230545 |
pk11_ctx->ontoken = false;
|
|
|
230545 |
PK11_RET(pkcs_C_CreateObject,
|
|
|
230545 |
@@ -1086,6 +1092,7 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
|
|
|
230545 |
keyTemplate[5].ulValueLen = attr->ulValueLen;
|
|
|
230545 |
break;
|
|
|
230545 |
case CKA_PUBLIC_EXPONENT:
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
INSIST(keyTemplate[6].type == attr->type);
|
|
|
230545 |
keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
|
|
|
230545 |
attr->ulValueLen);
|
|
|
230545 |
@@ -1094,10 +1101,12 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
|
|
|
230545 |
memmove(keyTemplate[6].pValue, attr->pValue,
|
|
|
230545 |
attr->ulValueLen);
|
|
|
230545 |
keyTemplate[6].ulValueLen = attr->ulValueLen;
|
|
|
230545 |
- if (pk11_numbits(attr->pValue,
|
|
|
230545 |
- attr->ulValueLen)
|
|
|
230545 |
- > RSA_MAX_PUBEXP_BITS)
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen,
|
|
|
230545 |
+ &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS || bits > RSA_MAX_PUBEXP_BITS)
|
|
|
230545 |
+ {
|
|
|
230545 |
DST_RET(DST_R_VERIFYFAILURE);
|
|
|
230545 |
+ }
|
|
|
230545 |
break;
|
|
|
230545 |
}
|
|
|
230545 |
pk11_ctx->object = CK_INVALID_HANDLE;
|
|
|
230545 |
@@ -1475,6 +1484,8 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
CK_BYTE *exponent = NULL, *modulus = NULL;
|
|
|
230545 |
CK_ATTRIBUTE *attr;
|
|
|
230545 |
unsigned int length;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
+ isc_result_t ret = ISC_R_SUCCESS;
|
|
|
230545 |
|
|
|
230545 |
isc_buffer_remainingregion(data, &r);
|
|
|
230545 |
if (r.length == 0)
|
|
|
230545 |
@@ -1492,9 +1503,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
|
|
|
230545 |
if (e_bytes == 0) {
|
|
|
230545 |
if (r.length < 2) {
|
|
|
230545 |
- isc_safe_memwipe(rsa, sizeof(*rsa));
|
|
|
230545 |
- isc_mem_put(key->mctx, rsa, sizeof(*rsa));
|
|
|
230545 |
- return (DST_R_INVALIDPUBLICKEY);
|
|
|
230545 |
+ DST_RET(DST_R_INVALIDPUBLICKEY);
|
|
|
230545 |
}
|
|
|
230545 |
e_bytes = (*r.base) << 8;
|
|
|
230545 |
isc_region_consume(&r, 1);
|
|
|
230545 |
@@ -1503,16 +1512,18 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
}
|
|
|
230545 |
|
|
|
230545 |
if (r.length < e_bytes) {
|
|
|
230545 |
- isc_safe_memwipe(rsa, sizeof(*rsa));
|
|
|
230545 |
- isc_mem_put(key->mctx, rsa, sizeof(*rsa));
|
|
|
230545 |
- return (DST_R_INVALIDPUBLICKEY);
|
|
|
230545 |
+ DST_RET(DST_R_INVALIDPUBLICKEY);
|
|
|
230545 |
}
|
|
|
230545 |
exponent = r.base;
|
|
|
230545 |
isc_region_consume(&r, e_bytes);
|
|
|
230545 |
modulus = r.base;
|
|
|
230545 |
mod_bytes = r.length;
|
|
|
230545 |
|
|
|
230545 |
- key->key_size = pk11_numbits(modulus, mod_bytes);
|
|
|
230545 |
+ ret = pk11_numbits(modulus, mod_bytes, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
isc_buffer_forward(data, length);
|
|
|
230545 |
|
|
|
230545 |
@@ -1562,9 +1573,12 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
|
|
|
230545 |
rsa->repr,
|
|
|
230545 |
rsa->attrcnt * sizeof(*attr));
|
|
|
230545 |
}
|
|
|
230545 |
+ ret = ISC_R_NOMEMORY;
|
|
|
230545 |
+
|
|
|
230545 |
+ err:
|
|
|
230545 |
isc_safe_memwipe(rsa, sizeof(*rsa));
|
|
|
230545 |
isc_mem_put(key->mctx, rsa, sizeof(*rsa));
|
|
|
230545 |
- return (ISC_R_NOMEMORY);
|
|
|
230545 |
+ return (ret);
|
|
|
230545 |
}
|
|
|
230545 |
|
|
|
230545 |
static isc_result_t
|
|
|
230545 |
@@ -1743,6 +1757,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|
|
230545 |
pk11_object_t *pubrsa;
|
|
|
230545 |
pk11_context_t *pk11_ctx = NULL;
|
|
|
230545 |
isc_result_t ret;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
|
|
|
230545 |
if (label == NULL)
|
|
|
230545 |
return (DST_R_NOENGINE);
|
|
|
230545 |
@@ -1829,7 +1844,11 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
return (ISC_R_SUCCESS);
|
|
|
230545 |
|
|
|
230545 |
@@ -1915,6 +1934,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
CK_ATTRIBUTE *attr;
|
|
|
230545 |
isc_mem_t *mctx = key->mctx;
|
|
|
230545 |
const char *engine = NULL, *label = NULL;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
|
|
|
230545 |
/* read private key file */
|
|
|
230545 |
ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv;;
|
|
|
230545 |
@@ -2058,12 +2078,22 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
|
|
|
230545 |
+
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (bits > RSA_MAX_PUBEXP_BITS) {
|
|
|
230545 |
DST_RET(ISC_R_RANGE);
|
|
|
230545 |
+ }
|
|
|
230545 |
|
|
|
230545 |
dst__privstruct_free(&priv, mctx);
|
|
|
230545 |
isc_safe_memwipe(&priv, sizeof(priv));
|
|
|
230545 |
@@ -2098,6 +2128,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
|
|
|
230545 |
pk11_context_t *pk11_ctx = NULL;
|
|
|
230545 |
isc_result_t ret;
|
|
|
230545 |
unsigned int i;
|
|
|
230545 |
+ unsigned int bits;
|
|
|
230545 |
|
|
|
230545 |
UNUSED(pin);
|
|
|
230545 |
|
|
|
230545 |
@@ -2192,12 +2223,22 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
|
|
|
230545 |
+
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (bits > RSA_MAX_PUBEXP_BITS) {
|
|
|
230545 |
DST_RET(ISC_R_RANGE);
|
|
|
230545 |
+ }
|
|
|
230545 |
|
|
|
230545 |
attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
|
|
|
230545 |
INSIST(attr != NULL);
|
|
|
230545 |
- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
|
|
|
230545 |
+ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits);
|
|
|
230545 |
+ if (ret != ISC_R_SUCCESS) {
|
|
|
230545 |
+ goto err;
|
|
|
230545 |
+ }
|
|
|
230545 |
+ key->key_size = bits;
|
|
|
230545 |
|
|
|
230545 |
pk11_return_session(pk11_ctx);
|
|
|
230545 |
isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
|
|
|
230545 |
diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h
|
|
|
230545 |
index 603712a..b9680bc 100644
|
|
|
230545 |
--- a/lib/isc/include/pk11/internal.h
|
|
|
230545 |
+++ b/lib/isc/include/pk11/internal.h
|
|
|
230545 |
@@ -27,7 +27,8 @@ void pk11_mem_put(void *ptr, size_t size);
|
|
|
230545 |
|
|
|
230545 |
CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype);
|
|
|
230545 |
|
|
|
230545 |
-unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt);
|
|
|
230545 |
+isc_result_t
|
|
|
230545 |
+pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits);
|
|
|
230545 |
|
|
|
230545 |
CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj);
|
|
|
230545 |
|
|
|
230545 |
diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c
|
|
|
230545 |
index 4b85527..9c450da 100644
|
|
|
230545 |
--- a/lib/isc/pk11.c
|
|
|
230545 |
+++ b/lib/isc/pk11.c
|
|
|
230545 |
@@ -982,13 +982,15 @@ pk11_get_best_token(pk11_optype_t optype) {
|
|
|
230545 |
return (token->slotid);
|
|
|
230545 |
}
|
|
|
230545 |
|
|
|
230545 |
-unsigned int
|
|
|
230545 |
-pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) {
|
|
|
230545 |
+isc_result_t
|
|
|
230545 |
+pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) {
|
|
|
230545 |
unsigned int bitcnt, i;
|
|
|
230545 |
CK_BYTE top;
|
|
|
230545 |
|
|
|
230545 |
- if (bytecnt == 0)
|
|
|
230545 |
- return (0);
|
|
|
230545 |
+ if (bytecnt == 0) {
|
|
|
230545 |
+ *bits = 0;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
bitcnt = bytecnt * 8;
|
|
|
230545 |
for (i = 0; i < bytecnt; i++) {
|
|
|
230545 |
top = data[i];
|
|
|
230545 |
@@ -996,26 +998,41 @@ pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) {
|
|
|
230545 |
bitcnt -= 8;
|
|
|
230545 |
continue;
|
|
|
230545 |
}
|
|
|
230545 |
- if (top & 0x80)
|
|
|
230545 |
- return (bitcnt);
|
|
|
230545 |
- if (top & 0x40)
|
|
|
230545 |
- return (bitcnt - 1);
|
|
|
230545 |
- if (top & 0x20)
|
|
|
230545 |
- return (bitcnt - 2);
|
|
|
230545 |
- if (top & 0x10)
|
|
|
230545 |
- return (bitcnt - 3);
|
|
|
230545 |
- if (top & 0x08)
|
|
|
230545 |
- return (bitcnt - 4);
|
|
|
230545 |
- if (top & 0x04)
|
|
|
230545 |
- return (bitcnt - 5);
|
|
|
230545 |
- if (top & 0x02)
|
|
|
230545 |
- return (bitcnt - 6);
|
|
|
230545 |
- if (top & 0x01)
|
|
|
230545 |
- return (bitcnt - 7);
|
|
|
230545 |
+ if (top & 0x80) {
|
|
|
230545 |
+ *bits = bitcnt;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x40) {
|
|
|
230545 |
+ *bits = bitcnt - 1;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x20) {
|
|
|
230545 |
+ *bits = bitcnt - 2;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x10) {
|
|
|
230545 |
+ *bits = bitcnt - 3;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x08) {
|
|
|
230545 |
+ *bits = bitcnt - 4;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x04) {
|
|
|
230545 |
+ *bits = bitcnt - 5;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x02) {
|
|
|
230545 |
+ *bits = bitcnt - 6;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
+ if (top & 0x01) {
|
|
|
230545 |
+ *bits = bitcnt - 7;
|
|
|
230545 |
+ return (ISC_R_SUCCESS);
|
|
|
230545 |
+ }
|
|
|
230545 |
break;
|
|
|
230545 |
}
|
|
|
230545 |
- INSIST(0);
|
|
|
230545 |
- ISC_UNREACHABLE();
|
|
|
230545 |
+ return (ISC_R_RANGE);
|
|
|
230545 |
}
|
|
|
230545 |
|
|
|
230545 |
CK_ATTRIBUTE *
|
|
|
230545 |
--
|
|
|
230545 |
2.26.2
|
|
|
230545 |
|