Skip to main content
  • Home
  • login
  • Browse the archive

    swh mirror partner logo
swh logo
SoftwareHeritage
Software
Heritage
Mirror
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • afd609a
  • /
  • oqs_test_endecode.c
Raw File
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge Iframe embedding
swh:1:cnt:2fb3964780d09294885942cf25fcd7f8c007a498
directory badge Iframe embedding
swh:1:dir:afd609aa2aed1298dc68e73d964aeceb47031ec2
oqs_test_endecode.c
// SPDX-License-Identifier: Apache-2.0 AND MIT

#include <openssl/provider.h>
#include <openssl/encoder.h>
#include <openssl/decoder.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/buffer.h>
#include <string.h>
#include "test_common.h"
#include <openssl/core_names.h>
#include <openssl/trace.h>
#include "oqs/oqs.h"

static OSSL_LIB_CTX *libctx = NULL;
static char *modulename = NULL;
static char *configfile = NULL;
static char *testpropq = NULL;
static OSSL_LIB_CTX *keyctx = NULL;
static OSSL_LIB_CTX *testctx = NULL;

static OSSL_PROVIDER *dfltprov = NULL;
static OSSL_PROVIDER *keyprov = NULL;

#define nelem(a) (sizeof(a)/sizeof((a)[0]))

typedef struct endecode_params_st {
    char *format;
    char *structure;
    char *keytype;
    char *pass;
    int selection;

} ENDECODE_PARAMS;

static ENDECODE_PARAMS test_params_list[] = {
        {"PEM", "PrivateKeyInfo",          NULL, NULL,
                                                                                         OSSL_KEYMGMT_SELECT_KEYPAIR |
                                                                                         OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
        {"PEM", "EncryptedPrivateKeyInfo", NULL, "Pass the holy handgrenade of antioch", OSSL_KEYMGMT_SELECT_KEYPAIR |
                                                                                         OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS},
        {"PEM", "SubjectPublicKeyInfo",    NULL, NULL,                                   OSSL_KEYMGMT_SELECT_PUBLIC_KEY |
                                                                                         OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
        {"DER", "PrivateKeyInfo",          NULL, NULL,                                   OSSL_KEYMGMT_SELECT_KEYPAIR |
                                                                                         OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
        {"DER", "EncryptedPrivateKeyInfo", NULL, "Pass the holy handgrenade of antioch", OSSL_KEYMGMT_SELECT_KEYPAIR |
                                                                                         OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS},
        {"DER", "SubjectPublicKeyInfo",    NULL, NULL,                                   OSSL_KEYMGMT_SELECT_PUBLIC_KEY |
                                                                                         OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
};

static const char *sigalg_names[] = {
///// OQS_TEMPLATE_FRAGMENT_SIGNATURE_CASES_START
#ifdef OQS_ENABLE_SIG_dilithium_2
        "dilithium2","p256_dilithium2","rsa3072_dilithium2",
#endif
#ifdef OQS_ENABLE_SIG_dilithium_3
        "dilithium3","p384_dilithium3",
#endif
#ifdef OQS_ENABLE_SIG_dilithium_5
        "dilithium5","p521_dilithium5",
#endif
#ifdef OQS_ENABLE_SIG_falcon_512
        "falcon512","p256_falcon512","rsa3072_falcon512",
#endif
#ifdef OQS_ENABLE_SIG_falcon_1024
        "falcon1024","p521_falcon1024",
#endif
#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
        "sphincssha2128fsimple","p256_sphincssha2128fsimple","rsa3072_sphincssha2128fsimple",
#endif
#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
        "sphincssha2128ssimple","p256_sphincssha2128ssimple","rsa3072_sphincssha2128ssimple",
#endif
#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
        "sphincssha2192fsimple","p384_sphincssha2192fsimple",
#endif
#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
        "sphincsshake128fsimple","p256_sphincsshake128fsimple","rsa3072_sphincsshake128fsimple",
#endif

///// OQS_TEMPLATE_FRAGMENT_SIGNATURE_CASES_END
};

static EVP_PKEY *oqstest_make_key(const char *type, EVP_PKEY *template,
                                  OSSL_PARAM *genparams) {
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;

    if (!alg_is_enabled(type)) {
        printf("Not generating key for disabled algorithm %s.\n", type);
        return NULL;
    }

    ctx = (template != NULL)
          ? EVP_PKEY_CTX_new_from_pkey(keyctx, template, testpropq)
          : EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq);

    /*
     * No real need to check the errors other than for the cascade
     * effect.  |pkey| will simply remain NULL if something goes wrong.
     */
    (void) (ctx != NULL
            && EVP_PKEY_keygen_init(ctx) > 0
            && (genparams == NULL
                || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
            && EVP_PKEY_keygen(ctx, &pkey) > 0);
    EVP_PKEY_CTX_free(ctx);
    return pkey;
}

static int encode_EVP_PKEY_prov(const EVP_PKEY *pkey, const char *format, const char *structure, const char *pass,
                                const int selection, void **encoded, long *encoded_len) {
    OSSL_ENCODER_CTX *ectx;
    BIO *mem_ser = NULL;
    BUF_MEM *mem_buf = NULL;
    const char *cipher = "AES-256-CBC";
    int ok = 0;

    ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
                                         selection,
                                         format, structure,
                                         NULL);
    if (ectx == NULL) {
        printf("No suitable encoder found\n");
        goto end;
    }

    if (pass != NULL) {
        OSSL_ENCODER_CTX_set_passphrase(ectx, (const unsigned char *) pass, strlen(pass));
        OSSL_ENCODER_CTX_set_cipher(ectx, cipher, NULL);
    }
    mem_ser = BIO_new(BIO_s_mem());
    if (!OSSL_ENCODER_to_bio(ectx, mem_ser)) {
        /* encoding failure */
        goto end;
    }

    BIO_get_mem_ptr(mem_ser, &mem_buf);
    if (mem_buf == NULL || mem_buf->length == 0)
        goto end;

    /* pkey was successfully encoded into the bio */
    *encoded = mem_buf->data;
    *encoded_len = mem_buf->length;

    /* Detach the encoded output */
    mem_buf->data = NULL;
    mem_buf->length = 0;
    ok = 1;

    end:
    BIO_free(mem_ser);
    OSSL_ENCODER_CTX_free(ectx);
    return ok;
}

static int decode_EVP_PKEY_prov(const char *input_type, const char *structure, const char *pass,
                                const char *keytype, const int selection, EVP_PKEY **object,
                                const void *encoded, const long encoded_len) {
    EVP_PKEY *pkey = NULL;
    OSSL_DECODER_CTX *dctx = NULL;
    BIO *encoded_bio = NULL;

    int ok = 0;

    encoded_bio = BIO_new_mem_buf(encoded, encoded_len);
    if (encoded_bio == NULL)
        goto end;

    dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey,
                                         input_type, structure,
                                         keytype, selection,
                                         keyctx, NULL);
    if (dctx == NULL)
        goto end;

    if (pass != NULL)
        OSSL_DECODER_CTX_set_passphrase(dctx, (const unsigned char *) pass, strlen(pass));

    if (!OSSL_DECODER_from_bio(dctx, encoded_bio))
        goto end;

    OSSL_DECODER_CTX_free(dctx);
    dctx = NULL;

    ok = 1;
    *object = pkey;
    pkey = NULL;

    end:
    EVP_PKEY_free(pkey);
    BIO_free(encoded_bio);
    OSSL_DECODER_CTX_free(dctx);
    return ok;
}

static int test_oqs_encdec(const char *sigalg_name) {
    EVP_PKEY *pkey = NULL;
    EVP_PKEY *decoded_pkey = NULL;
    void *encoded = NULL;
    long encoded_len = 0;
    size_t i;
    int ok = 0;

    for (i = 0; i < nelem(test_params_list); i++) {

        pkey = oqstest_make_key(sigalg_name, NULL, NULL);
        if (pkey == NULL)
            goto end;


        if (!encode_EVP_PKEY_prov(pkey, test_params_list[i].format, test_params_list[i].structure,
                                  test_params_list[i].pass, test_params_list[i].selection,
                                  &encoded, &encoded_len)) {
            printf("Failed encoding %s", sigalg_name);
            goto end;
        }
        if (!decode_EVP_PKEY_prov(test_params_list[i].format, test_params_list[i].structure,
                                  test_params_list[i].pass, test_params_list[i].keytype,
                                  test_params_list[i].selection,
                                  &decoded_pkey, encoded, encoded_len)) {
            printf("Failed decoding %s", sigalg_name);
            goto end;
        }

        if (EVP_PKEY_eq(pkey, decoded_pkey) != 1)
            goto end;
    }
    ok = 1;
    end:
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(decoded_pkey);
    return ok;
}

int main(int argc, char *argv[]) {
    size_t i;
    int errcnt = 0, test = 0;

    T((libctx = OSSL_LIB_CTX_new()) != NULL);
    T(argc == 3);
    modulename = argv[1];
    configfile = argv[2];

    T(OSSL_LIB_CTX_load_config(libctx, configfile));

    T(OSSL_PROVIDER_available(libctx, modulename));
    keyctx = OSSL_LIB_CTX_new();
    dfltprov = OSSL_PROVIDER_load(NULL, "default");
    dfltprov = OSSL_PROVIDER_load(keyctx, "default");
    keyprov = OSSL_PROVIDER_load(keyctx, modulename);

    for (i = 0; i < nelem(sigalg_names); i++) {
        if (test_oqs_encdec(sigalg_names[i])) {
            fprintf(stderr,
                    cGREEN "  Encoding/Decoding test succeeded: %s" cNORM "\n",
                    sigalg_names[i]);
        } else {
            fprintf(stderr,
                    cRED "  Encoding/Decoding test failed: %s" cNORM "\n",
                    sigalg_names[i]);
            ERR_print_errors_fp(stderr);
            errcnt++;
        }
    }

    OSSL_LIB_CTX_free(libctx);
    OSSL_PROVIDER_unload(dfltprov);
    OSSL_PROVIDER_unload(keyprov);
    OSSL_LIB_CTX_free(keyctx);

    TEST_ASSERT(errcnt == 0)
    return !test;
}

ENEA — Copyright (C), ENEA. License: GNU AGPLv3+.
Legal notes  ::  JavaScript license information ::  Web API

back to top