corrected copyright notices
[gnutls.git] / lib / algorithms / ciphers.c
blob8e3399f21565baae56404902dc85b6e7edd68b19
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <algorithms.h>
25 #include <gnutls_errors.h>
26 #include <x509/common.h>
28 struct gnutls_cipher_entry
30 const char *name;
31 gnutls_cipher_algorithm_t id;
32 uint16_t blocksize;
33 uint16_t keysize;
34 unsigned block:1;
35 uint16_t iv; /* the size of IV */
36 unsigned export_flag:1; /* 0 non export */
37 unsigned auth:1; /* Whether it is authenc cipher */
39 typedef struct gnutls_cipher_entry gnutls_cipher_entry;
41 /* Note that all algorithms are in CBC or STREAM modes.
42 * Do not add any algorithms in other modes (avoid modified algorithms).
43 * View first: "The order of encryption and authentication for
44 * protecting communications" by Hugo Krawczyk - CRYPTO 2001
46 * Make sure to update MAX_CIPHER_BLOCK_SIZE and MAX_CIPHER_KEY_SIZE as well.
48 static const gnutls_cipher_entry algorithms[] = {
49 {"AES-256-CBC", GNUTLS_CIPHER_AES_256_CBC, 16, 32, CIPHER_BLOCK, 16, 0, 0},
50 {"AES-192-CBC", GNUTLS_CIPHER_AES_192_CBC, 16, 24, CIPHER_BLOCK, 16, 0, 0},
51 {"AES-128-CBC", GNUTLS_CIPHER_AES_128_CBC, 16, 16, CIPHER_BLOCK, 16, 0, 0},
52 {"AES-128-GCM", GNUTLS_CIPHER_AES_128_GCM, 16, 16, CIPHER_STREAM, AEAD_IMPLICIT_DATA_SIZE, 0, 1},
53 {"AES-256-GCM", GNUTLS_CIPHER_AES_256_GCM, 16, 32, CIPHER_STREAM, AEAD_IMPLICIT_DATA_SIZE, 0, 1},
54 {"ARCFOUR-128", GNUTLS_CIPHER_ARCFOUR_128, 1, 16, CIPHER_STREAM, 0, 0, 0},
55 {"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC, 16, 32, CIPHER_BLOCK,
56 16, 0, 0},
57 {"CAMELLIA-192-CBC", GNUTLS_CIPHER_CAMELLIA_192_CBC, 16, 24, CIPHER_BLOCK,
58 16, 0, 0},
59 {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16, CIPHER_BLOCK,
60 16, 0, 0},
61 {"3DES-CBC", GNUTLS_CIPHER_3DES_CBC, 8, 24, CIPHER_BLOCK, 8, 0, 0},
62 {"DES-CBC", GNUTLS_CIPHER_DES_CBC, 8, 8, CIPHER_BLOCK, 8, 0, 0},
63 {"ARCFOUR-40", GNUTLS_CIPHER_ARCFOUR_40, 1, 5, CIPHER_STREAM, 0, 1, 0},
64 {"RC2-40", GNUTLS_CIPHER_RC2_40_CBC, 8, 5, CIPHER_BLOCK, 8, 1, 0},
66 #ifdef ENABLE_OPENPGP
67 {"IDEA-PGP-CFB", GNUTLS_CIPHER_IDEA_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0, 0},
68 {"3DES-PGP-CFB", GNUTLS_CIPHER_3DES_PGP_CFB, 8, 24, CIPHER_BLOCK, 8, 0, 0},
69 {"CAST5-PGP-CFB", GNUTLS_CIPHER_CAST5_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0, 0},
70 {"BLOWFISH-PGP-CFB", GNUTLS_CIPHER_BLOWFISH_PGP_CFB, 8,
71 16 /*actually unlimited */ , CIPHER_BLOCK, 8, 0, 0},
72 {"SAFER-SK128-PGP-CFB", GNUTLS_CIPHER_SAFER_SK128_PGP_CFB, 8, 16,
73 CIPHER_BLOCK, 8, 0, 0},
74 {"AES-128-PGP-CFB", GNUTLS_CIPHER_AES128_PGP_CFB, 16, 16, CIPHER_BLOCK, 16,
75 0, 0},
76 {"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB, 16, 24, CIPHER_BLOCK, 16,
77 0, 0},
78 {"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB, 16, 32, CIPHER_BLOCK, 16,
79 0, 0},
80 {"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB, 16, 16, CIPHER_BLOCK, 16,
81 0, 0},
82 #endif
83 {"NULL", GNUTLS_CIPHER_NULL, 1, 0, CIPHER_STREAM, 0, 0, 0},
84 {0, 0, 0, 0, 0, 0, 0}
87 #define GNUTLS_CIPHER_LOOP(b) \
88 const gnutls_cipher_entry *p; \
89 for(p = algorithms; p->name != NULL; p++) { b ; }
91 #define GNUTLS_ALG_LOOP(a) \
92 GNUTLS_CIPHER_LOOP( if(p->id == algorithm) { a; break; } )
94 /* CIPHER functions */
96 /**
97 * gnutls_cipher_get_block_size:
98 * @algorithm: is an encryption algorithm
100 * Get block size for encryption algorithm.
102 * Returns: block size for encryption algorithm.
104 * Since: 2.10.0
107 gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm)
109 size_t ret = 0;
110 GNUTLS_ALG_LOOP (ret = p->blocksize);
111 return ret;
115 /* returns the priority */
117 _gnutls_cipher_priority (gnutls_session_t session,
118 gnutls_cipher_algorithm_t algorithm)
120 unsigned int i;
121 for (i = 0; i < session->internals.priorities.cipher.algorithms; i++)
123 if (session->internals.priorities.cipher.priority[i] == algorithm)
124 return i;
126 return -1;
131 _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm)
133 size_t ret = 0;
135 GNUTLS_ALG_LOOP (ret = p->block);
136 return ret;
141 _gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm)
143 size_t ret = 0;
145 GNUTLS_ALG_LOOP (ret = p->auth);
146 return ret;
151 * gnutls_cipher_get_key_size:
152 * @algorithm: is an encryption algorithm
154 * Get key size for cipher.
156 * Returns: length (in bytes) of the given cipher's key size, or 0 if
157 * the given cipher is invalid.
159 size_t
160 gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm)
161 { /* In bytes */
162 size_t ret = 0;
163 GNUTLS_ALG_LOOP (ret = p->keysize);
164 return ret;
169 _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm)
170 { /* In bytes */
171 size_t ret = 0;
172 GNUTLS_ALG_LOOP (ret = p->iv);
173 return ret;
178 _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm)
179 { /* In bytes */
180 size_t ret = 0;
181 GNUTLS_ALG_LOOP (ret = p->export_flag);
182 return ret;
187 * gnutls_cipher_get_name:
188 * @algorithm: is an encryption algorithm
190 * Convert a #gnutls_cipher_algorithm_t type to a string.
192 * Returns: a pointer to a string that contains the name of the
193 * specified cipher, or %NULL.
195 const char *
196 gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
198 const char *ret = NULL;
200 /* avoid prefix */
201 GNUTLS_ALG_LOOP (ret = p->name);
203 return ret;
207 * gnutls_cipher_get_id:
208 * @name: is a cipher algorithm name
210 * The names are compared in a case insensitive way.
212 * Returns: return a #gnutls_cipher_algorithm_t value corresponding to
213 * the specified cipher, or %GNUTLS_CIPHER_UNKNOWN on error.
215 gnutls_cipher_algorithm_t
216 gnutls_cipher_get_id (const char *name)
218 gnutls_cipher_algorithm_t ret = GNUTLS_CIPHER_UNKNOWN;
220 GNUTLS_CIPHER_LOOP (
221 if (strcasecmp (p->name, name) == 0)
223 ret = p->id;
224 break;
228 return ret;
232 * gnutls_cipher_list:
234 * Get a list of supported cipher algorithms. Note that not
235 * necessarily all ciphers are supported as TLS cipher suites. For
236 * example, DES is not supported as a cipher suite, but is supported
237 * for other purposes (e.g., PKCS#8 or similar).
239 * This function is not thread safe.
241 * Returns: a (0)-terminated list of #gnutls_cipher_algorithm_t
242 * integers indicating the available ciphers.
245 const gnutls_cipher_algorithm_t *
246 gnutls_cipher_list (void)
248 static gnutls_cipher_algorithm_t supported_ciphers[MAX_ALGOS] = {0};
250 if (supported_ciphers[0] == 0)
252 int i = 0;
254 GNUTLS_CIPHER_LOOP (
255 if (_gnutls_cipher_exists(p->id))
256 supported_ciphers[i++]=p->id;
258 supported_ciphers[i++]=0;
261 return supported_ciphers;
265 _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm)
267 ssize_t ret = -1;
268 GNUTLS_ALG_LOOP (ret = p->id);
269 if (ret >= 0)
270 ret = 0;
271 else
272 ret = 1;
273 return ret;