ucissl / src /uci_provider_kem.c
Jack698's picture
Upload folder using huggingface_hub
efadae0 verified
#include "uci_provider.h"
#ifdef HAVE_OPENSSL
#include "unified_crypto_interface.h"
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
UCI_PROVIDER_CTX *provctx;
uci_algorithm_id_t algorithm;
uci_keypair_t keypair;
} UCI_KEM_CTX;
static OSSL_FUNC_kem_newctx_fn uci_kem_newctx;
static OSSL_FUNC_kem_freectx_fn uci_kem_freectx;
static OSSL_FUNC_kem_encapsulate_init_fn uci_kem_encapsulate_init;
static OSSL_FUNC_kem_encapsulate_fn uci_kem_encapsulate;
static OSSL_FUNC_kem_decapsulate_init_fn uci_kem_decapsulate_init;
static OSSL_FUNC_kem_decapsulate_fn uci_kem_decapsulate;
static void *uci_kem_newctx(void *provctx) {
UCI_KEM_CTX *ctx = malloc(sizeof(UCI_KEM_CTX));
if (ctx != NULL) {
memset(ctx, 0, sizeof(UCI_KEM_CTX));
ctx->provctx = (UCI_PROVIDER_CTX *)provctx;
}
return ctx;
}
static void uci_kem_freectx(void *ctx) {
UCI_KEM_CTX *kemctx = (UCI_KEM_CTX *)ctx;
if (kemctx != NULL) {
uci_keypair_free(&kemctx->keypair);
free(kemctx);
}
}
static int uci_kem_encapsulate_init(void *ctx, void *provkey, const OSSL_PARAM params[]) {
UCI_KEM_CTX *kemctx = (UCI_KEM_CTX *)ctx;
if (kemctx == NULL || provkey == NULL)
return 0;
return 1;
}
static int uci_kem_encapsulate(void *ctx,
unsigned char *out, size_t *outlen,
unsigned char *secret, size_t *secretlen) {
UCI_KEM_CTX *kemctx = (UCI_KEM_CTX *)ctx;
uci_kem_encaps_result_t result;
int ret;
if (kemctx == NULL)
return 0;
if (out == NULL || secret == NULL) {
uci_algorithm_info_t info;
if (uci_get_algorithm_info(kemctx->algorithm, &info) != UCI_SUCCESS)
return 0;
if (outlen != NULL)
*outlen = 1088;
if (secretlen != NULL)
*secretlen = 32;
return 1;
}
ret = uci_kem_encaps(&kemctx->keypair, &result);
if (ret != UCI_SUCCESS)
return 0;
if (*outlen < result.ciphertext_len || *secretlen < result.shared_secret_len) {
uci_kem_encaps_result_free(&result);
return 0;
}
memcpy(out, result.ciphertext, result.ciphertext_len);
*outlen = result.ciphertext_len;
memcpy(secret, result.shared_secret, result.shared_secret_len);
*secretlen = result.shared_secret_len;
uci_kem_encaps_result_free(&result);
return 1;
}
static int uci_kem_decapsulate_init(void *ctx, void *provkey, const OSSL_PARAM params[]) {
UCI_KEM_CTX *kemctx = (UCI_KEM_CTX *)ctx;
if (kemctx == NULL || provkey == NULL)
return 0;
return 1;
}
static int uci_kem_decapsulate(void *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen) {
UCI_KEM_CTX *kemctx = (UCI_KEM_CTX *)ctx;
int ret;
if (kemctx == NULL)
return 0;
if (out == NULL) {
*outlen = 32;
return 1;
}
ret = uci_kem_decaps(&kemctx->keypair, in, inlen, out, outlen);
return (ret == UCI_SUCCESS) ? 1 : 0;
}
#define MAKE_KEM_FUNCTIONS(name, ucialg) \
static void *name##_newctx(void *provctx) { \
UCI_KEM_CTX *ctx = uci_kem_newctx(provctx); \
if (ctx != NULL) ctx->algorithm = ucialg; \
return ctx; \
} \
static const OSSL_DISPATCH name##_functions[] = { \
{ OSSL_FUNC_KEM_NEWCTX, (void (*)(void))name##_newctx }, \
{ OSSL_FUNC_KEM_FREECTX, (void (*)(void))uci_kem_freectx }, \
{ OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))uci_kem_encapsulate_init }, \
{ OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))uci_kem_encapsulate }, \
{ OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))uci_kem_decapsulate_init }, \
{ OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))uci_kem_decapsulate }, \
{ 0, NULL } \
}
MAKE_KEM_FUNCTIONS(kyber512, UCI_ALG_KYBER512);
MAKE_KEM_FUNCTIONS(kyber768, UCI_ALG_KYBER768);
MAKE_KEM_FUNCTIONS(kyber1024, UCI_ALG_KYBER1024);
const OSSL_ALGORITHM *uci_provider_query_kem(void *provctx, int *no_cache) {
static const OSSL_ALGORITHM kem_algs[] = {
{ "kyber512", "provider=uci", kyber512_functions, "Kyber512 KEM" },
{ "kyber768", "provider=uci", kyber768_functions, "Kyber768 KEM" },
{ "kyber1024", "provider=uci", kyber1024_functions, "Kyber1024 KEM" },
{ NULL, NULL, NULL, NULL }
};
*no_cache = 0;
return kem_algs;
}
#else
const OSSL_ALGORITHM *uci_provider_query_kem(void *provctx, int *no_cache) {
return NULL;
}
#endif /* HAVE_OPENSSL */