add some sanity checks to threading code

From Mike Mohr
This commit is contained in:
Brian Pellin
2012-07-28 15:20:24 -05:00
parent 0dd0fc6407
commit acaed35527
2 changed files with 26 additions and 11 deletions

View File

@@ -4,6 +4,8 @@ KeePassDroid (1.9.10)
* Add Portugese translations from Carlos Schlyter * Add Portugese translations from Carlos Schlyter
* Japanese translation corrections from Matsuu Takuto * Japanese translation corrections from Matsuu Takuto
* Fix x86 key generation compatibility * Fix x86 key generation compatibility
* Add 2 thread support to key generation for dual core devices from
Mike Mohr
KeePassDroid (1.9.9) KeePassDroid (1.9.9)

View File

@@ -362,8 +362,8 @@ JNIEXPORT jint JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nGetCache
#define MASTER_KEY_SIZE 32 #define MASTER_KEY_SIZE 32
typedef struct _master_key { typedef struct _master_key {
uint32_t rounds; uint32_t rounds, done[2];
pthread_mutex_t lock; // locks the first half of the key material pthread_mutex_t lock1, lock2; // these lock the two halves of the key material
uint8_t c_seed[MASTER_KEY_SIZE] __attribute__ ((aligned (16))); uint8_t c_seed[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
uint8_t key1[MASTER_KEY_SIZE] __attribute__ ((aligned (16))); uint8_t key1[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
uint8_t key2[MASTER_KEY_SIZE] __attribute__ ((aligned (16))); uint8_t key2[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
@@ -379,12 +379,15 @@ void *generate_key_material(void *arg) {
master_key *mk = (master_key *)arg; master_key *mk = (master_key *)arg;
aes_encrypt_ctx e_ctx[1] __attribute__ ((aligned (16))); aes_encrypt_ctx e_ctx[1] __attribute__ ((aligned (16)));
if( pthread_mutex_trylock(&mk->lock) == 0 ) { if( mk->done[0] == 0 && pthread_mutex_trylock(&mk->lock1) == 0 ) {
key1 = mk->key1; key1 = mk->key1;
key2 = mk->key2; key2 = mk->key2;
} else if( mk->done[1] == 0 && pthread_mutex_trylock(&mk->lock2) == 0 ) {
key1 = mk->key1 + (MASTER_KEY_SIZE/2);
key2 = mk->key2 + (MASTER_KEY_SIZE/2);
} else { } else {
key1 = mk->key1 + 16; // this can only be scaled to two threads
key2 = mk->key2 + 16; pthread_exit( (void *)(-1) );
} }
#if defined(KPD_PROFILE) #if defined(KPD_PROFILE)
@@ -410,8 +413,13 @@ void *generate_key_material(void *arg) {
__android_log_print(ANDROID_LOG_INFO, "kpd_jni.c/nTransformMasterKey", "Thread 2 master key transformation took ~%d seconds", (end.tv_sec-start.tv_sec)); __android_log_print(ANDROID_LOG_INFO, "kpd_jni.c/nTransformMasterKey", "Thread 2 master key transformation took ~%d seconds", (end.tv_sec-start.tv_sec));
#endif #endif
if( key1 == mk->key1 ) if( key1 == mk->key1 ) {
pthread_mutex_unlock(&mk->lock); mk->done[0] = 1;
pthread_mutex_unlock(&mk->lock1);
} else {
mk->done[1] = 1;
pthread_mutex_unlock(&mk->lock2);
}
return (void *)flip; return (void *)flip;
} }
@@ -439,8 +447,13 @@ JNIEXPORT jbyteArray JNICALL Java_com_keepassdroid_crypto_finalkey_NativeFinalKe
return NULL; return NULL;
} }
mk.rounds = (uint32_t)rounds; mk.rounds = (uint32_t)rounds;
if( pthread_mutex_init(&mk.lock, NULL) != 0 ) { mk.done[0] = mk.done[1] = 0;
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to initialize the mutex"); // FIXME: get a better exception class for this... if( pthread_mutex_init(&mk.lock1, NULL) != 0 ) {
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to initialize the mutex for thread 1"); // FIXME: get a better exception class for this...
return NULL;
}
if( pthread_mutex_init(&mk.lock2, NULL) != 0 ) {
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to initialize the mutex for thread 2"); // FIXME: get a better exception class for this...
return NULL; return NULL;
} }
(*env)->GetByteArrayRegion(env, seed, 0, MASTER_KEY_SIZE, (jbyte *)mk.c_seed); (*env)->GetByteArrayRegion(env, seed, 0, MASTER_KEY_SIZE, (jbyte *)mk.c_seed);
@@ -467,8 +480,8 @@ JNIEXPORT jbyteArray JNICALL Java_com_keepassdroid_crypto_finalkey_NativeFinalKe
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to join thread 2"); // FIXME: get a better exception class for this... (*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to join thread 2"); // FIXME: get a better exception class for this...
return NULL; return NULL;
} }
if( vret1 != vret2 ) { if( vret1 == (void *)(-1) || vret2 == (void *)(-1) || vret1 != vret2 ) {
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: flip values from threads do not match"); // FIXME: get a better exception class for this... (*env)->ThrowNew(env, bad_arg, "TransformMasterKey: invalid flip value(s) from completed thread(s)"); // FIXME: get a better exception class for this...
return NULL; return NULL;
} else { } else {
flip = (uint32_t)vret1; flip = (uint32_t)vret1;