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

Expand Scope to include CMS #26

Open
johngray-dev opened this issue Jan 9, 2023 · 10 comments
Open

Expand Scope to include CMS #26

johngray-dev opened this issue Jan 9, 2023 · 10 comments

Comments

@johngray-dev
Copy link
Collaborator

  • Add support for CMS in the repo

  • Needs .zip file format update to include folders

  • output matrix needs to be updates

@dghgit
Copy link
Contributor

dghgit commented Jan 13, 2023

Here's a first attempt.

It's based on https://datatracker.ietf.org/doc/draft-ietf-lamps-kyber/

In the absence of any other OIDs I've used the following:

id-kem-trans 1.3.6.1.4.1.22554.5
id-kyber512 1.3.6.1.4.1.22554.5.6.1

No KDF is specified (KDF is set to NULL in GenericKemTransParameters, I've assumed the others resolve to AlgorithmIdentifier), key wrapping is done using AES-128 KWP.

The encrypted payload is the kyber certifcate (slowly working towards CMP). The kyber certificate can be verified using issuer_cert.pem which is a Dilithium certificate. Kyber public key has been encoded the same way we've been encoding Dilithium public keys (so value octets in the SubjectPublicKeyInfo BIT STRING).

The Kyber private key in a OneAsymmetricKey and has been encoded as: https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details.

KyberPrivateKey ::= SEQUENCE {
        version     INTEGER {v0(0)}   -- version (round 3)
        s           OCTET STRING,     -- EMPTY
        hpk         OCTET STRING      -- EMPTY
        nonce       OCTET STRING,     -- d
        publicKey   [0] IMPLICIT KyberPublicKey OPTIONAL,
 }

Here's the PEM files:

kyber_cms.zip

Questions:

  • is everyone happy with the OIDs? If so can we get them added to the oid_mapping,md file until some real ones are available, if not, would someone add the appropriate OIDs for the id-kem-trans and id-kyber512. If the OIDs are okay, id-kyber768 will be "1.3.6.1.4.1.22554.5.6.2" and id-kyber1024 will be "1.3.6.1.4.1.22554.5.6.3"
  • GenericKemTransParameters feels really odd at the moment, it does make sense that the kdf is the second entry, but I'd like to suggest that it gets flagged as OPTIONAL and gets written as:
   GenericKemTransParameters ::= {
       kem  KeyEncapsulationMechanism,
       kdf  [1] KeyDerivationFunction OPTIONAL,
       wrap KeyWrappingMechanism
   }

at the moment OPTIONAL would be enough as I can't really imagine the structure needing to change (I've generated a few different envelopes now, it seems to meet everything we currently try to do), that said experience has shown that my imagination is not always as wild as I think it is and that the extra flexibility that a tag provides might help in future.

Any questions or feedback, please let me know. Thanks.

@johngray-dev
Copy link
Collaborator Author

johngray-dev commented Jan 18, 2023 via email

@dghgit
Copy link
Contributor

dghgit commented Jan 18, 2023

So, this would also work. In some ways it's cleaner, while following the practice of RFC 5990 with truncating the encapsulation and the wrapped key works okay, it does assume that the encapsulation will always be some easily known length, I'd agree for these algorithms that may not be an assumption which will always stand up (and apart from anything, it does save people the problem of splitting things up and it may make it easier to deal with HSM that just implement the generic operations).

I think KDF should still be optional as well, With the RSA KEM you have to specify a KDF (the payload just being a big integer to use as a seed), but all the PQC KEMs already use one internally (at least as far as I can tell) - a KDF will only be necessary where the KEM's parameter set output doesn't match what's in kekLength, but where it does it's probably better to use the KEM as designed.

One other suggestion, at the risk of being pedantic, I think "kemct" should be called "kemenc" (KEM ENCapsulation). I've spent a bit of time explaining these algorithms to people now - for programmers with some familiarity of the domain encapsulation is a better term to use. When people hear the word "cipher text" they immediately think these things behave like RSA OAEP/PKCS1.5 - I think we really need to get people away from that. While it's true that some KEMs can be used like that, the security strengths of the different parameter sets rely in part on how the payload is managed and the core shared secret generation is done on that basis. Of course this is also true with RSA, but as it's not really enforced, and getting around it is easy, I've had people come to us with uses of RSA that are, to put it plainly, frightening. I'd feel better if we could put as much distance between the use of KEMs and RSA's concept of cipher text as possible, so avoiding the term cipher text seems like a good thing. My 2 cents worth.

@ounsworth
Copy link
Collaborator

ounsworth commented Jan 20, 2023 via email

@dghgit
Copy link
Contributor

dghgit commented Jan 20, 2023

a KDF will only be necessary where the KEM's parameter set output doesn't match what's in kekLength

To play devil's advocate, if it's too long, then you truncate. If it's too short then you should probably not just stretch it out cause it won't be full entropy; you should probably reject with an incompatible cipher suite error.

Yes, I'd be scratching my head if I saw someone using a 128 bit secure KEM as the source for a 256 bit AES key... as for going the other way, everything I've read tells me truncation should be fine as well. Still, I know what some people are like about KDFs, so I think it's worth having one as optional and I guess, RFC 5990 notwithstanding, being able to provide a KDF would make this RFC "RSA-style KEM" complete, as in the structure would cover the known KEM universe at that point.

@ounsworth
Copy link
Collaborator

We can make the KDF param OPTIONAL or nullable if we want to allow for cipher suites that omit the KDF.

@dghgit
Copy link
Contributor

dghgit commented Feb 17, 2023

Hi everyone,

So here's the new one, based on:

https://www.ietf.org/id/draft-housley-lamps-cms-kemri-01.html

I've used the following two made up OIDs:

id-ori-kem 1.3.6.1.4.1.22554.5

id-kyber512 1.3.6.1.4.1.22554.5.6.1

I gather there's no prize for guessing what id-ori-kem will be, it just seemed a bit rude of me to preempt it.

There's no UKM and after some consultation I've used SHAKE256_len as the KDF - as a dump given as:

                        DER Sequence
                            ObjectIdentifier(2.16.840.1.101.3.4.2.18)
                            Integer(256)

The key wrapping algorithm is AES256-WRAP with AES128-CBC being used for the encryption of the certificate.

Sample files, same setup as before are here:

kyber_cms.zip

I think it's correct, I can parse and validate it myself, so at least if it's wrong, I'm consistent if not correct. Anyway, any questions, thoughts, or comments, please let me know. Thanks.

PS. minor correction, found where I was consistently wrong, should be correct now.

@johngray-dev
Copy link
Collaborator Author

johngray-dev commented Feb 17, 2023 via email

@dghgit
Copy link
Contributor

dghgit commented Feb 19, 2023

Cheers. Never underestimate the ability of jetlag as a means to find time to work when all is quiet ;-) Yes, it's currently based on the BC adaption. With the JEP, I've actually contacted Max at Oracle about this as well, just to clarify exactly where in the mix they expect things like user-keying-material to be passed in.

Yep, this is the wrong year to give up caffeine...

@dghgit
Copy link
Contributor

dghgit commented Mar 8, 2023

Here's an update - the revision for RFC 5990 includes the official OID for the KEM type for OtherRecipientInfo. This version uses that OID and also creates an EnvelopedData object with the correct version number (should have been 3).

kyber_cms.zip

The files are generated using commented out code in the testKyberRequestWithDilithiumCA method of:

https://github.com/bcgit/bc-java/blob/master/pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants