Commit | Line | Data |
---|---|---|
79ba130c | 1 | /* -*-c-*- |
2 | * | |
79ba130c | 3 | * Definitions electronic code book mode |
4 | * | |
5 | * (c) 1999 Straylight/Edgeware | |
6 | */ | |
7 | ||
45c0fd36 | 8 | /*----- Licensing notice --------------------------------------------------* |
79ba130c | 9 | * |
10 | * This file is part of Catacomb. | |
11 | * | |
12 | * Catacomb is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
45c0fd36 | 16 | * |
79ba130c | 17 | * Catacomb is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
45c0fd36 | 21 | * |
79ba130c | 22 | * You should have received a copy of the GNU Library General Public |
23 | * License along with Catacomb; if not, write to the Free | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
79ba130c | 28 | #ifndef CATACOMB_ECB_DEF_H |
29 | #define CATACOMB_ECB_DEF_H | |
30 | ||
31 | #ifdef __cplusplus | |
32 | extern "C" { | |
33 | #endif | |
34 | ||
35 | /*----- Header files ------------------------------------------------------*/ | |
36 | ||
37 | #include <assert.h> | |
38 | #include <string.h> | |
39 | ||
40 | #include <mLib/bits.h> | |
41 | #include <mLib/sub.h> | |
42 | ||
99461409 | 43 | #ifndef CATACOMB_ARENA_H |
44 | # include "arena.h" | |
45 | #endif | |
46 | ||
79ba130c | 47 | #ifndef CATACOMB_BLKC_H |
48 | # include "blkc.h" | |
49 | #endif | |
50 | ||
51 | #ifndef CATACOMB_GCIPHER_H | |
52 | # include "gcipher.h" | |
53 | #endif | |
54 | ||
99461409 | 55 | #ifndef CATACOMB_PARANOIA_H |
56 | # include "paranoia.h" | |
57 | #endif | |
58 | ||
79ba130c | 59 | /*----- Macros ------------------------------------------------------------*/ |
60 | ||
61 | /* --- @ECB_DEF@ --- * | |
62 | * | |
63 | * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher | |
64 | * | |
65 | * Use: Creates an implementation for ECB stealing mode. | |
66 | */ | |
67 | ||
aaae9cab MW |
68 | #define ECB_DEF(PRE, pre) ECB_DEFX(PRE, pre, #pre, #pre) |
69 | ||
70 | #define ECB_DEFX(PRE, pre, name, fname) \ | |
79ba130c | 71 | \ |
72 | /* --- @pre_ecbsetkey@ --- * \ | |
73 | * \ | |
74 | * Arguments: @pre_ecbctx *ctx@ = pointer to ECB context block \ | |
75 | * @const pre_ctx *k@ = pointer to cipher context \ | |
76 | * \ | |
77 | * Returns: --- \ | |
78 | * \ | |
79 | * Use: Sets the ECB context to use a different cipher key. \ | |
80 | */ \ | |
81 | \ | |
82 | void pre##_ecbsetkey(pre##_ecbctx *ctx, const pre##_ctx *k) \ | |
0fee61eb | 83 | { ctx->ctx = *k; } \ |
79ba130c | 84 | \ |
85 | /* --- @pre_ecbinit@ --- * \ | |
86 | * \ | |
87 | * Arguments: @pre_ecbctx *ctx@ = pointer to cipher context \ | |
88 | * @const void *key@ = pointer to the key buffer \ | |
89 | * @size_t sz@ = size of the key \ | |
90 | * @const void *iv@ = pointer to initialization vector \ | |
91 | * \ | |
92 | * Returns: --- \ | |
93 | * \ | |
94 | * Use: Initializes an ECB context ready for use. This is \ | |
95 | * equivalent to calls to @pre_init@ and @pre_setkey@. \ | |
96 | */ \ | |
97 | \ | |
98 | void pre##_ecbinit(pre##_ecbctx *ctx, \ | |
81b52866 MW |
99 | const void *key, size_t sz, \ |
100 | const void *iv) \ | |
0fee61eb | 101 | { pre##_init(&ctx->ctx, key, sz); } \ |
79ba130c | 102 | \ |
103 | /* --- @pre_ecbencrypt@ --- * \ | |
104 | * \ | |
105 | * Arguments: @pre_ecbctx *ctx@ = pointer to ECB context block \ | |
106 | * @const void *src@ = pointer to source data \ | |
107 | * @void *dest@ = pointer to destination data \ | |
108 | * @size_t sz@ = size of block to be encrypted \ | |
109 | * \ | |
110 | * Returns: --- \ | |
111 | * \ | |
112 | * Use: Encrypts a block with a block cipher in ECB mode, with \ | |
113 | * ciphertext stealing and other clever tricks. \ | |
114 | * Essentially, data can be encrypted in arbitrary sized \ | |
115 | * chunks, although decryption must use the same chunks. \ | |
116 | */ \ | |
117 | \ | |
118 | void pre##_ecbencrypt(pre##_ecbctx *ctx, \ | |
81b52866 MW |
119 | const void *src, void *dest, \ |
120 | size_t sz) \ | |
79ba130c | 121 | { \ |
122 | const octet *s = src; \ | |
123 | octet *d = dest; \ | |
0fee61eb MW |
124 | uint32 t[PRE##_BLKSZ/4]; \ |
125 | octet b[PRE##_BLKSZ]; \ | |
126 | octet y; \ | |
127 | unsigned i; \ | |
79ba130c | 128 | \ |
ab197b6b | 129 | /* --- Empty blocks are trivial, and ECB is stateless --- */ \ |
79ba130c | 130 | \ |
ab197b6b | 131 | if (!sz || !d) return; \ |
79ba130c | 132 | \ |
133 | /* --- Short blocks aren't allowed in ECB --- * \ | |
134 | * \ | |
135 | * There's absolutely nothing secure I can do with them. \ | |
136 | */ \ | |
137 | \ | |
138 | assert(((void)"ECB must have at least one whole block to work with", \ | |
139 | sz >= PRE##_BLKSZ)); \ | |
140 | \ | |
141 | /* --- Do the main chunk of encryption --- * \ | |
142 | * \ | |
143 | * This will do the whole lot if it's a whole number of blocks. Just \ | |
144 | * give each block to the cipher in turn. This is trivial. \ | |
145 | * Hopefully... \ | |
146 | */ \ | |
147 | \ | |
0fee61eb MW |
148 | while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ |
149 | if (!s) BLKC_ZERO(PRE, t); \ | |
150 | else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; } \ | |
151 | pre##_eblk(&ctx->ctx, t, t); \ | |
ab197b6b | 152 | BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ |
79ba130c | 153 | sz -= PRE##_BLKSZ; \ |
154 | } \ | |
155 | \ | |
156 | /* --- Do the tail-end block and bit-left-over --- * \ | |
157 | * \ | |
158 | * This isn't very efficient. That shouldn't matter much. \ | |
159 | */ \ | |
160 | \ | |
161 | if (sz) { \ | |
79ba130c | 162 | \ |
163 | /* --- Let @sz@ be the size of the partial block --- */ \ | |
164 | \ | |
165 | sz -= PRE##_BLKSZ; \ | |
166 | \ | |
167 | /* --- First stage --- * \ | |
168 | * \ | |
169 | * Read in the current block, and encrypt it. The first part of \ | |
170 | * the result is the partial ciphertext block. Don't write that \ | |
171 | * out yet, because I've not read the partial plaintext block. \ | |
172 | */ \ | |
173 | \ | |
0fee61eb MW |
174 | if (!s) BLKC_ZERO(PRE, t); \ |
175 | else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; } \ | |
176 | pre##_eblk(&ctx->ctx, t, t); \ | |
177 | BLKC_STORE(PRE, b, t); \ | |
79ba130c | 178 | \ |
179 | /* --- Second stage --- * \ | |
180 | * \ | |
181 | * Now move in the partial plaintext block, writing out the \ | |
182 | * ciphertext as I go. Then encrypt, and write the complete \ | |
183 | * ciphertext block. \ | |
184 | */ \ | |
185 | \ | |
ab197b6b MW |
186 | d += PRE##_BLKSZ; \ |
187 | for (i = 0; i < sz; i++) { y = b[i]; b[i] = s[i]; d[i] = y; } \ | |
0fee61eb MW |
188 | BLKC_LOAD(PRE, t, b); \ |
189 | pre##_eblk(&ctx->ctx, t, t); \ | |
ab197b6b | 190 | BLKC_STORE(PRE, d - PRE##_BLKSZ, t); \ |
79ba130c | 191 | } \ |
192 | \ | |
193 | /* --- Done --- */ \ | |
194 | \ | |
195 | return; \ | |
196 | } \ | |
197 | \ | |
198 | /* --- @pre_ecbdecrypt@ --- * \ | |
199 | * \ | |
200 | * Arguments: @pre_ecbctx *ctx@ = pointer to ECB context block \ | |
201 | * @const void *src@ = pointer to source data \ | |
202 | * @void *dest@ = pointer to destination data \ | |
203 | * @size_t sz@ = size of block to be encrypted \ | |
204 | * \ | |
205 | * Returns: --- \ | |
206 | * \ | |
207 | * Use: Decrypts a block with a block cipher in ECB mode, with \ | |
208 | * ciphertext stealing and other clever tricks. \ | |
209 | * Essentially, data can be encrypted in arbitrary sized \ | |
210 | * chunks, although decryption must use the same chunks. \ | |
211 | */ \ | |
212 | \ | |
213 | void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ | |
214 | const void *src, void *dest, \ | |
215 | size_t sz) \ | |
216 | { \ | |
217 | const octet *s = src; \ | |
218 | octet *d = dest; \ | |
0fee61eb MW |
219 | uint32 t[PRE##_BLKSZ/4]; \ |
220 | octet b[PRE##_BLKSZ]; \ | |
221 | octet y; \ | |
222 | unsigned i; \ | |
79ba130c | 223 | \ |
224 | /* --- Empty blocks are trivial --- */ \ | |
225 | \ | |
0fee61eb | 226 | if (!sz) return; \ |
79ba130c | 227 | \ |
228 | /* --- Short blocks aren't allowed in ECB --- * \ | |
229 | * \ | |
230 | * There's absolutely nothing secure I can do with them. \ | |
231 | */ \ | |
232 | \ | |
233 | assert(((void)"ECB must have at least one whole block to work with", \ | |
234 | sz >= PRE##_BLKSZ)); \ | |
235 | \ | |
236 | /* --- Do the main chunk of decryption --- * \ | |
237 | * \ | |
238 | * This will do the whole lot if it's a whole number of blocks. \ | |
239 | * Each block is just handed to the block cipher in turn. \ | |
240 | */ \ | |
241 | \ | |
0fee61eb MW |
242 | while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ |
243 | BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; \ | |
244 | pre##_dblk(&ctx->ctx, t, t); \ | |
245 | BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ | |
79ba130c | 246 | sz -= PRE##_BLKSZ; \ |
247 | } \ | |
248 | \ | |
249 | /* --- Do the tail-end block and bit-left-over --- * \ | |
250 | * \ | |
251 | * This isn't very efficient. That shouldn't matter much. \ | |
252 | */ \ | |
253 | \ | |
254 | if (sz) { \ | |
79ba130c | 255 | \ |
256 | /* --- Let @sz@ be the size of the partial block --- */ \ | |
257 | \ | |
258 | sz -= PRE##_BLKSZ; \ | |
259 | \ | |
260 | /* --- First stage --- * \ | |
261 | * \ | |
262 | * Take the complete ciphertext block, and decrypt it. This block \ | |
263 | * is carried over for the next encryption operation. \ | |
264 | */ \ | |
265 | \ | |
0fee61eb MW |
266 | BLKC_LOAD(PRE, t, s); \ |
267 | pre##_dblk(&ctx->ctx, t, t); \ | |
268 | BLKC_STORE(PRE, b, t); \ | |
79ba130c | 269 | \ |
270 | /* --- Second stage --- * \ | |
271 | * \ | |
272 | * The first few bytes are the partial plaintext block. Write that \ | |
273 | * and replace with the partial ciphertext block. Then decrypt \ | |
274 | * what's left as the complete plaintext. \ | |
275 | */ \ | |
276 | \ | |
277 | s += PRE##_BLKSZ; \ | |
278 | d += PRE##_BLKSZ; \ | |
0fee61eb MW |
279 | for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i]; b[i] = y; } \ |
280 | BLKC_LOAD(PRE, t, b); \ | |
281 | pre##_dblk(&ctx->ctx, t, t); \ | |
282 | BLKC_STORE(PRE, d - PRE##_BLKSZ, t); \ | |
79ba130c | 283 | } \ |
284 | \ | |
285 | /* --- Done --- */ \ | |
286 | \ | |
287 | return; \ | |
288 | } \ | |
289 | \ | |
290 | /* --- Generic cipher interface --- */ \ | |
291 | \ | |
292 | static const gcipher_ops gops; \ | |
293 | \ | |
294 | typedef struct gctx { \ | |
295 | gcipher c; \ | |
296 | pre##_ecbctx k; \ | |
297 | } gctx; \ | |
298 | \ | |
299 | static gcipher *ginit(const void *k, size_t sz) \ | |
300 | { \ | |
99461409 | 301 | gctx *g = S_CREATE(gctx); \ |
79ba130c | 302 | g->c.ops = &gops; \ |
303 | pre##_ecbinit(&g->k, k, sz, 0); \ | |
304 | return (&g->c); \ | |
305 | } \ | |
306 | \ | |
307 | static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ | |
0fee61eb | 308 | { gctx *g = (gctx *)c; pre##_ecbencrypt(&g->k, s, t, sz); } \ |
79ba130c | 309 | \ |
310 | static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz) \ | |
0fee61eb | 311 | { gctx *g = (gctx *)c; pre##_ecbdecrypt(&g->k, s, t, sz); } \ |
79ba130c | 312 | \ |
313 | static void gdestroy(gcipher *c) \ | |
0fee61eb | 314 | { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ |
79ba130c | 315 | \ |
316 | static const gcipher_ops gops = { \ | |
99461409 | 317 | &pre##_ecb, \ |
318 | gencrypt, gdecrypt, gdestroy, 0, 0 \ | |
79ba130c | 319 | }; \ |
320 | \ | |
321 | const gccipher pre##_ecb = { \ | |
aaae9cab | 322 | name "-ecb", pre##_keysz, PRE##_BLKSZ, \ |
79ba130c | 323 | ginit \ |
324 | }; \ | |
325 | \ | |
aaae9cab | 326 | ECB_TESTX(PRE, pre, name, fname) |
79ba130c | 327 | |
328 | /*----- Test rig ----------------------------------------------------------*/ | |
329 | ||
aaae9cab MW |
330 | #define ECB_TEST(PRE, pre) ECB_TESTX(PRE, pre, #pre, #pre) |
331 | ||
79ba130c | 332 | #ifdef TEST_RIG |
333 | ||
57f459eb | 334 | #include "modes-test.h" |
79ba130c | 335 | |
336 | /* --- @ECB_TEST@ --- * | |
337 | * | |
338 | * Arguments: @PRE@, @pre@ = prefixes for block cipher definitions | |
339 | * | |
340 | * Use: Standard test rig for ECB functions. | |
341 | */ | |
342 | ||
aaae9cab | 343 | #define ECB_TESTX(PRE, pre, name, fname) \ |
79ba130c | 344 | \ |
57f459eb MW |
345 | static pre##_ctx key; \ |
346 | static pre##_ecbctx ctx; \ | |
79ba130c | 347 | \ |
57f459eb MW |
348 | static void pre##_ecb_test_setup(const octet *k, size_t ksz) \ |
349 | { pre##_init(&key, k, ksz); pre##_ecbsetkey(&ctx, &key); } \ | |
79ba130c | 350 | \ |
57f459eb MW |
351 | static void pre##_ecb_test_reset(const octet *iv) \ |
352 | { ; } \ | |
79ba130c | 353 | \ |
57f459eb MW |
354 | static void pre##_ecb_test_enc(const octet *s, octet *d, size_t sz) \ |
355 | { pre##_ecbencrypt(&ctx, s, d, sz); } \ | |
79ba130c | 356 | \ |
57f459eb MW |
357 | static void pre##_ecb_test_dec(const octet *s, octet *d, size_t sz) \ |
358 | { pre##_ecbdecrypt(&ctx, s, d, sz); } \ | |
79ba130c | 359 | \ |
57f459eb | 360 | int main(int argc, char *argv[]) \ |
79ba130c | 361 | { \ |
57f459eb MW |
362 | return test_encmode(fname "-ecb", PRE##_KEYSZ, PRE##_BLKSZ, \ |
363 | PRE##_BLKSZ, TEMF_REFALIGN, \ | |
364 | pre##_ecb_test_setup, pre##_ecb_test_reset, \ | |
365 | pre##_ecb_test_enc, pre##_ecb_test_dec, \ | |
366 | argc, argv); \ | |
79ba130c | 367 | } |
368 | ||
369 | #else | |
aaae9cab | 370 | # define ECB_TESTX(PRE, pre, name, fname) |
79ba130c | 371 | #endif |
372 | ||
373 | /*----- That's all, folks -------------------------------------------------*/ | |
374 | ||
375 | #ifdef __cplusplus | |
376 | } | |
377 | #endif | |
378 | ||
379 | #endif |