Skip to content

Commit

Permalink
Add MLKEM768 Hybrid Groups to libssl
Browse files Browse the repository at this point in the history
  • Loading branch information
alexw91 committed Sep 12, 2024
1 parent 3f4d2f6 commit 313712a
Show file tree
Hide file tree
Showing 7 changed files with 475 additions and 5 deletions.
24 changes: 23 additions & 1 deletion crypto/obj/obj_dat.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

/* This file is generated by crypto/obj/objects.go. */

#define NUM_NID 991
#define NUM_NID 993

static const uint8_t kObjectData[] = {
/* NID_rsadsi */
Expand Down Expand Up @@ -7269,6 +7269,18 @@ static const uint8_t kObjectData[] = {
0x04,
0x04,
0x03,
/* NID_X25519MLKEM768 */
0x2b,
0xce,
0x0f,
0x63,
0x36,
/* NID_SecP256r1MLKEM768 */
0x2b,
0xce,
0x0f,
0x63,
0x37,
};

static const ASN1_OBJECT kObjects[NUM_NID] = {
Expand Down Expand Up @@ -8945,6 +8957,10 @@ static const ASN1_OBJECT kObjects[NUM_NID] = {
{"MLKEM512", "MLKEM512", NID_MLKEM512, 9, &kObjectData[6288], 0},
{"MLKEM768", "MLKEM768", NID_MLKEM768, 9, &kObjectData[6297], 0},
{"MLKEM1024", "MLKEM1024", NID_MLKEM1024, 9, &kObjectData[6306], 0},
{"X25519MLKEM768", "X25519MLKEM768", NID_X25519MLKEM768, 5,
&kObjectData[6315], 0},
{"SecP256r1MLKEM768", "SecP256r1MLKEM768", NID_SecP256r1MLKEM768, 5,
&kObjectData[6320], 0},
};

static const uint16_t kNIDsInShortNameOrder[] = {
Expand Down Expand Up @@ -9162,9 +9178,11 @@ static const uint16_t kNIDsInShortNameOrder[] = {
16 /* ST */,
143 /* SXNetID */,
981 /* SecP256r1Kyber768Draft00 */,
992 /* SecP256r1MLKEM768 */,
458 /* UID */,
948 /* X25519 */,
982 /* X25519Kyber768Draft00 */,
991 /* X25519MLKEM768 */,
961 /* X448 */,
11 /* X500 */,
378 /* X500algorithms */,
Expand Down Expand Up @@ -10041,6 +10059,7 @@ static const uint16_t kNIDsInLongNameOrder[] = {
167 /* S/MIME Capabilities */,
387 /* SNMPv2 */,
981 /* SecP256r1Kyber768Draft00 */,
992 /* SecP256r1MLKEM768 */,
512 /* Secure Electronic Transactions */,
386 /* Security */,
394 /* Selected Attribute Types */,
Expand All @@ -10052,6 +10071,7 @@ static const uint16_t kNIDsInLongNameOrder[] = {
375 /* Trust Root */,
948 /* X25519 */,
982 /* X25519Kyber768Draft00 */,
991 /* X25519MLKEM768 */,
961 /* X448 */,
12 /* X509 */,
402 /* X509v3 AC Targeting */,
Expand Down Expand Up @@ -11199,6 +11219,8 @@ static const uint16_t kNIDsInOIDOrder[] = {
734 /* 1.3.132.0.39 (OBJ_sect571r1) */,
982 /* 1.3.9999.99.51 (OBJ_X25519Kyber768Draft00) */,
981 /* 1.3.9999.99.52 (OBJ_SecP256r1Kyber768Draft00) */,
991 /* 1.3.9999.99.54 (OBJ_X25519MLKEM768) */,
992 /* 1.3.9999.99.55 (OBJ_SecP256r1MLKEM768) */,
624 /* 2.23.42.3.0.0 (OBJ_set_rootKeyThumb) */,
625 /* 2.23.42.3.0.1 (OBJ_set_addPolicy) */,
626 /* 2.23.42.3.2.1 (OBJ_setAttr_Token_EMV) */,
Expand Down
2 changes: 2 additions & 0 deletions crypto/obj/obj_mac.num
Original file line number Diff line number Diff line change
Expand Up @@ -978,3 +978,5 @@ MLKEM1024IPD 987
MLKEM512 988
MLKEM768 989
MLKEM1024 990
X25519MLKEM768 991
SecP256r1MLKEM768 992
3 changes: 3 additions & 0 deletions crypto/obj/objects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,11 @@ secg-ellipticCurve 39 : sect571r1
: ffdhe8192

# PQ Group OIDs from OQS
# https://github.com/open-quantum-safe/oqs-provider/blob/main/ALGORITHMS.md#oids
1 3 9999 99 51 : X25519Kyber768Draft00
1 3 9999 99 52 : SecP256r1Kyber768Draft00
1 3 9999 99 54 : X25519MLKEM768
1 3 9999 99 55 : SecP256r1MLKEM768

# WAP/TLS curve OIDs (http://www.wapforum.org/)
!Alias wap-wsg-idm-ecid wap-wsg 4
Expand Down
8 changes: 8 additions & 0 deletions include/openssl/nid.h
Original file line number Diff line number Diff line change
Expand Up @@ -4355,6 +4355,14 @@ extern "C" {
#define NID_MLKEM1024 990
#define OBJ_MLKEM1024 2L, 16L, 840L, 1L, 101L, 3L, 4L, 4L, 3L

#define SN_X25519MLKEM768 "X25519MLKEM768"
#define NID_X25519MLKEM768 991
#define OBJ_X25519MLKEM768 1L, 3L, 9999L, 99L, 54L

#define SN_SecP256r1MLKEM768 "SecP256r1MLKEM768"
#define NID_SecP256r1MLKEM768 992
#define OBJ_SecP256r1MLKEM768 1L, 3L, 9999L, 99L, 55L

#if defined(__cplusplus)
} /* extern C */
#endif
Expand Down
8 changes: 8 additions & 0 deletions include/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2675,13 +2675,21 @@ OPENSSL_EXPORT int SSL_set1_groups_list(SSL *ssl, const char *groups);
// https://datatracker.ietf.org/doc/html/draft-tls-westerbaan-xyber768d00
#define SSL_GROUP_X25519_KYBER768_DRAFT00 0x6399

// https://datatracker.ietf.org/doc/html/draft-kwiatkowski-tls-ecdhe-mlkem.html
#define SSL_GROUP_SECP256R1_MLKEM768 0x11EB
#define SSL_GROUP_X25519_MLKEM768 0x11EC

// PQ and hybrid group IDs are not yet standardized. Current IDs are driven by
// community consensus and are defined at
// https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/oqs-kem-info.md
#define SSL_GROUP_KYBER512_R3 0x023A
#define SSL_GROUP_KYBER768_R3 0x023C
#define SSL_GROUP_KYBER1024_R3 0x023D

// https://datatracker.ietf.org/doc/html/draft-connolly-tls-mlkem-key-agreement.html
#define SSL_GROUP_MLKEM768 0x0768
#define SSL_GROUP_MLKEM1024 0x1024

// SSL_get_group_id returns the ID of the group used by |ssl|'s most recently
// completed handshake, or 0 if not applicable.
OPENSSL_EXPORT uint16_t SSL_get_group_id(const SSL *ssl);
Expand Down
42 changes: 40 additions & 2 deletions ssl/ssl_key_share.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "internal.h"
#include "../crypto/internal.h"
#include "../crypto/fipsmodule/ec/internal.h"
#include "../crypto/fipsmodule/ml_kem/ml_kem.h"
#include "../crypto/kyber/kem_kyber.h"

BSSL_NAMESPACE_BEGIN
Expand Down Expand Up @@ -638,6 +639,9 @@ class HybridKeyShare : public SSLKeyShare {
case SSL_GROUP_KYBER768_R3:
*out = KYBER768_R3_PUBLIC_KEY_BYTES;
return true;
case SSL_GROUP_MLKEM768:
*out = MLKEM768_PUBLIC_KEY_BYTES;
return true;
case SSL_GROUP_X25519:
*out = 32;
return true;
Expand All @@ -655,6 +659,9 @@ class HybridKeyShare : public SSLKeyShare {
case SSL_GROUP_KYBER768_R3:
*out = KYBER768_R3_CIPHERTEXT_BYTES;
return true;
case SSL_GROUP_MLKEM768:
*out = MLKEM768_CIPHERTEXT_BYTES;
return true;
case SSL_GROUP_X25519:
*out = 32;
return true;
Expand All @@ -677,14 +684,20 @@ CONSTEXPR_ARRAY NamedGroup kNamedGroups[] = {
{NID_X25519, SSL_GROUP_X25519, "X25519", "x25519"},
{NID_SecP256r1Kyber768Draft00, SSL_GROUP_SECP256R1_KYBER768_DRAFT00, "SecP256r1Kyber768Draft00", ""},
{NID_X25519Kyber768Draft00, SSL_GROUP_X25519_KYBER768_DRAFT00, "X25519Kyber768Draft00", ""},
{NID_SecP256r1MLKEM768, SSL_GROUP_SECP256R1_MLKEM768, "SecP256r1MLKEM768", ""},
{NID_X25519MLKEM768, SSL_GROUP_X25519_MLKEM768, "X25519MLKEM768", ""},
};

CONSTEXPR_ARRAY uint16_t kPQGroups[] = {
SSL_GROUP_KYBER512_R3,
SSL_GROUP_KYBER768_R3,
SSL_GROUP_KYBER1024_R3,
SSL_GROUP_MLKEM768,
SSL_GROUP_MLKEM1024,
SSL_GROUP_SECP256R1_KYBER768_DRAFT00,
SSL_GROUP_X25519_KYBER768_DRAFT00
SSL_GROUP_X25519_KYBER768_DRAFT00,
SSL_GROUP_SECP256R1_MLKEM768,
SSL_GROUP_X25519_MLKEM768
};

CONSTEXPR_ARRAY HybridGroup kHybridGroups[] = {
Expand All @@ -695,13 +708,30 @@ CONSTEXPR_ARRAY HybridGroup kHybridGroups[] = {
SSL_GROUP_KYBER768_R3, // component_group_ids[1]
},
},

{
SSL_GROUP_X25519_KYBER768_DRAFT00, // group_id
{
SSL_GROUP_X25519, // component_group_ids[0]
SSL_GROUP_KYBER768_R3, // component_group_ids[1]
},
},

{
SSL_GROUP_SECP256R1_MLKEM768, // group_id
{
SSL_GROUP_SECP256R1, // component_group_ids[0]
SSL_GROUP_MLKEM768, // component_group_ids[1]
},
},

{
SSL_GROUP_X25519_MLKEM768, // group_id
{
// Note: MLKEM768 is sent first due to FIPS requirements.
// For more details, see https://www.ietf.org/archive/id/draft-kwiatkowski-tls-ecdhe-mlkem.html#section-3
SSL_GROUP_MLKEM768, // component_group_ids[0]
SSL_GROUP_X25519, // component_group_ids[1]
},
}
};

Expand Down Expand Up @@ -739,6 +769,14 @@ UniquePtr<SSLKeyShare> SSLKeyShare::Create(uint16_t group_id) {
return MakeUnique<HybridKeyShare>(SSL_GROUP_SECP256R1_KYBER768_DRAFT00);
case SSL_GROUP_X25519_KYBER768_DRAFT00:
return MakeUnique<HybridKeyShare>(SSL_GROUP_X25519_KYBER768_DRAFT00);
case SSL_GROUP_MLKEM768:
// MLKEM768, as a standalone group, is not a NamedGroup; however, we
// need to create MLKEM768 key shares as part of hybrid groups.
return MakeUnique<KEMKeyShare>(NID_MLKEM768, SSL_GROUP_MLKEM768);
case SSL_GROUP_SECP256R1_MLKEM768:
return MakeUnique<HybridKeyShare>(SSL_GROUP_SECP256R1_MLKEM768);
case SSL_GROUP_X25519_MLKEM768:
return MakeUnique<HybridKeyShare>(SSL_GROUP_X25519_MLKEM768);
default:
return nullptr;
}
Expand Down
Loading

0 comments on commit 313712a

Please sign in to comment.