GNUnet  0.10.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", __VA_ARGS__)
33 
39 void
41 {
42  gcry_randomize(key->aes_key,
44  GCRY_STRONG_RANDOM);
45  gcry_randomize(key->twofish_key,
47  GCRY_STRONG_RANDOM);
48 }
49 
50 
59 static int
60 setup_cipher_aes(gcry_cipher_hd_t *handle,
61  const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
63 {
64  int rc;
65 
66  GNUNET_assert(0 ==
67  gcry_cipher_open(handle, GCRY_CIPHER_AES256,
68  GCRY_CIPHER_MODE_CFB, 0));
69  rc = gcry_cipher_setkey(*handle,
70  sessionkey->aes_key,
71  sizeof(sessionkey->aes_key));
72  GNUNET_assert((0 == rc) || ((char)rc == GPG_ERR_WEAK_KEY));
73  rc = gcry_cipher_setiv(*handle,
74  iv->aes_iv,
75  sizeof(iv->aes_iv));
76  GNUNET_assert((0 == rc) || ((char)rc == GPG_ERR_WEAK_KEY));
77  return GNUNET_OK;
78 }
79 
80 
89 static int
90 setup_cipher_twofish(gcry_cipher_hd_t *handle,
91  const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
93 {
94  int rc;
95 
96  GNUNET_assert(0 ==
97  gcry_cipher_open(handle, GCRY_CIPHER_TWOFISH,
98  GCRY_CIPHER_MODE_CFB, 0));
99  rc = gcry_cipher_setkey(*handle,
100  sessionkey->twofish_key,
101  sizeof(sessionkey->twofish_key));
102  GNUNET_assert((0 == rc) || ((char)rc == GPG_ERR_WEAK_KEY));
103  rc = gcry_cipher_setiv(*handle,
104  iv->twofish_iv,
105  sizeof(iv->twofish_iv));
106  GNUNET_assert((0 == rc) || ((char)rc == GPG_ERR_WEAK_KEY));
107  return GNUNET_OK;
108 }
109 
110 
124 ssize_t
126  size_t size,
127  const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
129  void *result)
130 {
131  gcry_cipher_hd_t handle;
132  char tmp[size];
133 
134  if (GNUNET_OK != setup_cipher_aes(&handle, sessionkey, iv))
135  return -1;
136  GNUNET_assert(0 == gcry_cipher_encrypt(handle, tmp, size, block, size));
137  gcry_cipher_close(handle);
138  if (GNUNET_OK != setup_cipher_twofish(&handle, sessionkey, iv))
139  return -1;
140  GNUNET_assert(0 == gcry_cipher_encrypt(handle, result, size, tmp, size));
141  gcry_cipher_close(handle);
142  memset(tmp, 0, sizeof(tmp));
143  return size;
144 }
145 
146 
160 ssize_t
162  size_t size,
163  const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
165  void *result)
166 {
167  gcry_cipher_hd_t handle;
168  char tmp[size];
169 
170  if (GNUNET_OK != setup_cipher_twofish(&handle, sessionkey, iv))
171  return -1;
172  GNUNET_assert(0 == gcry_cipher_decrypt(handle, tmp, size, block, size));
173  gcry_cipher_close(handle);
174  if (GNUNET_OK != setup_cipher_aes(&handle, sessionkey, iv))
175  return -1;
176  GNUNET_assert(0 == gcry_cipher_decrypt(handle, result, size, tmp, size));
177  gcry_cipher_close(handle);
178  memset(tmp, 0, sizeof(tmp));
179  return size;
180 }
181 
182 
192 void
194  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
195  const void *salt,
196  size_t salt_len,
197  ...)
198 {
199  va_list argp;
200 
201  va_start(argp, salt_len);
202  GNUNET_CRYPTO_symmetric_derive_iv_v(iv, skey, salt, salt_len, argp);
203  va_end(argp);
204 }
205 
206 
216 void
218  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
219  const void *salt,
220  size_t salt_len,
221  va_list argp)
222 {
223  char aes_salt[salt_len + 4];
224  char twofish_salt[salt_len + 4];
225 
226  GNUNET_memcpy(aes_salt, salt, salt_len);
227  GNUNET_memcpy(&aes_salt[salt_len], "AES!", 4);
228  GNUNET_memcpy(twofish_salt, salt, salt_len);
229  GNUNET_memcpy(&twofish_salt[salt_len], "FISH", 4);
231  sizeof(iv->aes_iv),
232  aes_salt,
233  salt_len + 4,
234  skey->aes_key,
235  sizeof(skey->aes_key),
236  argp);
238  sizeof(iv->twofish_iv),
239  twofish_salt,
240  salt_len + 4,
241  skey->twofish_key,
242  sizeof(skey->twofish_key),
243  argp);
244 }
245 
246 /* 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:66
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.