Beispiel #1
0
/**
 * @brief Decipher a buffer using AES-128 with CBC.
 */
int crypt_aes_dec(crypt_context_t *context, char *encBuffer, char *outBuffer, unsigned int buffLen, char *iniVector) {
    int rv;

    ASSERT(context, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n");
    ASSERT(encBuffer, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n");
    ASSERT(outBuffer, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n");
    ASSERT(iniVector, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n");
    ASSERT(context->initialised, rv, CRYPT_FAILED, "crypt_aes_dec: Context is not initialised.\n");

    gcry_error_t gcryError;
    gcry_cipher_hd_t gcryCipherHd = NULL;
    size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES128);
    size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES128);

    gcryError = gcry_cipher_open(&gcryCipherHd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
    ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));

    gcryError = gcry_cipher_setkey(gcryCipherHd, context->secretKey, keyLength);
    ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));

    gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
    ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));

    gcryError = gcry_cipher_decrypt(gcryCipherHd, outBuffer, buffLen, encBuffer, buffLen);
    ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError));

_err:
    if(gcryCipherHd)
        gcry_cipher_close(gcryCipherHd);

    return rv;
}
Beispiel #2
0
static void
test_generate_key_pbe (void)
{
	int i;
	gboolean ret;
	guchar *key;

	for (i = 0; i < N_GENERATION_TESTS; ++i) {

		if (!all_generation_tests[i].result_pbe)
			continue;

		ret = egg_symkey_generate_pbe (all_generation_tests[i].cipher_algo,
		                               all_generation_tests[i].hash_algo,
		                               all_generation_tests[i].password, -1,
		                               (guchar*)all_generation_tests[i].salt, 8,
		                               all_generation_tests[i].iterations,
		                               &key, NULL);
		g_assert ("failed to generate pbe key" && ret);

		ret = (memcmp (key, all_generation_tests[i].result_pbe,
			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);

		g_assert ("invalid pbe key generated" && ret);

	}
}
Beispiel #3
0
guchar *
egg_openssl_decrypt_block (const gchar *dekinfo,
                           const gchar *password,
                           gssize n_password,
                           GBytes *data,
                           gsize *n_decrypted)
{
	gcry_cipher_hd_t ch;
	guchar *key = NULL;
	guchar *iv = NULL;
	int gcry, ivlen;
	int algo = 0;
	int mode = 0;
	guchar *decrypted;

	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
		return FALSE;

	ivlen = gcry_cipher_get_algo_blklen (algo);

	/* We assume the iv is at least as long as at 8 byte salt */
	g_return_val_if_fail (ivlen >= 8, FALSE);

	/* IV is already set from the DEK info */
	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
	                                 n_password, iv, 8, 1, &key, NULL)) {
		g_free (iv);
		return NULL;
	}

	gcry = gcry_cipher_open (&ch, algo, mode, 0);
	g_return_val_if_fail (!gcry, NULL);

	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
	g_return_val_if_fail (!gcry, NULL);
	egg_secure_free (key);

	/* 16 = 128 bits */
	gcry = gcry_cipher_setiv (ch, iv, ivlen);
	g_return_val_if_fail (!gcry, NULL);
	g_free (iv);

	/* Allocate output area */
	*n_decrypted = g_bytes_get_size (data);
	decrypted = egg_secure_alloc (*n_decrypted);

	gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted,
	                            g_bytes_get_data (data, NULL),
	                            g_bytes_get_size (data));
	if (gcry) {
		egg_secure_free (decrypted);
		g_return_val_if_reached (NULL);
	}

	gcry_cipher_close (ch);

	return decrypted;
}
static gboolean
decrypt_buffer (EggBuffer *buffer, GkmSecret *master,
		guchar salt[8], int iterations)
{
	const gchar *password = NULL;
	gcry_cipher_hd_t cih;
	gcry_error_t gerr;
        guchar *key, *iv;
        gsize n_password = 0;
	size_t pos;

	g_assert (buffer->len % 16 == 0);
	g_assert (16 == gcry_cipher_get_algo_blklen (GCRY_CIPHER_AES128));
	g_assert (16 == gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES128));

	/* No password is set, try an null password */
	if (master == NULL) {
		password = NULL;
		n_password = 0;
	} else {
		password = gkm_secret_get_password (master, &n_password);
	}

	if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256,
	                                 password, n_password, salt, 8, iterations, &key, &iv))
		return FALSE;

	gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
	if (gerr) {
		g_warning ("couldn't create aes cipher context: %s",
			   gcry_strerror (gerr));
		egg_secure_free (key);
		g_free (iv);
		return FALSE;
	}

	/* 16 = 128 bits */
	gerr = gcry_cipher_setkey (cih, key, 16);
	g_return_val_if_fail (!gerr, FALSE);
	egg_secure_free (key);

	/* 16 = 128 bits */
	gerr = gcry_cipher_setiv (cih, iv, 16);
	g_return_val_if_fail (!gerr, FALSE);
	g_free (iv);

	for (pos = 0; pos < buffer->len; pos += 16) {
		/* In place encryption */
		gerr = gcry_cipher_decrypt (cih, buffer->buf + pos, 16, NULL, 0);
		g_return_val_if_fail (!gerr, FALSE);
	}

	gcry_cipher_close (cih);

	return TRUE;
}
Beispiel #5
0
int main(int argc, const char *argv[])
{
    const char *libgcrypt_version = gcry_check_version(GCRYPT_VERSION);
    gcry_error_t err = 0;
    //char key[32];
    const char *key;
    int keylen;
    int algo = GCRY_CIPHER_SERPENT128;
    const char *filename;
    const char *filename2;

    if (argc != 4) {
        printf("Wrong parameter quantity\n");
        exit(1);
    }

    filename = argv[1];
    filename2 = argv[2];
    key = argv[3];
    //filename3 = argv[3];

    // cipher initialization
    if (!libgcrypt_version) {
        fputs ("libgcrypt version mismatch or not installed\n", stderr);
        exit (2);
    } else {
        printf("Using libgcrypt version: %s\n", libgcrypt_version);
    }

    // cipher settings
    gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
    keylen = gcry_cipher_get_algo_keylen(algo);
    
    // Open cipher handler
    gcry_cipher_hd_t hd;
    gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_OFB, 0);
    err = gcry_cipher_setkey(hd, key, keylen);
    if (err) {
        printf("grcy_cipher_setkey failed: %s\n", gpg_strerror(err));
        exit(2);
    }
    //gcry_cipher_setiv

    //decryptFile(hd, filename);
    //encryptDecryptTest(hd, filename);
    //encryptFileToFile(hd, filename, filename2);
    decryptFileToFile(hd, filename, filename2);

    // Release handler
    gcry_cipher_close(hd);

    return 0;
}
/* Function to decrypt the ciphertext passed to it, it also takes the lenght of the file as input. function returns palintext*/
char * decryptfunction(char *textbuffer, char * aeskey, size_t textlen, char *iv)
{

	gcry_error_t err;
	gcry_cipher_hd_t handle;
	size_t keylength = gcry_cipher_get_algo_keylen(CIPHER); /* For aes256 keylength is 32 */
	size_t blklength = gcry_cipher_get_algo_blklen(CIPHER); /*For aes256 blklength is 16 */
	size_t i,result;	

	char *decbuffer = malloc(textlen); /*buffer to hold decrypted data */

	printf("Starting Decryption Process\n");
	err = gcry_cipher_open( &handle, CIPHER, MODE, GCRY_CIPHER_CBC_CTS);

	if(err)
	{
		printf("Error creating cipher handle\n");
		exit(0);
	}
	printf("Cipher handle created successfully\n");

	err= gcry_cipher_setkey(handle, aeskey, keylength);

	if(err)
	{
		printf("Error setting cipher key\n");
	}

	printf("Cipher key created successfully\n");

	err = gcry_cipher_setiv(handle, iv , blklength);

	if(err)
	{
		printf("Error setting initialization vector\n");
	}	

	printf("Initialization vector set successfully\n");

	err = gcry_cipher_decrypt( handle, decbuffer, textlen, textbuffer, textlen);

	if(err)
	{
		printf("Error while decrypting\n");
	}

	printf("Text successfully decrypted\n");

	gcry_cipher_close(handle);
	printf("Cipher handle closed successfully\n");			
	
	return decbuffer;
}
Beispiel #7
0
Datei: kex.c Projekt: gpg/gsti
static gsti_error_t
construct_keys (gsti_ctx_t ctx)
{
  gsti_error_t err;
  gcry_md_hd_t md;
  int algo = GCRY_MD_SHA1;
  int keylen, blksize, maclen;

  if (ctx->kex.iv_a)
    return 0;			/* already constructed */

  err = gcry_md_open (&md, algo, 0);
  if (err)
    return err;

  hash_mpi (md, ctx->kex.k);
  gcry_md_write (md, gsti_bstr_data (ctx->kex.h),
		 gsti_bstr_length (ctx->kex.h));

  blksize = ctx->ciph_blksize;
  maclen = ctx->mac_len;
  keylen = gcry_cipher_get_algo_keylen (ctx->ciph_algo);

  ctx->kex.iv_a = construct_one_key (ctx, md, algo,
                                     (const unsigned char*)"\x41", blksize);
  ctx->kex.iv_b = construct_one_key (ctx, md, algo,
                                     (const unsigned char*)"\x42", blksize);
  ctx->kex.key_c = construct_one_key (ctx, md, algo,
                                      (const unsigned char*)"\x43", keylen);
  ctx->kex.key_d = construct_one_key (ctx, md, algo,
                                      (const unsigned char*)"\x44", keylen);
  ctx->kex.mac_e = construct_one_key (ctx, md, algo,
                                      (const unsigned char*)"\x45", maclen);
  ctx->kex.mac_f = construct_one_key (ctx, md, algo,
                                      (const unsigned char*)"\x46", maclen);
  gcry_md_close (md);

  _gsti_dump_hexbuf (ctx, "key A=", gsti_bstr_data (ctx->kex.iv_a),
		     gsti_bstr_length (ctx->kex.iv_a));
  _gsti_dump_hexbuf (ctx, "key B=", gsti_bstr_data (ctx->kex.iv_b),
		     gsti_bstr_length (ctx->kex.iv_b));
  _gsti_dump_hexbuf (ctx, "key C=", gsti_bstr_data (ctx->kex.key_c),
		     gsti_bstr_length (ctx->kex.key_c));
  _gsti_dump_hexbuf (ctx, "key D=", gsti_bstr_data (ctx->kex.key_d),
		     gsti_bstr_length (ctx->kex.key_d));
  _gsti_dump_hexbuf (ctx, "key E=", gsti_bstr_data (ctx->kex.mac_e),
		     gsti_bstr_length (ctx->kex.mac_e));
  _gsti_dump_hexbuf (ctx, "key F=", gsti_bstr_data (ctx->kex.mac_f),
		     gsti_bstr_length (ctx->kex.mac_f));

  return 0;
}
Beispiel #8
0
static int
bench_encrypt_init (struct bench_obj *obj)
{
  struct bench_cipher_mode *mode = obj->priv;
  gcry_cipher_hd_t hd;
  int err, keylen;

  obj->min_bufsize = BUF_START_SIZE;
  obj->max_bufsize = BUF_END_SIZE;
  obj->step_size = BUF_STEP_SIZE;
  obj->num_measure_repetitions = num_measurement_repetitions;

  err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0);
  if (err)
    {
      fprintf (stderr, PGM ": error opening cipher `%s'\n",
	       gcry_cipher_algo_name (mode->algo));
      exit (1);
    }

  keylen = gcry_cipher_get_algo_keylen (mode->algo);
  if (keylen)
    {
      char key[keylen];
      int i;

      for (i = 0; i < keylen; i++)
	key[i] = 0x33 ^ (11 - i);

      err = gcry_cipher_setkey (hd, key, keylen);
      if (err)
	{
	  fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n",
		   gpg_strerror (err));
	  gcry_cipher_close (hd);
	  exit (1);
	}
    }
  else
    {
      fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
	       gcry_cipher_algo_name (mode->algo));
      gcry_cipher_close (hd);
      exit (1);
    }

  obj->priv = hd;

  return 0;
}
Beispiel #9
0
static int
initCrypt(FILE *eifp)
{
 	int r = 0;
	gcry_error_t gcryError;
	char iv[4096];

	blkLength = gcry_cipher_get_algo_blklen(cry_algo);
	if(blkLength > sizeof(iv)) {
		fprintf(stderr, "internal error[%s:%d]: block length %d too large for "
			"iv buffer\n", __FILE__, __LINE__, blkLength);
		r = 1; goto done;
	}
	if((r = eiGetIV(eifp, iv, blkLength)) != 0) goto done;

	size_t keyLength = gcry_cipher_get_algo_keylen(cry_algo);
	if(strlen(cry_key) != keyLength) {
		fprintf(stderr, "invalid key length; key is %u characters, but "
			"exactly %u characters are required\n", cry_keylen,
			keyLength);
		r = 1; goto done;
	}

	gcryError = gcry_cipher_open(&gcry_chd, cry_algo, cry_mode, 0);
	if (gcryError) {
		printf("gcry_cipher_open failed:  %s/%s\n",
			gcry_strsource(gcryError),
			gcry_strerror(gcryError));
		r = 1; goto done;
	}

	gcryError = gcry_cipher_setkey(gcry_chd, cry_key, keyLength);
	if (gcryError) {
		printf("gcry_cipher_setkey failed:  %s/%s\n",
			gcry_strsource(gcryError),
			gcry_strerror(gcryError));
		r = 1; goto done;
	}

	gcryError = gcry_cipher_setiv(gcry_chd, iv, blkLength);
	if (gcryError) {
		printf("gcry_cipher_setiv failed:  %s/%s\n",
			gcry_strsource(gcryError),
			gcry_strerror(gcryError));
		r = 1; goto done;
	}
done: return r;
}
Beispiel #10
0
/* returns 0 on succes, positive if key length does not match and key
 * of return value size is required.
 */
int
rsgcrySetKey(gcryctx ctx, unsigned char *key, uint16_t keyLen)
{
	uint16_t reqKeyLen;
	int r;

	reqKeyLen = gcry_cipher_get_algo_keylen(ctx->algo);
	if(keyLen != reqKeyLen) {
		r = reqKeyLen;
		goto done;
	}
	ctx->keyLen = keyLen;
	ctx->key = malloc(keyLen);
	memcpy(ctx->key, key, keyLen);
	r = 0;
done:	return r;
}
Beispiel #11
0
static crypto_t _setkey(crypto_t c, gchar *key)
{
  gcry_error_t e;
  gsize keylen;
#ifdef _1
  g_message("[%s] key=%s", __func__, key);
#endif
  c->cipher.key = (gchar*) crypto_hex2bytes(key, &keylen);
  if (c->cipher.key == NULL || keylen ==0)
    {
      return (_fail(c,
                    g_strdup("crypto_hex2bytes failed: invalid "
                             "hexadecimal string length")));
    }
#ifdef _1
  crypto_dump("c->cipher.key", (guchar*) c->cipher.key, keylen);
#endif
  c->cipher.keylen = gcry_cipher_get_algo_keylen(c->algo);
  if (c->cipher.keylen ==0)
    {
      return (_fail(c, g_strdup_printf("gcry_cipher_get_algo_keylen failed "
                                       "c->cipher.keylen=%" G_GSIZE_FORMAT", "
                                       "keylen=%" G_GSIZE_FORMAT,
                                       c->cipher.keylen, keylen)));
    }

#ifdef _1
  if (keylen > c->cipher.keylen)
    {
      g_warning("key length exceeds %lu, ignoring the exceeding bytes",keylen);
      keylen = c->cipher.keylen;
    }
#endif

  e = gcry_cipher_setkey(c->cipher.h, c->cipher.key, keylen);
  if (e != 0)
    {
      return (_fail(c,
                    g_strdup_printf("gcry_cipher_setkey failed: %s",
                                    gpg_strerror(e))));
    }
  c->rc = EXIT_SUCCESS;
  return (c);
}
Beispiel #12
0
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
                     _libssh2_cipher_type(algo),
                     unsigned char *iv, unsigned char *secret, int encrypt)
{
    int ret;
    int cipher = _libssh2_gcry_cipher(algo);
    int mode = _libssh2_gcry_mode(algo);
    int keylen = gcry_cipher_get_algo_keylen(cipher);

    (void) encrypt;

    ret = gcry_cipher_open(h, cipher, mode, 0);
    if(ret) {
        return -1;
    }

    ret = gcry_cipher_setkey(*h, secret, keylen);
    if(ret) {
        gcry_cipher_close(*h);
        return -1;
    }

    if(mode != GCRY_CIPHER_MODE_STREAM) {
        int blklen = gcry_cipher_get_algo_blklen(cipher);
        if(mode == GCRY_CIPHER_MODE_CTR)
            ret = gcry_cipher_setctr(*h, iv, blklen);
        else
            ret = gcry_cipher_setiv(*h, iv, blklen);
        if(ret) {
            gcry_cipher_close(*h);
            return -1;
        }
    }

    return 0;
}
Beispiel #13
0
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
                     _libssh2_cipher_type(algo),
                     unsigned char *iv, unsigned char *secret, int encrypt)
{
    int mode = 0, ret;
    int keylen = gcry_cipher_get_algo_keylen(algo);

    (void) encrypt;

    if (algo != GCRY_CIPHER_ARCFOUR) {
        mode = GCRY_CIPHER_MODE_CBC;
    }

    ret = gcry_cipher_open(h, algo, mode, 0);
    if (ret) {
        return -1;
    }

    ret = gcry_cipher_setkey(*h, secret, keylen);
    if (ret) {
        gcry_cipher_close(*h);
        return -1;
    }

    if (algo != GCRY_CIPHER_ARCFOUR) {
        int blklen = gcry_cipher_get_algo_blklen(algo);
        ret = gcry_cipher_setiv(*h, iv, blklen);
        if (ret) {
            gcry_cipher_close(*h);
            return -1;
        }
    }

    return 0;
}
Beispiel #14
0
static void
decrypt (Metadata *header_metadata, CryptoKeys *dec_keys, GFile *enc_data, goffset enc_data_size, GFileOutputStream *ostream)
{
    gcry_cipher_hd_t hd;
    gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0);
    gcry_cipher_setkey (hd, dec_keys->crypto_key, gcry_cipher_get_algo_keylen (header_metadata->algo));

    if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) {
        gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size);
    }
    else {
        gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size);
    }

    GError *err = NULL;

    GFileInputStream *in_stream = g_file_read (enc_data, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }
    if (!g_seekable_seek (G_SEEKABLE (in_stream), sizeof (Metadata), G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }

    guchar *enc_buf = g_try_malloc0 (FILE_BUFFER);
    guchar *dec_buf = g_try_malloc0 (FILE_BUFFER);

    if (enc_buf == NULL || dec_buf == NULL) {
        g_printerr ("Error during memory allocation\n");
        // TODO
        return;
    }

    goffset done_size = 0;
    gssize read_len;

    while (done_size < enc_data_size) {
        if ((enc_data_size - done_size) <= FILE_BUFFER) {
            read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), enc_buf, enc_data_size - done_size, NULL, &err);
            gcry_cipher_decrypt (hd, dec_buf, read_len, enc_buf, read_len);
            g_output_stream_write (G_OUTPUT_STREAM (ostream), dec_buf, read_len - header_metadata->padding_value, NULL, &err);
        }
        else {
            read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), enc_buf, FILE_BUFFER, NULL, &err);
            gcry_cipher_decrypt (hd, dec_buf, read_len, enc_buf, read_len);
            g_output_stream_write (G_OUTPUT_STREAM (ostream), dec_buf, read_len, NULL, &err);
        }

        memset (dec_buf, 0, FILE_BUFFER);
        memset (enc_buf, 0, FILE_BUFFER);

        done_size += read_len;
    }

    gcry_cipher_close (hd);

    multiple_free (2, (gpointer) &enc_buf, (gpointer) &dec_buf);

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);

    g_object_unref (in_stream);
}
Beispiel #15
0
void
decrypt_file (const gchar *input_file_path, const gchar *pwd)
{
    GError *err = NULL;

    goffset file_size = get_file_size (input_file_path);
    if (file_size == -1) {
        return;
    }
    if (file_size < (goffset) (sizeof (Metadata) + SHA512_DIGEST_SIZE)) {
        g_printerr ("The selected file is not encrypted.\n");
        return;
    }

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    gchar *output_file_path;
    if (!g_str_has_suffix (input_file_path, ".enc")) {
        g_printerr ("The selected file may not be encrypted\n");
        output_file_path = g_strconcat (input_file_path, ".decrypted", NULL);
    }
    else {
        output_file_path = g_strndup (input_file_path, (gsize) g_utf8_strlen (input_file_path, -1) - 4); // remove .enc
    }
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *decryption_keys = g_new0 (CryptoKeys, 1);

    gssize rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), header_metadata, sizeof (Metadata), NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    guchar *original_hmac = g_malloc (SHA512_DIGEST_SIZE);
    if (!g_seekable_seek (G_SEEKABLE (in_stream), file_size - SHA512_DIGEST_SIZE, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), original_hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    if (!g_seekable_seek (G_SEEKABLE (in_stream), 0, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    GFile *file_encrypted_data = get_g_file_with_encrypted_data (in_stream, file_size);
    if (file_encrypted_data == NULL) {
        // TODO
        return;
    }

    if (!setup_keys (pwd, gcry_cipher_get_algo_keylen (header_metadata->algo), header_metadata, decryption_keys)) {
        g_printerr ("Error during key derivation or during memory allocation\n");
        //TODO
        return;
    }

    if (!compare_hmac (decryption_keys->hmac_key, original_hmac, file_encrypted_data)) {
        g_printerr ("HMAC differs from the one stored inside the file.\nEither the password is wrong or the file has been corrupted.\n");
        // TODO
        return;
    }

    decrypt (header_metadata, decryption_keys, file_encrypted_data, file_size - sizeof (Metadata) - SHA512_DIGEST_SIZE, out_stream);

    g_unlink (g_file_get_path (file_encrypted_data));
    // TODO remove encrypted file? Give option to the user

    multiple_unref (5, (gpointer) &file_encrypted_data,
                    (gpointer) &in_stream,
                    (gpointer) &out_stream,
                    (gpointer) &in_file,
                    (gpointer) &out_file);

    multiple_gcry_free (3, (gpointer) &decryption_keys->crypto_key,
                        (gpointer) &decryption_keys->derived_key,
                        (gpointer) &decryption_keys->hmac_key);

    multiple_free (4, (gpointer) &header_metadata,
                   (gpointer) &output_file_path,
                   (gpointer) &original_hmac,
                   (gpointer) &decryption_keys);
}
gboolean
egg_symkey_generate_simple (int cipher_algo, int hash_algo, 
                            const gchar *password, gssize n_password, 
                            const guchar *salt, gsize n_salt, int iterations, 
                            guchar **key, guchar **iv)
{
	gcry_md_hd_t mdh;
	gcry_error_t gcry;
	guchar *digest;
	guchar *digested;
	guint n_digest;
	gint pass, i;
	gint needed_iv, needed_key;
	guchar *at_iv, *at_key;

	g_assert (cipher_algo);
	g_assert (hash_algo);

	g_return_val_if_fail (iterations >= 1, FALSE);
	
	if (!password)
		n_password = 0;
	if (n_password == -1)
		n_password = strlen (password);
	
	/* 
	 * If cipher algo needs more bytes than hash algo has available
	 * then the entire hashing process is done again (with the previous
	 * hash bytes as extra input), and so on until satisfied.
	 */ 
	
	needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
	needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
	
	gcry = gcry_md_open (&mdh, hash_algo, 0);
	if (gcry) {
		g_warning ("couldn't create '%s' hash context: %s", 
			   gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
		return FALSE;
	}

	n_digest = gcry_md_get_algo_dlen (hash_algo);
	g_return_val_if_fail (n_digest > 0, FALSE);
	
	digest = egg_secure_alloc (n_digest);
	g_return_val_if_fail (digest, FALSE);
	if (key) {
		*key = egg_secure_alloc (needed_key);
		g_return_val_if_fail (*key, FALSE);
	}
	if (iv) 
		*iv = g_new0 (guchar, needed_iv);

	at_key = key ? *key : NULL;
	at_iv = iv ? *iv : NULL;

	for (pass = 0; TRUE; ++pass) {
		gcry_md_reset (mdh);
		
		/* Hash in the previous buffer on later passes */
		if (pass > 0)
			gcry_md_write (mdh, digest, n_digest);

		if (password)
			gcry_md_write (mdh, password, n_password);
		if (salt && n_salt)
			gcry_md_write (mdh, salt, n_salt);
		gcry_md_final (mdh);
		digested = gcry_md_read (mdh, 0);
		g_return_val_if_fail (digested, FALSE);
		memcpy (digest, digested, n_digest);
		
		for (i = 1; i < iterations; ++i) {
			gcry_md_reset (mdh);
			gcry_md_write (mdh, digest, n_digest);
			gcry_md_final (mdh);
			digested = gcry_md_read (mdh, 0);
			g_return_val_if_fail (digested, FALSE);
			memcpy (digest, digested, n_digest);
		}
		
		/* Copy as much as possible into the destinations */
		i = 0; 
		while (needed_key && i < n_digest) {
			if (at_key)
				*(at_key++) = digest[i];
			needed_key--;
			i++;
		}
		while (needed_iv && i < n_digest) {
			if (at_iv) 
				*(at_iv++) = digest[i];
			needed_iv--;
			i++;
		}
		
		if (needed_key == 0 && needed_iv == 0)
			break;
	}

	egg_secure_free (digest);
	gcry_md_close (mdh);
	
	return TRUE;
}
gboolean
egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password, 
                         gssize n_password, const guchar *salt, gsize n_salt, int iterations, 
                         guchar **key, guchar **iv)
{
	gcry_md_hd_t mdh;
	gcry_error_t gcry;
	guchar *digest;
	guchar *digested;
	guint i, n_digest;
	gint needed_iv, needed_key;

	g_assert (cipher_algo);
	g_assert (hash_algo);

	g_return_val_if_fail (iterations >= 1, FALSE);
	
	if (!password)
		n_password = 0;
	if (n_password == -1)
		n_password = strlen (password);
	
	/* 
	 * We only do one pass here.
	 * 
	 * The key ends up as the first needed_key bytes of the hash buffer.
	 * The iv ends up as the last needed_iv bytes of the hash buffer. 
	 * 
	 * The IV may overlap the key (which is stupid) if the wrong pair of 
	 * hash/cipher algorithms are chosen.
	 */ 

	n_digest = gcry_md_get_algo_dlen (hash_algo);
	g_return_val_if_fail (n_digest > 0, FALSE);
	
	needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
	needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
	if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) {
		g_warning ("using PBE symkey generation with %s using an algorithm that needs " 
		           "too many bytes of key and/or IV: %s",
		           gcry_cipher_algo_name (hash_algo), 
		           gcry_cipher_algo_name (cipher_algo));
		return FALSE;
	}
	
	gcry = gcry_md_open (&mdh, hash_algo, 0);
	if (gcry) {
		g_warning ("couldn't create '%s' hash context: %s", 
			   gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
		return FALSE;
	}

	digest = egg_secure_alloc (n_digest);
	g_return_val_if_fail (digest, FALSE);
	if (key) {
		*key = egg_secure_alloc (needed_key);
		g_return_val_if_fail (*key, FALSE);
	}
	if (iv) 
		*iv = g_new0 (guchar, needed_iv);

	if (password)
		gcry_md_write (mdh, password, n_password);
	if (salt && n_salt)
		gcry_md_write (mdh, salt, n_salt);
	gcry_md_final (mdh);
	digested = gcry_md_read (mdh, 0);
	g_return_val_if_fail (digested, FALSE);
	memcpy (digest, digested, n_digest);
		
	for (i = 1; i < iterations; ++i)
		gcry_md_hash_buffer (hash_algo, digest, digest, n_digest);
	
	/* The first x bytes are the key */
	if (key) {
		g_assert (needed_key <= n_digest);
		memcpy (*key, digest, needed_key);
	}
	
	/* The last 16 - x bytes are the iv */
	if (iv) {
		g_assert (needed_iv <= n_digest && n_digest >= 16);
		memcpy (*iv, digest + (16 - needed_iv), needed_iv);
	}
		
	egg_secure_free (digest);
	gcry_md_close (mdh);
	
	return TRUE;	
}
Beispiel #18
0
static void
check_cbc_mac_cipher (void)
{
  struct tv
  {
    int algo;
    char key[MAX_DATA_LEN];
    char plaintext[MAX_DATA_LEN];
    size_t plaintextlen;
    char mac[MAX_DATA_LEN];
  }
  tv[] =
    {
      { GCRY_CIPHER_AES,
	"chicken teriyaki",
	"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
	0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" },
      { GCRY_CIPHER_3DES,
	"abcdefghABCDEFGH01234567",
	"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
	0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
      { GCRY_CIPHER_DES,
	"abcdefgh",
	"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
	0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
    };
  gcry_cipher_hd_t hd;
  char out[MAX_DATA_LEN];
  int i, blklen, keylen;
  gcry_error_t err = 0;

  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    {
      err = gcry_cipher_open (&hd,
			      tv[i].algo,
			      GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
      if (!hd)
	{
	  fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n",
		tv[i].algo, gpg_strerror (err));
	  return;
	}

      blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
      if (!blklen)
	{
	  fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n",
		 tv[i].algo);
	  gcry_cipher_close (hd);
	  return;
	}

      keylen = gcry_cipher_get_algo_keylen (tv[i].algo);
      if (!keylen)
	{
	  fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n",
		tv[i].algo);
	  return;
	}

      err = gcry_cipher_setkey (hd, tv[i].key, keylen);
      if (err)
	{
	  fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
		tv[i].algo, gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

      err = gcry_cipher_setiv (hd, NULL, 0);
      if (err)
	{
	  fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
		tv[i].algo, gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

      err = gcry_cipher_encrypt (hd,
				 out, blklen,
				 tv[i].plaintext,
				 tv[i].plaintextlen ?
				 tv[i].plaintextlen :
				 strlen (tv[i].plaintext));
      if (err)
	{
	  fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
		tv[i].algo, gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

#if 0
      {
	int j;
	for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++)
	  printf ("\\x%02x", out[j] & 0xFF);
	printf ("\n");
      }
#endif

      if (memcmp (tv[i].mac, out, blklen))
	fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);

      gcry_cipher_close (hd);
    }
}
Beispiel #19
0
extern void io_encryption_init(IO_HANDLE ptr, enum gcry_cipher_algos c, enum gcry_md_algos h, enum gcry_cipher_modes m, const uint8_t *k, size_t l, io_extra_t x)
{
	io_private_t *io_ptr = ptr;
	if (!io_ptr || io_ptr->fd < 0)
		return errno = EBADF , (void)NULL;
	/*
	 * start setting up the encryption buffer
	 */
	if (!(io_ptr->buffer_crypt = gcry_malloc_secure(sizeof( buffer_t ))))
		die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, sizeof( buffer_t ));

	gcry_md_open(&io_ptr->hash_handle, h, GCRY_MD_FLAG_SECURE);
	gcry_cipher_open(&io_ptr->cipher_handle, c, m, GCRY_CIPHER_SECURE);
	/*
	 * generate a hash of the supplied key data
	 */
	size_t hash_length = gcry_md_get_algo_dlen(h);
	uint8_t *hash = gcry_malloc_secure(hash_length);
	if (!hash)
		die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, hash_length);
	gcry_md_hash_buffer(gcry_md_get_algo(io_ptr->hash_handle), hash, k, l);
	/*
	 * set the key as the hash of supplied data
	 */
	size_t key_length = gcry_cipher_get_algo_keylen(c);
	uint8_t *key = gcry_calloc_secure(key_length, sizeof( byte_t ));
	if (!key)
		die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, key_length);
	memcpy(key, hash, key_length < hash_length ? key_length : hash_length);
	gcry_cipher_setkey(io_ptr->cipher_handle, key, key_length); /* here is where it blows-up on Windows 8, using AES */
	gcry_free(key);
	/*
	 * the 2011.* versions (incorrectly) used key length instead of block
	 * length; versions after 2014.06 randomly generate the IV instead
	 */
	io_ptr->buffer_crypt->block = gcry_cipher_get_algo_blklen(c);
	uint8_t *iv = gcry_calloc_secure(x.x_iv == IV_BROKEN ? key_length : io_ptr->buffer_crypt->block, sizeof( byte_t ));
	if (!iv)
	   die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, io_ptr->buffer_crypt->block);
	if (x.x_iv == IV_RANDOM)
	{
		if (x.x_encrypt)
		{
			gcry_create_nonce(iv, io_ptr->buffer_crypt->block);
			io_write(ptr, iv, io_ptr->buffer_crypt->block);
		}
		else
			io_read(ptr, iv, io_ptr->buffer_crypt->block);
	}
	else
	{
		uint8_t *iv_hash = gcry_malloc_secure(hash_length);
		if (!iv_hash)
			die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, hash_length);
		/*
		 * set the IV as the hash of the hash
		 */
		gcry_md_hash_buffer(gcry_md_get_algo(io_ptr->hash_handle), iv_hash, hash, hash_length);
		memcpy(iv, iv_hash, io_ptr->buffer_crypt->block < hash_length ? io_ptr->buffer_crypt->block : hash_length);
		gcry_free(iv_hash);
	}
	gcry_free(hash);

	if (m == GCRY_CIPHER_MODE_CTR)
		gcry_cipher_setctr(io_ptr->cipher_handle, iv, io_ptr->buffer_crypt->block);
	else
		gcry_cipher_setiv(io_ptr->cipher_handle, iv, io_ptr->buffer_crypt->block);
	gcry_free(iv);
	/*
	 * set the rest of the buffer
	 */
	if (!(io_ptr->buffer_crypt->stream = gcry_malloc_secure(io_ptr->buffer_crypt->block)))
		die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, io_ptr->buffer_crypt->block);
	/*
	 * when encrypting/writing data:
	 *   0: length of data buffered so far (in stream)
	 *   1: length of data processed (from d)
	 * when decrypting/reading data:
	 *   0: length of available data in input buffer (stream)
	 *   1: available space in read buffer (d)
	 *   2: next available memory location for data (from d)
	 */
	for (unsigned i = 0; i < OFFSET_SLOTS; i++)
		io_ptr->buffer_crypt->offset[i] = 0;
	io_ptr->cipher_init = true;
	io_ptr->hash_init = true;
	io_ptr->operation = IO_ENCRYPT;
	return;
}
Beispiel #20
0
/* Initialize the data encryption key (session key). */
static int
init_dek (DEK dek)
{
  int rc=0, mode, i;

  dek->algo = gcry_cipher_map_name (dek->algoid);
  mode = gcry_cipher_mode_from_oid (dek->algoid);
  if (!dek->algo || !mode)
    {
      log_error ("unsupported algorithm `%s'\n", dek->algoid);
      return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    }
  
  /* Extra check for algorithms we consider to be too weak for
     encryption, although we support them for decryption.  Note that
     there is another check below discriminating on the key length. */
  switch (dek->algo)
    {
    case GCRY_CIPHER_DES:
    case GCRY_CIPHER_RFC2268_40:
      log_error ("cipher algorithm `%s' not allowed: too weak\n",
                 gcry_cipher_algo_name (dek->algo));
      return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    default:
      break;
    }

  dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
  if (!dek->keylen || dek->keylen > sizeof (dek->key))
    return gpg_error (GPG_ERR_BUG);

  dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo);
  if (!dek->ivlen || dek->ivlen > sizeof (dek->iv))
    return gpg_error (GPG_ERR_BUG);

  /* Make sure we don't use weak keys. */
  if (dek->keylen < 100/8)
    { 
      log_error ("key length of `%s' too small\n", dek->algoid);
      return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
    }
  
  rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
  if (rc)
    {
      log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
      return rc;
    }
  
  for (i=0; i < 8; i++)
    {
      gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
      rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
      if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
        break;
      log_info(_("weak key created - retrying\n") );
    }
  if (rc)
    {
      log_error ("failed to set the key: %s\n", gpg_strerror (rc));
      gcry_cipher_close (dek->chd);
      dek->chd = NULL;
      return rc;
    }

  gcry_create_nonce (dek->iv, dek->ivlen);
  rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
  if (rc)
    {
      log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
      gcry_cipher_close (dek->chd);
      dek->chd = NULL;
      return rc;
    }
  
  return 0;
}
void decrypt(char *outfile, char *inpfile) {

	gcry_err_code_t err = 0;
	gcry_cipher_hd_t gchandle;
	const int blks = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256);
	const int keyl = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256);
	long outfileSize = 0;
	char key[keyl];
	const char* salt = "iuyjdbnbtaqonbgt";
	//open output file
	FILE *fout = fopen(outfile, "r");
	if (!fout) {
		printf("output file name : %s\n", outfile);
		fout = fopen(outfile, "w");
	} else {
		printf("Output file already exist on disk.\n");
		return;;
	}
	char password[100];
	do {
		printf("Please enter password between 8-20 chars :");
		scanf("%s", password);
	} while (strlen(password) > 20 || strlen(password) < 8);

	err = gcry_kdf_derive(password, strlen(password), GCRY_KDF_PBKDF2,
			GCRY_MD_SHA256, salt, strlen(salt), 937, keyl, key);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		exit(EXIT_FAILURE);
	}

	char ctext[blks];
	char extractedIV[blks];
	FILE *finp = fopen(inpfile, "r");
	fseek(finp, 0, SEEK_SET);
	unsigned char extractedHMAC[keyl + 1];

	fread(extractedHMAC, 1, keyl, finp); //extract HMAC from received file
	extractedHMAC[keyl] = '\0';

	// Compare calculated HMAC with extracted HMAC ---> start
	long cipherSize = 0;
	fseek(finp, 0, SEEK_END);
	cipherSize = ftell(finp) - keyl;
	fseek(finp, keyl, SEEK_SET);
	unsigned char *hmacBuffer = malloc(cipherSize + 1);
	fread(hmacBuffer, 1, cipherSize, finp);
	gcry_md_hd_t hd;
	err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		fclose(finp);
		fclose(fout);
		exit(EXIT_FAILURE);
	}
	err = gcry_md_setkey(hd, key, keyl);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		fclose(finp);
		fclose(fout);
		exit(EXIT_FAILURE);
	}
	err = gcry_md_enable(hd, GCRY_MD_SHA256);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		fclose(finp);
		fclose(fout);
		exit(EXIT_FAILURE);
	}
	gcry_md_write(hd, hmacBuffer, cipherSize);

	char thmac[keyl];
	unsigned char *hmac = thmac;
	hmac = gcry_md_read(hd, GCRY_MD_SHA256);

	int i = 0;
	int hflag = 1;
	for (; i < keyl; i++) {
		if (hmac[i] != extractedHMAC[i])
			hflag = 0;
	}
	if (hflag)
		printf("HMAC successfully matched\n");
	else
		printf("HMAC not matched\n");

	fseek(finp, keyl, SEEK_SET);
	// Compare calculated HMAC with extracted HMAC ---> end

	//Decryption algo ------> start
	fread(extractedIV, 1, blks, finp); // read IV
	err = gcry_cipher_open(&gchandle, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC,
			0);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		exit(EXIT_FAILURE);
	}

	err = gcry_cipher_setkey(gchandle, key, keyl);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		exit(EXIT_FAILURE);
	}
	err = gcry_cipher_setiv(gchandle, extractedIV, blks);
	if (err) {
		fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
				gcry_strerror(err));
		exit(EXIT_FAILURE);
	}

	if (!finp) {
		printf("Could not open input text file\n");
	} else {
		int x = 0;
		char plaintext[blks];
		while ((x = fread(plaintext, 1, blks, finp))) {
			if (x < blks) // add padding to last block
				outfileSize += x;
			err = gcry_cipher_decrypt(gchandle, ctext, blks, plaintext, x);
			if (err && x == blks) {
				fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err),
						gcry_strerror(err));
				fclose(finp);
				fclose(fout);
				exit(EXIT_FAILURE);
			}
			fwrite(ctext, 1, blks, fout);
		}
		gcry_cipher_close(gchandle);

		gcry_md_close(hd);

		fclose(finp);
		fclose(fout);
	}
	free(hmacBuffer);
	//Decryption algo ------> end
}
static void
cipher_bench ( const char *algoname )
{
  static int header_printed;
  int algo;
  gcry_cipher_hd_t hd;
  int i;
  int keylen, blklen;
  char key[128];
  char outbuf[1000], buf[1000];
  size_t buflen;
  static struct { int mode; const char *name; int blocked; } modes[] = {
    { GCRY_CIPHER_MODE_ECB, "ECB", 1 },
    { GCRY_CIPHER_MODE_CBC, "CBC", 1 },
    { GCRY_CIPHER_MODE_CFB, "CFB", 0 },
    { GCRY_CIPHER_MODE_CTR, "CTR", 0 },
    { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 },
    {0}
  };
  int modeidx;
  gcry_error_t err = GPG_ERR_NO_ERROR;


  if (!algoname)
    {
      for (i=1; i < 400; i++)
        if ( !gcry_cipher_test_algo (i) )
          cipher_bench (gcry_cipher_algo_name (i));
      return;
    }


  if (!header_printed)
    {
      printf ("%-10s", "");
      for (modeidx=0; modes[modeidx].mode; modeidx++)
        printf (" %-15s", modes[modeidx].name );
      putchar ('\n');
      printf ("%-10s", "");
      for (modeidx=0; modes[modeidx].mode; modeidx++)
        printf (" ---------------" );
      putchar ('\n');
      header_printed = 1;
    }

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

  keylen = gcry_cipher_get_algo_keylen (algo);
  if (!keylen)
    {
      fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
	       algoname);
      exit (1);
    }
  if ( keylen > sizeof key )
    {
        fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
                 algo, keylen );
        exit (1);
    }
  for (i=0; i < keylen; i++)
    key[i] = i + (clock () & 0xff);

  blklen = gcry_cipher_get_algo_blklen (algo);
  if (!blklen)
    {
      fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
	       algoname);
      exit (1);
    }

  printf ("%-10s", gcry_cipher_algo_name (algo));
  fflush (stdout);

  for (modeidx=0; modes[modeidx].mode; modeidx++)
    {
      if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
          | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
        {
          printf ("                " );
          continue;
        }

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

      err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
      if (err)
        {
          fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
          exit (1);
        }
      
      err = gcry_cipher_setkey (hd, key, keylen);
      if (err)
      { 
          fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
		   gpg_strerror (err));
          gcry_cipher_close (hd);
          exit (1);
        }

      buflen = sizeof buf;
      if (modes[modeidx].blocked)
        buflen = (buflen / blklen) * blklen;

      start_timer ();
      for (i=err=0; !err && i < 1000; i++)
        err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
      stop_timer ();
      printf (" %s", elapsed_time ());
      fflush (stdout);
      gcry_cipher_close (hd);
      if (err)
        { 
          fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
                   gpg_strerror (err) );
          exit (1);
        }

      err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
      if (err)
        {
          fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
          exit (1);
        }
      
      err = gcry_cipher_setkey (hd, key, keylen);
      if (err)
        { 
          fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
                   gpg_strerror (err));
          gcry_cipher_close (hd);
          exit (1);
        }

      start_timer ();
      for (i=err=0; !err && i < 1000; i++)
        err = gcry_cipher_decrypt ( hd, outbuf, buflen,  buf, buflen);
      stop_timer ();
      printf (" %s", elapsed_time ());
      fflush (stdout);
      gcry_cipher_close (hd);
      if (err)
        { 
          fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
                   gpg_strerror (err) );
          exit (1);
        }
    }

  putchar ('\n');
}
Beispiel #23
0
static void
check_ctr_cipher (void)
{
  struct tv
  {
    int algo;
    char key[MAX_DATA_LEN];
    char ctr[MAX_DATA_LEN];
    struct data
    {
      char plaintext[MAX_DATA_LEN];
      int inlen;
      char out[MAX_DATA_LEN];
    }
    data[MAX_DATA_LEN];
  } tv[] =
    {
      /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
      {	GCRY_CIPHER_AES,
	"\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
	"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
	{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
	    16,
	    "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
	  { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
	    16,
	    "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
	  { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
	    16,
	    "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
	  { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
	    16,
	    "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
	}
      },
      {	GCRY_CIPHER_AES192,
	"\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
	"\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
	"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
	{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
	    16,
	    "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
	  { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
	    16,
	    "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
	  { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
	    16,
	    "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
	  { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
	    16,
	    "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
	}
      },
      {	GCRY_CIPHER_AES256,
	"\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
	"\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
	"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
	{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
	    16,
	    "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
	  { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
	    16,
	    "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
	  { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
	    16,
	    "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
	  { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
	    16,
	    "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }
	}
      }
    };
  gcry_cipher_hd_t hde, hdd;
  char out[MAX_DATA_LEN];
  int i, j, keylen, blklen;
  gcry_error_t err = 0;

  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    {
      err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
      if (!err)
	err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
      if (err)
	{
	  fail ("aes-ctr, grcy_open_cipher failed: %s\n", gpg_strerror (err));
	  return;
	}

      keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
      if (!keylen)
	{
	  fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n");
	  return;
	}

      err = gcry_cipher_setkey (hde, tv[i].key, keylen);
      if (!err)
	err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
      if (err)
	{
	  fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hde);
	  gcry_cipher_close (hdd);
	  return;
	}

      blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
      if (!blklen)
	{
	  fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n");
	  return;
	}

      err = gcry_cipher_setctr (hde, tv[i].ctr, blklen);
      if (!err)
	err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen);
      if (err)
	{
	  fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hde);
	  gcry_cipher_close (hdd);
	  return;
	}

      for (j = 0; tv[i].data[j].inlen; j++)
	{
	  err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
				     tv[i].data[j].plaintext,
				     tv[i].data[j].inlen == -1 ?
				     strlen (tv[i].data[j].plaintext) :
				     tv[i].data[j].inlen);
	  if (err)
	    {
	      fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n",
		    i, j, gpg_strerror (err));
	      gcry_cipher_close (hde);
	      gcry_cipher_close (hdd);
	      return;
	    }

	  if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
	    fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j);

	  err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
	  if (err)
	    {
	      fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n",
		    i, j, gpg_strerror (err));
	      gcry_cipher_close (hde);
	      gcry_cipher_close (hdd);
	      return;
	    }

	  if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
	    fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j);
	}

      gcry_cipher_close (hde);
      gcry_cipher_close (hdd);
    }
}
Beispiel #24
0
int
tls_process_record_handshake(struct SSLConnection *conn, const opaque *fragment)
{
    struct Handshake *handshake;
    struct ClientHello *clienthello;
    struct ServerHello *serverhello;
    struct ClientKeyExchange *clientkeyex;
    const opaque *body;

    // Get Handshake data
    handshake = (struct Handshake *) fragment;

    if (UINT24_INT(handshake->length) > 0) {
        // Hanshake body pointer
        body = fragment + sizeof(struct Handshake);

        switch (handshake->type) {
            case hello_request:
                break;
            case client_hello:
                // Store client random
                clienthello = (struct ClientHello *) body;
                memcpy(&conn->client_random, &clienthello->random, sizeof(struct Random));
                // Check we have a TLS handshake
                if (!(clienthello->client_version.major == 0x03
                      && clienthello->client_version.minor == 0x01)) {
                    tls_connection_destroy(conn);
                    return 1;
                }
                break;
            case server_hello:
                // Store server random
                serverhello = (struct ServerHello *) body;
                memcpy(&conn->server_random, &serverhello->random, sizeof(struct Random));
                // Get the selected cipher
                memcpy(&conn->cipher_suite,
                       body + sizeof(struct ServerHello) + serverhello->session_id_length,
                       sizeof(uint16_t));
                // Check if we have a handled cipher
                if (tls_connection_load_cipher(conn) != 0) {
                    tls_connection_destroy(conn);
                    return 1;
                }
                break;
            case certificate:
            case certificate_request:
            case server_hello_done:
            case certificate_verify:
                break;
            case client_key_exchange:
                // Decrypt PreMasterKey
                clientkeyex = (struct ClientKeyExchange *) body;

                gnutls_datum_t exkeys, pms;
                exkeys.size = UINT16_INT(clientkeyex->length);
                exkeys.data = (unsigned char *)&clientkeyex->exchange_keys;
                gnutls_privkey_decrypt_data(conn->server_private_key, 0, &exkeys, &pms);
                memcpy(&conn->pre_master_secret, pms.data, pms.size);

                // Get MasterSecret
                unsigned char *seed = sng_malloc(sizeof(struct Random) * 2);
                memcpy(seed, &conn->client_random, sizeof(struct Random));
                memcpy(seed + sizeof(struct Random), &conn->server_random, sizeof(struct Random));
                PRF((unsigned char *) &conn->master_secret, sizeof(struct MasterSecret),
                    (unsigned char *) &conn->pre_master_secret, sizeof(struct PreMasterSecret),
                    (unsigned char *) "master secret", seed, sizeof(struct Random) * 2);

                memcpy(seed, &conn->server_random, sizeof(struct Random));
                memcpy(seed + sizeof(struct Random), &conn->client_random, sizeof(struct Random));

                // Generate MACs, Write Keys and IVs
                PRF((unsigned char *) &conn->key_material, sizeof(struct tls_data),
                    (unsigned char *) &conn->master_secret, sizeof(struct MasterSecret),
                    (unsigned char *) "key expansion", seed, sizeof(struct Random) * 2);

                // Done with the seed
                sng_free(seed);

                // Create Client decoder
                gcry_cipher_open(&conn->client_cipher_ctx, conn->ciph, GCRY_CIPHER_MODE_CBC, 0);
                gcry_cipher_setkey(conn->client_cipher_ctx,
                                   conn->key_material.client_write_key,
                                   gcry_cipher_get_algo_keylen(conn->ciph));
                gcry_cipher_setiv(conn->client_cipher_ctx,
                                  conn->key_material.client_write_IV,
                                  gcry_cipher_get_algo_blklen(conn->ciph));

                // Create Server decoder
                gcry_cipher_open(&conn->server_cipher_ctx, conn->ciph, GCRY_CIPHER_MODE_CBC, 0);
                gcry_cipher_setkey(conn->server_cipher_ctx,
                                   conn->key_material.server_write_key,
                                   gcry_cipher_get_algo_keylen(conn->ciph));
                gcry_cipher_setiv(conn->server_cipher_ctx,
                                  conn->key_material.server_write_IV,
                                  gcry_cipher_get_algo_blklen(conn->ciph));

                break;
            case finished:
                break;
            default:
                if (conn->encrypted) {
                    // Encrypted Hanshake Message
                    unsigned char *decoded = sng_malloc(48);
                    uint32_t decodedlen;
                    tls_process_record_data(conn, fragment, 48, &decoded, &decodedlen);
                    sng_free(decoded);
                }
                break;
        }
    }

    return 0;
}
Beispiel #25
0
static int
xmlSecGCryptKWDes3Encrypt(const xmlSecByte *key, xmlSecSize keySize,
                          const xmlSecByte *iv, xmlSecSize ivSize,
                          const xmlSecByte *in, xmlSecSize inSize,
                          xmlSecByte *out, xmlSecSize outSize,
                          int enc) {
    size_t key_len = gcry_cipher_get_algo_keylen(GCRY_CIPHER_3DES);
    size_t block_len = gcry_cipher_get_algo_blklen(GCRY_CIPHER_3DES);
    gcry_cipher_hd_t cipherCtx;
    gcry_error_t err;

    xmlSecAssert2(key != NULL, -1);
    xmlSecAssert2(keySize >= key_len, -1);
    xmlSecAssert2(iv != NULL, -1);
    xmlSecAssert2(ivSize >= block_len, -1);
    xmlSecAssert2(in != NULL, -1);
    xmlSecAssert2(inSize > 0, -1);
    xmlSecAssert2(out != NULL, -1);
    xmlSecAssert2(outSize >= inSize, -1);

    err = gcry_cipher_open(&cipherCtx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); /* we are paranoid */
    if(err != GPG_ERR_NO_ERROR) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "gcry_cipher_open(GCRY_CIPHER_3DES)",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_GCRYPT_REPORT_ERROR(err));
        return(-1);
    }

    err = gcry_cipher_setkey(cipherCtx, key, keySize);
    if(err != GPG_ERR_NO_ERROR) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "gcry_cipher_setkey",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_GCRYPT_REPORT_ERROR(err));
        return(-1);
    }

    err = gcry_cipher_setiv(cipherCtx, iv, ivSize);
    if(err != GPG_ERR_NO_ERROR) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "gcry_cipher_setiv",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_GCRYPT_REPORT_ERROR(err));
        return(-1);
    }

    if(enc) {
        err = gcry_cipher_encrypt(cipherCtx, out, outSize, in, inSize);
        if(err != GPG_ERR_NO_ERROR) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "gcry_cipher_encrypt",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        XMLSEC_GCRYPT_REPORT_ERROR(err));
            gcry_cipher_close(cipherCtx);
            return(-1);
        }
    } else {
        err = gcry_cipher_decrypt(cipherCtx, out, outSize, in, inSize);
        if(err != GPG_ERR_NO_ERROR) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "gcry_cipher_decrypt",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        XMLSEC_GCRYPT_REPORT_ERROR(err));
            gcry_cipher_close(cipherCtx);
            return(-1);
        }
    }

    /* done */
    gcry_cipher_close(cipherCtx);
    return((int)inSize); /* out size == in size */
}
Beispiel #26
0
static void
check_one_cipher (int algo, int mode, int flags)
{
  gcry_cipher_hd_t hd;
  char key[32], plain[16], in[16], out[16];
  int keylen;
  gcry_error_t err = 0;

  memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
  memcpy (plain, "foobar42FOOBAR17", 16);

  keylen = gcry_cipher_get_algo_keylen (algo);
  if (!keylen)
    {
      fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
	    algo, mode);
      return;
    }

  if (keylen < 40 / 8 || keylen > 32)
    {
      fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen);
      return;
    }

  err = gcry_cipher_open (&hd, algo, mode, flags);
  if (err)
    {
      fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
	    algo, mode, gpg_strerror (err));
      return;
    }

  err = gcry_cipher_setkey (hd, key, keylen);
  if (err)
    {
      fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
	    algo, mode, gpg_strerror (err));
      gcry_cipher_close (hd);
      return;
    }

  err = gcry_cipher_encrypt (hd, out, 16, plain, 16);
  if (err)
    {
      fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
	    algo, mode, gpg_strerror (err));
      gcry_cipher_close (hd);
      return;
    }

  gcry_cipher_reset (hd);

  err = gcry_cipher_decrypt (hd, in, 16, out, 16);
  if (err)
    {
      fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
	    algo, mode, gpg_strerror (err));
      gcry_cipher_close (hd);
      return;
    }

  gcry_cipher_close (hd);

  if (memcmp (plain, in, 16))
    fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
}
Beispiel #27
0
gpointer
encrypt_file (const gchar *input_file_path, const gchar *pwd, const gchar *algo, const gchar *algo_mode)
{
    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *encryption_keys = g_new0 (CryptoKeys, 1);

    set_algo_and_mode (header_metadata, algo, algo_mode);
    gsize algo_key_len = gcry_cipher_get_algo_keylen (header_metadata->algo);
    gsize algo_blk_len = gcry_cipher_get_algo_blklen (header_metadata->algo);

    header_metadata->iv_size = algo_blk_len;  // iv must be the same size as the block size

    gcry_create_nonce (header_metadata->iv, header_metadata->iv_size);
    gcry_create_nonce (header_metadata->salt, KDF_SALT_SIZE);

    if (!setup_keys (pwd, algo_key_len, header_metadata, encryption_keys)) {
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        return g_strdup ("Couldn't setup the encryption keys, exiting...");
    }

    goffset filesize = get_file_size (input_file_path);

    GError *err = NULL;

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        g_object_unref (in_file);

        return g_strdup (err->message);
    }

    gchar *output_file_path = g_strconcat (input_file_path, ".enc", NULL);
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (3, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    gcry_cipher_hd_t hd;
    gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0);
    gcry_cipher_setkey (hd, encryption_keys->crypto_key, algo_key_len);

    gint64 number_of_blocks;
    gint number_of_padding_bytes;
    gchar *ret_msg;
    if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) {
        set_number_of_blocks_and_padding_bytes (filesize, algo_blk_len, &number_of_blocks, &number_of_padding_bytes);
        gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_cbc_mode (header_metadata, &hd, number_of_blocks, number_of_padding_bytes, algo_blk_len, in_stream, out_stream);
    }
    else {
        gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_ctr_mode (header_metadata, &hd, filesize, in_stream, out_stream);
    }
    if (ret_msg != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (ret_msg);

    }

    gcry_cipher_close (hd);

    guchar *hmac = calculate_hmac (output_file_path, encryption_keys->hmac_key, NULL);
    gssize written_bytes = g_output_stream_write (G_OUTPUT_STREAM (out_stream), hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (written_bytes == -1) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (4, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path,
                       (gpointer) &hmac);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
    g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

    multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                        (gpointer) &encryption_keys->hmac_key);

    multiple_free (4, (gpointer) &output_file_path, (gpointer) &encryption_keys, (gpointer) &header_metadata,
                   (gpointer) &hmac);

    multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                    (gpointer) &out_stream);

    return NULL;
}
Beispiel #28
0
size_t _encryption_key_size(SINGLE_QSP_ARG_DECL)
{
	/* Retrieve the key length in bytes used with algorithm A. */
	return gcry_cipher_get_algo_keylen (the_crypt_algo);
}
gboolean
egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password, 
                                gssize n_password, const guchar *data, gsize n_data,
                                guchar **encrypted, gsize *n_encrypted)
{
	gsize n_overflow, n_batch, n_padding;
	gcry_cipher_hd_t ch;
	guchar *key = NULL;
	guchar *iv = NULL;
	guchar *padded = NULL;
	int gcry, ivlen;
	int algo = 0;
	int mode = 0;
	
	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
		g_return_val_if_reached (FALSE);
		
	ivlen = gcry_cipher_get_algo_blklen (algo);

	/* We assume the iv is at least as long as at 8 byte salt */
	g_return_val_if_fail (ivlen >= 8, FALSE);
	
	/* IV is already set from the DEK info */
	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, 
	                                        n_password, iv, 8, 1, &key, NULL))
		g_return_val_if_reached (FALSE);
	
	gcry = gcry_cipher_open (&ch, algo, mode, 0);
	g_return_val_if_fail (!gcry, FALSE);
		
	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
	g_return_val_if_fail (!gcry, FALSE);
	egg_secure_free (key);

	/* 16 = 128 bits */
	gcry = gcry_cipher_setiv (ch, iv, ivlen);
	g_return_val_if_fail (!gcry, FALSE);
	g_free (iv);
	
	/* Allocate output area */
	n_overflow = (n_data % ivlen);
	n_padding = n_overflow ? (ivlen - n_overflow) : 0;
	n_batch = n_data - n_overflow;
	*n_encrypted = n_data + n_padding;
	*encrypted = g_malloc0 (*n_encrypted);
	
	g_assert (*n_encrypted % ivlen == 0);
	g_assert (*n_encrypted >= n_data);
	g_assert (*n_encrypted == n_batch + n_overflow + n_padding);

	/* Encrypt everything but the last bit */
	gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch);
	if (gcry) {
		g_free (*encrypted);
		g_return_val_if_reached (FALSE);
	}
	
	/* Encrypt the padded block */
	if (n_overflow) {
		padded = egg_secure_alloc (ivlen);
		memset (padded, 0, ivlen);
		memcpy (padded, data + n_batch, n_overflow);
		gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen);
		egg_secure_free (padded);
		if (gcry) {
			g_free (*encrypted);
			g_return_val_if_reached (FALSE);
		}
	}

	gcry_cipher_close (ch);
	return TRUE;
}
Beispiel #30
0
static void
cipher_bench ( const char *algoname )
{
  static int header_printed;
  int algo;
  gcry_cipher_hd_t hd;
  int i;
  int keylen, blklen;
  char key[128];
  char *outbuf, *buf;
  char *raw_outbuf, *raw_buf;
  size_t allocated_buflen, buflen;
  int repetitions;
  static struct { int mode; const char *name; int blocked; } modes[] = {
    { GCRY_CIPHER_MODE_ECB, "   ECB/Stream", 1 },
    { GCRY_CIPHER_MODE_CBC, "      CBC", 1 },
    { GCRY_CIPHER_MODE_CFB, "      CFB", 0 },
    { GCRY_CIPHER_MODE_OFB, "      OFB", 0 },
    { GCRY_CIPHER_MODE_CTR, "      CTR", 0 },
    { GCRY_CIPHER_MODE_STREAM, "", 0 },
    {0}
  };
  int modeidx;
  gcry_error_t err = GPG_ERR_NO_ERROR;


  if (!algoname)
    {
      for (i=1; i < 400; i++)
        if ( !gcry_cipher_test_algo (i) )
          cipher_bench (gcry_cipher_algo_name (i));
      return;
    }

  if (large_buffers)
    {
      allocated_buflen = 1024 * 100;
      repetitions = 10;
    }
  else
    {
      allocated_buflen = 1024;
      repetitions = 1000;
    }
  repetitions *= cipher_repetitions;

  raw_buf = gcry_xmalloc (allocated_buflen+15);
  buf = (raw_buf
         + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment));
  outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15);
  outbuf = (raw_outbuf
            + ((16 - ((size_t)raw_outbuf & 0x0f)) % buffer_alignment));

  if (!header_printed)
    {
      if (cipher_repetitions != 1)
        printf ("Running each test %d times.\n", cipher_repetitions);
      printf ("%-12s", "");
      for (modeidx=0; modes[modeidx].mode; modeidx++)
        if (*modes[modeidx].name)
          printf (" %-15s", modes[modeidx].name );
      putchar ('\n');
      printf ("%-12s", "");
      for (modeidx=0; modes[modeidx].mode; modeidx++)
        if (*modes[modeidx].name)
          printf (" ---------------" );
      putchar ('\n');
      header_printed = 1;
    }

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

  keylen = gcry_cipher_get_algo_keylen (algo);
  if (!keylen)
    {
      fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
	       algoname);
      exit (1);
    }
  if ( keylen > sizeof key )
    {
        fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
                 algo, keylen );
        exit (1);
    }
  for (i=0; i < keylen; i++)
    key[i] = i + (clock () & 0xff);

  blklen = gcry_cipher_get_algo_blklen (algo);
  if (!blklen)
    {
      fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
	       algoname);
      exit (1);
    }

  printf ("%-12s", gcry_cipher_algo_name (algo));
  fflush (stdout);

  for (modeidx=0; modes[modeidx].mode; modeidx++)
    {
      if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
          | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
        continue;

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

      err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
      if (err)
        {
          fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
          exit (1);
        }

      if (!cipher_with_keysetup)
        {
          err = gcry_cipher_setkey (hd, key, keylen);
          if (err)
            {
              fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
                       gpg_strerror (err));
              gcry_cipher_close (hd);
              exit (1);
            }
        }

      buflen = allocated_buflen;
      if (modes[modeidx].blocked)
        buflen = (buflen / blklen) * blklen;

      start_timer ();
      for (i=err=0; !err && i < repetitions; i++)
        {
          if (cipher_with_keysetup)
            {
              err = gcry_cipher_setkey (hd, key, keylen);
              if (err)
                {
                  fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
                           gpg_strerror (err));
                  gcry_cipher_close (hd);
                  exit (1);
                }
            }
          err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
        }
      stop_timer ();

      printf (" %s", elapsed_time ());
      fflush (stdout);
      gcry_cipher_close (hd);
      if (err)
        {
          fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
                   gpg_strerror (err) );
          exit (1);
        }

      err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
      if (err)
        {
          fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
          exit (1);
        }

      if (!cipher_with_keysetup)
        {
          err = gcry_cipher_setkey (hd, key, keylen);
          if (err)
            {
              fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
                       gpg_strerror (err));
              gcry_cipher_close (hd);
              exit (1);
            }
        }

      start_timer ();
      for (i=err=0; !err && i < repetitions; i++)
        {
          if (cipher_with_keysetup)
            {
              err = gcry_cipher_setkey (hd, key, keylen);
              if (err)
                {
                  fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
                           gpg_strerror (err));
                  gcry_cipher_close (hd);
                  exit (1);
                }
            }
          err = gcry_cipher_decrypt ( hd, outbuf, buflen,  buf, buflen);
        }
      stop_timer ();
      printf (" %s", elapsed_time ());
      fflush (stdout);
      gcry_cipher_close (hd);
      if (err)
        {
          fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
                   gpg_strerror (err) );
          exit (1);
        }
    }

  putchar ('\n');
  gcry_free (raw_buf);
  gcry_free (raw_outbuf);
}