Exemple #1
0
gcry_err_code_t
_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
{
  gcry_err_code_t rc = 0;

  switch (hd->mode)
    {
      case GCRY_CIPHER_MODE_CCM:
        rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen);
        break;

      case GCRY_CIPHER_MODE_GCM:
        rc =  _gcry_cipher_gcm_setiv (hd, iv, ivlen);
        break;

      case GCRY_CIPHER_MODE_POLY1305:
        rc =  _gcry_cipher_poly1305_setiv (hd, iv, ivlen);
        break;

      case GCRY_CIPHER_MODE_OCB:
        rc = _gcry_cipher_ocb_set_nonce (hd, iv, ivlen);
        break;

      default:
        rc = cipher_setiv (hd, iv, ivlen);
        break;
    }
  return rc;
}
static void
encode_seskey( DEK *dek, DEK **seskey, byte *enckey )
{
    CIPHER_HANDLE hd;
    byte buf[33];

    assert ( dek->keylen <= 32 );
    if(!*seskey)
      {
	*seskey=xmalloc_clear(sizeof(DEK));
	(*seskey)->keylen=dek->keylen;
	(*seskey)->algo=dek->algo;
	make_session_key(*seskey);
	/*log_hexdump( "thekey", c->key, c->keylen );*/
      }

    buf[0] = (*seskey)->algo;
    memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
    
    hd = cipher_open( dek->algo, CIPHER_MODE_CFB, 1 );
    cipher_setkey( hd, dek->key, dek->keylen );
    cipher_setiv( hd, NULL, 0 );
    cipher_encrypt( hd, buf, buf, (*seskey)->keylen + 1 );
    cipher_close( hd );

    memcpy( enckey, buf, (*seskey)->keylen + 1 );
    wipememory( buf, sizeof buf ); /* burn key */
}
Exemple #3
0
gcry_error_t
gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
{
  gcry_err_code_t rc = GPG_ERR_NO_ERROR;

  switch (cmd)
    {
    case GCRYCTL_SET_KEY:
      rc = cipher_setkey( h, buffer, buflen );
      break;
    case GCRYCTL_SET_IV:
      cipher_setiv( h, buffer, buflen );
      break;
    case GCRYCTL_RESET:
      cipher_reset (h);
      break;
    case GCRYCTL_CFB_SYNC:
      cipher_sync( h );
      break;
    case GCRYCTL_SET_CBC_CTS:
      if (buflen)
	if (h->flags & GCRY_CIPHER_CBC_MAC)
	  rc = GPG_ERR_INV_FLAG;
	else
	  h->flags |= GCRY_CIPHER_CBC_CTS;
      else
	h->flags &= ~GCRY_CIPHER_CBC_CTS;
      break;
    case GCRYCTL_SET_CBC_MAC:
      if (buflen)
	if (h->flags & GCRY_CIPHER_CBC_CTS)
	  rc = GPG_ERR_INV_FLAG;
	else
	  h->flags |= GCRY_CIPHER_CBC_MAC;
      else
	h->flags &= ~GCRY_CIPHER_CBC_MAC;
      break;
    case GCRYCTL_DISABLE_ALGO:
      /* this one expects a NULL handle and buffer pointing to an
       * integer with the algo number.
       */
      if( h || !buffer || buflen != sizeof(int) )
	return gcry_error (GPG_ERR_CIPHER_ALGO);
      disable_cipher_algo( *(int*)buffer );
      break;
    case GCRYCTL_SET_CTR:
      if (buffer && buflen == h->cipher->blocksize)
	memcpy (h->ctr, buffer, h->cipher->blocksize);
      else if (buffer == NULL || buflen == 0)
	memset (h->ctr, 0, h->cipher->blocksize);
      else
	rc = GPG_ERR_INV_ARG;
      break;

    default:
      rc = GPG_ERR_INV_OP;
    }

  return gcry_error (rc);
}
Exemple #4
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;
}
Exemple #5
0
int
main(int argc, char **argv)
{
    int encode=0;
    CIPHER_HANDLE hd;
    char buf[4096];
    int n, size=4096;
    int algo;

#ifdef HAVE_DOSISH_SYSTEM
    setmode( fileno(stdin), O_BINARY );
    setmode( fileno(stdout), O_BINARY );
#endif

    i18n_init();
    if( argc > 1 && !strcmp(argv[1], "-e") ) {
	encode++;
	argc--; argv++;
    }
    else if( argc > 1 && !strcmp(argv[1], "-E") ) {
	encode++;
	argc--; argv++;
	size = 10;
    }
    else if( argc > 1 && !strcmp(argv[1], "-d") ) {
	argc--; argv++;
    }
    else if( argc > 1 && !strcmp(argv[1], "-D") ) {
	argc--; argv++;
	size = 10;
    }
    if( argc != 3 )
	my_usage();
    argc--; argv++;
    algo = string_to_cipher_algo( *argv );
    argc--; argv++;

    hd = cipher_open( algo, CIPHER_MODE_CFB, 0 );
    cipher_setkey( hd, *argv, strlen(*argv) );
    cipher_setiv( hd, NULL, 0 );
    while( (n = fread( buf, 1, size, stdin )) > 0 ) {
	if( encode )
	    cipher_encrypt( hd, buf, buf, n );
	else
	    cipher_decrypt( hd, buf, buf, n );
	if( fwrite( buf, 1, n, stdout) != n )
	    log_fatal("write error\n");
    }
    cipher_close(hd);
    return 0;
}
Exemple #6
0
/**
 * Test CBC decryption
 *
 * @v cipher			Cipher algorithm
 * @v key			Key
 * @v key_len			Length of key
 * @v iv			Initialisation vector
 * @v ciphertext		Ciphertext data
 * @v expected_plaintext	Expected plaintext data
 * @v len			Length of data
 * @ret ok			Plaintext is as expected
 */
int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
		       size_t key_len, const void *iv, const void *ciphertext,
		       const void *expected_plaintext, size_t len ) {
	uint8_t ctx[cipher->ctxsize];
	uint8_t plaintext[len];
	int rc;

	/* Initialise cipher */
	rc = cipher_setkey ( cipher, ctx, key, key_len );
	assert ( rc == 0 );
	cipher_setiv ( cipher, ctx, iv );

	/* Perform encryption */
	cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );

	/* Verify result */
	return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
}
Exemple #7
0
/**
 * Calculate CBC encryption or decryption cost
 *
 * @v cipher			Cipher algorithm
 * @v key_len			Length of key
 * @v op			Encryption or decryption operation
 * @ret cost			Cost (in cycles per byte)
 */
static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
				size_t key_len,
				void ( * op ) ( struct cipher_algorithm *cipher,
						void *ctx, const void *src,
						void *dst, size_t len ) ) {
	static uint8_t random[8192]; /* Too large for stack */
	uint8_t key[key_len];
	uint8_t iv[cipher->blocksize];
	uint8_t ctx[cipher->ctxsize];
	union profiler profiler;
	unsigned long long elapsed;
	unsigned long cost;
	unsigned int i;
	int rc;

	/* Fill buffer with pseudo-random data */
	srand ( 0x1234568 );
	for ( i = 0 ; i < sizeof ( random ) ; i++ )
		random[i] = rand();
	for ( i = 0 ; i < sizeof ( key ) ; i++ )
		key[i] = rand();
	for ( i = 0 ; i < sizeof ( iv ) ; i++ )
		iv[i] = rand();

	/* Initialise cipher */
	rc = cipher_setkey ( cipher, ctx, key, key_len );
	assert ( rc == 0 );
	cipher_setiv ( cipher, ctx, iv );

	/* Time operation */
	profile ( &profiler );
	op ( cipher, ctx, random, random, sizeof ( random ) );
	elapsed = profile ( &profiler );

	/* Round to nearest whole number of cycles per byte */
	cost = ( ( elapsed + ( sizeof ( random ) / 2 ) ) / sizeof ( random ) );

	return cost;
}
Exemple #8
0
/**
 * Generate key material
 *
 * @v tls		TLS session
 *
 * The master secret must already be known.
 */
static int tls_generate_keys ( struct tls_session *tls ) {
	struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
	struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
	size_t hash_size = tx_cipherspec->digest->digestsize;
	size_t key_size = tx_cipherspec->key_len;
	size_t iv_size = tx_cipherspec->cipher->blocksize;
	size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
	uint8_t key_block[total];
	uint8_t *key;
	int rc;

	/* Generate key block */
	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
			key_block, sizeof ( key_block ), "key expansion",
			&tls->server_random, sizeof ( tls->server_random ),
			&tls->client_random, sizeof ( tls->client_random ) );

	/* Split key block into portions */
	key = key_block;

	/* TX MAC secret */
	memcpy ( tx_cipherspec->mac_secret, key, hash_size );
	DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
	DBGC_HD ( tls, key, hash_size );
	key += hash_size;

	/* RX MAC secret */
	memcpy ( rx_cipherspec->mac_secret, key, hash_size );
	DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
	DBGC_HD ( tls, key, hash_size );
	key += hash_size;

	/* TX key */
	if ( ( rc = cipher_setkey ( tx_cipherspec->cipher,
				    tx_cipherspec->cipher_ctx,
				    key, key_size ) ) != 0 ) {
		DBGC ( tls, "TLS %p could not set TX key: %s\n",
		       tls, strerror ( rc ) );
		return rc;
	}
	DBGC ( tls, "TLS %p TX key:\n", tls );
	DBGC_HD ( tls, key, key_size );
	key += key_size;

	/* RX key */
	if ( ( rc = cipher_setkey ( rx_cipherspec->cipher,
				    rx_cipherspec->cipher_ctx,
				    key, key_size ) ) != 0 ) {
		DBGC ( tls, "TLS %p could not set TX key: %s\n",
		       tls, strerror ( rc ) );
		return rc;
	}
	DBGC ( tls, "TLS %p RX key:\n", tls );
	DBGC_HD ( tls, key, key_size );
	key += key_size;

	/* TX initialisation vector */
	cipher_setiv ( tx_cipherspec->cipher, tx_cipherspec->cipher_ctx, key );
	DBGC ( tls, "TLS %p TX IV:\n", tls );
	DBGC_HD ( tls, key, iv_size );
	key += iv_size;

	/* RX initialisation vector */
	cipher_setiv ( rx_cipherspec->cipher, rx_cipherspec->cipher_ctx, key );
	DBGC ( tls, "TLS %p RX IV:\n", tls );
	DBGC_HD ( tls, key, iv_size );
	key += iv_size;

	assert ( ( key_block + total ) == key );

	return 0;
}
Exemple #9
0
struct ibuf *
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
    struct ibuf *msg, struct ibuf *src)
{
	ssize_t			 ivlen, encrlen, integrlen, blocklen,
				    outlen, tmplen;
	uint8_t			 pad = 0, *ptr;
	struct ibuf		*integr, *encr, *tmp = NULL, *out = NULL;
	off_t			 ivoff, encroff, integroff;

	if (sa == NULL ||
	    sa->sa_encr == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		print_hex(ibuf_data(src), 0, ibuf_size(src));
		goto done;
	}

	if (!sa->sa_hdr.sh_initiator) {
		encr = sa->sa_key_iencr;
		integr = sa->sa_key_iauth;
	} else {
		encr = sa->sa_key_rencr;
		integr = sa->sa_key_rauth;
	}

	blocklen = cipher_length(sa->sa_encr);
	ivlen = cipher_ivlength(sa->sa_encr);
	ivoff = 0;
	integrlen = hash_length(sa->sa_integr);
	integroff = ibuf_size(src) - integrlen;
	encroff = ivlen;
	encrlen = ibuf_size(src) - integrlen - ivlen;

	if (encrlen < 0 || integroff < 0) {
		log_debug("%s: invalid integrity value", __func__);
		goto done;
	}

	log_debug("%s: IV length %zd", __func__, ivlen);
	print_hex(ibuf_data(src), 0, ivlen);
	log_debug("%s: encrypted payload length %zd", __func__, encrlen);
	print_hex(ibuf_data(src), encroff, encrlen);
	log_debug("%s: integrity checksum length %zd", __func__, integrlen);
	print_hex(ibuf_data(src), integroff, integrlen);

	/*
	 * Validate packet checksum
	 */
	if ((tmp = ibuf_new(NULL, ibuf_length(integr))) == NULL)
		goto done;

	hash_setkey(sa->sa_integr, integr->buf, ibuf_length(integr));
	hash_init(sa->sa_integr);
	hash_update(sa->sa_integr, ibuf_data(msg),
	    ibuf_size(msg) - integrlen);
	hash_final(sa->sa_integr, tmp->buf, &tmplen);

	if (memcmp(tmp->buf, ibuf_data(src) + integroff, integrlen) != 0) {
		log_debug("%s: integrity check failed", __func__);
		goto done;
	}

	log_debug("%s: integrity check succeeded", __func__);
	print_hex(tmp->buf, 0, tmplen);

	ibuf_release(tmp);
	tmp = NULL;

	/*
	 * Decrypt the payload and strip any padding
	 */
	if ((encrlen % blocklen) != 0) {
		log_debug("%s: unaligned encrypted payload", __func__);
		goto done;
	}

	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
	cipher_setiv(sa->sa_encr, ibuf_data(src) + ivoff, ivlen);
	cipher_init_decrypt(sa->sa_encr);

	if ((out = ibuf_new(NULL, cipher_outlength(sa->sa_encr,
	    encrlen))) == NULL)
		goto done;

	if ((outlen = ibuf_length(out)) != 0) {
		cipher_update(sa->sa_encr, ibuf_data(src) + encroff, encrlen,
		    ibuf_data(out), &outlen);

		ptr = ibuf_seek(out, outlen - 1, 1);
		pad = *ptr;
	}

	log_debug("%s: decrypted payload length %zd/%zd padding %d",
	    __func__, outlen, encrlen, pad);
	print_hex(ibuf_data(out), 0, ibuf_size(out));

	if (ibuf_setsize(out, outlen) != 0)
		goto done;

	ibuf_release(src);
	return (out);
 done:
	ibuf_release(tmp);
	ibuf_release(out);
	ibuf_release(src);
	return (NULL);
}
Exemple #10
0
struct ibuf *
ikev2_msg_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf *src)
{
	size_t			 len, encrlen, integrlen, blocklen, outlen;
	uint8_t			*buf, pad = 0, *ptr;
	struct ibuf		*encr, *dst = NULL, *out = NULL;

	buf = ibuf_data(src);
	len = ibuf_size(src);

	log_debug("%s: decrypted length %zu", __func__, len);
	print_hex(buf, 0, len);

	if (sa == NULL ||
	    sa->sa_encr == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		goto done;
	}

	if (sa->sa_hdr.sh_initiator)
		encr = sa->sa_key_iencr;
	else
		encr = sa->sa_key_rencr;

	blocklen = cipher_length(sa->sa_encr);
	integrlen = hash_length(sa->sa_integr);
	encrlen = roundup(len + sizeof(pad), blocklen);
	pad = encrlen - (len + sizeof(pad));

	/*
	 * Pad the payload and encrypt it
	 */
	if (pad) {
		if ((ptr = ibuf_advance(src, pad)) == NULL)
			goto done;
		arc4random_buf(ptr, pad);
	}
	if (ibuf_add(src, &pad, sizeof(pad)) != 0)
		goto done;

	log_debug("%s: padded length %zu", __func__, ibuf_size(src));
	print_hex(ibuf_data(src), 0, ibuf_size(src));

	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
	cipher_setiv(sa->sa_encr, NULL, 0);
	cipher_init_encrypt(sa->sa_encr);

	if ((dst = ibuf_dup(sa->sa_encr->encr_iv)) == NULL)
		goto done;

	if ((out = ibuf_new(NULL,
	    cipher_outlength(sa->sa_encr, encrlen))) == NULL)
		goto done;

	outlen = ibuf_size(out);
	cipher_update(sa->sa_encr,
	    ibuf_data(src), encrlen, ibuf_data(out), &outlen);

	if (outlen && ibuf_add(dst, ibuf_data(out), outlen) != 0)
		goto done;

	if ((ptr = ibuf_advance(dst, integrlen)) == NULL)
		goto done;
	explicit_bzero(ptr, integrlen);

	log_debug("%s: length %zu, padding %d, output length %zu",
	    __func__, len + sizeof(pad), pad, ibuf_size(dst));
	print_hex(ibuf_data(dst), 0, ibuf_size(dst));

	ibuf_release(src);
	ibuf_release(out);
	return (dst);
 done:
	ibuf_release(src);
	ibuf_release(out);
	ibuf_release(dst);
	return (NULL);
}
Exemple #11
0
gcry_error_t
gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
{
  gcry_err_code_t rc = GPG_ERR_NO_ERROR;

  switch (cmd)
    {
    case GCRYCTL_SET_KEY:  /* Deprecated; use gcry_cipher_setkey.  */
      rc = cipher_setkey( h, buffer, buflen );
      break;

    case GCRYCTL_SET_IV:   /* Deprecated; use gcry_cipher_setiv.  */
      cipher_setiv( h, buffer, buflen );
      break;

    case GCRYCTL_RESET:
      cipher_reset (h);
      break;

    case GCRYCTL_CFB_SYNC:
      cipher_sync( h );
      break;

    case GCRYCTL_SET_CBC_CTS:
      if (buflen)
	if (h->flags & GCRY_CIPHER_CBC_MAC)
	  rc = GPG_ERR_INV_FLAG;
	else
	  h->flags |= GCRY_CIPHER_CBC_CTS;
      else
	h->flags &= ~GCRY_CIPHER_CBC_CTS;
      break;

    case GCRYCTL_SET_CBC_MAC:
      if (buflen)
	if (h->flags & GCRY_CIPHER_CBC_CTS)
	  rc = GPG_ERR_INV_FLAG;
	else
	  h->flags |= GCRY_CIPHER_CBC_MAC;
      else
	h->flags &= ~GCRY_CIPHER_CBC_MAC;
      break;

    case GCRYCTL_DISABLE_ALGO:
      /* This command expects NULL for H and BUFFER to point to an
         integer with the algo number.  */
      if( h || !buffer || buflen != sizeof(int) )
	return gcry_error (GPG_ERR_CIPHER_ALGO);
      disable_cipher_algo( *(int*)buffer );
      break;

    case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr.  */
      rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen));
      break;

    case 61:  /* Disable weak key detection (private).  */
      if (h->extraspec->set_extra_info)
        rc = h->extraspec->set_extra_info
          (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
      else
        rc = GPG_ERR_NOT_SUPPORTED;
      break;

    case 62: /* Return current input vector (private).  */
      /* This is the input block as used in CFB and OFB mode which has
         initially been set as IV.  The returned format is:
           1 byte  Actual length of the block in bytes.
           n byte  The block.
         If the provided buffer is too short, an error is returned. */
      if (buflen < (1 + h->cipher->blocksize))
        rc = GPG_ERR_TOO_SHORT;
      else
        {
          unsigned char *ivp;
          unsigned char *dst = buffer;
          int n = h->unused;

          if (!n)
            n = h->cipher->blocksize;
          gcry_assert (n <= h->cipher->blocksize);
          *dst++ = n;
          ivp = h->u_iv.iv + h->cipher->blocksize - n;
          while (n--)
            *dst++ = *ivp++;
        }
      break;

    default:
      rc = GPG_ERR_INV_OP;
    }

  return gcry_error (rc);
}
Exemple #12
0
gcry_error_t
_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
{
  cipher_setiv (hd, iv, ivlen);
  return 0;
}