// Generate each party's random numbers. xa is in [0, q), xb is in [1, q). static void genrand(JPakeUser * user, const JPakeParameters * params) { BIGNUM *qm1; // xa in [0, q) user->xa = BN_new(); BN_rand_range(user->xa, params->q); // q-1 qm1 = BN_new(); BN_copy(qm1, params->q); BN_sub_word(qm1, 1); // ... and xb in [0, q-1) user->xb = BN_new(); BN_rand_range(user->xb, qm1); // [1, q) BN_add_word(user->xb, 1); // cleanup BN_free(qm1); // Show printf("x%d", user->p.base); showbn("", user->xa); printf("x%d", user->p.base + 1); showbn("", user->xb); }
static int probable_prime(BIGNUM *rnd, int bits) { int i; prime_t mods[NUMPRIMES]; BN_ULONG delta, maxdelta; again: if (!BN_rand(rnd, bits, 1, 1)) return (0); /* we now have a random number 'rand' to test. */ for (i = 1; i < NUMPRIMES; i++) mods[i] = (prime_t)BN_mod_word(rnd, (BN_ULONG)primes[i]); maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; delta = 0; loop: for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is not a prime and also * that gcd(rnd-1,primes) == 1 (except for 2) */ if (((mods[i] + delta) % primes[i]) <= 1) { delta += 2; if (delta > maxdelta) goto again; goto loop; } } if (!BN_add_word(rnd, delta)) return (0); bn_check_top(rnd); return (1); }
static int bn_rand_range_with_additional_data( BIGNUM *r, BN_ULONG min_inclusive, const BIGNUM *max_exclusive, const uint8_t additional_data[32]) { if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); return 0; } /* This function is used to implement steps 4 through 7 of FIPS 186-4 * appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| * is n and |min_inclusive| is one. */ unsigned count = 100; unsigned n = BN_num_bits(max_exclusive); /* n > 0 */ do { if (!--count) { OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); return 0; } if (/* steps 4 and 5 */ !bn_rand_with_additional_data(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, additional_data) || /* step 7 */ !BN_add_word(r, min_inclusive)) { return 0; } /* Step 6. This loops if |r| >= |max_exclusive|. This is identical to * checking |r| > |max_exclusive| - 1 or |r| - 1 > |max_exclusive| - 2, the * formulation stated in FIPS 186-4. */ } while (BN_cmp(r, max_exclusive) >= 0); return 1; }
static int probable_prime(BIGNUM *rnd, int bits) { int i; BN_ULONG mods[NUMPRIMES]; BN_ULONG delta,d; again: if (!BN_rand(rnd,bits,1,1)) return(0); /* we now have a random number 'rand' to test. */ for (i=1; i<NUMPRIMES; i++) mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]); delta=0; loop: for (i=1; i<NUMPRIMES; i++) { /* check that rnd is not a prime and also * that gcd(rnd-1,primes) == 1 (except for 2) */ if (((mods[i]+delta)%primes[i]) <= 1) { d=delta; delta+=2; /* perhaps need to check for overflow of * delta (but delta can be up to 2^32) * 21-May-98 eay - added overflow check */ if (delta < d) goto again; goto loop; } } if (!BN_add_word(rnd,delta)) return(0); return(1); }
/* * Decode a base_n-encoded string into a byte sequence. */ bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base) { const char *enc; BN_zero(bn); assert(base == 16 || base == 58); switch (base) { case 16: enc = enc_16; break; case 58: enc = enc_58; break; } while (len) { char current = *src; if (base == 16) current = tolower(current); /* TODO: Not in ccan. */ int val = decode_char(current, enc); if (val < 0) { BN_free(bn); return false; } BN_mul_word(bn, base); BN_add_word(bn, val); src++; len--; } return true; }
/* * Copy the serial number from src certificate to dst certificate * and modify it by a random offset. * If reading the serial fails for some reason, generate a new * random serial and store it in the dst certificate. * Using the same serial is not a good idea since some SSL stacks * check for duplicate certificate serials. * Returns 0 on success, -1 on error. */ int ssl_x509_serial_copyrand(X509 *dstcrt, X509 *srccrt) { ASN1_INTEGER *srcptr, *dstptr; BIGNUM *bnserial; unsigned int rand; int rv; #ifndef PURIFY rv = ssl_rand(&rand, sizeof(rand)); #else /* PURIFY */ rand = 0xF001; rv = 0; #endif /* PURIFY */ dstptr = X509_get_serialNumber(dstcrt); srcptr = X509_get_serialNumber(srccrt); if ((rv == -1) || !dstptr || !srcptr) return -1; bnserial = ASN1_INTEGER_to_BN(srcptr, NULL); if (!bnserial) { /* random 32-bit serial */ ASN1_INTEGER_set(dstptr, rand); } else { /* original serial plus random 32-bit offset */ BN_add_word(bnserial, rand); BN_to_ASN1_INTEGER(bnserial, dstptr); BN_free(bnserial); } return 0; }
static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile, int create) { char *buf = NULL; ASN1_INTEGER *bs = NULL; BIGNUM *serial = NULL; if (serialfile == NULL) { const char *p = strrchr(CAfile, '.'); size_t len = p != NULL ? (size_t)(p - CAfile) : strlen(CAfile); buf = app_malloc(len + sizeof(POSTFIX), "serial# buffer"); memcpy(buf, CAfile, len); memcpy(buf + len, POSTFIX, sizeof(POSTFIX)); serialfile = buf; } serial = load_serial(serialfile, create, NULL); if (serial == NULL) goto end; if (!BN_add_word(serial, 1)) { BIO_printf(bio_err, "add_word failure\n"); goto end; } if (!save_serial(serialfile, NULL, serial, &bs)) goto end; end: OPENSSL_free(buf); BN_free(serial); return bs; }
int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { int ret = 0; BN_CTX *new_ctx = NULL; BIGNUM *tmp_a; /* p must be a prime > 3 */ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); return 0; } if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } BN_CTX_start(ctx); tmp_a = BN_CTX_get(ctx); if (tmp_a == NULL) goto err; /* group->field */ if (!BN_copy(&group->field, p)) goto err; BN_set_negative(&group->field, 0); /* group->a */ if (!BN_nnmod(tmp_a, a, p, ctx)) goto err; if (group->meth->field_encode) { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; } else if (!BN_copy(&group->a, tmp_a)) goto err; /* group->b */ if (!BN_nnmod(&group->b, b, p, ctx)) goto err; if (group->meth->field_encode) if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err; /* group->a_is_minus3 */ if (!BN_add_word(tmp_a, 3)) goto err; group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); ret = 1; err: BN_CTX_end(ctx); if (new_ctx != NULL) BN_CTX_free(new_ctx); return ret; }
int test_div(BIO *bp, BN_CTX *ctx) { BIGNUM a, b,c, d, e; int i; int rc = 1; BN_init(&a); BN_init(&b); BN_init(&c); BN_init(&d); BN_init(&e); for (i = 0; i < num0 + num1; i++) { if (i < num1) { BN_bntest_rand(&a, 400, 0, 0); BN_copy(&b, &a); BN_lshift(&a, &a, i); BN_add_word(&a, i); } else BN_bntest_rand(&b, 50 + 3*(i - num1), 0, 0); a.neg = rand_neg(); b.neg = rand_neg(); BN_div(&d, &c, &a, &b, ctx); if (bp != NULL) { if (!results) { BN_print(bp, &a); BIO_puts(bp, " / "); BN_print(bp, &b); BIO_puts(bp, " - "); } BN_print(bp, &d); BIO_puts(bp, "\n"); if (!results) { BN_print(bp, &a); BIO_puts(bp, " % "); BN_print(bp, &b); BIO_puts(bp, " - "); } BN_print(bp, &c); BIO_puts(bp, "\n"); } BN_mul(&e, &d, &b, ctx); BN_add(&d, &e, &c); BN_sub(&d, &d, &a); if (!BN_is_zero(&d)) { fprintf(stderr, "Division test failed!\n"); rc = 0; break; } } BN_free(&a); BN_free(&b); BN_free(&c); BN_free(&d); BN_free(&e); return (rc); }
int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx) { int i; BIGNUM *offset_index; BIGNUM *offset_count; int ret = 0; OPENSSL_assert(bits > prime_multiplier_bits); BN_CTX_start(ctx); if ((offset_index = BN_CTX_get(ctx)) == NULL) goto err; if ((offset_count = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_add_word(offset_count, prime_offset_count)) goto err; loop: if (!BN_rand(rnd, bits - prime_multiplier_bits, 0, 1)) goto err; if (BN_is_bit_set(rnd, bits)) goto loop; if (!BN_rand_range(offset_index, offset_count)) goto err; if (!BN_mul_word(rnd, prime_multiplier) || !BN_add_word(rnd, prime_offsets[BN_get_word(offset_index)])) goto err; /* we now have a random number 'rand' to test. */ /* skip coprimes */ for (i = first_prime_index; i < NUMPRIMES; i++) { /* check that rnd is a prime */ if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { goto loop; } } ret = 1; err: BN_CTX_end(ctx); bn_check_top(rnd); return ret; }
int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn) { int ret = 0; BIGNUM *tmp = NULL; if (!solinas || !bn) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE); return 0; } if (solinas->b <= 0 || solinas->a <= solinas->b || (solinas->s != 1 && solinas->s != -1) || (solinas->c != 1 && solinas->c != -1)) { BNerr(BN_F_BN_SOLINAS2BN, BN_R_INVALID_SOLINAS_PARAMETERS); return 0; } if (!(tmp = BN_new())) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE); goto end; } BN_one(tmp); if (!BN_lshift(bn, tmp, solinas->a)) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); goto end; } if (!BN_lshift(tmp, tmp, solinas->b)) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); goto end; } if (!BN_add_word(tmp, solinas->c)) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); goto end; } if (solinas->s > 0) { if (!BN_add(bn, bn, tmp)) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); goto end; } } else { if (!BN_sub(bn, bn, tmp)) { BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB); goto end; } } /* check if it is a prime */ ret = 1; end: BN_free(tmp); return ret; }
int BN_dec2bn(BIGNUM **bn, const char *a) { BIGNUM *ret=NULL; BN_ULONG l=0; int neg=0,i,j; int num; if ((a == NULL) || (*a == '\0')) return(0); if (*a == '-') { neg=1; a++; } for (i=0; isdigit((unsigned char) a[i]); i++) ; num=i+neg; if (bn == NULL) return(num); /* a is the start of the digits, and it is 'i' long. * We chop it into BN_DEC_NUM digits at a time */ if (*bn == NULL) { if ((ret=BN_new()) == NULL) return(0); } else { ret= *bn; BN_zero(ret); } /* i is the number of digests, a bit of an over expand; */ if (bn_expand(ret,i*4) == NULL) goto err; j=BN_DEC_NUM-(i%BN_DEC_NUM); if (j == BN_DEC_NUM) j=0; l=0; while (*a) { l*=10; l+= *a-'0'; a++; if (++j == BN_DEC_NUM) { BN_mul_word(ret,BN_DEC_CONV); BN_add_word(ret,l); l=0; j=0; } } ret->neg=neg; bn_correct_top(ret); *bn=ret; bn_check_top(ret); return(num); err: if (*bn == NULL) BN_free(ret); return(0); }
int test_div(BIO *bp, BN_CTX *ctx) { BIGNUM *a, *b, *c, *d, *e; int i; a = BN_new(); b = BN_new(); c = BN_new(); d = BN_new(); e = BN_new(); for (i = 0; i < num0 + num1; i++) { if (i < num1) { BN_bntest_rand(a, 400, 0, 0); BN_copy(b, a); BN_lshift(a, a, i); BN_add_word(a, i); } else BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0); a->neg = rand_neg(); b->neg = rand_neg(); BN_div(d, c, a, b, ctx); if (bp != NULL) { if (!results) { BN_print(bp, a); BIO_puts(bp, " / "); BN_print(bp, b); BIO_puts(bp, " - "); } BN_print(bp, d); BIO_puts(bp, "\n"); if (!results) { BN_print(bp, a); BIO_puts(bp, " % "); BN_print(bp, b); BIO_puts(bp, " - "); } BN_print(bp, c); BIO_puts(bp, "\n"); } BN_mul(e, d, b, ctx); BN_add(d, e, c); BN_sub(d, d, a); if (!BN_is_zero(d)) { fprintf(stderr, "Division test failed!\n"); return 0; } } BN_free(a); BN_free(b); BN_free(c); BN_free(d); BN_free(e); return (1); }
static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { int i, ret = 0; BIGNUM *t1; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) { goto err; } if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { goto err; } /* we need ((rnd-rem) % add) == 0 */ if (!BN_mod(t1, rnd, add, ctx)) { goto err; } if (!BN_sub(rnd, rnd, t1)) { goto err; } if (rem == NULL) { if (!BN_add_word(rnd, 1)) { goto err; } } else { if (!BN_add(rnd, rnd, rem)) { goto err; } } /* we now have a random number 'rand' to test. */ loop: for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is a prime */ BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); if (mod == (BN_ULONG)-1) { goto err; } if (mod <= 1) { if (!BN_add(rnd, rnd, add)) { goto err; } goto loop; } } ret = 1; err: BN_CTX_end(ctx); return ret; }
static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, BN_GENCB *cb) { int i = 0; if (!BN_copy(pi, Xpi)) return 0; if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) return 0; for (;;) { i++; BN_GENCB_call(cb, 0, i); /* NB 27 MR is specificed in X9.31 */ if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) break; if (!BN_add_word(pi, 2)) return 0; } BN_GENCB_call(cb, 2, i); return 1; }
int BN_sub_word(BIGNUM *a, BN_ULONG w) { int i; bn_check_top(a); w &= BN_MASK2; /* degenerate case: w is zero */ if (!w) return 1; /* degenerate case: a is zero */ if(BN_is_zero(a)) { i = BN_set_word(a,w); if (i != 0) BN_set_negative(a, 1); return i; } /* handle 'a' when negative */ if (a->neg) { a->neg=0; i=BN_add_word(a,w); a->neg=1; return(i); } if ((a->top == 1) && (a->d[0] < w)) { a->d[0]=w-a->d[0]; a->neg=1; return(1); } i=0; for (;;) { if (a->d[i] >= w) { a->d[i]-=w; break; } else { a->d[i]=(a->d[i]-w)&BN_MASK2; i++; w=1; } } if ((a->d[i] == 0) && (i == (a->top-1))) a->top--; bn_check_top(a); return(1); }
static int test_check_public_key(void) { int ret = 0; BIGNUM *n = NULL, *e = NULL; RSA *key = NULL; ret = TEST_ptr(key = RSA_new()) /* check NULL pointers fail */ && TEST_false(rsa_sp800_56b_check_public(key)) /* load public key */ && TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e))) && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n))) && TEST_true(RSA_set0_key(key, n, e, NULL)); if (!ret) { BN_free(e); BN_free(n); goto end; } /* check public key is valid */ ret = TEST_true(rsa_sp800_56b_check_public(key)) /* check fail if n is even */ && TEST_true(BN_add_word(n, 1)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_sub_word(n, 1)) /* check fail if n is wrong number of bits */ && TEST_true(BN_lshift1(n, n)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_rshift1(n, n)) /* test odd exponent fails */ && TEST_true(BN_add_word(e, 1)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_sub_word(e, 1)) /* modulus fails composite check */ && TEST_true(BN_add_word(n, 2)) && TEST_false(rsa_sp800_56b_check_public(key)); end: RSA_free(key); return ret; }
struct number * readnumber(struct source *src, u_int base) { struct number *n; int ch; bool sign = false; bool dot = false; BN_ULONG v; u_int i; n = new_number(); bn_check(BN_zero(n->number)); while ((ch = (*src->vtable->readchar)(src)) != EOF) { if ('0' <= ch && ch <= '9') v = ch - '0'; else if ('A' <= ch && ch <= 'F') v = ch - 'A' + 10; else if (ch == '_') { sign = true; continue; } else if (ch == '.') { if (dot) break; dot = true; continue; } else { (*src->vtable->unreadchar)(src); break; } if (dot) n->scale++; bn_check(BN_mul_word(n->number, base)); #if 0 /* work around a bug in BN_add_word: 0 += 0 is buggy.... */ if (v > 0) #endif bn_check(BN_add_word(n->number, v)); } if (base != 10) { scale_number(n->number, n->scale); for (i = 0; i < n->scale; i++) (void)BN_div_word(n->number, base); } if (sign) negate(n); return n; }
int test_sub(BIO *bp) { BIGNUM a,b,c; int i; BN_init(&a); BN_init(&b); BN_init(&c); for (i=0; i<num0+num1; i++) { if (i < num1) { BN_bntest_rand(&a,512,0,0); BN_copy(&b,&a); if (BN_set_bit(&a,i)==0) return(0); BN_add_word(&b,i); } else { BN_bntest_rand(&b,400+i-num1,0,0); a.neg=rand_neg(); b.neg=rand_neg(); } BN_sub(&c,&a,&b); if (bp != NULL) { if (!results) { BN_print(bp,&a); BIO_puts(bp," - "); BN_print(bp,&b); BIO_puts(bp," - "); } BN_print(bp,&c); BIO_puts(bp,"\n"); } BN_add(&c,&c,&b); BN_sub(&c,&c,&a); if(!BN_is_zero(&c)) { fprintf(stderr,"Subtract test failed!\n"); return 0; } } BN_free(&a); BN_free(&b); BN_free(&c); return(1); }
static ASN1_INTEGER *x509_load_serial (char *CAfile, char *serialfile, int create) { char *buf = NULL, *p; ASN1_INTEGER *bs = NULL; BIGNUM *serial = NULL; size_t len; len = ((serialfile == NULL) ? (strlen (CAfile) + strlen (POSTFIX) + 1) : (strlen (serialfile))) + 1; buf = OPENSSL_malloc (len); if (buf == NULL) { BIO_printf (bio_err, "out of mem\n"); goto end; } if (serialfile == NULL) { BUF_strlcpy (buf, CAfile, len); for (p = buf; *p; p++) if (*p == '.') { *p = '\0'; break; } BUF_strlcat (buf, POSTFIX, len); } else BUF_strlcpy (buf, serialfile, len); serial = load_serial (buf, create, NULL); if (serial == NULL) goto end; if (!BN_add_word (serial, 1)) { BIO_printf (bio_err, "add_word failure\n"); goto end; } if (!save_serial (buf, NULL, serial, &bs)) goto end; end: if (buf) OPENSSL_free (buf); BN_free (serial); return bs; }
int BN_sub_word(BIGNUM *a, BN_ULONG w) { int i; // degenerate case: w is zero if (!w) { return 1; } // degenerate case: a is zero if (BN_is_zero(a)) { i = BN_set_word(a, w); if (i != 0) { BN_set_negative(a, 1); } return i; } // handle 'a' when negative if (a->neg) { a->neg = 0; i = BN_add_word(a, w); a->neg = 1; return i; } if ((bn_minimal_width(a) == 1) && (a->d[0] < w)) { a->d[0] = w - a->d[0]; a->neg = 1; return 1; } i = 0; for (;;) { if (a->d[i] >= w) { a->d[i] -= w; break; } else { a->d[i] -= w; i++; w = 1; } } if ((a->d[i] == 0) && (i == (a->width - 1))) { a->width--; } return 1; }
// http://stackoverflow.com/questions/356090/how-to-compute-the-nth-root-of-a-very-big-integer static BIGNUM *nearest_cuberoot(BIGNUM *in) { BN_CTX *ctx = BN_CTX_new(); BN_CTX_start(ctx); BIGNUM *three = BN_CTX_get(ctx); BIGNUM *high = BN_CTX_get(ctx); BIGNUM *mid = BN_CTX_get(ctx); BIGNUM *low = BN_CTX_get(ctx); BIGNUM *tmp = BN_CTX_get(ctx); BN_set_word(three, 3); // Create the constant 3 BN_set_word(high, 1); // high = 1 do { BN_lshift1(high, high); // high = high << 1 (high * 2) BN_exp(tmp, high, three, ctx); // tmp = high^3 } while (BN_ucmp(tmp, in) <= -1); // while (tmp < in) BN_rshift1(low, high); // low = high >> 1 (high / 2) while (BN_ucmp(low, high) <= -1) // while (low < high) { BN_add(tmp, low, high); // tmp = low + high BN_rshift1(mid, tmp); // mid = tmp >> 1 (tmp / 2) BN_exp(tmp, mid, three, ctx); // tmp = mid^3 if (BN_ucmp(low, mid) <= -1 && BN_ucmp(tmp, in) <= -1) // if (low < mid && tmp < in) BN_copy(low, mid); // low = mid else if (BN_ucmp(high, mid) >= 1 && BN_ucmp(tmp, in) >= 1) // else if (high > mid && tmp > in) BN_copy(high, mid); // high = mid else { // subtract 1 from mid because 1 will be added after the loop BN_sub_word(mid, 1); // mid -= 1 break; } } BN_add_word(mid, 1); // mid += 1 BIGNUM *result = BN_dup(mid); BN_CTX_end(ctx); BN_CTX_free(ctx); return result; }
/* * RSA: generate keys and sign, verify input plaintext. */ static int FIPS_rsa_test(int bad) { RSA *key; unsigned char input_ptext[] = "etaonrishdlc"; unsigned char buf[256]; unsigned int slen; BIGNUM *bn; EVP_MD_CTX mctx; EVP_PKEY pk; int r = 0; ERR_clear_error(); EVP_MD_CTX_init(&mctx); key = RSA_new(); bn = BN_new(); if (!key || !bn) return 0; BN_set_word(bn, 65537); if (!RSA_generate_key_ex(key, 1024, bn, NULL)) return 0; BN_free(bn); if (bad) BN_add_word(key->n, 1); pk.type = EVP_PKEY_RSA; pk.pkey.rsa = key; if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL)) goto end; if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) goto end; if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL)) goto end; if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; r = EVP_VerifyFinal(&mctx, buf, slen, &pk); end: EVP_MD_CTX_cleanup(&mctx); if (key) RSA_free(key); if (r != 1) return 0; return 1; }
static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { int i, ret = 0; BIGNUM *t1; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_rand(rnd, bits, 0, 1)) goto err; /* we need ((rnd-rem) % add) == 0 */ if (!BN_mod(t1, rnd, add, ctx)) goto err; if (!BN_sub(rnd, rnd, t1)) goto err; if (rem == NULL) { if (!BN_add_word(rnd, 1)) goto err; } else { if (!BN_add(rnd, rnd, rem)) goto err; } /* we now have a random number 'rand' to test. */ loop: for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is a prime */ if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { if (!BN_add(rnd, rnd, add)) goto err; goto loop; } } ret = 1; err: BN_CTX_end(ctx); bn_check_top(rnd); return (ret); }
/* * DSA: generate keys and sign, verify input plaintext. */ static int FIPS_dsa_test(int bad) { DSA *dsa = NULL; EVP_PKEY pk; unsigned char dgst[] = "etaonrishdlc"; unsigned char buf[60]; unsigned int slen; int r = 0; EVP_MD_CTX mctx; ERR_clear_error(); EVP_MD_CTX_init(&mctx); dsa = DSA_new(); if (!dsa) goto end; if (!DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL)) goto end; if (!DSA_generate_key(dsa)) goto end; if (bad) BN_add_word(dsa->pub_key, 1); pk.type = EVP_PKEY_DSA; pk.pkey.dsa = dsa; if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) goto end; if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) goto end; if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) goto end; if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; r = EVP_VerifyFinal(&mctx, buf, slen, &pk); end: EVP_MD_CTX_cleanup(&mctx); if (dsa) DSA_free(dsa); if (r != 1) return 0; return 1; }
int test_sub(BIO *bp) { BIGNUM *a, *b, *c; int i; a = BN_new(); b = BN_new(); c = BN_new(); for (i = 0; i < num0 + num1; i++) { if (i < num1) { BN_bntest_rand(a, 512, 0, 0); BN_copy(b, a); if (BN_set_bit(a, i) == 0) return (0); BN_add_word(b, i); } else { BN_bntest_rand(b, 400 + i - num1, 0, 0); a->neg = rand_neg(); b->neg = rand_neg(); } BN_sub(c, a, b); if (bp != NULL) { if (!results) { BN_print(bp, a); BIO_puts(bp, " - "); BN_print(bp, b); BIO_puts(bp, " - "); } BN_print(bp, c); BIO_puts(bp, "\n"); } BN_add(c, c, b); BN_sub(c, c, a); if (!BN_is_zero(c)) { fprintf(stderr, "Subtract test failed!\n"); return 0; } } BN_free(a); BN_free(b); BN_free(c); return (1); }
static ASN1_INTEGER *next_serial(const char *serialfile) { int ret = 0; BIO *in = NULL; ASN1_INTEGER *serial = NULL; BIGNUM *bn = NULL; if ((serial = ASN1_INTEGER_new()) == NULL) goto err; if ((in = BIO_new_file(serialfile, "r")) == NULL) { ERR_clear_error(); BIO_printf(bio_err, "Warning: could not open file %s for " "reading, using serial number: 1\n", serialfile); if (!ASN1_INTEGER_set(serial, 1)) goto err; } else { char buf[1024]; if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) { BIO_printf(bio_err, "unable to load number from %s\n", serialfile); goto err; } if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL) goto err; ASN1_INTEGER_free(serial); serial = NULL; if (!BN_add_word(bn, 1)) goto err; if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) goto err; } ret = 1; err: if (!ret) { ASN1_INTEGER_free(serial); serial = NULL; } BIO_free_all(in); BN_free(bn); return serial; }
/* * DSA: generate keys and sign, verify input plaintext. */ static int FIPS_dsa_test(int bad) { DSA *dsa = NULL; unsigned char dgst[] = "etaonrishdlc"; int r = 0; EVP_MD_CTX mctx; DSA_SIG *sig = NULL; ERR_clear_error(); FIPS_md_ctx_init(&mctx); dsa = FIPS_dsa_new(); if (!dsa) goto end; if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL)) goto end; if (!DSA_generate_key(dsa)) goto end; if (bad) BN_add_word(dsa->pub_key, 1); if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; sig = FIPS_dsa_sign_ctx(dsa, &mctx); if (!sig) goto end; if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1)) goto end; r = FIPS_dsa_verify_ctx(dsa, &mctx, sig); end: if (sig) FIPS_dsa_sig_free(sig); FIPS_md_ctx_cleanup(&mctx); if (dsa) FIPS_dsa_free(dsa); if (r != 1) return 0; return 1; }
/* * RSA: generate keys and sign, verify input plaintext. */ static int FIPS_rsa_test(int bad) { RSA *key; unsigned char input_ptext[] = "etaonrishdlc"; unsigned char buf[256]; unsigned int slen; BIGNUM *bn; EVP_MD_CTX mctx; int r = 0; ERR_clear_error(); FIPS_md_ctx_init(&mctx); key = FIPS_rsa_new(); bn = BN_new(); if (!key || !bn) return 0; BN_set_word(bn, 65537); if (!RSA_generate_key_ex(key, 2048,bn,NULL)) return 0; BN_free(bn); if (bad) BN_add_word(key->n, 1); if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; if (!FIPS_rsa_sign_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, &slen)) goto end; if (!FIPS_digestinit(&mctx, EVP_sha256())) goto end; if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) goto end; r = FIPS_rsa_verify_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, slen); end: FIPS_md_ctx_cleanup(&mctx); if (key) FIPS_rsa_free(key); if (r != 1) return 0; return 1; }
/* pollard p-1, algorithm from Jim Gillogly, May 2000 */ static void pollard_pminus1(BIGNUM *val) { BIGNUM *base, *num, *i, *x; base = BN_new(); num = BN_new(); i = BN_new(); x = BN_new(); BN_set_word(i, 2); BN_set_word(base, 2); for (;;) { BN_mod_exp(base, base, i, val, ctx); BN_copy(x, base); BN_sub_word(x, 1); BN_gcd(x, x, val, ctx); if (!BN_is_one(x)) { if (BN_is_prime(x, PRIME_CHECKS, NULL, NULL, NULL) == 1) pr_print(x); else pollard_pminus1(x); fflush(stdout); BN_div(num, NULL, val, x, ctx); if (BN_is_one(num)) return; if (BN_is_prime(num, PRIME_CHECKS, NULL, NULL, NULL) == 1) { pr_print(num); fflush(stdout); return; } BN_copy(val, num); } BN_add_word(i, 1); } }