Skip to content

Commit

Permalink
Add: authenticator for gcm/ccm en- and decryption
Browse files Browse the repository at this point in the history
  • Loading branch information
Kraemii authored and nichtsfrei committed Jun 3, 2022
1 parent 628680d commit ad75ffe
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 43 deletions.
185 changes: 142 additions & 43 deletions nasl/nasl_crypto2.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@
#define INTBLOB_LEN 20
#define SIGBLOB_LEN (2 * INTBLOB_LEN)
#define MAX_CIPHER_ID 32
#define NASL_ENCRYPT 1
#define NASL_DECRYPT 2
#define NASL_ENCRYPT 0
#define NASL_DECRYPT 1
#define NASL_AAD 2

#undef G_LOG_DOMAIN
/**
Expand Down Expand Up @@ -1750,12 +1751,13 @@ nasl_aes_mac_gcm (lex_ctxt *lexic)
}

static tree_cell *
crypt_data (lex_ctxt *lexic, int cipher, int mode, int crypt)
crypt_data (lex_ctxt *lexic, int cipher, int mode, int flags)
{
gcry_cipher_hd_t hd;
gcry_error_t error;
void *result, *data, *key, *iv;
size_t resultlen, datalen, keylen, ivlen;
void *data, *key, *iv, *aad;
unsigned char *result = NULL, *auth = NULL;
size_t resultlen, datalen, keylen, ivlen, aadlen, authlen, len;
tree_cell *retc;

data = get_str_var_by_name (lexic, "data");
Expand All @@ -1764,13 +1766,23 @@ crypt_data (lex_ctxt *lexic, int cipher, int mode, int crypt)
keylen = get_var_size_by_name (lexic, "key");
iv = get_str_var_by_name (lexic, "iv");
ivlen = get_var_size_by_name (lexic, "iv");
aad = get_str_var_by_name (lexic, "aad");
aadlen = get_var_size_by_name (lexic, "aad");
len = get_int_var_by_name (lexic, "len", 0);

if (!data || datalen == 0 || !key || keylen == 0)
{
nasl_perror (lexic, "Syntax: crypt_data: Missing data or key argument");
return NULL;
}

if (flags & NASL_DECRYPT && len <= 0)
{
nasl_perror (lexic,
"Syntax: crypt_data: Missing or invalid len argument");
return NULL;
}

if ((error = gcry_cipher_open (&hd, cipher, mode, 0)))
{
nasl_perror (lexic, "gcry_cipher_open: %s", gcry_strerror (error));
Expand All @@ -1795,83 +1807,118 @@ crypt_data (lex_ctxt *lexic, int cipher, int mode, int crypt)
}
}

if (cipher == GCRY_CIPHER_ARCFOUR)
resultlen = datalen;
else if (cipher == GCRY_CIPHER_3DES)
resultlen = ((datalen / 8) + 1) * 8;
else if (cipher == GCRY_CIPHER_AES128)
resultlen = ((datalen / 16) + 1) * 16;
else if (cipher == GCRY_CIPHER_AES256)
resultlen = ((datalen / 32) + 1) * 32;
else
if (flags & NASL_DECRYPT)
{
nasl_perror (lexic, "encrypt_data: Unknown cipher %d", cipher);
gcry_cipher_close (hd);
return NULL;
resultlen = len;
}

if (mode == GCRY_CIPHER_MODE_CCM)
else
{
if (crypt == NASL_DECRYPT)
if (cipher == GCRY_CIPHER_ARCFOUR || mode == GCRY_CIPHER_MODE_CCM)
resultlen = datalen;
else if (cipher == GCRY_CIPHER_3DES)
resultlen = ((datalen / 8) + 1) * 8;
else if (cipher == GCRY_CIPHER_AES128)
resultlen = ((datalen / 16) + 1) * 16;
else if (cipher == GCRY_CIPHER_AES256)
resultlen = ((datalen / 32) + 1) * 32;
else
{
resultlen = get_int_var_by_name (lexic, "len", 0);
if (resultlen == 0)
{
nasl_perror (lexic, "Syntax: crypt_data: Missing or invalid "
"message length required "
"for CCM decryption");
return NULL;
}
nasl_perror (lexic, "encrypt_data: Unknown cipher %d", cipher);
gcry_cipher_close (hd);
return NULL;
}
else
resultlen = datalen;
}

if (mode == GCRY_CIPHER_MODE_CCM)
{
u_int64_t params[3];
params[0] = datalen;
params[1] = 0;
params[2] = 10;
params[1] = aadlen;
params[2] = 16;
if ((error = gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params,
sizeof (params))))
{
nasl_perror (lexic, "gcry_cipher_ctl: %s", gcry_strerror (error));
gcry_cipher_close (hd);
return NULL;
}
}
if (flags & NASL_AAD)
{
if (!aad || aadlen == 0)
{
nasl_perror (
lexic, "Syntax: crypt_data: Missing or invalid aad value required");
gcry_cipher_close (hd);
return NULL;
}

if ((error = gcry_cipher_authenticate (hd, aad, aadlen)))
{
nasl_perror (lexic, "gcry_cipher_authenticate: %s",
gcry_strerror (error));
gcry_cipher_close (hd);
return NULL;
}
}

result = g_malloc0 (resultlen);
if (crypt == NASL_ENCRYPT)
if (flags & NASL_DECRYPT)
{
if ((error =
gcry_cipher_encrypt (hd, result, resultlen, data, resultlen)))
gcry_cipher_decrypt (hd, result, resultlen, data, resultlen)))
{
g_message ("gcry_cipher_encrypt: %s", gcry_strerror (error));
g_message ("gcry_cipher_decrypt: %s", gcry_strerror (error));
gcry_cipher_close (hd);
g_free (result);
return NULL;
}
}
else if (crypt == NASL_DECRYPT)
else
{
if ((error =
gcry_cipher_decrypt (hd, result, resultlen, data, resultlen)))
gcry_cipher_encrypt (hd, result, resultlen, data, resultlen)))
{
g_message ("gcry_cipher_decrypt: %s", gcry_strerror (error));
g_message ("gcry_cipher_encrypt: %s", gcry_strerror (error));
gcry_cipher_close (hd);
g_free (result);
return NULL;
}
}
else
authlen = 16;
auth = g_malloc0 (authlen);
if (flags & NASL_AAD)
{
g_message ("crypt_data: invalid crypt value");
if ((error = gcry_cipher_gettag (hd, auth, authlen)))
{
g_message ("gcry_cipher_gettag: %s", gcry_strerror (error));
gcry_cipher_close (hd);
g_free (result);
g_free (auth);
return NULL;
}
gcry_cipher_close (hd);
g_free (result);
return NULL;

anon_nasl_var v;
retc = alloc_typed_cell (DYN_ARRAY);
retc->x.ref_val = g_malloc0 (sizeof (nasl_array));
memset (&v, 0, sizeof (v));
v.var_type = VAR2_DATA;
v.v.v_str.s_val = result;
v.v.v_str.s_siz = resultlen;
add_var_to_list (retc->x.ref_val, 0, &v);

memset (&v, 0, sizeof (v));
v.var_type = VAR2_DATA;
v.v.v_str.s_val = auth;
v.v.v_str.s_siz = authlen;
add_var_to_list (retc->x.ref_val, 1, &v);
return retc;
}

gcry_cipher_close (hd);
retc = alloc_typed_cell (CONST_DATA);
retc->x.str_val = result;
retc->x.str_val = (char *) result;
retc->size = resultlen;
return retc;
}
Expand Down Expand Up @@ -1963,55 +2010,107 @@ nasl_aes128_gcm_encrypt (lex_ctxt *lexic)
NASL_ENCRYPT);
}

tree_cell *
nasl_aes128_gcm_encrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, NASL_AAD);
}

tree_cell *
nasl_aes128_gcm_decrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM,
NASL_DECRYPT);
}

tree_cell *
nasl_aes128_gcm_decrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM,
NASL_AAD | NASL_DECRYPT);
}

tree_cell *
nasl_aes256_gcm_encrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM,
NASL_ENCRYPT);
}

tree_cell *
nasl_aes256_gcm_encrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, NASL_AAD);
}

tree_cell *
nasl_aes256_gcm_decrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM,
NASL_DECRYPT);
}

tree_cell *
nasl_aes256_gcm_decrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM,
NASL_AAD | NASL_DECRYPT);
}

tree_cell *
nasl_aes128_ccm_encrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM,
NASL_ENCRYPT);
}

tree_cell *
nasl_aes128_ccm_encrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, NASL_AAD);
}

tree_cell *
nasl_aes128_ccm_decrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM,
NASL_DECRYPT);
}

tree_cell *
nasl_aes128_ccm_decrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM,
NASL_AAD | NASL_DECRYPT);
}

tree_cell *
nasl_aes256_ccm_encrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM,
NASL_ENCRYPT);
}

tree_cell *
nasl_aes256_ccm_encrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, NASL_AAD);
}

tree_cell *
nasl_aes256_ccm_decrypt (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM,
NASL_DECRYPT);
}

tree_cell *
nasl_aes256_ccm_decrypt_auth (lex_ctxt *lexic)
{
return crypt_data (lexic, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM,
NASL_AAD | NASL_DECRYPT);
}

/**
* @brief Add the SMB3KDF as specified in [SP800-108] section 5.1
*
Expand Down
24 changes: 24 additions & 0 deletions nasl/nasl_crypto2.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,51 @@ nasl_des_ede_cbc_encrypt (lex_ctxt *lexic);
tree_cell *
nasl_aes128_gcm_encrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes128_gcm_encrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes128_gcm_decrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes128_gcm_decrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes256_gcm_encrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes256_gcm_encrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes256_gcm_decrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes256_gcm_decrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes128_ccm_encrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes128_ccm_encrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes128_ccm_decrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes128_ccm_decrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes256_ccm_encrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes256_ccm_encrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_aes256_ccm_decrypt (lex_ctxt *lexic);

tree_cell *
nasl_aes256_ccm_decrypt_auth (lex_ctxt *lexic);

tree_cell *
nasl_smb3kdf (lex_ctxt *lexic);

Expand Down
8 changes: 8 additions & 0 deletions nasl/nasl_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,21 @@ static init_func libfuncs[] = {
{"aes128_ctr_encrypt", nasl_aes128_ctr_encrypt},
{"aes256_ctr_encrypt", nasl_aes256_ctr_encrypt},
{"aes128_gcm_encrypt", nasl_aes128_gcm_encrypt},
{"aes128_gcm_encrypt_auth", nasl_aes128_gcm_encrypt_auth},
{"aes128_gcm_decrypt", nasl_aes128_gcm_decrypt},
{"aes128_gcm_decrypt_auth", nasl_aes128_gcm_decrypt_auth},
{"aes256_gcm_encrypt", nasl_aes256_gcm_encrypt},
{"aes256_gcm_encrypt_auth", nasl_aes256_gcm_encrypt_auth},
{"aes256_gcm_decrypt", nasl_aes256_gcm_decrypt},
{"aes256_gcm_decrypt_auth", nasl_aes256_gcm_decrypt_auth},
{"aes128_ccm_encrypt", nasl_aes128_ccm_encrypt},
{"aes128_ccm_encrypt_auth", nasl_aes128_ccm_encrypt_auth},
{"aes128_ccm_decrypt", nasl_aes128_ccm_decrypt},
{"aes128_ccm_decrypt_auth", nasl_aes128_ccm_decrypt_auth},
{"aes256_ccm_encrypt", nasl_aes256_ccm_encrypt},
{"aes256_ccm_encrypt_auth", nasl_aes256_ccm_encrypt_auth},
{"aes256_ccm_decrypt", nasl_aes256_ccm_decrypt},
{"aes256_ccm_decrypt_auth", nasl_aes256_ccm_decrypt_auth},
{"smb3kdf", nasl_smb3kdf},
{"des_ede_cbc_encrypt", nasl_des_ede_cbc_encrypt},
{"open_rc4_cipher", nasl_open_rc4_cipher},
Expand Down

0 comments on commit ad75ffe

Please sign in to comment.