|
Packit |
3ff1e7 |
/* libquvi
|
|
Packit |
3ff1e7 |
* Copyright (C) 2013 Toni Gundogdu <legatvs@gmail.com>
|
|
Packit |
3ff1e7 |
*
|
|
Packit |
3ff1e7 |
* This file is part of libquvi <http://quvi.sourceforge.net/>.
|
|
Packit |
3ff1e7 |
*
|
|
Packit |
3ff1e7 |
* This library is free software: you can redistribute it and/or
|
|
Packit |
3ff1e7 |
* modify it under the terms of the GNU Affero General Public
|
|
Packit |
3ff1e7 |
* License as published by the Free Software Foundation, either
|
|
Packit |
3ff1e7 |
* version 3 of the License, or (at your option) any later version.
|
|
Packit |
3ff1e7 |
*
|
|
Packit |
3ff1e7 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
3ff1e7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ff1e7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
3ff1e7 |
* GNU Affero General Public License for more details.
|
|
Packit |
3ff1e7 |
*
|
|
Packit |
3ff1e7 |
* You should have received a copy of the GNU Affero General
|
|
Packit |
3ff1e7 |
* Public License along with this library. If not, see
|
|
Packit |
3ff1e7 |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
3ff1e7 |
*/
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
#include "config.h"
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
#include <stdlib.h>
|
|
Packit |
3ff1e7 |
#include <gcrypt.h>
|
|
Packit |
3ff1e7 |
#include <glib/gstdio.h>
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
#include "gcrypt/crypto.h"
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static void _fail_set(crypto_t c, gchar *errmsg)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
c->errmsg = errmsg;
|
|
Packit |
3ff1e7 |
c->rc = EXIT_FAILURE;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static crypto_t _fail(crypto_t c, gchar *errmsg)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
_fail_set(c, errmsg);
|
|
Packit |
3ff1e7 |
return (c);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static gint _failn(crypto_t c, gchar *errmsg)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
_fail_set(c, errmsg);
|
|
Packit |
3ff1e7 |
return (c->rc);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static crypto_t _setkey(crypto_t c, gchar *key)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gcry_error_t e;
|
|
Packit |
3ff1e7 |
gsize keylen;
|
|
Packit |
3ff1e7 |
#ifdef _1
|
|
Packit |
3ff1e7 |
g_message("[%s] key=%s", __func__, key);
|
|
Packit |
3ff1e7 |
#endif
|
|
Packit |
3ff1e7 |
c->cipher.key = (gchar*) crypto_hex2bytes(key, &keylen);
|
|
Packit |
3ff1e7 |
if (c->cipher.key == NULL || keylen ==0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c,
|
|
Packit |
3ff1e7 |
g_strdup("crypto_hex2bytes failed: invalid "
|
|
Packit |
3ff1e7 |
"hexadecimal string length")));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
#ifdef _1
|
|
Packit |
3ff1e7 |
crypto_dump("c->cipher.key", (guchar*) c->cipher.key, keylen);
|
|
Packit |
3ff1e7 |
#endif
|
|
Packit |
3ff1e7 |
c->cipher.keylen = gcry_cipher_get_algo_keylen(c->algo);
|
|
Packit |
3ff1e7 |
if (c->cipher.keylen ==0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c, g_strdup_printf("gcry_cipher_get_algo_keylen failed "
|
|
Packit |
3ff1e7 |
"c->cipher.keylen=%" G_GSIZE_FORMAT", "
|
|
Packit |
3ff1e7 |
"keylen=%" G_GSIZE_FORMAT,
|
|
Packit |
3ff1e7 |
c->cipher.keylen, keylen)));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
#ifdef _1
|
|
Packit |
3ff1e7 |
if (keylen > c->cipher.keylen)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
g_warning("key length exceeds %lu, ignoring the exceeding bytes",keylen);
|
|
Packit |
3ff1e7 |
keylen = c->cipher.keylen;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
#endif
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
e = gcry_cipher_setkey(c->cipher.h, c->cipher.key, keylen);
|
|
Packit |
3ff1e7 |
if (e != 0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c,
|
|
Packit |
3ff1e7 |
g_strdup_printf("gcry_cipher_setkey failed: %s",
|
|
Packit |
3ff1e7 |
gpg_strerror(e))));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
c->rc = EXIT_SUCCESS;
|
|
Packit |
3ff1e7 |
return (c);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static crypto_t _cipher_new(crypto_t c, gchar *key,
|
|
Packit |
3ff1e7 |
const gchar *algoname,
|
|
Packit |
3ff1e7 |
const gint cipher_mode,
|
|
Packit |
3ff1e7 |
const guint cipher_flags)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gcry_error_t e;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
c->algo = gcry_cipher_map_name(algoname);
|
|
Packit |
3ff1e7 |
if (c->algo ==0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c, g_strdup_printf("algorithm `%s' was not available",
|
|
Packit |
3ff1e7 |
algoname)));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
c->cipher.flags = cipher_flags;
|
|
Packit |
3ff1e7 |
c->cipher.mode = cipher_mode;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
c->cipher.should_pad = (cipher_mode != GCRY_CIPHER_MODE_STREAM
|
|
Packit |
3ff1e7 |
&& cipher_mode != GCRY_CIPHER_MODE_CFB
|
|
Packit |
3ff1e7 |
&& cipher_mode != GCRY_CIPHER_MODE_OFB)
|
|
Packit |
3ff1e7 |
? TRUE
|
|
Packit |
3ff1e7 |
: FALSE;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
c->cipher.blklen = gcry_cipher_get_algo_blklen(c->algo);
|
|
Packit |
3ff1e7 |
if (c->cipher.blklen ==0)
|
|
Packit |
3ff1e7 |
return (_fail(c, g_strdup("gcry_cipher_get_algo_blklen failed")));
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
e = gcry_cipher_open(&c->cipher.h, c->algo, cipher_mode, cipher_flags);
|
|
Packit |
3ff1e7 |
if (e != 0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c, g_strdup_printf("gcry_cipher_open failed: %s",
|
|
Packit |
3ff1e7 |
gpg_strerror(e))));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (_setkey(c, key));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static crypto_t _hash_new(crypto_t c, const gchar *algoname)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
c->algo = gcry_md_map_name(algoname);
|
|
Packit |
3ff1e7 |
if (c->algo ==0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_fail(c, g_strdup_printf("algorithm `%s' was not available",
|
|
Packit |
3ff1e7 |
algoname)));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (c);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
crypto_t crypto_new(const gchar *algoname, const CryptoMode crypto_mode,
|
|
Packit |
3ff1e7 |
gchar *key, const gint cipher_mode,
|
|
Packit |
3ff1e7 |
const guint cipher_flags)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
crypto_t c = g_new0(struct crypto_s, 1);
|
|
Packit |
3ff1e7 |
c->mode = crypto_mode;
|
|
Packit |
3ff1e7 |
if (crypto_mode != CRYPTO_MODE_HASH)
|
|
Packit |
3ff1e7 |
_cipher_new(c, key, algoname, cipher_mode, cipher_flags);
|
|
Packit |
3ff1e7 |
else
|
|
Packit |
3ff1e7 |
_hash_new(c, algoname);
|
|
Packit |
3ff1e7 |
return (c);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
void crypto_free(crypto_t c)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
if (c == NULL)
|
|
Packit |
3ff1e7 |
return;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
if (c->cipher.h != NULL)
|
|
Packit |
3ff1e7 |
gcry_cipher_close(c->cipher.h);
|
|
Packit |
3ff1e7 |
c->cipher.h = NULL;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_free(c->cipher.key);
|
|
Packit |
3ff1e7 |
c->cipher.key = NULL;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_free(c->out.data);
|
|
Packit |
3ff1e7 |
c->out.data = NULL;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_free(c->errmsg);
|
|
Packit |
3ff1e7 |
c->errmsg = NULL;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_free(c);
|
|
Packit |
3ff1e7 |
c = NULL;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
gboolean crypto_ok(crypto_t c)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return ((c->rc == EXIT_SUCCESS) ? TRUE:FALSE);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static gint _encrypt_blk(crypto_t c, const guchar *data, const gsize dlen,
|
|
Packit |
3ff1e7 |
guchar *out /* size: c->blklen */)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gcry_error_t e;
|
|
Packit |
3ff1e7 |
gpointer p;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
memcpy(out, data, dlen);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
/* Pad to block length. */
|
|
Packit |
3ff1e7 |
if (c->cipher.should_pad == TRUE && dlen < c->cipher.blklen)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gsize i = dlen;
|
|
Packit |
3ff1e7 |
out[i++] = 0x80;
|
|
Packit |
3ff1e7 |
while (i < c->cipher.blklen)
|
|
Packit |
3ff1e7 |
out[i++] = 0x00;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
/* in-place */
|
|
Packit |
3ff1e7 |
e = gcry_cipher_encrypt(c->cipher.h, out, c->cipher.blklen, NULL, 0);
|
|
Packit |
3ff1e7 |
if (e != 0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_failn(c,
|
|
Packit |
3ff1e7 |
g_strdup_printf("gcry_cipher_encrypt failed: %s",
|
|
Packit |
3ff1e7 |
gpg_strerror(e))));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
/* Append. */
|
|
Packit |
3ff1e7 |
p = g_realloc(c->out.data, c->out.dlen + c->cipher.blklen);
|
|
Packit |
3ff1e7 |
if (p != NULL)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
c->out.data = p;
|
|
Packit |
3ff1e7 |
memcpy(&(c->out.data[c->out.dlen]), out, c->cipher.blklen);
|
|
Packit |
3ff1e7 |
c->out.dlen += c->cipher.blklen;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (EXIT_SUCCESS);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static gint _decrypt_blk(crypto_t c, const guchar *data, const gsize dlen,
|
|
Packit |
3ff1e7 |
guchar *out /* size: c->blk_len */)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gcry_error_t e;
|
|
Packit |
3ff1e7 |
gpointer p;
|
|
Packit |
3ff1e7 |
gsize i, n;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
memcpy(out, data, dlen);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
/* in-place */
|
|
Packit |
3ff1e7 |
e = gcry_cipher_decrypt(c->cipher.h, out, c->cipher.blklen, NULL, 0);
|
|
Packit |
3ff1e7 |
if (e != 0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_failn(c,
|
|
Packit |
3ff1e7 |
g_strdup_printf("gcry_cipher_decrypt failed: %s",
|
|
Packit |
3ff1e7 |
gpg_strerror(e))));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
n = c->cipher.blklen;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
if (c->cipher.should_pad == TRUE)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
for (i=0; i
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
if (out[i] == 0x80
|
|
Packit |
3ff1e7 |
&& (i >0 || i ==n || (i
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
n = i;
|
|
Packit |
3ff1e7 |
break;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
p = g_realloc(c->out.data, c->out.dlen+n); /* Append. */
|
|
Packit |
3ff1e7 |
if (p != NULL)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
c->out.data = p;
|
|
Packit |
3ff1e7 |
memcpy(&(c->out.data[c->out.dlen]), out, n);
|
|
Packit |
3ff1e7 |
c->out.dlen += n;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (EXIT_SUCCESS);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static gint _setiv(crypto_t c)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
const gcry_error_t e = gcry_cipher_setiv(c->cipher.h, NULL, 0);
|
|
Packit |
3ff1e7 |
if (e != 0)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
return (_failn(c, g_strdup_printf("gcry_cipher_setiv failed: %s",
|
|
Packit |
3ff1e7 |
gpg_strerror(e))));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (EXIT_SUCCESS);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
typedef gint (*blk_cb)(crypto_t, const guchar*, const gsize, guchar*);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
static gint _cipher_exec(crypto_t c, const guchar *data, const gsize size)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
guchar *out;
|
|
Packit |
3ff1e7 |
gsize n, m;
|
|
Packit |
3ff1e7 |
blk_cb cb;
|
|
Packit |
3ff1e7 |
gint r;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
if (_setiv(c) != EXIT_SUCCESS)
|
|
Packit |
3ff1e7 |
return (EXIT_FAILURE);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
cb = (c->mode == CRYPTO_MODE_ENCRYPT)
|
|
Packit |
3ff1e7 |
? _encrypt_blk
|
|
Packit |
3ff1e7 |
: _decrypt_blk;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_assert(c->out.data == NULL);
|
|
Packit |
3ff1e7 |
g_assert(c->out.dlen == 0);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
m = size - (size % c->cipher.blklen);
|
|
Packit |
3ff1e7 |
out = g_malloc0(c->cipher.blklen);
|
|
Packit |
3ff1e7 |
r = EXIT_SUCCESS;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
n = 0;
|
|
Packit |
3ff1e7 |
while ( (n < m) && (r == EXIT_SUCCESS) )
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
r = cb(c, (guchar*) data+n, c->cipher.blklen, out);
|
|
Packit |
3ff1e7 |
n += c->cipher.blklen;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
if ( (size % c->cipher.blklen) && (r == EXIT_SUCCESS) )
|
|
Packit |
3ff1e7 |
r = cb(c, (guchar*) data+n, (size % c->cipher.blklen), out);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_free(out);
|
|
Packit |
3ff1e7 |
c->rc = r;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
return (r);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
gint _hash_exec(crypto_t c, const guchar *data, const gsize size)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
guint dlen;
|
|
Packit |
3ff1e7 |
gsize n;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
dlen = gcry_md_get_algo_dlen(c->algo);
|
|
Packit |
3ff1e7 |
n = dlen * sizeof(guchar);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
c->out.data = g_malloc0(n);
|
|
Packit |
3ff1e7 |
c->out.dlen = n;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
gcry_md_hash_buffer(c->algo, c->out.data, data, size);
|
|
Packit |
3ff1e7 |
#ifdef _1
|
|
Packit |
3ff1e7 |
g_message("[%s] algo=%s", __func__, gcry_md_algo_name(c->algo));
|
|
Packit |
3ff1e7 |
g_message("[%s] dlen=%u, c->out.dlen=%lu", __func__, dlen, c->out.dlen);
|
|
Packit |
3ff1e7 |
#endif
|
|
Packit |
3ff1e7 |
return (EXIT_SUCCESS);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
gint crypto_exec(crypto_t c, const guchar *data, const gsize size)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
g_assert(data != NULL);
|
|
Packit |
3ff1e7 |
g_assert(size >0);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_assert(c->out.data == NULL);
|
|
Packit |
3ff1e7 |
g_assert(c->out.dlen == 0);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
if (c->mode != CRYPTO_MODE_HASH)
|
|
Packit |
3ff1e7 |
return (_cipher_exec(c, data, size));
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
return (_hash_exec(c, data, size));
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
void crypto_dump(const gchar *w, const guchar *p, const gsize n)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
gsize i = 0;
|
|
Packit |
3ff1e7 |
g_print("%s=", w);
|
|
Packit |
3ff1e7 |
while (i
|
|
Packit |
3ff1e7 |
g_print("%02x", p[i++] & 0xff);
|
|
Packit |
3ff1e7 |
g_print(" =(%" G_GSIZE_FORMAT ")\n", i);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
guchar *crypto_hex2bytes(const gchar *hexstr, gsize *size)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
const gchar *p;
|
|
Packit |
3ff1e7 |
guint n, b;
|
|
Packit |
3ff1e7 |
guchar *r;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
*size = 0;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
n = strlen(hexstr);
|
|
Packit |
3ff1e7 |
if ( (n % 2) ==1)
|
|
Packit |
3ff1e7 |
return (NULL); /* Invalid hexadecimal string length. */
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
r = g_malloc0_n(n/2, sizeof(guchar));
|
|
Packit |
3ff1e7 |
p = hexstr;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
while ( *p && (n = sscanf((gchar*) p, "%02x", &b)) == 1)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
r[(*size)++] = b;
|
|
Packit |
3ff1e7 |
p += 2;
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
return (r);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
gchar *crypto_bytes2hex(const guchar *data, const gsize n)
|
|
Packit |
3ff1e7 |
{
|
|
Packit |
3ff1e7 |
GString *s;
|
|
Packit |
3ff1e7 |
gchar *r;
|
|
Packit |
3ff1e7 |
gsize i;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
g_assert(data != NULL);
|
|
Packit |
3ff1e7 |
g_assert(n>0);
|
|
Packit |
3ff1e7 |
#ifdef _1
|
|
Packit |
3ff1e7 |
crypto_dump("data", data, n);
|
|
Packit |
3ff1e7 |
#endif
|
|
Packit |
3ff1e7 |
s = g_string_new(NULL);
|
|
Packit |
3ff1e7 |
i = 0;
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
while (i
|
|
Packit |
3ff1e7 |
g_string_append_printf(s, "%02x", data[i++] & 0xff);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
r = s->str;
|
|
Packit |
3ff1e7 |
g_string_free(s, FALSE);
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
return (r);
|
|
Packit |
3ff1e7 |
}
|
|
Packit |
3ff1e7 |
|
|
Packit |
3ff1e7 |
/* vim: set ts=2 sw=2 tw=72 expandtab: */
|