コード例 #1
0
ファイル: Tb_rsa.cpp プロジェクト: nforrester/6.375-rsa
char* decrypt(char *private_key, char *ciphertext){
	gcry_error_t error;
	gcry_sexp_t data = sexp_new(ciphertext);

	gcry_sexp_t private_sexp = sexp_new(private_key);
	gcry_sexp_t r_plain;
	struct timeval timer;
	timer_start(&timer);
	if ((error = gcry_pk_decrypt(&r_plain, data, private_sexp))) {
		printf("Error in gcry_pk_decrypt(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}
	timer_poll("\nSoftware decrypt: %d.%06d    seconds\n", &timer);

	gcry_mpi_t r_mpi = gcry_sexp_nth_mpi(r_plain, 0, GCRYMPI_FMT_USG);

	unsigned char *plaintext;
	size_t plaintext_size;
	if ((error = gcry_mpi_aprint(GCRYMPI_FMT_HEX, &plaintext, &plaintext_size, r_mpi))) {
		printf("Error in gcry_mpi_aprint(): %s\nSource: %s\n", gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	// Return type hack
	return (char *) plaintext;
}
コード例 #2
0
CK_RV
gkm_rsa_mechanism_decrypt (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR encrypted,
                           CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
{
	gcry_sexp_t splain, sdata;
	gcry_error_t gcry;
	guint nbits;
	CK_RV rv;

	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
	g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
	g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);

	nbits = gcry_pk_get_nbits (sexp);
	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);

	/* Just want to know the length */
	if (!data) {
		*n_data = (nbits + 7) / 8;
		return CKR_OK;
	}

	if (n_encrypted != (nbits + 7) / 8)
		return CKR_DATA_LEN_RANGE;

	/* Prepare the input s expression */
	rv = gkm_crypto_data_to_sexp ("(enc-val (flags) (rsa (a %m)))",
	                              nbits, NULL, encrypted, n_encrypted, &sdata);
	if (rv != CKR_OK)
		return rv;

	/* Do the magic */
	gcry = gcry_pk_decrypt (&splain, sdata, sexp);
	gcry_sexp_release (sdata);

	/* TODO: Certain codes should be returned (data too big etc... ) */
	if (gcry) {
		g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
		return CKR_FUNCTION_FAILED;
	}

	/* Now extract and send it back out */
	rv = gkm_crypto_sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
	gcry_sexp_release (splain);

	return rv;
}
コード例 #3
0
ファイル: p2p_crypt.c プロジェクト: tjhall13/p2p_net
int p2p_decrypt(unsigned char *buf, size_t buflen, char *msg, size_t msglen, gcry_sexp_t d_key) {    
    size_t err;
    gcry_sexp_t ciph;
    gcry_mpi_t data_mpi;
    gcry_mpi_scan(&data_mpi, GCRYMPI_FMT_PGP, buf, buflen, &err);
    gcry_sexp_build(&ciph, &err, "(enc-val (flags pkcs1) (rsa (a %M)))", data_mpi);
    gcry_mpi_release(data_mpi);
    
    gcry_sexp_t data_sexp;
    gcry_pk_decrypt(&data_sexp, ciph, d_key);
    gcry_sexp_release(ciph);
    gcry_sexp_t data = gcry_sexp_cdr(data_sexp);
    gcry_sexp_release(data_sexp);
    
    size_t len;
    const char *msg_data = gcry_sexp_nth_data(data, 0, &len);
    len = msglen > len ? len : msglen;
    memcpy(msg, msg_data, len);
    gcry_sexp_release(data);
    
    return len;
}
コード例 #4
0
/**
 * cdk_pk_decrypt:
 * @sk: the secret key
 * @pke: public key encrypted packet
 * @r_sk: the object to store the plain session key
 *
 * Decrypt the encrypted session key from @pke into @r_sk.
 **/
cdk_error_t
cdk_pk_decrypt (cdk_seckey_t sk, cdk_pkt_pubkey_enc_t pke,
                gcry_mpi_t *r_sk)
{
  gcry_sexp_t s_data = NULL, s_skey = NULL, s_plain = NULL;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk || !r_sk || !pke)
    return CDK_Inv_Value;
  
  if (!is_unprotected (sk))
    return CDK_Inv_Mode;
  
  *r_sk = NULL;
  rc = seckey_to_sexp (&s_skey, sk);
  if (rc)
    return rc;

  rc = pubenc_to_sexp (&s_data, pke);
  if (rc)
    {
      gcry_sexp_release (s_skey);
      return rc;
    }
  
  err = gcry_pk_decrypt (&s_plain, s_data, s_skey);
  if (err)
    rc = map_gcry_error (err);
  else
    *r_sk  = gcry_sexp_nth_mpi (s_plain, 0, 0);

  gcry_sexp_release (s_data);
  gcry_sexp_release (s_skey);
  gcry_sexp_release (s_plain);
  return rc;
}
コード例 #5
0
ファイル: gnutls_pk.c プロジェクト: uvbs/SupportCenter
static int
_gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
		    int pkey_len)
{
  gcry_sexp_t s_plain, s_data, s_pkey;
  int rc = -1;

  /* make a sexp from pkey */
  switch (algo)
    {
    case GCRY_PK_RSA:
      if (pkey_len >= 6)
	rc = gcry_sexp_build (&s_pkey, NULL,
			      "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
			      pkey[0], pkey[1], pkey[2], pkey[3],
			      pkey[4], pkey[5]);
      break;

    default:
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  if (rc != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* put the data into a simple list */
  if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data))
    {
      gnutls_assert ();
      gcry_sexp_release (s_pkey);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey);
  gcry_sexp_release (s_data);
  gcry_sexp_release (s_pkey);

  if (rc != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_DECRYPTION_FAILED;

    }
  else
    {				/* add better error handling or make gnupg use S-Exp directly */
      resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0);

      if (resarr[0] == NULL)
	{
	  gnutls_assert ();
	  gcry_sexp_release (s_plain);
	  return GNUTLS_E_INTERNAL_ERROR;
	}
    }

  gcry_sexp_release (s_plain);
  return rc;
}
コード例 #6
0
/**
 * ntfs_raw_fek_decrypt -
 *
 * Note: decrypting into the input buffer.
 */
static unsigned ntfs_raw_fek_decrypt(u8 *fek, u32 fek_size,
                                     ntfs_rsa_private_key rsa_key)
{
    gcry_mpi_t fek_mpi;
    gcry_sexp_t fek_sexp, fek_sexp2;
    gcry_error_t err;
    size_t size, padding;

    /* Reverse the raw FEK. */
    ntfs_buffer_reverse(fek, fek_size);
    /* Convert the FEK to internal MPI format. */
    err = gcry_mpi_scan(&fek_mpi, GCRYMPI_FMT_USG, fek, fek_size, NULL);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to convert file encryption key to "
                       "internal MPI format: %s\n",
                       gcry_strerror(err));
        return 0;
    }
    /* Create an internal S-expression from the FEK. */
    err = gcry_sexp_build(&fek_sexp, NULL,
                          "(enc-val (flags) (rsa (a %m)))", fek_mpi);
    gcry_mpi_release(fek_mpi);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to create internal S-expression of "
                       "the file encryption key: %s\n",
                       gcry_strerror(err));
        return 0;
    }
    /* Decrypt the FEK. */
    err = gcry_pk_decrypt(&fek_sexp2, fek_sexp, (gcry_sexp_t)rsa_key);
    gcry_sexp_release(fek_sexp);
    if (err != GPG_ERR_NO_ERROR) {
        ntfs_log_error("Failed to decrypt the file encryption key: "
                       "%s\n", gcry_strerror(err));
        return 0;
    }
    /* Extract the actual FEK from the decrypted raw S-expression. */
    fek_sexp = gcry_sexp_find_token(fek_sexp2, "value", 0);
    gcry_sexp_release(fek_sexp2);
    if (!fek_sexp) {
        ntfs_log_error("Failed to find the decrypted file encryption "
                       "key in the internal S-expression.\n");
        return 0;
    }
    /* Convert the decrypted FEK S-expression into MPI format. */
    fek_mpi = gcry_sexp_nth_mpi(fek_sexp, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(fek_sexp);
    if (!fek_mpi) {
        ntfs_log_error("Failed to convert the decrypted file "
                       "encryption key S-expression to internal MPI "
                       "format.\n");
        return 0;
    }
    /* Convert the decrypted FEK from MPI format to binary data. */
    err = gcry_mpi_print(GCRYMPI_FMT_USG, fek, fek_size, &size, fek_mpi);
    gcry_mpi_release(fek_mpi);
    if (err != GPG_ERR_NO_ERROR || !size) {
        ntfs_log_error("Failed to convert decrypted file encryption "
                       "key from internal MPI format to binary data: "
                       "%s\n", gcry_strerror(err));
        return 0;
    }
    /*
     * Finally, remove the PKCS#1 padding and return the size of the
     * decrypted FEK.
     */
    padding = strnlen((char *)fek, size) + 1;
    if (padding > size) {
        ntfs_log_error("Failed to remove PKCS#1 padding from "
                       "decrypted file encryption key.\n");
        return 0;
    }
    size -= padding;
    memmove(fek, fek + padding, size);
    return size;
}
コード例 #7
0
ファイル: pk.c プロジェクト: dezelin/maily
static int
_wrap_gcry_pk_decrypt (gnutls_pk_algorithm_t algo,
                       gnutls_datum_t * plaintext,
                       const gnutls_datum_t * ciphertext,
                       const gnutls_pk_params_st * pk_params)
{
  gcry_sexp_t s_plain = NULL, s_data = NULL, s_pkey = NULL;
  int rc = -1;
  int ret;
  bigint_t data, res;

  if (_gnutls_mpi_scan_nz (&data, ciphertext->data, ciphertext->size) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  /* make a sexp from pkey */
  switch (algo)
    {
    case GNUTLS_PK_RSA:
      if (pk_params->params_nr >= 6)
        rc = gcry_sexp_build (&s_pkey, NULL,
                              "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
                              pk_params->params[0], pk_params->params[1],
                              pk_params->params[2], pk_params->params[3],
                              pk_params->params[4], pk_params->params[5]);
      break;

    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  if (rc != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  /* put the data into a simple list */
  if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data))
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  /* pass it to libgcrypt */
  rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey);
  if (rc != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_PK_DECRYPTION_FAILED;
      goto cleanup;
    }

  res = gcry_sexp_nth_mpi (s_plain, 0, GCRYMPI_FMT_USG);
  if (res == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto cleanup;
    }

  ret = _gnutls_mpi_dprint_size (res, plaintext, ciphertext->size);
  _gnutls_mpi_release (&res);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = 0;

cleanup:
  _gnutls_mpi_release (&data);
  if (s_plain)
    gcry_sexp_release (s_plain);
  if (s_data)
    gcry_sexp_release (s_data);
  if (s_pkey)
    gcry_sexp_release (s_pkey);

  return ret;

}
コード例 #8
0
ファイル: dcpdecrypt.cpp プロジェクト: Hexkbr/vlc
/* decrypts the RSA encrypted text read from the XML file,
 * and saves the AES key and the other needed info
 * uses libgcrypt for decryption
 */
int AESKey::decryptRSA( string s_cipher_text_b64 )
{
    RSAKey rsa_key( this->p_demux );
    unsigned char *ps_cipher_text = NULL;
    unsigned char *ps_plain_text = NULL;
    gcry_mpi_t cipher_text_mpi = NULL;
    gcry_sexp_t cipher_text_sexp = NULL;
    gcry_sexp_t plain_text_sexp = NULL;
    gcry_mpi_t plain_text_mpi = NULL;
    gcry_sexp_t tmp_sexp = NULL;
    gcry_error_t err;
    size_t length;
    int i_ret = VLC_EGENERIC;

    /* get RSA private key file path */
    if( rsa_key.setPath() )
        goto end;

    /* read private key from file */
    if( rsa_key.readPEM() )
        goto end;

    /* remove spaces and newlines from encoded cipher text
     * (usually added for indentation in XML files)
     * */
    try
    {
        s_cipher_text_b64.erase( remove_if( s_cipher_text_b64.begin(), s_cipher_text_b64.end(), static_cast<int(*)(int)>(isspace) ),
                                 s_cipher_text_b64.end() );
    }
    catch( ... )
    {
        msg_Err( this->p_demux, "error while handling string" );
        goto end;
    }

    /* decode cipher from BASE64 to binary */
    if( ! ( length = vlc_b64_decode_binary( &ps_cipher_text, s_cipher_text_b64.c_str() ) ) )
    {
        msg_Err( this->p_demux, "could not decode cipher from Base64" );
        goto end;
    }

    /* initialize libgcrypt */
    vlc_gcrypt_init ();

    /* create S-expression for ciphertext */
    if( ( err = gcry_mpi_scan( &cipher_text_mpi, GCRYMPI_FMT_USG, ps_cipher_text, 256, NULL ) ) )
    {
        msg_Err( this->p_demux, "could not scan MPI from cipher text: %s", gcry_strerror( err ) );
        goto end;
    }
    if( ( err = gcry_sexp_build( &cipher_text_sexp, NULL, "(enc-val(flags oaep)(rsa(a %m)))", cipher_text_mpi ) ) )
    {
        msg_Err( this->p_demux, "could not build S-expression for cipher text: %s", gcry_strerror( err ) );
        goto end;
    }

    /* decrypt */
    if( ( err = gcry_pk_decrypt( &plain_text_sexp, cipher_text_sexp, rsa_key.priv_key ) ) )
    {
        msg_Err( this->p_demux, "error while decrypting RSA encrypted info: %s", gcry_strerror( err ) );
        goto end;
    }

    /* extract plain-text from S-expression */
    if( ! ( tmp_sexp = gcry_sexp_find_token( plain_text_sexp, "value", 0 ) ) )
        /* when using padding flags, the decrypted S-expression is of the form
         * "(value <plaintext>)", where <plaintext> is an MPI */
    {
        msg_Err( this->p_demux, "decrypted text is in an unexpected form; decryption may have failed" );
        goto end;
    }
    /* we could have used the gcry_sexp_nth_data to get the data directly,
     * but as that function is newly introduced (libgcrypt v1.6),
     * we prefer compatibility, even though that means passing the data through an MPI first */
    if( ! ( plain_text_mpi = gcry_sexp_nth_mpi( tmp_sexp, 1, GCRYMPI_FMT_USG ) ) )
    {
        msg_Err( this->p_demux, "could not extract MPI from decrypted S-expression" );
        goto end;
    }

    if( ( err = gcry_mpi_aprint( GCRYMPI_FMT_USG, &ps_plain_text, &length, plain_text_mpi ) ) )
    {
        msg_Err( this->p_demux, "error while extracting plain text from MPI: %s", gcry_strerror( err ) );
        goto end;
    }

    /* interpret the plaintext data */
    switch( length )
    {
        case 138:   /* SMPTE    DCP */
            if( this->extractInfo( ps_plain_text, true ) )
                goto end;
            break;
        case 134:   /* Interop  DCP */
            if( this->extractInfo( ps_plain_text, false ) )
                goto end;
            break;
        case -1:
            msg_Err( this->p_demux, "could not decrypt" );
            goto end;
        default:
            msg_Err( this->p_demux, "CipherValue field length does not match SMPTE nor Interop standards" );
            goto end;
    }

    i_ret = VLC_SUCCESS;

end:
    free( ps_cipher_text );
    gcry_mpi_release( cipher_text_mpi );
    gcry_sexp_release( cipher_text_sexp );
    gcry_sexp_release( plain_text_sexp );
    gcry_mpi_release( plain_text_mpi );
    gcry_sexp_release( tmp_sexp );
    gcry_free( ps_plain_text );
    return i_ret;
}
コード例 #9
0
ファイル: pkcs1v2.c プロジェクト: GostCrypt/libgcrypt
/* Check against PKCS#1 v1.5 encryption test  vectors as found at
   ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt .  */
static void
check_v15crypt (void)
{
#include "pkcs1v2-v15c.h"
  gpg_error_t err;
  int tno, mno;

  for (tno = 0; tno < DIM (tbl); tno++)
    {
      void *rsa_n, *rsa_e, *rsa_d;
      size_t rsa_n_len, rsa_e_len, rsa_d_len;
      gcry_sexp_t sec_key, pub_key;

      if (verbose > 1)
        info ("(%s)\n", tbl[tno].desc);

      rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
      rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
      rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
      err = gcry_sexp_build (&sec_key, NULL,
                             "(private-key (rsa (n %b)(e %b)(d %b)))",
                             (int)rsa_n_len, rsa_n,
                             (int)rsa_e_len, rsa_e,
                             (int)rsa_d_len, rsa_d);
      if (err)
        die ("constructing private key failed: %s\n", gpg_strerror (err));
      err = gcry_sexp_build (&pub_key, NULL,
                             "(public-key (rsa (n %b)(e %b)))",
                             (int)rsa_n_len, rsa_n,
                             (int)rsa_e_len, rsa_e);
      if (err)
        die ("constructing public key failed: %s\n", gpg_strerror (err));
      gcry_free (rsa_n);
      gcry_free (rsa_e);
      gcry_free (rsa_d);

      for (mno = 0; mno < DIM (tbl[0].m); mno++)
        {
          void *mesg, *seed, *encr;
          size_t mesg_len, seed_len, encr_len;
          gcry_sexp_t plain, ciph;

          if (verbose)
            info ("running test: %s\n", tbl[tno].m[mno].desc);

          mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
          seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);

          err = gcry_sexp_build (&plain, NULL,
                                 "(data (flags pkcs1)(hash-algo sha1)"
                                 "(value %b)(random-override %b))",
                                 (int)mesg_len, mesg,
                                 (int)seed_len, seed);
          if (err)
            die ("constructing plain data failed: %s\n", gpg_strerror (err));
          gcry_free (mesg);
          gcry_free (seed);

          err = gcry_pk_encrypt (&ciph, plain, pub_key);
          if (err)
            {
              show_sexp ("plain:\n", ciph);
              fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
            }
          else
            {
              if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
                                    tbl[tno].m[mno].desc))
                {
                  show_sexp ("encrypt result:\n", ciph);
                  fail ("mismatch in gcry_pk_encrypt\n");
                }
              gcry_sexp_release (ciph);
              ciph = NULL;
            }
          gcry_sexp_release (plain);
          plain = NULL;

          /* Now test the decryption.  */
          seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
          encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);

          err = gcry_sexp_build (&ciph, NULL,
                                 "(enc-val (flags pkcs1)(hash-algo sha1)"
                                 "(random-override %b)"
                                 "(rsa (a %b)))",
                                 (int)seed_len, seed,
                                 (int)encr_len, encr);
          if (err)
            die ("constructing cipher data failed: %s\n", gpg_strerror (err));
          gcry_free (encr);
          gcry_free (seed);

          err = gcry_pk_decrypt (&plain, ciph, sec_key);
          if (err)
            {
              show_sexp ("ciph:\n", ciph);
              fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
            }
          else
            {
              if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
                                    tbl[tno].m[mno].desc))
                {
                  show_sexp ("decrypt result:\n", plain);
                  fail ("mismatch in gcry_pk_decrypt\n");
                }
              gcry_sexp_release (plain);
              plain = NULL;
            }
          gcry_sexp_release (ciph);
          ciph = NULL;
        }

      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
}
コード例 #10
0
ファイル: pubkey.c プロジェクト: creationst/Creation2
static void
check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
		  gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
{
  gcry_sexp_t plain1, cipher, l;
  gcry_mpi_t x0, x1;
  int rc;
  int have_flags;

  /* Extract data from plaintext.  */
  l = gcry_sexp_find_token (plain0, "value", 0);
  x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (l);

  /* Encrypt data.  */
  rc = gcry_pk_encrypt (&cipher, plain0, pkey);
  if (rc)
    die ("encryption failed: %s\n", gcry_strerror (rc));

  l = gcry_sexp_find_token (cipher, "flags", 0);
  have_flags = !!l;
  gcry_sexp_release (l);

  /* Decrypt data.  */
  rc = gcry_pk_decrypt (&plain1, cipher, skey);
  gcry_sexp_release (cipher);
  if (rc)
    {
      if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
	{
	  gcry_mpi_release (x0);
	  return; /* This is the expected failure code.  */
	}
      die ("decryption failed: %s\n", gcry_strerror (rc));
    }

  /* Extract decrypted data.  Note that for compatibility reasons, the
     output of gcry_pk_decrypt depends on whether a flags lists (even
     if empty) occurs in its input data.  Because we passed the output
     of encrypt directly to decrypt, such a flag value won't be there
     as of today.  We check it anyway. */
  l = gcry_sexp_find_token (plain1, "value", 0);
  if (l)
    {
      if (!have_flags)
        die ("compatibility mode of pk_decrypt broken\n");
      gcry_sexp_release (plain1);
      x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
      gcry_sexp_release (l);
    }
  else
    {
      if (have_flags)
        die ("compatibility mode of pk_decrypt broken\n");
      x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
      gcry_sexp_release (plain1);
    }

  /* Compare.  */
  if (gcry_mpi_cmp (x0, x1))
    die ("data corrupted\n");
  gcry_mpi_release (x0);
  gcry_mpi_release (x1);
}