Пример #1
0
int
secure_decrypt_data (const char *buffer, int length_buffer,
                     int hash_algo, int cipher, const char *passphrase,
                     char **decrypted, int *length_decrypted)
{
    int rc, length_hash, length_key, hd_md_opened, hd_cipher_opened;
    gcry_md_hd_t *hd_md;
    gcry_cipher_hd_t *hd_cipher;
    unsigned char *ptr_hash, *key, *decrypted_hash_data;

    rc = -1;

    /* check length of buffer */
    length_hash = gcry_md_get_algo_dlen (hash_algo);
    if (length_buffer <= SALT_SIZE + length_hash)
        return -2;

    hd_md = NULL;
    hd_md_opened = 0;
    hd_cipher = NULL;
    hd_cipher_opened = 0;
    key = NULL;
    decrypted_hash_data = NULL;

    hd_md = malloc (sizeof (gcry_md_hd_t));
    if (!hd_md)
        return rc;
    hd_cipher = malloc (sizeof (gcry_cipher_hd_t));
    if (!hd_cipher)
    {
        free (hd_md);
        return rc;
    }

    /* derive a key from the passphrase */
    length_key = gcry_cipher_get_algo_keylen (cipher);
    key = malloc (length_key);
    if (!key)
        goto decend;
    if (!secure_derive_key (buffer, passphrase, key, length_key))
    {
        rc = -3;
        goto decend;
    }

    /* decrypt hash + data */
    decrypted_hash_data = malloc (length_buffer - SALT_SIZE);
    if (!decrypted_hash_data)
        goto decend;
    if (gcry_cipher_open (hd_cipher, cipher, GCRY_CIPHER_MODE_CFB, 0) != 0)
    {
        rc = -4;
        goto decend;
    }
    hd_cipher_opened = 1;
    if (gcry_cipher_setkey (*hd_cipher, key, length_key) != 0)
    {
        rc = -5;
        goto decend;
    }
    if (gcry_cipher_decrypt (*hd_cipher,
                             decrypted_hash_data, length_buffer - SALT_SIZE,
                             buffer + SALT_SIZE, length_buffer - SALT_SIZE) != 0)
    {
        rc = -6;
        goto decend;
    }

    /* check if hash is OK for decrypted data */
    if (gcry_md_open (hd_md, hash_algo, 0) != 0)
    {
        rc = -7;
        goto decend;
    }
    hd_md_opened = 1;
    gcry_md_write (*hd_md, decrypted_hash_data + length_hash,
                   length_buffer - SALT_SIZE - length_hash);
    ptr_hash = gcry_md_read (*hd_md, hash_algo);
    if (!ptr_hash)
    {
        rc = -7;
        goto decend;
    }
    if (memcmp (ptr_hash, decrypted_hash_data, length_hash) != 0)
    {
        rc = -8;
        goto decend;
    }

    /* return the decrypted data */
    *length_decrypted = length_buffer - SALT_SIZE - length_hash;
    *decrypted = malloc (*length_decrypted);
    if (!*decrypted)
        goto decend;

    memcpy (*decrypted, decrypted_hash_data + length_hash, *length_decrypted);

    rc = 0;

decend:
    if (hd_md)
    {
        if (hd_md_opened)
            gcry_md_close (*hd_md);
        free (hd_md);
    }
    if (hd_cipher)
    {
        if (hd_cipher_opened)
            gcry_cipher_close (*hd_cipher);
        free (hd_cipher);
    }
    if (key)
        free (key);
    if (decrypted_hash_data)
        free (decrypted_hash_data);

    return rc;
}
Пример #2
0
static gboolean
gcr_secret_exchange_default_decrypt_transport_data (GcrSecretExchange *exchange,
                                                    GckAllocator allocator,
                                                    const guchar *cipher_text,
                                                    gsize n_cipher_text,
                                                    const guchar *iv,
                                                    gsize n_iv,
                                                    guchar **plain_text,
                                                    gsize *n_plain_text)
{
	GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
	guchar* padded;
	guchar* result;
	gsize n_result;
	gsize pos;
	gcry_cipher_hd_t cih;
	gcry_error_t gcry;

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

	if (iv == NULL || n_iv != EXCHANGE_1_IV_LENGTH) {
		g_message ("secret-exchange: invalid or missing iv");
		return FALSE;
	}

	if (n_cipher_text % 16 != 0) {
		g_message ("secret-message: invalid length for cipher text");
		return 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));
		return FALSE;
	}

	/* 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, n_iv);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* Allocate memory for the result */
	padded = (allocator) (NULL, n_cipher_text);
	g_return_val_if_fail (padded != NULL, FALSE);

	for (pos = 0; pos < n_cipher_text; pos += 16) {
		gcry = gcry_cipher_decrypt (cih, padded + pos, 16, (guchar *)cipher_text + pos, 16);
		g_return_val_if_fail (gcry == 0, FALSE);
	}

	gcry_cipher_close (cih);

	if (!egg_padding_pkcs7_unpad (allocator, 16, padded, n_cipher_text,
	                              (gpointer*)&result, &n_result))
		result = NULL;

	/* Free the padded text */
	(allocator) (padded, 0);

	*plain_text = result;
	*n_plain_text = n_result;
	return TRUE;
}
Пример #3
0
/* Accept an OTR Data Message in datamsg.  Decrypt it and put the
 * plaintext into *plaintextp, and any TLVs into tlvsp.  Put any
 * received flags into *flagsp (if non-NULL). */
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
	ConnContext *context, const char *datamsg, unsigned char *flagsp)
{
    char *otrtag, *endtag;
    gcry_error_t err;
    unsigned char *rawmsg = NULL;
    size_t msglen, rawlen, lenp;
    unsigned char *macstart, *macend;
    unsigned char *bufp;
    unsigned int sender_keyid, recipient_keyid;
    gcry_mpi_t sender_next_y = NULL;
    unsigned char ctr[8];
    unsigned int datalen, reveallen;
    unsigned char *data = NULL;
    unsigned char *nul = NULL;
    unsigned char givenmac[20];
    DH_sesskeys *sess;
    unsigned char version;

    *plaintextp = NULL;
    *tlvsp = NULL;
    if (flagsp) *flagsp = 0;
    otrtag = strstr(datamsg, "?OTR:");
    if (!otrtag) {
	goto invval;
    }
    endtag = strchr(otrtag, '.');
    if (endtag) {
	msglen = endtag-otrtag;
    } else {
	msglen = strlen(otrtag);
    }

    /* Base64-decode the message */
    rawlen = ((msglen-5) / 4) * 3;   /* maximum possible */
    rawmsg = malloc(rawlen);
    if (!rawmsg && rawlen > 0) {
	err = gcry_error(GPG_ERR_ENOMEM);
	goto err;
    }
    rawlen = otrl_base64_decode(rawmsg, otrtag+5, msglen-5);  /* actual size */

    bufp = rawmsg;
    lenp = rawlen;

    macstart = bufp;
    require_len(3);
    if (memcmp(bufp, "\x00\x01\x03", 3) && memcmp(bufp, "\x00\x02\x03", 3)) {
	/* Invalid header */
	goto invval;
    }
    version = bufp[1];
    bufp += 3; lenp -= 3;

    if (version == 2) {
	require_len(1);
	if (flagsp) *flagsp = bufp[0];
	bufp += 1; lenp -= 1;
    }
    read_int(sender_keyid);
    read_int(recipient_keyid);
    read_mpi(sender_next_y);
    require_len(8);
    memmove(ctr, bufp, 8);
    bufp += 8; lenp -= 8;
    read_int(datalen);
    require_len(datalen);
    data = malloc(datalen+1);
    if (!data) {
	err = gcry_error(GPG_ERR_ENOMEM);
	goto err;
    }
    memmove(data, bufp, datalen);
    data[datalen] = '\0';
    bufp += datalen; lenp -= datalen;
    macend = bufp;
    require_len(20);
    memmove(givenmac, bufp, 20);
    bufp += 20; lenp -= 20;
    read_int(reveallen);
    require_len(reveallen);
    /* Just skip over the revealed MAC keys, which we don't need.  They
     * were published for deniability of transcripts. */
    bufp += reveallen; lenp -= reveallen;

    /* That should be everything */
    if (lenp != 0) goto invval;

    /* We don't take any action on this message (especially rotating
     * keys) until we've verified the MAC on this message.  To that end,
     * we need to know which keys this message is claiming to use. */
    if (context->their_keyid == 0 ||
	    (sender_keyid != context->their_keyid &&
		sender_keyid != context->their_keyid - 1) ||
	    (recipient_keyid != context->our_keyid &&
	     recipient_keyid != context->our_keyid - 1) ||
	    sender_keyid == 0 || recipient_keyid == 0) {
	goto conflict;
    }

    if (sender_keyid == context->their_keyid - 1 &&
	    context->their_old_y == NULL) {
	goto conflict;
    }

    /* These are the session keys this message is claiming to use. */
    sess = &(context->sesskeys
	    [context->our_keyid - recipient_keyid]
	    [context->their_keyid - sender_keyid]);

    gcry_md_reset(sess->rcvmac);
    gcry_md_write(sess->rcvmac, macstart, macend-macstart);
    if (memcmp(givenmac, gcry_md_read(sess->rcvmac, GCRY_MD_SHA1), 20)) {
	/* The MACs didn't match! */
	goto conflict;
    }
    sess->rcvmacused = 1;

    /* Check to see that the counter is increasing; i.e. that this isn't
     * a replay. */
    if (otrl_dh_cmpctr(ctr, sess->rcvctr) <= 0) {
	goto conflict;
    }

    /* Decrypt the message */
    memmove(sess->rcvctr, ctr, 8);
    err = gcry_cipher_reset(sess->rcvenc);
    if (err) goto err;
    err = gcry_cipher_setctr(sess->rcvenc, sess->rcvctr, 16);
    if (err) goto err;
    err = gcry_cipher_decrypt(sess->rcvenc, data, datalen, NULL, 0);
    if (err) goto err;

    /* See if either set of keys needs rotating */

    if (recipient_keyid == context->our_keyid) {
	/* They're using our most recent key, so generate a new one */
	err = rotate_dh_keys(context);
	if (err) goto err;
    }

    if (sender_keyid == context->their_keyid) {
	/* They've sent us a new public key */
	err = rotate_y_keys(context, sender_next_y);
	if (err) goto err;
    }

    gcry_mpi_release(sender_next_y);
    *plaintextp = (char *)data;

    /* See if there are TLVs */
    nul = data;
    while (nul < data+datalen && *nul) ++nul;
    /* If we stopped before the end, skip the NUL we stopped at */
    if (nul < data+datalen) ++nul;
    *tlvsp = otrl_tlv_parse(nul, (data+datalen)-nul);

    free(rawmsg);
    return gcry_error(GPG_ERR_NO_ERROR);

invval:
    err = gcry_error(GPG_ERR_INV_VALUE);
    goto err;
conflict:
    err = gcry_error(GPG_ERR_CONFLICT);
    goto err;
err:
    gcry_mpi_release(sender_next_y);
    free(data);
    free(rawmsg);
    return err;
}
Пример #4
0
int elektraCryptoGcryDecrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
{
	kdb_octet_t * value = (kdb_octet_t *)keyValue (k);
	const size_t valueLen = keyGetValueSize (k);

	kdb_octet_t * output;
	kdb_octet_t cipherBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE];
	kdb_octet_t contentBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE];
	kdb_unsigned_long_t written = 0;
	gcry_error_t gcry_err;

	// initialize crypto header data
	kdb_unsigned_long_t contentLen = 0;
	kdb_octet_t flags = ELEKTRA_CRYPTO_FLAG_NONE;

	// check if key has been encrypted in the first place
	const Key * metaEncrypted = keyGetMeta (k, ELEKTRA_CRYPTO_META_ENCRYPT);
	if (metaEncrypted == NULL || strlen (keyValue (metaEncrypted)) == 0)
	{
		// nothing to do
		return 1;
	}

	// plausibility check
	if (valueLen % ELEKTRA_CRYPTO_GCRY_BLOCKSIZE != 0)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "value length is not a multiple of the block size");
		return (-1);
	}

	// prepare buffer for plain text output
	output = elektraMalloc (valueLen);
	if (output == NULL)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return (-1);
	}

	// decrypt the header (1st block)
	memcpy (cipherBuffer, value, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	gcry_err = gcry_cipher_decrypt (*handle, contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Decryption failed because: %s", gcry_strerror (gcry_err));
		elektraFree (output);
		return (-1);
	}

	// restore the header data
	memcpy (&flags, contentBuffer, sizeof (flags));
	memcpy (&contentLen, contentBuffer + sizeof (flags), sizeof (contentLen));

	// decrypt content block by block
	// (i = start of the current block and the 1st block has already been consumed)
	for (kdb_unsigned_long_t i = ELEKTRA_CRYPTO_GCRY_BLOCKSIZE; i < valueLen; i += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE)
	{
		memcpy (cipherBuffer, (value + i), ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		gcry_err = gcry_cipher_decrypt (*handle, contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, cipherBuffer,
						ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		if (gcry_err != 0)
		{
			ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Decryption failed because: %s",
					    gcry_strerror (gcry_err));
			elektraFree (output);
			return (-1);
		}
		memcpy ((output + i - ELEKTRA_CRYPTO_GCRY_BLOCKSIZE), contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		written += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
	}

	if (written < contentLen)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Content was shorter than described in the header");
		elektraFree (output);
		return (-1);
	}

	// write back the cipher text to the key
	if ((flags & ELEKTRA_CRYPTO_FLAG_STRING) == ELEKTRA_CRYPTO_FLAG_STRING)
	{
		keySetString (k, (const char *)output);
	}
	else if ((flags & ELEKTRA_CRYPTO_FLAG_NULL) == ELEKTRA_CRYPTO_FLAG_NULL || contentLen == 0)
	{
		keySetBinary (k, NULL, 0);
	}
	else
	{
		keySetBinary (k, output, contentLen);
	}

	elektraFree (output);
	return 1;
}
Пример #5
0
/* Try to find an item in the cache.  Note that we currently don't
   make use of CACHE_MODE except for CACHE_MODE_NONCE and
   CACHE_MODE_USER.  */
char *
agent_get_cache (const char *key, cache_mode_t cache_mode)
{
  gpg_error_t err;
  ITEM r;
  char *value = NULL;
  int res;
  int last_stored = 0;

  if (cache_mode == CACHE_MODE_IGNORE)
    return NULL;

  if (!key)
    {
      key = last_stored_cache_key;
      if (!key)
        return NULL;
      last_stored = 1;
    }


  if (DBG_CACHE)
    log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
               key, cache_mode,
               last_stored? " (stored cache key)":"");
  housekeeping ();

  for (r=thecache; r; r = r->next)
    {
      if (r->pw
          && ((cache_mode != CACHE_MODE_USER
               && cache_mode != CACHE_MODE_NONCE)
              || r->cache_mode == cache_mode)
          && !strcmp (r->key, key))
        {
          /* Note: To avoid races KEY may not be accessed anymore below.  */
          r->accessed = gnupg_get_time ();
          if (DBG_CACHE)
            log_debug ("... hit\n");
          if (r->pw->totallen < 32)
            err = gpg_error (GPG_ERR_INV_LENGTH);
          else if ((err = init_encryption ()))
            ;
          else if (!(value = xtrymalloc_secure (r->pw->totallen - 8)))
            err = gpg_error_from_syserror ();
          else
            {
              res = npth_mutex_lock (&encryption_lock);
              if (res)
                log_fatal ("failed to acquire cache encryption mutex: %s\n",
			   strerror (res));
              err = gcry_cipher_decrypt (encryption_handle,
                                         value, r->pw->totallen - 8,
                                         r->pw->data, r->pw->totallen);
              res = npth_mutex_unlock (&encryption_lock);
              if (res)
                log_fatal ("failed to release cache encryption mutex: %s\n",
			   strerror (res));
            }
          if (err)
            {
              xfree (value);
              value = NULL;
              log_error ("retrieving cache entry '%s' failed: %s\n",
                         key, gpg_strerror (err));
            }
          return value;
        }
    }
  if (DBG_CACHE)
    log_debug ("... miss\n");

  return NULL;
}
Пример #6
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 */
}
Пример #7
0
static int
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
{
  decode_filter_ctx_t fc = opaque;
  size_t size = *ret_len;
  size_t n;
  int c, rc = 0;


  if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
    {
      *ret_len = 0;
      rc = -1;
    }
  else if ( control == IOBUFCTRL_UNDERFLOW )
    {
      log_assert (a);

      if (fc->partial)
        {
          for (n=0; n < size; n++ )
            {
              c = iobuf_get(a);
              if (c == -1)
                {
                  fc->eof_seen = 1; /* Normal EOF. */
                  break;
                }
              buf[n] = c;
            }
        }
      else
        {
          for (n=0; n < size && fc->length; n++, fc->length--)
            {
              c = iobuf_get(a);
              if (c == -1)
                {
                  fc->eof_seen = 3; /* Premature EOF. */
                  break;
                }
              buf[n] = c;
            }
          if (!fc->length)
            fc->eof_seen = 1; /* Normal EOF.  */
        }
      if (n)
        {
          if (fc->cipher_hd)
            gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
        }
      else
        {
          if (!fc->eof_seen)
            fc->eof_seen = 1;
          rc = -1; /* Return EOF. */
        }
      *ret_len = n;
    }
  else if ( control == IOBUFCTRL_FREE )
    {
      release_dfx_context (fc);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      mem2str (buf, "decode_filter", *ret_len);
    }
  return rc;
}
Пример #8
0
int PBE_decrypt_data(const char *object_identifier_id_param, tvbuff_t *encrypted_tvb, asn1_ctx_t *actx, proto_item *item)
{
#ifdef HAVE_LIBGCRYPT
	const char	*encryption_algorithm;
	gcry_cipher_hd_t cipher;
	gcry_error_t	err;
	int		algo;
	int		mode;
	int		ivlen = 0;
	int		keylen = 0;
	int		datalen = 0;
	char		*key = NULL;
	char		*iv = NULL;
	char		*clear_data = NULL;
	tvbuff_t	*clear_tvb = NULL;
	const gchar     *oidname;
	GString		*name;
	proto_tree	*tree;
	char		byte;
	gboolean	decrypt_ok = TRUE;

	if(((password == NULL) || (*password == '\0')) && (try_null_password == FALSE)) {
		/* we are not configured to decrypt */
		return FALSE;
	}

	encryption_algorithm = x509af_get_last_algorithm_id();

	/* these are the only encryption schemes we understand for now */
	if(!strcmp(encryption_algorithm, PKCS12_PBE_3DES_SHA1_OID)) {
		ivlen = 8;
		keylen = 24;
		algo = GCRY_CIPHER_3DES;
		mode = GCRY_CIPHER_MODE_CBC;
	} else if(!strcmp(encryption_algorithm, PKCS12_PBE_ARCFOUR_SHA1_OID)) {
		ivlen = 0;
		keylen = 16;
		algo = GCRY_CIPHER_ARCFOUR;
		mode = GCRY_CIPHER_MODE_NONE;
	} else if(!strcmp(encryption_algorithm, PKCS12_PBE_RC2_40_SHA1_OID)) {
		ivlen = 8;
		keylen = 5;
		algo = GCRY_CIPHER_RFC2268_40;
		mode = GCRY_CIPHER_MODE_CBC;
	} else {
		/* we don't know how to decrypt this */

		proto_item_append_text(item, " [Unsupported encryption algorithm]");
		return FALSE;
	}

	if((iteration_count == 0) || (salt == NULL)) {
		proto_item_append_text(item, " [Insufficient parameters]");
		return FALSE;
	}

	/* allocate buffers */
	key = ep_alloc(keylen);

	if(!generate_key_or_iv(1 /*LEY */, salt, iteration_count, password, keylen, key))
		return FALSE;

	if(ivlen) {

		iv = ep_alloc(ivlen);

		if(!generate_key_or_iv(2 /* IV */, salt, iteration_count, password, ivlen, iv))
			return FALSE;
	}

	/* now try an internal function */
	err = gcry_cipher_open(&cipher, algo, mode, 0);
	if (gcry_err_code (err))
			return FALSE;

	err = gcry_cipher_setkey (cipher, key, keylen);
	if (gcry_err_code (err)) {
			gcry_cipher_close (cipher);
			return FALSE;
	}

	if(ivlen) {
		  err = gcry_cipher_setiv (cipher, iv, ivlen);
		  if (gcry_err_code (err)) {
			  gcry_cipher_close (cipher);
			  return FALSE;
		  }
	}

	datalen = tvb_length(encrypted_tvb);
	clear_data = g_malloc(datalen);

	err = gcry_cipher_decrypt (cipher, clear_data, datalen, tvb_get_ephemeral_string(encrypted_tvb, 0, datalen), datalen);
	if (gcry_err_code (err)) {

		proto_item_append_text(item, " [Failed to decrypt with password preference]");

		gcry_cipher_close (cipher);
		g_free(clear_data);
		return FALSE;
	}

	gcry_cipher_close (cipher);

	/* We don't know if we have successfully decrypted the data or not so we:
		a) check the trailing bytes
		b) see if we start with a sequence or a set (is this too constraining?
		*/

	/* first the trailing bytes */
	byte = clear_data[datalen-1];
	if(byte <= 0x08) {
		int i;

		for(i = (int)byte; i > 0 ; i--) {
			if(clear_data[datalen - i] != byte) {
				decrypt_ok = FALSE;
				break;
			}
		}
	} else {
		/* XXX: is this a failure? */
	}

	/* we assume the result is ASN.1 - check it is a SET or SEQUENCE */
	byte = clear_data[0];
	if((byte != 0x30) && (byte != 0x31)) { /* do we need more here? OCTET STRING? */
		decrypt_ok = FALSE;
	}

	if(!decrypt_ok) {
		g_free(clear_data);
		proto_item_append_text(item, " [Failed to decrypt with supplied password]");

		return FALSE;
	}

	proto_item_append_text(item, " [Decrypted successfully]");

	tree = proto_item_add_subtree(item, ett_decrypted_pbe);

	/* OK - so now clear_data contains the decrypted data */

	clear_tvb = tvb_new_child_real_data(encrypted_tvb,(const guint8 *)clear_data, datalen, datalen);
	tvb_set_free_cb(clear_tvb, g_free);

	name = g_string_new("");
	oidname = oid_resolved_from_string(object_identifier_id_param);
	g_string_printf(name, "Decrypted %s", oidname ? oidname : object_identifier_id_param);

	/* add it as a new source */
	add_new_data_source(actx->pinfo, clear_tvb, name->str);

	g_string_free(name, TRUE);

	/* now try and decode it */
	call_ber_oid_callback(object_identifier_id_param, clear_tvb, 0, actx->pinfo, tree);

	return TRUE;
#else
	/* we cannot decrypt */
	return FALSE;

#endif
}
Пример #9
0
static SecretValue *
service_decode_aes_secret (SecretSession *session,
                           gconstpointer param,
                           gsize n_param,
                           gconstpointer value,
                           gsize n_value,
                           const gchar *content_type)
{
	gcry_cipher_hd_t cih;
	gsize n_padded;
	gcry_error_t gcry;
	guchar *padded;
	gsize pos;

	if (n_param != 16) {
		g_message ("received an encrypted secret structure with invalid parameter");
		return NULL;
	}

	if (n_value == 0 || n_value % 16 != 0) {
		g_message ("received an encrypted secret structure with bad secret length");
		return NULL;
	}

	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 NULL;
	}

#if 0
	g_printerr ("    lib iv:  %s\n", egg_hex_encode (param, n_param));
#endif

	gcry = gcry_cipher_setiv (cih, param, n_param);
	g_return_val_if_fail (gcry == 0, NULL);

#if 0
	g_printerr ("   lib key:  %s\n", egg_hex_encode (session->key, session->n_key));
#endif

	gcry = gcry_cipher_setkey (cih, session->key, session->n_key);
	g_return_val_if_fail (gcry == 0, NULL);

	/* Copy the memory buffer */
	n_padded = n_value;
	padded = egg_secure_alloc (n_padded);
	memcpy (padded, value, n_padded);

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

	gcry_cipher_close (cih);

	/* Unpad the resulting value */
	if (!pkcs7_unpad_bytes_in_place (padded, &n_padded)) {
		egg_secure_clear (padded, n_padded);
		egg_secure_free (padded);
		g_message ("received an invalid or unencryptable secret");
		return FALSE;
	}

	return secret_value_new_full ((gchar *)padded, n_padded, content_type, egg_secure_free);
}
Пример #10
0
static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
    void *out, unsigned long len) {
  gcry_cipher_decrypt(cipher->key[2], out, len, in, len);
  gcry_cipher_encrypt(cipher->key[1], in, len, out, len);
  gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
}
Пример #11
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[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');
}
Пример #12
0
static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
    unsigned long len) {
  gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
}
static
int
mode_decrypt(File filein, File fileout)
{
	xb_rcrypt_t		*xbcrypt_file = NULL;
	void			*chunkbuf = NULL;
	size_t			chunksize;
	size_t			originalsize;
	void			*ivbuf = NULL;
	size_t			ivsize;
	void			*decryptbuf = NULL;
	size_t			decryptbufsize = 0;
	ulonglong		ttlchunksread = 0;
	ulonglong		ttlbytesread = 0;
	xb_rcrypt_result_t	result;
	gcry_cipher_hd_t	cipher_handle;
	gcry_error_t		gcry_error;

	if (encrypt_algo != GCRY_CIPHER_NONE) {
		gcry_error = gcry_cipher_open(&cipher_handle,
					      encrypt_algo,
					      encrypt_mode, 0);
		if (gcry_error) {
			msg("%s:decrypt: unable to open libgcrypt"
			    " cipher - %s : %s\n", my_progname,
			    gcry_strsource(gcry_error),
			    gcry_strerror(gcry_error));
			return 1;
		}

		gcry_error = gcry_cipher_setkey(cipher_handle,
						opt_encrypt_key,
						encrypt_key_len);
		if (gcry_error) {
			msg("%s:decrypt: unable to set libgcrypt cipher"
			    "key - %s : %s\n", my_progname,
			    gcry_strsource(gcry_error),
			    gcry_strerror(gcry_error));
			goto err;
		}
	}

	/* Initialize the xb_crypt format reader */
	xbcrypt_file = xb_crypt_read_open(&filein, my_xb_crypt_read_callback);
	if (xbcrypt_file == NULL) {
		msg("%s:decrypt: xb_crypt_read_open() failed.\n", my_progname);
		goto err;
	}

	/* Walk the encrypted chunks, decrypting them and writing out */
	while ((result = xb_crypt_read_chunk(xbcrypt_file, &chunkbuf,
					     &originalsize, &chunksize,
					     &ivbuf, &ivsize))
		== XB_CRYPT_READ_CHUNK) {

		if (encrypt_algo != GCRY_CIPHER_NONE) {
			gcry_error = gcry_cipher_reset(cipher_handle);
			if (gcry_error) {
				msg("%s:decrypt: unable to reset libgcrypt"
				    " cipher - %s : %s\n", my_progname,
				    gcry_strsource(gcry_error),
				    gcry_strerror(gcry_error));
				goto err;
			}

			if (ivsize) {
				gcry_error = gcry_cipher_setiv(cipher_handle,
							       ivbuf,
							       ivsize);
			} else {
				gcry_error = gcry_cipher_setiv(cipher_handle,
							       v1_encrypt_iv,
							       encrypt_iv_len);
			}
			if (gcry_error) {
				msg("%s:decrypt: unable to set cipher iv - "
				    "%s : %s\n", my_progname,
				    gcry_strsource(gcry_error),
				    gcry_strerror(gcry_error));
				continue;
			}

			if (decryptbufsize < originalsize) {
				if (decryptbufsize) {
					decryptbuf = my_realloc(decryptbuf,
								originalsize,
								MYF(MY_WME));
					decryptbufsize = originalsize;
				} else {
					decryptbuf = my_malloc(originalsize,
							       MYF(MY_WME));
					decryptbufsize = originalsize;
				}
			}

			/* Try to decrypt it */
			gcry_error = gcry_cipher_decrypt(cipher_handle,
							 decryptbuf,
							 originalsize,
							 chunkbuf,
							 chunksize);
			if (gcry_error) {
				msg("%s:decrypt: unable to decrypt chunk - "
				    "%s : %s\n", my_progname,
				    gcry_strsource(gcry_error),
				    gcry_strerror(gcry_error));
				gcry_cipher_close(cipher_handle);
					goto err;
			}

		} else {
			decryptbuf = chunkbuf;
		}

		/* Write it out */
		if (my_write(fileout, decryptbuf, originalsize,
			     MYF(MY_WME | MY_NABP))) {
			msg("%s:decrypt: unable to write output chunk.\n",
			    my_progname);
			goto err;
		}
		ttlchunksread++;
		ttlbytesread += chunksize;
		if (opt_verbose)
			msg("%s:decrypt: %llu chunks read, %llu bytes read\n.",
		    	    my_progname, ttlchunksread, ttlbytesread);
	}

	xb_crypt_read_close(xbcrypt_file);

	if (encrypt_algo != GCRY_CIPHER_NONE)
		gcry_cipher_close(cipher_handle);

	if (decryptbuf && decryptbufsize)
		my_free(decryptbuf);

	if (opt_verbose)
		msg("\n%s:decrypt: done\n", my_progname);

	return 0;
err:
	if (xbcrypt_file)
		xb_crypt_read_close(xbcrypt_file);

	if (encrypt_algo != GCRY_CIPHER_NONE)
		gcry_cipher_close(cipher_handle);

	if (decryptbuf && decryptbufsize)
		my_free(decryptbuf);

	return 1;
}
/*
 * decrypts the underlying XSPF playlist.
 * does not *parse* the XSPF playlist.
 */
static gboolean
amzfile_decrypt_blob(gchar *indata, gsize inlen, gchar **outdata)
{
	gcry_cipher_hd_t hd;
	gcry_error_t err;
	guchar *unpackdata, *decryptdata;
	gsize unpacklen;
	gint i;

	unpackdata = g_base64_decode(indata, &unpacklen);
	if (unpackdata == NULL)
	{
		g_print("g_base64_decode failed\n");
		return FALSE;
	}

	if (unpacklen % 8)
		unpacklen -= (unpacklen % 8);

	decryptdata = g_malloc0(unpacklen + 1);

	if ((err = gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0)))
	{
		g_print("unable to initialise gcrypt: %s", gcry_strerror(err));
		g_free(unpackdata);
		g_free(decryptdata);
		return FALSE;
	}

	if ((err = gcry_cipher_setkey(hd, amazon_key, 8)))
	{
		g_print("unable to set key for DES block cipher: %s", gcry_strerror(err));
		gcry_cipher_close(hd);
		g_free(unpackdata);
		g_free(decryptdata);
		return FALSE;
	}

	if ((err = gcry_cipher_setiv(hd, amazon_iv, 8)))
	{
		g_print("unable to set initialisation vector for DES block cipher: %s", gcry_strerror(err));
		gcry_cipher_close(hd);
		g_free(unpackdata);
		g_free(decryptdata);
		return FALSE;
	}

	if ((err = gcry_cipher_decrypt(hd, decryptdata, unpacklen, unpackdata, unpacklen)))
	{
		g_print("unable to decrypt embedded DES-encrypted XSPF document: %s", gcry_strerror(err));
		gcry_cipher_close(hd);
		g_free(unpackdata);
		g_free(decryptdata);
		return FALSE;
	}

	g_free(unpackdata);
	gcry_cipher_close(hd);

	/* remove padding from XSPF document */
	for (i = unpacklen; i > 0; i--)
	{
		if (decryptdata[i - 1] == '\n' || decryptdata[i] == '\r' || decryptdata[i - 1] >= ' ')
			break;
	}
	decryptdata[i] = 0;

	*outdata = (char *) decryptdata;
	return TRUE;
}
Пример #15
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);
}
Пример #16
0
static void
check_aes128_cbc_cts_cipher (void)
{
  char key[128 / 8] = "chicken teriyaki";
  char plaintext[] =
    "I would like the General Gau's Chicken, please, and wonton soup.";
  struct tv
  {
    char out[MAX_DATA_LEN];
    int inlen;
  } tv[] =
    {
      { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
	"\x97",
	17 },
      { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
	"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
	31 },
      { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
	"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
	32 },
      { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
	"\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
	"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
	47 },
      { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
	"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
	"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
	48 },
      { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
	"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
	"\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
	"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
	64 },
    };
  gcry_cipher_hd_t hd;
  char out[MAX_DATA_LEN];
  int i;
  gcry_error_t err = 0;

  err = gcry_cipher_open (&hd,
			  GCRY_CIPHER_AES,
			  GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
  if (err)
    {
      fail ("aes-cbc-cts, grcy_open_cipher failed: %s\n", gpg_strerror (err));
      return;
    }

  err = gcry_cipher_setkey (hd, key, 128 / 8);
  if (err)
    {
      fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n",
	    gpg_strerror (err));
      gcry_cipher_close (hd);
      return;
    }

  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    {
      err = gcry_cipher_setiv (hd, NULL, 0);
      if (err)
	{
	  fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

      err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN,
				 plaintext, tv[i].inlen);
      if (err)
	{
	  fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

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

      err = gcry_cipher_setiv (hd, NULL, 0);
      if (err)
	{
	  fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}
      err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0);
      if (err)
	{
	  fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
		gpg_strerror (err));
	  gcry_cipher_close (hd);
	  return;
	}

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

  gcry_cipher_close (hd);
}
Пример #17
0
static void
check (int algo,
       const void *kek, size_t keklen,
       const void *data, size_t datalen,
       const void *expected, size_t expectedlen)
{
  gcry_error_t err;
  gcry_cipher_hd_t hd;
  unsigned char outbuf[32+8];
  size_t outbuflen;

  err = gcry_cipher_open (&hd, algo, GCRY_CIPHER_MODE_AESWRAP, 0);
  if (err)
    {
      fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
      return;
    }

  err = gcry_cipher_setkey (hd, kek, keklen);
  if (err)
    {
      fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
      return;
    }

  outbuflen = datalen + 8;
  if (outbuflen > sizeof outbuf)
    err = gpg_error (GPG_ERR_INTERNAL);
  else
    err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen);
  if (err)
    {
      fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err));
      return;
    }

  if (outbuflen != expectedlen || memcmp (outbuf, expected, expectedlen))
    {
      const unsigned char *s;
      int i;

      fail ("mismatch at encryption!\n");
      fprintf (stderr, "computed: ");
      for (i = 0; i < outbuflen; i++)
	fprintf (stderr, "%02x ", outbuf[i]);
      fprintf (stderr, "\nexpected: ");
      for (s = expected, i = 0; i < expectedlen; s++, i++)
        fprintf (stderr, "%02x ", *s);
      putc ('\n', stderr);
    }


  outbuflen = expectedlen - 8;
  if (outbuflen > sizeof outbuf)
    err = gpg_error (GPG_ERR_INTERNAL);
  else
    err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
  if (err)
    {
      fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err));
      return;
    }

  if (outbuflen != datalen || memcmp (outbuf, data, datalen))
    {
      const unsigned char *s;
      int i;

      fail ("mismatch at decryption!\n");
      fprintf (stderr, "computed: ");
      for (i = 0; i < outbuflen; i++)
	fprintf (stderr, "%02x ", outbuf[i]);
      fprintf (stderr, "\nexpected: ");
      for (s = data, i = 0; i < datalen; s++, i++)
        fprintf (stderr, "%02x ", *s);
      putc ('\n', stderr);
    }

  /* Now the last step again with a key reset. */
  gcry_cipher_reset (hd);

  outbuflen = expectedlen - 8;
  if (outbuflen > sizeof outbuf)
    err = gpg_error (GPG_ERR_INTERNAL);
  else
    err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
  if (err)
    {
      fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err));
      return;
    }

  if (outbuflen != datalen || memcmp (outbuf, data, datalen))
    fail ("mismatch at decryption(2)!\n");

  /* And once ore without a key reset. */
  outbuflen = expectedlen - 8;
  if (outbuflen > sizeof outbuf)
    err = gpg_error (GPG_ERR_INTERNAL);
  else
    err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
  if (err)
    {
      fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err));
      return;
    }

  if (outbuflen != datalen || memcmp (outbuf, data, datalen))
    fail ("mismatch at decryption(3)!\n");

  gcry_cipher_close (hd);
}
Пример #18
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);
    }
}
Пример #19
0
static int
mdc_decode_filter (void *opaque, int control, IOBUF a,
                   byte *buf, size_t *ret_len)
{
  decode_filter_ctx_t dfx = opaque;
  size_t n, size = *ret_len;
  int rc = 0;
  int c;

  /* Note: We need to distinguish between a partial and a fixed length
     packet.  The first is the usual case as created by GPG.  However
     for short messages the format degrades to a fixed length packet
     and other implementations might use fixed length as well.  Only
     looking for the EOF on fixed data works only if the encrypted
     packet is not followed by other data.  This used to be a long
     standing bug which was fixed on 2009-10-02.  */

  if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
    {
      *ret_len = 0;
      rc = -1;
    }
  else if( control == IOBUFCTRL_UNDERFLOW )
    {
      log_assert (a);
      log_assert (size > 44); /* Our code requires at least this size.  */

      /* Get at least 22 bytes and put it ahead in the buffer.  */
      if (dfx->partial)
        {
          for (n=22; n < 44; n++)
            {
              if ( (c = iobuf_get(a)) == -1 )
                break;
              buf[n] = c;
            }
        }
      else
        {
          for (n=22; n < 44 && dfx->length; n++, dfx->length--)
            {
              c = iobuf_get (a);
              if (c == -1)
                break; /* Premature EOF.  */
              buf[n] = c;
            }
        }
      if (n == 44)
        {
          /* We have enough stuff - flush the deferred stuff.  */
          if ( !dfx->defer_filled )  /* First time. */
            {
              memcpy (buf, buf+22, 22);
              n = 22;
	    }
          else
            {
              memcpy (buf, dfx->defer, 22);
	    }
          /* Fill up the buffer. */
          if (dfx->partial)
            {
              for (; n < size; n++ )
                {
                  if ( (c = iobuf_get(a)) == -1 )
                    {
                      dfx->eof_seen = 1; /* Normal EOF. */
                      break;
                    }
                  buf[n] = c;
                }
            }
          else
            {
              for (; n < size && dfx->length; n++, dfx->length--)
                {
                  c = iobuf_get(a);
                  if (c == -1)
                    {
                      dfx->eof_seen = 3; /* Premature EOF. */
                      break;
                    }
                  buf[n] = c;
                }
              if (!dfx->length)
                dfx->eof_seen = 1; /* Normal EOF.  */
            }

          /* Move the trailing 22 bytes back to the defer buffer.  We
             have at least 44 bytes thus a memmove is not needed.  */
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->defer_filled = 1;
	}
      else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
        {
          /* This is bad because it means an incomplete hash. */
          n -= 22;
          memcpy (buf, buf+22, n );
          dfx->eof_seen = 2; /* EOF with incomplete hash.  */
	}
      else  /* EOF seen (i.e. read less than 22 bytes). */
        {
          memcpy (buf, dfx->defer, 22 );
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->eof_seen = 1; /* Normal EOF. */
	}

      if ( n )
        {
          if ( dfx->cipher_hd )
            gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
          if ( dfx->mdc_hash )
            gcry_md_write (dfx->mdc_hash, buf, n);
	}
      else
        {
          log_assert ( dfx->eof_seen );
          rc = -1; /* Return EOF.  */
	}
      *ret_len = n;
    }
  else if ( control == IOBUFCTRL_FREE )
    {
      release_dfx_context (dfx);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      mem2str (buf, "mdc_decode_filter", *ret_len);
    }
  return rc;
}
Пример #20
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);
}
Пример #21
0
/****************
 * Decrypt the data, specified by ED with the key DEK.
 */
int
decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
{
  decode_filter_ctx_t dfx;
  byte *p;
  int rc=0, c, i;
  byte temp[32];
  unsigned blocksize;
  unsigned nprefix;

  dfx = xtrycalloc (1, sizeof *dfx);
  if (!dfx)
    return gpg_error_from_syserror ();
  dfx->refcount = 1;

  if ( opt.verbose && !dek->algo_info_printed )
    {
      if (!openpgp_cipher_test_algo (dek->algo))
        log_info (_("%s encrypted data\n"),
                  openpgp_cipher_algo_name (dek->algo));
      else
        log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
      dek->algo_info_printed = 1;
    }

  {
    char buf[20];

    snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo);
    write_status_text (STATUS_DECRYPTION_INFO, buf);
  }

  if (opt.show_session_key)
    {
      char numbuf[25];
      char *hexbuf;

      snprintf (numbuf, sizeof numbuf, "%d:", dek->algo);
      hexbuf = bin2hex (dek->key, dek->keylen, NULL);
      if (!hexbuf)
        {
          rc = gpg_error_from_syserror ();
          goto leave;
        }
      log_info ("session key: '%s%s'\n", numbuf, hexbuf);
      write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL);
      xfree (hexbuf);
    }

  rc = openpgp_cipher_test_algo (dek->algo);
  if (rc)
    goto leave;
  blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
  if ( !blocksize || blocksize > 16 )
    log_fatal ("unsupported blocksize %u\n", blocksize );
  nprefix = blocksize;
  if ( ed->len && ed->len < (nprefix+2) )
    {
       /* An invalid message.  We can't check that during parsing
          because we may not know the used cipher then.  */
      rc = gpg_error (GPG_ERR_INV_PACKET);
      goto leave;
    }

  if ( ed->mdc_method )
    {
      if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
        BUG ();
      if ( DBG_HASHING )
        gcry_md_debug (dfx->mdc_hash, "checkmdc");
    }

  rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
			    GCRY_CIPHER_MODE_CFB,
			    (GCRY_CIPHER_SECURE
			     | ((ed->mdc_method || dek->algo >= 100)?
				0 : GCRY_CIPHER_ENABLE_SYNC)));
  if (rc)
    {
      /* We should never get an error here cause we already checked
       * that the algorithm is available.  */
      BUG();
    }


  /* log_hexdump( "thekey", dek->key, dek->keylen );*/
  rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
  if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
    {
      log_info(_("WARNING: message was encrypted with"
                 " a weak key in the symmetric cipher.\n"));
      rc=0;
    }
  else if( rc )
    {
      log_error("key setup failed: %s\n", gpg_strerror (rc) );
      goto leave;
    }

  if (!ed->buf)
    {
      log_error(_("problem handling encrypted packet\n"));
      goto leave;
    }

  gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);

  if ( ed->len )
    {
      for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
        {
          if ( (c=iobuf_get(ed->buf)) == -1 )
            break;
          else
            temp[i] = c;
        }
    }
  else
    {
      for (i=0; i < (nprefix+2); i++ )
        if ( (c=iobuf_get(ed->buf)) == -1 )
          break;
        else
          temp[i] = c;
    }

  gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
  gcry_cipher_sync (dfx->cipher_hd);
  p = temp;
  /* log_hexdump( "prefix", temp, nprefix+2 ); */
  if (dek->symmetric
      && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
    {
      rc = gpg_error (GPG_ERR_BAD_KEY);
      goto leave;
    }

  if ( dfx->mdc_hash )
    gcry_md_write (dfx->mdc_hash, temp, nprefix+2);

  dfx->refcount++;
  dfx->partial = ed->is_partial;
  dfx->length = ed->len;
  if ( ed->mdc_method )
    iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
  else
    iobuf_push_filter ( ed->buf, decode_filter, dfx );

  if (opt.unwrap_encryption)
    {
      char *filename;
      estream_t fp;
      rc = get_output_file ("", 0, ed->buf, &filename, &fp);
      if (! rc)
        {
          iobuf_t output = iobuf_esopen (fp, "w", 0);
          armor_filter_context_t *afx = NULL;

          if (opt.armor)
            {
              afx = new_armor_context ();
              push_armor_filter (afx, output);
            }

          iobuf_copy (output, ed->buf);
          if ((rc = iobuf_error (ed->buf)))
            log_error (_("error reading '%s': %s\n"),
                       filename, gpg_strerror (rc));
          else if ((rc = iobuf_error (output)))
            log_error (_("error writing '%s': %s\n"),
                       filename, gpg_strerror (rc));

          iobuf_close (output);
          if (afx)
            release_armor_context (afx);
        }
    }
  else
    proc_packets (ctrl, procctx, ed->buf );

  ed->buf = NULL;
  if (dfx->eof_seen > 1 )
    rc = gpg_error (GPG_ERR_INV_PACKET);
  else if ( ed->mdc_method )
    {
      /* We used to let parse-packet.c handle the MDC packet but this
         turned out to be a problem with compressed packets: With old
         style packets there is no length information available and
         the decompressor uses an implicit end.  However we can't know
         this implicit end beforehand (:-) and thus may feed the
         decompressor with more bytes than actually needed.  It would
         be possible to unread the extra bytes but due to our weird
         iobuf system any unread is non reliable due to filters
         already popped off.  The easy and sane solution is to care
         about the MDC packet only here and never pass it to the
         packet parser.  Fortunatley the OpenPGP spec requires a
         strict format for the MDC packet so that we know that 22
         bytes are appended.  */
      int datalen = gcry_md_get_algo_dlen (ed->mdc_method);

      log_assert (dfx->cipher_hd);
      log_assert (dfx->mdc_hash);
      gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
      gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
      gcry_md_final (dfx->mdc_hash);

      if (   dfx->defer[0] != '\xd3'
          || dfx->defer[1] != '\x14'
          || datalen != 20
          || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen))
        rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
      /* log_printhex("MDC message:", dfx->defer, 22); */
      /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
    }


 leave:
  release_dfx_context (dfx);
  return rc;
}
Пример #22
0
int main(int argc, char **argv)
{
	int ret;
	setlocale(LC_ALL, "");

	if (argc != 3) {
		wprintf(L"Usage: psafe file.psafe3 passphrase");
		exit(EXIT_FAILURE);
	}

	init_crypto(64*1024);

	size_t sz;
	uint8_t *ptr;
	ptr = mapfile_ro(argv[1], &sz);
	if (ptr == NULL)
		err(1, "%s", argv[1]);

	struct psafe3_pro *pro;
	pro = (struct psafe3_pro *)(ptr + 4);
	struct safe_sec *sec;
	sec = gcry_malloc_secure(sizeof(*sec));
	ret = stretch_and_check_pass(argv[2], strlen(argv[2]), pro, sec);
	if (ret != 0) {
		gcry_free(sec);
		wprintf(L"Invalid password.\n");
		exit(1);
	}

	uint8_t *safe;
	size_t safe_size;
	safe_size = sz - (4 + sizeof(*pro) + 48);
	assert(safe_size > 0);
	assert(safe_size % TWOF_BLKSIZE == 0);
	safe = gcry_malloc_secure(safe_size);
	assert(safe != NULL);

	gcry_error_t gerr;
	struct decrypt_ctx ctx;
	if (init_decrypt_ctx(&ctx, pro, sec) < 0)
		gcrypt_fatal(ctx.gerr);

	size_t bcnt;
	bcnt = safe_size / TWOF_BLKSIZE;
	assert(bcnt > 0);
	uint8_t *encp;
	uint8_t *safep;
	encp = ptr + 4 + sizeof(*pro);
	safep = safe;
	while (bcnt--) {
		gerr = gcry_cipher_decrypt(ctx.cipher, safep, TWOF_BLKSIZE, encp, TWOF_BLKSIZE);
		if (gerr != GPG_ERR_NO_ERROR)
			gcrypt_fatal(gerr);
		safep += TWOF_BLKSIZE;
		encp += TWOF_BLKSIZE;
	}

	enum { HDR, DB };
	int state = HDR;
	safep = safe;
	while (safep < safe + safe_size) {
		struct field *fld;
		fld = (struct field *)safep;
		wprintf(L"len=%-3u  type=%02x  ", fld->len, fld->type);
		if (state == DB)
			db_print(stdout, fld);
		else
			hd_print(stdout, fld);
		if (fld->type == 0xff)
			state = DB;
		putwc('\n', stdout);
		if (fld->len)
			gcry_md_write(ctx.hmac, safep + sizeof(*fld), fld->len);
		safep += ((fld->len + 5 + 15) / TWOF_BLKSIZE) * TWOF_BLKSIZE;
	}

	assert(memcmp(ptr + (sz - 48), "PWS3-EOFPWS3-EOF", TWOF_BLKSIZE) == 0);

#define EOL() putwc('\n', stdout)
	EOL();
	print_prologue(stdout, pro);
	wprintf(L"KEY    "); printhex(stdout, sec->pprime, 32); EOL();
	wprintf(L"H(KEY) "); printhex(stdout, pro->h_pprime, 32); EOL();

	gcry_md_final(ctx.hmac);
	wprintf(L"HMAC'  ");
	uint8_t hmac[32];
	memmove(hmac, gcry_md_read(ctx.hmac, GCRY_MD_SHA256), 32);
	printhex(stdout, hmac, 32);
	EOL();

	wprintf(L"HMAC   ");
	printhex(stdout, ptr + (sz - 32), 32);
	EOL();
#undef EOL

	gcry_free(safe);
	gcry_free(sec);
	unmapfile(ptr, sz);
	term_decrypt_ctx(&ctx);

	exit(0);
}
Пример #23
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);
}
Пример #24
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;
}
Пример #25
0
static int
xxxx_do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
               int *canceled )
{
    gpg_error_t err;
    byte *buffer;
    u16 csum=0;
    int i, res;
    size_t nbytes;

    if( sk->is_protected ) { /* remove the protection */
	DEK *dek = NULL;
	u32 keyid[4]; /* 4! because we need two of them */
	gcry_cipher_hd_t cipher_hd=NULL;
	PKT_secret_key *save_sk;

	if( sk->protect.s2k.mode == 1001 ) {
	    log_info(_("secret key parts are not available\n"));
	    return GPG_ERR_UNUSABLE_SECKEY;
	}
	if( sk->protect.algo == CIPHER_ALGO_NONE )
	    BUG();
	if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
	    log_info(_("protection algorithm %d%s is not supported\n"),
			sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
	    return GPG_ERR_CIPHER_ALGO;
	}
	if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
	  {
	    log_info(_("protection digest %d is not supported\n"),
		     sk->protect.s2k.hash_algo);
	    return GPG_ERR_DIGEST_ALGO;
	  }
	keyid_from_sk( sk, keyid );
	keyid[2] = keyid[3] = 0;
	if (!sk->flags.primary)
          {
            keyid[2] = sk->main_keyid[0];
            keyid[3] = sk->main_keyid[1];
          }
	dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
				 &sk->protect.s2k, mode,
                                 tryagain_text, canceled );
        if (!dek && canceled && *canceled)
	    return GPG_ERR_CANCELED;


	err = openpgp_cipher_open (&cipher_hd, sk->protect.algo,
				   GCRY_CIPHER_MODE_CFB,
				   (GCRY_CIPHER_SECURE
				    | (sk->protect.algo >= 100 ?
				       0 : GCRY_CIPHER_ENABLE_SYNC)));
        if (err)
          log_fatal ("cipher open failed: %s\n", gpg_strerror (err) );

	err = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
        if (err)
          log_fatal ("set key failed: %s\n", gpg_strerror (err) );

	xfree(dek);
	save_sk = copy_secret_key( NULL, sk );

	gcry_cipher_setiv ( cipher_hd, sk->protect.iv, sk->protect.ivlen );

	csum = 0;
	if( sk->version >= 4 ) {
            int ndata;
	    unsigned int ndatabits;
	    byte *p, *data;
            u16 csumc = 0;

	    i = pubkey_get_npkey(sk->pubkey_algo);

            assert ( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
            p = gcry_mpi_get_opaque ( sk->skey[i], &ndatabits );
            ndata = (ndatabits+7)/8;

            if ( ndata > 1 )
              csumc = buf16_to_u16 (p+ndata-2);
	    data = xmalloc_secure ( ndata );
	    gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
	    gcry_mpi_release (sk->skey[i]); sk->skey[i] = NULL ;

	    p = data;
            if (sk->protect.sha1chk) {
                /* This is the new SHA1 checksum method to detect
                   tampering with the key as used by the Klima/Rosa
                   attack */
                sk->csum = 0;
                csum = 1;
                if( ndata < 20 )
                    log_error("not enough bytes for SHA-1 checksum\n");
                else {
                    gcry_md_hd_t h;

                    if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
                        BUG(); /* Algo not available. */
                    gcry_md_write (h, data, ndata - 20);
                    gcry_md_final (h);
                    if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
                                 data + ndata - 20, 20) )
                      {
                        /* Digest does match.  We have to keep the old
                           style checksum in sk->csum, so that the
                           test used for unprotected keys does work.
                           This test gets used when we are adding new
                           keys. */
                        sk->csum = csum = checksum (data, ndata-20);
                      }
                    gcry_md_close (h);
                }
            }
            else {
                if( ndata < 2 ) {
                    log_error("not enough bytes for checksum\n");
                    sk->csum = 0;
                    csum = 1;
                }
                else {
                    csum = checksum( data, ndata-2);
                    sk->csum = data[ndata-2] << 8 | data[ndata-1];
                    if ( sk->csum != csum ) {
                        /* This is a PGP 7.0.0 workaround */
                        sk->csum = csumc; /* take the encrypted one */
                    }
                }
            }

            /* Must check it here otherwise the mpi_read_xx would fail
               because the length may have an arbitrary value */
            if( sk->csum == csum ) {
                for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
                    if ( gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
                                        p, ndata, &nbytes))
                      {
                        /* Checksum was okay, but not correctly
                           decrypted.  */
                        sk->csum = 0;
                        csum = 1;
                        break;
                      }
                    ndata -= nbytes;
                    p += nbytes;
                }
                /* Note: at this point ndata should be 2 for a simple
                   checksum or 20 for the sha1 digest */
            }
	    xfree(data);
	}
	else {
	    for(i=pubkey_get_npkey(sk->pubkey_algo);
		    i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
                byte *p;
                size_t ndata;
                unsigned int ndatabits;

                assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
                p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
                ndata = (ndatabits+7)/8;
                assert (ndata >= 2);
                assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
                buffer = xmalloc_secure (ndata);
		gcry_cipher_sync (cipher_hd);
                buffer[0] = p[0];
                buffer[1] = p[1];
                gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
                                     p+2, ndata-2);
                csum += checksum (buffer, ndata);
                gcry_mpi_release (sk->skey[i]);

		err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
				     buffer, ndata, &ndata );
		xfree (buffer);
                if (err)
                  {
                    /* Checksum was okay, but not correctly
                       decrypted.  */
                    sk->csum = 0;
                    csum = 1;
                    break;
                  }
/*  		csum += checksum_mpi (sk->skey[i]); */
	    }
	}
	gcry_cipher_close ( cipher_hd );

	/* Now let's see whether we have used the correct passphrase. */
	if( csum != sk->csum ) {
	    copy_secret_key( sk, save_sk );
            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
	    free_secret_key( save_sk );
	    return gpg_error (GPG_ERR_BAD_PASSPHRASE);
	}

	/* The checksum may fail, so we also check the key itself. */
	res = pk_check_secret_key ( sk->pubkey_algo, sk->skey );
	if( res ) {
	    copy_secret_key( sk, save_sk );
            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
	    free_secret_key( save_sk );
	    return gpg_error (GPG_ERR_BAD_PASSPHRASE);
	}
	free_secret_key( save_sk );
	sk->is_protected = 0;
    }
    else { /* not protected, assume it is okay if the checksum is okay */
	csum = 0;
	for(i=pubkey_get_npkey(sk->pubkey_algo);
		i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
	    csum += checksum_mpi( sk->skey[i] );
	}
	if( csum != sk->csum )
	    return GPG_ERR_CHECKSUM;
    }

    return 0;
}
Пример #26
0
netmd_error netmd_secure_send_track(netmd_dev_handle *dev,
                                    netmd_wireformat wireformat,
                                    unsigned char discformat,
                                    unsigned int frames,
                                    netmd_track_packets *packets,
                                    size_t packet_count,
                                    unsigned char *sessionkey,

                                    uint16_t *track, unsigned char *uuid,
                                    unsigned char *content_id)
{
    unsigned char cmdhdr[] = {0x00, 0x01, 0x00, 0x10, 0x01};
    unsigned char cmd[sizeof(cmdhdr) + 13];
    unsigned char *buf;
    size_t totalbytes;

    netmd_response response;
    netmd_error error;

    gcry_cipher_hd_t handle;
    unsigned char encryptedreply[32] = { 0 };
    unsigned char iv[8] = { 0 };

    memcpy(cmd, cmdhdr, sizeof(cmdhdr));
    buf = cmd + sizeof(cmdhdr);
    netmd_copy_word_to_buffer(&buf, 0xffffU, 0);
    *(buf++) = 0;
    *(buf++) = wireformat & 0xffU;
    *(buf++) = discformat & 0xffU;
    netmd_copy_doubleword_to_buffer(&buf, frames, 0);

    totalbytes = netmd_get_frame_size(wireformat) * frames + packet_count * 24U;
    netmd_copy_doubleword_to_buffer(&buf, totalbytes, 0);

    netmd_send_secure_msg(dev, 0x28, cmd, sizeof(cmd));
    error = netmd_recv_secure_msg(dev, 0x28, &response, NETMD_STATUS_INTERIM);
    netmd_check_response_bulk(&response, cmdhdr, sizeof(cmdhdr), &error);
    netmd_read_response_bulk(&response, NULL, 2, &error);
    netmd_check_response(&response, 0x00, &error);

    if (error == NETMD_NO_ERROR) {
        netmd_transfer_song_packets(dev, packets);

        error = netmd_recv_secure_msg(dev, 0x28, &response, NETMD_STATUS_ACCEPTED);
        netmd_check_response_bulk(&response, cmdhdr, sizeof(cmdhdr), &error);
        *track = netmd_read_word(&response);
        netmd_check_response(&response, 0x00, &error);
        netmd_read_response_bulk(&response, NULL, 10, &error);
        netmd_read_response_bulk(&response, encryptedreply,
                                 sizeof(encryptedreply), &error);
    }

    if (error == NETMD_NO_ERROR) {
        gcry_cipher_open(&handle, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
        gcry_cipher_setiv(handle, iv, 8);
        gcry_cipher_setkey(handle, sessionkey, 8);
        gcry_cipher_decrypt(handle, encryptedreply, sizeof(encryptedreply), NULL, 0);
        gcry_cipher_close(handle);
        
        memcpy(uuid, encryptedreply, 8);
        memcpy(content_id, encryptedreply + 12, 20);
    }

    return error;
}
Пример #27
0
gchar * __pkey_manage_aes_decrypt_aux (const gchar *string, const gchar *password, const guchar *iv, const guchar *ctr)
{
    guchar *out = __pkey_manage_from_hex(string);

    guchar *key = __pkey_manage_create_key (password);

    gcry_cipher_hd_t cry_ctxt;
    gcry_error_t get;

    get = gcry_cipher_open (&cry_ctxt, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, 0);
    if (get) {
        fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
        return NULL;
    }

    if (! iv || !ctr) {

        get = gcry_cipher_setiv(cry_ctxt, &old_iv, 16);
        if (get) {
            fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
            return NULL;
        }

        if (! ctr)
            ctr = old_ctr;

        get = gcry_cipher_setctr(cry_ctxt, &old_ctr, 16);
        if (get) {
            fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
            return NULL;
        }

    } else {
        get = gcry_cipher_setiv(cry_ctxt, iv, 16);
        if (get) {
            fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
            return NULL;
        }

        if (! ctr)
            ctr = old_ctr;

        get = gcry_cipher_setctr(cry_ctxt, ctr, 16);
        if (get) {
            fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
            return NULL;
        }
    }

    get = gcry_cipher_setkey (cry_ctxt, key, 32);
    if (get) {
        fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
        return NULL;
    }

    get = gcry_cipher_decrypt(cry_ctxt, out, strlen(string)/2, NULL, 0);
    if (get) {
        fprintf (stderr, "ERR GCRYPT: %ud\n", gcry_err_code(get));
        return NULL;
    }

    gcry_cipher_close (cry_ctxt);

    return (gchar *) out;
}
Пример #28
0
static int
xmlSecGCryptKWAesBlockDecrypt(const xmlSecByte * in, xmlSecSize inSize,
                               xmlSecByte * out, xmlSecSize outSize,
                               void * context) {
    xmlSecGCryptKWAesCtxPtr ctx = (xmlSecGCryptKWAesCtxPtr)context;
    gcry_cipher_hd_t cipherCtx;
    gcry_error_t err;

    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(in != NULL, -1);
    xmlSecAssert2(inSize >= ctx->blockSize, -1);
    xmlSecAssert2(out != NULL, -1);
    xmlSecAssert2(outSize >= ctx->blockSize, -1);

    err = gcry_cipher_open(&cipherCtx, ctx->cipher, ctx->mode, ctx->flags);
    if(err != GPG_ERR_NO_ERROR) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "gcry_cipher_open",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_GCRYPT_REPORT_ERROR(err));
        return(-1);
    }

    err = gcry_cipher_setkey(cipherCtx,
                             xmlSecBufferGetData(&ctx->keyBuffer),
                             xmlSecBufferGetSize(&ctx->keyBuffer));
    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);
    }

    /* use zero IV and CBC mode to ensure we get result as-is */
    err = gcry_cipher_setiv(cipherCtx, g_zero_iv, sizeof(g_zero_iv));
    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);
    }

    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);
    }
    gcry_cipher_close(cipherCtx);

    return(ctx->blockSize);
}
Пример #29
0
/* I think we should merge this with cipher_filter */
static int
mdc_decode_filter (void *opaque, int control, IOBUF a,
                   byte *buf, size_t *ret_len)
{
  decode_filter_ctx_t dfx = opaque;
  size_t n, size = *ret_len;
  int rc = 0;
  int c;

  if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
    {
      *ret_len = 0;
      rc = -1;
    }
  else if( control == IOBUFCTRL_UNDERFLOW )
    {
      assert (a);
      assert ( size > 44 );

      /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
      for (n=22; n < 44 ; n++ )
        {
          if( (c = iobuf_get(a)) == -1 )
            break;
          buf[n] = c;
	}
      if ( n == 44 )
        {
          /* We have enough stuff - flush the deferred stuff.  */
          /* (we asserted that the buffer is large enough) */
          if ( !dfx->defer_filled )  /* First time. */
            {
              memcpy (buf, buf+22, 22 );
              n = 22;
	    }
          else
            {
              memcpy (buf, dfx->defer, 22 );
	    }
          /* Now fill up. */
          for (; n < size; n++ )
            {
              if ( (c = iobuf_get(a)) == -1 )
                break;
              buf[n] = c;
	    }
          /* Move the last 22 bytes back to the defer buffer. */
	  /* (right, we are wasting 22 bytes of the supplied buffer.) */
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->defer_filled = 1;
	}
      else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
        {
          /* This is bad because it means an incomplete hash. */
          n -= 22;
          memcpy (buf, buf+22, n );
          dfx->eof_seen = 2; /* EOF with incomplete hash.  */
	}
      else  /* EOF seen (i.e. read less than 22 bytes). */
        {
          memcpy (buf, dfx->defer, 22 );
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->eof_seen = 1; /* Normal EOF. */
	}

      if ( n )
        {
          if ( dfx->cipher_hd )
            gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
          if ( dfx->mdc_hash )
            gcry_md_write (dfx->mdc_hash, buf, n);
	}
      else
        {
          assert ( dfx->eof_seen );
          rc = -1; /* eof */
	}
      *ret_len = n;
    }
  else if ( control == IOBUFCTRL_FREE )
    {
      release_dfx_context (dfx);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      *(char**)buf = "mdc_decode_filter";
    }
  return rc;
}
Пример #30
0
GkmDataResult
gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const gchar *password,
                                         gsize n_password, gcry_sexp_t *s_key)
{
	GNode *asn = NULL;
	gcry_cipher_hd_t cih = NULL;
	gcry_error_t gcry;
	GkmDataResult ret, r;
	GQuark scheme;
	guchar *crypted = NULL;
	const guchar *params;
	gsize n_crypted, n_params;
	gint l;

	init_quarks ();

	ret = GKM_DATA_UNRECOGNIZED;

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;

	/* Figure out the type of encryption */
	scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
	if (!scheme)
		goto done;

	params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
	if (!params)
		goto done;

	/*
	 * Parse the encryption stuff into a cipher.
	 */
	r = egg_symkey_read_cipher (scheme, password, n_password, params, n_params, &cih);
	if (r == GKM_DATA_UNRECOGNIZED) {
		ret = GKM_DATA_FAILURE;
		goto done;
	} else if (r != GKM_DATA_SUCCESS) {
		ret = r;
		goto done;
	}

	crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL),
	                                       egg_secure_realloc, &n_crypted);
	if (!crypted)
		goto done;

	gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
	gcry_cipher_close (cih);
	cih = NULL;

	if (gcry != 0) {
		g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
		goto done;
	}

	/* Unpad the DER data */
	l = egg_asn1x_element_length (crypted, n_crypted);
	if (l <= 0 || l > n_crypted) {
		ret = GKM_DATA_LOCKED;
		goto done;
	}
	n_crypted = l;

	/* Try to parse the resulting key */
	ret = gkm_data_der_read_private_pkcs8_plain (crypted, n_crypted, s_key);
	egg_secure_free (crypted);
	crypted = NULL;

	/* If unrecognized we assume bad password */
	if (ret == GKM_DATA_UNRECOGNIZED)
		ret = GKM_DATA_LOCKED;

done:
	if (cih)
		gcry_cipher_close (cih);
	egg_asn1x_destroy (asn);
	egg_secure_free (crypted);

	return ret;
}