1 /*
2 
3   silchmac.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 1999 - 2006 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 
20 #ifndef SILCHMAC_H
21 #define SILCHMAC_H
22 
23 /****h* silccrypt/SILC HMAC Interface
24  *
25  * DESCRIPTION
26  *
27  *    This is the interface for HMAC, or the keyed hash values, that are
28  *    used for packet and message authentication.  These routines uses
29  *    already implemented hash functions from the SilcHashAPI. These
30  *    routines were created according to RFC 2104.
31  *
32  ***/
33 
34 /****s* silccrypt/SilcHMACAPI/SilcHmac
35  *
36  * NAME
37  *
38  *    typedef struct SilcHmacStruct *SilcHmac;
39  *
40  * DESCRIPTION
41  *
42  *    This context is the actual HMAC context and is allocated
43  *    by silc_hmac_alloc and given as argument usually to all
44  *    silc_hmac_* functions.  It is freed by the silc_hmac_free
45  *    function.
46  *
47  ***/
48 typedef struct SilcHmacStruct *SilcHmac;
49 
50 /****s* silccrypt/SilcHMACAPI/SilcHmacObject
51  *
52  * NAME
53  *
54  *    typedef struct { ... } SilcHmacObject;
55  *
56  * DESCRIPTION
57  *
58  *    This structure represents one HMAC.  The HMAC's name and the
59  *    MAC length is defined in the structure.  This structure is
60  *    then given as argument to the silc_hmac_register.  That function
61  *    is used to register all HMACs into SILC.  They can be then
62  *    allocated by the name found in this structure by calling the
63  *    silc_hmac_alloc.
64  *
65  ***/
66 typedef struct {
67   char *name;
68   SilcUInt32 len;
69 } SilcHmacObject;
70 
71 /* Marks for all hmacs. This can be used in silc_hmac_unregister
72    to unregister all hmacs at once. */
73 #define SILC_ALL_HMACS ((SilcHmacObject *)1)
74 
75 /* Default hmacs for silc_hmac_register_default(). */
76 extern DLLAPI const SilcHmacObject silc_default_hmacs[];
77 
78 /* Default HMAC in the SILC protocol */
79 #define SILC_DEFAULT_HMAC "hmac-sha1-96"
80 
81 /* Prototypes */
82 
83 /****f* silccrypt/SilcHMACAPI/silc_hmac_register
84  *
85  * SYNOPSIS
86  *
87  *    SilcBool silc_hmac_register(const SilcHmacObject *hmac);
88  *
89  * DESCRIPTION
90  *
91  *    Registers a new HMAC into the SILC. This function is used at the
92  *    initialization of the SILC.  All registered HMACs should be
93  *    unregistered with silc_hmac_unregister.  The `hmac' includes the
94  *    name of the HMAC and the length of the MAC.  Usually this
95  *    function is not called directly.  Instead, application can call
96  *    the silc_hmac_register_default to register all default HMACs
97  *    that are builtin the sources.  Returns FALSE on error.
98  *
99  ***/
100 SilcBool silc_hmac_register(const SilcHmacObject *hmac);
101 
102 /****f* silccrypt/SilcHMACAPI/silc_hmac_unregister
103  *
104  * SYNOPSIS
105  *
106  *    SilcBool silc_hmac_unregister(SilcHmacObject *hmac);
107  *
108  * DESCRIPTION
109  *
110  *    Unregister a HMAC from SILC by the HMAC structure `hmac'.  This
111  *    should be called for all registered HMAC's.  Returns FALSE on
112  *    error.
113  *
114  ***/
115 SilcBool silc_hmac_unregister(SilcHmacObject *hmac);
116 
117 /****f* silccrypt/SilcHMACAPI/silc_hmac_register_default
118  *
119  * SYNOPSIS
120  *
121  *    SilcBool silc_hmac_register_default(void);
122  *
123  * DESCRIPTION
124  *
125  *    Registers all default HMACs into the SILC.  These are the HMACs
126  *    that are builtin in the sources.  See the list of default HMACs
127  *    in the silchmac.c source file.  The application may use this
128  *    to register default HMACs if specific HMAC in any specific order
129  *    is not wanted (application's configuration usually may decide
130  *    the order of the registration, in which case this should not be
131  *    used).
132  *
133  ***/
134 SilcBool silc_hmac_register_default(void);
135 
136 /****f* silccrypt/SilcHMACAPI/silc_hmac_unregister_all
137  *
138  * SYNOPSIS
139  *
140  *    SilcBool silc_hmac_unregister_all(void);
141  *
142  * DESCRIPTION
143  *
144  *    Unregisters all registered HMACs.
145  *
146  ***/
147 SilcBool silc_hmac_unregister_all(void);
148 
149 /****f* silccrypt/SilcHMACAPI/silc_hmac_alloc
150  *
151  * SYNOPSIS
152  *
153  *    SilcBool silc_hmac_alloc(const char *name, SilcHash hash,
154  *                         SilcHmac *new_hmac);
155  *
156  * DESCRIPTION
157  *
158  *    Allocates a new SilcHmac object of name of `name'.  The `hash' may
159  *    be provided as argument.  If provided it is used as the hash function
160  *    of the HMAC.  If it is NULL then the hash function is allocated and
161  *    the name of the hash algorithm is derived from the `name'.  Returns
162  *    FALSE if such HMAC does not exist.
163  *
164  ***/
165 SilcBool silc_hmac_alloc(const char *name, SilcHash hash, SilcHmac *new_hmac);
166 
167 /****f* silccrypt/SilcHMACAPI/silc_hmac_free
168  *
169  * SYNOPSIS
170  *
171  *    void silc_hmac_free(SilcHmac hmac);
172  *
173  * DESCRIPTION
174  *
175  *    Frees the allocated HMAC context.  The key that may have been set
176  *    with the silc_hmac_set_key is also destroyed.
177  *
178  ***/
179 void silc_hmac_free(SilcHmac hmac);
180 
181 /****f* silccrypt/SilcHMACAPI/silc_hmac_is_supported
182  *
183  * SYNOPSIS
184  *
185  *    SilcBool silc_hmac_is_supported(const char *name);
186  *
187  * DESCRIPTION
188  *
189  *    Returns TRUE if the HMAC indicated by the `name' exists.
190  *
191  ***/
192 SilcBool silc_hmac_is_supported(const char *name);
193 
194 /****f* silccrypt/SilcHMACAPI/silc_hmac_get_supported
195  *
196  * SYNOPSIS
197  *
198  *    char *silc_hmac_get_supported(void);
199  *
200  * DESCRIPTION
201  *
202  *    Returns comma (`,') separated list of registered HMACs.  This is
203  *    used for example when sending supported HMAC list during the SILC
204  *    Key Exchange protocol (SKE).  The caller must free the returned
205  *    pointer.
206  *
207  ***/
208 char *silc_hmac_get_supported(void);
209 
210 /****f* silccrypt/SilcHMACAPI/silc_hmac_len
211  *
212  * SYNOPSIS
213  *
214  *    SilcUInt32 silc_hmac_len(SilcHmac hmac);
215  *
216  * DESCRIPTION
217  *
218  *    Returns the length of the MAC that the HMAC will produce.
219  *
220  ***/
221 SilcUInt32 silc_hmac_len(SilcHmac hmac);
222 
223 /****f* silccrypt/SilcHMACAPI/silc_hmac_get_hash
224  *
225  * SYNOPSIS
226  *
227  *    SilcHash silc_hmac_get_hash(SilcHmac hmac);
228  *
229  * DESCRIPTION
230  *
231  *    Returns the SilcHash context that has been associated with the
232  *    HMAC context.  The caller must not free the returned context.
233  *
234  ***/
235 SilcHash silc_hmac_get_hash(SilcHmac hmac);
236 
237 /****f* silccrypt/SilcHMACAPI/silc_hmac_get_name
238  *
239  * SYNOPSIS
240  *
241  *    const char *silc_hmac_get_name(SilcHmac hmac);
242  *
243  * DESCRIPTION
244  *
245  *    Returns the name of the HMAC context.
246  *
247  ***/
248 const char *silc_hmac_get_name(SilcHmac hmac);
249 
250 /****f* silccrypt/SilcHMACAPI/silc_hmac_set_key
251  *
252  * SYNOPSIS
253  *
254  *    void silc_hmac_set_key(SilcHmac hmac, const unsigned char *key,
255  *                           SilcUInt32 key_len);
256  *
257  * DESCRIPTION
258  *
259  *    Sets the key to be used in the HMAC operation.  This must be set
260  *    before calling silc_hmac_make or silc_hmac_final functions.  If
261  *    you do not want to set the key you can still produce a MAC by
262  *    calling the silc_hmac_make_with_key where you give the key as
263  *    argument.  Usually application still wants to set the key.
264  *
265  ***/
266 void silc_hmac_set_key(SilcHmac hmac, const unsigned char *key,
267 		       SilcUInt32 key_len);
268 
269 /****f* silccrypt/SilcHMACAPI/silc_hmac_get_key
270  *
271  * SYNOPSIS
272  *
273  *    const unsigned char *
274  *    silc_hmac_get_key(SilcHmac hmac, SilcUInt32 *key_len);
275  *
276  * DESCRIPTION
277  *
278  *    Returns the key data from the `hmac' set with silc_hamc_set_key.
279  *    The caller must not free the returned pointer.
280  *
281  ***/
282 const unsigned char *silc_hmac_get_key(SilcHmac hmac, SilcUInt32 *key_len);
283 
284 /****f* silccrypt/SilcHMACAPI/silc_hmac_make
285  *
286  * SYNOPSIS
287  *
288  *    void silc_hmac_make(SilcHmac hmac, unsigned char *data,
289  *                        SilcUInt32 data_len, unsigned char *return_hash,
290  *                        SilcUInt32 *return_len);
291  *
292  * DESCRIPTION
293  *
294  *    Computes a MAC from a data buffer indicated by the `data' of the
295  *    length of `data_len'.  The returned MAC is copied into the
296  *    `return_hash' pointer which must be at least the size of the
297  *    value silc_hmac_len returns.  The returned length is still
298  *    returned to `return_len'.
299  *
300  ***/
301 void silc_hmac_make(SilcHmac hmac, unsigned char *data,
302 		    SilcUInt32 data_len, unsigned char *return_hash,
303 		    SilcUInt32 *return_len);
304 
305 /****f* silccrypt/SilcHMACAPI/silc_hmac_make_with_key
306  *
307  * SYNOPSIS
308  *
309  *    void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
310  *                                 SilcUInt32 data_len,
311  *                                 unsigned char *key, SilcUInt32 key_len,
312  *                                 unsigned char *return_hash,
313  *                                 SilcUInt32 *return_len);
314  *
315  * DESCRIPTION
316  *
317  *    Same as the silc_hmac_make but takes the key for the HMAC as
318  *    argument.  If this is used the key that may have been set by calling
319  *    silc_hmac_set_key is ignored.
320  *
321  ***/
322 void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
323 			     SilcUInt32 data_len,
324 			     unsigned char *key, SilcUInt32 key_len,
325 			     unsigned char *return_hash,
326 			     SilcUInt32 *return_len);
327 
328 /****f* silccrypt/SilcHMACAPI/silc_hmac_make_truncated
329  *
330  * SYNOPSIS
331  *
332  *    void silc_hmac_make_truncated(SilcHmac hmac,
333  *                                  unsigned char *data,
334  *                                  SilcUInt32 data_len,
335  *                                  SilcUInt32 truncated_len,
336  *                                  unsigned char *return_hash);
337  *
338  * DESCRIPTION
339  *
340  *    Same as the silc_hmac_make except that the returned MAC is
341  *    truncated to the length indicated by the `truncated_len'.  Some
342  *    special applications may need this function.  The `return_hash'
343  *    must be at least the size of `truncated_len'.
344  *
345  * NOTES
346  *
347  *    For security reasons, one should not truncate to less than half
348  *    of the length of the true MAC lenght.  However, since this routine
349  *    may be used to non-critical applications this allows these dangerous
350  *    truncations.
351  *
352  ***/
353 void silc_hmac_make_truncated(SilcHmac hmac,
354 			      unsigned char *data,
355 			      SilcUInt32 data_len,
356 			      SilcUInt32 truncated_len,
357 			      unsigned char *return_hash);
358 
359 /****f* silccrypt/SilcHMACAPI/silc_hmac_init
360  *
361  * SYNOPSIS
362  *
363  *    void silc_hmac_init(SilcHmac hmac);
364  *
365  * DESCRIPTION
366  *
367  *    Sometimes calling the silc_hmac_make might not be the most
368  *    optimal case of doing MACs.  If you have a lot of different data
369  *    that you need to put together for computing a MAC you may either
370  *    put them into a buffer and compute the MAC from the buffer by
371  *    calling the silc_hmac_make, or you can use the silc_hmac_init,
372  *    silc_hmac_update and silc_hmac_final to do the MAC.  This function
373  *    prepares the allocated HMAC context for this kind of MAC
374  *    computation.  The caller must have been called the function
375  *    silc_hmac_set_key before calling this function.  To add the
376  *    data to be used in the MAC computation call the silc_hmac_update
377  *    function.
378  *
379  ***/
380 void silc_hmac_init(SilcHmac hmac);
381 
382 /****f* silccrypt/SilcHMACAPI/silc_hmac_init_with_key
383  *
384  * SYNOPSIS
385  *
386  *    void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key,
387  *                                 SilcUInt32 key_len);
388  *
389  * DESCRIPTION
390  *
391  *    Same as silc_hmac_init but initializes with specific key.  The
392  *    key that may have been set with silc_hmac_set_key is ignored.
393  *
394  ***/
395 void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key,
396 			     SilcUInt32 key_len);
397 
398 /****f* silccrypt/SilcHMACAPI/silc_hmac_update
399  *
400  * SYNOPSIS
401  *
402  *    void silc_hmac_update(SilcHmac hmac, const unsigned char *data,
403  *                          SilcUInt32 data_len);
404  *
405  * DESCRIPTION
406  *
407  *    This function may be called to add data to be used in the MAC
408  *    computation.  This can be called multiple times to add data from
409  *    many sources before actually performing the HMAC.  Once you've
410  *    added all the data you need you can call the silc_hmac_final to
411  *    actually produce the MAC.
412  *
413  * EXAMPLE
414  *
415  *    unsigned char mac[20];
416  *    SilcUInt32 mac_len;
417  *
418  *    silc_hmac_init(hmac);
419  *    silc_hmac_update(hmac, data, data_len);
420  *    silc_hmac_update(hmac, more_data, more_data_len);
421  *    silc_hmac_final(hmac, mac, &mac_len);
422  *
423  ***/
424 void silc_hmac_update(SilcHmac hmac, const unsigned char *data,
425 		      SilcUInt32 data_len);
426 
427 /****f* silccrypt/SilcHMACAPI/silc_hmac_final
428  *
429  * SYNOPSIS
430  *
431  *    void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash,
432  *                         SilcUInt32 *return_len);
433  *
434  * DESCRIPTION
435  *
436  *    This function is used to produce the final MAC from the data
437  *    that has been added to the HMAC context by calling the
438  *    silc_hmac_update function.  The MAC is copied in to the
439  *    `return_hash' pointer which must be at least the size that
440  *    the silc_hmac_len returns.  The length of the MAC is still
441  *    returned into `return_len'.
442  *
443  ***/
444 void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash,
445 		     SilcUInt32 *return_len);
446 
447 #endif
448