See ChangeLog: Wed Feb 10 17:15:39 CET 1999 Werner Koch
[libgcrypt.git] / src / symapi.c
1 /* symapi.c  -  symmetric cipher function interface
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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  * GnuPG 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 /* fixme: merge this function with ../cipher/cipher.c */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <assert.h>
29
30 #include "g10lib.h"
31 #include "cipher.h"
32
33
34 #define CONTEXT_MAGIC = 0x12569afe;
35
36 struct gcry_cipher_context {
37     u32 magic;
38     unsigned flags;
39     CIPHER_HD *hd;
40 };
41
42
43 GCRY_CIPHER_HD
44 gcry_cipher_open( int algo, int mode, unsigned flags )
45 {
46     GCRY_CIPHER_HD h;
47
48     /* check whether the algo is available */
49     if( check_cipher_algo( algo ) ) {
50         set_lasterr( GCRYERR_INV_ALGO );
51         return NULL;
52     }
53     /* check flags */
54     if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) {
55         set_lasterr( GCRYERR_INV_ARG );
56         return NULL;
57     }
58
59     /* map mode to internal mode */
60     switch( mode ) {
61       case GCRY_CIPHER_MODE_NONE: mode = CIPHER_MODE_DUMMY; break;
62       case GCRY_CIPHER_MODE_ECB: mode = CIPHER_MODE_ECB; break;
63       case GCRY_CIPHER_MODE_CFB:
64         mode = (flags & GCRY_CIPHER_ENABLE_SYNC) ? CIPHER_MODE_PHILS_CFB
65                                                  : CIPHER_MODE_CFB;
66         break;
67       default:
68         set_lasterr( GCRYERR_INV_ALGO );
69         return NULL;
70     }
71
72     /* allocate the handle */
73     h = m_lib_alloc_clear( sizeof *h );
74     if( !h ) {
75         set_lasterr( GCRYERR_NOMEM );
76         return NULL;
77     }
78     h->magic = CONTEXT_MAGIC;
79     h->mode = mode;
80     h->hd = cipher_open( algo, mode, (flags & GCRY_CIPHER_SECURE) );
81     if( !h ) {
82         m_lib_free( h );
83         set_lasterr( GCRYERR_INTERNAL );
84         return NULL;
85     }
86
87     return h;
88 }
89
90
91 void
92 gcry_cipher_close( GCRY_CIPHER_HD h )
93 {
94     if( !h )
95         return;
96     if( h->magic != CONTEXT_MAGIC )  {
97         fatal_invalid_arg("gcry_cipher_close: already closed/invalid handle");
98         return;
99     }
100     cipher_close( h->hd );
101     h->magic = 0;
102     m_lib_free(h);
103 }
104
105 int gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, byte *buffer, size_t buflen)
106 {
107     switch( cmd ) {
108       case GCRYCTL_SET_KEY:
109         cipher_setkey( h->hd, buffer, buflen );
110         break;
111       case GCRYCTL_SET_IV:
112         cipher_setiv( h->hd, buffer );
113         break;
114       case GCRYCTL_CFB_SYNC:
115         cipher_sync( h->hd );
116       default:
117         return set_lasterr( GCRYERR_INV_OP );
118     }
119     return 0;
120 }
121
122
123 int
124 gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
125                                        byte  *in, size_t inlen )
126 {
127     if( outsize < inlen )
128         return set_lasterr( GCRYERR_TOO_SHORT );
129     cipher_encrypt( h->hd, out, in, inlen );
130     return 0;
131 }
132
133 int
134 gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
135                                        byte  *in, size_t inlen )
136 {
137     if( outsize < inlen )
138         return set_lasterr( GCRYERR_TOO_SHORT );
139     cipher_decrypt( h->hd, out, in, inlen );
140     return 0;
141 }
142