#include "internal.h"
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
static pthread_mutex_t *mutexes = NULL;
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
static __thread bool current_thread_initialized = false;
static size_t threads_cnt = 0;
return 1;
}
-static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+
+static int RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num)
{
+ return 1;
}
-static int RAND_METHOD_bytes(unsigned char *buf, int num)
+static int RAND_METHOD_add(UNUSED const void *buf, UNUSED int num, UNUSED double entropy)
{
- return getrandom_wrapper(buf, num);
+ return 1;
}
-static void RAND_METHOD_cleanup(void)
+#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+
+static void RAND_METHOD_seed(UNUSED const void *buf, UNUSED int num)
{
}
{
}
+#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+
+static int RAND_METHOD_bytes(unsigned char *buf, int num)
+{
+ return getrandom_wrapper(buf, num);
+}
+
+static void RAND_METHOD_cleanup(void)
+{
+}
+
static int RAND_METHOD_pseudorand(UNUSED unsigned char *buf, UNUSED int num)
{
return getrandom_wrapper(buf, num);
RAND_METHOD_status,
};
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
static void locking_callback(int mode, int type, UNUSED const char *file, UNUSED int line)
{
/* Ignore NULL mutexes and lock/unlock error codes as we can't do anything
}
}
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
API int yaca_initialize(void)
{
int ret = YACA_ERROR_NONE;
pthread_mutex_lock(&init_mutex);
{
if (threads_cnt == 0) {
- assert(mutexes == NULL);
#ifndef SYS_getrandom
if (urandom_fd == -2) {
OpenSSL_add_all_digests();
OpenSSL_add_all_ciphers();
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* enable threads support */
+ assert(mutexes == NULL);
+
if (CRYPTO_num_locks() > 0) {
ret = yaca_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t),
(void**)&mutexes);
CRYPTO_set_id_callback(thread_id_callback);
CRYPTO_set_locking_callback(locking_callback);
}
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
/*
* TODO:
threads_cnt++;
current_thread_initialized = true;
}
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom
exit:
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L || !defined SYS_getrandom */
+
pthread_mutex_unlock(&init_mutex);
return ret;
return;
/* per thread cleanup */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
ERR_remove_thread_state(NULL);
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
CRYPTO_cleanup_all_ex_data();
pthread_mutex_lock(&init_mutex);
/* last one turns off the light */
if (threads_cnt == 1) {
ERR_free_strings();
- ERR_remove_thread_state(NULL);
EVP_cleanup();
RAND_cleanup();
- CRYPTO_cleanup_all_ex_data();
RAND_set_rand_method(saved_rand_method);
+
#ifndef SYS_getrandom
close(urandom_fd);
urandom_fd = -2;
#endif /* SYS_getrandom */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* threads support cleanup */
CRYPTO_set_id_callback(NULL);
CRYPTO_set_locking_callback(NULL);
destroy_mutexes(CRYPTO_num_locks());
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
}
assert(threads_cnt > 0);
/* known errors */
switch (err) {
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+#else /* OPENSSL_VERSION_NUMBER > 0x10100000L */
case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS):
case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+#endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL):
case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED):
case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE):
case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA):
/* fatal errors */
int reason = ERR_GET_REASON(err);
- if (ret == YACA_ERROR_NONE && reason <= GENERIC_REASON_MAX && ERR_FATAL_ERROR(err) > 0) {
+ if (ret == YACA_ERROR_NONE && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
switch (reason) {
case ERR_R_MALLOC_FAILURE:
ret = YACA_ERROR_OUT_OF_MEMORY;
assert(c->cipher_ctx != NULL);
bool encryption = is_encryption_op(c->op_type);
- int type = EVP_CIPHER_type(c->cipher_ctx->cipher);
+ int type = EVP_CIPHER_CTX_type(c->cipher_ctx);
if (input_len > 0) {
if (type == NID_id_aes128_wrap || type == NID_id_aes192_wrap || type == NID_id_aes256_wrap) {
assert(c->cipher_ctx != NULL);
mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
- nid = EVP_CIPHER_nid(c->cipher_ctx->cipher);
+ nid = EVP_CIPHER_CTX_nid(c->cipher_ctx);
switch (property) {
case YACA_PROPERTY_GCM_AAD:
goto exit;
mode = EVP_CIPHER_CTX_mode(nc->cipher_ctx);
- nid = EVP_CIPHER_nid(nc->cipher_ctx->cipher);
+ nid = EVP_CIPHER_CTX_nid(nc->cipher_ctx);
if (mode == EVP_CIPH_CCM_MODE ||
nid == NID_rc2_cbc || nid == NID_rc2_ecb || nid == NID_rc2_cfb64 || nid == NID_rc2_ofb64) {
ret = encrypt_ctx_backup(nc, cipher, sym_key, iv);
return YACA_ERROR_INVALID_PARAMETER;
mode = EVP_CIPHER_CTX_mode(c->cipher_ctx);
- type = EVP_CIPHER_type(c->cipher_ctx->cipher);
+ type = EVP_CIPHER_CTX_type(c->cipher_ctx);
enum encrypt_context_state_e target_state;
if (output == NULL && input == NULL)
}
/* Fix for OpenSSL error in 3DES CFB1 */
- if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
+ if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
if (input_len > INT_MAX / 8)
return YACA_ERROR_INVALID_PARAMETER;
input_len *= 8;
c->state = target_state;
/* Fix for OpenSSL error in 3DES CFB1 */
- if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
+ if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
*output_len /= 8;
return YACA_ERROR_NONE;
*output_len = loutput_len;
/* Fix for OpenSSL error in 3DES CFB1 */
- if ((c->cipher_ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
+ if ((EVP_CIPHER_CTX_flags(c->cipher_ctx) & EVP_CIPH_FLAG_LENGTH_BITS) != 0)
*output_len /= 8;
c->state = STATE_FINALIZED;
#include <openssl/ossl_typ.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/opensslv.h>
+#include <openssl/rand.h>
#include <yaca_types.h>
#define API __attribute__ ((visibility("default")))
#define UNUSED __attribute__((unused))
+/* Functions that handle the hidden nature of internal
+ * OpenSSL structures that don't exist in OpenSSL < 1.1.0
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+static inline EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
+{
+ return ctx->pctx;
+}
+
+static inline int EVP_PKEY_up_ref(EVP_PKEY *pkey)
+{
+ if (CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY) <= 0)
+ return 0;
+ return 1;
+}
+
+static inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA)
+ return NULL;
+ return pkey->pkey.rsa;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
enum yaca_context_type_e {
YACA_CONTEXT_INVALID = 0,
YACA_CONTEXT_DIGEST,
goto exit;
}
- imported_evp_id = EVP_PKEY_type(pkey->type);
+ imported_evp_id = EVP_PKEY_type(EVP_PKEY_id(pkey));
switch (imported_key_category) {
case IMPORTED_KEY_CATEGORY_PRIVATE:
if (ret != YACA_ERROR_NONE)
return ret;
} else {
- CRYPTO_add(¶ms->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ EVP_PKEY_up_ref(params);
}
kctx = EVP_PKEY_CTX_new(params, NULL);
return YACA_KEY_NULL;
/* raise the refcount */
- CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ EVP_PKEY_up_ref(key->evp);
copy->key.type = key->key.type;
copy->evp = key->evp;
case YACA_KEY_TYPE_EC_PRIV:
case YACA_KEY_TYPE_EC_PUB:
case YACA_KEY_TYPE_EC_PARAMS: {
- assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC);
+ assert(EVP_PKEY_type(EVP_PKEY_id(evp_key->evp)) == EVP_PKEY_EC);
const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp);
const EC_GROUP *ecg = EC_KEY_get0_group(eck);
ret = fn(input_len,
(const unsigned char*)input,
(unsigned char*)loutput,
- lasym_key->evp->pkey.rsa,
+ EVP_PKEY_get0_RSA(lasym_key->evp),
lpadding);
if (ret < 0) {
assert(output_len != NULL);
struct yaca_sign_context_s *c = get_sign_context(ctx);
+ EVP_PKEY_CTX *pctx;
if (c == NULL || input_len != 0)
return YACA_ERROR_INVALID_PARAMETER;
assert(c->md_ctx != NULL);
- if (c->md_ctx->pctx == NULL)
+ pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx);
+ if (pctx == NULL)
return YACA_ERROR_INTERNAL;
- EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx);
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
if (pkey == NULL) {
ERROR_DUMP(YACA_ERROR_INTERNAL);
return YACA_ERROR_INTERNAL;
yaca_padding_e padding;
int pad;
EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pctx;
if (c == NULL || value == NULL)
return YACA_ERROR_INVALID_PARAMETER;
assert(c->md_ctx != NULL);
- if (c->md_ctx->pctx == NULL)
+ pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx);
+ if (pctx == NULL)
return YACA_ERROR_INTERNAL;
/* this function only supports padding */
pad = rsa_padding2openssl(padding);
assert(pad != -1);
- pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
if (pkey == NULL) {
ret = YACA_ERROR_INTERNAL;
ERROR_DUMP(ret);
}
/* padding only works for RSA */
- if (pkey->type != EVP_PKEY_RSA)
+ if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA)
return YACA_ERROR_INVALID_PARAMETER;
- ret = EVP_PKEY_CTX_set_rsa_padding(c->md_ctx->pctx, pad);
+ ret = EVP_PKEY_CTX_set_rsa_padding(pctx, pad);
if (ret <= 0) {
ret = YACA_ERROR_INTERNAL;
ERROR_DUMP(ret);
int ret;
struct yaca_sign_context_s *c = get_sign_context(ctx);
EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pctx;
int pad;
yaca_padding_e padding;
assert(c->md_ctx != NULL);
- if (c->md_ctx->pctx == NULL)
+ pctx = EVP_MD_CTX_pkey_ctx(c->md_ctx);
+ if (pctx == NULL)
return YACA_ERROR_INTERNAL;
/* this function only supports padding */
if (property != YACA_PROPERTY_PADDING)
return YACA_ERROR_INVALID_PARAMETER;
- pkey = EVP_PKEY_CTX_get0_pkey(c->md_ctx->pctx);
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
if (pkey == NULL) {
ret = YACA_ERROR_INTERNAL;
ERROR_DUMP(ret);
}
/* padding only works for RSA */
- if (pkey->type != EVP_PKEY_RSA)
+ if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA)
return YACA_ERROR_INVALID_PARAMETER;
- ret = EVP_PKEY_CTX_get_rsa_padding(c->md_ctx->pctx, &pad);
+ ret = EVP_PKEY_CTX_get_rsa_padding(pctx, &pad);
if (ret <= 0) {
ret = YACA_ERROR_INTERNAL;
ERROR_DUMP(ret);