Applied changes from GnuPG stable.
[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 = _gcry_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 = _gcry_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 = _gcry_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 = _gcry_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 = _gcry_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 = _gcry_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 = _gcry_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 = _gcry_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         _gcry_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 = _gcry_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( _gcry_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     _gcry_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 ? gcry_calloc_secure( 1, sizeof *h
465                                        + cipher_table[idx].contextsize
466                                        - sizeof(PROPERLY_ALIGNED_TYPE) )
467                : gcry_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         _gcry_fatal_error(GCRYERR_INTERNAL,
495                         "gcry_cipher_close: already closed/invalid handle");
496     h->magic = 0;
497     gcry_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 int
705 cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
706                                   const byte *inbuf, unsigned int nbytes )
707 {
708     int rc = 0;
709
710     switch( c->mode ) {
711       case GCRY_CIPHER_MODE_ECB:
712         if (!(nbytes%c->blocksize))
713             do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
714         else 
715             rc = GCRYERR_INV_ARG;
716         break;
717       case GCRY_CIPHER_MODE_CBC:
718         if (!(nbytes%c->blocksize))
719             do_cbc_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
720         else 
721             rc = GCRYERR_INV_ARG;
722         break;
723       case GCRY_CIPHER_MODE_CFB:
724         do_cfb_encrypt(c, outbuf, inbuf, nbytes );
725         break;
726       case GCRY_CIPHER_MODE_STREAM:
727         (*c->stencrypt)( &c->context.c,
728                          outbuf, (byte*)/*arggg*/inbuf, nbytes );
729         break;
730       case GCRY_CIPHER_MODE_NONE:
731         if( inbuf != outbuf )
732             memmove( outbuf, inbuf, nbytes );
733         break;
734       default:
735         log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
736         rc = GCRYERR_INV_CIPHER_MODE;
737         break;
738     }
739     return rc;
740 }
741
742
743 /****************
744  * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
745  * been requested,
746  */
747 int
748 gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
749                                        const byte  *in, size_t inlen )
750 {
751     int rc;
752
753     if ( !in ) {
754         /* caller requested in-place encryption */
755         /* actullay cipher_encrypt() does not need to know about it, but
756          * we may chnage this to get better performace */
757         rc = cipher_encrypt ( h, out, out, outsize );
758     }
759     else {
760         if ( outsize < inlen )
761             return set_lasterr ( GCRYERR_TOO_SHORT );
762         /* fixme: check that the inlength is a multipe of the blocksize
763          * if a blockoriented mode is used, or modify cipher_encrypt to
764          * return an error in this case */
765         rc = cipher_encrypt ( h, out, in, inlen );
766     }
767
768     return rc? set_lasterr (rc):0;
769 }
770
771
772
773 /****************
774  * Decrypt INBUF to OUTBUF with the mode selected at open.
775  * inbuf and outbuf may overlap or be the same.
776  * Depending on the mode some some contraints apply to NBYTES.
777  */
778 static int
779 cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
780                                                         unsigned nbytes )
781 {
782     int rc = 0;
783
784     switch( c->mode ) {
785       case GCRY_CIPHER_MODE_ECB:
786         if (!(nbytes%c->blocksize))
787             do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
788         else 
789             rc = GCRYERR_INV_ARG;
790         break;
791       case GCRY_CIPHER_MODE_CBC:
792         if (!(nbytes%c->blocksize))
793             do_cbc_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
794         else 
795             rc = GCRYERR_INV_ARG;
796         break;
797       case GCRY_CIPHER_MODE_CFB:
798         do_cfb_decrypt(c, outbuf, inbuf, nbytes );
799         break;
800       case GCRY_CIPHER_MODE_STREAM:
801         (*c->stdecrypt)( &c->context.c,
802                          outbuf, (byte*)/*arggg*/inbuf, nbytes );
803         break;
804       case GCRY_CIPHER_MODE_NONE:
805         if( inbuf != outbuf )
806             memmove( outbuf, inbuf, nbytes );
807         break;
808       default:
809         log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
810         rc = GCRYERR_INV_CIPHER_MODE;
811         break;
812     }
813     return rc;
814 }
815
816
817 int
818 gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
819                                  const byte  *in, size_t inlen )
820 {
821     int rc;
822
823     if( !in ) {
824         /* caller requested in-place encryption */
825         /* actullay cipher_encrypt() does not need to know about it, but
826          * we may chnage this to get better performace */
827         rc = cipher_decrypt( h, out, out, outsize );
828     }
829     else {
830         if( outsize < inlen )
831             return set_lasterr( GCRYERR_TOO_SHORT );
832         /* fixme: check that the inlength is a multipe of the blocksize
833          * if a blockoriented mode is used, or modify cipher_encrypt to
834          * return an error in this case */
835         rc = cipher_decrypt( h, out, in, inlen );
836     }
837     return rc? set_lasterr (rc):0;
838 }
839
840
841
842 /****************
843  * Used for PGP's somewhat strange CFB mode. Only works if
844  * the corresponding flag is set.
845  */
846 static void
847 cipher_sync( GCRY_CIPHER_HD c )
848 {
849     if( (c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused ) {
850         memmove(c->iv + c->unused, c->iv, c->blocksize - c->unused );
851         memcpy(c->iv, c->lastiv + c->blocksize - c->unused, c->unused);
852         c->unused = 0;
853     }
854 }
855
856
857 int
858 gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
859 {
860     int rc = 0;
861
862     switch( cmd ) {
863       case GCRYCTL_SET_KEY:
864         rc = cipher_setkey( h, buffer, buflen );
865         break;
866       case GCRYCTL_SET_IV:
867         cipher_setiv( h, buffer, buflen );
868         break;
869       case GCRYCTL_CFB_SYNC:
870         cipher_sync( h );
871         break;
872
873       case GCRYCTL_DISABLE_ALGO:
874         /* this one expects a NULL handle and buffer pointing to an
875          * integer with the algo number.
876          */
877         if( h || !buffer || buflen != sizeof(int) )
878             return set_lasterr( GCRYERR_INV_CIPHER_ALGO );
879         disable_cipher_algo( *(int*)buffer );
880         break;
881
882       default:
883         rc = GCRYERR_INV_OP;
884     }
885     return set_lasterr (rc);
886 }
887
888
889 /****************
890  * Return information about the cipher handle.
891  * -1 is returned on error and gcry_errno() may be used to get more information
892  * about the error.
893  */
894 int
895 gcry_cipher_info( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t *nbytes)
896 {
897     switch( cmd ) {
898       default:
899         set_lasterr( GCRYERR_INV_OP );
900         return -1;
901     }
902     return 0;
903 }
904
905 /****************
906  * Return information about the given cipher algorithm
907  * WHAT select the kind of information returned:
908  *  GCRYCTL_GET_KEYLEN:
909  *      Return the length of the key, if the algorithm
910  *      supports multiple key length, the maximum supported value
911  *      is returnd.  The length is return as number of octets.
912  *      buffer and nbytes must be zero.
913  *      The keylength is returned in _bytes_.
914  *  GCRYCTL_GET_BLKLEN:
915  *      Return the blocklength of the algorithm counted in octets.
916  *      buffer and nbytes must be zero.
917  *  GCRYCTL_TEST_ALGO:
918  *      Returns 0 when the specified algorithm is available for use.
919  *      buffer and nbytes must be zero.
920  *
921  * On error the value -1 is returned and the error reason may be
922  * retrieved by gcry_errno().
923  * Note:  Because this function is in most caes used to return an
924  * integer value, we can make it easier for the caller to just look at
925  * the return value.  The caller will in all cases consult the value
926  * and thereby detecting whether a error occured or not (i.e. while checking
927  * the block size)
928  */
929 int
930 gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes)
931 {
932     unsigned int ui;
933
934     switch( what ) {
935       case GCRYCTL_GET_KEYLEN:
936         if( buffer || nbytes ) {
937             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
938             break;
939         }
940         ui = cipher_get_keylen( algo );
941         if( ui > 0 && ui <= 512 )
942             return (int)ui/8;
943         /* the only reason is an invalid algo or a strange blocksize */
944         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
945         break;
946
947       case GCRYCTL_GET_BLKLEN:
948         if( buffer || nbytes ) {
949             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
950             break;
951         }
952         ui = cipher_get_blocksize( algo );
953         if( ui > 0 && ui < 10000 )
954             return (int)ui;
955         /* the only reason is an invalid algo or a strange blocksize */
956         set_lasterr( GCRYERR_INV_CIPHER_ALGO );
957         break;
958
959       case GCRYCTL_TEST_ALGO:
960         if( buffer || nbytes ) {
961             set_lasterr( GCRYERR_INV_ARG );
962             break;
963         }
964         if( check_cipher_algo( algo ) ) {
965             set_lasterr( GCRYERR_INV_CIPHER_ALGO );
966             break;
967         }
968         return 0;
969
970       default:
971         set_lasterr( GCRYERR_INV_OP );
972     }
973     return -1;
974 }
975
976
977