/** * public static native void modifyBit(int, int, int) */ static jboolean NativeBN_modifyBit(JNIEnv* env, jclass cls, BIGNUM* a, int n, int op) { // LOGD("NativeBN_BN_modifyBit"); if (!oneValidHandle(env, a)) return FALSE; switch (op) { case 1: return BN_set_bit(a, n); case 0: return BN_clear_bit(a, n); case -1: if (BN_is_bit_set(a, n)) return BN_clear_bit(a, n); else return BN_set_bit(a, n); } return FALSE; }
BIGNUM *BN_mpi2bn(unsigned char *d, int n, BIGNUM *a) { long len; int neg=0; if (n < 4) return(NULL); len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3]; if ((len+4) != n) return(NULL); if (a == NULL) a=BN_new(); if (a == NULL) return(NULL); if (len == 0) { a->neg=0; a->top=0; return(a); } d+=4; if ((*d) & 0x80) neg=1; if (BN_bin2bn(d,(int)len,a) == NULL) return(NULL); a->neg=neg; if (neg) { BN_clear_bit(a,BN_num_bits(a)-1); } return(a); }
// Takes in a BigNum, sets bits 0 and k-1 to 1, bits >= k to 0 void RndOddNum(int numbits, BIGNUM* odd_num, FILE* rndfile) { int num_bytes = ceil(numbits/8.0); unsigned char* num_read = (unsigned char*)calloc(1, num_bytes); if(fread(num_read, 1, num_bytes, rndfile) <= 0) { fprintf(stderr, "ERROR: Ran out of random bits in rndfile!\n"); return; } BN_bin2bn(num_read, num_bytes, odd_num); BN_set_bit(odd_num, 0); BN_set_bit(odd_num, numbits-1); for(int i=numbits; i<num_bytes*8; i++) { BN_clear_bit(odd_num, i); } free(num_read); }
int BN_rand(BIGNUM *bn, int bits, int top, int bottom) { size_t len = (bits + 7) / 8; heim_integer *i = (heim_integer *)bn; BN_clear(bn); i->negative = 0; i->data = malloc(len); if (i->data == NULL && len != 0) return 0; i->length = len; if (RAND_bytes(i->data, i->length) != 1) { free(i->data); i->data = NULL; return 0; } { size_t j = len * 8; while(j > bits) { BN_clear_bit(bn, j - 1); j--; } } if (top == -1) { ; } else if (top == 0 && bits > 0) { BN_set_bit(bn, bits - 1); } else if (top == 1 && bits > 1) { BN_set_bit(bn, bits - 1); BN_set_bit(bn, bits - 2); } else { BN_clear(bn); return 0; } if (bottom && bits > 0) BN_set_bit(bn, 0); return 1; }
BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a) { long len; int neg=0; if (n < 4) { BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH); return(NULL); } len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3]; if ((len+4) != n) { BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR); return(NULL); } if (a == NULL) a=BN_new(); if (a == NULL) return(NULL); if (len == 0) { a->neg=0; a->top=0; return(a); } d+=4; if ((*d) & 0x80) neg=1; if (BN_bin2bn(d,(int)len,a) == NULL) return(NULL); a->neg=neg; if (neg) { BN_clear_bit(a,BN_num_bits(a)-1); } bn_check_top(a); return(a); }
void tests(void) { #ifndef USING_WOLFSSL struct bitmap *b; BIGNUM *bn; size_t len; int i, j, k, n; u_char bbuf[1024], bnbuf[1024]; int r; #else struct bitmap *b; BIGNUM *bn; #endif TEST_START("bitmap_new"); b = bitmap_new(); ASSERT_PTR_NE(b, NULL); bn = BN_new(); ASSERT_PTR_NE(bn, NULL); TEST_DONE(); TEST_START("bitmap_set_bit / bitmap_test_bit"); #ifndef USING_WOLFSSL for (i = -1; i < NTESTS; i++) { for (j = -1; j < NTESTS; j++) { for (k = -1; k < NTESTS; k++) { bitmap_zero(b); /* wolfSSL does not have support for BN_clear at this time */ BN_clear(bn); test_subtest_info("set %d/%d/%d", i, j, k); /* Set bits */ if (i >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, i), 0); ASSERT_INT_EQ(BN_set_bit(bn, i), 1); } if (j >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, j), 0); ASSERT_INT_EQ(BN_set_bit(bn, j), 1); } if (k >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, k), 0); ASSERT_INT_EQ(BN_set_bit(bn, k), 1); } /* Check perfect match between bitmap and bn */ test_subtest_info("match %d/%d/%d", i, j, k); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } /* Test length calculations */ test_subtest_info("length %d/%d/%d", i, j, k); ASSERT_INT_EQ(BN_num_bits(bn), (int)bitmap_nbits(b)); ASSERT_INT_EQ(BN_num_bytes(bn), (int)bitmap_nbytes(b)); /* Test serialisation */ test_subtest_info("serialise %d/%d/%d", i, j, k); len = bitmap_nbytes(b); memset(bbuf, 0xfc, sizeof(bbuf)); ASSERT_INT_EQ(bitmap_to_string(b, bbuf, sizeof(bbuf)), 0); for (n = len; n < (int)sizeof(bbuf); n++) ASSERT_U8_EQ(bbuf[n], 0xfc); r = BN_bn2bin(bn, bnbuf); ASSERT_INT_GE(r, 0); ASSERT_INT_EQ(r, (int)len); ASSERT_MEM_EQ(bbuf, bnbuf, len); /* Test deserialisation */ test_subtest_info("deserialise %d/%d/%d", i, j, k); bitmap_zero(b); ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, len), 0); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } /* Test clearing bits */ test_subtest_info("clear %d/%d/%d", i, j, k); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); ASSERT_INT_EQ(BN_set_bit(bn, n), 1); } if (i >= 0) { bitmap_clear_bit(b, i); /* wolfSSL does not have support for BN_clear_bit at this time */ BN_clear_bit(bn, i); } if (j >= 0) { bitmap_clear_bit(b, j); /* wolfSSL does not have support for BN_clear_bit at this time */ BN_clear_bit(bn, j); } if (k >= 0) { bitmap_clear_bit(b, k); /* wolfSSL does not have support for BN_clear_bit at this time */ BN_clear_bit(bn, k); } for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } } } } #endif /* USING_WOLFSSL */ bitmap_free(b); BN_free(bn); TEST_DONE(); }
static int test_BN_bit(void) { BIGNUM *bn; int ret = 0; bn = BN_new(); /* test setting and getting of "word" */ if (!BN_set_word(bn, 1)) return 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_set_word(bn, 2)) return 1; if (!BN_is_bit_set(bn, 1)) ret += 1; if (!BN_set_word(bn, 3)) return 1; if (!BN_is_bit_set(bn, 0)) ret += 1; if (!BN_is_bit_set(bn, 1)) ret += 1; if (!BN_set_word(bn, 0x100)) return 1; if (!BN_is_bit_set(bn, 8)) ret += 1; if (!BN_set_word(bn, 0x1000)) return 1; if (!BN_is_bit_set(bn, 12)) ret += 1; /* test bitsetting */ if (!BN_set_word(bn, 1)) return 1; if (!BN_set_bit(bn, 1)) return 1; if (BN_get_word(bn) != 3) return 1; if (!BN_clear_bit(bn, 0)) return 1; if (BN_get_word(bn) != 2) return 1; /* test bitsetting past end of current end */ BN_clear(bn); if (!BN_set_bit(bn, 12)) return 1; if (BN_get_word(bn) != 0x1000) return 1; /* test bit and byte counting functions */ if (BN_num_bits(bn) != 13) return 1; if (BN_num_bytes(bn) != 2) return 1; BN_free(bn); return ret; }
static dpl_status_t dpltest_gen_key(BIGNUM *id, uint64_t oid, uint32_t volid, uint8_t serviceid, uint32_t specific) { int off, i; MD5_CTX ctx; char entropy[DPLTEST_PAYLOAD_NBITS/NBBY]; u_char hash[MD5_DIGEST_LENGTH]; BN_zero(id); off = DPLTEST_REPLICA_NBITS + DPLTEST_CLASS_NBITS; for (i = 0;i < DPLTEST_SPECIFIC_NBITS;i++) { if (specific & 1<<i) { BN_set_bit(id, off + i); BIT_SET(off - DPLTEST_EXTRA_NBITS + i); } else { BN_clear_bit(id, off + i); BIT_CLEAR(off - DPLTEST_EXTRA_NBITS + i); } } off += DPLTEST_SPECIFIC_NBITS; for (i = 0;i < DPLTEST_SERVICEID_NBITS;i++) { if (serviceid & 1<<i) { BN_set_bit(id, off + i); BIT_SET(off - DPLTEST_EXTRA_NBITS + i); } else { BN_clear_bit(id, off + i); BIT_CLEAR(off - DPLTEST_EXTRA_NBITS + i); } } off += DPLTEST_SERVICEID_NBITS; for (i = 0;i < DPLTEST_VOLID_NBITS;i++) { if (volid & 1<<i) { BN_set_bit(id, off + i); BIT_SET(off - DPLTEST_EXTRA_NBITS + i); } else { BN_clear_bit(id, off + i); BIT_CLEAR(off - DPLTEST_EXTRA_NBITS + i); } } off += DPLTEST_VOLID_NBITS; for (i = 0;i < DPLTEST_OID_NBITS;i++) { if (oid & (1ULL<<i)) { BN_set_bit(id, off + i); BIT_SET(off - DPLTEST_EXTRA_NBITS + i); } else { BN_clear_bit(id, off + i); BIT_CLEAR(off - DPLTEST_EXTRA_NBITS + i); } } off += DPLTEST_OID_NBITS; MD5_Init(&ctx); MD5_Update(&ctx, entropy, sizeof (entropy)); MD5_Final(hash, &ctx); for (i = 0;i < DPLTEST_HASH_NBITS;i++) { if (hash[i/8] & 1<<(i%8)) BN_set_bit(id, off + i); else BN_clear_bit(id, off + i); } return DPL_SUCCESS; }
/* * Supplemental function to return BIGNUM containing value n = RndOddNum(k) algorithm * @param: k numbits and char pointer to binary read in using x = ceil(k/8) bytes * @return: BIGNUM n */ BIGNUM *RndOddNum(int k, char *temp, int x_byte) { BIGNUM *result = NULL; result = BN_new(); if(result == NULL) { fprintf(stderr, "Can't allocate space to hold returned result for RndOddNum function\n"); return NULL; } BN_zero(result); if(BN_bin2bn((unsigned char*)temp, x_byte, result) != NULL) { //Set bit 0 and k-1 if(BN_set_bit(result, 0)) { if(BN_set_bit(result, k-1)) { //Get total number of bits in result int total_num_bits = BN_num_bits(result); //Clear all higher order bit while(k < total_num_bits) { if(BN_clear_bit(result, k) == 0) //error: can't clear bit { //error: can't clear bit fprintf(stderr, "ERROR: can't clear bit %dth\n", k); BN_free(result); return NULL; } k += 1; } } else { //error: can't set bit k-1 fprintf(stderr, "ERROR: can't set bit k-1\n"); BN_free(result); return NULL; } } else { //error: can't set bit 0 fprintf(stderr, "ERROR: can't set bit 0\n"); BN_free(result); return NULL; } } else { //error: can't convert from bin to bn fprintf(stderr, "ERROR: can't convert binary read from rndfile to bn\n"); BN_free(result); return NULL; } return result; //It is the calling function responsibility to free BIGNUM result }