GNUnet  0.11.x
crypto_symmetric.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2013 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 
28 #include "platform.h"
29 #include "gnunet_crypto_lib.h"
30 #include <gcrypt.h>
31 
32 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-symmetric", \
33  __VA_ARGS__)
34 
40 void
43  key)
44 {
45  gcry_randomize (key->aes_key,
47  GCRY_STRONG_RANDOM);
48  gcry_randomize (key->twofish_key,
50  GCRY_STRONG_RANDOM);
51 }
52 
53 
62 static int
63 setup_cipher_aes (gcry_cipher_hd_t *handle,
64  const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
66 {
67  int rc;
68 
69  GNUNET_assert (0 ==
70  gcry_cipher_open (handle, GCRY_CIPHER_AES256,
71  GCRY_CIPHER_MODE_CFB, 0));
72  rc = gcry_cipher_setkey (*handle,
73  sessionkey->aes_key,
74  sizeof(sessionkey->aes_key));
75  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
76  rc = gcry_cipher_setiv (*handle,
77  iv->aes_iv,
78  sizeof(iv->aes_iv));
79  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
80  return GNUNET_OK;
81 }
82 
83 
92 static int
93 setup_cipher_twofish (gcry_cipher_hd_t *handle,
94  const struct
96  const struct
98 {
99  int rc;
100 
101  GNUNET_assert (0 ==
102  gcry_cipher_open (handle, GCRY_CIPHER_TWOFISH,
103  GCRY_CIPHER_MODE_CFB, 0));
104  rc = gcry_cipher_setkey (*handle,
105  sessionkey->twofish_key,
106  sizeof(sessionkey->twofish_key));
107  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
108  rc = gcry_cipher_setiv (*handle,
109  iv->twofish_iv,
110  sizeof(iv->twofish_iv));
111  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
112  return GNUNET_OK;
113 }
114 
115 
129 ssize_t
131  size_t size,
132  const struct
134  const struct
136  void *result)
137 {
138  gcry_cipher_hd_t handle;
139  char tmp[size];
140 
141  if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
142  return -1;
143  GNUNET_assert (0 == gcry_cipher_encrypt (handle, tmp, size, block, size));
144  gcry_cipher_close (handle);
145  if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
146  return -1;
147  GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, tmp, size));
148  gcry_cipher_close (handle);
149  memset (tmp, 0, sizeof(tmp));
150  return size;
151 }
152 
153 
167 ssize_t
169  size_t size,
170  const struct
172  const struct
174  void *result)
175 {
176  gcry_cipher_hd_t handle;
177  char tmp[size];
178 
179  if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
180  return -1;
181  GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, block, size));
182  gcry_cipher_close (handle);
183  if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
184  return -1;
185  GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, tmp, size));
186  gcry_cipher_close (handle);
187  memset (tmp, 0, sizeof(tmp));
188  return size;
189 }
190 
191 
201 void
204  iv,
205  const struct
207  const void *salt,
208  size_t salt_len,
209  ...)
210 {
211  va_list argp;
212 
213  va_start (argp, salt_len);
214  GNUNET_CRYPTO_symmetric_derive_iv_v (iv, skey, salt, salt_len, argp);
215  va_end (argp);
216 }
217 
218 
228 void
231  *iv,
232  const struct
234  const void *salt,
235  size_t salt_len,
236  va_list argp)
237 {
238  char aes_salt[salt_len + 4];
239  char twofish_salt[salt_len + 4];
240 
241  GNUNET_memcpy (aes_salt, salt, salt_len);
242  GNUNET_memcpy (&aes_salt[salt_len], "AES!", 4);
243  GNUNET_memcpy (twofish_salt, salt, salt_len);
244  GNUNET_memcpy (&twofish_salt[salt_len], "FISH", 4);
246  sizeof(iv->aes_iv),
247  aes_salt,
248  salt_len + 4,
249  skey->aes_key,
250  sizeof(skey->aes_key),
251  argp);
253  sizeof(iv->twofish_iv),
254  twofish_salt,
255  salt_len + 4,
256  skey->twofish_key,
257  sizeof(skey->twofish_key),
258  argp);
259 }
260 
261 
262 /* end of crypto_symmetric.c */
static int setup_cipher_aes(gcry_cipher_hd_t *handle, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Initialize AES cipher.
void GNUNET_CRYPTO_symmetric_create_session_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key)
Create a new SessionKey (for symmetric encryption).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
unsigned char aes_key[(256/8)]
Actual key for AES.
cryptographic primitives for GNUnet
void GNUNET_CRYPTO_symmetric_derive_iv_v(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len, va_list argp)
Derive an IV.
unsigned char twofish_key[(256/8)]
Actual key for TwoFish.
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block with a symmetric session key.
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
#define GNUNET_CRYPTO_AES_KEY_LENGTH
length of the sessionkey in bytes (256 BIT sessionkey)
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
static int setup_cipher_twofish(gcry_cipher_hd_t *handle, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Initialize TWOFISH cipher.
int GNUNET_CRYPTO_kdf_v(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp)
Derive key.
Definition: crypto_kdf.c:47
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block with the session key.