Make LHASH a completely internal type

The one remaining external reference was in an unused parameter where it
was impossible to obtain a non-null value. Remove the last of that
machinery from the public API. This leaves us free to completely rework
LHASH_OF(T) internally, including making it a template that understands
whether it owns its values.

(If we end up needing to revert it, we can still make the real
LHASH_OF(T) into a template. It just won't be called LHASH_OF(T)
anymore.)

Update-Note: Calling code which references LHASH_OF(T) will no longer
compile. We have had no public APIs that allow a caller to usefully
construct an LHASH_OF(T) for some time, so this only ever came up in odd
cases around bindings APIs.

Change-Id: I5a44310b04d8f8f3599f0f356b64786e62db5fbf
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78787
Reviewed-by: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/conf/conf.cc b/crypto/conf/conf.cc
index 02f2be3..d5177ef 100644
--- a/crypto/conf/conf.cc
+++ b/crypto/conf/conf.cc
@@ -21,7 +21,6 @@
 #include <openssl/bio.h>
 #include <openssl/buf.h>
 #include <openssl/err.h>
-#include <openssl/lhash.h>
 #include <openssl/mem.h>
 
 #include "../internal.h"
diff --git a/crypto/lhash/internal.h b/crypto/lhash/internal.h
index cb09dfa..5484880 100644
--- a/crypto/lhash/internal.h
+++ b/crypto/lhash/internal.h
@@ -15,7 +15,7 @@
 #ifndef OPENSSL_HEADER_CRYPTO_LHASH_INTERNAL_H
 #define OPENSSL_HEADER_CRYPTO_LHASH_INTERNAL_H
 
-#include <openssl/lhash.h>
+#include <openssl/base.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -40,8 +40,14 @@
 //
 // A macro will be defined for each of the |OPENSSL_lh_*| functions below. For
 // |LHASH_OF(foo)|, the macros would be |lh_foo_new|, |lh_foo_num_items| etc.
+//
+// TODO(davidben): Now that this type is completely internal, this can just be a
+// C++ template without any macros.
 
 
+#define LHASH_OF(type) struct lhash_st_##type
+#define DECLARE_LHASH_OF(type) LHASH_OF(type);
+
 // lhash_cmp_func is a comparison function that returns a value equal, or not
 // equal, to zero depending on whether |*a| is equal, or not equal to |*b|,
 // respectively. Note the difference between this and |stack_cmp_func| in that
diff --git a/crypto/lhash/lhash.cc b/crypto/lhash/lhash.cc
index 1af8df7..28fde70 100644
--- a/crypto/lhash/lhash.cc
+++ b/crypto/lhash/lhash.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <openssl/lhash.h>
-
 #include <assert.h>
 #include <limits.h>
 #include <string.h>
diff --git a/crypto/lhash/lhash_test.cc b/crypto/lhash/lhash_test.cc
index a458580..ec13628 100644
--- a/crypto/lhash/lhash_test.cc
+++ b/crypto/lhash/lhash_test.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <openssl/lhash.h>
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/crypto/obj/obj.cc b/crypto/obj/obj.cc
index 9fa26bb..7e38bfb 100644
--- a/crypto/obj/obj.cc
+++ b/crypto/obj/obj.cc
@@ -21,7 +21,6 @@
 #include <openssl/asn1.h>
 #include <openssl/bytestring.h>
 #include <openssl/err.h>
-#include <openssl/lhash.h>
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
diff --git a/crypto/pool/internal.h b/crypto/pool/internal.h
index 2533fc9..27315b6 100644
--- a/crypto/pool/internal.h
+++ b/crypto/pool/internal.h
@@ -15,7 +15,6 @@
 #ifndef OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H
 #define OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H
 
-#include <openssl/lhash.h>
 #include <openssl/thread.h>
 
 #include "../internal.h"
diff --git a/decrepit/x509/x509_decrepit.cc b/decrepit/x509/x509_decrepit.cc
index 778f129..5611d42 100644
--- a/decrepit/x509/x509_decrepit.cc
+++ b/decrepit/x509/x509_decrepit.cc
@@ -19,7 +19,7 @@
 #include <openssl/conf.h>
 
 
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+X509_EXTENSION *X509V3_EXT_conf_nid(CRYPTO_MUST_BE_NULL *conf,
                                     const X509V3_CTX *ctx, int ext_nid,
                                     const char *value) {
   assert(conf == NULL);
diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h
index 60c1b62..b3650af 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -290,12 +290,10 @@
 typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
 typedef struct ASN1_ADB_st ASN1_ADB;
 
-typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL;
-
 struct ASN1_ADB_st {
   uint32_t flags;       /* Various flags */
   unsigned long offset; /* Offset of selector field */
-  ASN1_MUST_BE_NULL *unused;
+  CRYPTO_MUST_BE_NULL *unused;
   const ASN1_ADB_TABLE *tbl;       /* Table of possible types */
   long tblcount;                   /* Number of entries in tbl */
   const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
diff --git a/include/openssl/base.h b/include/openssl/base.h
index ebbb1cf..43e3a01 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -239,6 +239,10 @@
 // an opaque, non-NULL |ASN1_NULL*| pointer.
 typedef struct asn1_null_st ASN1_NULL;
 
+// CRYPTO_MUST_BE_NULL is an opaque type that is never returned from BoringSSL.
+// It is used in function parameters that must be NULL.
+typedef struct crypto_must_be_null_st CRYPTO_MUST_BE_NULL;
+
 typedef int ASN1_BOOLEAN;
 typedef struct ASN1_ITEM_st ASN1_ITEM;
 typedef struct asn1_object_st ASN1_OBJECT;
diff --git a/include/openssl/conf.h b/include/openssl/conf.h
index ff20b60..9bbded4 100644
--- a/include/openssl/conf.h
+++ b/include/openssl/conf.h
@@ -18,7 +18,6 @@
 #include <openssl/base.h>   // IWYU pragma: export
 
 #include <openssl/stack.h>
-#include <openssl/lhash.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -50,7 +49,6 @@
 };
 
 DEFINE_STACK_OF(CONF_VALUE)
-DECLARE_LHASH_OF(CONF_VALUE)
 
 
 // NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method|
diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h
index 6b305ac..076d271 100644
--- a/include/openssl/lhash.h
+++ b/include/openssl/lhash.h
@@ -1,4 +1,4 @@
-// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+// Copyright 2025 The BoringSSL Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,28 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef OPENSSL_HEADER_LHASH_H
-#define OPENSSL_HEADER_LHASH_H
+// This header is provided in order to make compiling against code that expects
+// OpenSSL easier.
 
-#include <openssl/base.h>   // IWYU pragma: export
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-// lhash is an internal library and not exported for use outside BoringSSL. This
-// header is provided for compatibility with code that expects OpenSSL.
-
-
-// These two macros are exported for compatibility with existing callers of
-// |X509V3_EXT_conf_nid|. Do not use these symbols outside BoringSSL.
-#define LHASH_OF(type) struct lhash_st_##type
-#define DECLARE_LHASH_OF(type) LHASH_OF(type);
-
-
-#if defined(__cplusplus)
-}  // extern C
-#endif
-
-#endif  // OPENSSL_HEADER_LHASH_H
+#include "base.h"
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 58508a5..9d03ca0 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -30,7 +30,6 @@
 #include <openssl/ecdh.h>
 #include <openssl/ecdsa.h>
 #include <openssl/evp.h>
-#include <openssl/lhash.h>
 #include <openssl/obj.h>
 #include <openssl/pkcs7.h>
 #include <openssl/pool.h>
@@ -4976,11 +4975,7 @@
                                                     const char *value);
 
 // X509V3_EXT_conf_nid calls |X509V3_EXT_nconf_nid|. |conf| must be NULL.
-//
-// TODO(davidben): This is the only exposed instance of an LHASH in our public
-// headers. cryptography.io wraps this function so we cannot, yet, replace the
-// type with a dummy struct.
-OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(CRYPTO_MUST_BE_NULL *conf,
                                                    const X509V3_CTX *ctx,
                                                    int ext_nid,
                                                    const char *value);
diff --git a/ssl/internal.h b/ssl/internal.h
index ba6b444..4e87f47 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -36,7 +36,6 @@
 #include <openssl/curve25519.h>
 #include <openssl/err.h>
 #include <openssl/hpke.h>
-#include <openssl/lhash.h>
 #include <openssl/mem.h>
 #include <openssl/span.h>
 #include <openssl/ssl.h>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 1b8ab54..69f3fe2 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -26,7 +26,6 @@
 #include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
-#include <openssl/lhash.h>
 #include <openssl/mem.h>
 #include <openssl/rand.h>
 
diff --git a/ssl/ssl_session.cc b/ssl/ssl_session.cc
index 52c2807..87d263b 100644
--- a/ssl/ssl_session.cc
+++ b/ssl/ssl_session.cc
@@ -23,7 +23,6 @@
 
 #include <openssl/err.h>
 #include <openssl/hmac.h>
-#include <openssl/lhash.h>
 #include <openssl/mem.h>
 #include <openssl/rand.h>
 
diff --git a/util/doc.config b/util/doc.config
index afcdd8d..9637c98 100644
--- a/util/doc.config
+++ b/util/doc.config
@@ -10,7 +10,6 @@
       "include/openssl/err.h",
       "include/openssl/crypto.h",
       "include/openssl/ex_data.h",
-      "include/openssl/lhash.h",
       "include/openssl/mem.h",
       "include/openssl/obj.h",
       "include/openssl/pool.h",