How to generate ML-KEM key-pair?

635 views
Skip to first unread message

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 10, 2024, 5:22:10 PM12/10/24
to openssl-users

Guys,

 

I’m trying to generate an ML-KEM key-pair (well, and ML-DSA key-pair) using OpenSSL CLI, specifically “openssl genpkey”. I have OpenSSLS-3.4.0 installed, and “oqs-provider” built from the “main” branch.

 

I thought that the simple

 

openssl genpkey -algorithm mlkem1024 -out /tmp/pr.out -outpubkey /tmp/pub.out

 

should do the job. Obviously, that’s not the case, and I’m doing something wrong – would love any help and guidance. I hope it’s something really small that’s missing…?

 

$ openssl genpkey -algorithm mlkem1024 -out /tmp/pr.out -outpubkey /tmp/pub.out -verbose -provider oqs

Error writing key(s)

40CBE258F87F0000:error:1D800065:ENCODER routines:OSSL_ENCODER_to_bio:reason(101):crypto/encode_decode/encoder_lib.c:55:No encoders were found. For standard encoders you need at least one of the default or base providers available. Did you forget to load them?

40CBE258F87F0000:error:04800073:PEM routines:do_pk8pkey:error converting private key:crypto/pem/pem_pk8.c:133:

$ openssl list -providers

Providers:

  default

    name: OpenSSL Default Provider

    version: 3.4.0

    status: active

  legacy

    name: OpenSSL Legacy Provider

    version: 3.4.0

    status: active

  oqs

    name: OpenSSL OQS Provider

    version: 0.7.1-dev

    status: active

  pkcs11

    name: PKCS#11 Provider

    version: 3.4.0

    status: active

  vigenere

    version: 1.2

$ openssl version

OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)

$

 

(Once these key-pairs are produced, I will try to create a certificate for the ML-KEM public key, signed by ML-DSA87 – so, if you can help me there as well, it would be outstanding.)

 

Thanks!

--

V/R,

Uri

 

There are two ways to design a system. One is to make it so simple there are obviously no deficiencies.

The other is to make it so complex there are no obvious deficiencies.

                                                                                                                                        C. A. R. Hoare

 

I was a shepherd to fools

Causelessly bold or afraid.

They would not abide by my rules.

Yet they escaped. For I stayed.

                                    R. Kipling “Epitaphs of the War. Convoy Escort”

 

Dmitry Belyavsky

unread,
Dec 10, 2024, 5:33:08 PM12/10/24
to Blumenthal, Uri - 0553 - MITLL, openssl-users

You have to build the OQS  provider using OQS_KEM_ENCODERS=on


--
You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.
To view this discussion visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/BN0P110MB14195B9F2F4AFD45ED2C8C6A903DA%40BN0P110MB1419.NAMP110.PROD.OUTLOOK.COM.

Viktor Dukhovni

unread,
Dec 28, 2024, 10:08:44 PM12/28/24
to openss...@openssl.org
On Tue, Dec 10, 2024 at 10:20:27PM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> I’m trying to generate an ML-KEM key-pair (well, and ML-DSA key-pair)
> using OpenSSL CLI, specifically “openssl genpkey”. I have
> OpenSSLS-3.4.0 installed, and “oqs-provider” built from the “main”
> branch.

While I can't help you with OQS, the good news it that ML-KEM and ML-DSA
will likely soon have native support in the upcoming OpenSSL 3.5. The
ML-KEM code is a bit further along, though not yet even fully merged into
the feature branch, a bunch is still in various PRs...

$ openssl genpkey -algorithm ml-kem-512 -out /tmp/ml-512-key.pem
$ openssl pkey -in /tmp/ml-512-key.pem -pubout -out /tmp/ml-512-pub.pem
$ openssl pkeyutl -encap -inkey /tmp/ml-512-pub.pem -secret /tmp/encap.dat -out /tmp/ctext.dat
$ openssl pkeyutl -decap -inkey /tmp/ml-512-key.pem -secret /tmp/decap.dat < /tmp/ctext.dat

$ openssl dgst -sha256 -binary < /tmp/encap.dat | xxd -p -c32
351bc81516ab2b70cf30fbbfd92cbb819f56351460ce655929655c7f2fae7256

$ openssl dgst -sha256 -binary < /tmp/decap.dat | xxd -p -c32
351bc81516ab2b70cf30fbbfd92cbb819f56351460ce655929655c7f2fae7256

$ wc -c /tmp/*.dat
768 /tmp/ctext.dat
32 /tmp/decap.dat
32 /tmp/encap.dat
832 total

$ openssl pkey -in /tmp/ml-512-key.pem -text | sed -e '/pub:/q'
-----BEGIN PRIVATE KEY-----
MFICAQAwCwYJYIZIAWUDBAQBBECkAuecgpTeeI3c9gNy/bor/lneCg08n4A85VlG
wYGhm9CgcO/o2h/xPIjBJ1Ry2n5bCICerYwMjal/MeZ1ioDV
-----END PRIVATE KEY-----
ML-KEM-512 Private-Key:
priv:
a4:02:e7:9c:82:94:de:78:8d:dc:f6:03:72:fd:ba:
2b:fe:59:de:0a:0d:3c:9f:80:3c:e5:59:46:c1:81:
a1:9b:d0:a0:70:ef:e8:da:1f:f1:3c:88:c1:27:54:
72:da:7e:5b:08:80:9e:ad:8c:0c:8d:a9:7f:31:e6:
75:8a:80:d5
pub:

$ openssl pkey -in /tmp/ml-512-pub.pem -pubin -text | sed -e '/pub:/q'
-----BEGIN PUBLIC KEY-----
MIIDMjALBglghkgBZQMEBAEDggMhAOcWAuPrJwXbi8ikCRuDSzoUunHGHJK0R+5L
UOQ2bcercJTqb7AleVijcTkigLDcO7SowHHnIuT2mE6lW4YzwdbKQdQZuQqravG4
x/JSs+jAvFLjrkeYqpYpUo2HDhpMSBAsXGi6rnpywaUyCJ9qhmOrqSEVx+43o1FI
VgiYnvh2XvyZmc/LLY8UywVJc8pxIudJYqpKeGPzMjzRCNQUp17cEpQ6h+6gpDZp
a8ILR7ryuMRBsLpUrNCXANCwqmCWvIP5rCHriVxXN54WBT6WTb7ryNMUjYNAaHiK
gIHUrFUFLIxJksUYYu5Uyj3xWIWBjc85Rk4wZWDHtF1wmoQ3cGymAZnwwGNMzG26
ZhBiuF6wRaNJK8AAqcins6aTCMDYet2njoL7VjCkYpZCnpC6aF67uwuQWEiwJVbi
jIySJ4h5V98zsIrRyHexPqnKvb7TGom5YDabnIPTMuRYAVnKKqIaE65UPn5Lc4AJ
W9dSJZeSE3i3ugchpPgZL1UiZzU4k/MsNdzkG+OLJw+aUit4XMfxhSdbJDhymS0n
TxZoX8HwE1FkggpyhjXit58qaumXLXLHWARJYjXJR+omRq6DYC0XnJCoVZJ6jF+R
iHVIx4e1PHQIVV51oFgcXgTwl8snXQI3tHJ6Aldcrfu8mYDpOdK2bV7octXpWQ0g
Z4U6ESIqh5Z1XPmwarFnipbVXQy5qxPFLvX1j2jMq2ALVPxXJPRZQDRFkDgKtG4o
PsJTPRyhzeHgUTb2dD+VJ9FkHtAMz0jncm/ycYxxklmgO2UQYrTpbZFWbEfhAW6L
bXtyb/T6qlDQaHo7zLGMDrj7MSf1X2yIgxdMBcPBI3HGTgCxpRD2G28bteyHEeuU
tRXbWckjWUVprj1Wqtz1p0tSQWQCC7rCE4NEI1OmNk9GY7BGDYqYBcKnzkb3QOXS
Pm0RTJybx9PnB09gxHsrdEF6LJrxV1H5aMYxXrzwL0rUt/cCdrXmbDvRuVMiYFcW
pOCVWxJWtZNrdTqkwf5gzG24XmqGjk/3GfkPkkEkchfz8eIaf8z0cWJ2wLhP+Mje
Z4PeJIIn
-----END PUBLIC KEY-----
ML-KEM-512 Public-Key:
pub:

[ The openssl-pkeyutl(1) support for encap/decap required some fixes. ]

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 28, 2024, 11:29:43 PM12/28/24
to openss...@openssl.org

Viktor,

 

Thank you very much! Very helpful!

 

$ openssl genpkey -algorithm mlkem1024 -outform PEM -out prkey-kem.pem -outpubkey pubkey-kem.pem

$ openssl genpkey -algorithm mldsa87 -outform PEM -out prkey-dsa.pem -outpubkey pubkey-dsa.pem

$ openssl pkey -pubin -in pubkey-kem.pem -text | head -10

-----BEGIN PUBLIC KEY-----

MIIGMjALBglghkgBZQMEBAMDggYhAL5xtR8wyXRFEPGAZAjDFFDThI90YcEkNeGF

rkCkJpoouPnYfJ/hPTSgJ5+GPS6iGeVkBymMWDHzMFi1yWc7v9S5lCD7vxGlTDIk

qmI2mk0jKLepcoewbh/1TgPDQt2GxxK1xuBEGEPKR/ppByacl0JVRGobJK5cHNr0

Kh8HdBXaBvwAWMXlDoTSPl9AhkBBOY2Er8R3gUIACopmYOFyNesoRrRgtcOgxidU

EJ+1q94jghlTuL1bT4oGYF3hQIIkr+c7nPEjIZt5EEPJP0RLdTUSRkS0mMcSeeWl

n1czfJjCGfm7Hsa3ia64qBNSJZ3hTbYpGkFRUssEPHTWB0RYW+mYzgvRwnZHY+8m

OSoRmjtKeAwlV2xKjKRwSOBcWypZwGJrYTZJYIOlhGArUXA6f5mYAHkJxcoqI/uD

PYClig87ffvQvwlzlMc1V6TJjnoRYDrig45cl9GSNFNGKlh6dNXmslcMw0tWdcxZ

WdAmQ8HUU1m2ssZZr56nysN6VW56JOPXLLl3VHLLbtDjE6Ybe5tQLzU5Xx9WxBks

$ 

$ openssl pkeyutl -encap -pubin -inkey pubkey-kem.pem -secret ss1.dat -out ctext.dat

$ openssl pkeyutl -decap -inkey prkey-kem.pem -out ss2.dat < ctext.dat

$ openssl dgst -sha256 -binary < ss1.dat | xxd -p -c32

6931e331b9ccb1267b90fcfc3a21707be9fdb2e3b8df160c552040cf151fb74b

$ openssl dgst -sha256 -binary < ss2.dat | xxd -p -c32

6931e331b9ccb1267b90fcfc3a21707be9fdb2e3b8df160c552040cf151fb74b

$ 

$ openssl version

OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)

$ 

 

The above worked like a charm. I used the stable/released OpenSSL 3.4.0, with the current OQS provider installed (so, slightly different parameters).

 

Question: could you help me, using the two key-pairs above, create (a) a self-signed certificate for the ML-DSA-87 pubkey with ML-DSA-87 as signature algorithm, and SHA384 as hash, and (b) a certificate for the above ML-KEM-1024 public key signed by the above ML-DSA-87 key?

(Getting CSR and all the arguments seems to be a problem for me.)

 

Thanks again!

--

V/R,

Uri

 

There are two ways to design a system. One is to make it so simple there are obviously no deficiencies.

The other is to make it so complex there are no obvious deficiencies.

                                                                                                                                     -  C. A. R. Hoare

 

I was a shepherd to fools

Causelessly bold or afraid.

They would not abide by my rules.

Yet they escaped. For I stayed.

                                                  R. Kipling “Epitaphs of the War. Convoy Escort”

 

 

 

From: openss...@openssl.org <openss...@openssl.org> on behalf of Viktor Dukhovni <openss...@dukhovni.org>
Date: Saturday, December 28, 2024 at 22:09
To: openss...@openssl.org <openss...@openssl.org>
Subject: [EXT] Re: How to generate ML-KEM key-pair?

!-------------------------------------------------------------------|
  This Message Is From an External Sender
  This message came from outside the Laboratory.
|-------------------------------------------------------------------!

--
You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.

Mounir IDRASSI

unread,
Dec 29, 2024, 11:06:28 AM12/29/24
to openss...@openssl.org
On 12/29/2024 5:29 AM, Blumenthal, Uri - 0553 - MITLL wrote:
could you help me, using the two key-pairs above, create (a) a self-signed certificate for the ML-DSA-87 pubkey with ML-DSA-87 as signature algorithm, and SHA384 as hash, and (b) a certificate for the above ML-KEM-1024 public key signed by the above ML-DSA-87 key?

Some quick thoughts:

To my knowledge, there is no OID for ML-DSA with SHA384 pre-hashing. NIST defines OIDs only for ML-DSA with SHA512 pre-hashing. So, your requirement for SHA384 pre-hash is not possible to implement, at least not in an interoperable standard way.

ML-KEM is not designed for signing, it is used for key encapsulation and decapsulation.So, it is not possible to use traditional CSR approaches like in RSA/ECDSA. Instead, alternative methods for proof of possession such as CRMF/CMP protocols must be used. This is for example how EJBCA implements ML-KEM certificates issuance in its latest version 9.1.0 (cf https://docs.keyfactor.com/ejbca/latest/ejbca-9-1-release-notes). 

OpenSSL do provide cmp command for CMP protocol but I don't know its level of compatibility with the latest RFC4210 (https://www.ietf.org/archive/id/draft-ietf-lamps-rfc4210bis-12.html#name-key-encapsulation-mechanism). Of course, you will still need a CA to request certificate from but I don't know any apart from EJBCA. That being said, it should be possible to implement a demo CA programmatically to issue ML-KEM certificates without the complexity of proof of possession and I'm sure someone has already done this although I cannot find it online.

--
Mounir IDRASSI

Viktor Dukhovni

unread,
Dec 29, 2024, 11:33:11 AM12/29/24
to openss...@openssl.org
On Sun, Dec 29, 2024 at 04:29:32AM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> $ openssl pkeyutl -encap -pubin -inkey pubkey-kem.pem -secret ss1.dat -out ctext.dat
> $ openssl pkeyutl -decap -inkey prkey-kem.pem -out ss2.dat < ctext.dat

The encap/decap interface isn't quite right. I'm changing it in:

https://github.com/openssl/openssl/pull/26281

The "-decap" option will also write the shared-secret to the file
specified with "-secret", rather than "-out", and the "-secret" file
permissions will be owner-only for both encap and decap. The '-pubin'
option for '-encap' will become implicit.

For backwards compatibility, the "-decap" option will default to using
the "-out" file (which then may not have the right permissions). I am
not inclined to encourage the use of the fallback interface by
documenting its use.

> Question: could you help me, using the two key-pairs above, create
> (a) a self-signed certificate for the ML-DSA-87 pubkey with ML-DSA-87
> as signature algorithm, and SHA384 as hash, and

Presumably, (a) just works with in the usual way:

openssl req -x509 -new \
-key somekey.pem \
-out somecert.pem \
-subj "/CN=somehost" -days 60 \
-extfile <(printf '...extensions...\n')

> (b) a certificate for the above ML-KEM-1024 public key signed by the
> above ML-DSA-87 key? (Getting CSR and all the arguments seems to be a
> problem for me.)

It isn't possible to create a CSR for ML-KEM, because CSR's needs to be
signed by the subject key, but ML-KEM keys can't sign.

While you can create a certificate with an ML-KEM public key in it, you
probably don't want to. Since the key can't do any of the things that
one expects a public key in a certificate to do.

$ openssl x509 -new -key /tmp/ed.pem -force_pubkey /tmp/ml-512-pub.pem \
-out /tmp/ml-cert.pem -subj / -days 30 -extfile <(
printf "keyUsage = keyEncipherment\n'
printf "subjectKeyIdentifier = none\n"
)
Warning: Signature key and public key of cert do not match

$ openssl x509 -in /tmp/ml-cert.pem -noout -text \
-certopt no_sigdump,no_serial,no_validity,no_issuer,no_subject |
sed -ne '1,/pub:/p;/extensions/,$p'
Certificate:
Data:
Version: 3 (0x2)
Signature Algorithm: ED25519
Subject Public Key Info:
Public Key Algorithm: ML-KEM-512
ML-KEM-512 Public-Key:
pub:
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment
X509v3 Authority Key Identifier:
F3:96:DE:29:A6:9B:71:A3:5F:B6:84:DF:6B:26:28:B5:FB:57:B2:75

Perhaps you're looking to implement KEMTLS "delegated credentials"?
For these the ML-DSA key signs a TLS "delegated credential" blob,
which is then only useful with KEMTLS, since again, the subject key
can't do signing.

What exactly is your use-case for an ML-KEM SPKI in an an X.509
certificate?

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 12:06:04 PM12/29/24
to Mounir IDRASSI, openss...@openssl.org

On 12/29/2024 5:29 AM, Blumenthal, Uri - 0553 - MITLL wrote:

could you help me, using the two key-pairs above, create (a) a self-signed certificate for the ML-DSA-87 pubkey with ML-DSA-87 as signature algorithm, and SHA384 as hash, and (b) a certificate for the above ML-KEM-1024 public key signed by the above ML-DSA-87 key?

Some quick thoughts:

To my knowledge, there is no OID for ML-DSA with SHA384 pre-hashing. NIST defines OIDs only for ML-DSA with SHA512 pre-hashing. So, your requirement for SHA384 pre-hash is not possible to implement, at least not in an interoperable standard way.

Thanks for bringing this up. My fault – I should’ve said “SHA384 or SHA512”, because either one is fine for my use case.

ML-KEM is not designed for signing, it is used for key encapsulation and decapsulation.So, it is not possible to use traditional CSR approaches like in RSA/ECDSA.

Yes, I’m aware of this – it was one of the reasons for my asking for help/guidance here.

Instead, alternative methods for proof of possession such as CRMF/CMP protocols must be used. This is for example how EJBCA implements ML-KEM certificates issuance in its latest version 9.1.0 (cf https://docs.keyfactor.com/ejbca/latest/ejbca-9-1-release-notes). 

EJBCA used to be an open-source product – it looks like now it’s commercial? I tried to do a quick-and-dirty experiment with it, and couldn’t make heads or tails. If that’s the only working option, I might want to download Keyfactor EJBCA container, as building it from the source turned out much less fun that it used to be several years ago.

OpenSSL do provide cmp command for CMP protocol but I don't know its level of compatibility with the latest RFC4210 (https://www.ietf.org/archive/id/draft-ietf-lamps-rfc4210bis-12.html#name-key-encapsulation-mechanism). Of course, you will still need a CA to request certificate from but I don't know any apart from EJBCA. That being said, it should be possible to implement a demo CA programmatically to issue ML-KEM certificates without the complexity of proof of possession and I'm sure someone has already done this although I cannot find it online.

I see – so, in your opinion my best way would be to use OpenSSL CMP CLI and/or protocol?

Thanks!

 

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 12:58:15 PM12/29/24
to openss...@openssl.org

On Sun, Dec 29, 2024 at 04:29:32AM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> $ openssl pkeyutl -encap -pubin -inkey pubkey-kem.pem -secret ss1.dat -out ctext.dat
> $ openssl pkeyutl -decap -inkey prkey-kem.pem -out ss2.dat < ctext.dat

The encap/decap interface isn't quite right.  I'm changing it in:

    https://github.com/openssl/openssl/pull/26281

The "-decap" option will also write the shared-secret to the file
specified with "-secret", rather than "-out", and the "-secret" file
permissions will be owner-only for both encap and decap.  The '-pubin'
option for '-encap' will become implicit.

 

Excellent, thanks – it would make much more sense that way.


For backwards compatibility, the "-decap" option will default to using
the "-out" file (which then may not have the right permissions). I am
not inclined to encourage the use of the fallback interface by
documenting its use. 

 

😉

> Question: could you help me, using the two key-pairs above, create
> (a) a self-signed certificate for the ML-DSA-87 pubkey with ML-DSA-87
>     as signature algorithm, and SHA384 as hash, and

Presumably, (a) just works with in the usual way:

    openssl req -x509 -new \
        -key somekey.pem \
        -out somecert.pem \
        -subj "/CN=somehost" -days 60 \
        -extfile <(printf '...extensions...\n')

 

Thanks! Indeed, the above works. Is there a good (“convenient” 😉) example of a text file that contains extensions (a) suitable for a CA (that would be for the ML-DSA “keyholder”), and (b) suitable for a TLS or IPsec peer (that would for the ML-KEM cert holder)? Something in a format “ready-for-OpenSSL-consumption”?


> (b) a certificate for the above ML-KEM-1024 public key signed by the
>     above ML-DSA-87 key?  (Getting CSR and all the arguments seems to be a
>     problem for me.)

It isn't possible to create a CSR for ML-KEM, because CSR's needs to be
signed by the subject key, but ML-KEM keys can't sign.

 

Yes…


While you can create a certificate with an ML-KEM public key in it, you
probably don't want to. 

 

Respectfully disagree. I absolutely do want to create a certificate with an ML-KEM public key in in, among other reasons – because I intend to use it in an Authenticated Key Exchange (currently working on an RFC that defines this protocol, spoiler alert – it’s named “PQuAKE”). It’s designed in the spirit of MQV/HMQV, KEMTLS, and such.

 

Since the key can't do any of the things that one expects a public key in a certificate to do.

 

What might those things be? For me the only value/benefit I expect from this certificate is the “attestation” to the “belonging” and the validity period of the ML-KEM public key it contains (probably a few other details – but, e.g., one thing I do not need it to do is signing anything).

 

    $ openssl x509 -new -key /tmp/ed.pem -force_pubkey /tmp/ml-512-pub.pem \
        -out /tmp/ml-cert.pem -subj / -days 30 -extfile <(
                printf "keyUsage = keyEncipherment\n'
                printf "subjectKeyIdentifier = none\n"
            )
    Warning: Signature key and public key of cert do not match

 

Thank you!! Yes, this works!


Perhaps you're looking to implement KEMTLS "delegated credentials"?

 

Well, not exactly, not really – but I can see the similarity. 😉


For these the ML-DSA key signs a TLS "delegated credential" blob,
which is then only useful with KEMTLS, since again, the subject key
can't do signing.

 

Since my use case is similar to KEMTLS, I’m perfectly happy with being unable to sign with the subject key. Implicit authentication is all I need here.


What exactly is your use-case for an ML-KEM SPKI in an an X.509
certificate?

 

Not to bore the audience with nitty-gritty details – it’s similar to PQ variant of MQV. Avoid explicit dynamic signatures as much as possible, rely upon implicit authentication and static certificates, prefer the cost of two extra KEM operations to the cost of two signatures.

 

Thanks!

Viktor Dukhovni

unread,
Dec 29, 2024, 1:37:05 PM12/29/24
to openss...@openssl.org
On Sun, Dec 29, 2024 at 05:58:01PM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> Is there a good ("convenient") example of a text file that contains
> extensions (a) suitable for a CA (that would be for the ML-DSA
> "keyholder"), and (b) suitable for a TLS or IPsec peer (that would for
> the ML-KEM cert holder)? Something in a format
> "ready-for-OpenSSL-consumption"?

Perhaps the below will help?

https://docs.google.com/presentation/d/1xU2-U_6uUW4gB3j_v7EQC81t1RZ_slHyY_91MLlMDEg/edit#slide=id.g2b4be0ee06d_0_0
https://www.youtube.com/watch?v=OuH4vwmzP_o

otherwise there are always the x509v3_config(5) and x509(1) manpages.

> $ openssl x509 -new -key /tmp/ed.pem -force_pubkey /tmp/ml-512-pub.pem \
> -out /tmp/ml-cert.pem -subj / -days 30 -extfile <(
> printf "keyUsage = keyEncipherment\n'
> printf "subjectKeyIdentifier = none\n"
> )
>
> Thank you!! Yes, this works!

If you need the subject and issuer to be different, you can instead try
some variant of:

$ openssl x509 -new -key /tmp/ed.pem \
-out /tmp/ml-cert.pem \
-force_pubkey /tmp/ml-512-pub.pem \
-set_issuer "/CN=Viktor Dukhovni" \
-set_subject "/CN=viktor" \
-days 30 -extfile <(
printf "keyUsage = keyEncipherment\n'
printf "subjectKeyIdentifier = none\n"
printf "authorityKeyIdentifier = none\n"
)

And end up with, say:

$ openssl x509 -in /tmp/ml-cert.pem -noout -text \
-certopt no_sigdump,no_serial,no_validity |
sed -ne '1,/pub:/p;/extensions/,$p'
Certificate:
Data:
Version: 3 (0x2)
Signature Algorithm: ED25519
Issuer: CN=Viktor Dukhovni
Subject: CN=viktor
Subject Public Key Info:
Public Key Algorithm: ML-KEM-512
ML-KEM-512 Public-Key:
pub:
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment

> > Perhaps you're looking to implement KEMTLS "delegated credentials"?
>
> Well, not exactly, not really – but I can see the similarity.
>
> Since my use case is similar to KEMTLS, I’m perfectly happy with being
> unable to sign with the subject key. Implicit authentication is all I
> need here.

Then, assuming it still makes sense for the payload to be an X.509
certificate, and not something much simpler (like a delegated
credential), you should be all set.

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 2:39:31 PM12/29/24
to openss...@openssl.org

> Is there a good ("convenient") example of a text file that contains
> extensions (a) suitable for a CA (that would be for the ML-DSA
> "keyholder"), and (b) suitable for a TLS or IPsec peer (that would for
> the ML-KEM cert holder)? Something in a format
> "ready-for-OpenSSL-consumption"?

Perhaps the below will help?

    https://docs.google.com/presentation/d/1xU2-U_6uUW4gB3j_v7EQC81t1RZ_slHyY_91MLlMDEg/edit#slide=id.g2b4be0ee06d_0_0
    https://www.youtube.com/watch?v=OuH4vwmzP_o

 

Oh, it absolutely does – thank you!

 

$ openssl x509 -new -key prkey-dsa.pem -out dsa-ca.pem -force_pubkey pubkey-dsa.pem -set_issuer "/CN=Experimental_PQ_CA" -set_subject "/CN=Experimental_PQ_CA" -days 360 -extfile <(printf "basicConstraints=critical,CA:true,pathlen:1\n")

$ 

$ openssl x509 -new -key prkey-dsa.pem -force_pubkey pubkey-kem.pem -out kem-cert.pem -subj "/CN=PQ_KEM_Entity" -set_issuer "/CN=Experimental_PQ_CA" -days 360 -extfile <(printf "keyUsage=keyEncipherment\n")

Warning: Signature key and public key of cert do not match

$ 

$ openssl verify -show_chain -CAfile dsa-ca.pem kem-cert.pem 

kem-cert.pem: OK

Chain:

depth=0: CN=PQ_KEM_Entity (untrusted)

depth=1: CN=Experimental_PQ_CA

$ 

$ 

$ openssl verify -show_chain -trusted dsa-ca.pem kem-cert.pem 

kem-cert.pem: OK

Chain:

depth=0: CN=PQ_KEM_Entity (untrusted)

depth=1: CN=Experimental_PQ_CA

$

 

The above – worked, thanks!

 

Perhaps you could clue me in regarding “(untrusted)” in the above?

 

Also, am I correct to assume that if I choose to prepare extension templates, those files would look like:

For CA template (ca-template.txt):

basicConstraints = critical, CA:TRUE, pathlen:1

keyUsage = critical, digitalSignature, nonRepudiation, keyCertSign

 

For KEM cert template (kem-template.txt):

basicConstraints = critical, CA:FALSE

keyUsage = critical, keyEncipherment

 

and I’d be able to refer to them in the “openssl x509 …..” command above as “-extfile kem-template.txt”?

 

If the format of the above files should be more elaborate – I’d appreciate being “clued in”!

 

> Since my use case is similar to KEMTLS, I’m perfectly happy with being
> unable to sign with the subject key. Implicit authentication is all I
> need here.

Then, assuming it still makes sense for the payload to be an X.509
certificate, and not something much simpler (like a delegated
credential), you should be all set.

 

Unless I’m mistaken, delegated credentials are supposed to have very short lifetime, and be “renewed” (re-“retrieved”) quite often. My use case suggests (reasonably) long-term certificates, whose main difference from the traditional PKI for TLS or IPsec is that they’re used in implicit authentication, rather than for generating dynamic signatures during the handshake.

 

Perhaps, I need to understand “delegated credentials” better. Though there’d be a question of whether my infrastructure is ready and willing to embrace that concept, and the workflows it would require…

 

Thank you!!

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 3:13:02 PM12/29/24
to openss...@openssl.org

I’m getting a very confusing problem: when I invoke “openssl” from the Makefile by “make”, it fails. But when I copy exactly the same command line into a Terminal (aka, shell), it works perfectly fine:

 

$ make

openssl genpkey -algorithm mlkem1024 -outform PEM -out prkey-kem.pem -outpubkey pubkey-kem.pem

Error initializing mlkem1024 context

C0642D48F87F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global default library context, Algorithm (mlkem1024 : 0), Properties (<null>)

make: *** [gen_kem_keys] Error 1

$ openssl genpkey -algorithm mlkem1024 -outform PEM -out prkey-kem.pem -outpubkey pubkey-kem.pem

$ ll prkey-kem.pem 

-rw-------  1 ur20980  staff  6506 Dec 29 15:10 prkey-kem.pem

$ 

 

What’s wrong???

--

V/R,

Uri

 

There are two ways to design a system. One is to make it so simple there are obviously no deficiencies.

The other is to make it so complex there are no obvious deficiencies.

                                                                                                                                     -  C. A. R. Hoare

 

I was a shepherd to fools

Causelessly bold or afraid.

They would not abide by my rules.

Yet they escaped. For I stayed.

                                                  R. Kipling “Epitaphs of the War. Convoy Escort”

 

 

 

--

You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.

Viktor Dukhovni

unread,
Dec 29, 2024, 3:29:31 PM12/29/24
to openss...@openssl.org
On Sun, Dec 29, 2024 at 07:39:20PM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> > Perhaps the below will help?
>
> > https://docs.google.com/presentation/d/1xU2-U_6uUW4gB3j_v7EQC81t1RZ_slHyY_91MLlMDEg/edit#slide=id.g2b4be0ee06d_0_0 <https://docs.google.com/presentation/d/1xU2-U_6uUW4gB3j_v7EQC81t1RZ_slHyY_91MLlMDEg/edit#slide=id.g2b4be0ee06d_0_0>
> > https://www.youtube.com/watch?v=OuH4vwmzP_o <https://www.youtube.com/watch?v=OuH4vwmzP_o>
>
> Oh, it absolutely does – thank you!

You're welcome, it is reasonable to guess you read the slides, and did
not watch the recording.

> $ openssl verify -show_chain -CAfile dsa-ca.pem kem-cert.pem
> kem-cert.pem: OK
> Chain:
> depth=0: CN=PQ_KEM_Entity (untrusted)
> depth=1: CN=Experimental_PQ_CA
> $
> $
> $ openssl verify -show_chain -trusted dsa-ca.pem kem-cert.pem
> kem-cert.pem: OK
> Chain:
> depth=0: CN=PQ_KEM_Entity (untrusted)
> depth=1: CN=Experimental_PQ_CA
> $
>
> Perhaps you could clue me in regarding “(untrusted)” in the above?

The "untrusted" (not a priori trusted) certificates were not from the
trust store, I think I mentioned this during the presentation.

> Also, am I correct to assume that if I choose to prepare extension
> templates, those files would look like: For CA template
> (ca-template.txt):
> basicConstraints = critical, CA:TRUE, pathlen:1
> keyUsage = critical, digitalSignature, nonRepudiation, keyCertSign

The output of the <(...) commands used as `-extfile` values in
bash-compatible shells can of course be saved in actual files. The
`openssl x509` just reads (without seeking) data from a file, which
can be a command pipe.

> For KEM cert template (kem-template.txt):
> basicConstraints = critical, CA:FALSE
> keyUsage = critical, keyEncipherment
>
> and I’d be able to refer to them in the “openssl x509 …..” command
> above as “-extfile kem-template.txt”?

I couldn't be otherwise, if you're comfortable with <(...) support in
your shell.

> If the format of the above files should be more elaborate – I’d
> appreciate being “clued in”!

It is an extension file, same syntax as "openssl.cnf", including
support for subsections:

[some_sect]
some_thing = some_value
other_think = other_value

if you need it. The only difference is that this the "extensions"
section of that file, so no "newoid" or other things that don't make
sense in the extensions section.

> > Then, assuming it still makes sense for the payload to be an X.509
> > certificate, and not something much simpler (like a delegated
> > credential), you should be all set.
>
> Unless I’m mistaken, delegated credentials are supposed to have very
> short lifetime, and be “renewed” (re-“retrieved”) quite often.

They are a TLS construct. In non-TLS contexts, you could invent and
use something similarly streamlined that conveys a key, but is not
a full X.509 certificate. Particularly if there's a need for non-CAs
(EE key holders) to be able to sign these, which they cannot with
X.509, as they are not CAs. So delegated credetials are carried in
a separate TLS extension, they are not part of the cert chain.

But one can, for example, imagine a situation where a delegated
credential signed by the EE public key, is used in combination with
RFC7250 raw public keys... But for this to make sense, one would
still need something like KEMTLS to make it possible for the KEM
key to authenticate the handshake.

> My use case suggests (reasonably) long-term certificates, whose main
> difference from the traditional PKI for TLS or IPsec is that they’re
> used in implicit authentication, rather than for generating dynamic
> signatures during the handshake.

The main difficulty is that, as X.509 certs, verified in the usual way,
these would need to be issued by a trusted CA, whereas CAs willing to
issue KEM certs are pretty thin on the ground. With designs like
delegated credentials the EE key holder can mint their own.

This may not be a concern in your use-case, your mileage may vary...

> Perhaps, I need to understand “delegated credentials” better. Though
> there’d be a question of whether my infrastructure is ready and
> willing to embrace that concept, and the workflows it would require…

They're lightweight assertions that the key in the credential is
authorised to act on behalf of the signing EE cert key holder. They can
be issued by the EE key holder without involving any 3rd-party CA.

They require protocol support, the TLS extension needs to be implemented
on both ends.

--
Viktor.

Viktor Dukhovni

unread,
Dec 29, 2024, 4:03:07 PM12/29/24
to openss...@openssl.org
On Sun, Dec 29, 2024 at 08:12:45PM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> I’m getting a very confusing problem: when I invoke “openssl” from the
> Makefile by “make”, it fails. But when I copy exactly the same command
> line into a Terminal (aka, shell), it works perfectly fine:

Makefiles run /bin/sh, while your terminal may run bash or zsh, ...
There may also be differences in your PATH, environment, etc. and
then of course which providers are loaded...

> openssl genpkey -algorithm mlkem1024 -outform PEM -out prkey-kem.pem -outpubkey pubkey-kem.pem

Once OpenSSL 3.5 is released, that'll be ML-KEM-1024, we'll be using the
NIST names for the algorithms. Only the TLS groups will be hyphen-free.

> Error initializing mlkem1024 context
> C0642D48F87F0000:error:0308010C:digital envelope
> routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global
> default library context, Algorithm (mlkem1024 : 0), Properties
> (<null>) make: *** [gen_kem_keys] Error 1

The algorithm was not found in any provider.


> $ openssl genpkey -algorithm mlkem1024 -outform PEM -out prkey-kem.pem -outpubkey pubkey-kem.pem

This time the algorithm was found. The Makefile may be runnign a
different OpenSSL command-line utility.

> What’s wrong???

This sort of question is just basic development tooling, not really
OpenSSL-specific. Ideally you'd do the root cause analysis yourself and
come to the list with actual OpenSSL questions. :-)

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 9:53:34 PM12/29/24
to openss...@openssl.org

Guilty as charged. 😉

Though I’m pretty sure I will watch the recording later.

 

[from another post]

Once OpenSSL 3.5 is released, that'll be ML-KEM-1024, we'll be using the
NIST names for the algorithms.  Only the TLS groups will be hyphen-free.

 

Now I’m getting PQ algorithms from the OQS provider available from Open Quantum Safe. Does the above mean that once OpenSSL 3.5 is released, I won’t need to use an extra provider, and OQS provider would be included in the standard distribution? Making the “outside” provider I’m currently using – obsolete?


> Perhaps you could clue me in regarding “(untrusted)” in the above?

The "untrusted" (not a priori trusted) certificates were not from the
trust store, I think I mentioned this during the presentation.

 

I’ll hold off my questions about this part until I watch the presentation then. I guess, merely stating “-trusted some_ca_cert.pem” on the command line isn’t going to cut it…

 

> My use case suggests (reasonably) long-term certificates, whose main
> difference from the traditional PKI for TLS or IPsec is that they’re
> used in implicit authentication, rather than for generating dynamic
> signatures during the handshake.

The main difficulty is that, as X.509 certs, verified in the usual way,
these would need to be issued by a trusted CA, whereas CAs willing to
issue KEM certs are pretty thin on the ground.  With designs like
delegated credentials the EE key holder can mint their own.

 

Yes, quite right. But I expect this problem to be “resolvable” in my use case, at least when this actually gets deployed in the field. As I’m not the only one who needs to certify ML-KEM keys. 😉


This may not be a concern in your use-case, your mileage may vary...

 

Well, it is  a concern – but I’m not a lone DonQuixote fighting an uphill battle against the current PKI. 😉


> Perhaps, I need to understand “delegated credentials” better. . . .


They're lightweight assertions that the key in the credential is
authorised to act on behalf of the signing EE cert key holder.  They can
be issued by the EE key holder without involving any 3rd-party CA.

They require protocol support, the TLS extension needs to be implemented
on both ends.

 

Understood. Excellent, thank you!!

 

Viktor Dukhovni

unread,
Dec 29, 2024, 11:38:03 PM12/29/24
to openss...@openssl.org
On Mon, Dec 30, 2024 at 02:53:24AM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> > Once OpenSSL 3.5 is released, that'll be ML-KEM-1024, we'll be using the
> > NIST names for the algorithms. Only the TLS groups will be hyphen-free.
>
> Now I’m getting PQ algorithms from the OQS provider available from
> Open Quantum Safe
> <https://github.com/open-quantum-safe/oqs-provider.git>. Does the
> above mean that once OpenSSL 3.5 is released, I won’t need to use an
> extra provider, and OQS provider would be included in the standard
> distribution? Making the “outside” provider I’m currently using –
> obsolete?

We won't in fact bundle the OQS provider, rather it won't be needed,
because we'll ship an integrated ML-KEM, Hybrids for TLS and ML-DSA
implementation in the OpenSSL default provider (and at some point also
the FIPS provider). The ML-KEM and related TLS hybrids are working
already, but still need some reviews and some polish of the error
reporting, which is in some places still a bit skimpy.

> > The "untrusted" (not a priori trusted) certificates were not from the
> > trust store, I think I mentioned this during the presentation.
>
> I’ll hold off my questions about this part until I watch the
> presentation then. I guess, merely stating “-trusted some_ca_cert.pem”
> on the command line isn’t going to cut it…

There's nothing to do here, if you believe that something needs to be
done to make these not show up, you're quire mistaken, the verification
succeeded, just pretend you did not see those "untrusted" markers, they
can be useful diagnostics if you know what they mean, but can be safely
ignored.

The only time you won't see "untrusted" is when the certificate you're
verifying is one of the ones from your trust store, that's not a common
thing to need/want to do. Usually you're verifying certificates
ultimately issued by some trust-anchor, but that are not themselves
trust anchors.

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 29, 2024, 11:50:29 PM12/29/24
to openss...@openssl.org, openss...@openssl.org
That’s great to hear, thanks! Do you know roughly when 3.5.0 is planned for release?

Also, I know that many people here want Hybrids. My use case, however, requires “pure” ML-KEM and ML-DSA. Will they be available in 3.5? Both directly (like in the CLI examples you showed) and in TLS?

Thank you very much! And enjoy the Holidays!

Regards,
Uri

Secure Resilient Systems and Technologies
MIT Lincoln Laboratory

> On Dec 29, 2024, at 23:38, Viktor Dukhovni <openss...@dukhovni.org> wrote:
>
> !-------------------------------------------------------------------|
> This Message Is From an External Sender
> This message came from outside the Laboratory.
> |-------------------------------------------------------------------!
>
> --
> You received this message because you are subscribed to the Google Groups "openssl-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.
> To view this discussion visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/Z3IjoEJoVnXbZO00%40chardros.imrryr.org.

Viktor Dukhovni

unread,
Dec 30, 2024, 9:05:29 AM12/30/24
to openss...@openssl.org
On Mon, Dec 30, 2024 at 04:50:18AM +0000, Blumenthal, Uri - 0553 - MITLL wrote:

> That’s great to hear, thanks! Do you know roughly when 3.5.0 is
> planned for release?

Rumour has it that a release is slated circa April '25, or more
generally ~every 6 months.

> Also, I know that many people here want Hybrids. My use case, however,
> requires “pure” ML-KEM and ML-DSA. Will they be available in 3.5? Both
> directly (like in the CLI examples you showed) and in TLS?

You mean something like this (run directly from a build in the source tree):

$ runserver=(./apps/openssl s_server -tls1_3 -groups MLKEM768 -accept 12345 \
-cert test/certs/ee-cert.pem -key test/certs/ee-key.pem \
-cert_chain test/certs/ca-cert.pem -brief)

$ ./util/wrap.pl "${runserver[@]}"
Protocol version: TLSv1.3
Client cipher list: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
Ciphersuite: TLS_AES_256_GCM_SHA384
Signature Algorithms: RSA-PSS+SHA256
No peer certificate or raw public key
Supported groups: MLKEM768

[ Meanwhile in another interactive shell) ]

$ runclient=(./apps/openssl s_client -tls1_3 -groups MLKEM768 -connect localhost:12345 \
-sigalgs RSA-PSS+SHA256 -CAfile test/certs/root-cert.pem -servername server.example \
-verify_hostname server.example -brief)

$ ./util/wrap.pl "${runclient[@]}"
Connecting to ::1
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=server.example
Hash used: SHA256
Signature type: RSA-PSS
Verification: OK
Verified peername: server.example
Negotiated TLS1.3 group: MLKEM768

[ Sigalgs restricted just to keep the output less noisy ]

> Thank you very much! And enjoy the Holidays!

Perfect opportunity to get a lot of code written...

Unsurprisingly, the non-hybrid ML-KEM got done first, and the hybrids
are next in the review pipeline...

--
Viktor.

Blumenthal, Uri - 0553 - MITLL

unread,
Dec 30, 2024, 9:47:59 AM12/30/24
to openss...@openssl.org

> That’s great to hear, thanks! Do you know roughly when 3.5.0 is
> planned for release?

Rumour has it that a release is slated circa April '25, or more
generally ~every 6 months.

 

Great, thanks!


> Also, I know that many people here want Hybrids. My use case, however,
> requires “pure” ML-KEM and ML-DSA. Will they be available in 3.5? Both
> directly (like in the CLI examples you showed) and in TLS?

You mean something like this (run directly from a build in the source tree):

    $ runserver=(./apps/openssl s_server -tls1_3 -groups MLKEM768 -accept 12345 \
        -cert test/certs/ee-cert.pem -key test/certs/ee-key.pem \
        -cert_chain test/certs/ca-cert.pem -brief)

                 .  .  .  .  .

 

Yes, pretty much that.


> Thank you very much! And enjoy the Holidays!

Perfect opportunity to get a lot of code written...

 

Indeed!

😃


Unsurprisingly, the non-hybrid ML-KEM got done first, and the hybrids
are next in the review pipeline...

 

I for one am happy about that timing/sequencing.

 

Thanks!

Reply all
Reply to author
Forward
0 new messages