1 /* dtls -- a very basic DTLS implementation
2  *
3  * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * Permission is hereby granted, free of charge, to any person
6  * obtaining a copy of this software and associated documentation
7  * files (the "Software"), to deal in the Software without
8  * restriction, including without limitation the rights to use, copy,
9  * modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 #ifndef _DTLS_HMAC_H_
27 #define _DTLS_HMAC_H_
28 
29 #include <sys/types.h>
30 
31 #include "global.h"
32 
33 #ifdef WITH_SHA256
34 /** Aaron D. Gifford's implementation of SHA256
35  *  see http://www.aarongifford.com/ */
36 #include "sha2/sha2.h"
37 
38 typedef SHA256_CTX dtls_hash_ctx;
39 typedef dtls_hash_ctx *dtls_hash_t;
40 #define DTLS_HASH_CTX_SIZE sizeof(SHA256_CTX)
41 
42 static inline void
dtls_hash_init(dtls_hash_t ctx)43 dtls_hash_init(dtls_hash_t ctx) {
44   SHA256_Init((SHA256_CTX *)ctx);
45 }
46 
47 static inline void
dtls_hash_update(dtls_hash_t ctx,const unsigned char * input,size_t len)48 dtls_hash_update(dtls_hash_t ctx, const unsigned char *input, size_t len) {
49   SHA256_Update((SHA256_CTX *)ctx, input, len);
50 }
51 
52 static inline size_t
dtls_hash_finalize(unsigned char * buf,dtls_hash_t ctx)53 dtls_hash_finalize(unsigned char *buf, dtls_hash_t ctx) {
54   SHA256_Final(buf, (SHA256_CTX *)ctx);
55   return SHA256_DIGEST_LENGTH;
56 }
57 #endif /* WITH_SHA256 */
58 
59 #ifndef WITH_CONTIKI
dtls_hmac_storage_init()60 static inline void dtls_hmac_storage_init()
61 { }
62 #else
63 void dtls_hmac_storage_init();
64 #endif
65 
66 /**
67  * \defgroup HMAC Keyed-Hash Message Authentication Code (HMAC)
68  * NIST Standard FIPS 198 describes the Keyed-Hash Message Authentication
69  * Code (HMAC) which is used as hash function for the DTLS PRF.
70  * @{
71  */
72 
73 #define DTLS_HMAC_BLOCKSIZE   64	/**< size of hmac blocks */
74 #define DTLS_HMAC_DIGEST_SIZE 32	/**< digest size (for SHA-256) */
75 #define DTLS_HMAC_MAX         64	/**< max number of bytes in digest */
76 
77 /**
78  * List of known hash functions for use in dtls_hmac_init(). The
79  * identifiers are the same as the HashAlgorithm defined in
80  * <a href="http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1"
81  * >Section 7.4.1.4.1 of RFC 5246</a>.
82  */
83 typedef enum {
84   HASH_NONE=0, HASH_MD5=1, HASH_SHA1=2, HASH_SHA224=3,
85   HASH_SHA256=4, HASH_SHA384=5, HASH_SHA512=6
86 } dtls_hashfunc_t;
87 
88 /**
89  * Context for HMAC generation. This object is initialized with
90  * dtls_hmac_init() and must be passed to dtls_hmac_update() and
91  * dtls_hmac_finalize(). Once, finalized, the component \c H is
92  * invalid and must be initialized again with dtls_hmac_init() before
93  * the structure can be used again.
94  */
95 typedef struct {
96   unsigned char pad[DTLS_HMAC_BLOCKSIZE]; /**< ipad and opad storage */
97   dtls_hash_ctx data;		          /**< context for hash function */
98 } dtls_hmac_context_t;
99 
100 /**
101  * Initializes an existing HMAC context.
102  *
103  * @param ctx The HMAC context to initialize.
104  * @param key    The secret key.
105  * @param klen   The length of @p key.
106  */
107 void dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen);
108 
109 /**
110  * Allocates a new HMAC context \p ctx with the given secret key.
111  * This function returns \c 1 if \c ctx has been set correctly, or \c
112  * 0 or \c -1 otherwise. Note that this function allocates new storage
113  * that must be released by dtls_hmac_free().
114  *
115  * \param key    The secret key.
116  * \param klen   The length of \p key.
117  * \return A new dtls_hmac_context_t object or @c NULL on error
118  */
119 dtls_hmac_context_t *dtls_hmac_new(const unsigned char *key, size_t klen);
120 
121 /**
122  * Releases the storage for @p ctx that has been allocated by
123  * dtls_hmac_new().
124  *
125  * @param ctx The dtls_hmac_context_t to free.
126  */
127 void dtls_hmac_free(dtls_hmac_context_t *ctx);
128 
129 /**
130  * Updates the HMAC context with data from \p input.
131  *
132  * \param ctx    The HMAC context.
133  * \param input  The input data.
134  * \param ilen   Size of \p input.
135  */
136 void dtls_hmac_update(dtls_hmac_context_t *ctx,
137 		      const unsigned char *input, size_t ilen);
138 
139 /**
140  * Completes the HMAC generation and writes the result to the given
141  * output parameter \c result. The buffer must be large enough to hold
142  * the message digest created by the actual hash function. If in
143  * doubt, use \c DTLS_HMAC_MAX. The function returns the number of
144  * bytes written to \c result.
145  *
146  * \param ctx    The HMAC context.
147  * \param result Output parameter where the MAC is written to.
148  * \return Length of the MAC written to \p result.
149  */
150 int dtls_hmac_finalize(dtls_hmac_context_t *ctx, unsigned char *result);
151 
152 /**@}*/
153 
154 #endif /* _DTLS_HMAC_H_ */
155