2 * Copyright (C) 2000, 2004, 2005, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
27 #include <gnutls_cipher_int.h>
28 #include <gnutls_datum.h>
29 #include <gnutls/crypto.h>
32 #define SR(x, cleanup) if ( (x)<0 ) { \
34 err = GNUTLS_E_INTERNAL_ERROR; \
39 _gnutls_cipher_init (cipher_hd_st
* handle
, gnutls_cipher_algorithm_t cipher
,
40 const gnutls_datum_t
* key
, const gnutls_datum_t
* iv
)
42 int err
= GC_INVALID_CIPHER
; /* doesn't matter */
43 gnutls_crypto_cipher_st
* cc
= NULL
;
45 /* check if a cipher has been registered
47 cc
= _gnutls_get_crypto_cipher( cipher
);
49 handle
->registered
= 1;
50 handle
->hd
.rh
.cc
= cc
;
51 SR( cc
->init(&handle
->hd
.rh
.ctx
), cc_cleanup
);
52 SR(cc
->setkey( handle
->hd
.rh
.ctx
, key
->data
, key
->size
), cc_cleanup
);
53 if (iv
->data
&& iv
->size
&& cc
->setiv
)
54 SR(cc
->setiv( handle
->hd
.rh
.ctx
, iv
->data
, iv
->size
), cc_cleanup
);
58 handle
->registered
= 0;
59 /* otherwise use included ciphers
63 case GNUTLS_CIPHER_AES_128_CBC
:
64 err
= gc_cipher_open (GC_AES128
, GC_CBC
, &handle
->hd
.gc
);
67 case GNUTLS_CIPHER_AES_256_CBC
:
68 err
= gc_cipher_open (GC_AES256
, GC_CBC
, &handle
->hd
.gc
);
71 case GNUTLS_CIPHER_3DES_CBC
:
72 err
= gc_cipher_open (GC_3DES
, GC_CBC
, &handle
->hd
.gc
);
75 case GNUTLS_CIPHER_DES_CBC
:
76 err
= gc_cipher_open (GC_DES
, GC_CBC
, &handle
->hd
.gc
);
79 case GNUTLS_CIPHER_ARCFOUR_128
:
80 err
= gc_cipher_open (GC_ARCFOUR128
, GC_STREAM
, &handle
->hd
.gc
);
83 case GNUTLS_CIPHER_ARCFOUR_40
:
84 err
= gc_cipher_open (GC_ARCFOUR40
, GC_STREAM
, &handle
->hd
.gc
);
87 case GNUTLS_CIPHER_RC2_40_CBC
:
88 err
= gc_cipher_open (GC_ARCTWO40
, GC_CBC
, &handle
->hd
.gc
);
91 #ifdef ENABLE_CAMELLIA
92 case GNUTLS_CIPHER_CAMELLIA_128_CBC
:
93 err
= gc_cipher_open (GC_CAMELLIA128
, GC_CBC
, &handle
->hd
.gc
);
96 case GNUTLS_CIPHER_CAMELLIA_256_CBC
:
97 err
= gc_cipher_open (GC_CAMELLIA256
, GC_CBC
, &handle
->hd
.gc
);
103 return GNUTLS_E_INVALID_REQUEST
;
108 gc_cipher_setkey (handle
->hd
.gc
, key
->size
, key
->data
);
109 if (iv
->data
!= NULL
&& iv
->size
> 0)
110 gc_cipher_setiv (handle
->hd
.gc
, iv
->size
, iv
->data
);
112 else if (cipher
!= GNUTLS_CIPHER_NULL
)
115 _gnutls_x509_log ("Crypto cipher[%d] error: %d\n", cipher
, err
);
116 return GNUTLS_E_INTERNAL_ERROR
;
117 /* FIXME: gc_strerror */
124 if (handle
->hd
.rh
.cc
)
125 cc
->deinit(handle
->hd
.rh
.ctx
);
131 _gnutls_cipher_encrypt (const cipher_hd_st
* handle
, void *text
, int textlen
)
135 if (handle
->registered
) {
136 if (handle
->hd
.rh
.ctx
== NULL
) return 0;
137 return handle
->hd
.rh
.cc
->encrypt( handle
->hd
.rh
.ctx
, text
, textlen
, text
, textlen
);
140 if (handle
->hd
.gc
== NULL
) return 0;
141 if (gc_cipher_encrypt_inline (handle
->hd
.gc
, textlen
, text
) != 0)
144 return GNUTLS_E_INTERNAL_ERROR
;
151 _gnutls_cipher_decrypt (const cipher_hd_st
*handle
, void *ciphertext
,
156 if (handle
->registered
) {
157 if (handle
->hd
.rh
.ctx
== NULL
) return 0;
158 return handle
->hd
.rh
.cc
->decrypt( handle
->hd
.rh
.ctx
, ciphertext
, ciphertextlen
, ciphertext
, ciphertextlen
);
161 if (handle
->hd
.gc
== NULL
) return 0;
162 if (gc_cipher_decrypt_inline (handle
->hd
.gc
, ciphertextlen
, ciphertext
) != 0)
165 return GNUTLS_E_INTERNAL_ERROR
;
172 _gnutls_cipher_deinit (cipher_hd_st
* handle
)
176 if (handle
->registered
&& handle
->hd
.rh
.ctx
!= NULL
) {
177 return handle
->hd
.rh
.cc
->deinit( handle
->hd
.rh
.ctx
);
179 gc_cipher_close (handle
->hd
.gc
);