2 * Copyright (C) 2011 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 {"3DES-CBC", GNUTLS_CIPHER_3DES_CBC
, 8, 24, CIPHER_BLOCK
, 8, 0, 0},
55 {"DES-CBC", GNUTLS_CIPHER_DES_CBC
, 8, 8, CIPHER_BLOCK
, 8, 0, 0},
56 {"ARCFOUR-128", GNUTLS_CIPHER_ARCFOUR_128
, 1, 16, CIPHER_STREAM
, 0, 0, 0},
57 {"ARCFOUR-40", GNUTLS_CIPHER_ARCFOUR_40
, 1, 5, CIPHER_STREAM
, 0, 1, 0},
58 {"RC2-40", GNUTLS_CIPHER_RC2_40_CBC
, 8, 5, CIPHER_BLOCK
, 8, 1, 0},
59 {"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC
, 16, 32, CIPHER_BLOCK
,
61 {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC
, 16, 16, CIPHER_BLOCK
,
65 {"IDEA-PGP-CFB", GNUTLS_CIPHER_IDEA_PGP_CFB
, 8, 16, CIPHER_BLOCK
, 8, 0, 0},
66 {"3DES-PGP-CFB", GNUTLS_CIPHER_3DES_PGP_CFB
, 8, 24, CIPHER_BLOCK
, 8, 0, 0},
67 {"CAST5-PGP-CFB", GNUTLS_CIPHER_CAST5_PGP_CFB
, 8, 16, CIPHER_BLOCK
, 8, 0, 0},
68 {"BLOWFISH-PGP-CFB", GNUTLS_CIPHER_BLOWFISH_PGP_CFB
, 8,
69 16 /*actually unlimited */ , CIPHER_BLOCK
, 8, 0, 0},
70 {"SAFER-SK128-PGP-CFB", GNUTLS_CIPHER_SAFER_SK128_PGP_CFB
, 8, 16,
71 CIPHER_BLOCK
, 8, 0, 0},
72 {"AES-128-PGP-CFB", GNUTLS_CIPHER_AES128_PGP_CFB
, 16, 16, CIPHER_BLOCK
, 16,
74 {"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB
, 16, 24, CIPHER_BLOCK
, 16,
76 {"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB
, 16, 32, CIPHER_BLOCK
, 16,
78 {"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB
, 16, 16, CIPHER_BLOCK
, 16,
81 {"NULL", GNUTLS_CIPHER_NULL
, 1, 0, CIPHER_STREAM
, 0, 0, 0},
85 #define GNUTLS_CIPHER_LOOP(b) \
86 const gnutls_cipher_entry *p; \
87 for(p = algorithms; p->name != NULL; p++) { b ; }
89 #define GNUTLS_ALG_LOOP(a) \
90 GNUTLS_CIPHER_LOOP( if(p->id == algorithm) { a; break; } )
92 /* CIPHER functions */
95 * gnutls_cipher_get_block_size:
96 * @algorithm: is an encryption algorithm
98 * Get block size for encryption algorithm.
100 * Returns: block size for encryption algorithm.
105 gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm
)
108 GNUTLS_ALG_LOOP (ret
= p
->blocksize
);
113 /* returns the priority */
115 _gnutls_cipher_priority (gnutls_session_t session
,
116 gnutls_cipher_algorithm_t algorithm
)
119 for (i
= 0; i
< session
->internals
.priorities
.cipher
.algorithms
; i
++)
121 if (session
->internals
.priorities
.cipher
.priority
[i
] == algorithm
)
129 _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm
)
133 GNUTLS_ALG_LOOP (ret
= p
->block
);
139 _gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm
)
143 GNUTLS_ALG_LOOP (ret
= p
->auth
);
149 * gnutls_cipher_get_key_size:
150 * @algorithm: is an encryption algorithm
152 * Get key size for cipher.
154 * Returns: length (in bytes) of the given cipher's key size, or 0 if
155 * the given cipher is invalid.
158 gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm
)
161 GNUTLS_ALG_LOOP (ret
= p
->keysize
);
167 _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm
)
170 GNUTLS_ALG_LOOP (ret
= p
->iv
);
176 _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm
)
179 GNUTLS_ALG_LOOP (ret
= p
->export_flag
);
185 * gnutls_cipher_get_name:
186 * @algorithm: is an encryption algorithm
188 * Convert a #gnutls_cipher_algorithm_t type to a string.
190 * Returns: a pointer to a string that contains the name of the
191 * specified cipher, or %NULL.
194 gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm
)
196 const char *ret
= NULL
;
199 GNUTLS_ALG_LOOP (ret
= p
->name
);
205 * gnutls_cipher_get_id:
206 * @name: is a cipher algorithm name
208 * The names are compared in a case insensitive way.
210 * Returns: return a #gnutls_cipher_algorithm_t value corresponding to
211 * the specified cipher, or %GNUTLS_CIPHER_UNKNOWN on error.
213 gnutls_cipher_algorithm_t
214 gnutls_cipher_get_id (const char *name
)
216 gnutls_cipher_algorithm_t ret
= GNUTLS_CIPHER_UNKNOWN
;
219 if (strcasecmp (p
->name
, name
) == 0)
230 * gnutls_cipher_list:
232 * Get a list of supported cipher algorithms. Note that not
233 * necessarily all ciphers are supported as TLS cipher suites. For
234 * example, DES is not supported as a cipher suite, but is supported
235 * for other purposes (e.g., PKCS#8 or similar).
237 * This function is not thread safe.
239 * Returns: a (0)-terminated list of #gnutls_cipher_algorithm_t
240 * integers indicating the available ciphers.
243 const gnutls_cipher_algorithm_t
*
244 gnutls_cipher_list (void)
246 static gnutls_cipher_algorithm_t supported_ciphers
[MAX_ALGOS
] = {0};
248 if (supported_ciphers
[0] == 0)
252 GNUTLS_CIPHER_LOOP (supported_ciphers
[i
++]=p
->id
);
253 supported_ciphers
[i
++]=0;
256 return supported_ciphers
;
260 _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm
)
263 GNUTLS_ALG_LOOP (ret
= p
->id
);