error handling
[oweals/gnunet.git] / src / util / gnunet-crypto-tvg.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2020 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file util/gnunet-crypto-tgv.c
23  * @brief Generate test vectors for cryptographic operations.
24  * @author Florian Dold
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_signatures.h"
29 #include "gnunet_testing_lib.h"
30 #include <gcrypt.h>
31
32 GNUNET_NETWORK_STRUCT_BEGIN
33
34 /**
35  * Sample signature struct.
36  *
37  * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST
38  */
39 struct TestSignatureDataPS
40 {
41   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
42   uint32_t testval;
43 };
44
45 GNUNET_NETWORK_STRUCT_END
46
47
48 /**
49  * Print data base32-crockford with a preceding label.
50  *
51  * @param label label to print
52  * @param data data to print
53  * @param size size of data
54  */
55 static void
56 display_data (char *label, void *data, size_t size)
57 {
58   char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
59   printf ("%s %s\n", label, enc);
60   GNUNET_free (enc);
61 }
62
63
64 /**
65  * Main function that will be run.
66  *
67  * @param cls closure
68  * @param args remaining command-line arguments
69  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
70  * @param cfg configuration
71  */
72 static void
73 run (void *cls,
74      char *const *args,
75      const char *cfgfile,
76      const struct GNUNET_CONFIGURATION_Handle *cfg)
77 {
78   {
79     struct GNUNET_HashCode hc;
80     char *str = "Hello, GNUnet";
81
82     GNUNET_CRYPTO_hash (str, strlen (str), &hc);
83
84     printf ("hash code:\n");
85     display_data ("  input", str, strlen (str));
86     display_data ("  output", &hc, sizeof (struct GNUNET_HashCode));
87   }
88   {
89     struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
90     struct GNUNET_CRYPTO_EcdhePublicKey pub1;
91     struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
92     struct GNUNET_HashCode skm;
93     priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
94     priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
95     GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
96     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
97
98     printf ("ecdhe key:\n");
99     display_data ("  priv1", priv1, sizeof (struct
100                                             GNUNET_CRYPTO_EcdhePrivateKey));
101     display_data ("  pub1", &pub1, sizeof (struct
102                                            GNUNET_CRYPTO_EcdhePublicKey));
103     display_data ("  priv2", priv2, sizeof (struct
104                                             GNUNET_CRYPTO_EcdhePrivateKey));
105     display_data ("  skm", &skm, sizeof (struct GNUNET_HashCode));
106     GNUNET_free (priv1);
107     GNUNET_free (priv2);
108   }
109
110   {
111     struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
112     struct GNUNET_CRYPTO_EddsaPublicKey pub;
113     priv = GNUNET_CRYPTO_eddsa_key_create ();
114     GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
115
116     printf ("eddsa key:\n");
117     display_data ("  priv", priv, sizeof (struct
118                                           GNUNET_CRYPTO_EddsaPrivateKey));
119     display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
120     GNUNET_free (priv);
121   }
122   {
123     struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
124     struct GNUNET_CRYPTO_EddsaPublicKey pub;
125     struct GNUNET_CRYPTO_EddsaSignature sig;
126     struct TestSignatureDataPS data = { 0 };
127     priv = GNUNET_CRYPTO_eddsa_key_create ();
128     GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
129     data.purpose.size = htonl (sizeof (struct TestSignatureDataPS));
130     data.purpose.size = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
131     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
132                                                           &sig));
133     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
134                                                             &data.purpose,
135                                                             &sig,
136                                                             &pub));
137
138     printf ("eddsa sig:\n");
139     display_data ("  priv", priv, sizeof (struct
140                                           GNUNET_CRYPTO_EddsaPrivateKey));
141     display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
142     display_data ("  data", &data, sizeof (struct TestSignatureDataPS));
143     display_data ("  sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
144     GNUNET_free (priv);
145   }
146
147   {
148     size_t out_len = 64;
149     char out[out_len];
150     char *ikm = "I'm the secret input key material";
151     char *salt = "I'm very salty";
152     char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
153
154     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
155                                                    out_len,
156                                                    salt,
157                                                    strlen (salt),
158                                                    ikm,
159                                                    strlen (ikm),
160                                                    ctx,
161                                                    strlen (ctx),
162                                                    NULL));
163
164     printf ("kdf:\n");
165     display_data ("  salt", salt, strlen (salt));
166     display_data ("  ikm", ikm, strlen (ikm));
167     display_data ("  ctx", ctx, strlen (ctx));
168     printf ("  out_len %u\n", (unsigned int) out_len);
169     display_data ("  out", out, out_len);
170   }
171   {
172     struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
173     struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
174     struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
175     struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
176     struct GNUNET_HashCode key_material;
177     priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
178     GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
179     priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
180     GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
181     GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
182
183     printf ("eddsa_ecdh:\n");
184     display_data ("  priv_ecdhe", priv_ecdhe, sizeof (struct
185                                                       GNUNET_CRYPTO_EcdhePrivateKey));
186     display_data ("  pub_ecdhe", &pub_ecdhe, sizeof (struct
187                                                      GNUNET_CRYPTO_EcdhePublicKey));
188     display_data ("  priv_eddsa", priv_eddsa, sizeof (struct
189                                                       GNUNET_CRYPTO_EddsaPrivateKey));
190     display_data ("  pub_eddsa", &pub_eddsa, sizeof (struct
191                                                      GNUNET_CRYPTO_EddsaPublicKey));
192     display_data ("  key_material", &key_material, sizeof (struct
193                                                            GNUNET_HashCode));
194   }
195
196   {
197     struct GNUNET_CRYPTO_RsaPrivateKey *skey;
198     struct GNUNET_CRYPTO_RsaPublicKey *pkey;
199     struct GNUNET_HashCode message_hash;
200     struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
201     struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
202     struct GNUNET_CRYPTO_RsaSignature *sig;
203     void *blinded_data;
204     size_t blinded_len;
205     void *public_enc_data;
206     size_t public_enc_len;
207     void *blinded_sig_enc_data;
208     size_t blinded_sig_enc_length;
209     void *sig_enc_data;
210     size_t sig_enc_length;
211     skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
212     pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
213     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
214                                 sizeof (struct GNUNET_HashCode));
215     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
216                                                                           GNUNET_CRYPTO_RsaBlindingKeySecret));
217     GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash,
218                                                           &bks,
219                                                           pkey,
220                                                           &blinded_data,
221                                                           &blinded_len));
222     blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
223                                                   blinded_len);
224     sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
225     GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
226                                                            pkey));
227     public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
228                                                           &public_enc_data);
229     blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
230                                                                  &
231                                                                  blinded_sig_enc_data);
232     sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
233     printf ("blind signing:\n");
234     display_data ("  message_hash", &message_hash, sizeof (struct
235                                                            GNUNET_HashCode));
236     display_data ("  rsa_public_key", public_enc_data, public_enc_len);
237     display_data ("  blinding_key_secret", &bks, sizeof (struct
238                                                          GNUNET_CRYPTO_RsaBlindingKeySecret));
239     display_data ("  blinded_message", blinded_data, blinded_len);
240     display_data ("  blinded_sig", blinded_sig_enc_data,
241                   blinded_sig_enc_length);
242     display_data ("  sig", sig_enc_data, sig_enc_length);
243     GNUNET_CRYPTO_rsa_private_key_free (skey);
244     GNUNET_CRYPTO_rsa_public_key_free (pkey);
245     GNUNET_CRYPTO_rsa_signature_free (sig);
246     GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
247   }
248 }
249
250
251 /**
252  * The main function of the test vector generation tool.
253  *
254  * @param argc number of arguments from the command line
255  * @param argv command line arguments
256  * @return 0 ok, 1 on error
257  */
258 int
259 main (int argc,
260       char *const *argv)
261 {
262   const struct GNUNET_GETOPT_CommandLineOption options[] = {
263     GNUNET_GETOPT_OPTION_END
264   };
265
266   GNUNET_assert (GNUNET_OK ==
267                  GNUNET_log_setup ("gnunet-crypto-tvg",
268                                    "INFO",
269                                    NULL));
270   if (GNUNET_OK !=
271       GNUNET_PROGRAM_run (argc, argv,
272                           "gnunet-crypto-tvg",
273                           "Generate test vectors for cryptographic operations",
274                           options,
275                           &run, NULL))
276     return 1;
277   return 0;
278 }
279
280
281 /* end of gnunet-crypto-tvg.c */