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
31 gnutls_cipher_algorithm_t id
;
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
,
57 {"CAMELLIA-192-CBC", GNUTLS_CIPHER_CAMELLIA_192_CBC
, 16, 24, CIPHER_BLOCK
,
59 {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC
, 16, 16, CIPHER_BLOCK
,
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},
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,
76 {"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB
, 16, 24, CIPHER_BLOCK
, 16,
78 {"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB
, 16, 32, CIPHER_BLOCK
, 16,
80 {"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB
, 16, 16, CIPHER_BLOCK
, 16,
83 {"NULL", GNUTLS_CIPHER_NULL
, 1, 0, CIPHER_STREAM
, 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 */
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.
107 gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm
)
110 GNUTLS_ALG_LOOP (ret
= p
->blocksize
);
115 /* returns the priority */
117 _gnutls_cipher_priority (gnutls_session_t session
,
118 gnutls_cipher_algorithm_t algorithm
)
121 for (i
= 0; i
< session
->internals
.priorities
.cipher
.algorithms
; i
++)
123 if (session
->internals
.priorities
.cipher
.priority
[i
] == algorithm
)
131 _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm
)
135 GNUTLS_ALG_LOOP (ret
= p
->block
);
141 _gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm
)
145 GNUTLS_ALG_LOOP (ret
= p
->auth
);
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.
160 gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm
)
163 GNUTLS_ALG_LOOP (ret
= p
->keysize
);
169 _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm
)
172 GNUTLS_ALG_LOOP (ret
= p
->iv
);
178 _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm
)
181 GNUTLS_ALG_LOOP (ret
= p
->export_flag
);
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.
196 gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm
)
198 const char *ret
= NULL
;
201 GNUTLS_ALG_LOOP (ret
= p
->name
);
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
;
221 if (strcasecmp (p
->name
, name
) == 0)
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)
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
)
268 GNUTLS_ALG_LOOP (ret
= p
->id
);