Esempio n. 1
0
static void
write_header( cipher_filter_context_t *cfx, IOBUF a )
{
    PACKET pkt;
    PKT_encrypted ed;
    byte temp[18];
    unsigned blocksize;
    unsigned nprefix;

    blocksize = cipher_get_blocksize( cfx->dek->algo );
    if( blocksize < 8 || blocksize > 16 )
        log_fatal("unsupported blocksize %u\n", blocksize );

    memset( &ed, 0, sizeof ed );
    ed.len = cfx->datalen;
    ed.extralen = blocksize+2;
    ed.new_ctb = !ed.len && !RFC1991;
    if( cfx->dek->use_mdc ) {
        ed.mdc_method = DIGEST_ALGO_SHA1;
        cfx->mdc_hash = md_open( DIGEST_ALGO_SHA1, 0 );
        if ( DBG_HASHING )
            md_start_debug( cfx->mdc_hash, "creatmdc" );
    }

    {
        char buf[20];

        sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo);
        write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
    }

    init_packet( &pkt );
    pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
    pkt.pkt.encrypted = &ed;
    if( build_packet( a, &pkt ))
        log_bug("build_packet(ENCR_DATA) failed\n");
    nprefix = blocksize;
    randomize_buffer( temp, nprefix, 1 );
    temp[nprefix] = temp[nprefix-2];
    temp[nprefix+1] = temp[nprefix-1];
    print_cipher_algo_note( cfx->dek->algo );
    cfx->cipher_hd = cipher_open( cfx->dek->algo,
                                  cfx->dek->use_mdc? CIPHER_MODE_CFB
                                  : CIPHER_MODE_AUTO_CFB, 1 );
    /*   log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/
    cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
    cipher_setiv( cfx->cipher_hd, NULL, 0 );
    /*  log_hexdump( "prefix", temp, nprefix+2 ); */
    if( cfx->mdc_hash ) /* hash the "IV" */
        md_write( cfx->mdc_hash, temp, nprefix+2 );
    cipher_encrypt( cfx->cipher_hd, temp, temp, nprefix+2);
    cipher_sync( cfx->cipher_hd );
    iobuf_write(a, temp, nprefix+2);
    cfx->header=1;
}
Esempio n. 2
0
/* Return information about the given cipher algorithm ALGO.

   WHAT select the kind of information returned:

    GCRYCTL_GET_KEYLEN:
  	Return the length of the key.  If the algorithm ALGO
  	supports multiple key lengths, the maximum supported key length
  	is returned.  The key length is returned as number of octets.
  	BUFFER and NBYTES must be zero.

    GCRYCTL_GET_BLKLEN:
  	Return the blocklength of the algorithm ALGO counted in octets.
  	BUFFER and NBYTES must be zero.

    GCRYCTL_TEST_ALGO:
  	Returns 0 if the specified algorithm ALGO is available for use.
  	BUFFER and NBYTES must be zero.

   Note: Because this function is in most cases used to return an
   integer value, we can make it easier for the caller to just look at
   the return value.  The caller will in all cases consult the value
   and thereby detecting whether a error occurred or not (i.e. while
   checking the block size)
 */
gcry_err_code_t
_gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
{
  gcry_err_code_t rc = 0;
  unsigned int ui;

  switch (what)
    {
    case GCRYCTL_GET_KEYLEN:
      if (buffer || (! nbytes))
	rc = GPG_ERR_CIPHER_ALGO;
      else
	{
	  ui = cipher_get_keylen (algo);
	  if ((ui > 0) && (ui <= 512))
	    *nbytes = (size_t) ui / 8;
	  else
	    /* The only reason for an error is an invalid algo.  */
	    rc = GPG_ERR_CIPHER_ALGO;
	}
      break;

    case GCRYCTL_GET_BLKLEN:
      if (buffer || (! nbytes))
	rc = GPG_ERR_CIPHER_ALGO;
      else
	{
	  ui = cipher_get_blocksize (algo);
	  if ((ui > 0) && (ui < 10000))
	    *nbytes = ui;
	  else
            {
              /* The only reason is an invalid algo or a strange
                 blocksize.  */
              rc = GPG_ERR_CIPHER_ALGO;
            }
	}
      break;

    case GCRYCTL_TEST_ALGO:
      if (buffer || nbytes)
	rc = GPG_ERR_INV_ARG;
      else
	rc = check_cipher_algo (algo);
      break;

      default:
	rc = GPG_ERR_INV_OP;
    }

  return rc;
}
/* We try very hard to use a MDC */
static int
use_mdc(PK_LIST pk_list,int algo)
{
  /* RFC-1991 and 2440 don't have MDC */
  if(RFC1991 || RFC2440)
    return 0;

  /* --force-mdc overrides --disable-mdc */
  if(opt.force_mdc)
    return 1;

  if(opt.disable_mdc)
    return 0;

  /* Do the keys really support MDC? */

  if(select_mdc_from_pklist(pk_list))
    return 1;
  
  /* The keys don't support MDC, so now we do a bit of a hack - if any
     of the AESes or TWOFISH are in the prefs, we assume that the user
     can handle a MDC.  This is valid for PGP 7, which can handle MDCs
     though it will not generate them.  2440bis allows this, by the
     way. */

  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
			    CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
    return 1;

  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
			    CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
    return 1;

  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
			    CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
    return 1;

  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
			    CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
    return 1;

  /* Last try.  Use MDC for the modern ciphers. */

  if(cipher_get_blocksize(algo)!=8)
    return 1;

  return 0; /* No MDC */
}