3 * $Id: icrypt.c,v 1.1 1997/07/21 13:47:49 mdw Exp $
5 * Higher level IDEA encryption
7 * (c) 1997 Mark Wooding
10 /*----- Licencing notice --------------------------------------------------*
12 * This file is part of `become'
14 * `Become' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * `Become' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with `become'; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.1 1997/07/21 13:47:49 mdw
37 /*----- Header files ------------------------------------------------------*/
39 /* --- ANSI headers --- */
45 /* --- Local headers --- */
51 /*----- Main code ---------------------------------------------------------*/
53 /* --- @icrypt_init@ --- *
55 * Arguments: @icrypt_job *j@ = pointer to job context block
56 * @unsigned char *k@ = pointer to key data
57 * @const unsigned char *iv@ = pointer to IV
61 * Use: Primes the context block ready for encryption.
64 void icrypt_init(icrypt_job
*j
, unsigned char *k
, const unsigned char *iv
)
68 memcpy(j
->iv
, iv
, IDEA_BLKSIZE
);
70 memset(j
->iv
, 0, IDEA_BLKSIZE
);
74 /* --- @icrypt_encrypt@ --- *
76 * Arguments: @icrypt_job *j@ = job handle
77 * @const void *src@ = pointer to source buffer
78 * @void *dest@ = pointer to destination buffer
79 * @size_t sz@ = size of buffers to handle
83 * Use: Encrypts data from the source to the destination, using the
84 * key attached to the job handle.
87 void icrypt_encrypt(icrypt_job
*j
, const void *src
, void *dest
, size_t sz
)
93 /* --- First, use up bytes in the buffer --- */
95 while (j
->i
< IDEA_BLKSIZE
&& sz
> 0) {
96 *d
++ = j
->iv
[j
->i
++] ^= *s
++;
101 /* --- Now encrypt larger chunks at a time --- */
103 while (sz
>= IDEA_BLKSIZE
) {
105 /* --- Freshen the IV --- */
107 idea_encrypt(&j
->k
, j
->iv
, j
->iv
);
109 /* --- Now encrypt some more bytes --- */
111 for (i
= 0; i
< IDEA_BLKSIZE
; i
++) {
112 *d
++ = j
->iv
[i
] ^= *s
++;
118 /* --- Do the tail-end bits --- */
120 idea_encrypt(&j
->k
, j
->iv
, j
->iv
);
123 *d
++ = j
->iv
[j
->i
++] ^= *s
++;
128 /* --- @icrypt_decrypt@ --- *
130 * Arguments: @icrypt_job *j@ = job handle
131 * @const void *src@ = pointer to source buffer
132 * @void *dest@ = pointer to destination buffer
133 * @size_t sz@ = size of buffers to handle
137 * Use: Decrypts data from the source to the destination, using
138 * the key attached to the job handle.
141 void icrypt_decrypt(icrypt_job
*j
, const void *src
, void *dest
, size_t sz
)
148 /* --- First, use up bytes in the buffer --- */
150 while (j
->i
< IDEA_BLKSIZE
&& sz
> 0) {
152 *d
++ = j
->iv
[j
->i
] ^ c
;
158 /* --- Now encrypt larger chunks at a time --- */
160 while (sz
>= IDEA_BLKSIZE
) {
162 /* --- Freshen the IV --- */
164 idea_encrypt(&j
->k
, j
->iv
, j
->iv
);
166 /* --- Now encrypt some more bytes --- */
168 for (i
= 0; i
< IDEA_BLKSIZE
; i
++) {
177 /* --- Do the tail-end bits --- */
179 idea_encrypt(&j
->k
, j
->iv
, j
->iv
);
183 *d
++ = j
->iv
[j
->i
] ^ c
;
189 /* --- @icrypt_reset@ --- *
191 * Arguments: @icrypt_job *j@ = pointer to job context block
192 * @unsigned char *k@ = pointer to key data, or zero for
194 * @const unsigned char *iv@ = pointer to IV, or zero
198 * Use: Alters the context block. This can be used after recovery
199 * of a session key, for example.
202 void icrypt_reset(icrypt_job
*j
, unsigned char *k
, const unsigned char *iv
)
205 idea_ekeys(&j
->k
, k
);
207 memcpy(j
->iv
, iv
, IDEA_BLKSIZE
);
209 unsigned char b
[IDEA_BLKSIZE
];
210 int n
= j
->i
, o
= IDEA_BLKSIZE
- j
->i
;
212 memcpy(b
, j
->iv
, sizeof(b
));
213 memcpy(j
->iv
, b
+ n
, o
);
214 memcpy(j
->iv
+ o
, b
, n
);
219 /* --- @icrypt_saveIV@ --- *
221 * Arguments: @icrypt_job *j@ = pointer to job context block
222 * @unsigned char *iv@ = where to store the IV
226 * Use: Writes out the job's IV after munging it a little.
229 void icrypt_saveIV(icrypt_job
*j
, unsigned char *iv
)
231 int n
= j
->i
, o
= IDEA_BLKSIZE
- j
->i
;
233 memcpy(j
->iv
, iv
+ n
, o
);
234 memcpy(j
->iv
+ o
, iv
, n
);
235 idea_encrypt(&j
->k
, iv
, iv
);
238 /*----- Test rig ----------------------------------------------------------*/
249 void icrypt(icrypt_job
*j
,
250 void (*proc
)(icrypt_job
*j
,
260 r
= fread(buff
, 1, sizeof(buff
), fp
);
262 proc(j
, buff
, buff
, r
);
263 fwrite(buff
, 1, r
, stdout
);
267 int main(int argc
, char *argv
[])
271 void (*proc
)(icrypt_job
*j
,
274 size_t sz
) = icrypt_encrypt
;
279 int i
= getopt(argc
, argv
, "d");
283 proc
= icrypt_decrypt
;
287 char *pass
= getpass("Password: ");
289 md5_buffer(&md
, pass
, strlen(pass
));
290 memset(pass
, 0, strlen(pass
));
293 icrypt_init(&j
, md
.val
, 0);
297 icrypt(&j
, proc
, stdin
);
299 while (optind
< argc
) {
300 char *p
= argv
[optind
++];
301 if (strcmp(p
, "-") == 0)
302 icrypt(&j
, proc
, stdin
);
304 FILE *fp
= fopen(p
, "rb");
306 die("couldn't open `%s': %s", p
, strerror(errno
));
307 icrypt(&j
, proc
, fp
);
317 /*----- That's all, folks -------------------------------------------------*/