cleaned up errno handling.
[gnutls.git] / lib / algorithms / mac.c
blobad7d57c582ada0d72ae723a7d6a35ddf13d7d032
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_hash_entry
30 const char *name;
31 const char *oid;
32 gnutls_mac_algorithm_t id;
33 size_t key_size; /* in case of mac */
34 unsigned placeholder; /* if set, then not a real MAC */
36 typedef struct gnutls_hash_entry gnutls_hash_entry;
38 static const gnutls_hash_entry hash_algorithms[] = {
39 {"SHA1", HASH_OID_SHA1, GNUTLS_MAC_SHA1, 20, 0},
40 {"MD5", HASH_OID_MD5, GNUTLS_MAC_MD5, 16, 0},
41 {"SHA256", HASH_OID_SHA256, GNUTLS_MAC_SHA256, 32, 0},
42 {"SHA384", HASH_OID_SHA384, GNUTLS_MAC_SHA384, 48, 0},
43 {"SHA512", HASH_OID_SHA512, GNUTLS_MAC_SHA512, 64, 0},
44 {"SHA224", HASH_OID_SHA224, GNUTLS_MAC_SHA224, 28, 0},
45 {"AEAD", NULL, GNUTLS_MAC_AEAD, 0, 1},
46 {"MD2", HASH_OID_MD2, GNUTLS_MAC_MD2, 0, 0}, /* not used as MAC */
47 {"RIPEMD160", HASH_OID_RMD160, GNUTLS_MAC_RMD160, 20, 0},
48 {"MAC-NULL", NULL, GNUTLS_MAC_NULL, 0, 0},
49 {0, 0, 0, 0}
53 #define GNUTLS_HASH_LOOP(b) \
54 const gnutls_hash_entry *p; \
55 for(p = hash_algorithms; p->name != NULL; p++) { b ; }
57 #define GNUTLS_HASH_ALG_LOOP(a) \
58 GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
60 int
61 _gnutls_mac_priority (gnutls_session_t session,
62 gnutls_mac_algorithm_t algorithm)
63 { /* actually returns the priority */
64 unsigned int i;
65 for (i = 0; i < session->internals.priorities.mac.algorithms; i++)
67 if (session->internals.priorities.mac.priority[i] == algorithm)
68 return i;
70 return -1;
73 /**
74 * gnutls_mac_get_name:
75 * @algorithm: is a MAC algorithm
77 * Convert a #gnutls_mac_algorithm_t value to a string.
79 * Returns: a string that contains the name of the specified MAC
80 * algorithm, or %NULL.
81 **/
82 const char *
83 gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm)
85 const char *ret = NULL;
87 /* avoid prefix */
88 GNUTLS_HASH_ALG_LOOP (ret = p->name);
90 return ret;
93 /**
94 * gnutls_mac_get_id:
95 * @name: is a MAC algorithm name
97 * Convert a string to a #gnutls_mac_algorithm_t value. The names are
98 * compared in a case insensitive way.
100 * Returns: a #gnutls_mac_algorithm_t id of the specified MAC
101 * algorithm string, or %GNUTLS_MAC_UNKNOWN on failures.
103 gnutls_mac_algorithm_t
104 gnutls_mac_get_id (const char *name)
106 gnutls_mac_algorithm_t ret = GNUTLS_MAC_UNKNOWN;
108 GNUTLS_HASH_LOOP (
109 if (strcasecmp (p->name, name) == 0)
111 ret = p->id;
112 break;
116 return ret;
120 * gnutls_mac_get_key_size:
121 * @algorithm: is an encryption algorithm
123 * Get size of MAC key.
125 * Returns: length (in bytes) of the given MAC key size, or 0 if the
126 * given MAC algorithm is invalid.
128 size_t
129 gnutls_mac_get_key_size (gnutls_mac_algorithm_t algorithm)
131 size_t ret = 0;
133 /* avoid prefix */
134 GNUTLS_HASH_ALG_LOOP (ret = p->key_size);
136 return ret;
140 * gnutls_mac_list:
142 * Get a list of hash algorithms for use as MACs. Note that not
143 * necessarily all MACs are supported in TLS cipher suites. For
144 * example, MD2 is not supported as a cipher suite, but is supported
145 * for other purposes (e.g., X.509 signature verification or similar).
147 * This function is not thread safe.
149 * Returns: Return a (0)-terminated list of #gnutls_mac_algorithm_t
150 * integers indicating the available MACs.
152 const gnutls_mac_algorithm_t *
153 gnutls_mac_list (void)
155 static gnutls_mac_algorithm_t supported_macs[MAX_ALGOS] = { 0 };
157 if (supported_macs[0] == 0)
159 int i = 0;
161 GNUTLS_HASH_LOOP (
162 if (p->placeholder != 0 || _gnutls_hmac_exists(p->id))
163 supported_macs[i++]=p->id;
165 supported_macs[i++]=0;
168 return supported_macs;
171 const char *
172 _gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t algorithm)
174 const char *ret = NULL;
176 /* avoid prefix */
177 GNUTLS_HASH_ALG_LOOP (ret = p->oid);
179 return ret;
182 gnutls_digest_algorithm_t
183 _gnutls_x509_oid_to_digest (const char *oid)
185 gnutls_digest_algorithm_t ret = 0;
187 GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
189 ret = (gnutls_digest_algorithm_t)p->id;
190 break;
194 if (ret == 0)
195 return GNUTLS_DIG_UNKNOWN;
196 return ret;
199 const char *
200 _gnutls_x509_digest_to_oid (gnutls_digest_algorithm_t algorithm)
202 return _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) algorithm);
205 const char *
206 _gnutls_digest_get_name (gnutls_digest_algorithm_t algorithm)
208 return gnutls_mac_get_name ((gnutls_mac_algorithm_t) algorithm);
212 _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
214 ssize_t ret = -1;
215 GNUTLS_HASH_ALG_LOOP (ret = p->id);
216 if (ret >= 0)
217 ret = 0;
218 else
219 ret = 1;
220 return ret;