Unexport the Kyber implementation

Kyber was the prestandard version of ML-KEM. Callers should be using
ML-KEM now. For now, keep the implementation behind an internal header
for libssl, but we expect to remove that soon too.

Update-Note: <openssl/experimental/kyber.h> is gone. Use
<openssl/mlkem.h> instead.

Bug: 438787615
Change-Id: I02919e5d627dcbe863e70e433c79e360a556d462
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81287
Reviewed-by: Lily Chen <chlily@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/build.json b/build.json
index 4c56391..5e7c0f2 100644
--- a/build.json
+++ b/build.json
@@ -449,7 +449,6 @@
             "include/openssl/evp.h",
             "include/openssl/evp_errors.h",
             "include/openssl/ex_data.h",
-            "include/openssl/experimental/kyber.h",
             "include/openssl/hkdf.h",
             "include/openssl/hmac.h",
             "include/openssl/hpke.h",
diff --git a/crypto/kyber/internal.h b/crypto/kyber/internal.h
index 59c80f7..89475a9 100644
--- a/crypto/kyber/internal.h
+++ b/crypto/kyber/internal.h
@@ -16,13 +16,122 @@
 #define OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H
 
 #include <openssl/base.h>
-#include <openssl/experimental/kyber.h>
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 
+// Kyber is the pre-standard version of ML-KEM. This was once exported as public
+// API, but is now internal and only used by libssl. It will be removed entirely
+// in the future.
+//
+// This implements the round-3 specification of Kyber, defined at
+// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf
+
+// KYBER_public_key contains a Kyber768 public key. The contents of this
+// object should never leave the address space since the format is unstable.
+struct KYBER_public_key {
+  union {
+    uint8_t bytes[512 * (3 + 9) + 32 + 32];
+    uint16_t alignment;
+  } opaque;
+};
+
+// KYBER_private_key contains a Kyber768 private key. The contents of this
+// object should never leave the address space since the format is unstable.
+struct KYBER_private_key {
+  union {
+    uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
+    uint16_t alignment;
+  } opaque;
+};
+
+// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public
+// key.
+#define KYBER_PUBLIC_KEY_BYTES 1184
+
+// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared
+// secret. Although the round-3 specification has a variable-length output, the
+// final ML-KEM construction is expected to use a fixed 32-byte output. To
+// simplify the future transition, we apply the same restriction.
+#define KYBER_SHARED_SECRET_BYTES 32
+
+// KYBER_generate_key generates a random public/private key pair, writes the
+// encoded public key to |out_encoded_public_key| and sets |out_private_key| to
+// the private key.
+OPENSSL_EXPORT void KYBER_generate_key(
+    uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES],
+    struct KYBER_private_key *out_private_key);
+
+// KYBER_public_from_private sets |*out_public_key| to the public key that
+// corresponds to |private_key|. (This is faster than parsing the output of
+// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key
+// that was just generated.)
+OPENSSL_EXPORT void KYBER_public_from_private(
+    struct KYBER_public_key *out_public_key,
+    const struct KYBER_private_key *private_key);
+
+// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext.
+#define KYBER_CIPHERTEXT_BYTES 1088
+
+// KYBER_encap encrypts a random shared secret for |public_key|, writes the
+// ciphertext to |out_ciphertext|, and writes the random shared secret to
+// |out_shared_secret|.
+OPENSSL_EXPORT void KYBER_encap(
+    uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES],
+    uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
+    const struct KYBER_public_key *public_key);
+
+// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key|
+// and writes it to |out_shared_secret|. If |ciphertext| is invalid,
+// |out_shared_secret| is filled with a key that will always be the same for the
+// same |ciphertext| and |private_key|, but which appears to be random unless
+// one has access to |private_key|. These alternatives occur in constant time.
+// Any subsequent symmetric encryption using |out_shared_secret| must use an
+// authenticated encryption scheme in order to discover the decapsulation
+// failure.
+OPENSSL_EXPORT void KYBER_decap(
+    uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
+    const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES],
+    const struct KYBER_private_key *private_key);
+
+
+// Serialisation of keys.
+
+// KYBER_marshal_public_key serializes |public_key| to |out| in the standard
+// format for Kyber public keys. It returns one on success or zero on allocation
+// error.
+OPENSSL_EXPORT int KYBER_marshal_public_key(
+    CBB *out, const struct KYBER_public_key *public_key);
+
+// KYBER_parse_public_key parses a public key, in the format generated by
+// |KYBER_marshal_public_key|, from |in| and writes the result to
+// |out_public_key|. It returns one on success or zero on parse error or if
+// there are trailing bytes in |in|.
+OPENSSL_EXPORT int KYBER_parse_public_key(
+    struct KYBER_public_key *out_public_key, CBS *in);
+
+// KYBER_marshal_private_key serializes |private_key| to |out| in the standard
+// format for Kyber private keys. It returns one on success or zero on
+// allocation error.
+OPENSSL_EXPORT int KYBER_marshal_private_key(
+    CBB *out, const struct KYBER_private_key *private_key);
+
+// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by
+// |KYBER_marshal_private_key|.
+#define KYBER_PRIVATE_KEY_BYTES 2400
+
+// KYBER_parse_private_key parses a private key, in the format generated by
+// |KYBER_marshal_private_key|, from |in| and writes the result to
+// |out_private_key|. It returns one on success or zero on parse error or if
+// there are trailing bytes in |in|.
+OPENSSL_EXPORT int KYBER_parse_private_key(
+    struct KYBER_private_key *out_private_key, CBS *in);
+
+
+// Internal symbols.
+
 // KYBER_ENCAP_ENTROPY is the number of bytes of uniformly random entropy
 // necessary to encapsulate a secret. The entropy will be leaked to the
 // decapsulating party.
diff --git a/crypto/kyber/kyber.cc b/crypto/kyber/kyber.cc
index 15eb65f..bc67ae1 100644
--- a/crypto/kyber/kyber.cc
+++ b/crypto/kyber/kyber.cc
@@ -12,9 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-#include <openssl/experimental/kyber.h>
-
 #include <assert.h>
 #include <stdlib.h>
 
diff --git a/crypto/kyber/kyber_test.cc b/crypto/kyber/kyber_test.cc
index e5a772e..35f2d7a 100644
--- a/crypto/kyber/kyber_test.cc
+++ b/crypto/kyber/kyber_test.cc
@@ -20,8 +20,6 @@
 
 #include <openssl/bytestring.h>
 #include <openssl/ctrdrbg.h>
-#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-#include <openssl/experimental/kyber.h>
 
 #include "../fipsmodule/keccak/internal.h"
 #include "../test/file_test.h"
diff --git a/gen/sources.bzl b/gen/sources.bzl
index ef789da..5d9520c 100644
--- a/gen/sources.bzl
+++ b/gen/sources.bzl
@@ -550,7 +550,6 @@
     "include/openssl/evp.h",
     "include/openssl/evp_errors.h",
     "include/openssl/ex_data.h",
-    "include/openssl/experimental/kyber.h",
     "include/openssl/hkdf.h",
     "include/openssl/hmac.h",
     "include/openssl/hpke.h",
diff --git a/gen/sources.cmake b/gen/sources.cmake
index ec1f827..00ac47e 100644
--- a/gen/sources.cmake
+++ b/gen/sources.cmake
@@ -566,7 +566,6 @@
   include/openssl/evp.h
   include/openssl/evp_errors.h
   include/openssl/ex_data.h
-  include/openssl/experimental/kyber.h
   include/openssl/hkdf.h
   include/openssl/hmac.h
   include/openssl/hpke.h
diff --git a/gen/sources.gni b/gen/sources.gni
index 9f4404d..3c5c6a4 100644
--- a/gen/sources.gni
+++ b/gen/sources.gni
@@ -550,7 +550,6 @@
   "include/openssl/evp.h",
   "include/openssl/evp_errors.h",
   "include/openssl/ex_data.h",
-  "include/openssl/experimental/kyber.h",
   "include/openssl/hkdf.h",
   "include/openssl/hmac.h",
   "include/openssl/hpke.h",
diff --git a/gen/sources.json b/gen/sources.json
index d074bcb..5d74df8 100644
--- a/gen/sources.json
+++ b/gen/sources.json
@@ -533,7 +533,6 @@
       "include/openssl/evp.h",
       "include/openssl/evp_errors.h",
       "include/openssl/ex_data.h",
-      "include/openssl/experimental/kyber.h",
       "include/openssl/hkdf.h",
       "include/openssl/hmac.h",
       "include/openssl/hpke.h",
diff --git a/gen/sources.mk b/gen/sources.mk
index baa2d06..85683b0 100644
--- a/gen/sources.mk
+++ b/gen/sources.mk
@@ -543,7 +543,6 @@
   include/openssl/evp.h \
   include/openssl/evp_errors.h \
   include/openssl/ex_data.h \
-  include/openssl/experimental/kyber.h \
   include/openssl/hkdf.h \
   include/openssl/hmac.h \
   include/openssl/hpke.h \
diff --git a/include/openssl/experimental/kyber.h b/include/openssl/experimental/kyber.h
deleted file mode 100644
index 14ff973..0000000
--- a/include/openssl/experimental/kyber.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2023 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.
-// You may obtain a copy of the License at
-//
-//     https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef OPENSSL_HEADER_KYBER_H
-#define OPENSSL_HEADER_KYBER_H
-
-#include <openssl/base.h>   // IWYU pragma: export
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-#if defined(OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER)
-// This header implements experimental, draft versions of not-yet-standardized
-// primitives. When the standard is complete, these functions will be removed
-// and replaced with the final, incompatible standard version. They are
-// available now for short-lived experiments, but must not be deployed anywhere
-// durable, such as a long-lived key store. To use these functions define
-// OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-
-// Kyber768.
-//
-// This implements the round-3 specification of Kyber, defined at
-// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf
-
-
-// KYBER_public_key contains a Kyber768 public key. The contents of this
-// object should never leave the address space since the format is unstable.
-struct KYBER_public_key {
-  union {
-    uint8_t bytes[512 * (3 + 9) + 32 + 32];
-    uint16_t alignment;
-  } opaque;
-};
-
-// KYBER_private_key contains a Kyber768 private key. The contents of this
-// object should never leave the address space since the format is unstable.
-struct KYBER_private_key {
-  union {
-    uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
-    uint16_t alignment;
-  } opaque;
-};
-
-// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public
-// key.
-#define KYBER_PUBLIC_KEY_BYTES 1184
-
-// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared
-// secret. Although the round-3 specification has a variable-length output, the
-// final ML-KEM construction is expected to use a fixed 32-byte output. To
-// simplify the future transition, we apply the same restriction.
-#define KYBER_SHARED_SECRET_BYTES 32
-
-// KYBER_generate_key generates a random public/private key pair, writes the
-// encoded public key to |out_encoded_public_key| and sets |out_private_key| to
-// the private key.
-OPENSSL_EXPORT void KYBER_generate_key(
-    uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES],
-    struct KYBER_private_key *out_private_key);
-
-// KYBER_public_from_private sets |*out_public_key| to the public key that
-// corresponds to |private_key|. (This is faster than parsing the output of
-// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key
-// that was just generated.)
-OPENSSL_EXPORT void KYBER_public_from_private(
-    struct KYBER_public_key *out_public_key,
-    const struct KYBER_private_key *private_key);
-
-// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext.
-#define KYBER_CIPHERTEXT_BYTES 1088
-
-// KYBER_encap encrypts a random shared secret for |public_key|, writes the
-// ciphertext to |out_ciphertext|, and writes the random shared secret to
-// |out_shared_secret|.
-OPENSSL_EXPORT void KYBER_encap(
-    uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES],
-    uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
-    const struct KYBER_public_key *public_key);
-
-// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key|
-// and writes it to |out_shared_secret|. If |ciphertext| is invalid,
-// |out_shared_secret| is filled with a key that will always be the same for the
-// same |ciphertext| and |private_key|, but which appears to be random unless
-// one has access to |private_key|. These alternatives occur in constant time.
-// Any subsequent symmetric encryption using |out_shared_secret| must use an
-// authenticated encryption scheme in order to discover the decapsulation
-// failure.
-OPENSSL_EXPORT void KYBER_decap(
-    uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
-    const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES],
-    const struct KYBER_private_key *private_key);
-
-
-// Serialisation of keys.
-
-// KYBER_marshal_public_key serializes |public_key| to |out| in the standard
-// format for Kyber public keys. It returns one on success or zero on allocation
-// error.
-OPENSSL_EXPORT int KYBER_marshal_public_key(
-    CBB *out, const struct KYBER_public_key *public_key);
-
-// KYBER_parse_public_key parses a public key, in the format generated by
-// |KYBER_marshal_public_key|, from |in| and writes the result to
-// |out_public_key|. It returns one on success or zero on parse error or if
-// there are trailing bytes in |in|.
-OPENSSL_EXPORT int KYBER_parse_public_key(
-    struct KYBER_public_key *out_public_key, CBS *in);
-
-// KYBER_marshal_private_key serializes |private_key| to |out| in the standard
-// format for Kyber private keys. It returns one on success or zero on
-// allocation error.
-OPENSSL_EXPORT int KYBER_marshal_private_key(
-    CBB *out, const struct KYBER_private_key *private_key);
-
-// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by
-// |KYBER_marshal_private_key|.
-#define KYBER_PRIVATE_KEY_BYTES 2400
-
-// KYBER_parse_private_key parses a private key, in the format generated by
-// |KYBER_marshal_private_key|, from |in| and writes the result to
-// |out_private_key|. It returns one on success or zero on parse error or if
-// there are trailing bytes in |in|.
-OPENSSL_EXPORT int KYBER_parse_private_key(
-    struct KYBER_private_key *out_private_key, CBS *in);
-
-#endif // OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-
-
-#if defined(__cplusplus)
-}  // extern C
-#endif
-
-#endif  // OPENSSL_HEADER_KYBER_H
diff --git a/ssl/ssl_key_share.cc b/ssl/ssl_key_share.cc
index c2c01e6..411a6ab 100644
--- a/ssl/ssl_key_share.cc
+++ b/ssl/ssl_key_share.cc
@@ -24,8 +24,6 @@
 #include <openssl/curve25519.h>
 #include <openssl/ec.h>
 #include <openssl/err.h>
-#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-#include <openssl/experimental/kyber.h>
 #include <openssl/hrss.h>
 #include <openssl/mem.h>
 #include <openssl/mlkem.h>
@@ -34,6 +32,7 @@
 #include <openssl/span.h>
 
 #include "../crypto/internal.h"
+#include "../crypto/kyber/internal.h"
 #include "internal.h"
 
 BSSL_NAMESPACE_BEGIN
diff --git a/tool/speed.cc b/tool/speed.cc
index b9bca8e..a6e75e0 100644
--- a/tool/speed.cc
+++ b/tool/speed.cc
@@ -38,8 +38,6 @@
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
-#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER
-#include <openssl/experimental/kyber.h>
 #include <openssl/hrss.h>
 #include <openssl/mem.h>
 #include <openssl/mldsa.h>
@@ -1079,55 +1077,6 @@
   return true;
 }
 
-static bool SpeedKyber(const std::string &selected) {
-  if (!selected.empty() && selected != "Kyber") {
-    return true;
-  }
-
-  TimeResults results;
-
-  uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
-  // This ciphertext is nonsense, but Kyber decap is constant-time so, for the
-  // purposes of timing, it's fine.
-  memset(ciphertext, 42, sizeof(ciphertext));
-  if (!TimeFunctionParallel(&results, [&]() -> bool {
-        KYBER_private_key priv;
-        uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
-        KYBER_generate_key(encoded_public_key, &priv);
-        uint8_t shared_secret[KYBER_SHARED_SECRET_BYTES];
-        KYBER_decap(shared_secret, ciphertext, &priv);
-        return true;
-      })) {
-    fprintf(stderr, "Failed to time KYBER_generate_key + KYBER_decap.\n");
-    return false;
-  }
-
-  results.Print("Kyber generate + decap");
-
-  KYBER_private_key priv;
-  uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
-  KYBER_generate_key(encoded_public_key, &priv);
-  KYBER_public_key pub;
-  if (!TimeFunctionParallel(&results, [&]() -> bool {
-        CBS encoded_public_key_cbs;
-        CBS_init(&encoded_public_key_cbs, encoded_public_key,
-                 sizeof(encoded_public_key));
-        if (!KYBER_parse_public_key(&pub, &encoded_public_key_cbs)) {
-          return false;
-        }
-        uint8_t shared_secret[KYBER_SHARED_SECRET_BYTES];
-        KYBER_encap(ciphertext, shared_secret, &pub);
-        return true;
-      })) {
-    fprintf(stderr, "Failed to time KYBER_encap.\n");
-    return false;
-  }
-
-  results.Print("Kyber parse + encap");
-
-  return true;
-}
-
 static bool SpeedMLDSA(const std::string &selected) {
   if (!selected.empty() && selected != "ML-DSA") {
     return true;
@@ -1857,7 +1806,6 @@
       !SpeedScrypt(selected) ||       //
       !SpeedRSAKeyGen(selected) ||    //
       !SpeedHRSS(selected) ||         //
-      !SpeedKyber(selected) ||        //
       !SpeedMLDSA(selected) ||        //
       !SpeedMLKEM(selected) ||        //
       !SpeedMLKEM1024(selected) ||    //
diff --git a/util/doc.config b/util/doc.config
index 9637c98..4903ee1 100644
--- a/util/doc.config
+++ b/util/doc.config
@@ -61,11 +61,6 @@
       "include/openssl/x509.h"
     ]
   },{
-    "Name": "Experimental primitives. Will be removed and replaced when standardized!",
-    "Headers": [
-      "include/openssl/experimental/kyber.h"
-    ]
-  },{
     "Name": "SSL implementation",
     "Headers": [
       "include/openssl/ssl.h"