コード例 #1
0
ファイル: Crypto.cpp プロジェクト: daniellandau/keepassx
bool Crypto::checkAlgorithms()
{
    if (gcry_cipher_algo_info(GCRY_CIPHER_AES256, GCRYCTL_TEST_ALGO, nullptr, nullptr) != 0) {
        m_errorStr = "GCRY_CIPHER_AES256 not found.";
        qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
        return false;
    }
    if (gcry_cipher_algo_info(GCRY_CIPHER_TWOFISH, GCRYCTL_TEST_ALGO, nullptr, nullptr) != 0) {
        m_errorStr = "GCRY_CIPHER_TWOFISH not found.";
        qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
        return false;
    }
    if (gcry_cipher_algo_info(GCRY_CIPHER_SALSA20, GCRYCTL_TEST_ALGO, nullptr, nullptr) != 0) {
        m_errorStr = "GCRY_CIPHER_SALSA20 not found.";
        qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
        return false;
    }
    if (gcry_md_test_algo(GCRY_MD_SHA256) != 0) {
        m_errorStr = "GCRY_MD_SHA256 not found.";
        qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
        return false;
    }

    return true;
}
コード例 #2
0
/* Put the DIGEST into an DER encoded container and return it in R_VAL. */
static int
encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
                    unsigned char **r_val, size_t *r_len)
{
  unsigned char *frame;
  unsigned char asn[100];
  size_t asnlen;

  *r_val = NULL;
  *r_len = 0;

  asnlen = DIM(asn);
  if (!algo || gcry_md_test_algo (algo))
    return gpg_error (GPG_ERR_DIGEST_ALGO);
  if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
    {
      log_error ("no object identifier for algo %d\n", algo);
      return gpg_error (GPG_ERR_INTERNAL);
    }

  frame = xtrymalloc (asnlen + digestlen);
  if (!frame)
    return out_of_core ();
  memcpy (frame, asn, asnlen);
  memcpy (frame+asnlen, digest, digestlen);
  if (DBG_CRYPTO)
    log_printhex ("encoded hash:", frame, asnlen+digestlen);
      
  *r_val = frame;
  *r_len = asnlen+digestlen;
  return 0;
}
コード例 #3
0
ファイル: csum-gcrypt.c プロジェクト: moben/duperemove
int init_hash(void)
{
	/*
	 * Version check should be the very first call because it makes sure
	 * that important subsystems are intialized.
	 */
	if (!gcry_check_version(GCRYPT_VERSION))
		return 1;

	/* Disable secure memory.  */
	gcry_control(GCRYCTL_DISABLE_SECMEM, 0);

	/* Tell Libgcrypt that initialization has completed. */
	gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);

	if (gcry_md_test_algo(HASH_FUNC))
		return 1;

	digest_len = gcry_md_get_algo_dlen(HASH_FUNC);
	if (!digest_len)
		return 1;

	abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX);

	return 0;
}
コード例 #4
0
ファイル: bench-slope.c プロジェクト: 0ndorio/libgcrypt
void
hash_bench (char **argv, int argc)
{
  int i, algo;

  bench_print_section ("hash", "Hash");
  bench_print_header (14, "");

  if (argv && argc)
    {
      for (i = 0; i < argc; i++)
	{
	  algo = gcry_md_map_name (argv[i]);
	  if (algo)
	    _hash_bench (algo);
	}
    }
  else
    {
      for (i = 1; i < 400; i++)
	if (!gcry_md_test_algo (i))
	  _hash_bench (i);
    }

  bench_print_footer (14);
}
コード例 #5
0
ファイル: rpmcdsa.c プロジェクト: hahnakane/junkcode
static int rpmcdsaAvailableDigest(pgpDig dig, int algo)
{
    int rc = 0;	/* assume available */
#ifdef	REFERENCE
    rc = rpmgcAvailable(dig->impl, algo,
    	(gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
#endif
    return rc;
}
コード例 #6
0
ファイル: bench-slope.c プロジェクト: 0ndorio/libgcrypt
void
kdf_bench (char **argv, int argc)
{
  char algo_name[32];
  int i, j;

  bench_print_section ("kdf", "KDF");

  if (!csv_mode)
    {
      printf (" %-*s | ", 24, "");
      printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
    }

  if (argv && argc)
    {
      for (i = 0; i < argc; i++)
	{
	  for (j = 1; j < 400; j++)
	    {
	      if (gcry_md_test_algo (j))
		continue;

	      snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
			gcry_md_algo_name (j));

	      if (!strcmp(argv[i], algo_name))
		kdf_bench_one (GCRY_KDF_PBKDF2, j);
	    }
	}
    }
  else
    {
      for (i = 1; i < 400; i++)
	if (!gcry_md_test_algo (i))
	  kdf_bench_one (GCRY_KDF_PBKDF2, i);
    }

  bench_print_footer (24);
}
コード例 #7
0
ファイル: kmocrypt.c プロジェクト: fdgonthier/kmod
/**
 * Proceed to a hash on a kbuffer, putting the result in the
 * hash kbuffer.
 */
void kmocrypt_hash(kbuffer * input, kbuffer * hash, int algo) {
    int digest_len;
    uint32_t input_size;
    
    /* Simple hashing, result is put directly in the buffer, no
       copy needed, no payment until 2099. */

    assert(gcry_md_test_algo(algo) == 0);

    digest_len = gcry_md_get_algo_dlen(algo);

    /* Get the length and addresse of unread data from input, and read it to
     * the end */
    input_size = input->len - input->pos;

    /* Hash the buffer. */
    gcry_md_hash_buffer(algo,
                        kbuffer_append_nbytes(hash, digest_len),
                        kbuffer_read_nbytes(input, input_size),
                        (size_t)input_size);
}
コード例 #8
0
ファイル: kmocryptsignature2.c プロジェクト: fdgonthier/kmod
/* This function recognizes the KSP content.
 * This function sets the KMO error string. It returns -1 on failure.
 */
int kmocrypt_recognize_ksp2(struct kmocrypt_signature2 *self, kbuffer *buffer) {
    uint32_t header_len = 27;
    uint32_t subpackets_len;

    if (buffer->len < header_len) {
        kmo_seterror("KSP header too short");
        return -1;
    }

    /* MAGIC */
    kbuffer_read32(buffer);

    /* MAJOR */
    self->major= kbuffer_read32(buffer);

    /* MINOR */
    self->minor = kbuffer_read32(buffer);

    /* MEMBER ID */
    self->mid = kbuffer_read64(buffer);

    /* HASH ALGO */
    self->hash_algo = kbuffer_read8(buffer);
    if (gcry_md_test_algo(self->hash_algo)) {
        kmo_seterror("unsupported hash algorithm");
        return -1;
    }

    /* SIG ALGO */
    self->sig_algo = kbuffer_read8(buffer);
    if (gcry_pk_test_algo(self->sig_algo)) {
        kmo_seterror("unsupported signature algorithm");
        return -1;
    }

    /* PACKAGING TYPE */
    self->pkg_type = kbuffer_read8(buffer);
    if (self->pkg_type >= KMO_P_NB_TYPE) {
        kmo_seterror("invalid signature packet type");
        return -1;
    }

    /* SUBPACKETS LENGTH */
    subpackets_len = kbuffer_read32(buffer);
    
    if (! subpackets_len) {
        kmo_seterror("no subpacket in KSP");
        return -1;
    }
    
    if (buffer->len < header_len + subpackets_len) {
        kmo_seterror("KSP subpacket section is too short");
        return -1;
    }
    
    /* Recognize the subpackets. */
    if (recognize_subpackets(self, buffer, subpackets_len)) {
        return -1;
    }
    
    /* Recognize the signature of the KSP, unless it's the encryption key. */
    if (self->mid && recognize_ksp_signature(self, buffer, buffer->len - buffer->pos)) {
        return -1;
    }
    
    return 0;
}
コード例 #9
0
ファイル: seckey-cert.c プロジェクト: 0ndorio/gnupg
static int
xxxx_do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
               int *canceled )
{
    gpg_error_t err;
    byte *buffer;
    u16 csum=0;
    int i, res;
    size_t nbytes;

    if( sk->is_protected ) { /* remove the protection */
	DEK *dek = NULL;
	u32 keyid[4]; /* 4! because we need two of them */
	gcry_cipher_hd_t cipher_hd=NULL;
	PKT_secret_key *save_sk;

	if( sk->protect.s2k.mode == 1001 ) {
	    log_info(_("secret key parts are not available\n"));
	    return GPG_ERR_UNUSABLE_SECKEY;
	}
	if( sk->protect.algo == CIPHER_ALGO_NONE )
	    BUG();
	if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
	    log_info(_("protection algorithm %d%s is not supported\n"),
			sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
	    return GPG_ERR_CIPHER_ALGO;
	}
	if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
	  {
	    log_info(_("protection digest %d is not supported\n"),
		     sk->protect.s2k.hash_algo);
	    return GPG_ERR_DIGEST_ALGO;
	  }
	keyid_from_sk( sk, keyid );
	keyid[2] = keyid[3] = 0;
	if (!sk->flags.primary)
          {
            keyid[2] = sk->main_keyid[0];
            keyid[3] = sk->main_keyid[1];
          }
	dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
				 &sk->protect.s2k, mode,
                                 tryagain_text, canceled );
        if (!dek && canceled && *canceled)
	    return GPG_ERR_CANCELED;


	err = openpgp_cipher_open (&cipher_hd, sk->protect.algo,
				   GCRY_CIPHER_MODE_CFB,
				   (GCRY_CIPHER_SECURE
				    | (sk->protect.algo >= 100 ?
				       0 : GCRY_CIPHER_ENABLE_SYNC)));
        if (err)
          log_fatal ("cipher open failed: %s\n", gpg_strerror (err) );

	err = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
        if (err)
          log_fatal ("set key failed: %s\n", gpg_strerror (err) );

	xfree(dek);
	save_sk = copy_secret_key( NULL, sk );

	gcry_cipher_setiv ( cipher_hd, sk->protect.iv, sk->protect.ivlen );

	csum = 0;
	if( sk->version >= 4 ) {
            int ndata;
	    unsigned int ndatabits;
	    byte *p, *data;
            u16 csumc = 0;

	    i = pubkey_get_npkey(sk->pubkey_algo);

            assert ( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
            p = gcry_mpi_get_opaque ( sk->skey[i], &ndatabits );
            ndata = (ndatabits+7)/8;

            if ( ndata > 1 )
              csumc = buf16_to_u16 (p+ndata-2);
	    data = xmalloc_secure ( ndata );
	    gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
	    gcry_mpi_release (sk->skey[i]); sk->skey[i] = NULL ;

	    p = data;
            if (sk->protect.sha1chk) {
                /* This is the new SHA1 checksum method to detect
                   tampering with the key as used by the Klima/Rosa
                   attack */
                sk->csum = 0;
                csum = 1;
                if( ndata < 20 )
                    log_error("not enough bytes for SHA-1 checksum\n");
                else {
                    gcry_md_hd_t h;

                    if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
                        BUG(); /* Algo not available. */
                    gcry_md_write (h, data, ndata - 20);
                    gcry_md_final (h);
                    if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
                                 data + ndata - 20, 20) )
                      {
                        /* Digest does match.  We have to keep the old
                           style checksum in sk->csum, so that the
                           test used for unprotected keys does work.
                           This test gets used when we are adding new
                           keys. */
                        sk->csum = csum = checksum (data, ndata-20);
                      }
                    gcry_md_close (h);
                }
            }
            else {
                if( ndata < 2 ) {
                    log_error("not enough bytes for checksum\n");
                    sk->csum = 0;
                    csum = 1;
                }
                else {
                    csum = checksum( data, ndata-2);
                    sk->csum = data[ndata-2] << 8 | data[ndata-1];
                    if ( sk->csum != csum ) {
                        /* This is a PGP 7.0.0 workaround */
                        sk->csum = csumc; /* take the encrypted one */
                    }
                }
            }

            /* Must check it here otherwise the mpi_read_xx would fail
               because the length may have an arbitrary value */
            if( sk->csum == csum ) {
                for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
                    if ( gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
                                        p, ndata, &nbytes))
                      {
                        /* Checksum was okay, but not correctly
                           decrypted.  */
                        sk->csum = 0;
                        csum = 1;
                        break;
                      }
                    ndata -= nbytes;
                    p += nbytes;
                }
                /* Note: at this point ndata should be 2 for a simple
                   checksum or 20 for the sha1 digest */
            }
	    xfree(data);
	}
	else {
	    for(i=pubkey_get_npkey(sk->pubkey_algo);
		    i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
                byte *p;
                size_t ndata;
                unsigned int ndatabits;

                assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
                p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
                ndata = (ndatabits+7)/8;
                assert (ndata >= 2);
                assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
                buffer = xmalloc_secure (ndata);
		gcry_cipher_sync (cipher_hd);
                buffer[0] = p[0];
                buffer[1] = p[1];
                gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
                                     p+2, ndata-2);
                csum += checksum (buffer, ndata);
                gcry_mpi_release (sk->skey[i]);

		err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
				     buffer, ndata, &ndata );
		xfree (buffer);
                if (err)
                  {
                    /* Checksum was okay, but not correctly
                       decrypted.  */
                    sk->csum = 0;
                    csum = 1;
                    break;
                  }
/*  		csum += checksum_mpi (sk->skey[i]); */
	    }
	}
	gcry_cipher_close ( cipher_hd );

	/* Now let's see whether we have used the correct passphrase. */
	if( csum != sk->csum ) {
	    copy_secret_key( sk, save_sk );
            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
	    free_secret_key( save_sk );
	    return gpg_error (GPG_ERR_BAD_PASSPHRASE);
	}

	/* The checksum may fail, so we also check the key itself. */
	res = pk_check_secret_key ( sk->pubkey_algo, sk->skey );
	if( res ) {
	    copy_secret_key( sk, save_sk );
            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
	    free_secret_key( save_sk );
	    return gpg_error (GPG_ERR_BAD_PASSPHRASE);
	}
	free_secret_key( save_sk );
	sk->is_protected = 0;
    }
    else { /* not protected, assume it is okay if the checksum is okay */
	csum = 0;
	for(i=pubkey_get_npkey(sk->pubkey_algo);
		i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
	    csum += checksum_mpi( sk->skey[i] );
	}
	if( csum != sk->csum )
	    return GPG_ERR_CHECKSUM;
    }

    return 0;
}
コード例 #10
0
ファイル: benchmark.c プロジェクト: Greenchik/libgcrypt
static void
md_bench ( const char *algoname )
{
  int algo;
  gcry_md_hd_t hd;
  int i, j, repcount;
  char buf_base[1000+15];
  size_t bufsize = 1000;
  char *buf;
  char *largebuf_base;
  char *largebuf;
  char digest[512/8];
  gcry_error_t err = GPG_ERR_NO_ERROR;

  if (!algoname)
    {
      for (i=1; i < 400; i++)
        if (in_fips_mode && i == GCRY_MD_MD5)
          ; /* Don't use MD5 in fips mode.  */
        else if ( !gcry_md_test_algo (i) )
          md_bench (gcry_md_algo_name (i));
      return;
    }

  buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment);

  algo = gcry_md_map_name (algoname);
  if (!algo)
    {
      fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
      exit (1);
    }

  err = gcry_md_open (&hd, algo, 0);
  if (err)
    {
      fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
      exit (1);
    }

  for (i=0; i < bufsize; i++)
    buf[i] = i;

  printf ("%-12s", gcry_md_algo_name (algo));

  start_timer ();
  for (repcount=0; repcount < hash_repetitions; repcount++)
    for (i=0; i < 1000; i++)
      gcry_md_write (hd, buf, bufsize);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());
  fflush (stdout);

  gcry_md_reset (hd);
  start_timer ();
  for (repcount=0; repcount < hash_repetitions; repcount++)
    for (i=0; i < 10000; i++)
      gcry_md_write (hd, buf, bufsize/10);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());
  fflush (stdout);

  gcry_md_reset (hd);
  start_timer ();
  for (repcount=0; repcount < hash_repetitions; repcount++)
    for (i=0; i < 1000000; i++)
      gcry_md_write (hd, buf, 1);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());
  fflush (stdout);

  start_timer ();
  for (repcount=0; repcount < hash_repetitions; repcount++)
    for (i=0; i < 1000; i++)
      for (j=0; j < bufsize; j++)
        gcry_md_putc (hd, buf[j]);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());
  fflush (stdout);

  gcry_md_close (hd);

  /* Now 100 hash operations on 10000 bytes using the fast function.
     We initialize the buffer so that all memory pages are committed
     and we have repeatable values.  */
  if (gcry_md_get_algo_dlen (algo) > sizeof digest)
    die ("digest buffer too short\n");

  largebuf_base = malloc (10000+15);
  if (!largebuf_base)
    die ("out of core\n");
  largebuf = (largebuf_base
              + ((16 - ((size_t)largebuf_base & 0x0f)) % buffer_alignment));

  for (i=0; i < 10000; i++)
    largebuf[i] = i;
  start_timer ();
  for (repcount=0; repcount < hash_repetitions; repcount++)
    for (i=0; i < 100; i++)
      gcry_md_hash_buffer (algo, digest, largebuf, 10000);
  stop_timer ();
  printf (" %s", elapsed_time ());
  free (largebuf_base);

  putchar ('\n');
  fflush (stdout);
}
コード例 #11
0
ファイル: gcrypt.c プロジェクト: jbmulligan/quip
//	gcry_md_close(my_hash_hdl);

	gcry_md_write(my_hash_hdl,data_buf,data_len);
	gcry_md_putc(my_hash_hdl,c);
	gcry_md_final(my_hash_hdl);
	unsigned char *digest;
	digest = gcry_md_read(my_hash_hdl,0);

	// shortcut function:

	gcry_md_get_algo_dlen(the_hash_algo);	// get required digest size
	unsigned char digest_buf[DIGEST_SIZE];
	gcry_md_hash_buffer(the_hash_algo,digest_buf,inbuf,inlen);

	// to verify algo available for use:
	status = gcry_md_test_algo(the_hash_algo);
#endif // ELSEWHERE

#else /* ! HAVE_LIBGCRYPT */

/* dummy functions which allow the thing to link */

/* Linkage to libgcrypt */

size_t _decrypt_char_buf(QSP_ARG_DECL  const uint8_t *in_buf, size_t in_len, char *out_buf, size_t out_len )
{
	warn("decrypt_char_buf:  libgcrypt not present!?");
	return 0;
}

size_t _encrypt_char_buf(QSP_ARG_DECL  const char *in_buf, size_t in_len, uint8_t *out_buf, size_t out_len)
コード例 #12
0
static void
md_bench ( const char *algoname )
{
  int algo;
  gcry_md_hd_t hd;
  int i;
  char buf[1000];
  gcry_error_t err = GPG_ERR_NO_ERROR;

  if (!algoname)
    {
      for (i=1; i < 400; i++)
        if ( !gcry_md_test_algo (i) )
          md_bench (gcry_md_algo_name (i));
      return;
    }

  algo = gcry_md_map_name (algoname);
  if (!algo)
    {
      fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
      exit (1);
    }

  err = gcry_md_open (&hd, algo, 0);
  if (err)
    {
      fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
      exit (1);
    }

  for (i=0; i < sizeof buf; i++)
    buf[i] = i;

  printf ("%-12s", gcry_md_algo_name (algo));

  start_timer ();
  for (i=0; i < 1000; i++)
    gcry_md_write (hd, buf, sizeof buf);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());

  gcry_md_reset (hd);
  start_timer ();
  for (i=0; i < 10000; i++)
    gcry_md_write (hd, buf, sizeof buf/10);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());

  gcry_md_reset (hd);
  start_timer ();
  for (i=0; i < 1000000; i++)
    gcry_md_write (hd, "", 1);
  gcry_md_final (hd);
  stop_timer ();
  printf (" %s", elapsed_time ());

  gcry_md_close (hd);
  putchar ('\n');
}
コード例 #13
0
ファイル: hashtest.c プロジェクト: HoraceWeebler/libgcrypt
int
main (int argc, char **argv)
{
  int last_argc = -1;
  int gigs = 0;
  int algo = 0;
  int idx;

  if (argc)
    { argc--; argv++; }

  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--help"))
        {
          fputs ("usage: " PGM " [options] [algos]\n"
                 "Options:\n"
                 "  --verbose       print timings etc.\n"
                 "  --debug         flyswatter\n"
                 "  --gigs N        Run a test on N GiB\n",
                 stdout);
          exit (0);
        }
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--debug"))
        {
          verbose += 2;
          debug++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--gigs"))
        {
          argc--; argv++;
          if (argc)
            {
              gigs = atoi (*argv);
              argc--; argv++;
            }
        }
      else if (!strncmp (*argv, "--", 2))
        die ("unknown option '%s'", *argv);
    }

  if (gigs < 0 || gigs > 1024*1024)
    die ("value for --gigs must be in the range 0 to %d", 1024*1024);

  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
  if (!gcry_check_version (GCRYPT_VERSION))
    die ("version mismatch\n");
  if (debug)
    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);

  /* A quick check that all given algorithms are valid.  */
  for (idx=0; idx < argc; idx++)
    {
      algo = gcry_md_map_name (argv[idx]);
      if (!algo)
        fail ("invalid algorithm '%s'", argv[idx]);
    }
  if (error_count)
    exit (1);

  /* Start checking.  */
  start_timer ();
  if (!argc)
    {
      for (algo=1; algo < 400; algo++)
        if (!gcry_md_test_algo (algo))
          {
            if (!gigs)
              run_selftest (algo);
            else
              run_longtest (algo, gigs);
          }
     }
  else
    {
      for (idx=0; idx < argc; idx++)
        {
          algo = gcry_md_map_name (argv[idx]);
          if (!algo)
            die ("invalid algorithm '%s'", argv[idx]);

          if (!gigs)
            run_selftest (algo);
          else
            run_longtest (algo, gigs);
        }
    }
  stop_timer ();

  if (missing_test_vectors)
    fail ("Some test vectors are missing");

  if (verbose)
    show ("All tests completed in %s.  Errors: %d\n",
          elapsed_time (), error_count);
  return !!error_count;
}
コード例 #14
0
ファイル: certcheck.c プロジェクト: 0ndorio/gnupg
static int
do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits,
              gcry_sexp_t pkey, gcry_mpi_t *r_val)
{
  int n;
  size_t nframe;
  unsigned char *frame;

  if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA)
    {
      unsigned int qbits;

      if ( pkalgo == GCRY_PK_ECDSA )
        qbits = gcry_pk_get_nbits (pkey);
      else
        qbits = get_dsa_qbits (pkey);

      if ( (qbits%8) )
	{
	  log_error(_("DSA requires the hash length to be a"
		      " multiple of 8 bits\n"));
	  return gpg_error (GPG_ERR_INTERNAL);
	}

      /* Don't allow any Q smaller than 160 bits.  We don't want
	 someone to issue signatures from a key with a 16-bit Q or
	 something like that, which would look correct but allow
	 trivial forgeries.  Yes, I know this rules out using MD5 with
	 DSA. ;) */
      if (qbits < 160)
	{
	  log_error (_("%s key uses an unsafe (%u bit) hash\n"),
                     gcry_pk_algo_name (pkalgo), qbits);
	  return gpg_error (GPG_ERR_INTERNAL);
	}

      /* Check if we're too short.  Too long is safe as we'll
	 automatically left-truncate. */
      nframe = gcry_md_get_algo_dlen (algo);
      if (nframe < qbits/8)
        {
	  log_error (_("a %u bit hash is not valid for a %u bit %s key\n"),
                     (unsigned int)nframe*8,
                     gcry_pk_get_nbits (pkey),
                     gcry_pk_algo_name (pkalgo));
          /* FIXME: we need to check the requirements for ECDSA.  */
          if (nframe < 20 || pkalgo == GCRY_PK_DSA  )
            return gpg_error (GPG_ERR_INTERNAL);
        }

      frame = xtrymalloc (nframe);
      if (!frame)
        return out_of_core ();
      memcpy (frame, gcry_md_read (md, algo), nframe);
      n = nframe;
      /* Truncate.  */
      if (n > qbits/8)
        n = qbits/8;
    }
  else
    {
      int i;
      unsigned char asn[100];
      size_t asnlen;
      size_t len;

      nframe = (nbits+7) / 8;

      asnlen = DIM(asn);
      if (!algo || gcry_md_test_algo (algo))
        return gpg_error (GPG_ERR_DIGEST_ALGO);
      if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
        {
          log_error ("no object identifier for algo %d\n", algo);
          return gpg_error (GPG_ERR_INTERNAL);
        }

      len = gcry_md_get_algo_dlen (algo);

      if ( len + asnlen + 4  > nframe )
        {
          log_error ("can't encode a %d bit MD into a %d bits frame\n",
                     (int)(len*8), (int)nbits);
          return gpg_error (GPG_ERR_INTERNAL);
        }

      /* We encode the MD in this way:
       *
       *	   0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
       *
       * PAD consists of FF bytes.
       */
      frame = xtrymalloc (nframe);
      if (!frame)
        return out_of_core ();
      n = 0;
      frame[n++] = 0;
      frame[n++] = 1; /* block type */
      i = nframe - len - asnlen -3 ;
      assert ( i > 1 );
      memset ( frame+n, 0xff, i ); n += i;
      frame[n++] = 0;
      memcpy ( frame+n, asn, asnlen ); n += asnlen;
      memcpy ( frame+n, gcry_md_read(md, algo), len ); n += len;
      assert ( n == nframe );
    }
  if (DBG_CRYPTO)
    {
      int j;
      log_debug ("encoded hash:");
      for (j=0; j < nframe; j++)
        log_printf (" %02X", frame[j]);
      log_printf ("\n");
    }

  gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, n, &nframe);
  xfree (frame);
  return 0;
}