Al analizar el código fuente de tpm-emulator
, encontré que el descifrado de la clave RSA usa un algoritmo que es desconocido para yo.
El archivo original con este misterio se encuentra en rsa.c
, donde reside la función rsa_private(...)
. El contenido abreviado de esta función es el siguiente:
static int rsa_private(tpm_rsa_private_key_t *key,
const uint8_t *in, size_t in_len, uint8_t *out)
{
...
if (!key->p || !key->q || !key->u) {
/* c = p ^ d mod n */
tpm_bn_powm(c, p, key->d, key->n);
} else {
tpm_bn_init2(m1, key->size / 2);
tpm_bn_init2(m2, key->size / 2);
tpm_bn_init2(h, key->size);
/* m1 = p ^ (d mod (p-1)) mod p */
tpm_bn_sub_ui(h, key->p, 1);
tpm_bn_mod(h, key->d, h);
tpm_bn_powm(m1, p, h, key->p);
/* m2 = p ^ (d mod (q-1)) mod q */
tpm_bn_sub_ui(h, key->q, 1);
tpm_bn_mod(h, key->d, h);
tpm_bn_powm(m2, p, h, key->q);
/* h = u * ( m2 - m1 ) mod q */
tpm_bn_sub(h, m2, m1);
if (tpm_bn_sgn(h) < 0) tpm_bn_add(h, h, key->q);
tpm_bn_mul(h, key->u, h);
tpm_bn_mod(h, h, key->q);
/* c = m1 + h * p */
tpm_bn_mul(h, h, key->p);
tpm_bn_add(c, m1, h);
tpm_bn_clear(m1);
tpm_bn_clear(m2);
tpm_bn_clear(h);
}
...
return 0;
}
La idea básica de esta función es descifrar el mensaje de entrada in
( p
en una fórmula) de tamaño in_len
con la ayuda de la clave RSA privada key
(el exponente es d
y el módulo es% código%).
Si bien esta parte del código (1er algoritmo de descifrado):
/* c = p ^ d mod n */
está claro, el otro posible algoritmo del código de descifrado es un misterio para mí:
/* m1 = p ^ (d mod (p-1)) mod p */
/* m2 = p ^ (d mod (q-1)) mod q */
/* h = u * ( m2 - m1 ) mod q */
/* c = m1 + h * p */