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