diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-01-17 13:45:01 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-01-17 13:45:01 +0100 |
commit | 551d36ad77df853998aa5726bd7d26c945122270 (patch) | |
tree | f5f3db4cfd14167f661cbfa06c2206cafc7cb713 | |
parent | ae5feca119e594767102ce7bcc17d1a3b7580a52 (diff) | |
download | libgnunetchat-551d36ad77df853998aa5726bd7d26c945122270.tar.gz libgnunetchat-551d36ad77df853998aa5726bd7d26c945122270.zip |
Fixed file encryption to not be stack limited
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | src/gnunet_chat_util.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c index 775e856..9876f8b 100644 --- a/src/gnunet_chat_util.c +++ b/src/gnunet_chat_util.c | |||
@@ -103,21 +103,47 @@ util_encrypt_file (const char *filename, | |||
103 | if (!file) | 103 | if (!file) |
104 | return GNUNET_SYSERR; | 104 | return GNUNET_SYSERR; |
105 | 105 | ||
106 | struct GNUNET_DISK_MapHandle *mapping; | 106 | struct GNUNET_DISK_MapHandle *mapping = NULL; |
107 | void* data = GNUNET_DISK_file_map( | 107 | void* data = GNUNET_DISK_file_map( |
108 | file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size | 108 | file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size |
109 | ); | 109 | ); |
110 | 110 | ||
111 | if (!data) | 111 | if ((!data) || (!mapping)) |
112 | { | 112 | { |
113 | GNUNET_DISK_file_close(file); | 113 | GNUNET_DISK_file_close(file); |
114 | return GNUNET_SYSERR; | 114 | return GNUNET_SYSERR; |
115 | } | 115 | } |
116 | 116 | ||
117 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 117 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
118 | memset(&iv, 0, sizeof(iv)); | 118 | const uint64_t block_size = 1024*1024; |
119 | ssize_t result = -1; | ||
120 | |||
121 | const uint64_t blocks = ((size + block_size - 1) / block_size); | ||
119 | 122 | ||
120 | ssize_t result = GNUNET_CRYPTO_symmetric_encrypt(data, size, key, &iv, data); | 123 | for (uint64_t i = 0; i < blocks; i++) |
124 | { | ||
125 | const uint64_t index = (blocks - i - 1); | ||
126 | const uint64_t offset = block_size * index; | ||
127 | |||
128 | const uint64_t remaining = (size - offset); | ||
129 | void* location = ((uint8_t*) data) + offset; | ||
130 | |||
131 | if (index > 0) | ||
132 | memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); | ||
133 | else | ||
134 | memset(&iv, 0, sizeof(iv)); | ||
135 | |||
136 | result = GNUNET_CRYPTO_symmetric_encrypt( | ||
137 | location, | ||
138 | remaining >= block_size? block_size : remaining, | ||
139 | key, | ||
140 | &iv, | ||
141 | location | ||
142 | ); | ||
143 | |||
144 | if (result < 0) | ||
145 | break; | ||
146 | } | ||
121 | 147 | ||
122 | if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) | 148 | if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) |
123 | result = -1; | 149 | result = -1; |
@@ -153,21 +179,46 @@ util_decrypt_file (const char *filename, | |||
153 | if (!file) | 179 | if (!file) |
154 | return GNUNET_SYSERR; | 180 | return GNUNET_SYSERR; |
155 | 181 | ||
156 | struct GNUNET_DISK_MapHandle *mapping; | 182 | struct GNUNET_DISK_MapHandle *mapping = NULL; |
157 | void* data = GNUNET_DISK_file_map( | 183 | void* data = GNUNET_DISK_file_map( |
158 | file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size | 184 | file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size |
159 | ); | 185 | ); |
160 | 186 | ||
161 | if (!data) | 187 | if ((!data) || (!mapping)) |
162 | { | 188 | { |
163 | GNUNET_DISK_file_close(file); | 189 | GNUNET_DISK_file_close(file); |
164 | return GNUNET_SYSERR; | 190 | return GNUNET_SYSERR; |
165 | } | 191 | } |
166 | 192 | ||
167 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 193 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
168 | memset(&iv, 0, sizeof(iv)); | 194 | const uint64_t block_size = 1024*1024; |
195 | ssize_t result = -1; | ||
196 | |||
197 | const uint64_t blocks = ((size + block_size - 1) / block_size); | ||
169 | 198 | ||
170 | ssize_t result = GNUNET_CRYPTO_symmetric_decrypt(data, size, key, &iv, data); | 199 | for (uint64_t index = 0; index < blocks; index++) |
200 | { | ||
201 | const uint64_t offset = block_size * index; | ||
202 | |||
203 | const uint64_t remaining = (size - offset); | ||
204 | void* location = ((uint8_t*) data) + offset; | ||
205 | |||
206 | if (index > 0) | ||
207 | memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); | ||
208 | else | ||
209 | memset(&iv, 0, sizeof(iv)); | ||
210 | |||
211 | result = GNUNET_CRYPTO_symmetric_decrypt( | ||
212 | location, | ||
213 | remaining >= block_size? block_size : remaining, | ||
214 | key, | ||
215 | &iv, | ||
216 | location | ||
217 | ); | ||
218 | |||
219 | if (result < 0) | ||
220 | break; | ||
221 | } | ||
171 | 222 | ||
172 | if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) | 223 | if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) |
173 | result = -1; | 224 | result = -1; |