Exemplo n.º 1
0
/* Check that forking won't return the same nonce. */
static void
check_nonce_forking (void)
{
  pid_t pid;
  int rp[2];
  int i, status;
  size_t nread;
  char nonce1[10], nonce1c[10], nonce1p[10];
  
  /* We won't get the same nonce back if we never initialized the
     nonce subsystem, thus we get one nonce here and forget about
     it. */
  gcry_create_nonce (nonce1, sizeof nonce1);
  if (verbose)
    print_hex ("initial nonce: ", nonce1, sizeof nonce1);

  if (pipe (rp) == -1)
    die ("pipe failed: %s\n", strerror (errno));

  pid = fork ();
  if (pid == (pid_t)(-1))
    die ("fork failed: %s\n", strerror (errno));
  if (!pid)
    {
      gcry_create_nonce (nonce1c, sizeof nonce1c);
      if (writen (rp[1], nonce1c, sizeof nonce1c))
        die ("write failed: %s\n", strerror (errno));
      if (verbose)
        {
          print_hex ("  child nonce: ", nonce1c, sizeof nonce1c);
          fflush (stdout);
        }
      _exit (0);
    }
  gcry_create_nonce (nonce1p, sizeof nonce1p);
  if (verbose)
    print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);

  close (rp[1]);
  if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
    die ("read failed: %s\n", strerror (errno)); 
  if (nread != sizeof nonce1c)
    die ("read too short\n");

  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
    ;
  if (i != (pid_t)(-1)
      && WIFEXITED (status) && !WEXITSTATUS (status))
    ;
  else
    die ("child failed\n");

  if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
    die ("parent and child got the same nonce\n");
}
Exemplo n.º 2
0
/**
 * @ingroup crypto
 * Fill block with a random values.
 *
 * @param mode desired quality of the random number
 * @param buffer the buffer to fill
 * @param length buffer length
 */
void
GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
{
#ifdef gcry_fast_random_poll
  static unsigned int invokeCount;
#endif
  switch (mode)
  {
  case GNUNET_CRYPTO_QUALITY_STRONG:
    /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
#ifdef gcry_fast_random_poll
    if ((invokeCount++ % 256) == 0)
      gcry_fast_random_poll ();
#endif
    gcry_randomize (buffer, length, GCRY_STRONG_RANDOM);
    return;
  case GNUNET_CRYPTO_QUALITY_NONCE:
    gcry_create_nonce (buffer, length);
    return;
  case GNUNET_CRYPTO_QUALITY_WEAK:
    /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
#ifdef gcry_fast_random_poll
    if ((invokeCount++ % 256) == 0)
      gcry_fast_random_poll ();
#endif
    gcry_randomize (buffer, length, GCRY_WEAK_RANDOM);
    return;
  default:
    GNUNET_assert (0);
  }
}
Exemplo n.º 3
0
const gchar*
egg_openssl_prep_dekinfo (GHashTable *headers)
{
	gchar *dekinfo, *hex;
	gsize ivlen;
	guchar *iv;

	/* Create the iv */
	ivlen = gcry_cipher_get_algo_blklen (GCRY_CIPHER_3DES);
	g_return_val_if_fail (ivlen, NULL);
	iv = g_malloc (ivlen);
	gcry_create_nonce (iv, ivlen);

	/* And encode it into the string */
	hex = egg_hex_encode (iv, ivlen);
	g_return_val_if_fail (hex, NULL);
	dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
	g_free (hex);
	g_free (iv);

	g_hash_table_insert (headers, g_strdup ("DEK-Info"), (void*)dekinfo);
	g_hash_table_insert (headers, g_strdup ("Proc-Type"), g_strdup ("4,ENCRYPTED"));

	return dekinfo;
}
Exemplo n.º 4
0
char *
build_hello (char *sub)
{

    uint8_t *nonce = malloc (32);

    gcry_create_nonce (nonce, 32);

    char *bnonce;
    int nl = base64url_encode_alloc (nonce, 32, &bnonce);

    time_t current_time;
    current_time = time(NULL);

    json_t *obj = json_object();



    json_object_set_new(obj, "jti", json_string(bnonce));
    json_object_set_new(obj, "sub", json_string(sub));
    json_object_set_new(obj, "Version", json_integer(1));
    json_object_set_new(obj, "msg_id", json_integer(1));

    json_object_set_new(obj, "iat", json_integer (current_time));
    json_object_set_new(obj, "exp", json_integer (current_time + 60 * 5));


    char * jwt = jwt_encode_old (obj, ES256, hard_sign);

    assert (NULL != jwt);

    return jwt;
}
Exemplo n.º 5
0
void
egg_libgcrypt_initialize (void)
{
	static volatile gsize gcrypt_initialized = 0;
	unsigned seed;

	if (g_once_init_enter (&gcrypt_initialized)) {
		
		/* Only initialize libgcrypt if it hasn't already been initialized */
		if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
#if GCRYPT_VERSION_NUMBER < 0x010600
			gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
#endif
			gcry_check_version (LIBGCRYPT_VERSION);
			gcry_set_log_handler (log_handler, NULL);
			gcry_set_outofcore_handler (no_mem_handler, NULL);
			gcry_set_fatalerror_handler (fatal_handler, NULL);
			gcry_set_allocation_handler ((gcry_handler_alloc_t)g_malloc, 
			                             (gcry_handler_alloc_t)egg_secure_alloc, 
			                             egg_secure_check, 
			                             (gcry_handler_realloc_t)egg_secure_realloc, 
			                             egg_secure_free);
			gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
		}
		
		gcry_create_nonce (&seed, sizeof (seed));
		srand (seed);

		g_once_init_leave (&gcrypt_initialized, 1);
	}
}
Exemplo n.º 6
0
Arquivo: stream.c Projeto: gpg/gsti
/* Write NBYTES from buffer. If BUFFER is NULL the strong random bytes
   are written.  Returns 0 on success or an error code.  */
gsti_error_t
_gsti_stream_writen (write_stream_t a, const void *buffer, size_t nbytes)
{
  gsti_error_t err = 0;
  const unsigned char *s = buffer;

  if (buffer)
    {
      while (nbytes)
	{
	  if (_gsti_stream_put (a, *s))
	    {
              err = a->error;
	      break;
	    }
	  s++;
	  nbytes--;
	}
    }
  else
    {				/* write random padding */
      byte * pad = _gsti_xcalloc (1, nbytes);
      gcry_create_nonce (pad, nbytes);
      err = _gsti_stream_writen (a, pad, nbytes);
      gcry_free (pad);
    }

  return err;
}
Exemplo n.º 7
0
static gboolean
service_encode_aes_secret (SecretSession *session,
                           SecretValue *value,
                           GVariantBuilder *builder)
{
	gcry_cipher_hd_t cih;
	guchar *padded;
	gsize n_padded, pos;
	gcry_error_t gcry;
	gpointer iv;
	gconstpointer secret;
	gsize n_secret;
	GVariant *child;

	g_variant_builder_add (builder, "o", session->path);

	/* Create the cipher */
	gcry = gcry_cipher_open (&cih, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
	if (gcry != 0) {
		g_warning ("couldn't create AES cipher: %s", gcry_strerror (gcry));
		return FALSE;
	}

	secret = secret_value_get (value, &n_secret);

	/* Perform the encoding here */
	padded = pkcs7_pad_bytes_in_secure_memory (secret, n_secret, &n_padded);
	g_assert (padded != NULL);

	/* Setup the IV */
	iv = g_malloc0 (16);
	gcry_create_nonce (iv, 16);
	gcry = gcry_cipher_setiv (cih, iv, 16);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* Setup the key */
	gcry = gcry_cipher_setkey (cih, session->key, session->n_key);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* Perform the encryption */
	for (pos = 0; pos < n_padded; pos += 16) {
		gcry = gcry_cipher_encrypt (cih, (guchar*)padded + pos, 16, NULL, 0);
		g_return_val_if_fail (gcry == 0, FALSE);
	}

	gcry_cipher_close (cih);

	child = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), iv, 16, TRUE, g_free, iv);
	g_variant_builder_add_value (builder, child);

	child = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), padded, n_padded, TRUE, egg_secure_free, padded);
	g_variant_builder_add_value (builder, child);

	g_variant_builder_add (builder, "s", secret_value_get_content_type (value));
	return TRUE;
}
Exemplo n.º 8
0
static int
wrap_gcry_rnd (void *ctx, int level, void *data, size_t datasize)
{
    if (level == GNUTLS_RND_NONCE)
        gcry_create_nonce (data, datasize);
    else
        gcry_randomize (data, datasize, level);

    return 0;
}
Exemplo n.º 9
0
static int
wrap_gcry_rnd_init (void **ctx)
{
    char c;

    gcry_create_nonce (&c, 1);
    gcry_randomize (&c, 1, GCRY_STRONG_RANDOM);

    return 0;
}
Exemplo n.º 10
0
Arquivo: ssl.c Projeto: ezc/elinks
/* When CONFIG_SSL is defined, this implementation replaces the one in
 * src/util/random.c.  */
void
random_nonce(unsigned char buf[], size_t size)
{
#ifdef USE_OPENSSL
	RAND_pseudo_bytes(buf, size);
#elif defined(CONFIG_GNUTLS)
	gcry_create_nonce(buf, size);
#else
# error unsupported SSL library
#endif
}
Exemplo n.º 11
0
static void
check_nonce (void)
{
    char a[32], b[32];
    int i,j;
    int oops=0;

    if (verbose)
        show ("checking gcry_create_nonce\n");

    gcry_create_nonce (a, sizeof a);
    for (i=0; i < 10; i++)
    {
        gcry_create_nonce (b, sizeof b);
        if (!memcmp (a, b, sizeof a))
            die ("identical nonce found\n");
    }
    for (i=0; i < 10; i++)
    {
        gcry_create_nonce (a, sizeof a);
        if (!memcmp (a, b, sizeof a))
            die ("identical nonce found\n");
    }

again:
    for (i=1,j=0; i < sizeof a; i++)
        if (a[0] == a[i])
            j++;
    if (j+1 == sizeof (a))
    {
        if (oops)
            die ("impossible nonce found\n");
        oops++;
        gcry_create_nonce (a, sizeof a);
        goto again;
    }
}
Exemplo n.º 12
0
/**
 * @brief create a random sequence of characters with given length.
 * @param errorKey holds an error description in case of failure.
 * @param length the number of random bytes to be generated.
 * @returns allocated buffer holding a hex-encoded random string or NULL in case of error. Must be freed by the caller.
 */
char * elektraCryptoGcryCreateRandomString (Key * errorKey, const kdb_unsigned_short_t length)
{
	char * encoded = NULL;
	kdb_octet_t buffer[length];
	gcry_create_nonce (buffer, length);
	if (CRYPTO_PLUGIN_FUNCTION (base64Encode) (errorKey, buffer, length, &encoded) < 0)
	{
		return NULL;
	}
	if (!encoded)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
	}
	return encoded;
}
Exemplo n.º 13
0
/**
 * Produce a random unsigned 32-bit number modulo @a i.
 *
 * @param mode desired quality of the random number
 * @param i the upper limit (exclusive) for the random number
 * @return a random value in the interval [0,i[.
 */
uint32_t
GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode,
			  uint32_t i)
{
#ifdef gcry_fast_random_poll
  static unsigned int invokeCount;
#endif
  uint32_t ret;
  uint32_t ul;

  GNUNET_assert (i > 0);

  switch (mode)
  {
  case GNUNET_CRYPTO_QUALITY_STRONG:
    /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
#ifdef gcry_fast_random_poll
    if ((invokeCount++ % 256) == 0)
      gcry_fast_random_poll ();
#endif
    ul = UINT32_MAX - (UINT32_MAX % i);
    do
    {
      gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t),
                      GCRY_STRONG_RANDOM);
    }
    while (ret >= ul);
    return ret % i;
  case GNUNET_CRYPTO_QUALITY_NONCE:
    ul = UINT32_MAX - (UINT32_MAX % i);
    do
    {
      gcry_create_nonce (&ret, sizeof (ret));
    }
    while (ret >= ul);
    return ret % i;
  case GNUNET_CRYPTO_QUALITY_WEAK:
    ret = i * get_weak_random ();
    if (ret >= i)
      ret = i - 1;
    return ret;
  default:
    GNUNET_assert (0);
  }
  return 0;
}
Exemplo n.º 14
0
/* The nonce thread.  We simply request a couple of nonces and
   return.  */
static THREAD_RET_TYPE
nonce_thread (void *argarg)
{
  struct thread_arg_s *arg = argarg;
  int i;
  char nonce[NONCE_SIZE];

  for (i = 0; i < N_NONCE_ITERATIONS; i++)
    {
      gcry_create_nonce (nonce, sizeof nonce);
      if (i && !(i%100))
        show ("thread %d created %d nonces so far", arg->no, i);
    }

  gcry_free (arg);
  return THREAD_RET_VALUE;
}
Exemplo n.º 15
0
/**
* builder: The GTKBuilder
* password_type: password type description
*
* Reads the encrypted data from the prompt and transfers it using output_data.
* If crypto is available, it uses crypto.
*
**/
static void
gather_password (GtkBuilder *builder, const gchar *password_type)
{
	GtkEntry *entry;
	gchar iv[16];
	gpointer data;
	gsize n_data;
	gchar *name;
	const gchar *text;
	gchar *value;

	name = g_strdup_printf ("%s_entry", password_type);
	entry = GTK_ENTRY (gtk_builder_get_object (builder, name));
	g_return_if_fail (GTK_IS_ENTRY (entry));
	g_free (name);

	if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
		return;

	/* A non-encrypted password: just send the value back */
	if (!g_key_file_has_group (input_data, "transport")) {
		text = gtk_entry_get_text (entry);
		value = egg_hex_encode ((const guchar*)text, strlen (text));
		g_key_file_set_string (output_data, password_type, "parameter", "");
		g_key_file_set_string (output_data, password_type, "value", value);
		g_free (value);
		return;
	}

	if (!the_key && !negotiate_transport_crypto ()) {
		g_warning ("couldn't negotiate transport crypto for password");
		return;
	}

	gcry_create_nonce (iv, sizeof (iv));
	data = gku_prompt_util_encrypt_text (the_key, n_the_key, iv, sizeof (iv),
	                                     gtk_entry_get_text (entry), &n_data);
	g_return_if_fail (data);

	gku_prompt_util_encode_hex (output_data, password_type, "parameter", iv, sizeof (iv));
	gku_prompt_util_encode_hex (output_data, password_type, "value", data, n_data);

	g_free (data);
}
Exemplo n.º 16
0
static ssize_t enc_write(io_private_t *f, const void *d, size_t l)
{
	size_t remainder[2] = { l, f->buffer_crypt->block - f->buffer_crypt->offset[0] }; /* 0: length of data yet to buffer (from d); 1: available space in output buffer (stream) */
	if (!d && !l)
	{
#if defined(__DEBUG__) && !defined(__DEBUG_WITH_ENCRYPTION__)
		memset(f->buffer_crypt->stream + f->buffer_crypt->offset[0], 0x00, remainder[1]);
#else
		gcry_create_nonce(f->buffer_crypt->stream + f->buffer_crypt->offset[0], remainder[1]);
		gcry_cipher_encrypt(f->cipher_handle, f->buffer_crypt->stream, f->buffer_crypt->block, NULL, 0);
#endif
		ssize_t e = ecc_write(f, f->buffer_crypt->stream, f->buffer_crypt->block);
		ecc_sync(f);
		f->buffer_crypt->block = 0;
		gcry_free(f->buffer_crypt->stream);
		f->buffer_crypt->stream = NULL;
		memset(f->buffer_crypt->offset, 0x00, sizeof f->buffer_crypt->offset);
		return e;
	}

	f->buffer_crypt->offset[1] = 0;
	while (remainder[0])
	{
		if (remainder[0] < remainder[1])
		{
			memcpy(f->buffer_crypt->stream + f->buffer_crypt->offset[0], d + f->buffer_crypt->offset[1], remainder[0]);
			f->buffer_crypt->offset[0] += remainder[0];
			return l;
		}
		memcpy(f->buffer_crypt->stream + f->buffer_crypt->offset[0], d + f->buffer_crypt->offset[1], remainder[1]);
#if !defined(__DEBUG__) || defined(__DEBUG_WITH_ENCRYPTION__)
		gcry_cipher_encrypt(f->cipher_handle, f->buffer_crypt->stream, f->buffer_crypt->block, NULL, 0);
#endif
		ssize_t e = EXIT_SUCCESS;
		if ((e = ecc_write(f, f->buffer_crypt->stream, f->buffer_crypt->block)) < 0)
			return e;
		f->buffer_crypt->offset[0] = 0;
		memset(f->buffer_crypt->stream, 0x00, f->buffer_crypt->block);
		f->buffer_crypt->offset[1] += remainder[1];
		remainder[0] -= remainder[1];
		remainder[1] = f->buffer_crypt->block - f->buffer_crypt->offset[0];
	}
	return l;
}
Exemplo n.º 17
0
/**
 * @brief derive the cryptographic key and IV for a given (Elektra) Key k
 * @param config KeySet holding the plugin/backend configuration
 * @param errorKey holds an error description in case of failure
 * @param masterKey holds the decrypted master password from the plugin configuration
 * @param k the (Elektra)-Key to be encrypted
 * @param cKey (Elektra)-Key holding the cryptographic material
 * @param cIv (Elektra)-Key holding the initialization vector
 * @retval -1 on failure. errorKey holds the error description.
 * @retval 1 on success
 */
static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
{
	gcry_error_t gcry_err;
	kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN];
	kdb_octet_t keyBuffer[KEY_BUFFER_SIZE];
	char * saltHexString = NULL;

	ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");

	// generate the salt
	gcry_create_nonce (salt, sizeof (salt));
	const int encodingResult = CRYPTO_PLUGIN_FUNCTION (base64Encode) (errorKey, salt, sizeof (salt), &saltHexString);
	if (encodingResult < 0)
	{
		// error in libinvoke - errorKey has been set by base64Encode
		return -1;
	}
	if (!saltHexString)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return -1;
	}
	keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString);
	elektraFree (saltHexString);

	// read iteration count
	const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);

	// generate/derive the cryptographic key and the IV
	if ((gcry_err = gcry_kdf_derive (keyValue (masterKey), keyGetValueSize (masterKey), GCRY_KDF_PBKDF2, GCRY_MD_SHA512, salt,
					 sizeof (salt), iterations, KEY_BUFFER_SIZE, keyBuffer)))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey,
				    "Failed to create a cryptographic key for encryption because: %s", gcry_strerror (gcry_err));
		return -1;
	}

	keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_GCRY_KEYSIZE);
	keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_GCRY_KEYSIZE, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	return 1;
}
Exemplo n.º 18
0
gchar * __pkey_manage_aes_encrypt (const gchar *in, const gchar *password)
{
    gchar * result = NULL;

    gint i;
    guint in_length = strlen (in);
    guchar * random_data = NULL;
    guchar * sha256 = NULL;
    gchar * sha256_hex = NULL;

    gchar * cyphered = NULL;

    random_data = g_new0 (guchar, in_length);

    // Fill random_data with random data
    gcry_create_nonce (random_data, in_length);

    // XOR random_data with in => random_data
    for (i=0; i<in_length; i++) {
        random_data[i] = random_data[i] ^ in[i];
    }

    // SHA-2 256 random_data
    sha256 = g_new0 (guchar, gcry_md_get_algo_dlen(GCRY_MD_SHA256));
    gcry_md_hash_buffer (GCRY_MD_SHA256, sha256, random_data, in_length);

    sha256_hex = __pkey_manage_to_hex (sha256, 32);

    cyphered = __pkey_manage_aes_encrypt_aux (in, password, &sha256[0], &sha256[16]);

    result = g_strdup_printf ("gCP%s%s", sha256_hex, cyphered);

    g_free (sha256_hex);
    g_free (cyphered);

    g_free (sha256);
    g_free (random_data);

    return result;

}
Exemplo n.º 19
0
void
gcry_mpi_randomize( gcry_mpi_t w,
		    unsigned int nbits, enum gcry_random_level level )
{
  unsigned char *p;
  size_t nbytes = (nbits+7)/8;
  
  if (level == GCRY_WEAK_RANDOM)
    {
      p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
                           : gcry_xmalloc (nbytes);
      gcry_create_nonce (p, nbytes);
    }
  else
    {
      p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
                           : gcry_random_bytes (nbytes, level);
    }
  _gcry_mpi_set_buffer( w, p, nbytes, 0 );
  gcry_free (p);
}
Exemplo n.º 20
0
/**
 * Generate random unsigned 64-bit value.
 *
 * @param mode desired quality of the random number
 * @param max value returned will be in range [0,max) (exclusive)
 * @return random 64-bit number
 */
uint64_t
GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
{
  uint64_t ret;
  uint64_t ul;

  GNUNET_assert (max > 0);
  switch (mode)
  {
  case GNUNET_CRYPTO_QUALITY_STRONG:
    ul = UINT64_MAX - (UINT64_MAX % max);
    do
    {
      gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t),
                      GCRY_STRONG_RANDOM);
    }
    while (ret >= ul);
    return ret % max;
  case GNUNET_CRYPTO_QUALITY_NONCE:
    ul = UINT64_MAX - (UINT64_MAX % max);
    do
    {
      gcry_create_nonce (&ret, sizeof (ret));
    }
    while (ret >= ul);

    return ret % max;
  case GNUNET_CRYPTO_QUALITY_WEAK:
    ret = max * get_weak_random ();
    if (ret >= max)
      ret = max - 1;
    return ret;
  default:
    GNUNET_assert (0);
  }
  return 0;
}
Exemplo n.º 21
0
cipher::cipher(string k) :
	encryptor(k)
{
	bool in=false,out=false;
	in=gcry_cipher_open(&hd_in,GCRY_CIPHER_AES,GCRY_CIPHER_MODE_CBC,0) == 0;
	out=gcry_cipher_open(&hd_out,GCRY_CIPHER_AES,GCRY_CIPHER_MODE_CBC,0) == 0;
	if(!in || !out){
		goto error_exit;
	}

	if( gcry_cipher_setkey(hd_in,&key.front(),16) != 0) {
		goto error_exit;
	}
	if( gcry_cipher_setkey(hd_out,&key.front(),16) != 0)
		goto error_exit;
	char iv[16];
	gcry_create_nonce(iv,sizeof(iv));
	gcry_cipher_setiv(hd_out,iv,sizeof(iv));
	return;
error_exit:
	if(in) gcry_cipher_close(hd_in);
	if(out) gcry_cipher_close(hd_out);
	throw cppcms_error("AES cipher initialization failed");
}
Exemplo n.º 22
0
char *
build_hello_rsp (char *sub, json_t *hellorsp)
{

    uint8_t *nonce = malloc (32);

    gcry_create_nonce (nonce, 32);

    char *bnonce;
    int nl = base64url_encode_alloc (nonce, 32, &bnonce);

    time_t current_time;
    current_time = time(NULL);

    json_t *obj = json_object();

    double msg_id = json_number_value( json_object_get (hellorsp, "msg_id"));

    const char *snonce = json_string_value( json_object_get (hellorsp, "jti"));

    json_object_set_new(obj, "jti", json_string(bnonce));
    json_object_set_new(obj, "sub", json_string(sub));
    json_object_set_new(obj, "snonce", json_string(snonce));
    json_object_set_new(obj, "Version", json_integer(1));
    json_object_set_new(obj, "msg_id", json_integer(msg_id + 1));

    json_object_set_new(obj, "iat", json_integer (current_time));
    json_object_set_new(obj, "exp", json_integer (current_time + 60 * 5));


    char * jwt = jwt_encode_old (obj, ES256, hard_sign);

    assert (NULL != jwt);

    return jwt;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
netmd_error netmd_prepare_packets(unsigned char* data, size_t data_lenght,
                                  netmd_track_packets **packets,
                                  size_t *packet_count,
                                  unsigned char *key_encryption_key)
{
    size_t position = 0;
    size_t chunksize = 0xffffffffU;
    netmd_track_packets *last = NULL;
    netmd_track_packets *next = NULL;

    gcry_cipher_hd_t key_handle;
    gcry_cipher_hd_t data_handle;
    unsigned char iv[8] = { 0 };
    unsigned char rand[8] = { 0 };

    netmd_error error = NETMD_NO_ERROR;


    gcry_cipher_open(&key_handle, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
    gcry_cipher_open(&data_handle, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
    gcry_cipher_setkey(key_handle, key_encryption_key, 8);


    /* generate initial iv */
    gcry_create_nonce(iv, sizeof(iv));

    *packet_count = 0;
    while (position < data_lenght) {
        if ((data_lenght - position) < chunksize) {
            /* limit chunksize for last packet */
            chunksize = data_lenght - position;
        }

        if ((chunksize % 8) != 0) {
            chunksize = chunksize + 8 - (chunksize % 8);
        }

        /* alloc memory */
        next = malloc(sizeof(netmd_track_packets));
        next->length = chunksize;
        next->data = malloc(next->length);
        memset(next->data, 0, next->length);
        next->iv = malloc(8);
        next->key = malloc(8);
        next->next = NULL;

        /* linked list */
        if (last != NULL) {
            last->next = next;
        }
        else {
            *packets = next;
        }

        /* generate key */
        gcry_randomize(rand, sizeof(rand), GCRY_STRONG_RANDOM);
        gcry_cipher_decrypt(key_handle, next->key, 8, rand, sizeof(rand));

        /* crypt data */
        memcpy(next->iv, iv, 8);
        gcry_cipher_setiv(data_handle, iv, 8);
        gcry_cipher_setkey(data_handle, rand, sizeof(rand));
        gcry_cipher_encrypt(data_handle, next->data, chunksize, data + position, chunksize);
        memcpy(iv, data + position - 8, 8);

        /* next packet */
        position = position + chunksize;
        (*packet_count)++;
        last = next;
    }

    gcry_cipher_close(key_handle);
    gcry_cipher_close(data_handle);

    return error;
}
Exemplo n.º 26
0
static gboolean
gcr_secret_exchange_default_encrypt_transport_data (GcrSecretExchange *exchange,
                                                    GckAllocator allocator,
                                                    const guchar *plain_text,
                                                    gsize n_plain_text,
                                                    guchar **iv,
                                                    gsize *n_iv,
                                                    guchar **cipher_text,
                                                    gsize *n_cipher_text)
{
	GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
	gcry_cipher_hd_t cih;
	gcry_error_t gcry;
	guchar *padded;
	gsize n_result;
	guchar *result;
	gsize pos;

	g_return_val_if_fail (data != NULL, FALSE);
	g_return_val_if_fail (data->key != NULL, FALSE);

	gcry = gcry_cipher_open (&cih, EXCHANGE_1_CIPHER_ALGO, EXCHANGE_1_CIPHER_MODE, 0);
	if (gcry != 0) {
		g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gcry));
		g_free (iv);
		return FALSE;
	}

	*iv = (allocator) (NULL, EXCHANGE_1_IV_LENGTH);
	g_return_val_if_fail (*iv != NULL, FALSE);
	gcry_create_nonce (*iv, EXCHANGE_1_IV_LENGTH);
	*n_iv = EXCHANGE_1_IV_LENGTH;

	/* 16 = 128 bits */
	gcry = gcry_cipher_setkey (cih, data->key, EXCHANGE_1_KEY_LENGTH);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* 16 = 128 bits */
	gcry = gcry_cipher_setiv (cih, *iv, EXCHANGE_1_IV_LENGTH);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* Pad the text properly */
	if (!egg_padding_pkcs7_pad (egg_secure_realloc, 16, plain_text, n_plain_text,
	                            (gpointer*)&padded, &n_result))
		g_return_val_if_reached (FALSE);
	result = (allocator) (NULL, n_result);
	g_return_val_if_fail (result != NULL, FALSE);

	for (pos = 0; pos < n_result; pos += 16) {
		gcry = gcry_cipher_encrypt (cih, result + pos, 16, padded + pos, 16);
		g_return_val_if_fail (gcry == 0, FALSE);
	}

	gcry_cipher_close (cih);

	egg_secure_clear (padded, n_result);
	egg_secure_free (padded);

	*cipher_text = result;
	*n_cipher_text = n_result;
	return TRUE;
}
Exemplo n.º 27
0
Gc_rc
gc_nonce (char *data, size_t datalen)
{
    gcry_create_nonce ((unsigned char *) data, datalen);
    return GC_OK;
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
void *
handle_client(void * arg)
{
  struct thread_data_t * datum = (struct thread_data_t *)(arg);
  /* Fetch the ID from the argument */
  #ifndef NDEBUG
  fprintf(stderr, "[thread %lu] INFO: worker started\n", datum->id);
  #endif

  /* Worker thread signal handling is unique */
  sigaction(SIGUSR1, datum->signal_action, NULL);
  sigaction(SIGUSR2, datum->signal_action, NULL);

  /* As long as possible, grab up whatever connection is available */
  while (!session_data.caught_signal && !datum->caught_signal) {
    /* Ensure only one worker accepts the next client */
    gcry_pthread_mutex_lock((void **)(&session_data.accept_mutex));
    datum->sock = accept(session_data.sock,
                         (struct sockaddr *)(&datum->remote_addr),
                         &datum->remote_addr_len);
    gcry_pthread_mutex_unlock((void **)(&session_data.accept_mutex));
    if (datum->sock >= 0) {
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker connected to client\n",
              datum->id);
      #endif
      /* Receive a "hello" message from the client */
      recv_message(&datum->buffet, datum->sock);
      /* Decrypt it with the default key */
      decrypt_message(&datum->buffet, keystore.key);
      /* Verify it is an authentication request */
      if (strncmp(datum->buffet.tbuffer,
                  AUTH_CHECK_MSG, sizeof(AUTH_CHECK_MSG))) {
        /* Respond with nonce (misdirection) */
        gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
      } else {
        /* Request a session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before request");
        #endif
        request_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after request");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
        /* Encrypted it using the default key */
        salt_and_pepper((char *)(datum->credentials.key), NULL,
                        &datum->buffet);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
        clear_buffet(&datum->buffet);
        /* Repeatedly poll for message streams */
        while (handle_stream(datum) == BANKING_SUCCESS);
        /* Revoke the session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before revoke");
        #endif
        revoke_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after revoke");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
      }
      /* Cleanup (disconnect) */
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker disconnected from client\n",
              datum->id);
      #endif
      clear_buffet(&datum->buffet);
      destroy_socket(datum->sock);
      datum->sock = BANKING_FAILURE;
    } else {
      fprintf(stderr,
              "[thread %lu] ERROR: worker unable to connect\n",
              datum->id);
    }
  }

  /* Teardown */
  handle_interruption(0);
  return NULL;
}
Exemplo n.º 30
0
/*! \brief Handle a message stream from a client */
int
handle_stream(struct thread_data_t * datum) {
  int i;
  handle_t hdl;
  char msg[MAX_COMMAND_LENGTH], * args;

  /* The initial message is always an authentication request */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  if (strncmp(datum->buffet.tbuffer,
              AUTH_CHECK_MSG, sizeof(AUTH_CHECK_MSG))) {
    #ifndef NDEBUG
    fprintf(stderr,
            "[thread %lu] INFO: malformed authentication message\n",
            datum->id);
    #endif
    /* Respond with a "mumble" (nonce) */
    gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
    encrypt_message(&datum->buffet, datum->credentials.key);
    send_message(&datum->buffet, datum->sock);
    return BANKING_FAILURE;
  }
  /* Turn around the buffer and toss it back */
  for (i = 0; i < MAX_COMMAND_LENGTH; ++i) {
    datum->buffet.pbuffer[i] =
     datum->buffet.tbuffer[MAX_COMMAND_LENGTH - 1 - i];
  }
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);
  clear_buffet(&datum->buffet);
  #ifndef NDEBUG
  fprintf(stderr,
          "[thread %lu] INFO: authentication successful\n",
          datum->id);
  #endif

  /* Read the actual command */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  /* Copy the command into a buffer so more can be received */
  strncpy(msg, datum->buffet.tbuffer, MAX_COMMAND_LENGTH);
  #ifndef NDEBUG
  /* Local echo for all received messages */
  fprintf(stderr,
          "[thread %lu] INFO: worker received message:\n",
          datum->id);
  hexdump(stderr, (unsigned char *)(msg), MAX_COMMAND_LENGTH);
  #endif
  
  /* Disconnect from any client that issues malformed commands */
  if (fetch_handle(msg, &hdl, &args)) {
    /* Respond with a "mumble" (nonce) */
    gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
    encrypt_message(&datum->buffet, datum->credentials.key);
    send_message(&datum->buffet, datum->sock);
    clear_buffet(&datum->buffet);
    return BANKING_FAILURE;
  }
  /* We are signaled by failed handlers */
  datum->caught_signal = hdl(datum, args);
  clear_buffet(&datum->buffet);

  return BANKING_SUCCESS;
}