Exemplo n.º 1
0
/* Update the message digest with the contents of INBUF with length
  INLEN.  */
static void
sha256_write (void *context, byte *inbuf, size_t inlen)
{
  SHA256_CONTEXT *hd = context;

  if (hd->count == 64)
    { /* flush the buffer */
      transform (hd, hd->buf);
      _gcry_burn_stack (74*4+32);
      hd->count = 0;
      hd->nblocks++;
    }
  if (!inbuf)
    return;
  if (hd->count)
    {
      for (; inlen && hd->count < 64; inlen--)
        hd->buf[hd->count++] = *inbuf++;
      sha256_write (hd, NULL, 0);
      if (!inlen)
        return;
    }

  while (inlen >= 64)
    {
      transform (hd, inbuf);
      hd->count = 0;
      hd->nblocks++;
      inlen -= 64;
      inbuf += 64;
    }
  _gcry_burn_stack (74*4+32);
  for (; inlen && hd->count < 64; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 2
0
/* The routine updates the message-digest context to
 * account for the presence of each of the characters inBuf[0..inLen-1]
 * in the message whose digest is being computed. */
void texpdf_MD5_write (MD5_CONTEXT *hd, const unsigned char *inbuf, unsigned long inlen)
{
  if (hd->count == 64) { /* flush the buffer */
    transform(hd, hd->buf);
    _gcry_burn_stack(80+6*sizeof(void*));
    hd->count = 0;
    hd->nblocks++;
  }
  if (!inbuf) return;
  if (hd->count) {
    for (; inlen && hd->count < 64; inlen--)
      hd->buf[hd->count++] = *inbuf++;
    texpdf_MD5_write(hd, NULL, 0);
    if (!inlen) return;
  }
  _gcry_burn_stack(80+6*sizeof(void*));

  while (inlen >= 64) {
    transform(hd, inbuf);
    hd->count = 0;
    hd->nblocks++;
    inlen -= 64;
    inbuf += 64;
  }
  for (; inlen && hd->count < 64; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 3
0
/* Update the message digest with the contents
 * of INBUF with length INLEN.
 */
static void
sha512_write (void *context, byte *inbuf, size_t inlen)
{
  SHA512_CONTEXT *hd = context;

  if (hd->count == 128)
    {				/* flush the buffer */
      transform (hd, hd->buf);
      _gcry_burn_stack (768);
      hd->count = 0;
      hd->nblocks++;
    }
  if (!inbuf)
    return;
  if (hd->count)
    {
      for (; inlen && hd->count < 128; inlen--)
	hd->buf[hd->count++] = *inbuf++;
      sha512_write (context, NULL, 0);
      if (!inlen)
	return;
    }

  while (inlen >= 128)
    {
      transform (hd, inbuf);
      hd->count = 0;
      hd->nblocks++;
      inlen -= 128;
      inbuf += 128;
    }
  _gcry_burn_stack (768);
  for (; inlen && hd->count < 128; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 4
0
/* Update the message digest with the contents
 * of INBUF with length INLEN.
 */
static void
rmd160_write( void *context, byte *inbuf, size_t inlen)
{
  RMD160_CONTEXT *hd = context;

  if( hd->count == 64 )  /* flush the buffer */
    {
      transform( hd, hd->buf );
      _gcry_burn_stack (108+5*sizeof(void*));
      hd->count = 0;
      hd->nblocks++;
    }
  if( !inbuf )
    return;
  if( hd->count ) 
    {
      for( ; inlen && hd->count < 64; inlen-- )
        hd->buf[hd->count++] = *inbuf++;
      rmd160_write( hd, NULL, 0 );
      if( !inlen )
        return;
    }

  while( inlen >= 64 )
    {
      transform( hd, inbuf );
      hd->count = 0;
      hd->nblocks++;
      inlen -= 64;
      inbuf += 64;
    }
  _gcry_burn_stack (108+5*sizeof(void*));
  for( ; inlen && hd->count < 64; inlen-- )
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 5
0
/* Common function to write a chunk of data to the transform function
   of a hash algorithm.  Note that the use of the term "block" does
   not imply a fixed size block.  Note that we explicitly allow to use
   this function after the context has been finalized; the result does
   not have any meaning but writing after finalize is sometimes
   helpful to mitigate timing attacks. */
void
_gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
{
  const unsigned char *inbuf = inbuf_arg;
  gcry_md_block_ctx_t *hd = context;
  unsigned int stack_burn = 0;
  const unsigned int blocksize = hd->blocksize;
  size_t inblocks;

  if (sizeof(hd->buf) < blocksize)
    BUG();

  if (!hd->bwrite)
    return;

  if (hd->count == blocksize)  /* Flush the buffer. */
    {
      stack_burn = hd->bwrite (hd, hd->buf, 1);
      _gcry_burn_stack (stack_burn);
      stack_burn = 0;
      hd->count = 0;
      if (!++hd->nblocks)
        hd->nblocks_high++;
    }
  if (!inbuf)
    return;

  if (hd->count)
    {
      for (; inlen && hd->count < blocksize; inlen--)
        hd->buf[hd->count++] = *inbuf++;
      _gcry_md_block_write (hd, NULL, 0);
      if (!inlen)
        return;
    }

  if (inlen >= blocksize)
    {
      inblocks = inlen / blocksize;
      stack_burn = hd->bwrite (hd, inbuf, inblocks);
      hd->count = 0;
      hd->nblocks_high += (hd->nblocks + inblocks < inblocks);
      hd->nblocks += inblocks;
      inlen -= inblocks * blocksize;
      inbuf += inblocks * blocksize;
    }
  _gcry_burn_stack (stack_burn);
  for (; inlen && hd->count < blocksize; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 6
0
/* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
static gcry_err_code_t
serpent_setkey (void *ctx,
		const byte *key, unsigned int key_length)
{
  serpent_context_t *context = ctx;
  static const char *serpent_test_ret;
  static int serpent_init_done;
  gcry_err_code_t ret = GPG_ERR_NO_ERROR;
  
  if (! serpent_init_done)
    {
      /* Execute a self-test the first time, Serpent is used.  */
      serpent_test_ret = serpent_test ();
      if (serpent_test_ret)
	log_error ("Serpent test failure: %s\n", serpent_test_ret);
      serpent_init_done = 1;
    }

  if (serpent_test_ret)
    ret = GPG_ERR_SELFTEST_FAILED;
  else
    {
      serpent_setkey_internal (context, key, key_length);
      _gcry_burn_stack (sizeof (serpent_key_t));
    }

  return ret;
}
Exemplo n.º 7
0
static gcry_err_code_t
do_ecb_crypt (gcry_cipher_hd_t c,
              unsigned char *outbuf, size_t outbuflen,
              const unsigned char *inbuf, size_t inbuflen,
              gcry_cipher_encrypt_t crypt_fn)
{
  unsigned int blocksize = c->spec->blocksize;
  size_t n, nblocks;
  unsigned int burn, nburn;

  if (outbuflen < inbuflen)
    return GPG_ERR_BUFFER_TOO_SHORT;
  if ((inbuflen % blocksize))
    return GPG_ERR_INV_LENGTH;

  nblocks = inbuflen / blocksize;
  burn = 0;

  for (n=0; n < nblocks; n++ )
    {
      nburn = crypt_fn (&c->context.c, outbuf, inbuf);
      burn = nburn > burn ? nburn : burn;
      inbuf  += blocksize;
      outbuf += blocksize;
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}
Exemplo n.º 8
0
static void
twofish_encrypt (void *context, byte *out, const byte *in)
{
  TWOFISH_context *ctx = context;
  do_twofish_encrypt (ctx, out, in);
  _gcry_burn_stack (24+3*sizeof (void*));
}
Exemplo n.º 9
0
/* Common function to write a chunk of data to the transform function
   of a hash algorithm.  Note that the use of the term "block" does
   not imply a fixed size block.  */
void
_gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
{
  const unsigned char *inbuf = inbuf_arg;
  gcry_md_block_ctx_t *hd = context;
  unsigned int stack_burn = 0;

  if (sizeof(hd->buf) < hd->blocksize)
    BUG();

  if (hd->buf == NULL || hd->bwrite == NULL)
    return;

  if (hd->count == hd->blocksize)  /* Flush the buffer. */
    {
      stack_burn = hd->bwrite (hd, hd->buf);
      _gcry_burn_stack (stack_burn);
      stack_burn = 0;
      hd->count = 0;
      if (!++hd->nblocks)
        hd->nblocks_high++;
    }
  if (!inbuf)
    return;

  if (hd->count)
    {
      for (; inlen && hd->count < hd->blocksize; inlen--)
        hd->buf[hd->count++] = *inbuf++;
      _gcry_md_block_write (hd, NULL, 0);
      if (!inlen)
        return;
    }

  while (inlen >= hd->blocksize)
    {
      stack_burn = hd->bwrite (hd, inbuf);
      hd->count = 0;
      if (!++hd->nblocks)
        hd->nblocks_high++;
      inlen -= hd->blocksize;
      inbuf += hd->blocksize;
    }
  _gcry_burn_stack (stack_burn);
  for (; inlen && hd->count < hd->blocksize; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 10
0
static void _gcry_burn_stack (int bytes)
{
  char buf[64];
    
  memset(buf, 0, sizeof buf);
  bytes -= sizeof buf;
  if (bytes > 0) _gcry_burn_stack(bytes);
}
Exemplo n.º 11
0
static gcry_err_code_t
arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
{
  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
  gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
  _gcry_burn_stack (300);
  return rc;
}
Exemplo n.º 12
0
static gcry_err_code_t
twofish_setkey (void *context, const byte *key, unsigned int keylen)
{
  TWOFISH_context *ctx = context;
  int rc = do_twofish_setkey (ctx, key, keylen);
  _gcry_burn_stack (23+6*sizeof(void*));
  return rc;
}
Exemplo n.º 13
0
static void
encrypt_stream (void *context,
                byte *outbuf, const byte *inbuf, size_t length)
{
  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
  do_encrypt_stream (ctx, outbuf, inbuf, length );
  _gcry_burn_stack (64);
}
Exemplo n.º 14
0
static gcry_err_code_t
salsa20_setkey (void *context, const byte *key, unsigned int keylen)
{
  SALSA20_context_t *ctx = (SALSA20_context_t *)context;
  gcry_err_code_t rc = salsa20_do_setkey (ctx, key, keylen);
  _gcry_burn_stack (300/* FIXME*/);
  return rc;
}
Exemplo n.º 15
0
/* Bulk decryption of complete blocks in CBC mode.  This function is only
   intended for the bulk encryption feature of cipher.c. */
void
_gcry_blowfish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
		       const void *inbuf_arg, size_t nblocks)
{
  BLOWFISH_context *ctx = context;
  unsigned char *outbuf = outbuf_arg;
  const unsigned char *inbuf = inbuf_arg;
  unsigned char savebuf[BLOWFISH_BLOCKSIZE];
  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;

#ifdef USE_AMD64_ASM
  {
    if (nblocks >= 4)
      burn_stack_depth += 5 * sizeof(void*);

    /* Process data in 4 block chunks. */
    while (nblocks >= 4)
      {
        _gcry_blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);

        nblocks -= 4;
        outbuf += 4 * BLOWFISH_BLOCKSIZE;
        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
  }
#elif defined(USE_ARM_ASM)
  {
    /* Process data in 2 block chunks. */
    while (nblocks >= 2)
      {
        _gcry_blowfish_arm_cbc_dec(ctx, outbuf, inbuf, iv);

        nblocks -= 2;
        outbuf += 2 * BLOWFISH_BLOCKSIZE;
        inbuf  += 2 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
  }
#endif

  for ( ;nblocks; nblocks-- )
    {
      /* INBUF is needed later and it may be identical to OUTBUF, so store
         the intermediate result to SAVEBUF.  */
      do_decrypt_block (ctx, savebuf, inbuf);

      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE);
      inbuf += BLOWFISH_BLOCKSIZE;
      outbuf += BLOWFISH_BLOCKSIZE;
    }

  wipememory(savebuf, sizeof(savebuf));
  _gcry_burn_stack(burn_stack_depth);
}
Exemplo n.º 16
0
static void
serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
  serpent_context_t *context = ctx;

  serpent_encrypt_internal (context,
			    (const u32 *) buffer_in, (u32 *) buffer_out);
  _gcry_burn_stack (2 * sizeof (serpent_block_t));
}
Exemplo n.º 17
0
/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
static void
serpent_setkey_internal (serpent_context_t *context,
			 const byte *key, unsigned int key_length)
{
  serpent_key_t key_prepared;

  serpent_key_prepare (key, key_length, key_prepared);
  serpent_subkeys_generate (key_prepared, context->keys);
  _gcry_burn_stack (272 * sizeof (u32));
}
Exemplo n.º 18
0
void
_gcry_burn_stack (int bytes)
{
    char buf[64];
    
    wipememory (buf, sizeof buf);
    bytes -= sizeof buf;
    if (bytes > 0)
        _gcry_burn_stack (bytes);
}
Exemplo n.º 19
0
void texpdf_MD5_final (unsigned char *outbuf, MD5_CONTEXT *hd)
{
  unsigned long t, msb, lsb;
  unsigned char *p;

  texpdf_MD5_write(hd, NULL, 0); /* flush */

  t = hd->nblocks;
  /* multiply by 64 to make a byte count */
  lsb = t << 6;
  msb = t >> 26;
  /* add the count */
  t = lsb;
  if ((lsb += hd->count) < t) msb++;
  /* multiply by 8 to make a bit count */
  t = lsb;
  lsb <<= 3;
  msb <<= 3;
  msb |= t >> 29;

  if (hd->count < 56) { /* enough room */
    hd->buf[hd->count++] = 0x80; /* pad */
    while (hd->count < 56) hd->buf[hd->count++] = 0; /* pad */
  } else { /* need one extra block */
    hd->buf[hd->count++] = 0x80; /* pad character */
    while (hd->count < 64) hd->buf[hd->count++] = 0;
    texpdf_MD5_write(hd, NULL, 0); /* flush */
    memset(hd->buf, 0, 56); /* fill next block with zeroes */
  }
  /* append the 64 bit count */
  hd->buf[56] = lsb & 0xff;
  hd->buf[57] = (lsb >> 8) & 0xff;
  hd->buf[58] = (lsb >> 16) & 0xff;
  hd->buf[59] = (lsb >> 24) & 0xff;
  hd->buf[60] = msb & 0xff;
  hd->buf[61] = (msb >> 8) & 0xff;
  hd->buf[62] = (msb >> 16) & 0xff;
  hd->buf[63] = (msb >> 24) & 0xff;
  transform(hd, hd->buf);
  _gcry_burn_stack(80+6*sizeof(void*));

  p = outbuf; /* p = hd->buf; */
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a; *p++ = hd->a >> 8; \
	          *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while (0)
#else /* little endian */
#define X(a) do { *(uint32_t *)p = (*hd).a ; p += sizeof(uint32_t); } while (0)
#endif
  X(A);
  X(B);
  X(C);
  X(D);
#undef X
}
Exemplo n.º 20
0
/* Update the message digest with the contents
 * of INBUF with length INLEN.
 */
static void
sha1_write( void *context, const void *inbuf_arg, size_t inlen)
{
  const unsigned char *inbuf = inbuf_arg;
  SHA1_CONTEXT *hd = context;
  size_t nblocks;

  if (hd->count == 64)  /* Flush the buffer. */
    {
      TRANSFORM( hd, hd->buf, 1 );
      _gcry_burn_stack (88+4*sizeof(void*));
      hd->count = 0;
      hd->nblocks++;
    }
  if (!inbuf)
    return;

  if (hd->count)
    {
      for (; inlen && hd->count < 64; inlen--)
        hd->buf[hd->count++] = *inbuf++;
      sha1_write (hd, NULL, 0);
      if (!inlen)
        return;
    }

  nblocks = inlen / 64;
  if (nblocks)
    {
      TRANSFORM (hd, inbuf, nblocks);
      hd->count = 0;
      hd->nblocks += nblocks;
      inlen -= nblocks * 64;
      inbuf += nblocks * 64;
    }
  _gcry_burn_stack (88+4*sizeof(void*));

  /* Save remaining bytes.  */
  for (; inlen && hd->count < 64; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
Exemplo n.º 21
0
static void
rmd160_final( void *context )
{
  RMD160_CONTEXT *hd = context;
  u32 t, msb, lsb;
  byte *p;
  unsigned int burn;

  _gcry_md_block_write(hd, NULL, 0); /* flush */;

  t = hd->bctx.nblocks;
  /* multiply by 64 to make a byte count */
  lsb = t << 6;
  msb = t >> 26;
  /* add the count */
  t = lsb;
  if( (lsb += hd->bctx.count) < t )
    msb++;
  /* multiply by 8 to make a bit count */
  t = lsb;
  lsb <<= 3;
  msb <<= 3;
  msb |= t >> 29;

  if( hd->bctx.count < 56 )  /* enough room */
    {
      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
      while( hd->bctx.count < 56 )
        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
    }
  else  /* need one extra block */
    {
      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
      while( hd->bctx.count < 64 )
        hd->bctx.buf[hd->bctx.count++] = 0;
      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
    }
  /* append the 64 bit count */
  buf_put_le32(hd->bctx.buf + 56, lsb);
  buf_put_le32(hd->bctx.buf + 60, msb);
  burn = transform( hd, hd->bctx.buf );
  _gcry_burn_stack (burn);

  p = hd->bctx.buf;
#define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0)
  X(0);
  X(1);
  X(2);
  X(3);
  X(4);
#undef X
}
Exemplo n.º 22
0
static gcry_err_code_t
camellia_setkey(void *c, const byte *key, unsigned keylen)
{
  CAMELLIA_context *ctx=c;
  static int initialized=0;
  static const char *selftest_failed=NULL;
#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
  unsigned int hwf = _gcry_get_hw_features ();
#endif

  if(keylen!=16 && keylen!=24 && keylen!=32)
    return GPG_ERR_INV_KEYLEN;

  if(!initialized)
    {
      initialized=1;
      selftest_failed=selftest();
      if(selftest_failed)
	log_error("%s\n",selftest_failed);
    }

  if(selftest_failed)
    return GPG_ERR_SELFTEST_FAILED;

#ifdef USE_AESNI_AVX
  ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX);
#endif
#ifdef USE_AESNI_AVX2
  ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2);
#endif

  ctx->keybitlength=keylen*8;

  if (0)
    { }
#ifdef USE_AESNI_AVX
  else if (ctx->use_aesni_avx)
    _gcry_camellia_aesni_avx_keygen(ctx, key, keylen);
  else
#endif
    {
      Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
      _gcry_burn_stack
        ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
         +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
         +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
         +3*2*sizeof(void*)                     /* Function calls.  */
         );
    }

  return 0;
}
Exemplo n.º 23
0
/* Bulk decryption of complete blocks in CFB mode.  This function is only
   intended for the bulk encryption feature of cipher.c. */
void
_gcry_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
		       const void *inbuf_arg, size_t nblocks)
{
  BLOWFISH_context *ctx = context;
  unsigned char *outbuf = outbuf_arg;
  const unsigned char *inbuf = inbuf_arg;
  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;

#ifdef USE_AMD64_ASM
  {
    if (nblocks >= 4)
      burn_stack_depth += 5 * sizeof(void*);

    /* Process data in 4 block chunks. */
    while (nblocks >= 4)
      {
        _gcry_blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);

        nblocks -= 4;
        outbuf += 4 * BLOWFISH_BLOCKSIZE;
        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
  }
#elif defined(USE_ARM_ASM)
  {
    /* Process data in 2 block chunks. */
    while (nblocks >= 2)
      {
        _gcry_blowfish_arm_cfb_dec(ctx, outbuf, inbuf, iv);

        nblocks -= 2;
        outbuf += 2 * BLOWFISH_BLOCKSIZE;
        inbuf  += 2 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
  }
#endif

  for ( ;nblocks; nblocks-- )
    {
      do_encrypt_block(ctx, iv, iv);
      buf_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE);
      outbuf += BLOWFISH_BLOCKSIZE;
      inbuf  += BLOWFISH_BLOCKSIZE;
    }

  _gcry_burn_stack(burn_stack_depth);
}
Exemplo n.º 24
0
Arquivo: md5.c Projeto: Arvian/GRUB2
/* The routine updates the message-digest context to
 * account for the presence of each of the characters inBuf[0..inLen-1]
 * in the message whose digest is being computed.
 */
static void
md5_write( void *context, const void *inbuf_arg , size_t inlen)
{
  const unsigned char *inbuf = inbuf_arg;
  MD5_CONTEXT *hd = context;
  
  if( hd->count == 64 )  /* flush the buffer */
    {
      transform( hd, hd->buf );
      _gcry_burn_stack (80+6*sizeof(void*));
      hd->count = 0;
      hd->nblocks++;
    }
  if( !inbuf )
    return;

  if( hd->count )
    {
      for( ; inlen && hd->count < 64; inlen-- )
        hd->buf[hd->count++] = *inbuf++;
      md5_write( hd, NULL, 0 );
      if( !inlen )
        return;
    }
  _gcry_burn_stack (80+6*sizeof(void*));

  while( inlen >= 64 ) 
    {
      transform( hd, inbuf );
      hd->count = 0;
      hd->nblocks++;
      inlen -= 64;
      inbuf += 64;
    }
  for( ; inlen && hd->count < 64; inlen-- )
    hd->buf[hd->count++] = *inbuf++;

}
Exemplo n.º 25
0
gcry_err_code_t
_gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c,
                          unsigned char *outbuf, size_t outbuflen,
                          const unsigned char *inbuf, size_t inbuflen)
{
  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
  size_t blocksize = c->spec->blocksize;
  unsigned int burn, nburn;
  unsigned char appendee;

  if (outbuflen < inbuflen)
    return GPG_ERR_BUFFER_TOO_SHORT;

  burn = 0;

  while (inbuflen > 0)
    {
      int i;

      /* Encrypt the IV. */
      nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv );
      burn = nburn > burn ? nburn : burn;

      /* inbuf might == outbuf, make sure we keep the value
         so we can append it later */
      appendee = inbuf[0];

      outbuf[0] = inbuf[0] ^ c->lastiv[0];

      /* Bitshift iv by 8 bit to the left */
      for (i = 0; i < blocksize-1; i++)
        c->u_iv.iv[i] = c->u_iv.iv[i+1];

      c->u_iv.iv[blocksize-1] = appendee;

      outbuf += 1;
      inbuf += 1;
      inbuflen -= 1;
    }

  if (burn > 0)
    _gcry_burn_stack (burn + 4 * sizeof(void *));

  return 0;
}
Exemplo n.º 26
0
static void
salsa20_encrypt_stream (void *context,
                        byte *outbuf, const byte *inbuf, unsigned int length)
{
  SALSA20_context_t *ctx = (SALSA20_context_t *)context;

  if (length)
    {
      salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length);
      _gcry_burn_stack (/* salsa20_do_encrypt_stream: */
                        2*sizeof (void*)
                        + 3*sizeof (void*) + sizeof (unsigned int)
                        /* salsa20_core: */
                        + 2*sizeof (void*)
                        + 2*sizeof (void*)
                        + 64
                        + sizeof (unsigned int)
                        + sizeof (u32)
                        );
    }
}
Exemplo n.º 27
0
static void
md4_final( void *context )
{
  MD4_CONTEXT *hd = context;
  u32 t, msb, lsb;
  byte *p;

  md4_write(hd, NULL, 0); /* flush */;

  t = hd->nblocks;
  /* multiply by 64 to make a byte count */
  lsb = t << 6;
  msb = t >> 26;
  /* add the count */
  t = lsb;
  if( (lsb += hd->count) < t )
    msb++;
  /* multiply by 8 to make a bit count */
  t = lsb;
  lsb <<= 3;
  msb <<= 3;
  msb |= t >> 29;
  
  if( hd->count < 56 )  /* enough room */
    {
      hd->buf[hd->count++] = 0x80; /* pad */
      while( hd->count < 56 )
        hd->buf[hd->count++] = 0;  /* pad */
    }
  else /* need one extra block */ 
    { 
      hd->buf[hd->count++] = 0x80; /* pad character */
      while( hd->count < 64 )
        hd->buf[hd->count++] = 0;
      md4_write(hd, NULL, 0);  /* flush */;
      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
    }
  /* append the 64 bit count */
  hd->buf[56] = lsb	   ;
  hd->buf[57] = lsb >>  8;
  hd->buf[58] = lsb >> 16;
  hd->buf[59] = lsb >> 24;
  hd->buf[60] = msb	   ;
  hd->buf[61] = msb >>  8;
  hd->buf[62] = msb >> 16;
  hd->buf[63] = msb >> 24;
  transform( hd, hd->buf );
  _gcry_burn_stack (80+6*sizeof(void*));

  p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
		  *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
#endif
  X(A);
  X(B);
  X(C);
  X(D);
#undef X

}
Exemplo n.º 28
0
/* Bulk encryption of complete blocks in CTR mode.  This function is only
   intended for the bulk encryption feature of cipher.c.  CTR is expected to be
   of size BLOWFISH_BLOCKSIZE. */
void
_gcry_blowfish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
		       const void *inbuf_arg, size_t nblocks)
{
  BLOWFISH_context *ctx = context;
  unsigned char *outbuf = outbuf_arg;
  const unsigned char *inbuf = inbuf_arg;
  unsigned char tmpbuf[BLOWFISH_BLOCKSIZE];
  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;
  int i;

#ifdef USE_AMD64_ASM
  {
    if (nblocks >= 4)
      burn_stack_depth += 5 * sizeof(void*);

    /* Process data in 4 block chunks. */
    while (nblocks >= 4)
      {
        _gcry_blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);

        nblocks -= 4;
        outbuf += 4 * BLOWFISH_BLOCKSIZE;
        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
    /* TODO: use caching instead? */
  }
#elif defined(USE_ARM_ASM)
  {
    /* Process data in 2 block chunks. */
    while (nblocks >= 2)
      {
        _gcry_blowfish_arm_ctr_enc(ctx, outbuf, inbuf, ctr);

        nblocks -= 2;
        outbuf += 2 * BLOWFISH_BLOCKSIZE;
        inbuf  += 2 * BLOWFISH_BLOCKSIZE;
      }

    /* Use generic code to handle smaller chunks... */
    /* TODO: use caching instead? */
  }
#endif

  for ( ;nblocks; nblocks-- )
    {
      /* Encrypt the counter. */
      do_encrypt_block(ctx, tmpbuf, ctr);
      /* XOR the input with the encrypted counter and store in output.  */
      buf_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE);
      outbuf += BLOWFISH_BLOCKSIZE;
      inbuf  += BLOWFISH_BLOCKSIZE;
      /* Increment the counter.  */
      for (i = BLOWFISH_BLOCKSIZE; i > 0; i--)
        {
          ctr[i-1]++;
          if (ctr[i-1])
            break;
        }
    }

  wipememory(tmpbuf, sizeof(tmpbuf));
  _gcry_burn_stack(burn_stack_depth);
}
Exemplo n.º 29
0
/*
   The routine finally terminates the computation and returns the
   digest.  The handle is prepared for a new cycle, but adding bytes
   to the handle will the destroy the returned buffer.  Returns: 32
   bytes with the message the digest.  */
static void
sha256_final(void *context)
{
  SHA256_CONTEXT *hd = context;
  u32 t, msb, lsb;
  byte *p;
  
  sha256_write (hd, NULL, 0); /* flush */;

  t = hd->nblocks;
  /* multiply by 64 to make a byte count */
  lsb = t << 6;
  msb = t >> 26;
  /* add the count */
  t = lsb;
  if ((lsb += hd->count) < t)
    msb++;
  /* multiply by 8 to make a bit count */
  t = lsb;
  lsb <<= 3;
  msb <<= 3;
  msb |= t >> 29;

  if (hd->count < 56)
    { /* enough room */
      hd->buf[hd->count++] = 0x80; /* pad */
      while (hd->count < 56)
        hd->buf[hd->count++] = 0;  /* pad */
    }
  else
    { /* need one extra block */
      hd->buf[hd->count++] = 0x80; /* pad character */
      while (hd->count < 64)
        hd->buf[hd->count++] = 0;
      sha256_write (hd, NULL, 0);  /* flush */;
      memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
    }
  /* append the 64 bit count */
  hd->buf[56] = msb >> 24;
  hd->buf[57] = msb >> 16;
  hd->buf[58] = msb >>  8;
  hd->buf[59] = msb;
  hd->buf[60] = lsb >> 24;
  hd->buf[61] = lsb >> 16;
  hd->buf[62] = lsb >>  8;
  hd->buf[63] = lsb;
  transform (hd, hd->buf);
  _gcry_burn_stack (74*4+32);

  p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;	 \
		  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
#endif
  X(0);
  X(1);
  X(2);
  X(3);
  X(4);
  X(5);
  X(6);
  X(7);
#undef X
}
Exemplo n.º 30
0
/* Bulk decryption of complete blocks in CFB mode.  This function is only
   intended for the bulk encryption feature of cipher.c. */
void
_gcry_camellia_cfb_dec(void *context, unsigned char *iv,
                       void *outbuf_arg, const void *inbuf_arg,
                       size_t nblocks)
{
  CAMELLIA_context *ctx = context;
  unsigned char *outbuf = outbuf_arg;
  const unsigned char *inbuf = inbuf_arg;
  int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;

#ifdef USE_AESNI_AVX2
  if (ctx->use_aesni_avx2)
    {
      int did_use_aesni_avx2 = 0;

      /* Process data in 32 block chunks. */
      while (nblocks >= 32)
        {
          _gcry_camellia_aesni_avx2_cfb_dec(ctx, outbuf, inbuf, iv);

          nblocks -= 32;
          outbuf += 32 * CAMELLIA_BLOCK_SIZE;
          inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
          did_use_aesni_avx2 = 1;
        }

      if (did_use_aesni_avx2)
        {
          int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
                                        2 * sizeof(void *) + ASM_EXTRA_STACK;

          if (burn_stack_depth < avx2_burn_stack_depth)
            burn_stack_depth = avx2_burn_stack_depth;
        }

      /* Use generic code to handle smaller chunks... */
    }
#endif

#ifdef USE_AESNI_AVX
  if (ctx->use_aesni_avx)
    {
      int did_use_aesni_avx = 0;

      /* Process data in 16 block chunks. */
      while (nblocks >= 16)
        {
          _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv);

          nblocks -= 16;
          outbuf += 16 * CAMELLIA_BLOCK_SIZE;
          inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
          did_use_aesni_avx = 1;
        }

      if (did_use_aesni_avx)
        {
          int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
                                       2 * sizeof(void *) + ASM_EXTRA_STACK;

          if (burn_stack_depth < avx_burn_stack_depth)
            burn_stack_depth = avx_burn_stack_depth;
        }

      /* Use generic code to handle smaller chunks... */
    }
#endif

  for ( ;nblocks; nblocks-- )
    {
      Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
      buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
      outbuf += CAMELLIA_BLOCK_SIZE;
      inbuf  += CAMELLIA_BLOCK_SIZE;
    }

  _gcry_burn_stack(burn_stack_depth);
}