Example #1
0
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
{
   error_t error;
   Mpi m1;
   Mpi m2;
   Mpi h;

   //The ciphertext representative c shall be between 0 and n - 1
   if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
      return ERROR_OUT_OF_RANGE;

   //Initialize multiple-precision integers
   mpiInit(&m1);
   mpiInit(&m2);
   mpiInit(&h);

   //Use the Chinese remainder algorithm?
   if(key->n.size && key->p.size && key->q.size &&
      key->dp.size && key->dq.size && key->qinv.size)
   {
      //Compute m1 = c ^ dP mod p
      MPI_CHECK(mpiExpMod(&m1, c, &key->dp, &key->p));
      //Compute m2 = c ^ dQ mod q
      MPI_CHECK(mpiExpMod(&m2, c, &key->dq, &key->q));
      //Let h = (m1 - m2) * qInv mod p
      MPI_CHECK(mpiSub(&h, &m1, &m2));
      MPI_CHECK(mpiMulMod(&h, &h, &key->qinv, &key->p));
      //Let m = m2 + q * h
      MPI_CHECK(mpiMul(m, &key->q, &h));
      MPI_CHECK(mpiAdd(m, m, &m2));
   }
   //Use modular exponentiation?
   else if(key->n.size && key->d.size)
   {
      //Let m = c ^ d mod n
      error = mpiExpMod(m, c, &key->d, &key->n);
   }
   //Invalid parameters?
   else
   {
      //Report an error
      error = ERROR_INVALID_PARAMETER;
   }

end:
   //Free previously allocated memory
   mpiFree(&m1);
   mpiFree(&m2);
   mpiFree(&h);

   //Return status code
   return error;
}
Example #2
0
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
{
   //Ensure the RSA public key is valid
   if(!key->n.size || !key->e.size)
      return ERROR_INVALID_PARAMETER;

   //The message representative m shall be between 0 and n - 1
   if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
      return ERROR_OUT_OF_RANGE;

   //Perform modular exponentiation (c = m ^ e mod n)
   return mpiExpMod(c, m, &key->e, &key->n);
}
Example #3
0
error_t dhGenerateKeyPair(DhContext *context,
   const PrngAlgo *prngAlgo, void *prngContext)
{
   error_t error;
   uint_t k;

   //Debug message
   TRACE_DEBUG("Generating Diffie-Hellman key pair...\r\n");

   //Get the length in bits of the prime p
   k = mpiGetBitLength(&context->params.p);
   //Ensure the length is valid
   if(!k) return ERROR_INVALID_PARAMETER;

   //The private value shall be randomly generated
   error = mpiRand(&context->xa, k, prngAlgo, prngContext);
   //Any error to report?
   if(error) return error;

   //The private value shall be less than p
   if(mpiComp(&context->xa, &context->params.p) >= 0)
   {
      //Shift value to the right
      error = mpiShiftRight(&context->xa, 1);
      //Any error to report?
      if(error) return error;
   }

   //Debug message
   TRACE_DEBUG("  Private value:\r\n");
   TRACE_DEBUG_MPI("    ", &context->xa);

   //Calculate the corresponding public value (ya = g ^ xa mod p)
   error = mpiExpMod(&context->ya, &context->params.g, &context->xa, &context->params.p);
   //Any error to report?
   if(error) return error;

   //Debug message
   TRACE_DEBUG("  Public value:\r\n");
   TRACE_DEBUG_MPI("    ", &context->ya);

   //Check public value
   error = dhCheckPublicKey(&context->params, &context->ya);
   //Weak public value?
   if(error) return error;

   //Public value successfully generated
   return NO_ERROR;
}
Example #4
0
error_t dhComputeSharedSecret(DhContext *context,
   uint8_t *output, size_t outputSize, size_t *outputLength)
{
   error_t error;
   size_t k;
   Mpi z;

   //Debug message
   TRACE_DEBUG("Computing Diffie-Hellman shared secret...\r\n");

   //Get the length in octets of the prime modulus
   k = mpiGetByteLength(&context->params.p);

   //Make sure that the output buffer is large enough
   if(outputSize < k)
      return ERROR_INVALID_LENGTH;

   //The multiple precision integer must be initialized before it can be used
   mpiInit(&z);

   //Start of exception handling block
   do
   {
      //Calculate the shared secret key (k = yb ^ xa mod p)
      error = mpiExpMod(&z, &context->yb, &context->xa, &context->params.p);
      //Any error to report?
      if(error) return error;

      //Convert the resulting integer to an octet string
      error = mpiWriteRaw(&z, output, k);
      //Conversion failed?
      if(error) return error;

      //Length of the resulting shared secret
      *outputLength = k;

      //Debug message
      TRACE_DEBUG("  Shared secret (%" PRIuSIZE " bytes):\r\n", *outputLength);
      TRACE_DEBUG_ARRAY("    ", output, *outputLength);

      //End of exception handling block
   } while(0);

   //Release previously allocated resources
   mpiFree(&z);
   //Return status code
   return error;
}