aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_aes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_aes.c')
-rw-r--r--src/util/crypto_aes.c110
1 files changed, 84 insertions, 26 deletions
diff --git a/src/util/crypto_aes.c b/src/util/crypto_aes.c
index f475494f8..91c578ab8 100644
--- a/src/util/crypto_aes.c
+++ b/src/util/crypto_aes.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file util/crypto_aes.c 22 * @file util/crypto_aes.c
23 * @brief Symmetric encryption services. 23 * @brief Symmetric encryption services; combined cipher AES+TWOFISH (256-bit each)
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Ioana Patrascu 25 * @author Ioana Patrascu
26 */ 26 */
@@ -33,14 +33,18 @@
33#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 33#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
34 34
35/** 35/**
36 * Create a new SessionKey (for AES-256). 36 * Create a new SessionKey (for symmetric encryption).
37 * 37 *
38 * @param key session key to initialize 38 * @param key session key to initialize
39 */ 39 */
40void 40void
41GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key) 41GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key)
42{ 42{
43 gcry_randomize (&key->key[0], GNUNET_CRYPTO_AES_KEY_LENGTH, 43 gcry_randomize (key->aes_key,
44 GNUNET_CRYPTO_AES_KEY_LENGTH,
45 GCRY_STRONG_RANDOM);
46 gcry_randomize (key->twofish_key,
47 GNUNET_CRYPTO_AES_KEY_LENGTH,
44 GCRY_STRONG_RANDOM); 48 GCRY_STRONG_RANDOM);
45} 49}
46 50
@@ -54,22 +58,52 @@ GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key)
54 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 58 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
55 */ 59 */
56static int 60static int
57setup_cipher (gcry_cipher_hd_t *handle, 61setup_cipher_aes (gcry_cipher_hd_t *handle,
58 const struct GNUNET_CRYPTO_AesSessionKey * 62 const struct GNUNET_CRYPTO_AesSessionKey *sessionkey,
59 sessionkey, 63 const struct GNUNET_CRYPTO_AesInitializationVector *iv)
60 const struct GNUNET_CRYPTO_AesInitializationVector *
61 iv)
62{ 64{
63 int rc; 65 int rc;
64 66
65 GNUNET_assert (0 == 67 GNUNET_assert (0 ==
66 gcry_cipher_open (handle, GCRY_CIPHER_AES256, 68 gcry_cipher_open (handle, GCRY_CIPHER_AES256,
67 GCRY_CIPHER_MODE_CFB, 0)); 69 GCRY_CIPHER_MODE_CFB, 0));
68 rc = gcry_cipher_setkey (*handle, sessionkey, GNUNET_CRYPTO_AES_KEY_LENGTH); 70 rc = gcry_cipher_setkey (*handle,
71 sessionkey->aes_key,
72 sizeof (sessionkey->aes_key));
69 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); 73 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
70 rc = gcry_cipher_setiv (*handle, iv, 74 rc = gcry_cipher_setiv (*handle,
71 sizeof (struct 75 iv->aes_iv,
72 GNUNET_CRYPTO_AesInitializationVector)); 76 sizeof (iv->aes_iv));
77 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
78 return GNUNET_OK;
79}
80
81
82/**
83 * Initialize TWOFISH cipher.
84 *
85 * @param handle handle to initialize
86 * @param sessionkey session key to use
87 * @param iv initialization vector to use
88 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
89 */
90static int
91setup_cipher_twofish (gcry_cipher_hd_t *handle,
92 const struct GNUNET_CRYPTO_AesSessionKey *sessionkey,
93 const struct GNUNET_CRYPTO_AesInitializationVector *iv)
94{
95 int rc;
96
97 GNUNET_assert (0 ==
98 gcry_cipher_open (handle, GCRY_CIPHER_TWOFISH,
99 GCRY_CIPHER_MODE_CFB, 0));
100 rc = gcry_cipher_setkey (*handle,
101 sessionkey->twofish_key,
102 sizeof (sessionkey->twofish_key));
103 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
104 rc = gcry_cipher_setiv (*handle,
105 iv->twofish_iv,
106 sizeof (iv->twofish_iv));
73 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); 107 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
74 return GNUNET_OK; 108 return GNUNET_OK;
75} 109}
@@ -80,7 +114,7 @@ setup_cipher (gcry_cipher_hd_t *handle,
80 * host that uses the same cyper. 114 * host that uses the same cyper.
81 * 115 *
82 * @param block the block to encrypt 116 * @param block the block to encrypt
83 * @param len the size of the block 117 * @param len the size of the @a block
84 * @param sessionkey the key used to encrypt 118 * @param sessionkey the key used to encrypt
85 * @param iv the initialization vector to use, use INITVALUE 119 * @param iv the initialization vector to use, use INITVALUE
86 * for streams. 120 * for streams.
@@ -95,11 +129,17 @@ GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len,
95 iv, void *result) 129 iv, void *result)
96{ 130{
97 gcry_cipher_hd_t handle; 131 gcry_cipher_hd_t handle;
132 char tmp[len];
98 133
99 if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv)) 134 if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
135 return -1;
136 GNUNET_assert (0 == gcry_cipher_encrypt (handle, tmp, len, block, len));
137 gcry_cipher_close (handle);
138 if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
100 return -1; 139 return -1;
101 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, len, block, len)); 140 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, len, tmp, len));
102 gcry_cipher_close (handle); 141 gcry_cipher_close (handle);
142 memset (tmp, 0, sizeof (tmp));
103 return len; 143 return len;
104} 144}
105 145
@@ -108,7 +148,7 @@ GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len,
108 * Decrypt a given block with the sessionkey. 148 * Decrypt a given block with the sessionkey.
109 * 149 *
110 * @param block the data to decrypt, encoded as returned by encrypt 150 * @param block the data to decrypt, encoded as returned by encrypt
111 * @param size the size of the block to decrypt 151 * @param size the size of the @a block to decrypt
112 * @param sessionkey the key used to decrypt 152 * @param sessionkey the key used to decrypt
113 * @param iv the initialization vector to use, use INITVALUE 153 * @param iv the initialization vector to use, use INITVALUE
114 * for streams. 154 * for streams.
@@ -117,17 +157,22 @@ GNUNET_CRYPTO_aes_encrypt (const void *block, size_t len,
117 */ 157 */
118ssize_t 158ssize_t
119GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size, 159GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size,
120 const struct GNUNET_CRYPTO_AesSessionKey * 160 const struct GNUNET_CRYPTO_AesSessionKey *sessionkey,
121 sessionkey, 161 const struct GNUNET_CRYPTO_AesInitializationVector *iv,
122 const struct GNUNET_CRYPTO_AesInitializationVector * 162 void *result)
123 iv, void *result)
124{ 163{
125 gcry_cipher_hd_t handle; 164 gcry_cipher_hd_t handle;
165 char tmp[size];
126 166
127 if (GNUNET_OK != setup_cipher (&handle, sessionkey, iv)) 167 if (GNUNET_OK != setup_cipher_twofish (&handle, sessionkey, iv))
128 return -1; 168 return -1;
129 GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size)); 169 GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, block, size));
130 gcry_cipher_close (handle); 170 gcry_cipher_close (handle);
171 if (GNUNET_OK != setup_cipher_aes (&handle, sessionkey, iv))
172 return -1;
173 GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, tmp, size));
174 gcry_cipher_close (handle);
175 memset (tmp, 0, sizeof (tmp));
131 return size; 176 return size;
132} 177}
133 178
@@ -138,7 +183,7 @@ GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size,
138 * @param iv initialization vector 183 * @param iv initialization vector
139 * @param skey session key 184 * @param skey session key
140 * @param salt salt for the derivation 185 * @param salt salt for the derivation
141 * @param salt_len size of the salt 186 * @param salt_len size of the @a salt
142 * @param ... pairs of void * & size_t for context chunks, terminated by NULL 187 * @param ... pairs of void * & size_t for context chunks, terminated by NULL
143 */ 188 */
144void 189void
@@ -168,8 +213,21 @@ GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv,
168 const struct GNUNET_CRYPTO_AesSessionKey *skey, 213 const struct GNUNET_CRYPTO_AesSessionKey *skey,
169 const void *salt, size_t salt_len, va_list argp) 214 const void *salt, size_t salt_len, va_list argp)
170{ 215{
171 GNUNET_CRYPTO_kdf_v (iv->iv, sizeof (iv->iv), salt, salt_len, skey->key, 216 char aes_salt[salt_len + 4];
172 sizeof (skey->key), argp); 217 char twofish_salt[salt_len + 4];
218
219 memcpy (aes_salt, salt, salt_len);
220 memcpy (&aes_salt[salt_len], "AES!", 4);
221 memcpy (twofish_salt, salt, salt_len);
222 memcpy (&twofish_salt[salt_len], "FISH", 4);
223 GNUNET_CRYPTO_kdf_v (iv->aes_iv, sizeof (iv->aes_iv),
224 aes_salt, salt_len + 4,
225 skey->aes_key, sizeof (skey->aes_key),
226 argp);
227 GNUNET_CRYPTO_kdf_v (iv->twofish_iv, sizeof (iv->twofish_iv),
228 twofish_salt, salt_len + 4,
229 skey->twofish_key, sizeof (skey->twofish_key),
230 argp);
173} 231}
174 232
175/* end of crypto_aes.c */ 233/* end of crypto_aes.c */