int16 rsa_public_block(uint8 *input, uint16 input_len, uint8 *output, uint16 *output_len, rsa_public_key *public_key)
{
  uint32 c[MAX_NN_DIGITS] = {0}, e[MAX_NN_DIGITS] = {0}, m[MAX_NN_DIGITS] = {0},
  n[MAX_NN_DIGITS] = {0};
  uint16 eDigits = 0, nDigits = 0;

  memset (c, 0, sizeof (c));
  memset (m, 0, sizeof (m));
  memset (n, 0, sizeof (n));

  nn_decode (m, MAX_NN_DIGITS, input, input_len);
  nn_decode (n, MAX_NN_DIGITS, public_key->modulus, MAX_RSA_MODULUS_LEN);
  nn_decode (e, MAX_NN_DIGITS, public_key->public_exponent, MAX_RSA_MODULUS_LEN);
  nDigits = nn_digits (n, MAX_NN_DIGITS);
  eDigits = nn_digits (e, MAX_NN_DIGITS);

  if (nn_cmp (m, n, nDigits) >= 0)
  return -1;

  /* Compute c = m^e mod n. */
  nn_mod_exp (c, m, e, eDigits, n, nDigits);

	*output_len = (uint16)(public_key->bits + 7) / 8;
	nn_encode (output, *output_len, c, nDigits);

	return (0);
}
Esempio n. 2
0
/* w.b. hart */
int zz_cmp(zz_srcptr a, zz_srcptr b)
{
   long asize = a->size;
   long bsize = b->size;
   int sgn;

   if (asize > bsize)
      return 1;
   else if (asize < bsize)
      return -1;

   sgn = nn_cmp(a->n, b->n, ABS(asize));
   return asize < 0 ? -sgn : sgn;
}
int16 rsa_private_block(uint8 *input, uint16 input_len, uint8 *output, uint16 *output_len, rsa_private_key *private_key)
{
  uint32 c[MAX_NN_DIGITS] = {0}, cP[MAX_NN_DIGITS] = {0}, cQ[MAX_NN_DIGITS] = {0},
  dP[MAX_NN_DIGITS] = {0}, dQ[MAX_NN_DIGITS] = {0}, mP[MAX_NN_DIGITS] = {0},
  mQ[MAX_NN_DIGITS] = {0}, n[MAX_NN_DIGITS] = {0}, p[MAX_NN_DIGITS] = {0}, q[MAX_NN_DIGITS] = {0},
  qInv[MAX_NN_DIGITS] = {0}, t[MAX_NN_DIGITS] = {0};
  uint16 cDigits = 0, nDigits = 0, pDigits = 0;

  memset (c, 0, sizeof (c));
  memset (cP, 0, sizeof (cP));
  memset (cQ, 0, sizeof (cQ));
  memset (dP, 0, sizeof (dP));
  memset (dQ, 0, sizeof (dQ));
  memset (mP, 0, sizeof (mP));
  memset (mQ, 0, sizeof (mQ));
  memset (p, 0, sizeof (p));
  memset (q, 0, sizeof (q));
  memset (qInv, 0, sizeof (qInv));
  memset (t, 0, sizeof (t));

  nn_decode (c, MAX_NN_DIGITS, input, input_len);
  nn_decode (n, MAX_NN_DIGITS, private_key->modulus, MAX_RSA_MODULUS_LEN);
  nn_decode (p, MAX_NN_DIGITS, private_key->prime[0], MAX_RSA_PRIME_LEN);
  nn_decode (q, MAX_NN_DIGITS, private_key->prime[1], MAX_RSA_PRIME_LEN);
  nn_decode (dP, MAX_NN_DIGITS, private_key->prime_exponent[0], MAX_RSA_PRIME_LEN);
  nn_decode (dQ, MAX_NN_DIGITS, private_key->prime_exponent[1], MAX_RSA_PRIME_LEN);
  nn_decode (qInv, MAX_NN_DIGITS, private_key->coefficient, MAX_RSA_PRIME_LEN);


  cDigits = nn_digits (c, MAX_NN_DIGITS);
  nDigits = nn_digits (n, MAX_NN_DIGITS);
  pDigits = nn_digits (p, MAX_NN_DIGITS);

  if (nn_cmp (c, n, nDigits) >= 0)
  return -1;

  /* Compute mP = cP^dP mod p  and  mQ = cQ^dQ mod q. (Assumes q has length at most pDigits, i.e., p > q.) */
  nn_mod (cP, c, cDigits, p, pDigits);
  nn_mod (cQ, c, cDigits, q, pDigits);
  nn_mod_exp (mP, cP, dP, pDigits, p, pDigits);

  nn_assign_zero (mQ, nDigits);
  nn_mod_exp (mQ, cQ, dQ, pDigits, q, pDigits);

  /* Chinese Remainder Theorem:  m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.   */
  if (nn_cmp (mP, mQ, pDigits) >= 0)
  {
    nn_sub (t, mP, mQ, pDigits);
  }
  else
  {
    nn_sub (t, mQ, mP, pDigits);
    nn_sub (t, p, t, pDigits);
  }
  nn_mod_mult (t, t, qInv, p, pDigits);
  nn_mult (t, t, q, pDigits);
  nn_add (t, t, mQ, nDigits);

	*output_len = (uint16)(private_key->bits + 7) / 8;
	nn_encode (output, *output_len, t, nDigits);

	return (0);
}