open-quantum-safe / oqs-provider

OpenSSL 3 provider containing post-quantum algorithms
https://openquantumsafe.org
MIT License
228 stars 88 forks source link

Generate a Kyber Certificate #450

Closed xianglingzhang closed 3 months ago

xianglingzhang commented 3 months ago

Hi,

How to generate a Kyber certificate containing a Kyber public key? I think OQS-provider can only generate a Dilithium certificate, but I need to create a CSR for a key pair whose algorithm does not allow signing (like Kyber). How to do it?

baentsch commented 3 months ago

Hmm -- isn't a CSR a digitally signed data structure? How should that work with an algorithm that cannot sign? Which spec are you referring to with this request?

xianglingzhang commented 3 months ago

Hi,

I have generated a certificate for a Kyber public key, it is signed by a Dilithium private key. The certificate generator is in another project. As far as I know, this project does not support this kind of certificate.

Now that I already have the Kyber certificate, how to add support in OQS-OpenSSL to parse it? Can you give me some advice? Thanks a lot.

baentsch commented 3 months ago

Please point to the "other project" used to generate the cert. That way I could try to understand the spec and data structure you want to use here.

xianglingzhang commented 3 months ago

kemtls-experiment

The mk-cert/encoder.py is used to generate the cert. rustls/test-ca/kyber has the prepared certificates.

baentsch commented 3 months ago

Ahh, now I understand; thanks for the pointer @xianglingzhang .

The answer then is: This is not possible: oqsprovider is an openssl provider implementing standards that are defined and published. KEMTLS AFAIK is not (correct @thomwiggers @dstebila ? Closing the issue until hearing differently from you).

Hence, such cert can neither be created nor operated with oqsprovider/openssl.

thomwiggers commented 3 months ago

You can still generate a certificate with any public key algorithm that OpenSSL supports by using the OpenSSL x509 command's -force_pubkey option, but that takes some extra steps: https://security.stackexchange.com/a/82868

baentsch commented 3 months ago

You can still generate a certificate with any public key algorithm that OpenSSL supports by using the OpenSSL x509 command's -force_pubkey option, but that takes some extra steps: https://security.stackexchange.com/a/82868

Thanks for the pointer @thomwiggers . But the resultant cert can't be used operationally in TLS afterwards, right? Or is KEMTLS implemented in OpenSSL?

thomwiggers commented 3 months ago

Not in standard TLS, no, but I believe OP wants to experiment with implementing it.

baentsch commented 3 months ago

Thanks for the re-confirmation. For my personal education, what/who is "OP"? And would this experimentation entail using the provider interface?

thomwiggers commented 3 months ago

OP: original poster; it's forum lingo

No, that would require messing with OpenSSL internals.

xianglingzhang commented 3 months ago

Yes, I am interested in implementing KEMTLS in OpenSSL.

You can still generate a certificate with any public key algorithm that OpenSSL supports by using the OpenSSL x509 command's -force_pubkey option, but that takes some extra steps: https://security.stackexchange.com/a/82868

I have tried this, and it can be successful with a DH cert, but OpenSSL does not support genpkey with Kyber.

$ openssl genpkey -provider default -provider oqsprovider -out ../test/kyber512.pem -algorithm kyber512
Error writing key(s)
40670F48A17F0000: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?
40670F48A17F0000:error:04800073:PEM routines:do_pk8pkey:error converting private key:crypto/pem/pem_pk8.c:133:

So I try to let OpenSSL recognize the certificate needed by KEMTLS. The following are certificates generated by OpenSSL (left) and kemtls-experiment (right). They are both signed by Dilithium2, but they don't share the same signature OID. I think this is the reason why OpenSSL can't operate it. And the right certificate contains a Kyber public key, so the public key OID stands for Kyber512, which can't be recognized either. Can I do something about this?

Snipaste_2024-08-01_14-39-23

baentsch commented 3 months ago

but OpenSSL does not support genpkey with Kyber.

This is incorrect. What you want is the capability to encode Kyber PKeys. This is not active by default: Be sure to set the required cmake config variable when building oqsprovider and the command openssl genpkey -provider default -provider oqsprovider -out ../test/kyber512.pem -algorithm kyber512 will execute without error (test command is the standard openssl list -encoders app). But that then still won't allow you to run KEMTLS as that logic simply is not present in openssl as per @thomwiggers .

thomwiggers commented 3 months ago

Oids are not synchronized between my implementations and OQS (which I only use for the crypto primitives). You will need to adjust either to match the other.

thomwiggers commented 3 months ago

Note that there are no "official" OIDs yet anyway, so neither project is using the "wrong" oids.

xianglingzhang commented 3 months ago

This is not active by default: Be sure to set the required cmake config variable when building oqsprovider

I build oqsprovider with

$ cmake -S . -B _build -DUSE_ENCODING_LIB=ON

and

$ cmake --build _build
[  2%] Creating directories for 'encoder'
[  5%] Performing download step (git clone) for 'encoder'
Cloning into 'encoder'...
Already on 'main'
[  7%] Performing disconnected update step for 'encoder'
[ 10%] No patch_disconnected step for 'encoder'
[ 12%] Performing configure step for 'encoder'
-- The C compiler identification is GNU 11.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/rh/devtoolset-11/root/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/zxl/KEMTLS/oqs-provider/_build/oqsprov/encoder-prefix/src/encoder-build
[ 15%] Performing build step for 'encoder'
[ 10%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_qsc.c.o
[ 20%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_kyber.c.o
[ 30%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_dilithium.c.o
[ 40%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_falcon.c.o
[ 50%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_sphincsplus.c.o
[ 60%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_asn1.c.o
[ 70%] Linking C static library libqsc_key_encoder.a
[ 70%] Built target qsc_key_encoder
[ 80%] Building C object test/CMakeFiles/qsc_key_encoder_test.dir/test.c.o
[ 90%] Building C object test/CMakeFiles/qsc_key_encoder_test.dir/test_kat_endec.c.o
[100%] Linking C executable qsc_key_encoder_test
[100%] Built target qsc_key_encoder_test
[ 17%] Performing install step for 'encoder'
[ 70%] Built target qsc_key_encoder
[100%] Built target qsc_key_encoder_test
Install the project...
-- Install configuration: "Release"
-- Installing: /home/zxl/KEMTLS/oqs-provider/_build/install/lib/libqsc_key_encoder.a
-- Installing: /home/zxl/KEMTLS/oqs-provider/_build/install/include/qsc_encoding.h
[ 20%] Completed 'encoder'
[ 20%] Built target encoder
[ 23%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov.c.o
[ 25%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_capabilities.c.o
[ 28%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_keys.c.o
/home/zxl/KEMTLS/oqs-provider/oqsprov/oqsprov_keys.c:193:18: error: ‘OQS_SIG_alg_mayo_1’ undeclared here (not in a function); did you mean ‘OQS_SIG_alg_count’?
  193 |     {0, "mayo1", OQS_SIG_alg_mayo_1, KEY_TYPE_SIG, 128},
      |                  ^~~~~~~~~~~~~~~~~~
      |                  OQS_SIG_alg_count
/home/zxl/KEMTLS/oqs-provider/oqsprov/oqsprov_keys.c:195:18: error: ‘OQS_SIG_alg_mayo_2’ undeclared here (not in a function); did you mean ‘OQS_SIG_alg_count’?
  195 |     {0, "mayo2", OQS_SIG_alg_mayo_2, KEY_TYPE_SIG, 128},
      |                  ^~~~~~~~~~~~~~~~~~
      |                  OQS_SIG_alg_count
/home/zxl/KEMTLS/oqs-provider/oqsprov/oqsprov_keys.c:197:18: error: ‘OQS_SIG_alg_mayo_3’ undeclared here (not in a function); did you mean ‘OQS_SIG_alg_count’?
  197 |     {0, "mayo3", OQS_SIG_alg_mayo_3, KEY_TYPE_SIG, 192},
      |                  ^~~~~~~~~~~~~~~~~~
      |                  OQS_SIG_alg_count
/home/zxl/KEMTLS/oqs-provider/oqsprov/oqsprov_keys.c:199:18: error: ‘OQS_SIG_alg_mayo_5’ undeclared here (not in a function); did you mean ‘OQS_SIG_alg_count’?
  199 |     {0, "mayo5", OQS_SIG_alg_mayo_5, KEY_TYPE_SIG, 256},
      |                  ^~~~~~~~~~~~~~~~~~
      |                  OQS_SIG_alg_count
gmake[2]: *** [oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_keys.c.o] Error 1
gmake[1]: *** [oqsprov/CMakeFiles/oqsprovider.dir/all] Error 2
gmake: *** [all] Error 2

but I got this error @baentsch

xianglingzhang commented 3 months ago

Oids are not synchronized between my implementations and OQS (which I only use for the crypto primitives). You will need to adjust either to match the other.

I see, thanks : )

xianglingzhang commented 3 months ago

Oh, I tried to build with oqs-provider-0.6.1, I got this

$ cmake --build _build
[  2%] Creating directories for 'encoder'
[  5%] Performing download step (git clone) for 'encoder'
Cloning into 'encoder'...
Already on 'main'
[  7%] Performing disconnected update step for 'encoder'
[ 10%] No patch_disconnected step for 'encoder'
[ 12%] Performing configure step for 'encoder'
-- The C compiler identification is GNU 11.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/rh/devtoolset-11/root/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done (0.5s)
-- Generating done (0.0s)
-- Build files have been written to: /home/zxl/oqs-provider-0.6.1/_build/oqsprov/encoder-prefix/src/encoder-build
[ 15%] Performing build step for 'encoder'
[ 10%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_qsc.c.o
[ 20%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_kyber.c.o
[ 30%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_dilithium.c.o
[ 40%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_falcon.c.o
[ 50%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_sphincsplus.c.o
[ 60%] Building C object CMakeFiles/qsc_key_encoder.dir/src/encoding_asn1.c.o
[ 70%] Linking C static library libqsc_key_encoder.a
[ 70%] Built target qsc_key_encoder
[ 80%] Building C object test/CMakeFiles/qsc_key_encoder_test.dir/test.c.o
[ 90%] Building C object test/CMakeFiles/qsc_key_encoder_test.dir/test_kat_endec.c.o
[100%] Linking C executable qsc_key_encoder_test
[100%] Built target qsc_key_encoder_test
[ 17%] Performing install step for 'encoder'
[ 70%] Built target qsc_key_encoder
[100%] Built target qsc_key_encoder_test
Install the project...
-- Install configuration: "Release"
-- Installing: /home/zxl/oqs-provider-0.6.1/_build/install/lib/libqsc_key_encoder.a
-- Installing: /home/zxl/oqs-provider-0.6.1/_build/install/include/qsc_encoding.h
[ 20%] Completed 'encoder'
[ 20%] Built target encoder
[ 23%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov.c.o
[ 25%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_capabilities.c.o
[ 28%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_keys.c.o
[ 30%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_kmgmt.c.o
[ 33%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_sig.c.o
[ 35%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_kem.c.o
[ 38%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_encode_key2any.c.o
[ 41%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_endecoder_common.c.o
[ 43%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_decode_der2key.c.o
[ 46%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_bio.c.o
[ 48%] Linking C shared module ../lib/oqsprovider.so
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: ../install/lib/libqsc_key_encoder.a(encoding_qsc.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: ../install/lib/libqsc_key_encoder.a(encoding_kyber.c.o): warning: relocation in read-only section `.rodata'
collect2: error: ld returned 1 exit status
gmake[2]: *** [lib/oqsprovider.so] Error 1
gmake[1]: *** [oqsprov/CMakeFiles/oqsprovider.dir/all] Error 2
gmake: *** [all] Error 2

add add_compile_options(-fpic) in the CMakeLists.txt doesn't help @baentsch.

baentsch commented 3 months ago

Please create a full bug report detailing your setup so we do not (wrongly) guess your dev setup. Most efficient would be to use an OS like Ubuntu as we're using for development & CI.