SHA256
1
0
forked from pool/libica
libica/fix-segfault-during-multithread-keygen.patch

184 lines
4.5 KiB
Diff
Raw Normal View History

Index: src/s390_rsa.c
===================================================================
--- a/src/s390_rsa.c
+++ b/src/s390_rsa.c
@@ -18,6 +18,9 @@
#include <errno.h>
#include <stdint.h>
#include <openssl/rsa.h>
+#include <openssl/crypto.h>
+#include <pthread.h>
+#include <semaphore.h>
#include "s390_rsa.h"
#include "s390_prng.h"
@@ -41,9 +44,22 @@ static unsigned int mod_expo_sw(int arg_
char *exp, int mod_length, char *mod,
int *res_length, char *res, BN_CTX *ctx);
-RSA* rsa_key_generate(unsigned int modulus_bit_length,
- unsigned long *public_exponent)
+struct thread_data
+{
+ unsigned int mod_bit_length;
+ unsigned long *pub_exp;
+ RSA *rsa;
+};
+
+static void *__rsa_key_generate(void *ptr)
{
+ struct thread_data *pth_data;
+ unsigned int modulus_bit_length;
+ unsigned long *public_exponent;
+
+ pth_data = (struct thread_data*)ptr;
+ modulus_bit_length = pth_data->mod_bit_length;
+ public_exponent = pth_data->pub_exp;
BN_GENCB cb;
if (*public_exponent == 0)
@@ -70,9 +86,36 @@ RSA* rsa_key_generate(unsigned int modul
if (RSA_generate_key_ex(rsa, modulus_bit_length, exp, &cb)) {
BN_free(exp);
- return rsa;
+ pth_data->rsa = rsa;
}
+ else
+ pth_data->rsa = NULL;
+
+ return 0;
+}
+RSA* rsa_key_generate(unsigned int modulus_bit_length,
+ unsigned long *public_exponent)
+{
+ pthread_t tid;
+ struct thread_data th_data;
+ int rc;
+
+ sem_wait(&openssl_crypto_lock_mtx);
+
+ th_data.mod_bit_length = modulus_bit_length;
+ th_data.pub_exp = public_exponent;
+ rc = pthread_create(&(tid), NULL, (void *)&__rsa_key_generate,
+ (void *)(&th_data));
+ if (rc)
+ return 0;
+ rc = pthread_join(tid, NULL);
+
+ if (!rc && th_data.rsa) {
+ sem_post(&openssl_crypto_lock_mtx);
+ return th_data.rsa;
+ }
+ sem_post(&openssl_crypto_lock_mtx);
return 0;
}
Index: src/init.c
===================================================================
--- a/src/init.c
+++ b/src/init.c
@@ -18,10 +18,14 @@
#include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <semaphore.h>
+#include <pthread.h>
#include <syslog.h>
#include "init.h"
#include "icastats.h"
+#include "s390_rsa.h"
#include "s390_prng.h"
#include "s390_crypto.h"
#include "ica_api.h"
@@ -79,12 +83,60 @@ void end_sigill_section(struct sigaction
sigprocmask(SIG_SETMASK, oldset, 0);
}
+static pthread_mutex_t *openssl_locks;
+
+static void openssl_lock_callback(int mode, int num, char *file, int line)
+{
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&(openssl_locks[num]));
+ }
+ else {
+ pthread_mutex_unlock(&(openssl_locks[num]));
+ }
+}
+
+static unsigned long get_thread_id(void)
+{
+ return (unsigned long)pthread_self();
+}
+
+static void init_openssl_locks(void)
+{
+ int i, crypt_num_locks;
+
+ crypt_num_locks = CRYPTO_num_locks();
+ openssl_locks = (pthread_mutex_t *)
+ OPENSSL_malloc(crypt_num_locks *
+ sizeof(pthread_mutex_t));
+ for (i = 0; i < CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&(openssl_locks[i]),NULL);
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())get_thread_id);
+ CRYPTO_set_locking_callback((void (*)
+ (int, int, const char*, int))openssl_lock_callback);
+
+ sem_init(&openssl_crypto_lock_mtx, 0, crypt_num_locks);
+}
+
+static void free_openssl_locks(void)
+{
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ pthread_mutex_destroy(&(openssl_locks[i]));
+
+ OPENSSL_free(openssl_locks);
+}
+
void openssl_init(void)
{
/* initial seed the openssl random generator */
unsigned char random_data[64];
s390_prng(random_data, sizeof(random_data));
RAND_seed(random_data, sizeof(random_data));
+ init_openssl_locks();
}
/* Switches have to be done first. Otherwise we will not have hw support
@@ -115,4 +167,5 @@ void __attribute__ ((constructor)) icain
void __attribute__ ((destructor)) icaexit(void)
{
stats_munmap(SHM_CLOSE);
+ free_openssl_locks();
}
Index: src/include/s390_rsa.h
===================================================================
--- a/src/include/s390_rsa.h
+++ b/src/include/s390_rsa.h
@@ -16,6 +16,7 @@
#include <openssl/bn.h>
#include <asm/zcrypt.h>
+#include <semaphore.h>
#include "ica_api.h"
typedef struct ica_rsa_modexpo ica_rsa_modexpo_t;
@@ -40,5 +41,7 @@ unsigned int rsa_key_generate_crt(ica_ad
unsigned int rsa_crt_sw(ica_rsa_modexpo_crt_t * pCrt);
unsigned int rsa_mod_mult_sw(ica_rsa_modmult_t * pMul);
unsigned int rsa_mod_expo_sw(ica_rsa_modexpo_t *pMex);
+
+sem_t openssl_crypto_lock_mtx;
#endif