3 * $Id: icrypt.c,v 1.2.2.1 1997/09/26 09:08:07 mdw Exp $
5 * Higher level encryption functions
7 * (c) 1997 Mark Wooding
10 /*----- Licensing 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 Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.2.2.1 1997/09/26 09:08:07 mdw
33 * Use the Blowfish encryption algorithm instead of IDEA. This is partly
34 * because I prefer Blowfish (without any particularly strong evidence) but
35 * mainly because IDEA is patented and Blowfish isn't.
37 * Revision 1.2 1997/08/04 10:24:22 mdw
38 * Sources placed under CVS control.
40 * Revision 1.1 1997/07/21 13:47:49 mdw
45 /*----- Header files ------------------------------------------------------*/
47 /* --- ANSI headers --- */
53 /* --- Local headers --- */
59 /*----- Main code ---------------------------------------------------------*/
61 /* --- @icrypt_init@ --- *
63 * Arguments: @icrypt_job *j@ = pointer to job context block
64 * @unsigned char *k@ = pointer to key data
65 * @size_t sz@ = size of the key data
66 * @const unsigned char *iv@ = pointer to IV
70 * Use: Primes the context block ready for encryption.
73 void icrypt_init(icrypt_job *j, unsigned char *k,
74 size_t sz, const unsigned char *iv)
76 blowfish_setKey(&j->k, k, sz);
78 memcpy(j->iv, iv, BLOWFISH_BLKSIZE);
80 memset(j->iv, 0, BLOWFISH_BLKSIZE);
84 /* --- @icrypt_encrypt@ --- *
86 * Arguments: @icrypt_job *j@ = job handle
87 * @const void *src@ = pointer to source buffer
88 * @void *dest@ = pointer to destination buffer
89 * @size_t sz@ = size of buffers to handle
93 * Use: Encrypts data from the source to the destination, using the
94 * key attached to the job handle.
97 void icrypt_encrypt(icrypt_job *j, const void *src, void *dest, size_t sz)
99 const unsigned char *s = src;
100 unsigned char *d = dest;
103 /* --- First, use up bytes in the buffer --- */
105 while (j->i < BLOWFISH_BLKSIZE && sz > 0) {
106 *d++ = j->iv[j->i++] ^= *s++;
111 /* --- Now encrypt larger chunks at a time --- */
113 while (sz >= BLOWFISH_BLKSIZE) {
115 /* --- Freshen the IV --- */
117 blowfish_encrypt(&j->k, j->iv, j->iv);
119 /* --- Now encrypt some more bytes --- */
121 for (i = 0; i < BLOWFISH_BLKSIZE; i++) {
122 *d++ = j->iv[i] ^= *s++;
124 sz -= BLOWFISH_BLKSIZE;
128 /* --- Do the tail-end bits --- */
130 blowfish_encrypt(&j->k, j->iv, j->iv);
133 *d++ = j->iv[j->i++] ^= *s++;
138 /* --- @icrypt_decrypt@ --- *
140 * Arguments: @icrypt_job *j@ = job handle
141 * @const void *src@ = pointer to source buffer
142 * @void *dest@ = pointer to destination buffer
143 * @size_t sz@ = size of buffers to handle
147 * Use: Decrypts data from the source to the destination, using
148 * the key attached to the job handle.
151 void icrypt_decrypt(icrypt_job *j, const void *src, void *dest, size_t sz)
153 unsigned const char *s = src;
154 unsigned char *d = dest;
158 /* --- First, use up bytes in the buffer --- */
160 while (j->i < BLOWFISH_BLKSIZE && sz > 0) {
162 *d++ = j->iv[j->i] ^ c;
168 /* --- Now encrypt larger chunks at a time --- */
170 while (sz >= BLOWFISH_BLKSIZE) {
172 /* --- Freshen the IV --- */
174 blowfish_encrypt(&j->k, j->iv, j->iv);
176 /* --- Now encrypt some more bytes --- */
178 for (i = 0; i < BLOWFISH_BLKSIZE; i++) {
183 sz -= BLOWFISH_BLKSIZE;
187 /* --- Do the tail-end bits --- */
189 blowfish_encrypt(&j->k, j->iv, j->iv);
193 *d++ = j->iv[j->i] ^ c;
199 /* --- @icrypt_reset@ --- *
201 * Arguments: @icrypt_job *j@ = pointer to job context block
202 * @unsigned char *k@ = pointer to key data, or zero for
204 * @size_t sz@ = size of the key in bytes
205 * @const unsigned char *iv@ = pointer to IV, or zero
209 * Use: Alters the context block. This can be used after recovery
210 * of a session key, for example.
213 void icrypt_reset(icrypt_job *j, unsigned char *k,
214 size_t sz, const unsigned char *iv)
217 blowfish_setKey(&j->k, k, sz);
219 memcpy(j->iv, iv, BLOWFISH_BLKSIZE);
221 unsigned char b[BLOWFISH_BLKSIZE];
222 int n = j->i, o = BLOWFISH_BLKSIZE - j->i;
224 memcpy(b, j->iv, sizeof(b));
225 memcpy(j->iv, b + n, o);
226 memcpy(j->iv + o, b, n);
231 /* --- @icrypt_saveIV@ --- *
233 * Arguments: @icrypt_job *j@ = pointer to job context block
234 * @unsigned char *iv@ = where to store the IV
238 * Use: Writes out the job's IV after munging it a little.
241 void icrypt_saveIV(icrypt_job *j, unsigned char *iv)
243 int n = j->i, o = BLOWFISH_BLKSIZE - j->i;
245 memcpy(j->iv, iv + n, o);
246 memcpy(j->iv + o, iv, n);
247 blowfish_encrypt(&j->k, iv, iv);
250 /*----- Test rig ----------------------------------------------------------*/
262 void icrypt(icrypt_job *j,
263 void (*proc)(icrypt_job *j,
273 r = fread(buff, 1, sizeof(buff), fp);
275 proc(j, buff, buff, r);
276 fwrite(buff, 1, r, stdout);
280 int main(int argc, char *argv[])
284 void (*proc)(icrypt_job *j,
287 size_t sz) = icrypt_encrypt;
292 int i = getopt(argc, argv, "d");
296 proc = icrypt_decrypt;
300 char *pass = getpass("Password: ");
301 unsigned char k[BLOWFISH_KEYSIZE];
303 md5_buffer(&md, pass, strlen(pass));
304 memset(pass, 0, strlen(pass));
307 icrypt_init(&j, k, BLOWFISH_KEYSIZE, 0);
311 icrypt(&j, proc, stdin);
313 while (optind < argc) {
314 char *p = argv[optind++];
315 if (strcmp(p, "-") == 0)
316 icrypt(&j, proc, stdin);
318 FILE *fp = fopen(p, "rb");
320 die("couldn't open `%s': %s", p, strerror(errno));
321 icrypt(&j, proc, fp);
331 /*----- That's all, folks -------------------------------------------------*/