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