libnm/crypto: refactor to use enum for supported ciphers

We need to (and already did) define our own identifier for ciphers,
because the gnutls/nss identifiers must be abstracted.

Don't use a string for that. The number of supported ciphers
is not generic but fixed and known at compiler time. An enum
is better suited.
This commit is contained in:
Thomas Haller 2018-08-31 09:01:08 +02:00
parent 1f550790bb
commit 858d5c3e91
5 changed files with 193 additions and 137 deletions

View file

@ -33,7 +33,32 @@
#include "nm-utils/nm-secret-utils.h"
#include "nm-errors.h"
#define SALT_LEN 8
/*****************************************************************************/
static gboolean
_get_cipher_info (NMCryptoCipherType cipher,
int *out_cipher_mech,
guint8 *out_real_iv_len)
{
static const int cipher_mechs[] = {
[NM_CRYPTO_CIPHER_DES_EDE3_CBC] = GNUTLS_CIPHER_3DES_CBC,
[NM_CRYPTO_CIPHER_DES_CBC] = GNUTLS_CIPHER_DES_CBC,
[NM_CRYPTO_CIPHER_AES_128_CBC] = GNUTLS_CIPHER_AES_128_CBC,
[NM_CRYPTO_CIPHER_AES_192_CBC] = GNUTLS_CIPHER_AES_192_CBC,
[NM_CRYPTO_CIPHER_AES_256_CBC] = GNUTLS_CIPHER_AES_256_CBC,
};
g_return_val_if_fail (_NM_INT_NOT_NEGATIVE (cipher) && (gsize) cipher < G_N_ELEMENTS (cipher_mechs), FALSE);
if (cipher_mechs[cipher] == 0)
return FALSE;
NM_SET_OUT (out_cipher_mech, cipher_mechs[cipher]);
NM_SET_OUT (out_real_iv_len, nm_crypto_cipher_get_info (cipher)->real_iv_len);
return TRUE;
}
/*****************************************************************************/
static gboolean initialized = FALSE;
@ -56,7 +81,7 @@ _nm_crypto_init (GError **error)
}
guint8 *
_nmtst_crypto_decrypt (const char *cipher,
_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,
@ -72,39 +97,24 @@ _nmtst_crypto_decrypt (const char *cipher,
int cipher_mech, i;
char *output = NULL;
gboolean success = FALSE;
gsize pad_len, real_iv_len;
gsize pad_len;
guint8 real_iv_len;
if (!_get_cipher_info (cipher, &cipher_mech, &real_iv_len)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for decryption"));
return NULL;
}
if (!_nm_crypto_init (error))
return NULL;
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
cipher_mech = GNUTLS_CIPHER_3DES_CBC;
real_iv_len = SALT_LEN;
} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
cipher_mech = GNUTLS_CIPHER_DES_CBC;
real_iv_len = SALT_LEN;
} else if (!strcmp (cipher, CIPHER_AES_128_CBC)) {
cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
real_iv_len = 16;
} else if (!strcmp (cipher, CIPHER_AES_192_CBC)) {
cipher_mech = GNUTLS_CIPHER_AES_192_CBC;
real_iv_len = 16;
} else if (!strcmp (cipher, CIPHER_AES_256_CBC)) {
cipher_mech = GNUTLS_CIPHER_AES_256_CBC;
real_iv_len = 16;
} else {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Private key cipher '%s' was unknown."),
cipher);
return NULL;
}
if (iv_len < real_iv_len) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_INVALID_DATA,
_("Invalid IV length (must be at least %zd)."),
real_iv_len);
_("Invalid IV length (must be at least %u)."),
(guint) real_iv_len);
return NULL;
}
@ -170,7 +180,7 @@ out:
}
guint8 *
_nmtst_crypto_encrypt (const char *cipher,
_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,
@ -190,25 +200,17 @@ _nmtst_crypto_encrypt (const char *cipher,
char *padded_buf = NULL;
guint32 i;
if (!_nm_crypto_init (error))
return NULL;
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
cipher_mech = GNUTLS_CIPHER_3DES_CBC;
else if (!strcmp (cipher, CIPHER_AES_128_CBC))
cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
else if (!strcmp (cipher, CIPHER_AES_192_CBC))
cipher_mech = GNUTLS_CIPHER_AES_192_CBC;
else if (!strcmp (cipher, CIPHER_AES_256_CBC))
cipher_mech = GNUTLS_CIPHER_AES_256_CBC;
else {
if ( cipher == NM_CRYPTO_CIPHER_DES_CBC
|| !_get_cipher_info (cipher, &cipher_mech, NULL)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Private key cipher '%s' was unknown."),
cipher);
_("Unsupported key cipher for encryption"));
return NULL;
}
if (!_nm_crypto_init (error))
return NULL;
/* If data_len % ivlen == 0, then we add another complete block
* onto the end so that the decrypter knows there's padding.
*/

View file

@ -51,7 +51,7 @@ gboolean _nm_crypto_verify_pkcs8 (const guint8 *data,
/*****************************************************************************/
guint8 *_nmtst_crypto_encrypt (const char *cipher,
guint8 *_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,
@ -61,7 +61,7 @@ guint8 *_nmtst_crypto_encrypt (const char *cipher,
gsize *out_len,
GError **error);
guint8 *_nmtst_crypto_decrypt (const char *cipher,
guint8 *_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,

View file

@ -38,6 +38,33 @@
#include "nm-utils/nm-secret-utils.h"
#include "nm-errors.h"
/*****************************************************************************/
static gboolean
_get_cipher_info (NMCryptoCipherType cipher,
CK_MECHANISM_TYPE *out_cipher_mech,
guint8 *out_real_iv_len)
{
static const CK_MECHANISM_TYPE cipher_mechs[] = {
[NM_CRYPTO_CIPHER_DES_EDE3_CBC] = CKM_DES3_CBC_PAD,
[NM_CRYPTO_CIPHER_DES_CBC] = CKM_DES_CBC_PAD,
[NM_CRYPTO_CIPHER_AES_128_CBC] = CKM_AES_CBC_PAD,
[NM_CRYPTO_CIPHER_AES_192_CBC] = CKM_AES_CBC_PAD,
[NM_CRYPTO_CIPHER_AES_256_CBC] = CKM_AES_CBC_PAD,
};
g_return_val_if_fail (_NM_INT_NOT_NEGATIVE (cipher) && (gsize) cipher < G_N_ELEMENTS (cipher_mechs), FALSE);
if (!cipher_mechs[cipher])
return FALSE;
NM_SET_OUT (out_cipher_mech, cipher_mechs[cipher]);
NM_SET_OUT (out_real_iv_len, nm_crypto_cipher_get_info (cipher)->real_iv_len);
return TRUE;
}
/*****************************************************************************/
static gboolean initialized = FALSE;
gboolean
@ -72,7 +99,7 @@ _nm_crypto_init (GError **error)
}
guint8 *
_nmtst_crypto_decrypt (const char *cipher,
_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,
@ -93,35 +120,24 @@ _nmtst_crypto_decrypt (const char *cipher,
SECStatus s;
gboolean success = FALSE;
unsigned pad_len = 0, extra = 0;
guint32 i, real_iv_len = 0;
guint32 i;
guint8 real_iv_len;
if (!_get_cipher_info (cipher, &cipher_mech, &real_iv_len)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for decryption"));
return NULL;
}
if (!_nm_crypto_init (error))
return NULL;
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
cipher_mech = CKM_DES3_CBC_PAD;
real_iv_len = 8;
} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
cipher_mech = CKM_DES_CBC_PAD;
real_iv_len = 8;
} else if (NM_IN_STRSET (cipher, CIPHER_AES_128_CBC,
CIPHER_AES_192_CBC,
CIPHER_AES_256_CBC)) {
cipher_mech = CKM_AES_CBC_PAD;
real_iv_len = 16;
} else {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Private key cipher '%s' was unknown."),
cipher);
return NULL;
}
if (iv_len < real_iv_len) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_INVALID_DATA,
_("Invalid IV length (must be at least %d)."),
real_iv_len);
_("Invalid IV length (must be at least %u)."),
(guint) real_iv_len);
return NULL;
}
@ -242,7 +258,7 @@ out:
}
guint8 *
_nmtst_crypto_encrypt (const char *cipher,
_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const guint8 *iv,
@ -269,18 +285,11 @@ _nmtst_crypto_encrypt (const char *cipher,
if (!_nm_crypto_init (error))
return NULL;
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
cipher_mech = CKM_DES3_CBC_PAD;
else if (NM_IN_STRSET (cipher,
CIPHER_AES_128_CBC,
CIPHER_AES_192_CBC,
CIPHER_AES_256_CBC))
cipher_mech = CKM_AES_CBC_PAD;
else {
if ( cipher == NM_CRYPTO_CIPHER_DES_CBC
|| !_get_cipher_info (cipher, &cipher_mech, NULL)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Private key cipher '%s' was unknown."),
cipher);
_("Unsupported key cipher for encryption"));
return NULL;
}

View file

@ -54,6 +54,64 @@
/*****************************************************************************/
static const NMCryptoCipherInfo cipher_infos[] = {
#define _CI(_cipher, _name, _digest_len, _real_iv_len) \
[(_cipher) - 1] = { .cipher = _cipher, .name = ""_name"", .digest_len = _digest_len, .real_iv_len = _real_iv_len }
_CI (NM_CRYPTO_CIPHER_DES_EDE3_CBC, "DES-EDE3-CBC", 24, 8),
_CI (NM_CRYPTO_CIPHER_DES_CBC, "DES-CBC", 8, 8),
_CI (NM_CRYPTO_CIPHER_AES_128_CBC, "AES-128-CBC", 16, 16),
_CI (NM_CRYPTO_CIPHER_AES_192_CBC, "AES-192-CBC", 24, 16),
_CI (NM_CRYPTO_CIPHER_AES_256_CBC, "AES-256-CBC", 32, 16),
};
const NMCryptoCipherInfo *
nm_crypto_cipher_get_info (NMCryptoCipherType cipher)
{
g_return_val_if_fail (cipher > NM_CRYPTO_CIPHER_UNKNOWN && (gsize) cipher < G_N_ELEMENTS (cipher_infos) + 1, NULL);
#if NM_MORE_ASSERTS > 10
{
int i, j;
for (i = 0; i < (int) G_N_ELEMENTS (cipher_infos); i++) {
const NMCryptoCipherInfo *info = &cipher_infos[i];
nm_assert (info->cipher == (NMCryptoCipherType) (i + 1));
nm_assert (info->name && info->name[0]);
for (j = 0; j < i; j++)
nm_assert (g_ascii_strcasecmp (info->name, cipher_infos[j].name) != 0);
}
}
#endif
return &cipher_infos[cipher - 1];
}
const NMCryptoCipherInfo *
nm_crypto_cipher_get_info_by_name (const char *cipher_name, gssize p_len)
{
int i;
nm_assert (nm_crypto_cipher_get_info (NM_CRYPTO_CIPHER_DES_CBC)->cipher == NM_CRYPTO_CIPHER_DES_CBC);
if (p_len < 0) {
if (!cipher_name)
return FALSE;
p_len = strlen (cipher_name);
}
for (i = 0; i < (int) G_N_ELEMENTS (cipher_infos); i++) {
const NMCryptoCipherInfo *info = &cipher_infos[i];
if ( (gsize) p_len == strlen (info->name)
&& g_ascii_strncasecmp (info->name, cipher_name, p_len) == 0)
return info;
}
return NULL;
}
/*****************************************************************************/
static gboolean
find_tag (const char *tag,
const guint8 *data,
@ -119,7 +177,7 @@ parse_old_openssl_key_file (const guint8 *data,
gsize data_len,
NMSecretPtr *out_parsed,
NMCryptoKeyType *out_key_type,
const char **out_cipher,
NMCryptoCipherType *out_cipher,
char **out_iv,
GError **error)
{
@ -132,7 +190,7 @@ parse_old_openssl_key_file (const guint8 *data,
nm_auto_clear_secret_ptr NMSecretPtr parsed = { 0 };
nm_auto_clear_secret_ptr NMSecretPtr data_content = { 0 };
nm_auto_free_secret char *iv = NULL;
const char *cipher = NULL;
NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN;
const char *start_tag;
const char *end_tag;
const guint8 *data_start, *data_end;
@ -141,7 +199,7 @@ parse_old_openssl_key_file (const guint8 *data,
nm_assert (!out_iv || !*out_iv);
NM_SET_OUT (out_key_type, NM_CRYPTO_KEY_TYPE_UNKNOWN);
*out_cipher = NULL;
NM_SET_OUT (out_cipher, NM_CRYPTO_CIPHER_UNKNOWN);
if (find_tag (PEM_RSA_KEY_BEGIN, data, data_len, 0, &start)) {
key_type = NM_CRYPTO_KEY_TYPE_RSA;
@ -202,14 +260,9 @@ parse_old_openssl_key_file (const guint8 *data,
return FALSE;
}
} else if (!strncmp (p, DEK_INFO_TAG, strlen (DEK_INFO_TAG))) {
static const char *const known_ciphers[] = { CIPHER_DES_EDE3_CBC,
CIPHER_DES_CBC,
CIPHER_AES_128_CBC,
CIPHER_AES_192_CBC,
CIPHER_AES_256_CBC };
const NMCryptoCipherInfo *cipher_info;
char *comma;
gsize p_len;
guint i;
if (enc_tags++ != 1 || str_p != str) {
g_set_error (error, NM_CRYPTO_ERROR,
@ -240,20 +293,15 @@ parse_old_openssl_key_file (const guint8 *data,
iv = g_strdup (comma);
/* Get the private key cipher */
for (i = 0; i < G_N_ELEMENTS (known_ciphers); i++) {
if ( strlen (known_ciphers[i]) == p_len
&& !g_ascii_strncasecmp (p, known_ciphers[i], p_len)) {
cipher = known_ciphers[i];
break;
}
}
if (!cipher) {
cipher_info = nm_crypto_cipher_get_info_by_name (p, p_len);
if (!cipher_info) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: unknown private key cipher '%s'."),
p);
return FALSE;
}
cipher = cipher_info->cipher;
} else {
if (enc_tags == 1) {
g_set_error (error, NM_CRYPTO_ERROR,
@ -277,7 +325,7 @@ parse_old_openssl_key_file (const guint8 *data,
NM_SET_OUT (out_key_type, key_type);
NM_SET_OUT (out_iv, g_steal_pointer (&iv));
*out_cipher = cipher;
NM_SET_OUT (out_cipher, cipher);
nm_secret_ptr_move (out_parsed, &parsed);
return TRUE;
}
@ -419,7 +467,7 @@ _nmtst_convert_iv (const char *src,
}
guint8 *
nm_crypto_make_des_aes_key (const char *cipher,
nm_crypto_make_des_aes_key (NMCryptoCipherType cipher,
const guint8 *salt,
gsize salt_len,
const char *password,
@ -427,9 +475,8 @@ nm_crypto_make_des_aes_key (const char *cipher,
GError **error)
{
guint8 *key;
gsize digest_len;
const NMCryptoCipherInfo *cipher_info;
g_return_val_if_fail (cipher != NULL, NULL);
g_return_val_if_fail (salt != NULL, NULL);
g_return_val_if_fail (salt_len >= 8, NULL);
g_return_val_if_fail (password != NULL, NULL);
@ -437,42 +484,28 @@ nm_crypto_make_des_aes_key (const char *cipher,
*out_len = 0;
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
digest_len = 24;
else if (!strcmp (cipher, CIPHER_DES_CBC))
digest_len = 8;
else if (!strcmp (cipher, CIPHER_AES_128_CBC))
digest_len = 16;
else if (!strcmp (cipher, CIPHER_AES_192_CBC))
digest_len = 24;
else if (!strcmp (cipher, CIPHER_AES_256_CBC))
digest_len = 32;
else {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Private key cipher '%s' was unknown."),
cipher);
return NULL;
}
cipher_info = nm_crypto_cipher_get_info (cipher);
g_return_val_if_fail (cipher_info, NULL);
if (password[0] == '\0')
return NULL;
key = g_malloc (digest_len);
key = g_malloc (cipher_info->digest_len);
nm_crypto_md5_hash (salt,
8,
(guint8 *) password,
strlen (password),
key,
digest_len);
cipher_info->digest_len);
*out_len = digest_len;
*out_len = cipher_info->digest_len;
return key;
}
static gboolean
_nmtst_decrypt_key (const char *cipher,
_nmtst_decrypt_key (NMCryptoCipherType cipher,
const guint8 *data,
gsize data_len,
const char *iv,
@ -485,7 +518,7 @@ _nmtst_decrypt_key (const char *cipher,
gs_free char *output = NULL;
nm_assert (password);
nm_assert (cipher);
nm_assert (cipher != NM_CRYPTO_CIPHER_UNKNOWN);
nm_assert (iv);
nm_assert (parsed);
nm_assert (!parsed->bin);
@ -535,7 +568,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
nm_auto_clear_secret_ptr NMSecretPtr parsed = { 0 };
nm_auto_free_secret char *iv = NULL;
const char *cipher = NULL;
NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN;
g_return_val_if_fail (data != NULL, NULL);
@ -556,7 +589,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
if (password) {
nm_auto_clear_secret_ptr NMSecretPtr parsed2 = { 0 };
if (!cipher || !iv) {
if (cipher == NM_CRYPTO_CIPHER_UNKNOWN || !iv) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_INVALID_PASSWORD,
_("Password provided, but key was not encrypted."));
@ -575,7 +608,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
return nm_secret_copy_to_gbytes (parsed2.bin, parsed2.len);
}
if (cipher || iv)
if (cipher != NM_CRYPTO_CIPHER_UNKNOWN || iv)
return NULL;
return nm_secret_copy_to_gbytes (parsed.bin, parsed.len);
@ -796,13 +829,13 @@ nm_crypto_verify_private_key_data (const guint8 *data,
|| _nm_crypto_verify_pkcs8 (parsed.bin, parsed.len, is_encrypted, password, error))
format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
} else {
const char *cipher;
NMCryptoCipherType cipher;
nm_auto_free_secret char *iv = NULL;
/* Or it's old-style OpenSSL */
if (parse_old_openssl_key_file (data, data_len, NULL, NULL, &cipher, &iv, NULL)) {
format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
is_encrypted = (cipher && iv);
is_encrypted = (cipher != NM_CRYPTO_CIPHER_UNKNOWN && iv);
}
}
}
@ -936,11 +969,11 @@ nmtst_crypto_rsa_key_encrypt (const guint8 *data,
if (!nm_crypto_randomize (salt, sizeof (salt), error))
return NULL;
key.bin = nm_crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, salt, sizeof (salt), in_password, &key.len, NULL);
key.bin = nm_crypto_make_des_aes_key (NM_CRYPTO_CIPHER_DES_EDE3_CBC, salt, sizeof (salt), in_password, &key.len, NULL);
if (!key.bin)
g_return_val_if_reached (NULL);
enc.bin = _nmtst_crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, sizeof (salt), key.bin, key.len, &enc.len, error);
enc.bin = _nmtst_crypto_encrypt (NM_CRYPTO_CIPHER_DES_EDE3_CBC, data, len, salt, sizeof (salt), key.bin, key.len, &enc.len, error);
if (!enc.bin)
return NULL;
@ -956,7 +989,8 @@ nmtst_crypto_rsa_key_encrypt (const guint8 *data,
g_ptr_array_add (pem, g_strdup ("Proc-Type: 4,ENCRYPTED\n"));
/* Convert the salt to a hex string */
g_ptr_array_add (pem, g_strdup ("DEK-Info: "CIPHER_DES_EDE3_CBC","));
g_ptr_array_add (pem, g_strdup_printf ("DEK-Info: %s,",
nm_crypto_cipher_get_info (NM_CRYPTO_CIPHER_DES_EDE3_CBC)->name));
g_ptr_array_add (pem, nm_utils_bin2hexstr (salt, sizeof (salt), sizeof (salt) * 2));
g_ptr_array_add (pem, g_strdup ("\n\n"));

View file

@ -28,13 +28,24 @@
#error Cannot use this header.
#endif
#define MD5_HASH_LEN 20
typedef enum {
NM_CRYPTO_CIPHER_UNKNOWN,
NM_CRYPTO_CIPHER_DES_EDE3_CBC,
NM_CRYPTO_CIPHER_DES_CBC,
NM_CRYPTO_CIPHER_AES_128_CBC,
NM_CRYPTO_CIPHER_AES_192_CBC,
NM_CRYPTO_CIPHER_AES_256_CBC,
} NMCryptoCipherType;
#define CIPHER_DES_EDE3_CBC "DES-EDE3-CBC"
#define CIPHER_DES_CBC "DES-CBC"
#define CIPHER_AES_128_CBC "AES-128-CBC"
#define CIPHER_AES_192_CBC "AES-192-CBC"
#define CIPHER_AES_256_CBC "AES-256-CBC"
typedef struct {
const char *name;
NMCryptoCipherType cipher;
guint8 digest_len;
guint8 real_iv_len;
} NMCryptoCipherInfo;
const NMCryptoCipherInfo *nm_crypto_cipher_get_info (NMCryptoCipherType cipher);
const NMCryptoCipherInfo *nm_crypto_cipher_get_info_by_name (const char *cipher_name, gssize p_len);
typedef enum {
NM_CRYPTO_KEY_TYPE_UNKNOWN = 0,
@ -81,7 +92,7 @@ void nm_crypto_md5_hash (const guint8 *salt,
guint8 *buffer,
gsize buflen);
guint8 *nm_crypto_make_des_aes_key (const char *cipher,
guint8 *nm_crypto_make_des_aes_key (NMCryptoCipherType cipher,
const guint8 *salt,
gsize salt_len,
const char *password,