Search code examples
encryptioncryptographyrsalibgcrypt

gcry_pk_genkey function is extremely slow in libgcrypt


I am a newbie to libgcrypt version 1.6.1, and right now I am trying to produce a public/private key pair for rsa algorithm.

I list the code I am using below. What I am trapped into is the gcry_pk_genkey function, in which it can take over 1.5 hours but never return.

void gcrypt_init()
{
 if (!gcry_check_version (GCRYPT_VERSION))
{
    xerr("gcrypt: library version mismatch");
}

gcry_error_t err = 0;

err &= gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);

err &= gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);

err &= gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
err &= gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);

if (err) {
    xerr("gcrypt: failed initialization");
}
}


#include "gcry.hh"
#include <cstdio>
#include <cstdlib>
#include <cstring>

int main(int argc, char** argv)
{
if (argc != 2) {
    fprintf(stderr, "Usage: %s <rsa-keypair.sp>\n", argv[0]);
    xerr1("Invalid arguments.");
}

gcrypt_init();

gcry_error_t err = 0;
gcry_sexp_t rsa_parms;
gcry_sexp_t rsa_keypair;

err &= gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:2048)))");
if (err) {
    xerr1("gcrypt: failed to create rsa params");
}

err &= gcry_pk_genkey(&rsa_keypair, rsa_parms); <------- This function call
if (err) {
    xerr1("gcrypt: failed to create rsa key pair");
}

char* fname = argv[1];
err = gcrypt_sexp_to_file(fname, rsa_keypair, 1 << 16);

    printf("i am here3\n");
gcry_sexp_release(rsa_keypair);
gcry_sexp_release(rsa_parms);

return err;
}

I am aware that this function can take a few minutes. Your computer needs to gather random entropy.. However, I can hardly believe it could take almost 2 hours without return/throw exception...

I am using a 32-bit Ubuntu 14.04, inside a virtualbox VM instance. Am I doing anything wrong here?


Solution

  • Could you test the speed of your /dev/random? If that's horribly slow (possibly because other processes require too much entropy) then /dev/random will block until entropy is gathered. This may also be an issue on headless machines. I've certainly had issues with the speed of random number generation on Ubuntu on my laptop.

    You can also specify transient-key (as flag in the s expression) to use a somewhat less secure random number generator, which probably means less entropy and therefore less blocking.

    It's highly unlikely that the time it costs to validate that a number is prime takes that long. And even though the time to find a prime (or two) isn't known it advance, it is unlikely that anything other than blocking for random number generation could cause such huge generation times.