CryptX

 view release on metacpan or  search on metacpan

src/ltc/misc/argon2/argon2.c  view on Meta::CPAN

   }

   zeromem(blockhash_bytes, ARGON2_BLOCK_SIZE);
   return CRYPT_OK;
}

/* Finalize: XOR last blocks, produce tag */
static int s_finalize(unsigned char *out, unsigned long outlen,
                      const argon2_instance *instance)
{
   argon2_block blockhash;
   unsigned char blockhash_bytes[ARGON2_BLOCK_SIZE];
   ulong32 l;
   int err;

   s_block_copy(&blockhash, instance->memory + instance->lane_length - 1);

   for (l = 1; l < instance->lanes; ++l) {
      ulong32 last = l * instance->lane_length + (instance->lane_length - 1);
      s_block_xor(&blockhash, instance->memory + last);
   }

   s_block_store(blockhash_bytes, &blockhash);
   err = s_blake2b_long(out, outlen, blockhash_bytes, ARGON2_BLOCK_SIZE);

   zeromem(blockhash.v, ARGON2_BLOCK_SIZE);
   zeromem(blockhash_bytes, ARGON2_BLOCK_SIZE);
   return err;
}

/* Fill the entire memory */
static void s_fill_memory(argon2_instance *instance)
{
   ulong32 r, s, l;

   for (r = 0; r < instance->passes; ++r) {
      for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
         for (l = 0; l < instance->lanes; ++l) {
            argon2_position position;
            position.pass  = r;
            position.lane  = l;
            position.slice = (unsigned char)s;
            position.index = 0;
            s_fill_segment(instance, position);
         }
      }
   }
}

/**
   Hash a password with Argon2 (RFC 9106)

   @param pwd         Password (or message)
   @param pwdlen      Length of password
   @param salt        Salt
   @param saltlen     Length of salt
   @param secret      Optional secret value (may be NULL)
   @param secretlen   Length of secret
   @param ad          Optional associated data (may be NULL)
   @param adlen       Length of associated data
   @param t_cost      Number of passes (iterations), minimum 1
   @param m_cost      Memory size in KiB, minimum 8*parallelism
   @param parallelism Degree of parallelism (number of lanes), minimum 1
   @param type        ARGON2_D, ARGON2_I, or ARGON2_ID
   @param out         [out] Output tag
   @param outlen      Desired output length (4..2^32-1)
   @return CRYPT_OK on success
*/
int argon2_hash(const unsigned char *pwd,  unsigned long pwdlen,
                const unsigned char *salt, unsigned long saltlen,
                const unsigned char *secret, unsigned long secretlen,
                const unsigned char *ad, unsigned long adlen,
                unsigned int t_cost, unsigned int m_cost,
                unsigned int parallelism,
                argon2_type type,
                unsigned char *out, unsigned long outlen)
{
   argon2_instance instance;
   unsigned char blockhash[ARGON2_PREHASH_SEED_LEN];
   ulong32 memory_blocks, segment_length;
   int err;

   LTC_ARGCHK(out != NULL);
   LTC_ARGCHK(outlen >= ARGON2_MIN_OUTLEN);
   LTC_ARGCHK(pwd != NULL || pwdlen == 0);
   LTC_ARGCHK(salt != NULL || saltlen == 0);
   LTC_ARGCHK(secret != NULL || secretlen == 0);
   LTC_ARGCHK(ad != NULL || adlen == 0);
   LTC_ARGCHK(t_cost >= 1);
   LTC_ARGCHK(parallelism >= 1);
   LTC_ARGCHK(m_cost >= 8 * parallelism);
   LTC_ARGCHK(type == ARGON2_D || type == ARGON2_I || type == ARGON2_ID);

   /* Align memory: ensure memory_blocks is a multiple of 4*parallelism */
   memory_blocks = (ulong32)m_cost;
   if (memory_blocks < 2 * ARGON2_SYNC_POINTS * (ulong32)parallelism) {
      memory_blocks = 2 * ARGON2_SYNC_POINTS * (ulong32)parallelism;
   }
   segment_length = memory_blocks / ((ulong32)parallelism * ARGON2_SYNC_POINTS);
   memory_blocks = segment_length * ((ulong32)parallelism * ARGON2_SYNC_POINTS);

   /* Set up instance */
   instance.passes         = (ulong32)t_cost;
   instance.memory_blocks  = memory_blocks;
   instance.segment_length = segment_length;
   instance.lane_length    = segment_length * ARGON2_SYNC_POINTS;
   instance.lanes          = (ulong32)parallelism;
   instance.type           = (int)type;
   instance.memory         = NULL;

   /* Allocate memory */
   {
      unsigned long alloc_size = (unsigned long)memory_blocks * sizeof(argon2_block);
      /* overflow check */
      if (alloc_size / sizeof(argon2_block) != memory_blocks) {
         return CRYPT_OVERFLOW;
      }
      instance.memory = XMALLOC(alloc_size);
      if (instance.memory == NULL) {
         return CRYPT_MEM;
      }



( run in 0.442 second using v1.01-cache-2.11-cpan-71847e10f99 )