forked from pool/libica
184 lines
4.5 KiB
Diff
184 lines
4.5 KiB
Diff
|
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
|
||
|
|