mbed port of tinydtls

Committer:
ashleymills
Date:
Thu Oct 10 21:38:07 2013 +0000
Revision:
0:04990d454f45
It now works. Found nasty gotcha with non-std sockaddr_in

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:04990d454f45 1 /* dtls -- a very basic DTLS implementation
ashleymills 0:04990d454f45 2 *
ashleymills 0:04990d454f45 3 * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
ashleymills 0:04990d454f45 4 *
ashleymills 0:04990d454f45 5 * Permission is hereby granted, free of charge, to any person
ashleymills 0:04990d454f45 6 * obtaining a copy of this software and associated documentation
ashleymills 0:04990d454f45 7 * files (the "Software"), to deal in the Software without
ashleymills 0:04990d454f45 8 * restriction, including without limitation the rights to use, copy,
ashleymills 0:04990d454f45 9 * modify, merge, publish, distribute, sublicense, and/or sell copies
ashleymills 0:04990d454f45 10 * of the Software, and to permit persons to whom the Software is
ashleymills 0:04990d454f45 11 * furnished to do so, subject to the following conditions:
ashleymills 0:04990d454f45 12 *
ashleymills 0:04990d454f45 13 * The above copyright notice and this permission notice shall be
ashleymills 0:04990d454f45 14 * included in all copies or substantial portions of the Software.
ashleymills 0:04990d454f45 15 *
ashleymills 0:04990d454f45 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
ashleymills 0:04990d454f45 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
ashleymills 0:04990d454f45 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ashleymills 0:04990d454f45 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
ashleymills 0:04990d454f45 20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ashleymills 0:04990d454f45 21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
ashleymills 0:04990d454f45 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
ashleymills 0:04990d454f45 23 * SOFTWARE.
ashleymills 0:04990d454f45 24 */
ashleymills 0:04990d454f45 25
ashleymills 0:04990d454f45 26 #ifndef _CRYPTO_H_
ashleymills 0:04990d454f45 27 #define _CRYPTO_H_
ashleymills 0:04990d454f45 28
ashleymills 0:04990d454f45 29 #include "config.h"
ashleymills 0:04990d454f45 30
ashleymills 0:04990d454f45 31 #include <stdlib.h> /* for rand() and srand() */
ashleymills 0:04990d454f45 32
ashleymills 0:04990d454f45 33 #include "aes/rijndael.h"
ashleymills 0:04990d454f45 34
ashleymills 0:04990d454f45 35 #include "prng.h"
ashleymills 0:04990d454f45 36 #include "global.h"
ashleymills 0:04990d454f45 37 #include "numeric.h"
ashleymills 0:04990d454f45 38 #include "hmac.h"
ashleymills 0:04990d454f45 39 #include "ccm.h"
ashleymills 0:04990d454f45 40
ashleymills 0:04990d454f45 41 /* TLS_PSK_WITH_AES_128_CCM_8 */
ashleymills 0:04990d454f45 42 #define DTLS_MAC_KEY_LENGTH 0
ashleymills 0:04990d454f45 43 #define DTLS_KEY_LENGTH 16 /* AES-128 */
ashleymills 0:04990d454f45 44 #define DTLS_BLK_LENGTH 16 /* AES-128 */
ashleymills 0:04990d454f45 45 #define DTLS_MAC_LENGTH DTLS_HMAC_DIGEST_SIZE
ashleymills 0:04990d454f45 46 #define DTLS_IV_LENGTH 4 /* length of nonce_explicit */
ashleymills 0:04990d454f45 47
ashleymills 0:04990d454f45 48 /**
ashleymills 0:04990d454f45 49 * Maximum size of the generated keyblock. Note that MAX_KEYBLOCK_LENGTH must
ashleymills 0:04990d454f45 50 * be large enough to hold the pre_master_secret, i.e. twice the length of the
ashleymills 0:04990d454f45 51 * pre-shared key + 1.
ashleymills 0:04990d454f45 52 */
ashleymills 0:04990d454f45 53 #define MAX_KEYBLOCK_LENGTH \
ashleymills 0:04990d454f45 54 (2 * DTLS_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH + 2 * DTLS_IV_LENGTH)
ashleymills 0:04990d454f45 55
ashleymills 0:04990d454f45 56 /** Length of DTLS master_secret */
ashleymills 0:04990d454f45 57 #define DTLS_MASTER_SECRET_LENGTH 48
ashleymills 0:04990d454f45 58
ashleymills 0:04990d454f45 59 #ifndef DTLS_CIPHER_CONTEXT_MAX
ashleymills 0:04990d454f45 60 #define DTLS_CIPHER_CONTEXT_MAX 4
ashleymills 0:04990d454f45 61 #endif
ashleymills 0:04990d454f45 62
ashleymills 0:04990d454f45 63 typedef enum { AES128=0
ashleymills 0:04990d454f45 64 } dtls_crypto_alg;
ashleymills 0:04990d454f45 65
ashleymills 0:04990d454f45 66 /** Crypto context for TLS_PSK_WITH_AES_128_CCM_8 cipher suite. */
ashleymills 0:04990d454f45 67 typedef struct {
ashleymills 0:04990d454f45 68 rijndael_ctx ctx; /**< AES-128 encryption context */
ashleymills 0:04990d454f45 69 unsigned char N[DTLS_CCM_BLOCKSIZE]; /**< nonce */
ashleymills 0:04990d454f45 70 } aes128_ccm_t;
ashleymills 0:04990d454f45 71
ashleymills 0:04990d454f45 72 typedef struct dtls_cipher_context_t {
ashleymills 0:04990d454f45 73 /** numeric identifier of this cipher suite in host byte order. */
ashleymills 0:04990d454f45 74 dtls_cipher_t code;
ashleymills 0:04990d454f45 75 aes128_ccm_t data; /**< The crypto context */
ashleymills 0:04990d454f45 76 } dtls_cipher_context_t;
ashleymills 0:04990d454f45 77
ashleymills 0:04990d454f45 78 typedef enum { DTLS_CLIENT=0, DTLS_SERVER } dtls_peer_type;
ashleymills 0:04990d454f45 79
ashleymills 0:04990d454f45 80 typedef struct {
ashleymills 0:04990d454f45 81 uint8 client_random[32]; /**< client random gmt and bytes */
ashleymills 0:04990d454f45 82
ashleymills 0:04990d454f45 83 dtls_peer_type role; /**< denotes if the remote peer is DTLS_CLIENT or DTLS_SERVER */
ashleymills 0:04990d454f45 84 unsigned char compression; /**< compression method */
ashleymills 0:04990d454f45 85
ashleymills 0:04990d454f45 86 dtls_cipher_t cipher; /**< cipher type */
ashleymills 0:04990d454f45 87
ashleymills 0:04990d454f45 88 /** the session's master secret */
ashleymills 0:04990d454f45 89 uint8 master_secret[DTLS_MASTER_SECRET_LENGTH];
ashleymills 0:04990d454f45 90
ashleymills 0:04990d454f45 91 /**
ashleymills 0:04990d454f45 92 * The key block generated from PRF applied to client and server
ashleymills 0:04990d454f45 93 * random bytes. The actual size is given by the selected cipher and
ashleymills 0:04990d454f45 94 * can be calculated using dtls_kb_size(). Use \c dtls_kb_ macros to
ashleymills 0:04990d454f45 95 * access the components of the key block.
ashleymills 0:04990d454f45 96 */
ashleymills 0:04990d454f45 97 uint8 key_block[MAX_KEYBLOCK_LENGTH];
ashleymills 0:04990d454f45 98
ashleymills 0:04990d454f45 99 dtls_cipher_context_t *read_cipher; /**< decryption context */
ashleymills 0:04990d454f45 100 dtls_cipher_context_t *write_cipher; /**< encryption context */
ashleymills 0:04990d454f45 101 } dtls_security_parameters_t;
ashleymills 0:04990d454f45 102
ashleymills 0:04990d454f45 103 /* The following macros provide access to the components of the
ashleymills 0:04990d454f45 104 * key_block in the security parameters. */
ashleymills 0:04990d454f45 105
ashleymills 0:04990d454f45 106 #define dtls_kb_client_mac_secret(Param) ((Param)->key_block)
ashleymills 0:04990d454f45 107 #define dtls_kb_server_mac_secret(Param) \
ashleymills 0:04990d454f45 108 (dtls_kb_client_mac_secret(Param) + DTLS_MAC_KEY_LENGTH)
ashleymills 0:04990d454f45 109 #define dtls_kb_remote_mac_secret(Param) \
ashleymills 0:04990d454f45 110 ((Param)->role == DTLS_CLIENT \
ashleymills 0:04990d454f45 111 ? dtls_kb_client_mac_secret(Param) \
ashleymills 0:04990d454f45 112 : dtls_kb_server_mac_secret(Param))
ashleymills 0:04990d454f45 113 #define dtls_kb_local_mac_secret(Param) \
ashleymills 0:04990d454f45 114 ((Param)->role == DTLS_SERVER \
ashleymills 0:04990d454f45 115 ? dtls_kb_client_mac_secret(Param) \
ashleymills 0:04990d454f45 116 : dtls_kb_server_mac_secret(Param))
ashleymills 0:04990d454f45 117 #define dtls_kb_mac_secret_size(Param) DTLS_MAC_KEY_LENGTH
ashleymills 0:04990d454f45 118 #define dtls_kb_client_write_key(Param) \
ashleymills 0:04990d454f45 119 (dtls_kb_server_mac_secret(Param) + DTLS_MAC_KEY_LENGTH)
ashleymills 0:04990d454f45 120 #define dtls_kb_server_write_key(Param) \
ashleymills 0:04990d454f45 121 (dtls_kb_client_write_key(Param) + DTLS_KEY_LENGTH)
ashleymills 0:04990d454f45 122 #define dtls_kb_remote_write_key(Param) \
ashleymills 0:04990d454f45 123 ((Param)->role == DTLS_CLIENT \
ashleymills 0:04990d454f45 124 ? dtls_kb_client_write_key(Param) \
ashleymills 0:04990d454f45 125 : dtls_kb_server_write_key(Param))
ashleymills 0:04990d454f45 126 #define dtls_kb_local_write_key(Param) \
ashleymills 0:04990d454f45 127 ((Param)->role == DTLS_SERVER \
ashleymills 0:04990d454f45 128 ? dtls_kb_client_write_key(Param) \
ashleymills 0:04990d454f45 129 : dtls_kb_server_write_key(Param))
ashleymills 0:04990d454f45 130 #define dtls_kb_key_size(Param) DTLS_KEY_LENGTH
ashleymills 0:04990d454f45 131 #define dtls_kb_client_iv(Param) \
ashleymills 0:04990d454f45 132 (dtls_kb_server_write_key(Param) + DTLS_KEY_LENGTH)
ashleymills 0:04990d454f45 133 #define dtls_kb_server_iv(Param) \
ashleymills 0:04990d454f45 134 (dtls_kb_client_iv(Param) + DTLS_IV_LENGTH)
ashleymills 0:04990d454f45 135 #define dtls_kb_remote_iv(Param) \
ashleymills 0:04990d454f45 136 ((Param)->role == DTLS_CLIENT \
ashleymills 0:04990d454f45 137 ? dtls_kb_client_iv(Param) \
ashleymills 0:04990d454f45 138 : dtls_kb_server_iv(Param))
ashleymills 0:04990d454f45 139 #define dtls_kb_local_iv(Param) \
ashleymills 0:04990d454f45 140 ((Param)->role == DTLS_SERVER \
ashleymills 0:04990d454f45 141 ? dtls_kb_client_iv(Param) \
ashleymills 0:04990d454f45 142 : dtls_kb_server_iv(Param))
ashleymills 0:04990d454f45 143 #define dtls_kb_iv_size(Param) DTLS_IV_LENGTH
ashleymills 0:04990d454f45 144
ashleymills 0:04990d454f45 145 #define dtls_kb_size(Param) \
ashleymills 0:04990d454f45 146 (2 * (dtls_kb_mac_secret_size(Param) + \
ashleymills 0:04990d454f45 147 dtls_kb_key_size(Param) + dtls_kb_iv_size(Param)))
ashleymills 0:04990d454f45 148
ashleymills 0:04990d454f45 149 /* just for consistency */
ashleymills 0:04990d454f45 150 #define dtls_kb_digest_size(Param) DTLS_MAC_LENGTH
ashleymills 0:04990d454f45 151
ashleymills 0:04990d454f45 152 /**
ashleymills 0:04990d454f45 153 * Expands the secret and key to a block of DTLS_HMAC_MAX
ashleymills 0:04990d454f45 154 * size according to the algorithm specified in section 5 of
ashleymills 0:04990d454f45 155 * RFC 4346.
ashleymills 0:04990d454f45 156 *
ashleymills 0:04990d454f45 157 * \param h Identifier of the hash function to use.
ashleymills 0:04990d454f45 158 * \param key The secret.
ashleymills 0:04990d454f45 159 * \param keylen Length of \p key.
ashleymills 0:04990d454f45 160 * \param seed The seed.
ashleymills 0:04990d454f45 161 * \param seedlen Length of \p seed.
ashleymills 0:04990d454f45 162 * \param buf Output buffer where the result is XORed into
ashleymills 0:04990d454f45 163 * The buffe must be capable to hold at least
ashleymills 0:04990d454f45 164 * \p buflen bytes.
ashleymills 0:04990d454f45 165 * \return The actual number of bytes written to \p buf or 0
ashleymills 0:04990d454f45 166 * on error.
ashleymills 0:04990d454f45 167 */
ashleymills 0:04990d454f45 168 size_t dtls_p_hash(dtls_hashfunc_t h,
ashleymills 0:04990d454f45 169 const unsigned char *key, size_t keylen,
ashleymills 0:04990d454f45 170 const unsigned char *label, size_t labellen,
ashleymills 0:04990d454f45 171 const unsigned char *random1, size_t random1len,
ashleymills 0:04990d454f45 172 const unsigned char *random2, size_t random2len,
ashleymills 0:04990d454f45 173 unsigned char *buf, size_t buflen);
ashleymills 0:04990d454f45 174
ashleymills 0:04990d454f45 175 /**
ashleymills 0:04990d454f45 176 * This function implements the TLS PRF for DTLS_VERSION. For version
ashleymills 0:04990d454f45 177 * 1.0, the PRF is P_MD5 ^ P_SHA1 while version 1.2 uses
ashleymills 0:04990d454f45 178 * P_SHA256. Currently, the actual PRF is selected at compile time.
ashleymills 0:04990d454f45 179 */
ashleymills 0:04990d454f45 180 size_t dtls_prf(const unsigned char *key, size_t keylen,
ashleymills 0:04990d454f45 181 const unsigned char *label, size_t labellen,
ashleymills 0:04990d454f45 182 const unsigned char *random1, size_t random1len,
ashleymills 0:04990d454f45 183 const unsigned char *random2, size_t random2len,
ashleymills 0:04990d454f45 184 unsigned char *buf, size_t buflen);
ashleymills 0:04990d454f45 185
ashleymills 0:04990d454f45 186 /**
ashleymills 0:04990d454f45 187 * Calculates MAC for record + cleartext packet and places the result
ashleymills 0:04990d454f45 188 * in \p buf. The given \p hmac_ctx must be initialized with the HMAC
ashleymills 0:04990d454f45 189 * function to use and the proper secret. As the DTLS mac calculation
ashleymills 0:04990d454f45 190 * requires data from the record header, \p record must point to a
ashleymills 0:04990d454f45 191 * buffer of at least \c sizeof(dtls_record_header_t) bytes. Usually,
ashleymills 0:04990d454f45 192 * the remaining packet will be encrypted, therefore, the cleartext
ashleymills 0:04990d454f45 193 * is passed separately in \p packet.
ashleymills 0:04990d454f45 194 *
ashleymills 0:04990d454f45 195 * \param hmac_ctx The HMAC context to use for MAC calculation.
ashleymills 0:04990d454f45 196 * \param record The record header.
ashleymills 0:04990d454f45 197 * \param packet Cleartext payload to apply the MAC to.
ashleymills 0:04990d454f45 198 * \param length Size of \p packet.
ashleymills 0:04990d454f45 199 * \param buf A result buffer that is large enough to hold
ashleymills 0:04990d454f45 200 * the generated digest.
ashleymills 0:04990d454f45 201 */
ashleymills 0:04990d454f45 202 void dtls_mac(dtls_hmac_context_t *hmac_ctx,
ashleymills 0:04990d454f45 203 const unsigned char *record,
ashleymills 0:04990d454f45 204 const unsigned char *packet, size_t length,
ashleymills 0:04990d454f45 205 unsigned char *buf);
ashleymills 0:04990d454f45 206
ashleymills 0:04990d454f45 207 /**
ashleymills 0:04990d454f45 208 * Encrypts the specified \p src of given \p length, writing the
ashleymills 0:04990d454f45 209 * result to \p buf. The cipher implementation may add more data to
ashleymills 0:04990d454f45 210 * the result buffer such as an initialization vector or padding
ashleymills 0:04990d454f45 211 * (e.g. for block cipers in CBC mode). The caller therefore must
ashleymills 0:04990d454f45 212 * ensure that \p buf provides sufficient storage to hold the result.
ashleymills 0:04990d454f45 213 * Usually this means ( 2 + \p length / blocksize ) * blocksize. The
ashleymills 0:04990d454f45 214 * function returns a value less than zero on error or otherwise the
ashleymills 0:04990d454f45 215 * number of bytes written.
ashleymills 0:04990d454f45 216 *
ashleymills 0:04990d454f45 217 * \param ctx The cipher context to use.
ashleymills 0:04990d454f45 218 * \param src The data to encrypt.
ashleymills 0:04990d454f45 219 * \param length The actual size of of \p src.
ashleymills 0:04990d454f45 220 * \param buf The result buffer. \p src and \p buf must not
ashleymills 0:04990d454f45 221 * overlap.
ashleymills 0:04990d454f45 222 * \param aad additional data for AEAD ciphers
ashleymills 0:04990d454f45 223 * \param aad_length actual size of @p aad
ashleymills 0:04990d454f45 224 * \return The number of encrypted bytes on success, less than zero
ashleymills 0:04990d454f45 225 * otherwise.
ashleymills 0:04990d454f45 226 */
ashleymills 0:04990d454f45 227 int dtls_encrypt(dtls_cipher_context_t *ctx,
ashleymills 0:04990d454f45 228 const unsigned char *src, size_t length,
ashleymills 0:04990d454f45 229 unsigned char *buf,
ashleymills 0:04990d454f45 230 const unsigned char *aad, size_t aad_length);
ashleymills 0:04990d454f45 231
ashleymills 0:04990d454f45 232 /**
ashleymills 0:04990d454f45 233 * Decrypts the given buffer \p src of given \p length, writing the
ashleymills 0:04990d454f45 234 * result to \p buf. The function returns \c -1 in case of an error,
ashleymills 0:04990d454f45 235 * or the number of bytes written. Note that for block ciphers, \p
ashleymills 0:04990d454f45 236 * length must be a multiple of the cipher's block size. A return
ashleymills 0:04990d454f45 237 * value between \c 0 and the actual length indicates that only \c n-1
ashleymills 0:04990d454f45 238 * block have been processed. Unlike dtls_encrypt(), the source
ashleymills 0:04990d454f45 239 * and destination of dtls_decrypt() may overlap.
ashleymills 0:04990d454f45 240 *
ashleymills 0:04990d454f45 241 * \param ctx The cipher context to use.
ashleymills 0:04990d454f45 242 * \param src The buffer to decrypt.
ashleymills 0:04990d454f45 243 * \param length The length of the input buffer.
ashleymills 0:04990d454f45 244 * \param buf The result buffer.
ashleymills 0:04990d454f45 245 * \param aad additional authentication data for AEAD ciphers
ashleymills 0:04990d454f45 246 * \param aad_length actual size of @p aad
ashleymills 0:04990d454f45 247 * \return Less than zero on error, the number of decrypted bytes
ashleymills 0:04990d454f45 248 * otherwise.
ashleymills 0:04990d454f45 249 */
ashleymills 0:04990d454f45 250 int dtls_decrypt(dtls_cipher_context_t *ctx,
ashleymills 0:04990d454f45 251 const unsigned char *src, size_t length,
ashleymills 0:04990d454f45 252 unsigned char *buf,
ashleymills 0:04990d454f45 253 const unsigned char *a_data, size_t a_data_length);
ashleymills 0:04990d454f45 254
ashleymills 0:04990d454f45 255 /* helper functions */
ashleymills 0:04990d454f45 256
ashleymills 0:04990d454f45 257 /**
ashleymills 0:04990d454f45 258 * Generates pre_master_sercet from given PSK and fills the result
ashleymills 0:04990d454f45 259 * according to the "plain PSK" case in section 2 of RFC 4279.
ashleymills 0:04990d454f45 260 * Diffie-Hellman and RSA key exchange are currently not supported.
ashleymills 0:04990d454f45 261 *
ashleymills 0:04990d454f45 262 * @param key The shared key.
ashleymills 0:04990d454f45 263 * @param keylen Length of @p key in bytes.
ashleymills 0:04990d454f45 264 * @param result The derived pre master secret.
ashleymills 0:04990d454f45 265 * @return The actual length of @p result.
ashleymills 0:04990d454f45 266 */
ashleymills 0:04990d454f45 267 size_t dtls_pre_master_secret(unsigned char *key, size_t keylen,
ashleymills 0:04990d454f45 268 unsigned char *result);
ashleymills 0:04990d454f45 269
ashleymills 0:04990d454f45 270 /**
ashleymills 0:04990d454f45 271 * Creates a new dtls_cipher_context_t object for given @c cipher.
ashleymills 0:04990d454f45 272 * The storage allocated for this object must be released using
ashleymills 0:04990d454f45 273 * dtls_cipher_free().
ashleymills 0:04990d454f45 274 *
ashleymills 0:04990d454f45 275 * @param code Code of the requested cipher (host byte order)
ashleymills 0:04990d454f45 276 * @param key The encryption and decryption key.
ashleymills 0:04990d454f45 277 * @param keylen Actual length of @p key.
ashleymills 0:04990d454f45 278 * @return A new dtls_cipher_context_t object or @c NULL in case
ashleymills 0:04990d454f45 279 * something went wrong (e.g. insufficient memory or wrong
ashleymills 0:04990d454f45 280 * key length)
ashleymills 0:04990d454f45 281 */
ashleymills 0:04990d454f45 282 dtls_cipher_context_t *dtls_cipher_new(dtls_cipher_t code,
ashleymills 0:04990d454f45 283 unsigned char *key, size_t keylen);
ashleymills 0:04990d454f45 284
ashleymills 0:04990d454f45 285 /**
ashleymills 0:04990d454f45 286 * Releases the storage allocated by dtls_cipher_new() for @p cipher_context
ashleymills 0:04990d454f45 287 */
ashleymills 0:04990d454f45 288 void dtls_cipher_free(dtls_cipher_context_t *cipher_context);
ashleymills 0:04990d454f45 289
ashleymills 0:04990d454f45 290
ashleymills 0:04990d454f45 291 /**
ashleymills 0:04990d454f45 292 * Initializes the given cipher context @p ctx with the initialization
ashleymills 0:04990d454f45 293 * vector @p iv of length @p length. */
ashleymills 0:04990d454f45 294 void dtls_cipher_set_iv(dtls_cipher_context_t *ctx,
ashleymills 0:04990d454f45 295 unsigned char *iv, size_t length);
ashleymills 0:04990d454f45 296
ashleymills 0:04990d454f45 297 #endif /* _CRYPTO_H_ */
ashleymills 0:04990d454f45 298