O gnupg 2.1.16 bloqueia a espera da entropia

9

As liberações do gnupg de 2.1.16 (atualmente 2.1.17) bloqueiam a espera de entropia apenas na primeira chamada .

Nota: não se trata de uma tentativa de gerar uma chave, apenas para descriptografar um arquivo e iniciar o agente.

A primeira vez que o gpg-agent é iniciado, diretamente com gpg2 file.gpgou usando um aplicativo como pass, o pinentry aparece e, assim que eu digito minha senha e pressiono, Enterela fica suspensa por cerca de 15s.

Todas as chamadas subseqüentes, dentro da janela do default-cache-ttl, são executadas imediatamente.

Em execução no --debug-allmodo, o período em que ocorre o travamento é impresso 1 :

gpg: DBG: chan_6 <- S PROGRESS need_entropy X 30 120
gpg: DBG: chan_6 <- S PROGRESS need_entropy X 120 120
gpg: DBG: chan_6 <- S PROGRESS need_entropy X 30 120
gpg: DBG: chan_6 <- S PROGRESS need_entropy X 120 120
gpg: DBG: chan_6 <- S PROGRESS need_entropy X 30 120
...

Eu instalei o rng-tools para complementar o pool de entropia:

cat /proc/sys/kernel/random/entropy_avail 
4094

e comparado com uma máquina com a mesma versão do gnupg que não possui rng-tools ou não possui instalado, que não apresenta atraso:

cat /proc/sys/kernel/random/entropy_avail
3783

Portanto, parece haver entropia suficiente na piscina. Isso foi testado nos núcleos 4.8.13 e 4.9.

O gpg usa um pool diferente? Como posso fornecer entropia suficiente ou eliminar o atraso de 15s ao iniciar o agente?



1. O log de depuração completo .

jasonwryan
fonte
1
Você instalou o rng-toolscomo explicar aqui? serverfault.com/questions/214605/gpg-not-enough-entropy
aurelien
1
Sim, mencionei isso explicitamente na minha pergunta. Se nossas ligações eram mais acessíveis , você pode ter notado :)
jasonwryan
1
@Jasonwryan Eu perdi essa linha: - /
aurelien

Respostas:

2

Eu acho que sei o que está acontecendo. No agent / gpg-agent.c do gnupg, essa função processa mensagens do libgcrypt.

/* This is our callback function for gcrypt progress messages.  It is
   set once at startup and dispatches progress messages to the
   corresponding threads of the agent.  */
static void 
agent_libgcrypt_progress_cb (void *data, const char *what, int printchar,
                             int current, int total)
{
  struct progress_dispatch_s *dispatch;
  npth_t mytid = npth_self ();

  (void)data;

  for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next)
    if (dispatch->ctrl && dispatch->tid == mytid)
      break;
  if (dispatch && dispatch->cb)
    dispatch->cb (dispatch->ctrl, what, printchar, current, total);

  /* Libgcrypt < 1.8 does not know about nPth and thus when it reads
   * from /dev/random this will block the process.  To mitigate this
   * problem we take a short nap when Libgcrypt tells us that it needs
   * more entropy.  This way other threads have chance to run.  */
#if GCRYPT_VERSION_NUMBER < 0x010800 /* 1.8.0 */
  if (what && !strcmp (what, "need_entropy"))
    npth_usleep (100000); /* 100ms */
#endif
}

Essa última parte com npth_usleep foi adicionada entre 2.1.15 e 2.1.17. Como isso é compilado condicionalmente se a libgcrypt for anterior à 1.8.0, a correção direta seria recompilar o gnupg contra a libgcrypt 1.8.0 ou posterior ... infelizmente essa versão ainda não parece existir.

O estranho é que esse comentário sobre libgcrypt reading / dev / random não é verdadeiro. Rastrear o agente revela que ele está lendo em / dev / urandom e usando o novo syscall do getrandom (2), sem bloquear. No entanto, ele envia muitas mensagens need_entropy, causando o bloqueio de npth_usleep. A exclusão dessas linhas corrige o problema.

Devo mencionar que npth parece ser algum tipo de biblioteca multitarefa cooperativa, e npth_usleep é provavelmente o seu caminho para produzir, portanto, talvez seja melhor reduzir significativamente esse atraso, apenas no caso de a libgcrypt decidir bloquear algum dia. (1 ms não é perceptível)

stribika
fonte
Bom trabalho. Então, até que a libgcrypt 1.8.0 seja lançada (atualmente eu estou no 1.7.5), eu estou preso a ela. Parece estranho que a quantidade real de entropia disponível não tenha influência no bloqueio.
jasonwryan
Sim, 1.7.5 é o mais recente disponível. Se você estiver disposto a corrigir, é corrigível removendo 2 zeros. 4 para corrigir o comentário. :) BTW, eu tive o mesmo problema, eu realmente não percebi.
Stribika
Eu só notei porque estava afetando apenas uma das minhas máquinas, e esse tipo de variação realmente aciona meu TOC. Vou ver se o patch ajuda. Felicidades.
jasonwryan
Aplicou esse patch e o mesmo bloqueio (need_entropy). Ugh!
jasonwryan
Você tem certeza de que a versão correta do gpg-agent foi iniciada? Se você confiar no gpg para iniciá-lo, ele sempre será exibido no padrão / usr / bin / gpg-agent. Você pode iniciá-lo manualmente com killall gpg-agent; /path/to/gpg-agent --daemon.
stribika