Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add de-randomized ML-KEM modes to experimental EVP API #1578

Merged
merged 19 commits into from
Jun 19, 2024

Conversation

jakemas
Copy link
Contributor

@jakemas jakemas commented May 7, 2024

Issues:

This is a PR in which we are adding de-randomized modes for ML-KEM. These changes will provide customers with the ability to independently assess the correctness of our ML-KEM implementation through a public API, as well as facilitate upcoming ACVP test vectors (FIPS). These APIs also facilitate the use of ML-KEM in schemes/primitives such as Hybrid Public Key Encryption (HPKE RFC 9180), Messaging Layer Security (MLS RFC 9420), X-Wing (draft-connolly-cfrg-xwing-kem), and batch/multi-recipient KEM

Description of changes:

Today, the KEM API in AWS-LC does not support de-randomized/deterministic modes. As such, known answer testing (KAT) can be difficult to perform. Currently, AWS-LC uses pq_custom_randombytes to seed, and control internal entropy for testing.

As part of the standardisation of ML-KEM in FIPS 203, NIST are outlining the use of de-randomized modes. This PR hooks up the de-randomized APIs for ML-KEM with an experimental EVP APIs EVP_PKEY_keygen_deterministic and EVP_PKEY_encapsulate_deterministic within include/openssl/experimental.

Call-outs:

This is the first in a series of PRs. The overall plan is:

  • Add changes to AWS-LC KEM APIs and methods to allow for de-randomized keygen and encapsulation for ML-KEM ( complete: PR 91ca50f)
  • Make the same changes for kyber (pqcrystals_kyber_ref_common). (complete:1ad9a97)
  • Re-generate KATs to output coins instead of seed, we can then remove pq_custom_randombytes from kyber/ml-kem completely. (complete:1ad9a97 and 333911c) (can't remove completely from the library yet as they are required for dilithium KAT)

Testing:

Testing has been added for de-randomized modes within crypto/evp_extra/evp_extra_test.cc.

The testing function is not final, but tests functionality added within this PR. Once subsequent PRs are added, the testing procedure will be condensed with the rest of the KEM tests.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@jakemas jakemas requested a review from a team as a code owner May 7, 2024 18:10
@codecov-commenter
Copy link

codecov-commenter commented May 13, 2024

Codecov Report

Attention: Patch coverage is 85.18519% with 24 lines in your changes missing coverage. Please review.

Project coverage is 78.16%. Comparing base (e7e64f8) to head (3578aee).

Files Patch % Lines
crypto/evp_extra/p_kem.c 76.92% 15 Missing ⚠️
crypto/fipsmodule/evp/evp_ctx.c 66.66% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1578      +/-   ##
==========================================
+ Coverage   78.15%   78.16%   +0.01%     
==========================================
  Files         562      562              
  Lines       94676    94825     +149     
  Branches    13576    13597      +21     
==========================================
+ Hits        73995    74122     +127     
- Misses      20084    20108      +24     
+ Partials      597      595       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jakemas
Copy link
Contributor Author

jakemas commented May 20, 2024

Note: combining into a single PR as per discussions with AWS-LC. The Call-Outs above have been modified to reflect this.

Copy link
Contributor

@dkostic dkostic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few comments inline. In general, the most important thing missing is adding the seed length as an input argument to the API and then adding a check that the provided length is correct.

Also, we should now be able to completely get rid of pq_custom_rand_bytes, right? If so, let's delete that code.

include/openssl/experimental/ml-kem.h Outdated Show resolved Hide resolved
include/openssl/experimental/ml-kem.h Outdated Show resolved Hide resolved
include/openssl/experimental/ml-kem.h Outdated Show resolved Hide resolved
include/openssl/experimental/ml-kem.h Outdated Show resolved Hide resolved
include/openssl/experimental/ml-kem.h Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
@jakemas
Copy link
Contributor Author

jakemas commented May 21, 2024

left a few comments inline. In general, the most important thing missing is adding the seed length as an input argument to the API and then adding a check that the provided length is correct.

Also, we should now be able to completely get rid of pq_custom_rand_bytes, right? If so, let's delete that code.

Thank you! 333911c addresses these call outs with the exception of how the seed_len checks will be implemented. As the size of the seed is KEM specific, we may want to add a size check call (as we do with |ciphertext_len| and |shared_secret_len| when calling EVP_PKEY_encapsulate with NULL values). This would allow the caller to get the correct size of seed for the KEM used.

crypto/dilithium/p_dilithium3.c Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
@jakemas jakemas requested review from andrewhop and dkostic June 3, 2024 21:14
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
Copy link
Contributor

@dkostic dkostic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few more minor comments.

Can we delete pq_custom_randombytes.{h|c} now?

crypto/evp_extra/evp_extra_test.cc Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
@jakemas
Copy link
Contributor Author

jakemas commented Jun 5, 2024

left a few more minor comments.

Can we delete pq_custom_randombytes.{h|c} now?

Not just yet, if enable_dilithium is on then it's still required for Dilithium KATs

dkostic
dkostic previously approved these changes Jun 6, 2024
@jakemas
Copy link
Contributor Author

jakemas commented Jun 10, 2024

For documentation purposes: the Kyber KAT files have been modified so that they output the values of the "coins" generated by the DRBG. These KATs can be generated from the official Kyber repository using kyber/ref/PQCgenKAT_kem.c(https://github.com/pq-crystals/kyber/blob/main/ref/PQCgenKAT_kem.c).

To modify the KAT generation file in the same way as I did to output the internal random coins, and thus, see the keygen_coins and encap_coins used to generate the KAT, apply the following patch to PQCgenKAT_kem.c, kem.c, andkem.h:
PQCgenKAT_kem.c.patch
kem.h.patch
kem.c.patch

crypto/evp_extra/p_kem.c Show resolved Hide resolved
crypto/evp_extra/p_kem.c Show resolved Hide resolved
crypto/evp_extra/p_kem.c Outdated Show resolved Hide resolved
crypto/evp_extra/p_kem.c Show resolved Hide resolved
crypto/fipsmodule/evp/evp_ctx.c Outdated Show resolved Hide resolved
crypto/kyber/kat/kyber1024r3.txt Outdated Show resolved Hide resolved
crypto/evp_extra/evp_extra_test.cc Outdated Show resolved Hide resolved
crypto/ml_kem/kat/mlkem512ipd.txt Outdated Show resolved Hide resolved
Comment on lines +119 to +135
*ciphertext_len = kem->ciphertext_len;
*shared_secret_len = kem->shared_secret_len;
*seed_len = kem->encaps_seed_len;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, all of these in/out sizes also need null checks before writing to them. Same for keygen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great call out, as the caller will use seed_len as a length check, better make it writable. Added test coverage also for these checks in fa6e270

dkostic
dkostic previously approved these changes Jun 18, 2024
@dkostic dkostic merged commit c65d98a into aws:main Jun 19, 2024
97 of 98 checks passed
dkostic pushed a commit that referenced this pull request Jul 30, 2024
NIST have made the following public statements regarding the planned
changes to FIPS 203:
- NIST will specify lower-level de-randomized API to enable CAVP testing
with seeds as keys.

As such, this PR includes the following:
- The addition of ML-KEM-IPD-768 and ML-KEM-IPD-1024 to AWS-LC. *Note*:
as common functionality is already added to aws-lc, this lift is
extremely light, as we need only to define
`crypto/ml_kem/ml_kem_768_ipd.c` and `crypto/ml_kem/ml_kem_1024_ipd.c`.
- The addition of de-randomized testing API for ML-KEM-IPD-768 and
ML-KEM-IPD-1024
- KATs for ML-KEM-IPD-768 and ML-KEM-IPD-1024 that use seeds as keys (as
per CAVP requirement)
- An update to the file that captures the divergence from the upstream
reference listed at
https://github.com/aws/aws-lc/tree/main/crypto/ml_kem#readme. This
removes the outdated information regarding `pq_custom_randombytes` and
updates with information regarding the de-randomized API.

The new KEM algorithms have been added to the `built_in_kems` list, and
as such, are included within the complete `PerKEMTest` suite. This
includes testing of the de-randomized APIs added in
#1578.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants