Example #1
0
int tpm_rsa_import_key(tpm_rsa_private_key_t *key, int endian,
                       const uint8_t *n, size_t n_len,
                       const uint8_t *e, size_t e_len,
                       const uint8_t *p, const uint8_t *q)
{
  tpm_bn_t t1, t2, phi;
  if (n == NULL || n_len == 0 || (p == NULL && q == NULL)) return -1;
  /* init key */
  key->size = n_len << 3;
  if (e == NULL || e_len == 0) {
    tpm_bn_init_set_ui(key->e, 65537);
  } else {
    tpm_bn_init2(key->e, e_len << 3);
    tpm_bn_import(key->e, e_len, endian, e);
  }
  tpm_bn_init2(key->n, key->size);
  tpm_bn_init2(key->p, key->size / 2);
  tpm_bn_init2(key->q, key->size / 2);
  tpm_bn_init2(key->d, key->size);
  tpm_bn_init2(key->u, key->size / 2); 
  tpm_bn_init2(t1, key->size / 2);
  tpm_bn_init2(t2, key->size / 2);
  tpm_bn_init2(phi, key->size);
  /* import values */
  tpm_bn_import(key->n, n_len, endian, n);
  if (p != NULL) tpm_bn_import(key->p, n_len / 2, endian, p);
  if (q != NULL) tpm_bn_import(key->q, n_len / 2, endian, q);
  if (p == NULL) tpm_bn_tdiv_q(key->p, key->n, key->q);
  if (q == NULL) tpm_bn_tdiv_q(key->q, key->n, key->p);
  /* p shall be smaller than q */
  if (tpm_bn_cmp(key->p, key->q) > 0) tpm_bn_swap(key->p, key->q);
  /* calculate missing values */
  tpm_bn_sub_ui(t1, key->p, 1);
  tpm_bn_sub_ui(t2, key->q, 1);
  tpm_bn_mul(phi, t1, t2);
  tpm_bn_invert(key->d, key->e, phi);
  tpm_bn_invert(key->u, key->p, key->q);
  /* release helper variables */
  tpm_bn_clear(t1);
  tpm_bn_clear(t2);
  tpm_bn_clear(phi);
  /* test key */
  if (rsa_test_key(key) != 0) {
    tpm_rsa_release_private_key(key);
    return -1;
  }
  return 0;
}
Example #2
0
int rsa_import_key(rsa_private_key_t *key, int endian,
                   uint8_t *n, size_t n_len, uint8_t *e, size_t e_len,
                   uint8_t *p, uint8_t *q)
{
  mpz_t t1, t2, phi;
  if (n == NULL || n_len == 0 || (p == NULL && q == NULL)) return -1;
  /* init key */
  key->size = n_len << 3;
  if (e == NULL || e_len == 0) {
    mpz_init_set_ui(key->e, 65537);
  } else {
    mpz_init2(key->e, (e_len << 3) + GMP_NUMB_BITS);
    mpz_import(key->e, e_len, endian, 1, 0, 0, e);
  }
  mpz_init2(key->n, key->size + GMP_NUMB_BITS);
  mpz_init2(key->p, key->size / 2 + GMP_NUMB_BITS);
  mpz_init2(key->q, key->size / 2 + GMP_NUMB_BITS);
  mpz_init2(key->d, key->size + GMP_NUMB_BITS);
  mpz_init2(key->u, key->size / 2 + GMP_NUMB_BITS); 
  mpz_init2(t1, key->size / 2 + GMP_NUMB_BITS);
  mpz_init2(t2, key->size / 2 + GMP_NUMB_BITS);
  mpz_init2(phi, key->size + GMP_NUMB_BITS);
  /* import values */
  mpz_import(key->n, n_len, endian, 1, 0, 0, n);
  if (p != NULL) mpz_import(key->p, n_len / 2, endian, 1, 0, 0, p);
  if (q != NULL) mpz_import(key->q, n_len / 2, endian, 1, 0, 0, q);
  if (p == NULL) mpz_tdiv_q(key->p, key->n, key->q);
  if (q == NULL) mpz_tdiv_q(key->q, key->n, key->p);
  /* p shall be smaller than q */
  if (mpz_cmp(key->p, key->q) > 0) mpz_swap(key->p, key->q);
  /* calculate missing values */
  mpz_sub_ui(t1, key->p, 1);
  mpz_sub_ui(t2, key->q, 1);
  mpz_mul(phi, t1, t2);
  mpz_invert(key->d, key->e, phi);
  mpz_invert(key->u, key->p, key->q);
  /* release helper variables */
  mpz_clear(t1);
  mpz_clear(t2);
  mpz_clear(phi);
  /* test key */
  if (rsa_test_key(key) != 0) {
    rsa_release_private_key(key);
    return -1;
  }
  return 0;
}
Example #3
0
int rsa_generate_key(rsa_private_key_t *key, int key_size)
{
  mpz_t e, p, q, n, t1, t2, phi, d, u;

  /* bit_size must be even */
  if (key_size & 0x01) key_size++;
  /* we use e = 65537 */
  mpz_init_set_ui(e, 65537);
  mpz_init2(p, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(q, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(n, key_size + GMP_NUMB_BITS);
  mpz_init2(t1, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(t2, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(phi, key_size + GMP_NUMB_BITS);
  mpz_init2(d, key_size + GMP_NUMB_BITS);
  mpz_init2(u, key_size / 2 + GMP_NUMB_BITS);
  do {  
    /* get prime p */
    mpz_urandomb(p, NULL, key_size / 2);
    mpz_setbit(p, 0); 
    mpz_setbit(p, key_size / 2 - 1);
    mpz_setbit(p, key_size / 2 - 2);
    mpz_nextprime(p, p);
    mpz_sub_ui(t1, p, 1);
    mpz_gcd(phi, e, t1);
    if (mpz_cmp_ui(phi, 1) != 0) continue;
    /* get prime q */
    mpz_urandomb(q, NULL, key_size / 2);
    mpz_setbit(q, 0);
    mpz_setbit(q, key_size / 2 - 1);
    mpz_setbit(q, key_size / 2 - 2);
    mpz_nextprime(q, q);
    mpz_sub_ui(t2, q, 1); 
    mpz_gcd(phi, e, t1);
    if (mpz_cmp_ui(phi, 1) != 0) continue;
    /* p shall be smaller than q */
    if (mpz_cmp(p, q) > 0) mpz_swap(p, q);
    /* calculate the modulus */
    mpz_mul(n, p, q);
  } while (mpz_sizeinbase(n, 2) != key_size);
  /* calculate Euler totient: phi = (p-1)(q-1) */
  mpz_mul(phi, t1, t2);
  /* calculate the secret key d = e^(-1) mod phi */
  mpz_invert(d, e, phi);
  /* calculate the inverse of p and q (used for chinese remainder theorem) */
  mpz_invert(u, p, q);
  /* setup private key */
  mpz_init_set(key->n, n);
  mpz_init_set(key->e, e);
  mpz_init_set(key->p, p);
  mpz_init_set(key->q, q);
  mpz_init_set(key->d, d);
  mpz_init_set(key->u, u);  
  key->size = key_size;
  /* release helper variables */
  mpz_clear(e);
  mpz_clear(p);
  mpz_clear(q);
  mpz_clear(n);
  mpz_clear(t1);
  mpz_clear(t2);
  mpz_clear(phi);
  mpz_clear(d);
  mpz_clear(u);
  /* test key */
  if (rsa_test_key(key) != 0) {
    rsa_release_private_key(key);
    return -1;
  }
  return 0;
}