Skip to content

Commit

Permalink
Share reversal for x25519_mlkem*
Browse files Browse the repository at this point in the history
Signed-off-by: Basil Hess <[email protected]>
  • Loading branch information
bhess committed Sep 19, 2024
1 parent 4db09a9 commit f0b6310
Show file tree
Hide file tree
Showing 9 changed files with 553 additions and 255 deletions.
3 changes: 3 additions & 0 deletions oqs-template/generate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ kems:
# KEM prefix 2.16.840.1.101.3.4.4.
-
family: 'ML-KEM'
fips_standard: 1
name_group: 'mlkem512'
# code point not standardized: Why? XXX
nid: '0x024A'
Expand All @@ -167,6 +168,7 @@ kems:
nid: '0x2FB6'
-
family: 'ML-KEM'
fips_standard: 1
name_group: 'mlkem768'
# https://www.ietf.org/archive/id/draft-connolly-tls-mlkem-key-agreement-01.html
nid: '0x0768'
Expand All @@ -188,6 +190,7 @@ kems:
nid: '4587'
-
family: 'ML-KEM'
fips_standard: 1
name_group: 'mlkem1024'
# https://www.ietf.org/archive/id/draft-connolly-tls-mlkem-key-agreement-01.html
nid: '0x1024'
Expand Down
12 changes: 6 additions & 6 deletions oqs-template/oqsprov/oqs_kmgmt.c/keymgmt_constructors.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,37 @@
{%- set count.val = count.val + 1 %}
static void *{{variant['name']}}_new_key(void *provctx)
{
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{variant['name']}}", KEY_TYPE_SIG, NULL, {{variant['security']}}, {{ count.val }});
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{variant['name']}}", KEY_TYPE_SIG, NULL, {{variant['security']}}, {{ count.val }}, 0);
}

static void *{{variant['name']}}_gen_init(void *provctx, int selection)
{
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{variant['name']}}", 0, {{variant['security']}}, {{ count.val }});
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{variant['name']}}", 0, {{variant['security']}}, {{ count.val }}, 0);
}

{%- for classical_alg in variant['mix_with'] %}
{%- set count.val = count.val + 1 %}
static void *{{ classical_alg['name'] }}_{{variant['name']}}_new_key(void *provctx)
{
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, NULL, {{variant['security']}}, {{ count.val }});
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, NULL, {{variant['security']}}, {{ count.val }}, 0);
}

static void *{{ classical_alg['name'] }}_{{variant['name']}}_gen_init(void *provctx, int selection)
{
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, {{variant['security']}}, {{ count.val }});
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, {{variant['security']}}, {{ count.val }}, 0);
}

{%- endfor -%}
{%- for composite_alg in variant['composite'] %}
{%- set count.val = count.val + 1 %}
static void *{{ variant['name'] }}_{{ composite_alg['name'] }}_new_key(void *provctx)
{
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, NULL, {{composite_alg['security']}}, {{ count.val }});
return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, NULL, {{composite_alg['security']}}, {{ count.val }}, 0);
}

static void *{{ variant['name'] }}_{{ composite_alg['name'] }}_gen_init(void *provctx, int selection)
{
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, {{composite_alg['security']}}, {{ count.val }});
return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ variant['name'] }}_{{ composite_alg['name'] }}", KEY_TYPE_CMP_SIG, {{composite_alg['security']}}, {{ count.val }}, 0);
}

{%- endfor -%}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ MAKE_KEM_KEYMGMT_FUNCTIONS({{kem['name_group']}}, {{kem['oqs_alg']}}, {{kem['bit
{% if hybrid['hybrid_group'].startswith('p') -%}
MAKE_KEM_ECP_KEYMGMT_FUNCTIONS({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{kem['oqs_alg']}}, {{hybrid['bit_security']}})
{%- else %}
MAKE_KEM_ECX_KEYMGMT_FUNCTIONS({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{kem['oqs_alg']}}, {{hybrid['bit_security']}})
MAKE_KEM_ECX_KEYMGMT_FUNCTIONS({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{kem['oqs_alg']}}, {{hybrid['bit_security']}}, {% if 'fips_standard' in kem %}{{kem['fips_standard']}}{% else %}0{% endif %})
{%- endif %}
{%- endfor %}
{%- endfor %}
Expand Down
105 changes: 68 additions & 37 deletions oqsprov/oqs_hyb_kem.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static int oqs_evp_kem_encaps_keyslot(void *vpkemctx, unsigned char *ct,

// Free at err:
EVP_PKEY_CTX *ctx = NULL, *kgctx = NULL;
;

EVP_PKEY *pkey = NULL, *peerpk = NULL;
unsigned char *ctkex_encoded = NULL;

Expand Down Expand Up @@ -153,37 +153,53 @@ static int oqs_hyb_kem_encaps(void *vpkemctx, unsigned char *ct, size_t *ctlen,
unsigned char *secret, size_t *secretlen) {
int ret = OQS_SUCCESS;
const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
size_t secretLen0 = 0, secretLen1 = 0;
size_t ctLen0 = 0, ctLen1 = 0;
unsigned char *ct0, *ct1, *secret0, *secret1;

ret = oqs_evp_kem_encaps_keyslot(vpkemctx, NULL, &ctLen0, NULL, &secretLen0,
0);
const OQSX_KEY *oqsx_key = pkemctx->kem;
size_t secretLenClassical = 0, secretLenPQ = 0;
size_t ctLenClassical = 0, ctLenPQ = 0;
unsigned char *ctClassical, *ctPQ, *secretClassical, *secretPQ;

ret = oqs_evp_kem_encaps_keyslot(vpkemctx, NULL, &ctLenClassical, NULL,
&secretLenClassical,
oqsx_key->reverse_share ? 1 : 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_encaps_keyslot(vpkemctx, NULL, &ctLen1, NULL, &secretLen1,
1);
ret =
oqs_qs_kem_encaps_keyslot(vpkemctx, NULL, &ctLenPQ, NULL, &secretLenPQ,
oqsx_key->reverse_share ? 0 : 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

*ctlen = ctLen0 + ctLen1;
*secretlen = secretLen0 + secretLen1;
*ctlen = ctLenClassical + ctLenPQ;
*secretlen = secretLenClassical + secretLenPQ;

if (ct == NULL || secret == NULL) {
OQS_KEM_PRINTF3("HYB KEM returning lengths %ld and %ld\n", *ctlen,
*secretlen);
return 1;
}

ct0 = ct;
ct1 = ct + ctLen0;
secret0 = secret;
secret1 = secret + secretLen0;
/* Rule: if the classical algorthm is not FIPS approved
but the PQ algorithm is: PQ share comes first
otherwise: classical share comes first
*/
if (oqsx_key->reverse_share) {
ctPQ = ct;
ctClassical = ct + ctLenPQ;
secretPQ = secret;
secretClassical = secret + secretLenPQ;
} else {
ctClassical = ct;
ctPQ = ct + ctLenClassical;
secretClassical = secret;
secretPQ = secret + secretLenClassical;
}

ret = oqs_evp_kem_encaps_keyslot(vpkemctx, ct0, &ctLen0, secret0,
&secretLen0, 0);
ret = oqs_evp_kem_encaps_keyslot(vpkemctx, ctClassical, &ctLenClassical,
secretClassical, &secretLenClassical,
oqsx_key->reverse_share ? 1 : 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

ret = oqs_qs_kem_encaps_keyslot(vpkemctx, ct1, &ctLen1, secret1,
&secretLen1, 1);
ret = oqs_qs_kem_encaps_keyslot(vpkemctx, ctPQ, &ctLenPQ, secretPQ,
&secretLenPQ,
oqsx_key->reverse_share ? 0 : 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

err:
Expand All @@ -195,39 +211,54 @@ static int oqs_hyb_kem_decaps(void *vpkemctx, unsigned char *secret,
size_t ctlen) {
int ret = OQS_SUCCESS;
const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
const OQSX_KEY *oqsx_key = pkemctx->kem;
const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;
const OQS_KEM *qs_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;

size_t secretLen0 = 0, secretLen1 = 0;
size_t ctLen0 = 0, ctLen1 = 0;
const unsigned char *ct0, *ct1;
unsigned char *secret0, *secret1;
size_t secretLenClassical = 0, secretLenPQ = 0;
size_t ctLenClassical = 0, ctLenPQ = 0;
const unsigned char *ctClassical, *ctPQ;
unsigned char *secretClassical, *secretPQ;

ret = oqs_evp_kem_decaps_keyslot(vpkemctx, NULL, &secretLen0, NULL, 0, 0);
ret = oqs_evp_kem_decaps_keyslot(vpkemctx, NULL, &secretLenClassical, NULL,
0, oqsx_key->reverse_share ? 1 : 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, NULL, &secretLen1, NULL, 0, 1);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, NULL, &secretLenPQ, NULL, 0,
oqsx_key->reverse_share ? 0 : 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

*secretlen = secretLen0 + secretLen1;
*secretlen = secretLenClassical + secretLenPQ;

if (secret == NULL)
return 1;

ctLen0 = evp_ctx->evp_info->length_public_key;
ctLen1 = qs_ctx->length_ciphertext;
ctLenClassical = evp_ctx->evp_info->length_public_key;
ctLenPQ = qs_ctx->length_ciphertext;

ON_ERR_SET_GOTO(ctLen0 + ctLen1 != ctlen, ret, OQS_ERROR, err);
ON_ERR_SET_GOTO(ctLenClassical + ctLenPQ != ctlen, ret, OQS_ERROR, err);

ct0 = ct;
ct1 = ct + ctLen0;
secret0 = secret;
secret1 = secret + secretLen0;
/* Rule: if the classical algorthm is not FIPS approved
but the PQ algorithm is: PQ share comes first
otherwise: classical share comes first
*/
if (oqsx_key->reverse_share) {
ctPQ = ct;
ctClassical = ct + ctLenPQ;
secretPQ = secret;
secretClassical = secret + secretLenPQ;
} else {
ctClassical = ct;
ctPQ = ct + ctLenClassical;
secretClassical = secret;
secretPQ = secret + secretLenClassical;
}

ret = oqs_evp_kem_decaps_keyslot(vpkemctx, secret0, &secretLen0, ct0,
ctLen0, 0);
ret = oqs_evp_kem_decaps_keyslot(
vpkemctx, secretClassical, &secretLenClassical, ctClassical,
ctLenClassical, oqsx_key->reverse_share ? 1 : 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, secret1, &secretLen1, ct1, ctLen1,
1);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, secretPQ, &secretLenPQ, ctPQ,
ctLenPQ, oqsx_key->reverse_share ? 0 : 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

err:
Expand Down
Loading

0 comments on commit f0b6310

Please sign in to comment.