1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Native glue for Java class org.openssl.NativeBN 19 */ 20 21 #include <jni.h> 22 #include <JNIHelp.h> 23 #include <openssl/err.h> 24 #include <openssl/crypto.h> 25 #include <openssl/bn.h> 26 #include <stdio.h> 27 28 #define mcSignednessBull void * 29 #ifndef FALSE 30 #define FALSE 0 31 #define TRUE 1 32 #endif 33 34 static int isValidHandle (JNIEnv* env, void* handle, const char *message) { 35 if (handle == NULL) { 36 jniThrowNullPointerException(env, message); 37 return FALSE; 38 } 39 return TRUE; 40 } 41 42 static int oneValidHandle (JNIEnv* env, void* a) 43 { 44 return isValidHandle(env, a, "Mandatory handle (first) passed as null"); 45 } 46 47 static int twoValidHandles (JNIEnv* env, void* a, void *b) 48 { 49 if (!oneValidHandle(env, a)) return FALSE; 50 return isValidHandle(env, b, "Mandatory handle (second) passed as null"); 51 } 52 53 static int threeValidHandles (JNIEnv* env, void* a, void *b, void* c) 54 { 55 if (!twoValidHandles(env, a, b)) return FALSE; 56 return isValidHandle(env, c, "Mandatory handle (third) passed as null"); 57 } 58 59 static int fourValidHandles (JNIEnv* env, void* a, void *b, void* c, void* d) 60 { 61 if (!threeValidHandles(env, a, b, c)) return FALSE; 62 return isValidHandle(env, d, "Mandatory handle (fourth) passed as null"); 63 } 64 65 66 /** 67 * public static native int ERR_get_error(); 68 */ 69 static unsigned long NativeBN_ERR_get_error(JNIEnv* env, jclass cls) { 70 unsigned long e = ERR_get_error(); 71 return e; 72 } 73 74 /** 75 * public static native String ERR_error_string(int); 76 */ 77 static jstring NativeBN_ERR_error_string(JNIEnv* env, jclass cls, unsigned long e) { 78 jstring returnJString = 0; 79 char* errStr; 80 errStr = ERR_error_string(e, NULL); 81 returnJString = ((*env)->NewStringUTF(env, (mcSignednessBull)errStr)); 82 return returnJString; 83 } 84 85 86 /** 87 * public static native int BN_CTX_new() 88 */ 89 static BN_CTX* NativeBN_BN_CTX_new(JNIEnv* env, jclass cls) { 90 return BN_CTX_new(); 91 } 92 93 94 /** 95 * public static native int BN_new() 96 */ 97 static BIGNUM* NativeBN_BN_new(JNIEnv* env, jclass cls) { 98 return BN_new(); 99 } 100 101 /** 102 * public static native int BN_free() 103 */ 104 static void NativeBN_BN_free(JNIEnv* env, jclass cls, BIGNUM* a) { 105 if (!oneValidHandle(env, a)) return; 106 BN_free(a); 107 } 108 109 110 /** 111 * public static native int BN_cmp(int, int) 112 */ 113 static int NativeBN_BN_cmp(JNIEnv* env, jclass cls, BIGNUM* a, BIGNUM* b) { 114 if (!twoValidHandles(env, a, b)) return 1; 115 return BN_cmp(a, b); 116 } 117 118 /** 119 * public static native int BN_copy(int, int) 120 */ 121 static jboolean NativeBN_BN_copy(JNIEnv* env, jclass cls, BIGNUM* to, BIGNUM* from) { 122 if (!twoValidHandles(env, to, from)) return FALSE; 123 return (BN_copy(to, from) != NULL); 124 } 125 126 127 /** 128 * public static native int putULongInt(int, long, int) 129 */ 130 static jboolean NativeBN_putULongInt(JNIEnv* env, jclass cls, BIGNUM* a, unsigned long long dw, jboolean neg) { 131 if (!oneValidHandle(env, a)) return FALSE; 132 unsigned int hi = dw >> 32; // This shifts without sign extension. 133 int lo = (int)dw; // This truncates implicitely. 134 135 // cf. litEndInts2bn: 136 bn_check_top(a); 137 if (bn_wexpand(a, 2) != NULL) { 138 a->d[0] = lo; 139 a->d[1] = hi; 140 a->top = 2; 141 a->neg = neg; 142 bn_correct_top(a); 143 return TRUE; 144 } 145 else return FALSE; 146 } 147 148 /** 149 * public static native int putLongInt(int, long) 150 */ 151 static jboolean NativeBN_putLongInt(JNIEnv* env, jclass cls, BIGNUM* a, long long dw) { 152 if (dw >= 0) return NativeBN_putULongInt(env, cls, a, dw, FALSE); 153 else return NativeBN_putULongInt(env, cls, a, -dw, TRUE); 154 } 155 156 /** 157 * public static native int BN_dec2bn(int, java.lang.String) 158 */ 159 static int NativeBN_BN_dec2bn(JNIEnv* env, jclass cls, BIGNUM* a, jstring str) { 160 if (!oneValidHandle(env, a)) return -1; 161 char* tmpStr = (char*)(*env)->GetStringUTFChars(env, str, NULL); 162 if (tmpStr != NULL) { 163 int len = BN_dec2bn(&a, tmpStr); 164 (*env)->ReleaseStringUTFChars(env, str, tmpStr); 165 return len; // len == 0: Error 166 } 167 else return -1; // Error outside BN. 168 } 169 170 /** 171 * public static native int BN_hex2bn(int, java.lang.String) 172 */ 173 static int NativeBN_BN_hex2bn(JNIEnv* env, jclass cls, BIGNUM* a, jstring str) { 174 if (!oneValidHandle(env, a)) return -1; 175 char* tmpStr = (char*)(*env)->GetStringUTFChars(env, str, NULL); 176 if (tmpStr != NULL) { 177 int len = BN_hex2bn(&a, tmpStr); 178 (*env)->ReleaseStringUTFChars(env, str, tmpStr); 179 return len; // len == 0: Error 180 } 181 else return -1; // Error outside BN. 182 } 183 184 /** 185 * public static native boolean BN_bin2bn(byte[], int, int, int) 186 */ 187 static jboolean NativeBN_BN_bin2bn(JNIEnv* env, jclass cls, jbyteArray arr, int len, jboolean neg, BIGNUM* ret) { 188 if (!oneValidHandle(env, ret)) return FALSE; 189 jboolean success; 190 unsigned char * tmpBytes; 191 tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, arr, 0)); 192 if (tmpBytes != NULL) { 193 success = (BN_bin2bn(tmpBytes, len, ret) != NULL); 194 if (neg) { 195 BN_set_negative(ret, 1); 196 } 197 (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpBytes, JNI_ABORT); 198 return success; 199 } 200 else return -1; // Error outside BN. mc FIXME: what to do in this case? Does JNI throw exception itself? 201 } 202 203 /** 204 * public static native boolean litEndInts2bn(int[], int, int, int) 205 * Note: 206 * This procedure directly writes the internal representation of BIGNUMs. 207 * We do so as there is no direct interface based on Little Endian Integer Arrays. 208 * Also note that the same representation is used in the Cordoba Java Implementation of BigIntegers, 209 * whereof certain functionality is still being used. 210 */ 211 static jboolean NativeBN_litEndInts2bn(JNIEnv* env, jclass cls, jintArray arr, int len, jboolean neg, BIGNUM* ret) { 212 if (!oneValidHandle(env, ret)) return FALSE; 213 bn_check_top(ret); 214 if (len > 0) { 215 BN_ULONG* tmpInts; // BN_ULONG is 4 Bytes on this system for sure, i.e. same as jint! 216 tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, arr, 0)); 217 if ((tmpInts != NULL) && (bn_wexpand(ret, len) != NULL)) { 218 int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0); 219 (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpInts, JNI_ABORT); 220 ret->top = len; 221 ret->neg = neg; 222 // need to call this due to clear byte at top if avoiding 223 // having the top bit set (-ve number) 224 // Basically get rid of top zero ints: 225 bn_correct_top(ret); 226 return TRUE; 227 } 228 else { 229 if (tmpInts != NULL) 230 (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpInts, JNI_ABORT); 231 return FALSE; 232 } 233 } 234 else { // (len = 0) means value = 0 and sign will be 0, too. 235 ret->top = 0; 236 return TRUE; 237 } 238 } 239 240 241 #define BYTES2INT(bytes, k) \ 242 ( (bytes[k + 3] & 0xFF) \ 243 | (bytes[k + 2] & 0xFF) << 8 \ 244 | (bytes[k + 1] & 0xFF) << 16 \ 245 | (bytes[k + 0] & 0xFF) << 24 ) 246 247 static jboolean negBigEndianBytes2bn(JNIEnv* env, jclass cls, unsigned char* bytes, int bytesLen, BIGNUM* ret) { 248 // We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes: 249 // 250 bn_check_top(ret); 251 // FIXME: ASSERT (bytesLen > 0); 252 int intLen = (bytesLen + 3) / 4; 253 int firstNonzeroDigit = -2; 254 if (bn_wexpand(ret, intLen) != NULL) { 255 BN_ULONG* d = ret->d; 256 BN_ULONG di; 257 ret->top = intLen; 258 int highBytes = bytesLen % 4; 259 int k = bytesLen; 260 // Put bytes to the int array starting from the end of the byte array 261 int i = 0; 262 while (k > highBytes) { 263 k -= 4; 264 di = BYTES2INT(bytes, k); 265 if (di != 0) { 266 d[i] = -di; 267 firstNonzeroDigit = i; 268 i++; 269 while (k > highBytes) { 270 k -= 4; 271 d[i] = ~BYTES2INT(bytes, k); 272 i++; 273 } 274 break; 275 } else { 276 d[i] = 0; 277 i++; 278 } 279 } 280 if (highBytes != 0) { 281 di = -1; 282 // Put the first bytes in the highest element of the int array 283 if (firstNonzeroDigit != -2) { 284 for (k = 0; k < highBytes; k++) { 285 di = (di << 8) | (bytes[k] & 0xFF); 286 } 287 d[i] = ~di; 288 } else { 289 for (k = 0; k < highBytes; k++) { 290 di = (di << 8) | (bytes[k] & 0xFF); 291 } 292 d[i] = -di; 293 } 294 } 295 return TRUE; 296 } 297 else return FALSE; 298 } 299 300 /** 301 * public static native boolean twosComp2bn(byte[], int, int) 302 */ 303 static jboolean NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, BIGNUM* ret) { 304 if (!oneValidHandle(env, ret)) return FALSE; 305 jboolean success; 306 unsigned char* tmpBytes; 307 tmpBytes = (unsigned char*)((*env)->GetPrimitiveArrayCritical(env, arr, 0)); 308 if (tmpBytes != NULL) { 309 if ((tmpBytes[0] & 0X80) == 0) { // Positive value! 310 // 311 // We can use the existing BN implementation for unsigned big endian bytes: 312 // 313 success = (BN_bin2bn(tmpBytes, bytesLen, ret) != NULL); 314 BN_set_negative(ret, FALSE); 315 } 316 else { // Negative value! 317 // 318 // We need to apply two's complement: 319 // 320 success = negBigEndianBytes2bn(env, cls, tmpBytes, bytesLen, ret); 321 BN_set_negative(ret, TRUE); 322 } 323 (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpBytes, JNI_ABORT); 324 return success; 325 } 326 else return -1; // Error outside BN. mc FIXME: what to do in this case? Does JNI throw exception itself? 327 } 328 329 330 /** 331 * public static native long longInt(int) 332 */ 333 static long long NativeBN_longInt(JNIEnv* env, jclass cls, BIGNUM* a) { 334 if (!oneValidHandle(env, a)) return -1; 335 bn_check_top(a); 336 int intLen = a->top; 337 BN_ULONG* d = a->d; 338 switch (intLen) { 339 case 0: 340 return 0; 341 case 1: 342 if (!a->neg) return d[0] & 0X00000000FFFFFFFFLL; 343 else return -(d[0] & 0X00000000FFFFFFFFLL); 344 default: 345 if (!a->neg) return ((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL); 346 else return -(((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL)); 347 } 348 } 349 350 351 static char* leadingZerosTrimmed(char* s) { 352 char* p = s; 353 if (*p == '-') { 354 p++; 355 while ((*p == '0') && (*(p + 1) != 0)) { p++; } 356 p--; 357 *p = '-'; 358 } else { 359 while ((*p == '0') && (*(p + 1) != 0)) { p++; } 360 } 361 return p; 362 } 363 364 /** 365 * public static native java.lang.String BN_bn2dec(int) 366 */ 367 static jstring NativeBN_BN_bn2dec(JNIEnv* env, jclass cls, BIGNUM* a) { 368 if (!oneValidHandle(env, a)) return NULL; 369 char* tmpStr; 370 char* retStr; 371 tmpStr = BN_bn2dec(a); 372 if (tmpStr != NULL) { 373 retStr = leadingZerosTrimmed(tmpStr); 374 jstring returnJString = ((*env)->NewStringUTF(env, (mcSignednessBull)retStr)); 375 OPENSSL_free(tmpStr); 376 return returnJString; 377 } 378 else return NULL; 379 } 380 381 /** 382 * public static native java.lang.String BN_bn2hex(int) 383 */ 384 static jstring NativeBN_BN_bn2hex(JNIEnv* env, jclass cls, BIGNUM* a) { 385 if (!oneValidHandle(env, a)) return NULL; 386 char* tmpStr; 387 char* retStr; 388 tmpStr = BN_bn2hex(a); 389 if (tmpStr != NULL) { 390 retStr = leadingZerosTrimmed(tmpStr); 391 jstring returnJString = ((*env)->NewStringUTF(env, (mcSignednessBull)retStr)); 392 OPENSSL_free(tmpStr); 393 return returnJString; 394 } 395 else return NULL; 396 } 397 398 /** 399 * public static native byte[] BN_bn2bin(int, byte[]) 400 */ 401 static jbyteArray NativeBN_BN_bn2bin(JNIEnv* env, jclass cls, BIGNUM* a, jbyteArray to) { 402 if (!oneValidHandle(env, a)) return NULL; 403 jbyteArray returnJBytes = to; 404 unsigned char * tmpBytes; 405 int len, byteCnt; 406 byteCnt = BN_num_bytes(a); 407 // FIXME: Currently ignoring array passed in to: 408 returnJBytes = (*env)->NewByteArray(env, byteCnt); 409 // FIXME: is it neccessary to check for returnJBytes != NULL? 410 tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, NULL)); 411 if (tmpBytes != NULL) { 412 len = BN_bn2bin(a, tmpBytes); 413 (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, 0); 414 return returnJBytes; 415 } 416 else return NULL; 417 } 418 419 /** 420 * public static native int[] bn2litEndInts(int, int[]) 421 * cf. litEndInts2bn 422 */ 423 static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass cls, BIGNUM* a, jintArray to) { 424 if (!oneValidHandle(env, a)) return NULL; 425 jintArray returnJInts = to; 426 bn_check_top(a); 427 int len = a->top; 428 if (len > 0) { 429 // FIXME: Currently ignoring array passed in to: 430 returnJInts = (*env)->NewIntArray(env, len); 431 // FIXME: is it neccessary to check for returnJBytes != NULL? 432 BN_ULONG* tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, returnJInts, NULL)); 433 if (tmpInts != NULL) { 434 int i = len; do { i--; tmpInts[i] = a->d[i]; } while (i > 0); 435 (*env)->ReleasePrimitiveArrayCritical(env, returnJInts, tmpInts, 0); 436 return returnJInts; 437 } 438 else return NULL; 439 } 440 else { // value = 0 441 return NULL; // Client should not call when sign = 0! 442 } 443 } 444 445 446 /** 447 * public static native int sign(int) 448 */ 449 static int NativeBN_sign(JNIEnv* env, jclass cls, BIGNUM* a) { 450 if (!oneValidHandle(env, a)) return -2; 451 if (BN_is_zero(a)) return 0; 452 else if (BN_is_negative(a)) return -1; 453 else return 1; 454 } 455 456 /** 457 * public static native void BN_set_negative(int, int) 458 */ 459 static void NativeBN_BN_set_negative(JNIEnv* env, jclass cls, BIGNUM* b, int n) { 460 if (!oneValidHandle(env, b)) return; 461 BN_set_negative(b, n); 462 } 463 464 /** 465 * public static native int bitLength(int) 466 */ 467 static int NativeBN_bitLength(JNIEnv* env, jclass cls, BIGNUM* a) { 468 // We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes: 469 // 470 if (!oneValidHandle(env, a)) return FALSE; 471 bn_check_top(a); 472 int intLen = a->top; 473 if (intLen == 0) return 0; 474 BN_ULONG* d = a->d; 475 int i = intLen - 1; 476 BN_ULONG msd = d[i]; // most significant digit 477 if (a->neg) { 478 // Handle negative values correctly: 479 // i.e. decrement the msd if all other digits are 0: 480 // while ((i > 0) && (d[i] != 0)) { i--; } 481 do { i--; } while (!((i < 0) || (d[i] != 0))); 482 if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one. 483 } 484 return (intLen - 1) * 32 + BN_num_bits_word(msd); 485 } 486 487 /** 488 * public static native boolean BN_is_bit_set(int, int) 489 */ 490 static jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass cls, BIGNUM* a, int n) { 491 if (!oneValidHandle(env, a)) return FALSE; 492 return (jboolean)BN_is_bit_set(a, n); 493 } 494 495 /** 496 * public static native void modifyBit(int, int, int) 497 */ 498 static jboolean NativeBN_modifyBit(JNIEnv* env, jclass cls, BIGNUM* a, int n, int op) { 499 // LOGD("NativeBN_BN_modifyBit"); 500 if (!oneValidHandle(env, a)) return FALSE; 501 switch (op) { 502 case 1: return BN_set_bit(a, n); 503 case 0: return BN_clear_bit(a, n); 504 case -1: 505 if (BN_is_bit_set(a, n)) return BN_clear_bit(a, n); 506 else return BN_set_bit(a, n); 507 } 508 return FALSE; 509 } 510 511 /** 512 * public static native int BN_lshift(int, int, int) 513 */ 514 static jboolean NativeBN_BN_lshift(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, int n) { 515 // LOGD("NativeBN_BN_lshift %p %p %d", r, a, n); 516 if (!twoValidHandles(env, r, a)) return FALSE; 517 if (n >= 0) return BN_lshift(r, a, n); 518 519 n = -n; 520 // return BN_rshift(r, a, n); 521 // Following code insourced from bn_shift.c in order to have bug fixed: 522 // FIXME: Should report to openssl team!!! 523 524 int i,j,nw,lb,rb; 525 BN_ULONG *t,*f; 526 BN_ULONG l,tmp; 527 528 bn_check_top(r); 529 bn_check_top(a); 530 531 nw=n/BN_BITS2; 532 rb=n%BN_BITS2; 533 lb=BN_BITS2-rb; 534 // Changed "nw > a->top || a->top == 0" to nw >= a->top" as considering this a bug: 535 if (nw >= a->top) 536 { 537 BN_zero(r); 538 return(1); 539 } 540 if (r != a) 541 { 542 r->neg=a->neg; 543 if (bn_wexpand(r,a->top-nw+1) == NULL) return(0); 544 } 545 else 546 { 547 if (n == 0) 548 return 1; /* or the copying loop will go berserk */ 549 } 550 551 f= &(a->d[nw]); 552 t=r->d; 553 j=a->top-nw; 554 r->top=j; 555 556 if (rb == 0) 557 { 558 for (i=j; i != 0; i--) 559 *(t++)= *(f++); 560 } 561 else 562 { 563 l= *(f++); 564 for (i=j-1; i != 0; i--) 565 { 566 tmp =(l>>rb)&BN_MASK2; 567 l= *(f++); 568 *(t++) =(tmp|(l<<lb))&BN_MASK2; 569 } 570 *(t++) =(l>>rb)&BN_MASK2; 571 } 572 bn_correct_top(r); 573 bn_check_top(r); 574 return(1); 575 } 576 577 578 /** 579 * public static native boolean BN_add_word(int, int) 580 */ 581 static jboolean NativeBN_BN_add_word(JNIEnv* env, jclass cls, BIGNUM *a, BN_ULONG w) { 582 if (!oneValidHandle(env, a)) return FALSE; 583 return BN_add_word(a, w); 584 } 585 586 /** 587 * public static native boolean BN_sub_word(int, int) 588 */ 589 static jboolean NativeBN_BN_sub_word(JNIEnv* env, jclass cls, BIGNUM *a, BN_ULONG w) { 590 if (!oneValidHandle(env, a)) return FALSE; 591 return BN_sub_word(a, w); 592 } 593 594 /** 595 * public static native boolean BN_mul_word(int, int) 596 */ 597 static jboolean NativeBN_BN_mul_word(JNIEnv* env, jclass cls, BIGNUM *a, BN_ULONG w) { 598 if (!oneValidHandle(env, a)) return FALSE; 599 return BN_mul_word(a, w); 600 } 601 602 /** 603 * public static native boolean BN_div_word(int, int) 604 */ 605 static BN_ULONG NativeBN_BN_div_word(JNIEnv* env, jclass cls, BIGNUM *a, BN_ULONG w) { 606 if (!oneValidHandle(env, a)) return FALSE; 607 return BN_div_word(a, w); 608 } 609 610 /** 611 * public static native boolean BN_mod_word(int, int) 612 */ 613 static BN_ULONG NativeBN_BN_mod_word(JNIEnv* env, jclass cls, BIGNUM *a, BN_ULONG w) { 614 if (!oneValidHandle(env, a)) return FALSE; 615 return BN_mod_word(a, w); 616 } 617 618 619 620 /** 621 * public static native int BN_add(int, int, int) 622 */ 623 static jboolean NativeBN_BN_add(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* b) { 624 if (!threeValidHandles(env, r, a, b)) return FALSE; 625 return BN_add(r, a, b); 626 } 627 628 /** 629 * public static native int BN_sub(int, int, int) 630 */ 631 static jboolean NativeBN_BN_sub(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* b) { 632 if (!threeValidHandles(env, r, a, b)) return FALSE; 633 return BN_sub(r, a, b); 634 } 635 636 637 /** 638 * public static native int BN_gcd(int, int, int, int) 639 */ 640 static jboolean NativeBN_BN_gcd(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* b, BN_CTX* ctx) { 641 if (!threeValidHandles(env, r, a, b)) return FALSE; 642 return BN_gcd(r, a, b, ctx); 643 } 644 645 /** 646 * public static native int BN_mul(int, int, int, int) 647 */ 648 static jboolean NativeBN_BN_mul(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* b, BN_CTX* ctx) { 649 if (!threeValidHandles(env, r, a, b)) return FALSE; 650 return BN_mul(r, a, b, ctx); 651 } 652 653 /** 654 * public static native int BN_exp(int, int, int, int) 655 */ 656 static jboolean NativeBN_BN_exp(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* p, BN_CTX* ctx) { 657 if (!threeValidHandles(env, r, a, p)) return FALSE; 658 return BN_exp(r, a, p, ctx); 659 } 660 661 /** 662 * public static native boolean BN_div(int, int, int, int, int) 663 */ 664 static jboolean NativeBN_BN_div(JNIEnv* env, jclass cls, BIGNUM* dv, BIGNUM* rem, BIGNUM* m, BIGNUM* d, BN_CTX* ctx) { 665 if (!fourValidHandles(env, (rem ? rem : dv), (dv ? dv : rem), m, d)) return FALSE; 666 return BN_div(dv, rem, m, d, ctx); 667 } 668 669 /** 670 * public static native int BN_nnmod(int, int, int, int) 671 */ 672 static jboolean NativeBN_BN_nnmod(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* m, BN_CTX* ctx) { 673 if (!threeValidHandles(env, r, a, m)) return FALSE; 674 return BN_nnmod(r, a, m, ctx); 675 } 676 677 /** 678 * public static native int BN_mod_exp(int, int, int, int, int) 679 */ 680 static jboolean NativeBN_BN_mod_exp(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, BIGNUM* p, BIGNUM* m, BN_CTX* ctx) { 681 if (!fourValidHandles(env, r, a, p, m)) return FALSE; 682 return BN_mod_exp(r, a, p, m, ctx); 683 } 684 685 686 /** 687 * public static native int BN_mod_inverse(int, int, int, int) 688 */ 689 static jboolean NativeBN_BN_mod_inverse(JNIEnv* env, jclass cls, BIGNUM* ret, BIGNUM* a, BIGNUM* n, BN_CTX* ctx) { 690 if (!threeValidHandles(env, ret, a, n)) return FALSE; 691 return (BN_mod_inverse(ret, a, n, ctx) != NULL); 692 } 693 694 695 /** 696 * public static native int BN_generate_prime_ex(int, int, boolean, int, int, int) 697 */ 698 static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass cls, BIGNUM* ret, int bits, jboolean safe, 699 BIGNUM* add, BIGNUM* rem, jint cb) { 700 if (!oneValidHandle(env, ret)) return FALSE; 701 return BN_generate_prime_ex(ret, bits, safe, add, rem, cb); 702 } 703 704 /** 705 * public static native int BN_mod_inverse(int, int, int, int) 706 */ 707 static jboolean NativeBN_BN_is_prime_ex(JNIEnv* env, jclass cls, BIGNUM* p, int nchecks, BN_CTX* ctx, jint cb) { 708 if (!oneValidHandle(env, p)) return FALSE; 709 return BN_is_prime_ex(p, nchecks, ctx, cb); 710 } 711 712 713 /** 714 * Defines the mapping from Java methods and their signatures 715 * to native functions. Order is Java name, Java signature, 716 * then pointer to C function. 717 */ 718 static JNINativeMethod METHODS[] = { 719 { "ERR_get_error", "()I", (void*)NativeBN_ERR_get_error }, 720 { "ERR_error_string", "(I)Ljava/lang/String;", (void*)NativeBN_ERR_error_string }, 721 { "BN_CTX_new", "()I", (void*)NativeBN_BN_CTX_new }, 722 { "BN_new", "()I", (void*)NativeBN_BN_new }, 723 { "BN_free", "(I)V", (void*)NativeBN_BN_free }, 724 { "BN_cmp", "(II)I", (void*)NativeBN_BN_cmp }, 725 { "BN_copy", "(II)Z", (void*)NativeBN_BN_copy }, 726 { "putLongInt", "(IJ)Z", (void*)NativeBN_putLongInt }, 727 { "putULongInt", "(IJZ)Z", (void*)NativeBN_putULongInt }, 728 { "BN_dec2bn", "(ILjava/lang/String;)I", (void*)NativeBN_BN_dec2bn }, 729 { "BN_hex2bn", "(ILjava/lang/String;)I", (void*)NativeBN_BN_hex2bn }, 730 { "BN_bin2bn", "([BIZI)Z", (void*)NativeBN_BN_bin2bn }, 731 { "litEndInts2bn", "([IIZI)Z", (void*)NativeBN_litEndInts2bn }, 732 { "twosComp2bn", "([BII)Z", (void*)NativeBN_twosComp2bn }, 733 { "longInt", "(I)J", (void*)NativeBN_longInt }, 734 { "BN_bn2dec", "(I)Ljava/lang/String;", (void*)NativeBN_BN_bn2dec }, 735 { "BN_bn2hex", "(I)Ljava/lang/String;", (void*)NativeBN_BN_bn2hex }, 736 { "BN_bn2bin", "(I[B)[B", (void*)NativeBN_BN_bn2bin }, 737 { "bn2litEndInts", "(I[I)[I", (void*)NativeBN_bn2litEndInts }, 738 { "sign", "(I)I", (void*)NativeBN_sign }, 739 { "BN_set_negative", "(II)V", (void*)NativeBN_BN_set_negative }, 740 { "bitLength", "(I)I", (void*)NativeBN_bitLength }, 741 { "BN_is_bit_set", "(II)Z", (void*)NativeBN_BN_is_bit_set }, 742 { "modifyBit", "(III)Z", (void*)NativeBN_modifyBit }, 743 { "BN_lshift", "(III)Z", (void*)NativeBN_BN_lshift }, 744 { "BN_add_word", "(II)Z", (void*)NativeBN_BN_add_word }, 745 { "BN_sub_word", "(II)Z", (void*)NativeBN_BN_sub_word }, 746 { "BN_mul_word", "(II)Z", (void*)NativeBN_BN_mul_word }, 747 { "BN_div_word", "(II)I", (void*)NativeBN_BN_div_word }, 748 { "BN_mod_word", "(II)I", (void*)NativeBN_BN_mod_word }, 749 { "BN_add", "(III)Z", (void*)NativeBN_BN_add }, 750 { "BN_sub", "(III)Z", (void*)NativeBN_BN_sub }, 751 { "BN_gcd", "(IIII)Z", (void*)NativeBN_BN_gcd }, 752 { "BN_mul", "(IIII)Z", (void*)NativeBN_BN_mul }, 753 { "BN_exp", "(IIII)Z", (void*)NativeBN_BN_exp }, 754 { "BN_div", "(IIIII)Z", (void*)NativeBN_BN_div }, 755 { "BN_nnmod", "(IIII)Z", (void*)NativeBN_BN_nnmod }, 756 { "BN_mod_exp", "(IIIII)Z", (void*)NativeBN_BN_mod_exp }, 757 { "BN_mod_inverse", "(IIII)Z", (void*)NativeBN_BN_mod_inverse }, 758 { "BN_generate_prime_ex", "(IIZIII)Z", (void*)NativeBN_BN_generate_prime_ex }, 759 { "BN_is_prime_ex", "(IIII)Z", (void*)NativeBN_BN_is_prime_ex } 760 }; 761 762 int register_org_openssl_NativeBN(JNIEnv* env) { 763 return jniRegisterNativeMethods(env, "org/openssl/NativeBN", METHODS, NELEM(METHODS)); 764 } 765