diff options
Diffstat (limited to 'src/util/anastasis_crypto.c')
-rw-r--r-- | src/util/anastasis_crypto.c | 637 |
1 files changed, 637 insertions, 0 deletions
diff --git a/src/util/anastasis_crypto.c b/src/util/anastasis_crypto.c new file mode 100644 index 0000000..ace0162 --- /dev/null +++ b/src/util/anastasis_crypto.c | |||
@@ -0,0 +1,637 @@ | |||
1 | /* | ||
2 | This file is part of Anastasis | ||
3 | Copyright (C) 2020 Taler Systems SA | ||
4 | |||
5 | Anastasis is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU Lesser General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file lib/anastasis_crypto.c | ||
18 | * @brief anastasis crypto api | ||
19 | * @author Christian Grothoff | ||
20 | * @author Dominik Meister | ||
21 | * @author Dennis Neufeld | ||
22 | */ | ||
23 | |||
24 | #include "platform.h" | ||
25 | #include "anastasis_crypto_lib.h" | ||
26 | #include <gcrypt.h> | ||
27 | #include <taler/taler_json_lib.h> | ||
28 | #include <gnunet/gnunet_util_lib.h> | ||
29 | #include <string.h> | ||
30 | |||
31 | #if defined(DEBUG) || defined(DEBUG2) | ||
32 | #define SCRYPT_ITERATION 1 | ||
33 | |||
34 | #else | ||
35 | #define SCRYPT_ITERATION 1000 | ||
36 | #endif | ||
37 | |||
38 | |||
39 | void | ||
40 | ANASTASIS_hash_answer (uint64_t code, | ||
41 | struct GNUNET_HashCode *hashed_code) | ||
42 | { | ||
43 | char cbuf[40]; | ||
44 | |||
45 | GNUNET_snprintf (cbuf, | ||
46 | sizeof (cbuf), | ||
47 | "%llu", | ||
48 | (unsigned long long) code); | ||
49 | GNUNET_CRYPTO_hash (cbuf, | ||
50 | strlen (cbuf), | ||
51 | hashed_code); | ||
52 | } | ||
53 | |||
54 | |||
55 | void | ||
56 | ANASTASIS_CRYPTO_secure_answer_hash ( | ||
57 | const char *answer, | ||
58 | const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, | ||
59 | const struct ANASTASIS_CRYPTO_QuestionSaltP *salt, | ||
60 | struct GNUNET_HashCode *result) | ||
61 | { | ||
62 | struct GNUNET_HashCode pow; | ||
63 | |||
64 | GNUNET_CRYPTO_pow_hash (&salt->pow_salt, | ||
65 | answer, | ||
66 | strlen (answer), | ||
67 | &pow); | ||
68 | GNUNET_assert (GNUNET_YES == | ||
69 | GNUNET_CRYPTO_kdf ( | ||
70 | result, | ||
71 | sizeof (*result), | ||
72 | "Anastasis-secure-question-uuid-salting", | ||
73 | strlen ("Anastasis-secure-question-uuid-salting"), | ||
74 | &pow, | ||
75 | sizeof (pow), | ||
76 | uuid, | ||
77 | sizeof (*uuid), | ||
78 | NULL, | ||
79 | 0)); | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Compute @a key and @a iv. | ||
85 | * | ||
86 | * @param key_material key for calculation | ||
87 | * @param key_m_len length of key | ||
88 | * @param nonce nonce for calculation | ||
89 | * @param salt salt value for calculation | ||
90 | * @param[out] key where to write the en-/description key | ||
91 | * @param[out] iv where to write the IV | ||
92 | */ | ||
93 | static void | ||
94 | get_iv_key (const void *key_material, | ||
95 | size_t key_m_len, | ||
96 | const struct ANASTASIS_CRYPTO_NonceP *nonce, | ||
97 | const char *salt, | ||
98 | const struct ANASTASIS_CRYPTO_SymKeyP *key, | ||
99 | struct ANASTASIS_CRYPTO_IvP *iv) | ||
100 | { | ||
101 | char res[sizeof (struct ANASTASIS_CRYPTO_SymKeyP) | ||
102 | + sizeof (struct ANASTASIS_CRYPTO_IvP)]; | ||
103 | |||
104 | if (GNUNET_YES != | ||
105 | GNUNET_CRYPTO_hkdf (res, | ||
106 | sizeof (res), | ||
107 | GCRY_MD_SHA512, | ||
108 | GCRY_MD_SHA256, | ||
109 | key_material, | ||
110 | key_m_len, | ||
111 | nonce, | ||
112 | sizeof (struct ANASTASIS_CRYPTO_NonceP), | ||
113 | salt, | ||
114 | strlen (salt), | ||
115 | NULL, | ||
116 | 0)) | ||
117 | { | ||
118 | GNUNET_break (0); | ||
119 | return; | ||
120 | } | ||
121 | memcpy ((void *) key, | ||
122 | res, | ||
123 | sizeof (*key)); | ||
124 | memcpy (iv, | ||
125 | &res[sizeof (*key)], | ||
126 | sizeof (*iv)); | ||
127 | } | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Encryption of data like recovery document etc. | ||
132 | * | ||
133 | * @param nonce value to use for the nonce | ||
134 | * @param key key which is used to derive a key/iv pair from | ||
135 | * @param key_len length of key | ||
136 | * @param data data to encrypt | ||
137 | * @param data_size size of the data | ||
138 | * @param salt salt value which is used for key derivation | ||
139 | * @param res[out] ciphertext output | ||
140 | * @param res_size[out] size of the ciphertext | ||
141 | */ | ||
142 | static void | ||
143 | anastasis_encrypt (const struct ANASTASIS_CRYPTO_NonceP *nonce, | ||
144 | const void *key, | ||
145 | size_t key_len, | ||
146 | const void *data, | ||
147 | size_t data_size, | ||
148 | const char *salt, | ||
149 | void **res, | ||
150 | size_t *res_size) | ||
151 | { | ||
152 | struct ANASTASIS_CRYPTO_NonceP *nonceptr; | ||
153 | gcry_cipher_hd_t cipher; | ||
154 | struct ANASTASIS_CRYPTO_SymKeyP sym_key; | ||
155 | struct ANASTASIS_CRYPTO_IvP iv; | ||
156 | int rc; | ||
157 | struct ANASTASIS_CRYPTO_AesTagP *tag; | ||
158 | char *ciphertext; | ||
159 | |||
160 | *res_size = data_size | ||
161 | + sizeof (struct ANASTASIS_CRYPTO_NonceP) | ||
162 | + sizeof (struct ANASTASIS_CRYPTO_AesTagP); | ||
163 | if (*res_size <= data_size) | ||
164 | { | ||
165 | GNUNET_break (0); | ||
166 | return; | ||
167 | } | ||
168 | *res = GNUNET_malloc (*res_size); | ||
169 | if (*res_size != data_size | ||
170 | + sizeof (struct ANASTASIS_CRYPTO_NonceP) | ||
171 | + sizeof (struct ANASTASIS_CRYPTO_AesTagP)) | ||
172 | { | ||
173 | GNUNET_break (0); | ||
174 | return; | ||
175 | } | ||
176 | nonceptr = (struct ANASTASIS_CRYPTO_NonceP *) *res; | ||
177 | tag = (struct ANASTASIS_CRYPTO_AesTagP *) &nonceptr[1]; | ||
178 | ciphertext = (char *) &tag[1]; | ||
179 | memcpy (nonceptr, | ||
180 | nonce, | ||
181 | sizeof (*nonce)); | ||
182 | get_iv_key (key, | ||
183 | key_len, | ||
184 | nonce, | ||
185 | salt, | ||
186 | &sym_key, | ||
187 | &iv); | ||
188 | GNUNET_assert (0 == | ||
189 | gcry_cipher_open (&cipher, | ||
190 | GCRY_CIPHER_AES256, | ||
191 | GCRY_CIPHER_MODE_GCM, | ||
192 | 0)); | ||
193 | rc = gcry_cipher_setkey (cipher, | ||
194 | &sym_key, | ||
195 | sizeof (sym_key)); | ||
196 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
197 | rc = gcry_cipher_setiv (cipher, | ||
198 | &iv, | ||
199 | sizeof (iv)); | ||
200 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
201 | |||
202 | GNUNET_assert (0 == | ||
203 | gcry_cipher_encrypt (cipher, | ||
204 | ciphertext, | ||
205 | data_size, | ||
206 | data, | ||
207 | data_size)); | ||
208 | GNUNET_assert (0 == | ||
209 | gcry_cipher_gettag (cipher, | ||
210 | tag, | ||
211 | sizeof (struct ANASTASIS_CRYPTO_AesTagP))); | ||
212 | gcry_cipher_close (cipher); | ||
213 | } | ||
214 | |||
215 | |||
216 | /** | ||
217 | * Decryption of data like encrypted recovery document etc. | ||
218 | * | ||
219 | * @param key key which is used to derive a key/iv pair from | ||
220 | * @param key_len length of key | ||
221 | * @param data data to decrypt | ||
222 | * @param data_size size of the data | ||
223 | * @param salt salt value which is used for key derivation | ||
224 | * @param res[out] plaintext output | ||
225 | * @param res_size[out] size of the plaintext | ||
226 | */ | ||
227 | static void | ||
228 | anastasis_decrypt (const void *key, | ||
229 | size_t key_len, | ||
230 | const void *data, | ||
231 | size_t data_size, | ||
232 | const char *salt, | ||
233 | void **res, | ||
234 | size_t *res_size) | ||
235 | { | ||
236 | const struct ANASTASIS_CRYPTO_NonceP *nonce; | ||
237 | gcry_cipher_hd_t cipher; | ||
238 | const struct ANASTASIS_CRYPTO_SymKeyP sym_key; | ||
239 | struct ANASTASIS_CRYPTO_IvP iv; | ||
240 | int rc; | ||
241 | const struct ANASTASIS_CRYPTO_AesTagP *tag; | ||
242 | const char *ciphertext; | ||
243 | |||
244 | *res_size = data_size | ||
245 | - sizeof (struct ANASTASIS_CRYPTO_NonceP) | ||
246 | - sizeof (struct ANASTASIS_CRYPTO_AesTagP); | ||
247 | if (*res_size >= data_size) | ||
248 | { | ||
249 | GNUNET_break (0); | ||
250 | return; | ||
251 | } | ||
252 | *res = GNUNET_malloc (*res_size); | ||
253 | if (*res_size != data_size | ||
254 | - sizeof (struct ANASTASIS_CRYPTO_NonceP) | ||
255 | - sizeof (struct ANASTASIS_CRYPTO_AesTagP)) | ||
256 | { | ||
257 | GNUNET_break (0); | ||
258 | GNUNET_free (*res); | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | nonce = (const struct ANASTASIS_CRYPTO_NonceP *) data; | ||
263 | tag = (struct ANASTASIS_CRYPTO_AesTagP *) &nonce[1]; | ||
264 | ciphertext = (const char *) &tag[1]; | ||
265 | get_iv_key (key, | ||
266 | key_len, | ||
267 | nonce, | ||
268 | salt, | ||
269 | &sym_key, | ||
270 | &iv); | ||
271 | GNUNET_assert (0 == | ||
272 | gcry_cipher_open (&cipher, | ||
273 | GCRY_CIPHER_AES256, | ||
274 | GCRY_CIPHER_MODE_GCM, | ||
275 | 0)); | ||
276 | rc = gcry_cipher_setkey (cipher, | ||
277 | &sym_key, | ||
278 | sizeof (sym_key)); | ||
279 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
280 | |||
281 | rc = gcry_cipher_setiv (cipher, | ||
282 | &iv, | ||
283 | sizeof (iv)); | ||
284 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
285 | |||
286 | GNUNET_assert (0 == gcry_cipher_decrypt (cipher, | ||
287 | *res, | ||
288 | *res_size, | ||
289 | ciphertext, | ||
290 | *res_size)); | ||
291 | if (0 != | ||
292 | gcry_cipher_checktag (cipher, | ||
293 | tag, | ||
294 | sizeof (struct ANASTASIS_CRYPTO_AesTagP))) | ||
295 | { | ||
296 | GNUNET_break (0); | ||
297 | GNUNET_free (*res); | ||
298 | return; | ||
299 | } | ||
300 | gcry_cipher_close (cipher); | ||
301 | } | ||
302 | |||
303 | |||
304 | void | ||
305 | ANASTASIS_CRYPTO_user_identifier_derive ( | ||
306 | const json_t *id_data, | ||
307 | const struct ANASTASIS_CRYPTO_ProviderSaltP *server_salt, | ||
308 | struct ANASTASIS_CRYPTO_UserIdentifierP *id) | ||
309 | { | ||
310 | char *json_enc; | ||
311 | struct GNUNET_HashCode hash; | ||
312 | |||
313 | json_enc = json_dumps (id_data, | ||
314 | JSON_COMPACT | JSON_SORT_KEYS); | ||
315 | GNUNET_assert (NULL != json_enc); | ||
316 | GNUNET_CRYPTO_pow_hash (&server_salt->salt, | ||
317 | json_enc, | ||
318 | strlen (json_enc), | ||
319 | &hash); | ||
320 | id->hash = hash; | ||
321 | free (json_enc); | ||
322 | } | ||
323 | |||
324 | |||
325 | void | ||
326 | ANASTASIS_CRYPTO_account_private_key_derive ( | ||
327 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
328 | struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv_key) | ||
329 | { | ||
330 | /* priv_key = ver_secret */ | ||
331 | if (GNUNET_YES != | ||
332 | GNUNET_CRYPTO_hkdf (&priv_key->priv, | ||
333 | sizeof (priv_key->priv), | ||
334 | GCRY_MD_SHA512, | ||
335 | GCRY_MD_SHA256, | ||
336 | id, | ||
337 | sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP), | ||
338 | "ver", | ||
339 | strlen ("ver"), | ||
340 | NULL, | ||
341 | 0)) | ||
342 | { | ||
343 | GNUNET_break (0); | ||
344 | return; | ||
345 | } | ||
346 | /* go from ver_secret to proper private key (eddsa_d_to_a() in spec) */ | ||
347 | priv_key->priv.d[0] = (priv_key->priv.d[0] & 0x7f) | 0x40; | ||
348 | priv_key->priv.d[31] &= 0xf8; | ||
349 | } | ||
350 | |||
351 | |||
352 | void | ||
353 | ANASTASIS_CRYPTO_account_public_key_derive ( | ||
354 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
355 | struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub_key) | ||
356 | { | ||
357 | struct ANASTASIS_CRYPTO_AccountPrivateKeyP priv; | ||
358 | |||
359 | ANASTASIS_CRYPTO_account_private_key_derive (id, | ||
360 | &priv); | ||
361 | GNUNET_CRYPTO_eddsa_key_get_public (&priv.priv, | ||
362 | &pub_key->pub); | ||
363 | } | ||
364 | |||
365 | |||
366 | void | ||
367 | ANASTASIS_CRYPTO_recovery_document_encrypt ( | ||
368 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
369 | const void *rec_doc, | ||
370 | size_t rd_size, | ||
371 | void **enc_rec_doc, | ||
372 | size_t *erd_size) | ||
373 | { | ||
374 | const char *salt = "erd"; | ||
375 | struct ANASTASIS_CRYPTO_NonceP nonce; | ||
376 | |||
377 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
378 | &nonce, | ||
379 | sizeof (nonce)); | ||
380 | anastasis_encrypt (&nonce, | ||
381 | id, | ||
382 | sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP), | ||
383 | rec_doc, | ||
384 | rd_size, | ||
385 | salt, | ||
386 | enc_rec_doc, | ||
387 | erd_size); | ||
388 | } | ||
389 | |||
390 | |||
391 | void | ||
392 | ANASTASIS_CRYPTO_recovery_document_decrypt ( | ||
393 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
394 | const void *enc_rec_doc, | ||
395 | size_t erd_size, | ||
396 | void **rec_doc, | ||
397 | size_t *rd_size) | ||
398 | { | ||
399 | const char *salt = "erd"; | ||
400 | |||
401 | anastasis_decrypt (id, | ||
402 | sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP), | ||
403 | enc_rec_doc, | ||
404 | erd_size, | ||
405 | salt, | ||
406 | rec_doc, | ||
407 | rd_size); | ||
408 | } | ||
409 | |||
410 | |||
411 | void | ||
412 | ANASTASIS_CRYPTO_keyshare_encrypt ( | ||
413 | const struct ANASTASIS_CRYPTO_KeyShareP *key_share, | ||
414 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
415 | const char *xsalt, | ||
416 | struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share) | ||
417 | { | ||
418 | const char *salt = "eks"; | ||
419 | size_t eks_size = 0; | ||
420 | void *eks = NULL; | ||
421 | struct ANASTASIS_CRYPTO_NonceP nonce; | ||
422 | |||
423 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
424 | &nonce, | ||
425 | sizeof (nonce)); | ||
426 | anastasis_encrypt (&nonce, | ||
427 | id, | ||
428 | sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP), | ||
429 | key_share, | ||
430 | sizeof (struct ANASTASIS_CRYPTO_KeyShareP), | ||
431 | (NULL == xsalt) ? salt : xsalt, | ||
432 | &eks, | ||
433 | &eks_size); | ||
434 | GNUNET_assert (eks_size == | ||
435 | sizeof (struct ANASTASIS_CRYPTO_EncryptedKeyShareP)); | ||
436 | memcpy (enc_key_share, | ||
437 | eks, | ||
438 | sizeof (struct ANASTASIS_CRYPTO_EncryptedKeyShareP)); | ||
439 | GNUNET_free (eks); | ||
440 | } | ||
441 | |||
442 | |||
443 | void | ||
444 | ANASTASIS_CRYPTO_keyshare_decrypt ( | ||
445 | const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share, | ||
446 | const struct ANASTASIS_CRYPTO_UserIdentifierP *id, | ||
447 | const char *xsalt, | ||
448 | struct ANASTASIS_CRYPTO_KeyShareP *key_share) | ||
449 | { | ||
450 | const char *salt = "eks"; | ||
451 | size_t ks_size = 0; | ||
452 | void *ks = NULL; | ||
453 | |||
454 | anastasis_decrypt (id, | ||
455 | sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP), | ||
456 | enc_key_share, | ||
457 | sizeof (struct ANASTASIS_CRYPTO_EncryptedKeyShareP), | ||
458 | (NULL == xsalt) ? salt : xsalt, | ||
459 | &ks, | ||
460 | &ks_size); | ||
461 | GNUNET_assert (ks_size == | ||
462 | sizeof (struct ANASTASIS_CRYPTO_KeyShareP)); | ||
463 | memcpy (key_share, | ||
464 | ks, | ||
465 | sizeof (struct ANASTASIS_CRYPTO_KeyShareP)); | ||
466 | GNUNET_free (ks); | ||
467 | } | ||
468 | |||
469 | |||
470 | void | ||
471 | ANASTASIS_CRYPTO_truth_encrypt ( | ||
472 | const struct ANASTASIS_CRYPTO_NonceP *nonce, | ||
473 | const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key, | ||
474 | const void *truth, | ||
475 | size_t truth_size, | ||
476 | void **enc_truth, | ||
477 | size_t *ect_size) | ||
478 | { | ||
479 | const char *salt = "ect"; | ||
480 | |||
481 | anastasis_encrypt (nonce, | ||
482 | truth_enc_key, | ||
483 | sizeof (struct ANASTASIS_CRYPTO_TruthKeyP), | ||
484 | truth, | ||
485 | truth_size, | ||
486 | salt, | ||
487 | enc_truth, | ||
488 | ect_size); | ||
489 | } | ||
490 | |||
491 | |||
492 | void | ||
493 | ANASTASIS_CRYPTO_truth_decrypt ( | ||
494 | const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key, | ||
495 | const void *enc_truth, | ||
496 | size_t ect_size, | ||
497 | void **truth, | ||
498 | size_t *truth_size) | ||
499 | { | ||
500 | const char *salt = "ect"; | ||
501 | |||
502 | anastasis_decrypt (truth_enc_key, | ||
503 | sizeof (struct ANASTASIS_CRYPTO_TruthKeyP), | ||
504 | enc_truth, | ||
505 | ect_size, | ||
506 | salt, | ||
507 | truth, | ||
508 | truth_size); | ||
509 | } | ||
510 | |||
511 | |||
512 | void | ||
513 | ANASTASIS_CRYPTO_keyshare_create ( | ||
514 | struct ANASTASIS_CRYPTO_KeyShareP *key_share) | ||
515 | { | ||
516 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, | ||
517 | key_share, | ||
518 | sizeof (struct ANASTASIS_CRYPTO_KeyShareP)); | ||
519 | } | ||
520 | |||
521 | |||
522 | void | ||
523 | ANASTASIS_CRYPTO_policy_key_derive ( | ||
524 | const struct ANASTASIS_CRYPTO_KeyShareP *key_shares, | ||
525 | unsigned int keyshare_length, | ||
526 | const struct ANASTASIS_CRYPTO_MasterSaltP *salt, | ||
527 | struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key) | ||
528 | { | ||
529 | GNUNET_CRYPTO_hkdf (policy_key, | ||
530 | sizeof (*policy_key), | ||
531 | GCRY_MD_SHA512, | ||
532 | GCRY_MD_SHA256, | ||
533 | key_shares, | ||
534 | keyshare_length * sizeof (*key_shares), | ||
535 | salt, | ||
536 | sizeof (*salt), | ||
537 | NULL, 0); | ||
538 | } | ||
539 | |||
540 | |||
541 | void | ||
542 | ANASTASIS_CRYPTO_core_secret_encrypt ( | ||
543 | const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys, | ||
544 | unsigned int policy_keys_length, | ||
545 | const void *core_secret, | ||
546 | size_t core_secret_size, | ||
547 | void **enc_core_secret, | ||
548 | struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys) | ||
549 | { | ||
550 | struct GNUNET_CRYPTO_SymmetricSessionKey sk; | ||
551 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
552 | struct GNUNET_HashCode master_key; | ||
553 | |||
554 | *enc_core_secret = GNUNET_malloc (core_secret_size); | ||
555 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, | ||
556 | &master_key, | ||
557 | sizeof (struct GNUNET_HashCode)); | ||
558 | GNUNET_CRYPTO_hash_to_aes_key (&master_key, | ||
559 | &sk, | ||
560 | &iv); | ||
561 | GNUNET_assert (GNUNET_SYSERR != | ||
562 | GNUNET_CRYPTO_symmetric_encrypt (core_secret, | ||
563 | core_secret_size, | ||
564 | &sk, | ||
565 | &iv, | ||
566 | *enc_core_secret)); | ||
567 | for (unsigned int i = 0; i < policy_keys_length; i++) | ||
568 | { | ||
569 | struct GNUNET_CRYPTO_SymmetricSessionKey i_sk; | ||
570 | struct GNUNET_CRYPTO_SymmetricInitializationVector i_iv; | ||
571 | struct GNUNET_HashCode key = policy_keys[i].key; | ||
572 | |||
573 | GNUNET_CRYPTO_hash_to_aes_key (&key, | ||
574 | &i_sk, | ||
575 | &i_iv); | ||
576 | GNUNET_assert ( | ||
577 | GNUNET_SYSERR != | ||
578 | GNUNET_CRYPTO_symmetric_encrypt (&master_key, | ||
579 | sizeof (struct GNUNET_HashCode), | ||
580 | &i_sk, | ||
581 | &i_iv, | ||
582 | &encrypted_master_keys[i])); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | |||
587 | void | ||
588 | ANASTASIS_CRYPTO_core_secret_recover ( | ||
589 | const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key, | ||
590 | const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key, | ||
591 | const void *encrypted_core_secret, | ||
592 | size_t encrypted_core_secret_size, | ||
593 | void **core_secret, | ||
594 | size_t *core_secret_size) | ||
595 | { | ||
596 | struct GNUNET_CRYPTO_SymmetricSessionKey mk_sk; | ||
597 | struct GNUNET_CRYPTO_SymmetricInitializationVector mk_iv; | ||
598 | struct GNUNET_CRYPTO_SymmetricSessionKey core_sk; | ||
599 | struct GNUNET_CRYPTO_SymmetricInitializationVector core_iv; | ||
600 | struct GNUNET_HashCode master_key; | ||
601 | struct GNUNET_HashCode key = policy_key->key; | ||
602 | |||
603 | *core_secret = GNUNET_malloc (encrypted_core_secret_size); | ||
604 | GNUNET_CRYPTO_hash_to_aes_key (&key, | ||
605 | &mk_sk, | ||
606 | &mk_iv); | ||
607 | GNUNET_assert ( | ||
608 | GNUNET_SYSERR != | ||
609 | GNUNET_CRYPTO_symmetric_decrypt ( | ||
610 | encrypted_master_key, | ||
611 | sizeof (struct ANASTASIS_CRYPTO_EncryptedMasterKeyP), | ||
612 | &mk_sk, | ||
613 | &mk_iv, | ||
614 | &master_key)); | ||
615 | GNUNET_CRYPTO_hash_to_aes_key (&master_key, | ||
616 | &core_sk, | ||
617 | &core_iv); | ||
618 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
619 | "At %s:%d encrypted core secret is %s-%llu b\n", __FILE__, | ||
620 | __LINE__, | ||
621 | TALER_b2s (encrypted_core_secret, encrypted_core_secret_size), | ||
622 | (unsigned long long) encrypted_core_secret_size); | ||
623 | *core_secret_size = GNUNET_CRYPTO_symmetric_decrypt (encrypted_core_secret, | ||
624 | encrypted_core_secret_size, | ||
625 | &core_sk, | ||
626 | &core_iv, | ||
627 | *core_secret); | ||
628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
629 | "At %s:%d decrypted core secret is %s-%llu b\n", __FILE__, | ||
630 | __LINE__, | ||
631 | TALER_b2s (*core_secret, *core_secret_size), | ||
632 | (unsigned long long) *core_secret_size); | ||
633 | GNUNET_assert (GNUNET_SYSERR != *core_secret_size); | ||
634 | } | ||
635 | |||
636 | |||
637 | /* end of anastasis_crypto.c */ | ||