Changed program name in all files
[libgcrypt.git] / cipher / cipher.c
1 /* cipher.c  -  cipher dispatcher
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "des.h"
31 #include "blowfish.h"
32 #include "cast5.h"
33 #include "arcfour.h"
34 #include "dynload.h"
35
36 #define MAX_BLOCKSIZE 16
37 #define TABLE_SIZE 14
38 #define CTX_MAGIC_NORMAL 0x24091964
39 #define CTX_MAGIC_SECURE 0x46919042
40
41 struct cipher_table_s {
42     const char *name;
43     int algo;
44     size_t blocksize;
45     size_t keylen;
46     size_t contextsize; /* allocate this amount of context */
47     int  (*setkey)( void *c, byte *key, unsigned keylen );
48     void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
49     void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
50     void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
51     void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
52 };
53
54 static struct cipher_table_s cipher_table[TABLE_SIZE];
55 static int disabled_algos[TABLE_SIZE];
56
57 struct gcry_cipher_handle {
58     int magic;
59     int  algo;
60     int  mode;
61     unsigned int flags;
62     size_t blocksize;
63     byte iv[MAX_BLOCKSIZE];     /* (this should be ulong aligned) */
64     byte lastiv[MAX_BLOCKSIZE];
65     int  unused;  /* in IV */
66     int  (*setkey)( void *c, byte *key, unsigned keylen );
67     void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
68     void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
69     void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
70     void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
71     PROPERLY_ALIGNED_TYPE context;
72 };
73
74
75 static int
76 dummy_setkey( void *c, byte *key, unsigned keylen ) { return 0; }
77 static void
78 dummy_encrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
79 static void
80 dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
81 static void
82 dummy_encrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
83 { BUG(); }
84 static void
85 dummy_decrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
86 { BUG(); }
87
88
89
90 /****************
91  * Put the static entries into the table.
92  */
93 static void
94 setup_cipher_table(void)
95 {
96     int i;
97
98     for (i=0; i < TABLE_SIZE; i++ ) {
99         cipher_table[i].encrypt = dummy_encrypt_block;
100         cipher_table[i].decrypt = dummy_decrypt_block;
101         cipher_table[i].stencrypt = dummy_encrypt_stream;
102         cipher_table[i].stdecrypt = dummy_decrypt_stream;
103     }
104     
105     i = 0;
106     cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL;
107     cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
108                                          &cipher_table[i].keylen,
109                                          &cipher_table[i].blocksize,
110                                          &cipher_table[i].contextsize,
111                                          &cipher_table[i].setkey,
112                                          &cipher_table[i].encrypt,
113                                          &cipher_table[i].decrypt     );
114     if( !cipher_table[i].name )
115         BUG();
116     i++;
117     cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL192;
118     cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
119                                          &cipher_table[i].keylen,
120                                          &cipher_table[i].blocksize,
121                                          &cipher_table[i].contextsize,
122                                          &cipher_table[i].setkey,
123                                          &cipher_table[i].encrypt,
124                                          &cipher_table[i].decrypt     );
125     if( !cipher_table[i].name )
126         BUG();
127     i++;
128     cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL256;
129     cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
130                                          &cipher_table[i].keylen,
131                                          &cipher_table[i].blocksize,
132                                          &cipher_table[i].contextsize,
133                                          &cipher_table[i].setkey,
134                                          &cipher_table[i].encrypt,
135                                          &cipher_table[i].decrypt     );
136     if( !cipher_table[i].name )
137         BUG();
138     i++;
139     cipher_table[i].algo = GCRY_CIPHER_TWOFISH;
140     cipher_table[i].name = twofish_get_info( cipher_table[i].algo,
141                                          &cipher_table[i].keylen,
142                                          &cipher_table[i].blocksize,
143                                          &cipher_table[i].contextsize,
144                                          &cipher_table[i].setkey,
145                                          &cipher_table[i].encrypt,
146                                          &cipher_table[i].decrypt     );
147     if( !cipher_table[i].name )
148         BUG();
149     i++;
150     cipher_table[i].algo = GCRY_CIPHER_BLOWFISH;
151     cipher_table[i].name = blowfish_get_info( cipher_table[i].algo,
152                                          &cipher_table[i].keylen,
153                                          &cipher_table[i].blocksize,
154                                          &cipher_table[i].contextsize,
155                                          &cipher_table[i].setkey,
156                                          &cipher_table[i].encrypt,
157                                          &cipher_table[i].decrypt     );
158     if( !cipher_table[i].name )
159         BUG();
160     i++;
161     cipher_table[i].algo = GCRY_CIPHER_CAST5;
162     cipher_table[i].name = cast5_get_info( cipher_table[i].algo,
163                                          &cipher_table[i].keylen,
164                                          &cipher_table[i].blocksize,
165                                          &cipher_table[i].contextsize,
166                                          &cipher_table[i].setkey,
167                                          &cipher_table[i].encrypt,
168                                          &cipher_table[i].decrypt     );
169     if( !cipher_table[i].name )
170         BUG();
171     i++;
172     cipher_table[i].algo = GCRY_CIPHER_3DES;
173     cipher_table[i].name = des_get_info( cipher_table[i].algo,
174                                          &cipher_table[i].keylen,
175                                          &cipher_table[i].blocksize,
176                                          &cipher_table[i].contextsize,
177                                          &cipher_table[i].setkey,
178                                          &cipher_table[i].encrypt,
179                                          &cipher_table[i].decrypt     );
180     if( !cipher_table[i].name )
181         BUG();
182     i++;
183     cipher_table[i].algo = GCRY_CIPHER_ARCFOUR;
184     cipher_table[i].name = arcfour_get_info( cipher_table[i].algo,
185                                          &cipher_table[i].keylen,
186                                          &cipher_table[i].blocksize,
187                                          &cipher_table[i].contextsize,
188                                          &cipher_table[i].setkey,
189                                          &cipher_table[i].stencrypt,
190                                          &cipher_table[i].stdecrypt   );
191     if( !cipher_table[i].name )
192         BUG();
193     i++;
194     cipher_table[i].algo = CIPHER_ALGO_DUMMY;
195     cipher_table[i].name = "DUMMY";
196     cipher_table[i].blocksize = 8;
197     cipher_table[i].keylen = 128;
198     cipher_table[i].contextsize = 0;
199     cipher_table[i].setkey = dummy_setkey;
200     i++;
201
202     for( ; i < TABLE_SIZE; i++ )
203         cipher_table[i].name = NULL;
204 }
205
206
207 /****************
208  * Try to load all modules and return true if new modules are available
209  */
210 static int
211 load_cipher_modules(void)
212 {
213     static int done = 0;
214     static int initialized = 0;
215     void *context = NULL;
216     struct cipher_table_s *ct;
217     int ct_idx;
218     int i;
219     const char *name;
220     int any = 0;
221
222     if( !initialized ) {
223         cipher_modules_constructor();
224         setup_cipher_table(); /* load static modules on the first call */
225         initialized = 1;
226         return 1;
227     }
228
229     if( done )
230         return 0;
231     done = 1;
232
233     for(ct_idx=0, ct = cipher_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
234         if( !ct->name )
235             break;
236     }
237     if( ct_idx >= TABLE_SIZE-1 )
238         BUG(); /* table already full */
239     /* now load all extensions */
240     while( (name = enum_gnupgext_ciphers( &context, &ct->algo,
241                                 &ct->keylen, &ct->blocksize, &ct->contextsize,
242                                 &ct->setkey, &ct->encrypt, &ct->decrypt)) ) {
243         if( ct->blocksize != 8 && ct->blocksize != 16 ) {
244             log_info("skipping cipher %d: unsupported blocksize\n", ct->algo);
245             continue;
246         }
247         for(i=0; cipher_table[i].name; i++ )
248             if( cipher_table[i].algo == ct->algo )
249                 break;
250         if( cipher_table[i].name ) {
251             log_info("skipping cipher %d: already loaded\n", ct->algo );
252             continue;
253         }
254         /* put it into the table */
255         if( g10_log_verbosity( 2 ) )
256             log_info("loaded cipher %d (%s)\n", ct->algo, name);
257         ct->name = name;
258         ct_idx++;
259         ct++;
260         any = 1;
261         /* check whether there are more available table slots */
262         if( ct_idx >= TABLE_SIZE-1 ) {
263             log_info("cipher table full; ignoring other extensions\n");
264             break;
265         }
266     }
267     enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL,
268                                            NULL, NULL, NULL );
269     return any;
270 }
271
272
273 /****************
274  * Map a string to the cipher algo.
275  * Returns: The algo ID of the cipher for the gioven name or
276  *          0 if the name is not known.
277  */
278 int
279 gcry_cipher_map_name( const char *string )
280 {
281     int i;
282     const char *s;
283
284     do {
285         for(i=0; (s=cipher_table[i].name); i++ )
286             if( !stricmp( s, string ) )
287                 return cipher_table[i].algo;
288     } while( load_cipher_modules() );
289     return 0;
290 }
291
292 /****************
293  * Map a cipher algo to a string
294  */
295 static const char *
296 cipher_algo_to_string( int algo )
297 {
298     int i;
299
300     do {
301         for(i=0; cipher_table[i].name; i++ )
302             if( cipher_table[i].algo == algo )
303                 return cipher_table[i].name;
304     } while( load_cipher_modules() );
305     return NULL;
306 }
307
308 /****************
309  * This function simply returns the name of the algorithm or some constant
310  * string when there is no algo.  It will never return NULL.
311  */
312 const char *
313 gcry_cipher_algo_name( int algo )
314 {
315     const char *s = cipher_algo_to_string( algo );
316     return s? s: "";
317 }
318
319
320
321 static void
322 disable_cipher_algo( int algo )
323 {
324     int i;
325
326     for(i=0; i < DIM(disabled_algos); i++ ) {
327         if( !disabled_algos[i] || disabled_algos[i] == algo ) {
328             disabled_algos[i] = algo;
329             return;
330         }
331     }
332     /* fixme: we should use a linked list */
333     log_fatal("can't disable cipher algo %d: table full\n", algo );
334 }
335
336 /****************
337  * Return 0 if the cipher algo is available
338  */
339 static int
340 check_cipher_algo( int algo )
341 {
342     int i;
343
344     do {
345        for(i=0; cipher_table[i].name; i++ )
346            if( cipher_table[i].algo == algo ) {
347                 for(i=0; i < DIM(disabled_algos); i++ ) {
348                    if( disabled_algos[i] == algo )
349                        return GCRYERR_INV_CIPHER_ALGO;
350                 }
351                 return 0; /* okay */
352            }
353     } while( load_cipher_modules() );
354     return GCRYERR_INV_CIPHER_ALGO;
355 }
356
357
358 static unsigned
359 cipher_get_keylen( int algo )
360 {
361     int i;
362     unsigned len = 0;
363
364     do {
365         for(i=0; cipher_table[i].name; i++ ) {
366             if( cipher_table[i].algo == algo ) {
367                 len = cipher_table[i].keylen;
368                 if( !len )
369                     log_bug("cipher %d w/o key length\n", algo );
370                 return len;
371             }
372         }
373     } while( load_cipher_modules() );
374     log_bug("cipher %d not found\n", algo );
375     return 0;
376 }
377
378 static unsigned
379 cipher_get_blocksize( int algo )
380 {
381     int i;
382     unsigned len = 0;
383
384     do {
385         for(i=0; cipher_table[i].name; i++ ) {
386             if( cipher_table[i].algo == algo ) {
387                 len = cipher_table[i].blocksize;
388                 if( !len )
389                     log_bug("cipher %d w/o blocksize\n", algo );
390                 return len;
391             }
392         }
393     } while( load_cipher_modules() );
394     log_bug("cipher %d not found\n", algo );
395     return 0;
396 }
397
398
399 /****************
400  * Open a cipher handle for use with algorithm ALGO, in mode MODE
401  * and return the handle.  Return NULL and set the internal error variable
402  * if something goes wrong.
403  */
404
405 GCRY_CIPHER_HD
406 gcry_cipher_open( int algo, int mode, unsigned int flags )
407 {
408     GCRY_CIPHER_HD h;
409     int idx;
410     int secure = (flags & GCRY_CIPHER_SECURE);
411
412     fast_random_poll();
413
414     /* check whether the algo is available */
415     if( check_cipher_algo( algo ) ) {
416         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
417         return NULL;
418     }
419
420     /* check flags */
421     if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) {
422         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
423         return NULL;
424     }
425
426     /* get the table index of the algo */
427     for(idx=0; cipher_table[idx].name; idx++ )
428         if( cipher_table[idx].algo == algo )
429             break;
430     if( !cipher_table[idx].name )
431         BUG(); /* check_cipher_algo() should have loaded the algo */
432
433     if( algo == CIPHER_ALGO_DUMMY )
434         mode = GCRY_CIPHER_MODE_NONE;  /* force this mode for dummy algo */
435
436     /* check that a valid mode has been requested */
437     switch( mode ) {
438       case GCRY_CIPHER_MODE_ECB:
439       case GCRY_CIPHER_MODE_CBC:
440       case GCRY_CIPHER_MODE_CFB:
441         if ( cipher_table[idx].encrypt == dummy_encrypt_block
442              || cipher_table[idx].decrypt == dummy_decrypt_block ) {
443             set_lasterr( GCRYERR_INV_CIPHER_MODE );
444             return NULL;
445         }
446         break;
447       case GCRY_CIPHER_MODE_STREAM:
448         if ( cipher_table[idx].stencrypt == dummy_encrypt_stream
449              || cipher_table[idx].stdecrypt == dummy_decrypt_stream ) {
450             set_lasterr( GCRYERR_INV_CIPHER_MODE );
451             return NULL;
452         }
453         break;
454       case GCRY_CIPHER_MODE_NONE:
455         /* FIXME: issue a warning when this mode is used */
456         break;
457       default:
458         set_lasterr( GCRYERR_INV_CIPHER_MODE );
459         return NULL;
460     }
461
462     /* ? perform selftest here and mark this with a flag in cipher_table ? */
463
464     h = secure ? g10_calloc_secure( 1, sizeof *h
465                                        + cipher_table[idx].contextsize
466                                        - sizeof(PROPERLY_ALIGNED_TYPE) )
467                : g10_calloc( 1, sizeof *h + cipher_table[idx].contextsize
468                                        - sizeof(PROPERLY_ALIGNED_TYPE)  );
469     if( !h ) {
470         set_lasterr( GCRYERR_NO_MEM );
471         return NULL;
472     }
473     h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
474     h->algo = algo;
475     h->mode = mode;
476     h->flags = flags;
477     h->blocksize = cipher_table[idx].blocksize;
478     h->setkey  = cipher_table[idx].setkey;
479     h->encrypt = cipher_table[idx].encrypt;
480     h->decrypt = cipher_table[idx].decrypt;
481     h->stencrypt = cipher_table[idx].stencrypt;
482     h->stdecrypt = cipher_table[idx].stdecrypt;
483
484     return h;
485 }
486
487
488 void
489 gcry_cipher_close( GCRY_CIPHER_HD h )
490 {
491     if( !h )
492         return;
493     if( h->magic != CTX_MAGIC_SECURE && h->magic != CTX_MAGIC_NORMAL )
494         g10_fatal_error(GCRYERR_INTERNAL,
495                         "gcry_cipher_close: already closed/invalid handle");
496     h->magic = 0;
497     g10_free(h);
498 }
499
500
501 static int
502 cipher_setkey( GCRY_CIPHER_HD c, byte *key, unsigned keylen )
503 {
504     return (*c->setkey)( &c->context.c, key, keylen );
505 }
506
507
508 static void
509 cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen )
510 {
511     memset( c->iv, 0, c->blocksize );
512     if( iv ) {
513         if( ivlen != c->blocksize )
514             log_info("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
515                                              ivlen, (unsigned)c->blocksize );
516         if( ivlen > c->blocksize )
517             ivlen = c->blocksize;
518         memcpy( c->iv, iv, ivlen );
519     }
520     c->unused = 0;
521 }
522
523
524
525 static void
526 do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
527 {
528     unsigned n;
529
530     for(n=0; n < nblocks; n++ ) {
531         (*c->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
532         inbuf  += c->blocksize;
533         outbuf += c->blocksize;
534     }
535 }
536
537 static void
538 do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
539 {
540     unsigned n;
541
542     for(n=0; n < nblocks; n++ ) {
543         (*c->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
544         inbuf  += c->blocksize;
545         outbuf += c->blocksize;
546     }
547 }
548
549 static void
550 do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
551 {
552     unsigned int n;
553     byte *ivp;
554     int i;
555     size_t blocksize = c->blocksize;
556
557     for(n=0; n < nblocks; n++ ) {
558         /* fixme: the xor should works on words and not on
559          * bytes.  Maybe it is a good idea to enhance the cipher backend
560          * API to allow for CBC handling in the backend */
561         for(ivp=c->iv,i=0; i < blocksize; i++ )
562             outbuf[i] = inbuf[i] ^ *ivp++;
563         (*c->encrypt)( &c->context.c, outbuf, outbuf );
564         memcpy(c->iv, outbuf, blocksize );
565         inbuf  += c->blocksize;
566         outbuf += c->blocksize;
567     }
568 }
569
570 static void
571 do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
572 {
573     unsigned int n;
574     byte *ivp;
575     int i;
576     size_t blocksize = c->blocksize;
577
578     for(n=0; n < nblocks; n++ ) {
579         /* because outbuf and inbuf might be the same, we have
580          * to save the original ciphertext block.  We use lastiv
581          * for this here because it is not used otherwise */
582         memcpy(c->lastiv, inbuf, blocksize );
583         (*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
584         for(ivp=c->iv,i=0; i < blocksize; i++ )
585             outbuf[i] ^= *ivp++;
586         memcpy(c->iv, c->lastiv, blocksize );
587         inbuf  += c->blocksize;
588         outbuf += c->blocksize;
589     }
590 }
591
592
593 static void
594 do_cfb_encrypt( GCRY_CIPHER_HD c,
595                 byte *outbuf, const byte *inbuf, unsigned nbytes )
596 {
597     byte *ivp;
598     size_t blocksize = c->blocksize;
599
600     if( nbytes <= c->unused ) {
601         /* short enough to be encoded by the remaining XOR mask */
602         /* XOR the input with the IV and store input into IV */
603         for(ivp=c->iv+c->blocksize - c->unused; nbytes; nbytes--, c->unused-- )
604             *outbuf++ = (*ivp++ ^= *inbuf++);
605         return;
606     }
607
608     if( c->unused ) {
609         /* XOR the input with the IV and store input into IV */
610         nbytes -= c->unused;
611         for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- )
612             *outbuf++ = (*ivp++ ^= *inbuf++);
613     }
614
615     /* now we can process complete blocks */
616     while( nbytes >= blocksize ) {
617         int i;
618         /* encrypt the IV (and save the current one) */
619         memcpy( c->lastiv, c->iv, blocksize );
620         (*c->encrypt)( &c->context.c, c->iv, c->iv );
621         /* XOR the input with the IV and store input into IV */
622         for(ivp=c->iv,i=0; i < blocksize; i++ )
623             *outbuf++ = (*ivp++ ^= *inbuf++);
624         nbytes -= blocksize;
625     }
626     if( nbytes ) { /* process the remaining bytes */
627         /* encrypt the IV (and save the current one) */
628         memcpy( c->lastiv, c->iv, blocksize );
629         (*c->encrypt)( &c->context.c, c->iv, c->iv );
630         c->unused = blocksize;
631         /* and apply the xor */
632         c->unused -= nbytes;
633         for(ivp=c->iv; nbytes; nbytes-- )
634             *outbuf++ = (*ivp++ ^= *inbuf++);
635     }
636 }
637
638 static void
639 do_cfb_decrypt( GCRY_CIPHER_HD c,
640                 byte *outbuf, const byte *inbuf, unsigned nbytes )
641 {
642     byte *ivp;
643     ulong temp;
644     size_t blocksize = c->blocksize;
645
646     if( nbytes <= c->unused ) {
647         /* short enough to be encoded by the remaining XOR mask */
648         /* XOR the input with the IV and store input into IV */
649         for(ivp=c->iv+blocksize - c->unused; nbytes; nbytes--,c->unused--){
650             temp = *inbuf++;
651             *outbuf++ = *ivp ^ temp;
652             *ivp++ = temp;
653         }
654         return;
655     }
656
657     if( c->unused ) {
658         /* XOR the input with the IV and store input into IV */
659         nbytes -= c->unused;
660         for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- ) {
661             temp = *inbuf++;
662             *outbuf++ = *ivp ^ temp;
663             *ivp++ = temp;
664         }
665     }
666
667     /* now we can process complete blocks */
668     while( nbytes >= blocksize ) {
669         int i;
670         /* encrypt the IV (and save the current one) */
671         memcpy( c->lastiv, c->iv, blocksize );
672         (*c->encrypt)( &c->context.c, c->iv, c->iv );
673         /* XOR the input with the IV and store input into IV */
674         for(ivp=c->iv,i=0; i < blocksize; i++ ) {
675             temp = *inbuf++;
676             *outbuf++ = *ivp ^ temp;
677             *ivp++ = temp;
678         }
679         nbytes -= blocksize;
680     }
681     if( nbytes ) { /* process the remaining bytes */
682         /* encrypt the IV (and save the current one) */
683         memcpy( c->lastiv, c->iv, blocksize );
684         (*c->encrypt)( &c->context.c, c->iv, c->iv );
685         c->unused = blocksize;
686         /* and apply the xor */
687         c->unused -= nbytes;
688         for(ivp=c->iv; nbytes; nbytes-- ) {
689             temp = *inbuf++;
690             *outbuf++ = *ivp ^ temp;
691             *ivp++ = temp;
692         }
693     }
694 }
695
696
697
698
699 /****************
700  * Encrypt INBUF to OUTBUF with the mode selected at open.
701  * inbuf and outbuf may overlap or be the same.
702  * Depending on the mode some contraints apply to NBYTES.
703  */
704 static void
705 cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
706                                   const byte *inbuf, unsigned int nbytes )
707 {
708     switch( c->mode ) {
709       case GCRY_CIPHER_MODE_ECB:
710         assert(!(nbytes%8));
711         do_ecb_encrypt(c, outbuf, inbuf, nbytes/8 );
712         break;
713       case GCRY_CIPHER_MODE_CBC:
714         assert(!(nbytes%8));  /* fixme: should be blocksize */
715         do_cbc_encrypt(c, outbuf, inbuf, nbytes/8 );
716         break;
717       case GCRY_CIPHER_MODE_CFB:
718         do_cfb_encrypt(c, outbuf, inbuf, nbytes );
719         break;
720       case GCRY_CIPHER_MODE_STREAM:
721         (*c->stencrypt)( &c->context.c,
722                          outbuf, (byte*)/*arggg*/inbuf, nbytes );
723         break;
724       case GCRY_CIPHER_MODE_NONE:
725         if( inbuf != outbuf )
726             memmove( outbuf, inbuf, nbytes );
727         break;
728       default: log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
729     }
730 }
731
732
733 /****************
734  * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
735  * been requested,
736  */
737 int
738 gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
739                                        const byte  *in, size_t inlen )
740 {
741     if( !in ) {
742         /* caller requested in-place encryption */
743         /* actullay cipher_encrypt() does not need to know about it, but
744          * we may chnage this to get better performace */
745         cipher_encrypt( h, out, out, outsize );
746     }
747     else {
748         if( outsize < inlen )
749             return set_lasterr( GCRYERR_TOO_SHORT );
750         /* fixme: check that the inlength is a multipe of the blocksize
751          * if a blockoriented mode is used, or modify cipher_encrypt to
752          * return an error in this case */
753         cipher_encrypt( h, out, in, inlen );
754     }
755     return 0;
756 }
757
758
759
760 /****************
761  * Decrypt INBUF to OUTBUF with the mode selected at open.
762  * inbuf and outbuf may overlap or be the same.
763  * Depending on the mode some some contraints apply to NBYTES.
764  */
765 static void
766 cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
767                                                         unsigned nbytes )
768 {
769     switch( c->mode ) {
770       case GCRY_CIPHER_MODE_ECB:
771         assert(!(nbytes%8));
772         do_ecb_decrypt(c, outbuf, inbuf, nbytes/8 );
773         break;
774       case GCRY_CIPHER_MODE_CBC:
775         assert(!(nbytes%8));    /* fixme: should assert on blocksize */
776         do_cbc_decrypt(c, outbuf, inbuf, nbytes/8 );
777         break;
778       case GCRY_CIPHER_MODE_CFB:
779         do_cfb_decrypt(c, outbuf, inbuf, nbytes );
780         break;
781       case GCRY_CIPHER_MODE_STREAM:
782         (*c->stdecrypt)( &c->context.c,
783                          outbuf, (byte*)/*arggg*/inbuf, nbytes );
784         break;
785       case GCRY_CIPHER_MODE_NONE:
786         if( inbuf != outbuf )
787             memmove( outbuf, inbuf, nbytes );
788         break;
789       default: log_fatal("cipher_decrypt: invalid mode %d\n", c->mode );
790     }
791 }
792
793
794 int
795 gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
796                                  const byte  *in, size_t inlen )
797 {
798     if( !in ) {
799         /* caller requested in-place encryption */
800         /* actullay cipher_encrypt() does not need to know about it, but
801          * we may chnage this to get better performace */
802         cipher_decrypt( h, out, out, outsize );
803     }
804     else {
805         if( outsize < inlen )
806             return set_lasterr( GCRYERR_TOO_SHORT );
807         /* fixme: check that the inlength is a multipe of the blocksize
808          * if a blockoriented mode is used, or modify cipher_encrypt to
809          * return an error in this case */
810         cipher_decrypt( h, out, in, inlen );
811     }
812     return 0;
813 }
814
815
816
817 /****************
818  * Used for PGP's somewhat strange CFB mode. Only works if
819  * the corresponding flag is set.
820  */
821 static void
822 cipher_sync( GCRY_CIPHER_HD c )
823 {
824     if( (c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused ) {
825         memmove(c->iv + c->unused, c->iv, c->blocksize - c->unused );
826         memcpy(c->iv, c->lastiv + c->blocksize - c->unused, c->unused);
827         c->unused = 0;
828     }
829 }
830
831
832 int
833 gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
834 {
835     switch( cmd ) {
836       case GCRYCTL_SET_KEY:
837         cipher_setkey( h, buffer, buflen );
838         break;
839       case GCRYCTL_SET_IV:
840         cipher_setiv( h, buffer, buflen );
841         break;
842       case GCRYCTL_CFB_SYNC:
843         cipher_sync( h );
844         break;
845
846       case GCRYCTL_DISABLE_ALGO:
847         /* this one expects a NULL handle and buffer pointing to an
848          * integer with the algo number.
849          */
850         if( h || !buffer || buflen != sizeof(int) )
851             return set_lasterr( GCRYERR_INV_CIPHER_ALGO );
852         disable_cipher_algo( *(int*)buffer );
853         break;
854
855       default:
856         return set_lasterr( GCRYERR_INV_OP );
857     }
858     return 0;
859 }
860
861
862 /****************
863  * Return information about the cipher handle.
864  * -1 is returned on error and gcry_errno() may be used to get more information
865  * about the error.
866  */
867 int
868 gcry_cipher_info( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t *nbytes)
869 {
870     switch( cmd ) {
871       default:
872         set_lasterr( GCRYERR_INV_OP );
873         return -1;
874     }
875     return 0;
876 }
877
878 /****************
879  * Return information about the given cipher algorithm
880  * WHAT select the kind of information returned:
881  *  GCRYCTL_GET_KEYLEN:
882  *      Return the length of the key, if the algorithm
883  *      supports multiple key length, the maximum supported value
884  *      is returnd.  The length is return as number of octets.
885  *      buffer and nbytes must be zero.
886  *      The keylength is returned in _bytes_.
887  *  GCRYCTL_GET_BLKLEN:
888  *      Return the blocklength of the algorithm counted in octets.
889  *      buffer and nbytes must be zero.
890  *  GCRYCTL_TEST_ALGO:
891  *      Returns 0 when the specified algorithm is available for use.
892  *      buffer and nbytes must be zero.
893  *
894  * On error the value -1 is returned and the error reason may be
895  * retrieved by gcry_errno().
896  * Note:  Because this function is in most caes used to return an
897  * integer value, we can make it easier for the caller to just look at
898  * the return value.  The caller will in all cases consult the value
899  * and thereby detecting whether a error occured or not (i.e. while checking
900  * the block size)
901  */
902 int
903 gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes)
904 {
905     unsigned int ui;
906
907     switch( what ) {
908       case GCRYCTL_GET_KEYLEN:
909         if( buffer || nbytes ) {
910             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
911             break;
912         }
913         ui = cipher_get_keylen( algo );
914         if( ui > 0 && ui <= 512 )
915             return (int)ui/8;
916         /* the only reason is an invalid algo or a strange blocksize */
917         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
918         break;
919
920       case GCRYCTL_GET_BLKLEN:
921         if( buffer || nbytes ) {
922             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
923             break;
924         }
925         ui = cipher_get_blocksize( algo );
926         if( ui > 0 && ui < 10000 )
927             return (int)ui;
928         /* the only reason is an invalid algo or a strange blocksize */
929         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
930         break;
931
932       case GCRYCTL_TEST_ALGO:
933         if( buffer || nbytes ) {
934             set_lasterr( GCRYERR_INV_ARG );
935             break;
936         }
937         if( check_cipher_algo( algo ) ) {
938             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
939             break;
940         }
941         return 0;
942
943       default:
944         set_lasterr( GCRYERR_INV_OP );
945     }
946     return -1;
947 }
948
949
950