/* To generate a DH key either q must be set in the params or * level should be set to the number of required bits. */ static int wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, unsigned int level /*bits */ , gnutls_pk_params_st * params) { int ret; unsigned int i; switch (algo) { case GNUTLS_PK_DSA: #ifdef ENABLE_FIPS140 { struct dsa_public_key pub; struct dsa_private_key priv; if (params->params[DSA_Q] == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); _dsa_params_to_pubkey(params, &pub); dsa_private_key_init(&priv); mpz_init(pub.y); ret = dsa_generate_dss_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL); if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto dsa_fail; } ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL); if (ret < 0) { gnutls_assert(); goto dsa_fail; } mpz_set(TOMPZ(params->params[DSA_Y]), pub.y); mpz_set(TOMPZ(params->params[DSA_X]), priv.x); params->params_nr += 2; dsa_fail: dsa_private_key_clear(&priv); mpz_clear(pub.y); if (ret < 0) goto fail; break; } #endif case GNUTLS_PK_DH: { struct dsa_public_key pub; mpz_t r; mpz_t x, y; int max_tries; unsigned have_q = 0; if (algo != params->algo) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); _dsa_params_to_pubkey(params, &pub); if (params->params[DSA_Q] != NULL) have_q = 1; /* This check is for the case !ENABLE_FIPS140 */ if (algo == GNUTLS_PK_DSA && have_q == 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); mpz_init(r); mpz_init(x); mpz_init(y); max_tries = 3; do { if (have_q) { mpz_set(r, pub.q); mpz_sub_ui(r, r, 2); nettle_mpz_random(x, NULL, rnd_func, r); mpz_add_ui(x, x, 1); } else { unsigned size = mpz_sizeinbase(pub.p, 2); if (level == 0) level = MIN(size, DH_EXPONENT_SIZE(size)); nettle_mpz_random_size(x, NULL, rnd_func, level); if (level >= size) mpz_mod(x, x, pub.p); } mpz_powm(y, pub.g, x, pub.p); max_tries--; if (max_tries <= 0) { gnutls_assert(); ret = GNUTLS_E_RANDOM_FAILED; goto dh_fail; } } while(mpz_cmp_ui(y, 1) == 0); ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL); if (ret < 0) { gnutls_assert(); goto dh_fail; } mpz_set(TOMPZ(params->params[DSA_Y]), y); mpz_set(TOMPZ(params->params[DSA_X]), x); params->params_nr += 2; ret = 0; dh_fail: mpz_clear(r); mpz_clear(x); mpz_clear(y); if (ret < 0) goto fail; break; } case GNUTLS_PK_RSA: { struct rsa_public_key pub; struct rsa_private_key priv; rsa_public_key_init(&pub); rsa_private_key_init(&priv); mpz_set_ui(pub.e, 65537); #ifdef ENABLE_FIPS140 ret = rsa_generate_fips186_4_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL, level); #else ret = rsa_generate_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL, level, 0); #endif if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto rsa_fail; } params->params_nr = 0; for (i = 0; i < RSA_PRIVATE_PARAMS; i++) { ret = _gnutls_mpi_init(¶ms->params[i]); if (ret < 0) { gnutls_assert(); goto rsa_fail; } params->params_nr++; } mpz_set(TOMPZ(params->params[0]), pub.n); mpz_set(TOMPZ(params->params[1]), pub.e); mpz_set(TOMPZ(params->params[2]), priv.d); mpz_set(TOMPZ(params->params[3]), priv.p); mpz_set(TOMPZ(params->params[4]), priv.q); mpz_set(TOMPZ(params->params[5]), priv.c); mpz_set(TOMPZ(params->params[6]), priv.a); mpz_set(TOMPZ(params->params[7]), priv.b); ret = 0; rsa_fail: rsa_private_key_clear(&priv); rsa_public_key_clear(&pub); if (ret < 0) goto fail; break; } case GNUTLS_PK_EC: { struct ecc_scalar key; struct ecc_point pub; const struct ecc_curve *curve; curve = get_supported_curve(level); if (curve == NULL) return gnutls_assert_val (GNUTLS_E_ECC_UNSUPPORTED_CURVE); ecc_scalar_init(&key, curve); ecc_point_init(&pub, curve); ecdsa_generate_keypair(&pub, &key, NULL, rnd_func); ret = _gnutls_mpi_init_multi(¶ms->params[ECC_X], ¶ms->params[ECC_Y], ¶ms->params[ECC_K], NULL); if (ret < 0) { gnutls_assert(); goto ecc_fail; } params->flags = level; params->params_nr = ECC_PRIVATE_PARAMS; ecc_point_get(&pub, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); ecc_scalar_get(&key, TOMPZ(params->params[ECC_K])); ret = 0; ecc_fail: ecc_point_clear(&pub); ecc_scalar_clear(&key); if (ret < 0) goto fail; break; } default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } FAIL_IF_LIB_ERROR; return 0; fail: for (i = 0; i < params->params_nr; i++) { _gnutls_mpi_release(¶ms->params[i]); } params->params_nr = 0; FAIL_IF_LIB_ERROR; return ret; }
int rsa_generate_keypair(struct rsa_public_key *pub, struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, void *progress_ctx, nettle_progress_func *progress, unsigned n_size, unsigned e_size) { mpz_t p1; mpz_t q1; mpz_t phi; mpz_t tmp; if (e_size) { /* We should choose e randomly. Is the size reasonable? */ if ((e_size < 16) || (e_size >= n_size) ) return 0; } else { /* We have a fixed e. Check that it makes sense */ /* It must be odd */ if (!mpz_tstbit(pub->e, 0)) return 0; /* And 3 or larger */ if (mpz_cmp_ui(pub->e, 3) < 0) return 0; /* And size less than n */ if (mpz_sizeinbase(pub->e, 2) >= n_size) return 0; } if (n_size < RSA_MINIMUM_N_BITS) return 0; mpz_init(p1); mpz_init(q1); mpz_init(phi); mpz_init(tmp); /* Generate primes */ for (;;) { /* Generate p, such that gcd(p-1, e) = 1 */ for (;;) { nettle_random_prime(key->p, (n_size+1)/2, 1, random_ctx, random, progress_ctx, progress); mpz_sub_ui(p1, key->p, 1); /* If e was given, we must chose p such that p-1 has no factors in * common with e. */ if (e_size) break; mpz_gcd(tmp, pub->e, p1); if (mpz_cmp_ui(tmp, 1) == 0) break; else if (progress) progress(progress_ctx, 'c'); } if (progress) progress(progress_ctx, '\n'); /* Generate q, such that gcd(q-1, e) = 1 */ for (;;) { nettle_random_prime(key->q, n_size/2, 1, random_ctx, random, progress_ctx, progress); /* Very unlikely. */ if (mpz_cmp (key->q, key->p) == 0) continue; mpz_sub_ui(q1, key->q, 1); /* If e was given, we must chose q such that q-1 has no factors in * common with e. */ if (e_size) break; mpz_gcd(tmp, pub->e, q1); if (mpz_cmp_ui(tmp, 1) == 0) break; else if (progress) progress(progress_ctx, 'c'); } /* Now we have the primes. Is the product of the right size? */ mpz_mul(pub->n, key->p, key->q); assert (mpz_sizeinbase(pub->n, 2) == n_size); if (progress) progress(progress_ctx, '\n'); /* c = q^{-1} (mod p) */ if (mpz_invert(key->c, key->q, key->p)) /* This should succeed everytime. But if it doesn't, * we try again. */ break; else if (progress) progress(progress_ctx, '?'); } mpz_mul(phi, p1, q1); /* If we didn't have a given e, generate one now. */ if (e_size) { int retried = 0; for (;;) { nettle_mpz_random_size(pub->e, random_ctx, random, e_size); /* Make sure it's odd and that the most significant bit is * set */ mpz_setbit(pub->e, 0); mpz_setbit(pub->e, e_size - 1); /* Needs gmp-3, or inverse might be negative. */ if (mpz_invert(key->d, pub->e, phi)) break; if (progress) progress(progress_ctx, 'e'); retried = 1; } if (retried && progress) progress(progress_ctx, '\n'); } else { /* Must always succeed, as we already that e * doesn't have any common factor with p-1 or q-1. */ int res = mpz_invert(key->d, pub->e, phi); assert(res); } /* Done! Almost, we must compute the auxillary private values. */ /* a = d % (p-1) */ mpz_fdiv_r(key->a, key->d, p1); /* b = d % (q-1) */ mpz_fdiv_r(key->b, key->d, q1); /* c was computed earlier */ pub->size = key->size = (n_size + 7) / 8; assert(pub->size >= RSA_MINIMUM_N_OCTETS); mpz_clear(p1); mpz_clear(q1); mpz_clear(phi); mpz_clear(tmp); return 1; }
static void dsa_nist_gen(mpz_t p, mpz_t q, void *random_ctx, nettle_random_func random, void *progress_ctx, nettle_progress_func progress, unsigned L) { unsigned n; unsigned b; mpz_t s; mpz_t t; mpz_t c; /* For NIS keysizes, we should have L = 512 + 64 * l */ n = (L-1) / 160; b = (L-1) % 160; mpz_init(s); mpz_init(t); mpz_init(c); for (;;) { { /* Generate q */ uint8_t h1[SHA1_DIGEST_SIZE]; uint8_t h2[SHA1_DIGEST_SIZE]; if (progress) progress(progress_ctx, '.'); nettle_mpz_random_size(s, random_ctx, random, SEED_BITS); hash(s, h1); mpz_set(t, s); mpz_add_ui(t, t, 1); hash(t, h2); memxor(h1, h2, SHA1_DIGEST_SIZE); h1[0] |= 0x80; h1[SHA1_DIGEST_SIZE - 1] |= 1; nettle_mpz_set_str_256_u(q, SHA1_DIGEST_SIZE, h1); /* The spec says that we should use 18 iterations of * miller-rabin. For performance, we want to do some trial * divisions first. The curent version of mpz_probab_prime_p * does exactly that. */ if (!mpz_probab_prime_p(q, 18)) /* Try new seed. */ continue; } /* q is a prime, with overwhelming probability. */ if (progress) progress(progress_ctx, '\n'); { /* Official maximum key size: L = 1024 => n = 6 */ TMP_DECL(buffer, uint8_t, (6 + 1) * SHA1_DIGEST_SIZE); unsigned size = (n+1) * SHA1_DIGEST_SIZE; unsigned i, j; TMP_ALLOC(buffer, size); for (i = 0, j = 2; i<4096; i++, j+= n+1) { unsigned k; if (progress) progress(progress_ctx, ','); for (k = 0; k<=n ; k++) { mpz_set(t, s); mpz_add_ui(t, t, j + k); hash(t, buffer + ( (n-k) * SHA1_DIGEST_SIZE)); } nettle_mpz_set_str_256_u(p, size, buffer); mpz_fdiv_r_2exp(p, p, L); mpz_setbit(p, L-1); mpz_set(t, q); mpz_mul_2exp(t, t, 1); mpz_fdiv_r(c, p, t); mpz_sub_ui(c, c, 1); mpz_sub(p, p, c); if (mpz_probab_prime_p(p, 5)) { /* Done! */ if (progress) progress(progress_ctx, '\n'); mpz_clear(s); mpz_clear(t); mpz_clear(c); return; } } if (progress) progress(progress_ctx, '+'); } } }