Skip to content
New issue

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

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

Already on GitHub? # to your account

Update codeowners #458

Merged
merged 4 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners

* @baentsch
/oqsprov/oqs_hyb_kem.c @bhess
/oqs-template/generate.yml @baentsch @bhess @feventura
/CMakeLists.txt @baentsch @thb-sb
/.circleci/config.yml @baentsch @thb-sb
/.github/workflows @baentsch @thb-sb
/oqsprov/oqs_sig.c @baentsch @feventura
/scripts/oqsprovider-pkcs12gen.sh @iyanmv
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ All PRs should move to "Ready for Review" stage only if all CI tests pass (are g
The OQS core team is happy to provide feedback also to Draft PRs in order to improve
them before the final "Review" stage.

### CODEOWNERS

This file is used to track which contributors are most well suited for reviewing
changes to specific sections, typically because they authored part or all of them.
Thus, any PR should revisit and possibly update this file suitably.

### Coding style

This project has adopted the [OpenSSL coding style](https://www.openssl.org/policies/technical/coding-style.html).
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,16 @@ Team

Contributors to the `oqsprovider` include:

- Michael Baentsch
- Christian Paquin
- Richard Levitte
- Basil Hess
- Julian Segeth
- Alex Zaslavsky
- Will Childs-Klein
- Thomas Bailleux
- Felipe Ventura
- Iyán Méndez Veiga
- Michael Baentsch (initial author and maintainer; responsible for all code except as listed per specific contributions below)
- Christian Paquin (original OpenSSL111 OQS integrator)
- Richard Levitte (OpenSSL provider wizard and initial `cmake` setup)
- Basil Hess (hybrid KEM integration & pqcrystals/mayo OID management)
- Julian Segeth (some memory management improvements)
- Alex Zaslavsky (improvements on OpenSSL integration)
- Will Childs-Klein (improvements on Kyber hybrid OIDs)
- Thomas Bailleux (many build, CI and usage improvements for different platforms)
- Felipe Ventura (composite sig integration and OID management)
- Iyán Méndez Veiga (PKCS#12 testing)

History
-------
Expand Down
239 changes: 239 additions & 0 deletions oqsprov/oqs_hyb_kem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
// SPDX-License-Identifier: Apache-2.0 AND MIT

/*
* OQS OpenSSL 3 provider
*
* Hybrid KEM code.
*
*/

static OSSL_FUNC_kem_encapsulate_fn oqs_hyb_kem_encaps;
static OSSL_FUNC_kem_decapsulate_fn oqs_hyb_kem_decaps;

/// EVP KEM functions

static int oqs_evp_kem_encaps_keyslot(void *vpkemctx, unsigned char *ct,
size_t *ctlen, unsigned char *secret,
size_t *secretlen, int keyslot)
{
int ret = OQS_SUCCESS, ret2 = 0;

const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;

size_t pubkey_kexlen = 0;
size_t kexDeriveLen = 0, pkeylen = 0;
unsigned char *pubkey_kex = pkemctx->kem->comp_pubkey[keyslot];

// Free at err:
EVP_PKEY_CTX *ctx = NULL, *kgctx = NULL;
;
EVP_PKEY *pkey = NULL, *peerpk = NULL;
unsigned char *ctkex_encoded = NULL;

pubkey_kexlen = evp_ctx->evp_info->length_public_key;
kexDeriveLen = evp_ctx->evp_info->kex_length_secret;

*ctlen = pubkey_kexlen;
*secretlen = kexDeriveLen;

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

peerpk = EVP_PKEY_new();
ON_ERR_SET_GOTO(!peerpk, ret, -1, err);

ret2 = EVP_PKEY_copy_parameters(peerpk, evp_ctx->keyParam);
ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, err);

ret2 = EVP_PKEY_set1_encoded_public_key(peerpk, pubkey_kex, pubkey_kexlen);
ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, err);

kgctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL);
ON_ERR_SET_GOTO(!kgctx, ret, -1, err);

ret2 = EVP_PKEY_keygen_init(kgctx);
ON_ERR_SET_GOTO(ret2 != 1, ret, -1, err);

ret2 = EVP_PKEY_keygen(kgctx, &pkey);
ON_ERR_SET_GOTO(ret2 != 1, ret, -1, err);

ctx = EVP_PKEY_CTX_new(pkey, NULL);
ON_ERR_SET_GOTO(!ctx, ret, -1, err);

ret = EVP_PKEY_derive_init(ctx);
ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);

ret = EVP_PKEY_derive_set_peer(ctx, peerpk);
ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);

ret = EVP_PKEY_derive(ctx, secret, &kexDeriveLen);
ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);

pkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &ctkex_encoded);
ON_ERR_SET_GOTO(pkeylen <= 0 || !ctkex_encoded || pkeylen != pubkey_kexlen,
ret, -1, err);

memcpy(ct, ctkex_encoded, pkeylen);

err:
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_CTX_free(kgctx);
EVP_PKEY_free(pkey);
EVP_PKEY_free(peerpk);
OPENSSL_free(ctkex_encoded);
return ret;
}

static int oqs_evp_kem_decaps_keyslot(void *vpkemctx, unsigned char *secret,
size_t *secretlen,
const unsigned char *ct, size_t ctlen,
int keyslot)
{
OQS_KEM_PRINTF("OQS KEM provider called: oqs_hyb_kem_decaps\n");

int ret = OQS_SUCCESS, ret2 = 0;
const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;

size_t pubkey_kexlen = evp_ctx->evp_info->length_public_key;
size_t kexDeriveLen = evp_ctx->evp_info->kex_length_secret;
unsigned char *privkey_kex = pkemctx->kem->comp_privkey[keyslot];
size_t privkey_kexlen = evp_ctx->evp_info->length_private_key;

// Free at err:
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *pkey = NULL, *peerpkey = NULL;

*secretlen = kexDeriveLen;
if (secret == NULL)
return 1;

if (evp_ctx->evp_info->raw_key_support) {
pkey = EVP_PKEY_new_raw_private_key(evp_ctx->evp_info->keytype, NULL,
privkey_kex, privkey_kexlen);
ON_ERR_SET_GOTO(!pkey, ret, -10, err);
} else {
pkey = d2i_AutoPrivateKey(&pkey, (const unsigned char **)&privkey_kex,
privkey_kexlen);
ON_ERR_SET_GOTO(!pkey, ret, -2, err);
}

peerpkey = EVP_PKEY_new();
ON_ERR_SET_GOTO(!peerpkey, ret, -3, err);

ret2 = EVP_PKEY_copy_parameters(peerpkey, evp_ctx->keyParam);
ON_ERR_SET_GOTO(ret2 <= 0, ret, -4, err);

ret2 = EVP_PKEY_set1_encoded_public_key(peerpkey, ct, pubkey_kexlen);
ON_ERR_SET_GOTO(ret2 <= 0 || !peerpkey, ret, -5, err);

ctx = EVP_PKEY_CTX_new(pkey, NULL);
ON_ERR_SET_GOTO(!ctx, ret, -6, err);

ret = EVP_PKEY_derive_init(ctx);
ON_ERR_SET_GOTO(ret <= 0, ret, -7, err);
ret = EVP_PKEY_derive_set_peer(ctx, peerpkey);
ON_ERR_SET_GOTO(ret <= 0, ret, -8, err);

ret = EVP_PKEY_derive(ctx, secret, &kexDeriveLen);
ON_ERR_SET_GOTO(ret <= 0, ret, -9, err);

err:
EVP_PKEY_free(peerpkey);
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(ctx);
return ret;
}

/// Hybrid KEM functions

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);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_encaps_keyslot(vpkemctx, NULL, &ctLen1, NULL, &secretLen1,
1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

*ctlen = ctLen0 + ctLen1;
*secretlen = secretLen0 + secretLen1;

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;

ret = oqs_evp_kem_encaps_keyslot(vpkemctx, ct0, &ctLen0, secret0,
&secretLen0, 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

ret = oqs_qs_kem_encaps_keyslot(vpkemctx, ct1, &ctLen1, secret1,
&secretLen1, 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

err:
return ret;
}

static int oqs_hyb_kem_decaps(void *vpkemctx, unsigned char *secret,
size_t *secretlen, const unsigned char *ct,
size_t ctlen)
{
int ret = OQS_SUCCESS;
const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
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;

ret = oqs_evp_kem_decaps_keyslot(vpkemctx, NULL, &secretLen0, NULL, 0, 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, NULL, &secretLen1, NULL, 0, 1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

*secretlen = secretLen0 + secretLen1;

if (secret == NULL)
return 1;

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

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

ct0 = ct;
ct1 = ct + ctLen0;
secret0 = secret;
secret1 = secret + secretLen0;

ret = oqs_evp_kem_decaps_keyslot(vpkemctx, secret0, &secretLen0, ct0,
ctLen0, 0);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
ret = oqs_qs_kem_decaps_keyslot(vpkemctx, secret1, &secretLen1, ct1, ctLen1,
1);
ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);

err:
return ret;
}
Loading
Loading