Reduced combinations - #6
Conversation
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Update from upstream
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
…in those methods. Changed RSA depricated function. Added text to CHANGES.md (this needs enhancement) Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
… start of composite files. Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
Signed-off-by: feventura <felipe.ventura@entrust.com>
adding tests to reduced combinations branch
Signed-off-by: feventura <felipe.ventura@entrust.com>
|
|
||
| -- Taken from https://datatracker.ietf.org/doc/draft-ietf-lamps-pq-composite-sigs/ | ||
|
|
||
| sigAlgs OBJECT IDENTIFIER ::= { 1 3 6 1 5 5 7 6 } |
There was a problem hiding this comment.
That is actually "pkixAlgs", not "sigAlgs". For example, key exchanges and KEMs are also in the same arc.
https://www.iana.org/assignments/smi-numbers#smi-numbers-1.3.6.1.5.5.7.6
I suggest renaming this to "pkixAlgs". Also, if you're trying to be really efficient this arc is probably already defined somewhere in the openssl includes (but maybe it's just easier to define it fresh here).
| if (key->classic_key == NULL) | ||
| return 0; | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
This function seems unintuitive to me and is probably worth a header comment.
(Part of my problem is that I don't know what openssl ossl_ml_dsa_key_has is, but a quick Google AI search tells me that this is checking for the ML-DSA private key in Full, Seed, or Both mode).
Will a composite key ever have the ML-DSA component in Full or Both mode? Or only ever Seed?
| if (key->classic_key == NULL) | ||
| return ml_dsa_len; // if there is not classic key, composite is malformed | ||
| return ml_dsa_len + (size_t)((EVP_PKEY_get_bits(key->classic_key) + 7) / 8); | ||
| } |
There was a problem hiding this comment.
I know from the reference implementation that the RSA and EC public keys can change their length by one or two bytes (I think, depending on leading zeros, which get truncated in the DER encoding). You also need to account for the DER length tags in the classic component.
Is this code actually counting the encoded length, or is it assuming a maximum length? It looks like EVP_PKEY_get_bits is the maximum size that you could ever need for a buffer for this.
If that's the case, that the size_t returned from ossl_composite_key_get_pub_len might actually be longer than the key it contains, then you should say that in the header comment.
| /* | ||
| * Security bits of the composite = minimum of ML-DSA collision strength and | ||
| * the classic component's security bits. | ||
| */ |
There was a problem hiding this comment.
That's a bit of a weird way to measure the security strength of a composite. In the draft, we tried very hard to not do this because it's rather difficult to compare the security of PQ and classical algs.
Is this as function that you're required to implement in order for the EVP APIs to work correctly? If you deleted this function, does anything break?
| return 1; | ||
| } | ||
|
|
||
| static int composite_validate(const void *keydata, int selection, |
There was a problem hiding this comment.
This might be my unfamiliarity with openssl, but what is this validating? That the public keys and private keys match? It's not validating a signature.
It's probably worth adding a header comment.
(also, maybe there is a header file somewhere that declares these functions, and there's a comment on that?)
| */ | ||
| static const COMPOSITE_ALG_INFO composite_alg_table[] = { | ||
| /* name, label, oid, oid_sz, prehash, phlen, classic_hash, | ||
| classic_type, pss_salt_len, mgf1_hash */ |
There was a problem hiding this comment.
This is excellent and shows that you're ready for the RSA-PSS stuff, even though it's not in this PR.
| uint8_t *out) | ||
| { | ||
| return EVP_Q_digest(libctx, info->prehash_alg, NULL, msg, msg_len, out, NULL); | ||
| } |
There was a problem hiding this comment.
I'm not super convinced that a single-line helper function is all that helpful, but that's really a nit-pick.
| *siglen = ml_dsa_sig_max | ||
| + (size_t)EVP_PKEY_get_size(ctx->key->classic_key); | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
I think this needs to be a bit careful here because, as I understand this, this will return a max length, not necessarily the exact length.
That should be noted in the comment here for future maintainers, and check that this is only used for sizing buffers, which are ok to be oversized and contain some trailing un-used bytes, and nothing is expecting this to be an exact length.
| } | ||
|
|
||
| return 1; | ||
| } |
There was a problem hiding this comment.
Would it be better to pre-compute the DER strings and hard-code them as hex, rather than having this code?
"Better" in the sense that it's easier to code review?
| { | ||
| ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
These could be implemented, right?
If I am guessing correctly at what these are supposed to do, they could be supported.
_init() would need to initialize the composite PH, each chunk of message handed into _update() would be fed into that hash, and _final() would finish the PH, construct the M' and finish the operation.
You might find it easier to refactor so that you have a composite_sign_ph() and composite_verify_ph() as a shared building block between the streaming and one-shot functions.
Moreover, it would be worth exposing the composite_sign_ph() externally to openssl because calling applications may want to pre-compute the PH themselves (for example on another machine so that you only need to send the hash value, and not the whole message, over the network).
I think these are definitely worth implementing.
This PR was created to facilitate the identification of the changes made to implement composite signatures and certificates.
This branch only contains: