Add new EVP_KEM API This adds a new EVP_KEM type which provides a more ergonomic API for KEM encapsulate and decapsulate operations, and implements them for ML-KEM-768 and 1024. Bug: 449751916 Change-Id: Ie9b3a68a6e9e835a5055810cd23401716a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/91267 Commit-Queue: Lily Chen <chlily@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/build.json b/build.json index f909e33..88d962c 100644 --- a/build.json +++ b/build.json
@@ -259,6 +259,7 @@ "crypto/evp/evp.cc", "crypto/evp/evp_asn1.cc", "crypto/evp/evp_ctx.cc", + "crypto/evp/evp_kem.cc", "crypto/evp/p_dh.cc", "crypto/evp/p_dsa.cc", "crypto/evp/p_ec.cc",
diff --git a/crypto/err/evp.errordata b/crypto/err/evp.errordata index daf989a..b929efa 100644 --- a/crypto/err/evp.errordata +++ b/crypto/err/evp.errordata
@@ -11,6 +11,7 @@ EVP,106,EXPECTING_A_EC_KEY EVP,109,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE EVP,137,INVALID_BUFFER_SIZE +EVP,141,INVALID_CIPHERTEXT_LENGTH EVP,110,INVALID_DIGEST_LENGTH EVP,111,INVALID_DIGEST_TYPE EVP,112,INVALID_KEYBITS @@ -20,6 +21,7 @@ EVP,133,INVALID_PARAMETERS EVP,134,INVALID_PEER_KEY EVP,116,INVALID_PSS_SALTLEN +EVP,142,INVALID_SECRET_LENGTH EVP,131,INVALID_SIGNATURE EVP,117,KEYS_NOT_SET EVP,132,MEMORY_LIMIT_EXCEEDED
diff --git a/crypto/evp/evp_kem.cc b/crypto/evp/evp_kem.cc new file mode 100644 index 0000000..a74ec8d --- /dev/null +++ b/crypto/evp/evp_kem.cc
@@ -0,0 +1,78 @@ +// Copyright 2026 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. + +#include <openssl/evp.h> + +#include <openssl/err.h> + +#include "internal.h" + +using namespace bssl; + +// Checks whether KEM function invocation is valid. +// `ciphertext_len` may be nullptr if it is not required to match. +// `secret_len` must always match. +static bool check_kem_invocation(const EVP_KEM *kem, + const size_t *ciphertext_len, + size_t secret_len, + const bssl::EvpPkey *pkey_impl) { + if (pkey_impl == nullptr || pkey_impl->pkey == nullptr || + pkey_impl->ameth == nullptr) { + OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); + return false; + } + if (kem->pkey_id != EVP_PKEY_id(pkey_impl)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return false; + } + if (ciphertext_len && *ciphertext_len != kem->ciphertext_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CIPHERTEXT_LENGTH); + return false; + } + if (secret_len != kem->secret_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SECRET_LENGTH); + return false; + } + return true; +} + +size_t EVP_KEM_ciphertext_len(const EVP_KEM *kem) { + return kem->ciphertext_len; +} + +size_t EVP_KEM_secret_len(const EVP_KEM *kem) { + return kem->secret_len; +} + +int EVP_KEM_encap(const EVP_KEM *kem, uint8_t *out_ciphertext, + size_t ciphertext_len, uint8_t *out_secret, size_t secret_len, + const EVP_PKEY *peer_key) { + auto *pkey_impl = FromOpaque(peer_key); + if (!check_kem_invocation(kem, &ciphertext_len, secret_len, pkey_impl)) { + return 0; + } + return kem->encap(out_ciphertext, ciphertext_len, out_secret, secret_len, + pkey_impl); +} + +int EVP_KEM_decap(const EVP_KEM *kem, uint8_t *out_secret, size_t secret_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const EVP_PKEY *key) { + auto *pkey_impl = FromOpaque(key); + if (!check_kem_invocation(kem, nullptr, secret_len, pkey_impl)) { + return 0; + } + return kem->decap(out_secret, secret_len, ciphertext, ciphertext_len, + pkey_impl); +}
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc index 7fa1d95..7c4546a 100644 --- a/crypto/evp/evp_test.cc +++ b/crypto/evp/evp_test.cc
@@ -90,27 +90,46 @@ struct AlgorithmInfo { const EVP_PKEY_ALG *alg; + const EVP_KEM *kem; int pkey_id; bool is_default; }; const std::map<std::string, AlgorithmInfo> kAllAlgorithms = { - {"RSA", {EVP_pkey_rsa(), EVP_PKEY_RSA, true}}, - {"RSA-PSS-SHA-256", {EVP_pkey_rsa_pss_sha256(), EVP_PKEY_RSA_PSS, false}}, - {"RSA-PSS-SHA-384", {EVP_pkey_rsa_pss_sha384(), EVP_PKEY_RSA_PSS, false}}, - {"RSA-PSS-SHA-512", {EVP_pkey_rsa_pss_sha512(), EVP_PKEY_RSA_PSS, false}}, - {"EC-P-224", {EVP_pkey_ec_p224(), EVP_PKEY_EC, true}}, - {"EC-P-256", {EVP_pkey_ec_p256(), EVP_PKEY_EC, true}}, - {"EC-P-384", {EVP_pkey_ec_p384(), EVP_PKEY_EC, true}}, - {"EC-P-521", {EVP_pkey_ec_p521(), EVP_PKEY_EC, true}}, - {"X25519", {EVP_pkey_x25519(), EVP_PKEY_X25519, true}}, - {"Ed25519", {EVP_pkey_ed25519(), EVP_PKEY_ED25519, true}}, - {"DSA", {EVP_pkey_dsa(), EVP_PKEY_DSA, true}}, - {"ML-DSA-44", {EVP_pkey_ml_dsa_44(), EVP_PKEY_ML_DSA_44, true}}, - {"ML-DSA-65", {EVP_pkey_ml_dsa_65(), EVP_PKEY_ML_DSA_65, true}}, - {"ML-DSA-87", {EVP_pkey_ml_dsa_87(), EVP_PKEY_ML_DSA_87, true}}, - {"ML-KEM-768", {EVP_pkey_ml_kem_768(), EVP_PKEY_ML_KEM_768, false}}, - {"ML-KEM-1024", {EVP_pkey_ml_kem_1024(), EVP_PKEY_ML_KEM_1024, false}}, + {"RSA", + {EVP_pkey_rsa(), + /*kem=*/nullptr, EVP_PKEY_RSA, true}}, + + {"RSA-PSS-SHA-256", + {EVP_pkey_rsa_pss_sha256(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}}, + {"RSA-PSS-SHA-384", + {EVP_pkey_rsa_pss_sha384(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}}, + {"RSA-PSS-SHA-512", + {EVP_pkey_rsa_pss_sha512(), /*kem=*/nullptr, EVP_PKEY_RSA_PSS, false}}, + + {"EC-P-224", {EVP_pkey_ec_p224(), /*kem=*/nullptr, EVP_PKEY_EC, true}}, + {"EC-P-256", {EVP_pkey_ec_p256(), /*kem=*/nullptr, EVP_PKEY_EC, true}}, + {"EC-P-384", {EVP_pkey_ec_p384(), /*kem=*/nullptr, EVP_PKEY_EC, true}}, + {"EC-P-521", {EVP_pkey_ec_p521(), /*kem=*/nullptr, EVP_PKEY_EC, true}}, + + {"X25519", {EVP_pkey_x25519(), /*kem=*/nullptr, EVP_PKEY_X25519, true}}, + + {"Ed25519", {EVP_pkey_ed25519(), /*kem=*/nullptr, EVP_PKEY_ED25519, true}}, + + {"DSA", {EVP_pkey_dsa(), /*kem=*/nullptr, EVP_PKEY_DSA, true}}, + + {"ML-DSA-44", + {EVP_pkey_ml_dsa_44(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_44, true}}, + {"ML-DSA-65", + {EVP_pkey_ml_dsa_65(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_65, true}}, + {"ML-DSA-87", + {EVP_pkey_ml_dsa_87(), /*kem=*/nullptr, EVP_PKEY_ML_DSA_87, true}}, + + {"ML-KEM-768", + {EVP_pkey_ml_kem_768(), EVP_kem_ml_kem_768(), EVP_PKEY_ML_KEM_768, false}}, + {"ML-KEM-1024", + {EVP_pkey_ml_kem_1024(), EVP_kem_ml_kem_1024(), EVP_PKEY_ML_KEM_1024, + false}}, }; using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>; @@ -704,7 +723,7 @@ return false; } const AlgorithmInfo &alg_info = it->second; - if (alg_info.alg == nullptr) { + if (alg_info.alg == nullptr || alg_info.kem == nullptr) { ADD_FAILURE() << "Method not defined: " << alg_name; return false; } @@ -834,6 +853,78 @@ ctx.get(), decapsulated_secret.data(), &secret_size, ciphertext.data(), ciphertext.size())); } + + // Repeat everything the EVP_KEM way, which is simpler. + reset_test_state(); + + EXPECT_EQ(EVP_KEM_ciphertext_len(alg_info.kem), expected_ciphertext_len); + EXPECT_EQ(EVP_KEM_secret_len(alg_info.kem), expected_secret_len); + + if (encapsulate) { + ciphertext.resize(ciphertext_size); + + // Passing the wrong sizes fails (even if larger than required). + resize_output_buffers(expected_ciphertext_len - 1, expected_secret_len); + EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(), + secret.data(), secret.size(), pkey), + 0); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_EVP, + EVP_R_INVALID_CIPHERTEXT_LENGTH)); + ERR_clear_error(); + resize_output_buffers(expected_ciphertext_len + 1, expected_secret_len); + EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(), + secret.data(), secret.size(), pkey), + 0); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_EVP, + EVP_R_INVALID_CIPHERTEXT_LENGTH)); + ERR_clear_error(); + resize_output_buffers(expected_ciphertext_len, expected_secret_len - 1); + EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(), + secret.data(), secret.size(), pkey), + 0); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH)); + ERR_clear_error(); + resize_output_buffers(expected_ciphertext_len, expected_secret_len + 1); + EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(), + secret.data(), secret.size(), pkey), + 0); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH)); + ERR_clear_error(); + + // Only the correct sizes are accepted. + resize_output_buffers(expected_ciphertext_len, expected_secret_len); + EXPECT_EQ(EVP_KEM_encap(alg_info.kem, ciphertext.data(), ciphertext.size(), + secret.data(), secret.size(), pkey), + 1); + } + + if (decapsulate) { + // Passing the wrong sizes fails (even if larger than required). + resize_output_buffers(std::nullopt, expected_secret_len - 1, true); + EXPECT_EQ(EVP_KEM_decap(alg_info.kem, decapsulated_secret.data(), + decapsulated_secret.size(), ciphertext.data(), + ciphertext.size(), pkey), + 0); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH)); + ERR_clear_error(); + resize_output_buffers(std::nullopt, expected_secret_len + 1, true); + EXPECT_EQ(EVP_KEM_decap(alg_info.kem, decapsulated_secret.data(), + decapsulated_secret.size(), ciphertext.data(), + ciphertext.size(), pkey), + 0); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH)); + ERR_clear_error(); + + resize_output_buffers(std::nullopt, expected_secret_len, true); + check_decapsulate_result(EVP_KEM_decap( + alg_info.kem, decapsulated_secret.data(), decapsulated_secret.size(), + ciphertext.data(), ciphertext.size(), pkey)); + } + return true; }
diff --git a/crypto/evp/internal.h b/crypto/evp/internal.h index d634585..4e451a2 100644 --- a/crypto/evp/internal.h +++ b/crypto/evp/internal.h
@@ -294,6 +294,27 @@ int (*ctrl)(EvpPkeyCtx *ctx, int type, int p1, void *p2); } /* EVP_PKEY_CTX_METHOD */; +BSSL_NAMESPACE_END + +// TODO(chlily): Make compatible with `EVP_HPKE_KEM`. +struct evp_kem_st { + // Identifies the type of EVP_PKEYs compatible with this KEM. + int pkey_id; + + // Constant lengths of ciphertexts and secrets produced/consumed by this KEM. + size_t ciphertext_len; + size_t secret_len; + + int (*encap)(uint8_t *out_ciphertext, size_t ciphertext_len, + uint8_t *out_secret, size_t secret_len, + const EVP_PKEY *peer_key); + int (*decap)(uint8_t *out_secret, size_t secret_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const EVP_PKEY *key); +} /* EVP_KEM */; + +BSSL_NAMESPACE_BEGIN + // evp_pkey_ec_no_curve returns an internal curveless EC |EVP_PKEY_ALG|. This // cannot be used to parse anything and is only useful for key generation. const EVP_PKEY_ALG *evp_pkey_ec_no_curve();
diff --git a/crypto/evp/p_mlkem.cc b/crypto/evp/p_mlkem.cc index 34b4b7b..eefb7e0 100644 --- a/crypto/evp/p_mlkem.cc +++ b/crypto/evp/p_mlkem.cc
@@ -350,6 +350,22 @@ return 1; } + static int KemEncap(uint8_t *out_ciphertext, size_t ciphertext_len, + uint8_t *out_secret, size_t secret_len, + const EVP_PKEY *peer_key) { + const auto *peer_pubkey = GetKeyData(FromOpaque(peer_key))->GetPublicKey(); + if (ciphertext_len != Traits::kCiphertextBytes) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CIPHERTEXT_LENGTH); + return 0; + } + if (secret_len != MLKEM_SHARED_SECRET_BYTES) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SECRET_LENGTH); + return 0; + } + Traits::Encap(out_ciphertext, out_secret, peer_pubkey); + return 1; + } + static int EncapCtx(EvpPkeyCtx *ctx, uint8_t *out_ciphertext, size_t *out_ciphertext_len, uint8_t *out_secret, size_t *out_secret_len) { @@ -375,6 +391,21 @@ return 1; } + static int KemDecap(uint8_t *out_secret, size_t secret_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const EVP_PKEY *key) { + const auto *priv = GetKeyData(FromOpaque(key))->AsPrivateKeyData(); + if (priv == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + if (secret_len != MLKEM_SHARED_SECRET_BYTES) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SECRET_LENGTH); + return 0; + } + return Traits::Decap(out_secret, ciphertext, ciphertext_len, &priv->priv); + } + static int DecapCtx(EvpPkeyCtx *ctx, uint8_t *out_secret, size_t *out_secret_len, const uint8_t *ciphertext, size_t ciphertext_len) { @@ -469,6 +500,14 @@ return ret; } + static constexpr EVP_KEM evp_kem = { + /*pkey_id=*/Traits::kType, + /*ciphertext_len=*/Traits::kCiphertextBytes, + /*secret_len=*/MLKEM_SHARED_SECRET_BYTES, + &KemEncap, + &KemDecap, + }; + static constexpr EVP_PKEY_ASN1_METHOD asn1_method = BuildASN1Method(); static constexpr EVP_PKEY_ALG pkey_alg = {&asn1_method, &pkey_method}; }; @@ -482,3 +521,11 @@ const EVP_PKEY_ALG *EVP_pkey_ml_kem_1024() { return &MLKEMImplementation<MLKEM1024Traits>::pkey_alg; } + +const EVP_KEM *EVP_kem_ml_kem_768() { + return &MLKEMImplementation<MLKEM768Traits>::evp_kem; +} + +const EVP_KEM *EVP_kem_ml_kem_1024() { + return &MLKEMImplementation<MLKEM1024Traits>::evp_kem; +}
diff --git a/gen/crypto/err_data.cc b/gen/crypto/err_data.cc index 567616e..846ca1f 100644 --- a/gen/crypto/err_data.cc +++ b/gen/crypto/err_data.cc
@@ -80,54 +80,54 @@ 0xc3b00f7, 0xc3b8921, 0x10320892, - 0x103296da, - 0x103316e6, - 0x103396ff, - 0x10341712, + 0x1032970a, + 0x10331716, + 0x1033972f, + 0x10341742, 0x10348fd3, 0x10350d1f, - 0x10359725, - 0x1036174f, - 0x10369762, - 0x10371781, - 0x1037979a, - 0x103817af, - 0x103897cd, - 0x103917dc, - 0x103997f8, - 0x103a1813, - 0x103a9822, - 0x103b183e, - 0x103b9859, - 0x103c187f, + 0x10359755, + 0x1036177f, + 0x10369792, + 0x103717b1, + 0x103797ca, + 0x103817df, + 0x103897fd, + 0x1039180c, + 0x10399828, + 0x103a1843, + 0x103a9852, + 0x103b186e, + 0x103b9889, + 0x103c18af, 0x103c80f7, - 0x103d1890, - 0x103d98a4, - 0x103e18c3, - 0x103e98d2, - 0x103f18e9, - 0x103f98fc, + 0x103d18c0, + 0x103d98d4, + 0x103e18f3, + 0x103e9902, + 0x103f1919, + 0x103f992c, 0x10400ce3, - 0x1040990f, - 0x1041192d, - 0x10419940, - 0x1042195a, - 0x1042996a, - 0x1043197e, - 0x10439994, - 0x104419ac, - 0x104499c1, - 0x104519d5, - 0x104599e7, + 0x1040993f, + 0x1041195d, + 0x10419970, + 0x1042198a, + 0x1042999a, + 0x104319ae, + 0x104399c4, + 0x104419dc, + 0x104499f1, + 0x10451a05, + 0x10459a17, 0x10460635, 0x1046899a, - 0x104719fc, - 0x10479a13, - 0x10481a28, - 0x10489a36, + 0x10471a2c, + 0x10479a43, + 0x10481a58, + 0x10489a66, 0x10490f1f, - 0x10499870, - 0x104a173a, + 0x104998a0, + 0x104a176a, 0x14320cb3, 0x14328cd4, 0x14330ce3, @@ -145,55 +145,57 @@ 0x18359072, 0x1836109a, 0x183690c1, - 0x183710f9, - 0x1837910f, - 0x18381123, - 0x18389133, + 0x18371113, + 0x18379129, + 0x1838113d, + 0x1838914d, 0x18390ac0, - 0x18399143, - 0x183a1169, - 0x183a918f, + 0x1839915d, + 0x183a1183, + 0x183a91bf, 0x183b0d2b, - 0x183b91f1, - 0x183c1203, - 0x183c920e, - 0x183d121e, - 0x183d922f, - 0x183e1240, - 0x183e926c, - 0x183f1252, - 0x183f92ae, - 0x184012c6, + 0x183b9221, + 0x183c1233, + 0x183c923e, + 0x183d124e, + 0x183d925f, + 0x183e1270, + 0x183e929c, + 0x183f1282, + 0x183f92de, + 0x184012f6, 0x1840870d, - 0x184111c5, - 0x1841917d, - 0x1842119c, + 0x184111f5, + 0x184191ad, + 0x184211cc, 0x18428cc1, - 0x18431158, - 0x184391d7, + 0x18431172, + 0x18439207, 0x18441068, 0x184490e5, 0x18451087, - 0x18459295, - 0x184611b2, - 0x20321300, - 0x203292ed, - 0x2432130c, + 0x184592c5, + 0x184611e2, + 0x184690f9, + 0x18471197, + 0x20321330, + 0x2032931d, + 0x2432133c, 0x243289e0, - 0x2433131e, - 0x2433932b, - 0x24341338, - 0x2434934a, - 0x24351359, - 0x24359376, - 0x24361383, - 0x24369391, - 0x2437139f, - 0x243793ad, - 0x243813b6, - 0x243893c3, - 0x243913d6, - 0x243993ed, + 0x2433134e, + 0x2433935b, + 0x24341368, + 0x2434937a, + 0x24351389, + 0x243593a6, + 0x243613b3, + 0x243693c1, + 0x243713cf, + 0x243793dd, + 0x243813e6, + 0x243893f3, + 0x24391406, + 0x2439941d, 0x28320d13, 0x28328d2b, 0x28330ce3, @@ -203,51 +205,51 @@ 0x283500f7, 0x28358cc1, 0x2836099a, - 0x2c323462, - 0x2c32940b, - 0x2c333470, - 0x2c33b482, - 0x2c343496, - 0x2c34b4a8, - 0x2c3534c3, - 0x2c35b4d5, - 0x2c363505, + 0x2c323492, + 0x2c32943b, + 0x2c3334a0, + 0x2c33b4b2, + 0x2c3434c6, + 0x2c34b4d8, + 0x2c3534f3, + 0x2c35b505, + 0x2c363535, 0x2c36833a, - 0x2c373512, - 0x2c37b53e, - 0x2c38357c, - 0x2c38b593, - 0x2c3935b1, - 0x2c39b5c1, - 0x2c3a35d3, - 0x2c3ab5e7, - 0x2c3b35f8, - 0x2c3bb617, - 0x2c3c141d, - 0x2c3c9433, - 0x2c3d365c, - 0x2c3d944c, - 0x2c3e3686, - 0x2c3eb694, - 0x2c3f36ac, - 0x2c3fb6c4, - 0x2c4036ee, - 0x2c409300, - 0x2c4136ff, - 0x2c41b712, - 0x2c4212c6, - 0x2c42b723, + 0x2c373542, + 0x2c37b56e, + 0x2c3835ac, + 0x2c38b5c3, + 0x2c3935e1, + 0x2c39b5f1, + 0x2c3a3603, + 0x2c3ab617, + 0x2c3b3628, + 0x2c3bb647, + 0x2c3c144d, + 0x2c3c9463, + 0x2c3d368c, + 0x2c3d947c, + 0x2c3e36b6, + 0x2c3eb6c4, + 0x2c3f36dc, + 0x2c3fb6f4, + 0x2c40371e, + 0x2c409330, + 0x2c41372f, + 0x2c41b742, + 0x2c4212f6, + 0x2c42b753, 0x2c43076d, - 0x2c43b609, - 0x2c443551, - 0x2c44b6d1, - 0x2c4534e8, - 0x2c45b524, - 0x2c4635a1, - 0x2c46b62b, - 0x2c473640, - 0x2c47b679, - 0x2c483563, + 0x2c43b639, + 0x2c443581, + 0x2c44b701, + 0x2c453518, + 0x2c45b554, + 0x2c4635d1, + 0x2c46b65b, + 0x2c473670, + 0x2c47b6a9, + 0x2c483593, 0x30320000, 0x30328015, 0x3033001f, @@ -387,271 +389,271 @@ 0x3c418e13, 0x3c420f1f, 0x3c428ea9, - 0x40321aa2, - 0x40329ab8, - 0x40331ae6, - 0x40339af0, - 0x40341b07, - 0x40349b25, - 0x40351b35, - 0x40359b47, - 0x40361b54, - 0x40369b60, - 0x40371b75, - 0x40379b87, - 0x40381b92, - 0x40389ba4, + 0x40321ad2, + 0x40329ae8, + 0x40331b16, + 0x40339b20, + 0x40341b37, + 0x40349b55, + 0x40351b65, + 0x40359b77, + 0x40361b84, + 0x40369b90, + 0x40371ba5, + 0x40379bb7, + 0x40381bc2, + 0x40389bd4, 0x40390fd3, - 0x40399bb4, - 0x403a1bc7, - 0x403a9be8, - 0x403b1bf9, - 0x403b9c09, + 0x40399be4, + 0x403a1bf7, + 0x403a9c18, + 0x403b1c29, + 0x403b9c39, 0x403c0071, 0x403c8090, - 0x403d1c6a, - 0x403d9c80, - 0x403e1c8f, - 0x403e9cc7, - 0x403f1ce1, - 0x403f9d09, - 0x40401d1e, - 0x40409d32, - 0x40411d6d, - 0x40419d88, - 0x40421da1, - 0x40429db4, - 0x40431dc8, - 0x40439df6, - 0x40441e0d, + 0x403d1c9a, + 0x403d9cb0, + 0x403e1cbf, + 0x403e9cf7, + 0x403f1d11, + 0x403f9d39, + 0x40401d4e, + 0x40409d62, + 0x40411d9d, + 0x40419db8, + 0x40421dd1, + 0x40429de4, + 0x40431df8, + 0x40439e26, + 0x40441e3d, 0x404480b9, - 0x40451e22, - 0x40459e34, - 0x40461e58, - 0x40469e78, - 0x40471e86, - 0x40479ead, - 0x40481f2e, - 0x40489fe8, - 0x40491fff, - 0x4049a019, - 0x404a2030, - 0x404aa04e, - 0x404b2066, - 0x404ba093, - 0x404c20a9, - 0x404ca0bb, - 0x404d20dc, - 0x404da115, - 0x404e2129, - 0x404ea136, - 0x404f2209, - 0x404fa27f, - 0x40502324, - 0x4050a338, - 0x40512385, - 0x40522395, - 0x4052a3b9, - 0x405323d1, - 0x4053a3e4, - 0x405423f9, - 0x4054a41c, - 0x40552447, - 0x4055a484, - 0x405624a9, - 0x4056a4c2, - 0x405724da, - 0x4057a4ed, - 0x40582502, - 0x4058a529, - 0x40592558, - 0x4059a598, - 0x405aa5ac, - 0x405b25c4, - 0x405ba5d5, - 0x405c25e8, - 0x405ca63d, - 0x405d264a, - 0x405da66f, - 0x405e26ad, + 0x40451e52, + 0x40459e64, + 0x40461e88, + 0x40469ea8, + 0x40471eb6, + 0x40479edd, + 0x40481f5e, + 0x4048a018, + 0x4049202f, + 0x4049a049, + 0x404a2060, + 0x404aa07e, + 0x404b2096, + 0x404ba0c3, + 0x404c20d9, + 0x404ca0eb, + 0x404d210c, + 0x404da145, + 0x404e2159, + 0x404ea166, + 0x404f2239, + 0x404fa2af, + 0x40502354, + 0x4050a368, + 0x405123b5, + 0x405223c5, + 0x4052a3e9, + 0x40532401, + 0x4053a414, + 0x40542429, + 0x4054a44c, + 0x40552477, + 0x4055a4b4, + 0x405624d9, + 0x4056a4f2, + 0x4057250a, + 0x4057a51d, + 0x40582532, + 0x4058a559, + 0x40592588, + 0x4059a5c8, + 0x405aa5dc, + 0x405b25f4, + 0x405ba605, + 0x405c2618, + 0x405ca66d, + 0x405d267a, + 0x405da69f, + 0x405e26dd, 0x405e8afe, - 0x405f26fc, - 0x405fa709, - 0x40602717, - 0x4060a739, - 0x406127ad, - 0x4061a7e5, - 0x406227fc, - 0x4062a80d, - 0x4063285a, - 0x4063a86f, - 0x40642886, - 0x4064a8b2, - 0x406528cd, - 0x4065a8e4, - 0x406628fc, - 0x4066a926, - 0x40672951, - 0x4067a996, - 0x406829de, - 0x4068a9ff, - 0x40692a31, - 0x4069aa5f, - 0x406a2a80, - 0x406aaaa0, - 0x406b2c28, - 0x406bac4b, - 0x406c2c61, - 0x406caf6b, - 0x406d2f9a, - 0x406dafc2, - 0x406e2ff0, - 0x406eb03d, - 0x406f3096, - 0x406fb0ce, - 0x407030e1, - 0x4070b0fe, + 0x405f272c, + 0x405fa739, + 0x40602747, + 0x4060a769, + 0x406127dd, + 0x4061a815, + 0x4062282c, + 0x4062a83d, + 0x4063288a, + 0x4063a89f, + 0x406428b6, + 0x4064a8e2, + 0x406528fd, + 0x4065a914, + 0x4066292c, + 0x4066a956, + 0x40672981, + 0x4067a9c6, + 0x40682a0e, + 0x4068aa2f, + 0x40692a61, + 0x4069aa8f, + 0x406a2ab0, + 0x406aaad0, + 0x406b2c58, + 0x406bac7b, + 0x406c2c91, + 0x406caf9b, + 0x406d2fca, + 0x406daff2, + 0x406e3020, + 0x406eb06d, + 0x406f30c6, + 0x406fb0fe, + 0x40703111, + 0x4070b12e, 0x4071084d, - 0x4071b110, - 0x40723123, - 0x4072b159, - 0x40733171, - 0x40739635, - 0x40743185, - 0x4074b19f, - 0x407531b0, - 0x4075b1c4, - 0x407631d2, - 0x407693c3, - 0x407731f7, - 0x4077b253, - 0x4078326e, - 0x4078b2a7, - 0x407932be, - 0x4079b2d4, - 0x407a3300, - 0x407ab313, - 0x407b3328, - 0x407bb33a, - 0x407c336b, - 0x407cb374, - 0x407d2a1a, - 0x407da2a7, - 0x407e3283, - 0x407ea539, - 0x407f1e9a, - 0x407fa07d, - 0x40802219, - 0x40809ec2, - 0x408123a7, - 0x4081a184, - 0x40822fdb, - 0x40829c15, - 0x40832514, - 0x4083a897, - 0x40841ee6, - 0x4084a571, - 0x408525f9, - 0x4085a774, - 0x4086268f, - 0x4086a2dc, - 0x40873021, - 0x4087a7c2, - 0x40881c53, - 0x4088a9a9, - 0x40891ca2, - 0x40899c2f, - 0x408a2c99, - 0x408a9a4d, - 0x408b334f, - 0x408bb0ab, - 0x408c261f, - 0x408d1fce, - 0x408d9f18, - 0x408e20fe, - 0x408ea464, - 0x408f29bd, - 0x408fa790, - 0x40902972, - 0x4090a661, - 0x40912c81, - 0x40919a85, - 0x40921cef, - 0x4092b05c, - 0x4093313c, - 0x4093a2ed, - 0x40941efa, - 0x4094acb2, - 0x4095281e, - 0x4095b2e0, - 0x40963008, - 0x4096a232, - 0x4097236d, - 0x4097a14d, - 0x40981d4f, - 0x4098a832, - 0x40993078, - 0x4099a491, - 0x409a242a, - 0x409a9a69, - 0x409b1f54, - 0x409b9f7f, - 0x409c3235, - 0x409c9fa7, - 0x409d21ee, - 0x409da19a, - 0x409e1de0, - 0x409ea267, - 0x409f224f, - 0x409f9f47, - 0x40a0228f, - 0x40a0a167, - 0x40a121b5, - 0x40a1a585, - 0x40a22309, - 0x40a2a6ed, - 0x40a32761, - 0x40a3b219, - 0x40a42353, - 0x40a4a1cc, - 0x40a51ed6, - 0x40a5a2c1, - 0x40a62609, - 0x41f42b53, - 0x41f92be5, - 0x41fe2ad8, - 0x41fead8e, - 0x41ff2ebc, - 0x42032b6c, - 0x42082b8e, - 0x4208abca, - 0x42092abc, - 0x4209ac04, - 0x420a2b13, - 0x420aaaf3, - 0x420b2b33, - 0x420babac, - 0x420c2ed8, - 0x420cacc2, - 0x420d2d75, - 0x420dadac, - 0x42122ddf, - 0x42172e9f, - 0x4217ae21, - 0x421c2e43, - 0x421f2dfe, - 0x42212f50, - 0x42262e82, - 0x422b2f2e, - 0x422bad50, - 0x422c2f10, - 0x422cad03, - 0x422d2cdc, - 0x422daeef, - 0x422e2d2f, - 0x42302e5e, - 0x4230adc6, - 0x423126ce, + 0x4071b140, + 0x40723153, + 0x4072b189, + 0x407331a1, + 0x40739665, + 0x407431b5, + 0x4074b1cf, + 0x407531e0, + 0x4075b1f4, + 0x40763202, + 0x407693f3, + 0x40773227, + 0x4077b283, + 0x4078329e, + 0x4078b2d7, + 0x407932ee, + 0x4079b304, + 0x407a3330, + 0x407ab343, + 0x407b3358, + 0x407bb36a, + 0x407c339b, + 0x407cb3a4, + 0x407d2a4a, + 0x407da2d7, + 0x407e32b3, + 0x407ea569, + 0x407f1eca, + 0x407fa0ad, + 0x40802249, + 0x40809ef2, + 0x408123d7, + 0x4081a1b4, + 0x4082300b, + 0x40829c45, + 0x40832544, + 0x4083a8c7, + 0x40841f16, + 0x4084a5a1, + 0x40852629, + 0x4085a7a4, + 0x408626bf, + 0x4086a30c, + 0x40873051, + 0x4087a7f2, + 0x40881c83, + 0x4088a9d9, + 0x40891cd2, + 0x40899c5f, + 0x408a2cc9, + 0x408a9a7d, + 0x408b337f, + 0x408bb0db, + 0x408c264f, + 0x408d1ffe, + 0x408d9f48, + 0x408e212e, + 0x408ea494, + 0x408f29ed, + 0x408fa7c0, + 0x409029a2, + 0x4090a691, + 0x40912cb1, + 0x40919ab5, + 0x40921d1f, + 0x4092b08c, + 0x4093316c, + 0x4093a31d, + 0x40941f2a, + 0x4094ace2, + 0x4095284e, + 0x4095b310, + 0x40963038, + 0x4096a262, + 0x4097239d, + 0x4097a17d, + 0x40981d7f, + 0x4098a862, + 0x409930a8, + 0x4099a4c1, + 0x409a245a, + 0x409a9a99, + 0x409b1f84, + 0x409b9faf, + 0x409c3265, + 0x409c9fd7, + 0x409d221e, + 0x409da1ca, + 0x409e1e10, + 0x409ea297, + 0x409f227f, + 0x409f9f77, + 0x40a022bf, + 0x40a0a197, + 0x40a121e5, + 0x40a1a5b5, + 0x40a22339, + 0x40a2a71d, + 0x40a32791, + 0x40a3b249, + 0x40a42383, + 0x40a4a1fc, + 0x40a51f06, + 0x40a5a2f1, + 0x40a62639, + 0x41f42b83, + 0x41f92c15, + 0x41fe2b08, + 0x41feadbe, + 0x41ff2eec, + 0x42032b9c, + 0x42082bbe, + 0x4208abfa, + 0x42092aec, + 0x4209ac34, + 0x420a2b43, + 0x420aab23, + 0x420b2b63, + 0x420babdc, + 0x420c2f08, + 0x420cacf2, + 0x420d2da5, + 0x420daddc, + 0x42122e0f, + 0x42172ecf, + 0x4217ae51, + 0x421c2e73, + 0x421f2e2e, + 0x42212f80, + 0x42262eb2, + 0x422b2f5e, + 0x422bad80, + 0x422c2f40, + 0x422cad33, + 0x422d2d0c, + 0x422daf1f, + 0x422e2d5f, + 0x42302e8e, + 0x4230adf6, + 0x423126fe, 0x44320778, 0x44328787, 0x44330793, @@ -669,109 +671,109 @@ 0x4439084d, 0x4439885b, 0x443a086e, - 0x4832140b, - 0x4832941d, - 0x48331433, - 0x4833944c, - 0x4c321489, - 0x4c329499, - 0x4c3314ac, - 0x4c3394cc, + 0x4832143b, + 0x4832944d, + 0x48331463, + 0x4833947c, + 0x4c3214b9, + 0x4c3294c9, + 0x4c3314dc, + 0x4c3394fc, 0x4c3400b9, 0x4c3480f7, - 0x4c3514d8, - 0x4c3594e6, - 0x4c361502, - 0x4c369528, - 0x4c371537, - 0x4c379545, - 0x4c38155a, - 0x4c389566, - 0x4c391586, - 0x4c3995b0, - 0x4c3a15c9, - 0x4c3a95e2, + 0x4c351508, + 0x4c359516, + 0x4c361532, + 0x4c369558, + 0x4c371567, + 0x4c379575, + 0x4c38158a, + 0x4c389596, + 0x4c3915b6, + 0x4c3995e0, + 0x4c3a15f9, + 0x4c3a9612, 0x4c3b0635, - 0x4c3b95fb, - 0x4c3c160d, - 0x4c3c961c, - 0x4c3d1635, + 0x4c3b962b, + 0x4c3c163d, + 0x4c3c964c, + 0x4c3d1665, 0x4c3d8d06, - 0x4c3e16a2, - 0x4c3e9644, - 0x4c3f16c4, - 0x4c3f93c3, - 0x4c40165a, - 0x4c409475, - 0x4c411692, - 0x4c419515, - 0x4c42167e, - 0x4c42945d, - 0x50323735, - 0x5032b744, - 0x5033374f, - 0x5033b75f, - 0x50343778, - 0x5034b792, - 0x503537a0, - 0x5035b7b6, - 0x503637c8, - 0x5036b7de, - 0x503737f7, - 0x5037b80a, - 0x50383822, - 0x5038b833, - 0x50393848, - 0x5039b85c, - 0x503a387c, - 0x503ab892, - 0x503b38aa, - 0x503bb8bc, - 0x503c38d8, - 0x503cb8ef, - 0x503d3908, - 0x503db91e, - 0x503e392b, - 0x503eb941, - 0x503f3953, + 0x4c3e16d2, + 0x4c3e9674, + 0x4c3f16f4, + 0x4c3f93f3, + 0x4c40168a, + 0x4c4094a5, + 0x4c4116c2, + 0x4c419545, + 0x4c4216ae, + 0x4c42948d, + 0x50323765, + 0x5032b774, + 0x5033377f, + 0x5033b78f, + 0x503437a8, + 0x5034b7c2, + 0x503537d0, + 0x5035b7e6, + 0x503637f8, + 0x5036b80e, + 0x50373827, + 0x5037b83a, + 0x50383852, + 0x5038b863, + 0x50393878, + 0x5039b88c, + 0x503a38ac, + 0x503ab8c2, + 0x503b38da, + 0x503bb8ec, + 0x503c3908, + 0x503cb91f, + 0x503d3938, + 0x503db94e, + 0x503e395b, + 0x503eb971, + 0x503f3983, 0x503f83b3, - 0x50403966, - 0x5040b976, - 0x50413990, - 0x5041b99f, - 0x504239b9, - 0x5042b9d6, - 0x504339e6, - 0x5043b9f6, - 0x50443a13, + 0x50403996, + 0x5040b9a6, + 0x504139c0, + 0x5041b9cf, + 0x504239e9, + 0x5042ba06, + 0x50433a16, + 0x5043ba26, + 0x50443a43, 0x50448469, - 0x50453a27, - 0x5045ba45, - 0x50463a58, - 0x5046ba6e, - 0x50473a80, - 0x5047ba95, - 0x50483abb, - 0x5048bac9, - 0x50493adc, - 0x5049baf1, - 0x504a3b07, - 0x504abb17, - 0x504b3b37, - 0x504bbb4a, - 0x504c3b6d, - 0x504cbb9b, - 0x504d3bc8, - 0x504dbbe5, - 0x504e3c00, - 0x504ebc1c, - 0x504f3c2e, - 0x504fbc45, - 0x50503c54, + 0x50453a57, + 0x5045ba75, + 0x50463a88, + 0x5046ba9e, + 0x50473ab0, + 0x5047bac5, + 0x50483aeb, + 0x5048baf9, + 0x50493b0c, + 0x5049bb21, + 0x504a3b37, + 0x504abb47, + 0x504b3b67, + 0x504bbb7a, + 0x504c3b9d, + 0x504cbbcb, + 0x504d3bf8, + 0x504dbc15, + 0x504e3c30, + 0x504ebc4c, + 0x504f3c5e, + 0x504fbc75, + 0x50503c84, 0x50508729, - 0x50513c67, - 0x5051ba05, - 0x50523bad, + 0x50513c97, + 0x5051ba35, + 0x50523bdd, 0x58321011, 0x68320fd3, 0x68328d2b, @@ -813,22 +815,22 @@ 0x783d8b97, 0x783e0aed, 0x783e8a9f, - 0x7c3212dc, - 0x80321528, + 0x7c32130c, + 0x80321558, 0x80328090, - 0x80333431, + 0x80333461, 0x803380b9, - 0x80343440, - 0x8034b3a8, - 0x803533c6, - 0x8035b454, - 0x80363408, - 0x8036b3b7, - 0x803733fa, - 0x8037b395, - 0x8038341b, - 0x8038b3d7, - 0x803933ec, + 0x80343470, + 0x8034b3d8, + 0x803533f6, + 0x8035b484, + 0x80363438, + 0x8036b3e7, + 0x8037342a, + 0x8037b3c5, + 0x8038344b, + 0x8038b407, + 0x8039341c, 0x84320bb0, 0x84328bc9, }; @@ -1062,6 +1064,7 @@ "EXPECTING_A_EC_KEY\0" "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" "INVALID_BUFFER_SIZE\0" + "INVALID_CIPHERTEXT_LENGTH\0" "INVALID_DIGEST_LENGTH\0" "INVALID_DIGEST_TYPE\0" "INVALID_KEYBITS\0" @@ -1069,6 +1072,7 @@ "INVALID_PADDING_MODE\0" "INVALID_PEER_KEY\0" "INVALID_PSS_SALTLEN\0" + "INVALID_SECRET_LENGTH\0" "INVALID_SIGNATURE\0" "KEYS_NOT_SET\0" "MEMORY_LIMIT_EXCEEDED\0"
diff --git a/gen/sources.bzl b/gen/sources.bzl index 81be628..8955e91 100644 --- a/gen/sources.bzl +++ b/gen/sources.bzl
@@ -386,6 +386,7 @@ "crypto/evp/evp.cc", "crypto/evp/evp_asn1.cc", "crypto/evp/evp_ctx.cc", + "crypto/evp/evp_kem.cc", "crypto/evp/p_dh.cc", "crypto/evp/p_dsa.cc", "crypto/evp/p_ec.cc",
diff --git a/gen/sources.cmake b/gen/sources.cmake index 18292b9..c875958 100644 --- a/gen/sources.cmake +++ b/gen/sources.cmake
@@ -404,6 +404,7 @@ crypto/evp/evp.cc crypto/evp/evp_asn1.cc crypto/evp/evp_ctx.cc + crypto/evp/evp_kem.cc crypto/evp/p_dh.cc crypto/evp/p_dsa.cc crypto/evp/p_ec.cc
diff --git a/gen/sources.gni b/gen/sources.gni index 6677107..0deaacb 100644 --- a/gen/sources.gni +++ b/gen/sources.gni
@@ -386,6 +386,7 @@ "crypto/evp/evp.cc", "crypto/evp/evp_asn1.cc", "crypto/evp/evp_ctx.cc", + "crypto/evp/evp_kem.cc", "crypto/evp/p_dh.cc", "crypto/evp/p_dsa.cc", "crypto/evp/p_ec.cc",
diff --git a/gen/sources.json b/gen/sources.json index e7ca6a3..a844ca9 100644 --- a/gen/sources.json +++ b/gen/sources.json
@@ -370,6 +370,7 @@ "crypto/evp/evp.cc", "crypto/evp/evp_asn1.cc", "crypto/evp/evp_ctx.cc", + "crypto/evp/evp_kem.cc", "crypto/evp/p_dh.cc", "crypto/evp/p_dsa.cc", "crypto/evp/p_ec.cc",
diff --git a/gen/sources.mk b/gen/sources.mk index d7e61b9..66c192f 100644 --- a/gen/sources.mk +++ b/gen/sources.mk
@@ -378,6 +378,7 @@ crypto/evp/evp.cc \ crypto/evp/evp_asn1.cc \ crypto/evp/evp_ctx.cc \ + crypto/evp/evp_kem.cc \ crypto/evp/p_dh.cc \ crypto/evp/p_dsa.cc \ crypto/evp/p_ec.cc \
diff --git a/include/openssl/base.h b/include/openssl/base.h index 5cb2bd5..008b162 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h
@@ -343,6 +343,7 @@ typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; typedef struct evp_hpke_kem_st EVP_HPKE_KEM; typedef struct evp_hpke_key_st EVP_HPKE_KEY; +typedef struct evp_kem_st EVP_KEM; typedef struct evp_pkey_alg_st EVP_PKEY_ALG; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; typedef struct evp_pkey_st EVP_PKEY;
diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 8f17bcb..a437550 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h
@@ -1135,6 +1135,63 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); +// Key encapsulation mechanism algorithms. +// +// Two APIs for working with key encapsulation mechanism (KEM) algorithms are +// provided: +// +// 1. Create an |EVP_PKEY_CTX|, initialize it for the appropriate KEM operation +// (see |EVP_PKEY_encapsulate_init| and |EVP_PKEY_decapsulate_init|), then +// run the operation. This matches the OpenSSL API. +// +// 2. Pass an appropriate |EVP_KEM| object to the functions below to use it +// for encapsulation and decapsulation operations with compatible |EVP_PKEY| +// objects. This API requires fewer steps. +// +// The |EVP_KEM| API is only compatible with KEMs that use fixed-length +// ciphertexts and secrets. + +// EVP_kem_ml_kem_* implement ML-KEM, defined in FIPS 203. +OPENSSL_EXPORT const EVP_KEM *EVP_kem_ml_kem_768(void); +OPENSSL_EXPORT const EVP_KEM *EVP_kem_ml_kem_1024(void); + +// TODO(crbug.com/449751916): Add more supported KEMs. + +// EVP_KEM_ciphertext_len returns the fixed length, in bytes, of a ciphertext +// produced and consumed by |kem|. +OPENSSL_EXPORT size_t EVP_KEM_ciphertext_len(const EVP_KEM *kem); + +// EVP_KEM_secret_len returns the fixed length, in bytes, of the shared +// secret produced and consumed by |kem|. +OPENSSL_EXPORT size_t EVP_KEM_secret_len(const EVP_KEM *kem); + +// EVP_KEM_encap uses |kem| to encapsulate a |peer_key|. It outputs a +// ciphertext of length |ciphertext_len| into |*out_ciphertext| and outputs a +// shared secret of length |secret_len| into |*out_secret|. |peer_key| must be +// a public key of the type expected by |kem|. |ciphertext_len| and +// |secret_len| must match the output of |EVP_KEM_ciphertext_len| and +// |EVP_KEM_secret_len|, respectively, when called with |kem|. This function +// returns one on success or zero on failure. +OPENSSL_EXPORT int EVP_KEM_encap(const EVP_KEM *kem, uint8_t *out_ciphertext, + size_t ciphertext_len, uint8_t *out_secret, + size_t secret_len, const EVP_PKEY *peer_key); + +// EVP_KEM_decap uses |kem| to decapsulate a |ciphertext| of length +// |ciphertext_len|, using |key| as a decapsulation key. It outputs a shared +// secret of length |secret_len| into |*out_secret|. |key| must be a private key +// of the type expected by |kem|. |secret_len| must match the output of +// |EVP_KEM_secret_len| when called with |kem|. This function returns one on +// success or zero on failure. If |ciphertext| is invalid (but of the correct +// length), this will return one and fill |out_secret| with a key that will +// always be the same for the same |ciphertext| and |key|, but which appears to +// be random unless one has access to the private |key|. Any subsequent +// symmetric encryption using |*out_secret| must use an authenticated encryption +// scheme in order to discover the decapsulation failure. +OPENSSL_EXPORT int EVP_KEM_decap(const EVP_KEM *kem, uint8_t *out_secret, + size_t secret_len, const uint8_t *ciphertext, + size_t ciphertext_len, const EVP_PKEY *key); + + // Deprecated functions. // EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID
diff --git a/include/openssl/evp_errors.h b/include/openssl/evp_errors.h index eb062ca..77b7ab5 100644 --- a/include/openssl/evp_errors.h +++ b/include/openssl/evp_errors.h
@@ -56,6 +56,8 @@ #define EVP_R_EXPECTING_A_DH_KEY 138 #define EVP_R_PRIVATE_KEY_WAS_NOT_SEED 139 #define EVP_R_MISSING_PUBLIC_KEY 140 +#define EVP_R_INVALID_CIPHERTEXT_LENGTH 141 +#define EVP_R_INVALID_SECRET_LENGTH 142 // Compatibility defines. #define EVP_R_OPERATON_NOT_INITIALIZED EVP_R_OPERATION_NOT_INITIALIZED
diff --git a/include/openssl/prefix_symbols.h b/include/openssl/prefix_symbols.h index 40ee107..ee35d09 100644 --- a/include/openssl/prefix_symbols.h +++ b/include/openssl/prefix_symbols.h
@@ -1053,6 +1053,10 @@ #pragma redefine_extname EVP_HPKE_KEY_private_key BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_private_key)) #pragma redefine_extname EVP_HPKE_KEY_public_key BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_public_key)) #pragma redefine_extname EVP_HPKE_KEY_zero BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_zero)) +#pragma redefine_extname EVP_KEM_ciphertext_len BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_KEM_ciphertext_len)) +#pragma redefine_extname EVP_KEM_decap BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_KEM_decap)) +#pragma redefine_extname EVP_KEM_encap BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_KEM_encap)) +#pragma redefine_extname EVP_KEM_secret_len BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_KEM_secret_len)) #pragma redefine_extname EVP_MD_CTX_block_size BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_block_size)) #pragma redefine_extname EVP_MD_CTX_cleanse BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_cleanse)) #pragma redefine_extname EVP_MD_CTX_cleanup BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_cleanup)) @@ -1280,6 +1284,8 @@ #pragma redefine_extname EVP_hpke_p256_hkdf_sha256 BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_hpke_p256_hkdf_sha256)) #pragma redefine_extname EVP_hpke_x25519_hkdf_sha256 BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_hpke_x25519_hkdf_sha256)) #pragma redefine_extname EVP_hpke_xwing BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_hpke_xwing)) +#pragma redefine_extname EVP_kem_ml_kem_1024 BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_kem_ml_kem_1024)) +#pragma redefine_extname EVP_kem_ml_kem_768 BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_kem_ml_kem_768)) #pragma redefine_extname EVP_marshal_digest_algorithm BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_marshal_digest_algorithm)) #pragma redefine_extname EVP_marshal_digest_algorithm_no_params BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_marshal_digest_algorithm_no_params)) #pragma redefine_extname EVP_marshal_private_key BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_marshal_private_key)) @@ -4124,6 +4130,10 @@ #define EVP_HPKE_KEY_private_key BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_private_key) #define EVP_HPKE_KEY_public_key BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_public_key) #define EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX(EVP_HPKE_KEY_zero) +#define EVP_KEM_ciphertext_len BORINGSSL_ADD_PREFIX(EVP_KEM_ciphertext_len) +#define EVP_KEM_decap BORINGSSL_ADD_PREFIX(EVP_KEM_decap) +#define EVP_KEM_encap BORINGSSL_ADD_PREFIX(EVP_KEM_encap) +#define EVP_KEM_secret_len BORINGSSL_ADD_PREFIX(EVP_KEM_secret_len) #define EVP_MD_CTX_block_size BORINGSSL_ADD_PREFIX(EVP_MD_CTX_block_size) #define EVP_MD_CTX_cleanse BORINGSSL_ADD_PREFIX(EVP_MD_CTX_cleanse) #define EVP_MD_CTX_cleanup BORINGSSL_ADD_PREFIX(EVP_MD_CTX_cleanup) @@ -4351,6 +4361,8 @@ #define EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX(EVP_hpke_p256_hkdf_sha256) #define EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX(EVP_hpke_x25519_hkdf_sha256) #define EVP_hpke_xwing BORINGSSL_ADD_PREFIX(EVP_hpke_xwing) +#define EVP_kem_ml_kem_1024 BORINGSSL_ADD_PREFIX(EVP_kem_ml_kem_1024) +#define EVP_kem_ml_kem_768 BORINGSSL_ADD_PREFIX(EVP_kem_ml_kem_768) #define EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX(EVP_marshal_digest_algorithm) #define EVP_marshal_digest_algorithm_no_params BORINGSSL_ADD_PREFIX(EVP_marshal_digest_algorithm_no_params) #define EVP_marshal_private_key BORINGSSL_ADD_PREFIX(EVP_marshal_private_key)