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”
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,
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.
To view this discussion visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/Z3C9LzrQL4COcVP7%40chardros.imrryr.org.
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
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!
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!
> 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!!
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.
> > 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.
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!!
> 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!