diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-09-30 11:22:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-09-30 11:22:48 +0000 |
commit | 05ef63d9f8cf65561b7ed2234efdc80e3fb40bd0 (patch) | |
tree | 7c00b58220e87d7f2f050b46e0e2f59c3795e703 /src/util/crypto_aes.c | |
parent | 814457c05d62c8f0c167c6bc2015201151355249 (diff) | |
download | gnunet-05ef63d9f8cf65561b7ed2234efdc80e3fb40bd0.tar.gz gnunet-05ef63d9f8cf65561b7ed2234efdc80e3fb40bd0.zip |
-encrypt using both AES and TWOFISH, with independent symmetric keys
Diffstat (limited to 'src/util/crypto_aes.c')
-rw-r--r-- | src/util/crypto_aes.c | 110 |
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 | */ |
40 | void | 40 | void |
41 | GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key) | 41 | GNUNET_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 | */ |
56 | static int | 60 | static int |
57 | setup_cipher (gcry_cipher_hd_t *handle, | 61 | setup_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 | */ | ||
90 | static int | ||
91 | setup_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 | */ |
118 | ssize_t | 158 | ssize_t |
119 | GNUNET_CRYPTO_aes_decrypt (const void *block, size_t size, | 159 | GNUNET_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 | */ |
144 | void | 189 | void |
@@ -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 */ |