00001
00005 #define BEECRYPT_DLL_EXPORT
00006
00007 #define JNIEXPORT
00008 #define JNICALL
00009
00010 #include "system.h"
00011 #include "beecrypt.h"
00012 #include "blockmode.h"
00013
00014 #undef JAVAGLUE
00015 #define JAVAGLUE 0
00016
00017 #if JAVAGLUE
00018
00019 #include "javaglue.h"
00020 #include "debug.h"
00021
00022
00023
00024
00025
00026
00027 #ifndef WORDS_BIGENDIAN
00028 # define WORDS_BIGENDIAN 0
00029 #endif
00030
00031
00032 static const char* JAVA_OUT_OF_MEMORY_ERROR = "java/lang/OutOfMemoryError";
00033
00034 static const char* JAVA_PROVIDER_EXCEPTION = "java/security/ProviderException";
00035
00036 static const char* JAVA_INVALID_KEY_EXCEPTION = "java/security/InvalidKeyException";
00037
00038 static const char* MSG_OUT_OF_MEMORY = "out of memory";
00039
00040 static const char* MSG_NO_SUCH_ALGORITHM = "algorithm not available";
00041
00042 static const char* MSG_NO_ENTROPY_SOURCE = "no entropy source";
00043
00044 static const char* MSG_INVALID_KEY = "invalid key";
00045
00046
00047
00048 jlong JNICALL Java_beecrypt_security_NativeMessageDigest_find(JNIEnv* env, jclass dummy, jstring algorithm)
00049 {
00050 const char* name = (*env)->GetStringUTFChars(env, algorithm, (jboolean*) 0);
00051 const hashFunction* hash = hashFunctionFind(name);
00052 (*env)->ReleaseStringUTFChars(env, algorithm, name);
00053 if (hash == (hashFunction*) 0)
00054 {
00055 jclass ex = (*env)->FindClass(env, JAVA_PROVIDER_EXCEPTION);
00056 if (ex != (jclass) 0)
00057 (void) (*env)->ThrowNew(env, ex, MSG_NO_SUCH_ALGORITHM);
00058 }
00059 return (jlong) hash;
00060 }
00061
00062 jlong JNICALL Java_beecrypt_security_NativeMessageDigest_allocParam(JNIEnv* env, jclass dummy, jlong hash)
00063 {
00064 void *param = malloc(((const hashFunction*) hash)->paramsize);
00065 if (param == (void*) 0)
00066 {
00067 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00068 if (ex != (jclass) 0)
00069 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00070 }
00071 return (jlong) param;
00072 }
00073
00074 jlong JNICALL Java_beecrypt_security_NativeMessageDigest_cloneParam( JNIEnv* env, jclass dummy, jlong hash, jlong param)
00075 {
00076 unsigned int paramsize = ((const hashFunction*) hash)->paramsize;
00077 void *clone = malloc(paramsize);
00078 memcpy(clone, (void*) param, paramsize);
00079 return (jlong) clone;
00080 }
00081
00082 void JNICALL Java_beecrypt_security_NativeMessageDigest_freeParam( JNIEnv* env, jclass dummy, jlong param)
00083 {
00084 if (param)
00085 free((void*) param);
00086 }
00087
00088 void JNICALL Java_beecrypt_security_NativeMessageDigest_reset( JNIEnv* env, jclass dummy, jlong hash, jlong param)
00089 {
00090 (void) ((const hashFunction*) hash)->reset((hashFunctionParam*) param);
00091 }
00092
00093 void JNICALL Java_beecrypt_security_NativeMessageDigest_update( JNIEnv* env, jclass dummy, jlong hash, jlong param, jbyte input)
00094 {
00095 (void) ((const hashFunction*) hash)->update((hashFunctionParam*) param, (const byte*) &input, 1);
00096 }
00097
00098 void JNICALL Java_beecrypt_security_NativeMessageDigest_updateBlock(JNIEnv* env, jclass dummy, jlong hash, jlong param, jbyteArray input, jint offset, jint len)
00099 {
00100 jbyte* data = (*env)->GetByteArrayElements(env, input, (jboolean*) 0);
00101 if (data == (jbyte*) 0)
00102 {
00103 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00104 (*env)->ReleaseByteArrayElements(env, input, data, JNI_ABORT);
00105 if (ex)
00106 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00107 return;
00108 }
00109 (void) ((const hashFunction*) hash)->update((hashFunctionParam*) param, (const byte*) data+offset, len);
00110 (*env)->ReleaseByteArrayElements(env, input, data, JNI_ABORT);
00111 }
00112
00113 jbyteArray JNICALL Java_beecrypt_security_NativeMessageDigest_digest(JNIEnv* env, jclass dummy, jlong hash, jlong param)
00114 {
00115 jbyteArray digestArray;
00116 jbyte* digest;
00117
00118 int digestsize = (jsize) ((const hashFunction*) hash)->digestsize;
00119 int digestwords = digestsize >> 2;
00120
00121 digestArray = (*env)->NewByteArray(env, digestsize);
00122 digest = (*env)->GetByteArrayElements(env, digestArray, (jboolean*) 0);
00123
00124 if (digest == (jbyte*) 0)
00125 {
00126 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00127 if (ex)
00128 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00129 return (jbyteArray) 0;
00130 }
00131
00132 if (!WORDS_BIGENDIAN || (int) digest & 0x3)
00133 {
00134 uint32* data = (uint32*) malloc(digestwords * sizeof(uint32));
00135
00136 if (data == (uint32*) 0)
00137 {
00138 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00139 (*env)->ReleaseByteArrayElements(env, digestArray, digest, JNI_ABORT);
00140 if (ex)
00141 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00142 return (jbyteArray) 0;
00143 }
00144
00145 (void) ((const hashFunction*) hash)->digest((hashFunctionParam*) param, data);
00146 (void) encodeInts((const javaint*) data, digest, digestwords);
00147 free(data);
00148 }
00149 else
00150 {
00151 (void) ((const hashFunction*) hash)->digest((hashFunctionParam*) param, (uint32*) digest);
00152 }
00153
00154 (*env)->ReleaseByteArrayElements(env, digestArray, digest, 0);
00155
00156 return digestArray;
00157 }
00158
00159 jint JNICALL Java_beecrypt_security_NativeMessageDigest_digestLength( JNIEnv* env, jclass dummy, jlong hash)
00160 {
00161 return (jint) ((const hashFunction*) hash)->digestsize;
00162 }
00163
00164
00165
00166 jlong JNICALL Java_beecrypt_security_NativeSecureRandom_find(JNIEnv* env, jclass dummy, jstring algorithm)
00167 {
00168 const char* name = (*env)->GetStringUTFChars(env, algorithm, (jboolean*) 0);
00169 const randomGenerator* prng = randomGeneratorFind(name);
00170 (*env)->ReleaseStringUTFChars(env, algorithm, name);
00171 if (prng == (randomGenerator*) 0)
00172 {
00173 jclass ex = (*env)->FindClass(env, JAVA_PROVIDER_EXCEPTION);
00174 if (ex)
00175 (void) (*env)->ThrowNew(env, ex, MSG_NO_SUCH_ALGORITHM);
00176 }
00177 return (jlong) prng;
00178 }
00179
00180 jlong JNICALL Java_beecrypt_security_NativeSecureRandom_allocParam(JNIEnv* env, jclass dummy, jlong prng)
00181 {
00182 void *param = malloc(((const randomGenerator*) prng)->paramsize);
00183 if (param == (void*) 0)
00184 {
00185 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00186 if (ex)
00187 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00188 }
00189 return (jlong) param;
00190 }
00191
00192 jlong JNICALL Java_beecrypt_security_NativeSecureRandom_cloneParam( JNIEnv* env, jclass dummy, jlong prng, jlong param)
00193 {
00194 unsigned int paramsize = ((const randomGenerator*) prng)->paramsize;
00195 void *clone = malloc(paramsize);
00196 memcpy(clone, (void*) param, paramsize);
00197 return (jlong) clone;
00198 }
00199
00200 void JNICALL Java_beecrypt_security_NativeSecureRandom_freeParam( JNIEnv* env, jclass dummy, jlong param)
00201 {
00202 if (param)
00203 free((void*) param);
00204 }
00205
00206 void JNICALL Java_beecrypt_security_NativeSecureRandom_setup( JNIEnv* env, jclass dummy, jlong prng, jlong param)
00207 {
00208 (void) ((const randomGenerator*) prng)->setup((randomGeneratorParam*) param);
00209 }
00210
00211 void JNICALL Java_beecrypt_security_NativeSecureRandom_setSeed(JNIEnv* env, jclass dummy, jlong prng, jlong param, jbyteArray seedArray)
00212 {
00213
00214 jsize seedSize = (*env)->GetArrayLength(env, seedArray);
00215 if (seedSize)
00216 {
00217 jbyte* seed = (*env)->GetByteArrayElements(env, seedArray, (jboolean*) 0);
00218 if (seed == (jbyte*) 0)
00219 {
00220 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00221 if (ex)
00222 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00223 return;
00224 }
00225
00226 if (((int) seed & 0x3) || (seedSize & 0x3))
00227 {
00228 int size = (seedSize+3) >> 2;
00229 uint32* data = (uint32*) malloc(size * sizeof(uint32));
00230
00231 if (data == (uint32*) 0)
00232 {
00233 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00234 (*env)->ReleaseByteArrayElements(env, seedArray, seed, JNI_ABORT);
00235 if (ex)
00236 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00237 return;
00238 }
00239 (void) decodeIntsPartial(data, seed, seedSize);
00240 (void) ((const randomGenerator*) prng)->seed((randomGeneratorParam*) param, data, size);
00241 free(data);
00242 }
00243 else
00244 {
00245 (void) ((const randomGenerator*) prng)->seed((randomGeneratorParam*) param, (uint32*) seed, seedSize >> 2);
00246 }
00247
00248 (*env)->ReleaseByteArrayElements(env, seedArray, seed, JNI_ABORT);
00249 }
00250 }
00251
00252 void JNICALL Java_beecrypt_security_NativeSecureRandom_nextBytes(JNIEnv* env, jclass dummy, jlong prng, jlong param, jbyteArray bytesArray)
00253 {
00254
00255 jsize bytesSize = (*env)->GetArrayLength(env, bytesArray);
00256 if (bytesSize)
00257 {
00258 jbyte* bytes = (*env)->GetByteArrayElements(env, bytesArray, (jboolean*) 0);
00259 if (bytes == (jbyte*) 0)
00260 {
00261 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00262 if (ex)
00263 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00264 return;
00265 }
00266
00267
00268 if (((int) bytes & 0x3) || (bytesSize & 0x3))
00269 {
00270 int size = (bytesSize+3) >> 2;
00271 uint32* data = (uint32*) malloc(size * sizeof(uint32));
00272
00273 if (data == (uint32*) 0)
00274 {
00275 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00276 (*env)->ReleaseByteArrayElements(env, bytesArray, bytes, JNI_ABORT);
00277 if (ex)
00278 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00279 return;
00280 }
00281
00282 (void) ((const randomGenerator*) prng)->next((randomGeneratorParam*) param, data, size);
00283 memcpy(bytes, data, bytesSize);
00284 free(data);
00285 }
00286 else
00287 {
00288 (void) ((const randomGenerator*) prng)->next((randomGeneratorParam*) param, (uint32*) bytes, bytesSize >> 2);
00289 }
00290
00291 (*env)->ReleaseByteArrayElements(env, bytesArray, bytes, 0);
00292 }
00293 }
00294
00295 void JNICALL Java_beecrypt_security_NativeSecureRandom_generateSeed(JNIEnv* env, jclass dummy, jbyteArray seedArray)
00296 {
00297
00298 jsize seedSize = (*env)->GetArrayLength(env, seedArray);
00299
00300 if (seedSize)
00301 {
00302 jbyte* seed = (*env)->GetByteArrayElements(env, seedArray, (jboolean*) 0);
00303
00304 const entropySource* ents = entropySourceDefault();
00305
00306 if (seed == (jbyte*) 0)
00307 {
00308 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00309 if (ex)
00310 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00311 return;
00312 }
00313
00314 if (ents == (entropySource*) 0)
00315 {
00316 jclass ex = (*env)->FindClass(env, JAVA_PROVIDER_EXCEPTION);
00317 (*env)->ReleaseByteArrayElements(env, seedArray, seed, JNI_ABORT);
00318 if (ex)
00319 (void) (*env)->ThrowNew(env, ex, MSG_NO_ENTROPY_SOURCE);
00320 return;
00321 }
00322
00323
00324 if (((int) seed & 0x3) || (seedSize & 0x3))
00325 {
00326 int size = (seedSize+3) >> 2;
00327 uint32* data = (uint32*) malloc(size * sizeof(uint32));
00328 (void) ents->next(data, size);
00329 memcpy(seed, data, seedSize);
00330 free(data);
00331 }
00332 else
00333 {
00334 (void) ents->next((uint32*) seed, seedSize >> 2);
00335 }
00336
00337 (*env)->ReleaseByteArrayElements(env, seedArray, seed, 0);
00338 }
00339 }
00340
00341
00342
00343 jlong JNICALL Java_beecrypt_crypto_NativeBlockCipher_find(JNIEnv* env, jclass dummy, jstring algorithm)
00344 {
00345 const char* name = (*env)->GetStringUTFChars(env, algorithm, (jboolean*) 0);
00346 const blockCipher* ciph = blockCipherFind(name);
00347 (*env)->ReleaseStringUTFChars(env, algorithm, name);
00348 if (ciph == (blockCipher*) 0)
00349 {
00350 jclass ex = (*env)->FindClass(env, JAVA_PROVIDER_EXCEPTION);
00351 if (ex)
00352 (void) (*env)->ThrowNew(env, ex, MSG_NO_SUCH_ALGORITHM);
00353 }
00354 return (jlong) ciph;
00355 }
00356
00357 jlong JNICALL Java_beecrypt_crypto_NativeBlockCipher_allocParam(JNIEnv* env, jclass dummy, jlong ciph)
00358 {
00359 void *param = malloc(((const blockCipher*) ciph)->paramsize);
00360 if (param == (void*) 0)
00361 {
00362 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00363 if (ex)
00364 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00365 }
00366 return (jlong) param;
00367 }
00368
00369 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_freeParam( JNIEnv* env, jclass dummy, jlong param)
00370 {
00371 if (param)
00372 free((void*) param);
00373 }
00374
00375 jint JNICALL Java_beecrypt_crypto_NativeBlockCipher_getBlockSize( JNIEnv* env, jclass dummy, jlong ciph)
00376 {
00377 return ((const blockCipher*) ciph)->blocksize;
00378 }
00379
00380 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_setup(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jint mode, jbyteArray keyArray)
00381 {
00382
00383 jsize keysize = (*env)->GetArrayLength(env, keyArray);
00384
00385 if (keysize)
00386 {
00387 int rc;
00388 cipherOperation nativeop;
00389 jbyte* key;
00390
00391 switch (mode)
00392 {
00393 case javax_crypto_Cipher_ENCRYPT_MODE:
00394 nativeop = ENCRYPT;
00395 break;
00396 case javax_crypto_Cipher_DECRYPT_MODE:
00397 nativeop = DECRYPT;
00398 break;
00399 }
00400
00401 key = (*env)->GetByteArrayElements(env, keyArray, (jboolean*) 0);
00402 if (key == (jbyte*) 0)
00403 {
00404 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00405 if (ex)
00406 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00407 return;
00408 }
00409
00410 if (!WORDS_BIGENDIAN || ((int) key & 0x3) || (keysize & 0x3))
00411 {
00412 int size = (keysize + 3) >> 2;
00413 uint32* data = (uint32*) malloc(size * sizeof(uint32));
00414
00415 if (data == (uint32*) 0)
00416 {
00417 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00418 (*env)->ReleaseByteArrayElements(env, keyArray, key, JNI_ABORT);
00419 if (ex)
00420 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00421 return;
00422 }
00423
00424 (void) decodeIntsPartial(data, key, keysize);
00425 rc = ((const blockCipher*) ciph)->setup((blockCipherParam*) param, data, keysize << 3, nativeop);
00426 free(data);
00427 }
00428 else
00429 {
00430 rc = ((const blockCipher*) ciph)->setup((blockCipherParam*) param, (const uint32*) key, keysize << 3, nativeop);
00431 }
00432
00433 if (rc != 0)
00434 {
00435 jclass ex = (*env)->FindClass(env, JAVA_INVALID_KEY_EXCEPTION);
00436 if (ex)
00437 (void) (*env)->ThrowNew(env, ex, MSG_INVALID_KEY);
00438 }
00439
00440 (*env)->ReleaseByteArrayElements(env, keyArray, key, JNI_ABORT);
00441 }
00442 }
00443
00444 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_setIV(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jbyteArray ivArray)
00445 {
00446 if (ivArray == (jbyteArray) 0)
00447 {
00448 (void) ((const blockCipher*) ciph)->setiv((blockCipherParam*) param, 0);
00449 }
00450 else
00451 {
00452 jsize ivsize = (*env)->GetArrayLength(env, ivArray);
00453
00454 if (ivsize > 0)
00455 {
00456 jbyte* iv = (*env)->GetByteArrayElements(env, ivArray, (jboolean*) 0);
00457
00458 if (iv == (jbyte*) 0)
00459 {
00460 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00461 if (ex)
00462 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00463 return;
00464 }
00465
00466 if (!WORDS_BIGENDIAN || ((int) iv & 0x3) || (ivsize & 0x3))
00467 {
00468 int size = (ivsize + 3) >> 2;
00469 uint32* data = (uint32*) malloc(size * sizeof(uint32));
00470
00471 if (data == (uint32*) 0)
00472 {
00473 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00474 (*env)->ReleaseByteArrayElements(env, ivArray, iv, JNI_ABORT);
00475 if (ex)
00476 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00477 return;
00478 }
00479
00480 (void) decodeIntsPartial(data, iv, ivsize);
00481 (void) ((const blockCipher*) ciph)->setiv((blockCipherParam*) param, data);
00482 free(data);
00483 }
00484 else
00485 {
00486 (void) ((const blockCipher*) ciph)->setiv((blockCipherParam*) param, (uint32*) iv);
00487 }
00488 (*env)->ReleaseByteArrayElements(env, ivArray, iv, JNI_ABORT);
00489 }
00490 }
00491 }
00492
00493 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_encryptECB(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jbyteArray inputArray, jint inputOffset, jbyteArray outputArray, jint outputOffset, jint blocks)
00494 {
00495 jbyte* input;
00496 jbyte* output;
00497
00498 input = (*env)->GetByteArrayElements(env, inputArray, (jboolean*) 0);
00499 if (input == (jbyte*) 0)
00500 {
00501 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00502 if (ex)
00503 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00504 return;
00505 }
00506 output = (*env)->GetByteArrayElements(env, outputArray, (jboolean*) 0);
00507 if (input == (jbyte*) 0)
00508 {
00509 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00510 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00511 if (ex)
00512 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00513 return;
00514 }
00515
00516 if (((long) (input+inputOffset) & 0x3) || ((long) (output+outputOffset) & 0x3))
00517 {
00518 uint32* datain;
00519 uint32* dataout;
00520
00521 datain = (uint32*) malloc(blocks * sizeof(uint32));
00522 if (datain == (uint32*) 0)
00523 {
00524 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00525 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00526 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00527 if (ex)
00528 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00529 return;
00530 }
00531 dataout = (uint32*) malloc(blocks * sizeof(uint32));
00532 if (dataout == (uint32*) 0)
00533 {
00534 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00535 free(datain);
00536 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00537 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00538 if (ex)
00539 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00540 return;
00541 }
00542 memcpy(datain, input+inputOffset, blocks * sizeof(uint32));
00543 (void) blockEncrypt((const blockCipher*) ciph, (blockCipherParam*) param, ECB, blocks, dataout, datain);
00544 memcpy(output+outputOffset, dataout, blocks * sizeof(uint32));
00545 }
00546 else
00547 {
00548 (void) blockEncrypt((const blockCipher*) ciph, (blockCipherParam*) param, ECB, blocks, (uint32*)(output+outputOffset), (uint32*) (input+inputOffset));
00549 }
00550
00551 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00552 (*env)->ReleaseByteArrayElements(env, outputArray, output, 0);
00553 }
00554
00555 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_decryptECB(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jbyteArray inputArray, jint inputOffset, jbyteArray outputArray, jint outputOffset, jint blocks)
00556 {
00557 jbyte* input;
00558 jbyte* output;
00559
00560 input = (*env)->GetByteArrayElements(env, inputArray, (jboolean*) 0);
00561 if (input == (jbyte*) 0)
00562 {
00563 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00564 if (ex)
00565 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00566 return;
00567 }
00568 output = (*env)->GetByteArrayElements(env, outputArray, (jboolean*) 0);
00569 if (input == (jbyte*) 0)
00570 {
00571 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00572 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00573 if (ex)
00574 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00575 return;
00576 }
00577
00578 if (((long) (input+inputOffset) & 0x3) || ((long) (output+outputOffset) & 0x3))
00579 {
00580 uint32* datain;
00581 uint32* dataout;
00582
00583 datain = (uint32*) malloc(blocks * sizeof(uint32));
00584 if (datain == (uint32*) 0)
00585 {
00586 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00587 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00588 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00589 if (ex)
00590 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00591 return;
00592 }
00593 dataout = (uint32*) malloc(blocks * sizeof(uint32));
00594 if (dataout == (uint32*) 0)
00595 {
00596 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00597 free(datain);
00598 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00599 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00600 if (ex)
00601 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00602 return;
00603 }
00604 memcpy(datain, input+inputOffset, blocks * sizeof(uint32));
00605 (void) blockDecrypt((const blockCipher*) ciph, (blockCipherParam*) param, ECB, blocks, dataout, datain);
00606 memcpy(output+outputOffset, dataout, blocks * sizeof(uint32));
00607 }
00608 else
00609 {
00610 (void) blockDecrypt((const blockCipher*) ciph, (blockCipherParam*) param, ECB, blocks, (uint32*)(output+outputOffset), (uint32*) (input+inputOffset));
00611 }
00612
00613 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00614 (*env)->ReleaseByteArrayElements(env, outputArray, output, 0);
00615 }
00616
00617 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_encryptCBC(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jbyteArray inputArray, jint inputOffset, jbyteArray outputArray, jint outputOffset, jint blocks)
00618 {
00619 jbyte* input;
00620 jbyte* output;
00621
00622 input = (*env)->GetByteArrayElements(env, inputArray, (jboolean*) 0);
00623 if (input == (jbyte*) 0)
00624 {
00625 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00626 if (ex)
00627 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00628 return;
00629 }
00630 output = (*env)->GetByteArrayElements(env, outputArray, (jboolean*) 0);
00631 if (input == (jbyte*) 0)
00632 {
00633 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00634 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00635 if (ex)
00636 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00637 return;
00638 }
00639
00640 if (((long) (input+inputOffset) & 0x3) || ((long) (output+outputOffset) & 0x3))
00641 {
00642 uint32* datain;
00643 uint32* dataout;
00644
00645 datain = (uint32*) malloc(blocks * sizeof(uint32));
00646 if (datain == (uint32*) 0)
00647 {
00648 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00649 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00650 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00651 if (ex)
00652 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00653 return;
00654 }
00655 dataout = (uint32*) malloc(blocks * sizeof(uint32));
00656 if (dataout == (uint32*) 0)
00657 {
00658 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00659 free(datain);
00660 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00661 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00662 if (ex)
00663 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00664 return;
00665 }
00666 memcpy(datain, input+inputOffset, blocks * sizeof(uint32));
00667 (void) blockEncrypt((const blockCipher*) ciph, (blockCipherParam*) param, CBC, blocks, dataout, datain);
00668 memcpy(output+outputOffset, dataout, blocks * sizeof(uint32));
00669 }
00670 else
00671 {
00672 (void) blockEncrypt((const blockCipher*) ciph, (blockCipherParam*) param, CBC, blocks, (uint32*)(output+outputOffset), (uint32*) (input+inputOffset));
00673 }
00674
00675 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00676 (*env)->ReleaseByteArrayElements(env, outputArray, output, 0);
00677 }
00678
00679 void JNICALL Java_beecrypt_crypto_NativeBlockCipher_decryptCBC(JNIEnv* env, jclass dummy, jlong ciph, jlong param, jbyteArray inputArray, jint inputOffset, jbyteArray outputArray, jint outputOffset, jint blocks)
00680 {
00681 jbyte* input;
00682 jbyte* output;
00683
00684 input = (*env)->GetByteArrayElements(env, inputArray, (jboolean*) 0);
00685 if (input == (jbyte*) 0)
00686 {
00687 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00688 if (ex)
00689 (void) (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00690 return;
00691 }
00692 output = (*env)->GetByteArrayElements(env, outputArray, (jboolean*) 0);
00693 if (input == (jbyte*) 0)
00694 {
00695 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00696 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00697 if (ex)
00698 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00699 return;
00700 }
00701
00702 if (((long) (input+inputOffset) & 0x3) || ((long) (output+outputOffset) & 0x3))
00703 {
00704 uint32* datain;
00705 uint32* dataout;
00706
00707 datain = (uint32*) malloc(blocks * sizeof(uint32));
00708 if (datain == (uint32*) 0)
00709 {
00710 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00711 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00712 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00713 if (ex)
00714 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00715 return;
00716 }
00717 dataout = (uint32*) malloc(blocks * sizeof(uint32));
00718 if (dataout == (uint32*) 0)
00719 {
00720 jclass ex = (*env)->FindClass(env, JAVA_OUT_OF_MEMORY_ERROR);
00721 free(datain);
00722 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00723 (*env)->ReleaseByteArrayElements(env, outputArray, output, JNI_ABORT);
00724 if (ex)
00725 (void) (*env)->ThrowNew(env, ex, MSG_OUT_OF_MEMORY);
00726 return;
00727 }
00728 memcpy(datain, input+inputOffset, blocks * sizeof(uint32));
00729 (void) blockDecrypt((const blockCipher*) ciph, (blockCipherParam*) param, CBC, blocks, dataout, datain);
00730 memcpy(output+outputOffset, dataout, blocks * sizeof(uint32));
00731 }
00732 else
00733 {
00734 (void) blockDecrypt((const blockCipher*) ciph, (blockCipherParam*) param, CBC, blocks, (uint32*)(output+outputOffset), (uint32*) (input+inputOffset));
00735 }
00736
00737 (*env)->ReleaseByteArrayElements(env, inputArray, input, JNI_ABORT);
00738 (*env)->ReleaseByteArrayElements(env, outputArray, output, 0);
00739 }
00740
00741
00742
00743
00744
00745 #endif