static void check_primes (void) { gcry_error_t err = GPG_ERR_NO_ERROR; gcry_mpi_t *factors = NULL; gcry_mpi_t prime = NULL; gcry_mpi_t g; unsigned int i = 0; struct prime_spec { unsigned int prime_bits; unsigned int factor_bits; unsigned int flags; } prime_specs[] = { { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR }, { 128, 0, 0 }, { 0 }, }; for (i = 0; prime_specs[i].prime_bits; i++) { err = gcry_prime_generate (&prime, prime_specs[i].prime_bits, prime_specs[i].factor_bits, &factors, NULL, NULL, GCRY_WEAK_RANDOM, prime_specs[i].flags); assert (! err); if (verbose) { fprintf (stderr, "test %d: p = ", i); gcry_mpi_dump (prime); putc ('\n', stderr); } err = gcry_prime_check (prime, 0); assert (! err); err = gcry_prime_group_generator (&g, prime, factors, NULL); assert (!err); gcry_prime_release_factors (factors); factors = NULL; if (verbose) { fprintf (stderr, " %d: g = ", i); gcry_mpi_dump (g); putc ('\n', stderr); } gcry_mpi_release (g); gcry_mpi_add_ui (prime, prime, 1); err = gcry_prime_check (prime, 0); assert (err); } }
/** * This function will generate a new pair of prime and generator for use in * the Diffie-Hellman key exchange. * The bits value should be one of 768, 1024, 2048, 3072 or 4096. **/ static int dh_params_generate (unsigned int bits) { int result, times = 0, qbits; gcry_mpi_t *factors = NULL; gcry_error_t err; /* Version check should be the very first call because it makes sure that important subsystems are intialized. */ if (!gcry_check_version (GCRYPT_VERSION)) { LOG(log_error, logtype_uams, "PAM DHX2: libgcrypt versions mismatch. Need: %s", GCRYPT_VERSION); result = AFPERR_MISC; goto error; } if (bits < 256) qbits = bits / 2; else qbits = (bits / 40) + 105; if (qbits & 1) /* better have an even number */ qbits++; /* find a prime number of size bits. */ do { if (times) { gcry_mpi_release(p); gcry_prime_release_factors (factors); } err = gcry_prime_generate(&p, bits, qbits, &factors, NULL, NULL, GCRY_STRONG_RANDOM, GCRY_PRIME_FLAG_SPECIAL_FACTOR); if (err != 0) { result = AFPERR_MISC; goto error; } err = gcry_prime_check(p, 0); times++; } while (err != 0 && times < 10); if (err != 0) { result = AFPERR_MISC; goto error; } /* generate the group generator. */ err = gcry_prime_group_generator(&g, p, factors, NULL); if (err != 0) { result = AFPERR_MISC; goto error; } gcry_prime_release_factors(factors); return 0; error: gcry_prime_release_factors(factors); return result; }
static void do_primecheck (void) { gpg_error_t err; if (stackidx < 1) { fputs ("stack underflow\n", stderr); return; } err = gcry_prime_check (stack[stackidx - 1], 0); mpi_set_ui (stack[stackidx - 1], !err); if (err && gpg_err_code (err) != GPG_ERR_NO_PRIME) fprintf (stderr, "checking prime failed: %s\n", gpg_strerror (err)); }
/* deterministically generate from seed/idx a prime of length `bits' that is 3 (mod 4) */ static gcry_mpi_t genprime3mod4(int bits, const void *seed, size_t seedlen, uint32_t idx) { size_t buflen = bits / 8; uint8_t buf[buflen]; gcry_mpi_t p; assert(bits % 8 == 0); assert(buflen > 0); det_randomize(buf, buflen, seed, seedlen, idx); buf[0] |= 0xc0; /* set upper two bits, so that n=pq has maximum size */ buf[buflen - 1] |= 0x03; /* set lower two bits, to have result 3 (mod 4) */ p = mpi_import(buf, buflen); while (gcry_prime_check(p, 0)) gcry_mpi_add_ui(p, p, 4); return p; }
static int wrap_gcry_generate_group (gnutls_group_st * group, unsigned int bits) { gcry_mpi_t g = NULL, prime = NULL; gcry_error_t err; int times = 0, qbits; gcry_mpi_t *factors = NULL; /* Calculate the size of a prime factor of (prime-1)/2. * This is an emulation of the values in "Selecting Cryptographic Key Sizes" paper. */ if (bits < 256) qbits = bits / 2; else { qbits = (bits / 40) + 105; } if (qbits & 1) /* better have an even number */ qbits++; /* find a prime number of size bits. */ do { if (times) { gcry_mpi_release (prime); gcry_prime_release_factors (factors); } err = gcry_prime_generate (&prime, bits, qbits, &factors, NULL, NULL, GCRY_STRONG_RANDOM, GCRY_PRIME_FLAG_SPECIAL_FACTOR); if (err != 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } err = gcry_prime_check (prime, 0); times++; } while (err != 0 && times < 10); if (err != 0) { gnutls_assert (); gcry_mpi_release (prime); gcry_prime_release_factors (factors); return GNUTLS_E_INTERNAL_ERROR; } /* generate the group generator. */ err = gcry_prime_group_generator (&g, prime, factors, NULL); gcry_prime_release_factors (factors); if (err != 0) { gnutls_assert (); gcry_mpi_release (prime); return GNUTLS_E_INTERNAL_ERROR; } group->g = g; group->p = prime; return 0; }
static int wrap_gcry_prime_check (bigint_t pp) { return gcry_prime_check (pp, 0); }