OpenVAS Scanner  22.7.9
nasl_crypt_helper.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2023 Greenbone AG
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  */
5 
6 #include "../misc//support.h"
7 #include "nasl_crypto_helper.h"
8 #include "nasl_debug.h"
9 
10 #include <assert.h>
11 #include <ctype.h>
12 #include <gcrypt.h>
13 #include <glib.h>
14 #include <gpg-error.h>
15 #include <gvm/base/logging.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 
19 void *
20 hmac_md5_for_prf (const void *key, int keylen, const void *buf, int buflen)
21 {
22  void *signature = g_malloc0 (16);
23  gsize signlen = 16;
24  GHmac *hmac;
25 
26  hmac = g_hmac_new (G_CHECKSUM_MD5, key, keylen);
27  g_hmac_update (hmac, buf, buflen);
28  g_hmac_get_digest (hmac, signature, &signlen);
29  g_hmac_unref (hmac);
30  return signature;
31 }
32 
33 void *
34 hmac_sha1 (const void *key, int keylen, const void *buf, int buflen)
35 {
36  void *signature = g_malloc0 (20);
37  gsize signlen = 20;
38  GHmac *hmac;
39 
40  hmac = g_hmac_new (G_CHECKSUM_SHA1, key, keylen);
41  g_hmac_update (hmac, buf, buflen);
42  g_hmac_get_digest (hmac, signature, &signlen);
43  g_hmac_unref (hmac);
44  return signature;
45 }
46 
47 void *
48 hmac_sha256 (const void *key, int keylen, const void *buf, int buflen)
49 {
50  void *signature = g_malloc0 (32);
51  gsize signlen = 32;
52  GHmac *hmac;
53 
54  hmac = g_hmac_new (G_CHECKSUM_SHA256, key, keylen);
55  g_hmac_update (hmac, buf, buflen);
56  g_hmac_get_digest (hmac, signature, &signlen);
57  g_hmac_unref (hmac);
58  return signature;
59 }
60 
61 void *
62 hmac_sha384 (const void *key, int keylen, const void *buf, int buflen)
63 {
64  gcry_md_hd_t hd;
65  gcry_error_t err;
66  void *ret;
67 
68  if (!buf || buflen <= 0)
69  return NULL;
70 
71  err = gcry_md_open (&hd, GCRY_MD_SHA384, key ? GCRY_MD_FLAG_HMAC : 0);
72  if (err)
73  {
74  g_message ("nasl_gcrypt_hash(): gcry_md_open failed: %s/%s",
75  gcry_strsource (err), gcry_strerror (err));
76  return NULL;
77  }
78 
79  if (key)
80  {
81  err = gcry_md_setkey (hd, key, keylen);
82  if (err)
83  {
84  g_message ("nasl_gcrypt_hash(): gcry_md_setkey failed: %s/%s",
85  gcry_strsource (err), gcry_strerror (err));
86  return NULL;
87  }
88  }
89 
90  gcry_md_write (hd, buf, buflen);
91  ret = g_memdup2 (gcry_md_read (hd, 0), 48);
92  gcry_md_close (hd);
93  return ret;
94 }
95 
96 gpg_err_code_t
97 mac (const char *key, const size_t key_len, const char *data,
98  const size_t data_len, const char *iv, const size_t iv_len, int algo,
99  int flags, char **out, size_t *out_len)
100 {
101  // guardian
102  gpg_err_code_t result = 0;
103  gcry_mac_hd_t hd;
104  if (key == NULL || key_len < 1)
105  return GPG_ERR_MISSING_KEY;
106  if (data == NULL || data_len < 1)
107  return GPG_ERR_MISSING_VALUE;
108  if (out == NULL)
109  {
110  return GPG_ERR_GENERAL;
111  }
112  if ((result = gcry_mac_open (&hd, algo, flags, NULL)))
113  return result;
114  if ((result = gcry_mac_setkey (hd, key, key_len)))
115  goto cexit;
116  if (iv && (result = gcry_mac_setiv (hd, iv, iv_len)))
117  goto cexit;
118  if ((result = gcry_mac_write (hd, data, data_len)))
119  goto cexit;
120 
121  *out_len = gcry_mac_get_algo_maclen (algo);
122  if ((*out = g_malloc0 (*out_len * sizeof (*out))) == NULL)
123  {
124  result = GPG_ERR_ENOMEM;
125  goto cexit;
126  }
127  if ((result = gcry_mac_read (hd, *out, out_len)))
128  goto cexit;
129 
130 cexit:
131  gcry_mac_close (hd);
132  return result;
133 }
134 
135 static gcry_error_t
136 smb_sign (const int algo, const char *key, const size_t key_len, char *buf,
137  const size_t buf_len, const char *iv, const size_t iv_len, char **out)
138 {
139  gcry_error_t error = GPG_ERR_NO_ERROR;
140  char *signature = NULL;
141  size_t signature_len;
142  if (buf == NULL || buf_len < 64)
143  {
144  return GPG_ERR_NO_VALUE;
145  }
146  if (key == NULL || key_len < 16)
147  return GPG_ERR_NO_KEY;
148  memset ((char *) buf + 48, 0, 16);
149  switch (algo)
150  {
151  case GCRY_MAC_GMAC_AES:
152  if ((error = mac (key, key_len, buf, buf_len, iv, iv_len, algo,
153  GCRY_MAC_FLAG_SECURE, &signature, &signature_len)))
154  goto exit;
155  break;
156  case GCRY_MAC_CMAC_AES:
157  if ((error = mac (key, key_len, buf, buf_len, NULL, 0, algo,
158  GCRY_MAC_FLAG_SECURE, &signature, &signature_len)))
159  goto exit;
160  break;
161  case G_CHECKSUM_SHA256:
162  signature = hmac_sha256 (key, key_len, buf, buf_len);
163  break;
164  default:
165  // not defined;
166  error = GPG_ERR_UNKNOWN_ALGORITHM;
167  goto exit;
168  }
169  // TODO is 16 hard coded or should it be signature_len?
170  *out = g_malloc0 (buf_len);
171  memcpy (*out, buf, buf_len);
172  memcpy (*out + 48, signature, 16);
173  free (signature);
174 exit:
175  return error;
176 }
177 
178 tree_cell *
179 nasl_smb_sign (const int algo, lex_ctxt *lexic)
180 {
181  char *key, *buf, *iv, *res;
182  int keylen, buflen, ivlen;
183  gcry_error_t error;
184  tree_cell *retc = NULL;
185 
186  key = get_str_var_by_name (lexic, "key");
187  buf = get_str_var_by_name (lexic, "buf");
188  iv = get_str_var_by_name (lexic, "iv");
189  keylen = get_var_size_by_name (lexic, "key");
190  buflen = get_var_size_by_name (lexic, "buf");
191  ivlen = get_var_size_by_name (lexic, "iv");
192 
193  switch ((error = smb_sign (algo, key, keylen, buf, buflen, iv, ivlen, &res)))
194  {
195  case GPG_ERR_NO_ERROR:
196  retc = alloc_typed_cell (CONST_DATA);
197  retc->x.str_val = res;
198  retc->size = buflen;
199  break;
200  case GPG_ERR_MISSING_KEY:
201  case GPG_ERR_MISSING_VALUE:
202  nasl_perror (lexic, "Syntax: nasl_mac: Missing key, or data argument");
203  break;
204  default:
205  nasl_perror (lexic, "Internal: %s.", gcry_strerror (error));
206  }
207 
208  return retc;
209 }
nasl_crypto_helper.h
CONST_DATA
@ CONST_DATA
Definition: nasl_tree.h:82
get_var_size_by_name
int get_var_size_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1138
TC::str_val
char * str_val
Definition: nasl_tree.h:103
nasl_smb_sign
tree_cell * nasl_smb_sign(const int algo, lex_ctxt *lexic)
Definition: nasl_crypt_helper.c:179
TC::x
union TC::@5 x
get_str_var_by_name
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1118
nasl_debug.h
nasl_perror
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:111
TC::size
int size
Definition: nasl_tree.h:99
hmac_sha256
void * hmac_sha256(const void *key, int keylen, const void *buf, int buflen)
Definition: nasl_crypt_helper.c:48
mac
gpg_err_code_t mac(const char *key, const size_t key_len, const char *data, const size_t data_len, const char *iv, const size_t iv_len, int algo, int flags, char **out, size_t *out_len)
Definition: nasl_crypt_helper.c:97
hmac_md5_for_prf
void * hmac_md5_for_prf(const void *key, int keylen, const void *buf, int buflen)
Definition: nasl_crypt_helper.c:20
TC
Definition: nasl_tree.h:94
struct_lex_ctxt
Definition: nasl_lex_ctxt.h:23
hmac_sha1
void * hmac_sha1(const void *key, int keylen, const void *buf, int buflen)
Definition: nasl_crypt_helper.c:34
smb_sign
static gcry_error_t smb_sign(const int algo, const char *key, const size_t key_len, char *buf, const size_t buf_len, const char *iv, const size_t iv_len, char **out)
Definition: nasl_crypt_helper.c:136
alloc_typed_cell
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:28
free
void free(void *)
hmac_sha384
void * hmac_sha384(const void *key, int keylen, const void *buf, int buflen)
Definition: nasl_crypt_helper.c:62