GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
Loading...
Searching...
No Matches
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
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include <gcrypt.h>
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-symmetric", \
34 __VA_ARGS__)
35
41void
44 key)
45{
46 gcry_randomize (key->aes_key,
48 GCRY_STRONG_RANDOM);
49 gcry_randomize (key->twofish_key,
51 GCRY_STRONG_RANDOM);
52}
53
54
63static int
64setup_cipher_aes (gcry_cipher_hd_t *handle,
65 const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
67{
68 int rc;
69
70 GNUNET_assert (0 ==
71 gcry_cipher_open (handle, GCRY_CIPHER_AES256,
72 GCRY_CIPHER_MODE_CFB, 0));
73 rc = gcry_cipher_setkey (*handle,
74 sessionkey->aes_key,
75 sizeof(sessionkey->aes_key));
76 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
77 rc = gcry_cipher_setiv (*handle,
78 iv->aes_iv,
79 sizeof(iv->aes_iv));
80 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
81 return GNUNET_OK;
82}
83
84
93static int
94setup_cipher_twofish (gcry_cipher_hd_t *handle,
95 const struct
97 const struct
99{
100 int rc;
101
102 GNUNET_assert (0 ==
103 gcry_cipher_open (handle, GCRY_CIPHER_TWOFISH,
104 GCRY_CIPHER_MODE_CFB, 0));
105 rc = gcry_cipher_setkey (*handle,
106 sessionkey->twofish_key,
107 sizeof(sessionkey->twofish_key));
108 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
109 rc = gcry_cipher_setiv (*handle,
110 iv->twofish_iv,
111 sizeof(iv->twofish_iv));
112 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
113 return GNUNET_OK;
114}
115
116
117ssize_t
119 size_t size,
120 const struct
122 const struct
124 ,
125 void *result)
126{
127 gcry_cipher_hd_t handle;
128 char tmp[GNUNET_NZL (size)];
129
130 if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
131 return -1;
132 GNUNET_assert (0 == gcry_cipher_encrypt (handle, tmp, size, block, size));
133 gcry_cipher_close (handle);
134 if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
135 return -1;
136 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, tmp, size));
137 gcry_cipher_close (handle);
138 memset (tmp, 0, sizeof(tmp));
139 return size;
140}
141
142
143ssize_t
145 size_t size,
146 const struct
148 const struct
150 ,
151 void *result)
152{
153 gcry_cipher_hd_t handle;
154 char tmp[size];
155
156 if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
157 return -1;
158 GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, block, size));
159 gcry_cipher_close (handle);
160 if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
161 return -1;
162 GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, tmp, size));
163 gcry_cipher_close (handle);
164 memset (tmp, 0, sizeof(tmp));
165 return size;
166}
167
168
169void
171 const void *in_buf,
172 size_t in_buf_len,
173 const unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH],
174 const unsigned char iv[GNUNET_CRYPTO_AES_IV_LENGTH],
175 void *out_buf)
176{
177 gcry_cipher_hd_t handle;
178 int rc;
179
180 GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
181 GCRY_CIPHER_MODE_CTR, 0));
182 rc = gcry_cipher_setkey (handle,
183 key,
185 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
186 rc = gcry_cipher_setctr (handle,
187 iv,
189 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
190 GNUNET_assert (0 == gcry_cipher_encrypt (handle, out_buf, in_buf_len, in_buf,
191 in_buf_len));
192 gcry_cipher_close (handle);
193}
194
195
198 size_t in_buf_len,
199 const unsigned char in_buf[in_buf_len],
201 const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce,
202 void *out_buf)
203{
204 ssize_t ctlen = in_buf_len - crypto_secretbox_xsalsa20poly1305_MACBYTES;
205 if (ctlen < 0)
206 return GNUNET_SYSERR;
207 if (0 != crypto_secretbox_open_detached (
208 out_buf,
209 in_buf
210 + crypto_secretbox_xsalsa20poly1305_MACBYTES, // Ciphertext
211 in_buf, // Tag
212 ctlen,
213 nonce->nonce,
214 key->key))
215 {
216 return GNUNET_SYSERR;
217 }
218 return GNUNET_OK;
219
220}
221
222
225 size_t in_buf_len,
226 const unsigned char in_buf[in_buf_len],
228 const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce,
229 void *out_buf)
230{
231 if (in_buf_len > crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX)
232 return GNUNET_SYSERR;
233 crypto_secretbox_detached (out_buf
234 + crypto_secretbox_xsalsa20poly1305_MACBYTES, // Ciphertext
235 out_buf, // TAG
236 in_buf,
237 in_buf_len,
238 nonce->nonce,
239 key->key);
240 return GNUNET_OK;
241}
242
243
246 size_t ct_len,
247 const unsigned char ct[ct_len],
248 size_t aad_len,
249 const unsigned char aad[aad_len],
250 const struct GNUNET_CRYPTO_AeadSecretKey *key,
251 const struct GNUNET_CRYPTO_AeadNonce *nonce,
252 const struct GNUNET_CRYPTO_AeadMac *mac,
253 void *pt)
254{
255 if (0 != crypto_aead_xchacha20poly1305_ietf_decrypt_detached (
256 pt,
257 NULL,
258 ct, // Tag
259 ct_len,
260 mac->mac,
261 aad,
262 aad_len,
263 nonce->npub,
264 key->k))
265 {
266 return GNUNET_SYSERR;
267 }
268 return GNUNET_OK;
269
270}
271
272
275 size_t pt_len,
276 const unsigned char pt[pt_len],
277 size_t aad_len,
278 const unsigned char aad[aad_len],
279 const struct GNUNET_CRYPTO_AeadSecretKey *key,
280 const struct GNUNET_CRYPTO_AeadNonce *nonce,
281 void *ct,
282 struct GNUNET_CRYPTO_AeadMac *mac)
283{
284 crypto_aead_xchacha20poly1305_ietf_encrypt_detached (ct, // Ciphertext
285 mac->mac, // TAG
286 NULL,
287 pt,
288 pt_len,
289 aad,
290 aad_len,
291 NULL,
292 nonce->npub,
293 key->k);
294 return GNUNET_OK;
295}
296
297
298void
300{
301 crypto_aead_xchacha20poly1305_ietf_keygen (key->k);
302}
303
304
305/* 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_aes_ctr(const void *in_buf, size_t in_buf_len, const unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH], const unsigned char iv[GNUNET_CRYPTO_AES_IV_LENGTH], void *out_buf)
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.
struct GNUNET_HashCode key
The key used in the DHT.
static int result
Global testing status.
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
void GNUNET_CRYPTO_symmetric_create_session_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key)
Create a new SessionKey (for symmetric encryption).
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_decrypt(size_t ct_len, const unsigned char ct[ct_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, const struct GNUNET_CRYPTO_AeadMac *mac, void *pt)
Decrypt the given data using XChaCha20-Poly1305.
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 using a symmetric sessionkey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_encrypt(size_t pt_len, const unsigned char pt[pt_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, void *ct, struct GNUNET_CRYPTO_AeadMac *mac)
Encrypt the given data using XChaCha20-Poly1305.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_xsalsa20poly1305_decrypt(size_t in_buf_len, const unsigned char in_buf[in_buf_len], const struct GNUNET_CRYPTO_XSalsa20SecretKey *key, const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce, void *out_buf)
Encrypt the given data using XSalsa20-Poly1305.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_xsalsa20poly1305_encrypt(size_t in_buf_len, const unsigned char in_buf[in_buf_len], const struct GNUNET_CRYPTO_XSalsa20SecretKey *key, const struct GNUNET_CRYPTO_XSalsa20Nonce *nonce, void *out_buf)
Encrypt the given data using XSalsa20-Poly1305.
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 using a symmetric sessionkey.
#define GNUNET_CRYPTO_AES_IV_LENGTH
length of an AES key in bytes
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
#define GNUNET_CRYPTO_AES_KEY_LENGTH
length of the sessionkey in bytes
void GNUNET_CRYPTO_aead_create_key(struct GNUNET_CRYPTO_AeadSecretKey *key)
Create a new AEAD key.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static unsigned int size
Size of the "table".
Definition peer.c:68
type for session keys
unsigned char mac[16]
Initialization vector.
type for session keys
unsigned char npub[24]
Initialization vector.
unsigned char twofish_key[(256/8)]
Actual key for TwoFish.
unsigned char aes_key[(256/8)]
Actual key for AES.
unsigned char nonce[24]
Initialization vector.