mbed port of tinydtls

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers crypto.h Source File

crypto.h

00001 /* dtls -- a very basic DTLS implementation
00002  *
00003  * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
00004  *
00005  * Permission is hereby granted, free of charge, to any person
00006  * obtaining a copy of this software and associated documentation
00007  * files (the "Software"), to deal in the Software without
00008  * restriction, including without limitation the rights to use, copy,
00009  * modify, merge, publish, distribute, sublicense, and/or sell copies
00010  * of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be
00014  * included in all copies or substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00017  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00019  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00020  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00021  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00023  * SOFTWARE.
00024  */
00025 
00026 #ifndef _CRYPTO_H_
00027 #define _CRYPTO_H_
00028 
00029 #include "config.h"
00030 
00031 #include <stdlib.h>     /* for rand() and srand() */
00032 
00033 #include "aes/rijndael.h"
00034 
00035 #include "prng.h"
00036 #include "global.h"
00037 #include "numeric.h"
00038 #include "hmac.h"
00039 #include "ccm.h"
00040 
00041 /* TLS_PSK_WITH_AES_128_CCM_8 */
00042 #define DTLS_MAC_KEY_LENGTH    0
00043 #define DTLS_KEY_LENGTH        16 /* AES-128 */
00044 #define DTLS_BLK_LENGTH        16 /* AES-128 */
00045 #define DTLS_MAC_LENGTH        DTLS_HMAC_DIGEST_SIZE
00046 #define DTLS_IV_LENGTH         4  /* length of nonce_explicit */
00047 
00048 /** 
00049  * Maximum size of the generated keyblock. Note that MAX_KEYBLOCK_LENGTH must 
00050  * be large enough to hold the pre_master_secret, i.e. twice the length of the 
00051  * pre-shared key + 1.
00052  */
00053 #define MAX_KEYBLOCK_LENGTH  \
00054   (2 * DTLS_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH + 2 * DTLS_IV_LENGTH)
00055 
00056 /** Length of DTLS master_secret */
00057 #define DTLS_MASTER_SECRET_LENGTH 48
00058 
00059 #ifndef DTLS_CIPHER_CONTEXT_MAX
00060 #define DTLS_CIPHER_CONTEXT_MAX 4
00061 #endif
00062 
00063 typedef enum { AES128=0 
00064 } dtls_crypto_alg;
00065 
00066 /** Crypto context for TLS_PSK_WITH_AES_128_CCM_8 cipher suite. */
00067 typedef struct {
00068   rijndael_ctx ctx;            /**< AES-128 encryption context */
00069   unsigned char N[DTLS_CCM_BLOCKSIZE]; /**< nonce */
00070 } aes128_ccm_t;
00071 
00072 typedef struct dtls_cipher_context_t {
00073   /** numeric identifier of this cipher suite in host byte order. */
00074   dtls_cipher_t code;
00075   aes128_ccm_t data;        /**< The crypto context */
00076 } dtls_cipher_context_t;
00077 
00078 typedef enum { DTLS_CLIENT=0, DTLS_SERVER } dtls_peer_type;
00079 
00080 typedef struct {
00081   uint8  client_random[32]; /**< client random gmt and bytes */
00082 
00083   dtls_peer_type role; /**< denotes if the remote peer is DTLS_CLIENT or DTLS_SERVER */
00084   unsigned char compression;        /**< compression method */
00085 
00086   dtls_cipher_t cipher;     /**< cipher type */
00087 
00088   /** the session's master secret */
00089   uint8 master_secret[DTLS_MASTER_SECRET_LENGTH];
00090 
00091   /** 
00092    * The key block generated from PRF applied to client and server
00093    * random bytes. The actual size is given by the selected cipher and
00094    * can be calculated using dtls_kb_size(). Use \c dtls_kb_ macros to
00095    * access the components of the key block.
00096    */
00097   uint8 key_block[MAX_KEYBLOCK_LENGTH];
00098 
00099   dtls_cipher_context_t *read_cipher;  /**< decryption context */
00100   dtls_cipher_context_t *write_cipher; /**< encryption context */
00101 } dtls_security_parameters_t;
00102 
00103 /* The following macros provide access to the components of the
00104  * key_block in the security parameters. */
00105 
00106 #define dtls_kb_client_mac_secret(Param) ((Param)->key_block)
00107 #define dtls_kb_server_mac_secret(Param)                \
00108   (dtls_kb_client_mac_secret(Param) + DTLS_MAC_KEY_LENGTH)
00109 #define dtls_kb_remote_mac_secret(Param)                \
00110   ((Param)->role == DTLS_CLIENT                     \
00111    ? dtls_kb_client_mac_secret(Param)                   \
00112    : dtls_kb_server_mac_secret(Param))
00113 #define dtls_kb_local_mac_secret(Param)                 \
00114   ((Param)->role == DTLS_SERVER                     \
00115    ? dtls_kb_client_mac_secret(Param)                   \
00116    : dtls_kb_server_mac_secret(Param))
00117 #define dtls_kb_mac_secret_size(Param) DTLS_MAC_KEY_LENGTH
00118 #define dtls_kb_client_write_key(Param)                 \
00119   (dtls_kb_server_mac_secret(Param) + DTLS_MAC_KEY_LENGTH)
00120 #define dtls_kb_server_write_key(Param)                 \
00121   (dtls_kb_client_write_key(Param) + DTLS_KEY_LENGTH)
00122 #define dtls_kb_remote_write_key(Param)             \
00123   ((Param)->role == DTLS_CLIENT                 \
00124    ? dtls_kb_client_write_key(Param)                \
00125    : dtls_kb_server_write_key(Param))
00126 #define dtls_kb_local_write_key(Param)              \
00127   ((Param)->role == DTLS_SERVER                 \
00128    ? dtls_kb_client_write_key(Param)                \
00129    : dtls_kb_server_write_key(Param))
00130 #define dtls_kb_key_size(Param) DTLS_KEY_LENGTH
00131 #define dtls_kb_client_iv(Param)                    \
00132   (dtls_kb_server_write_key(Param) + DTLS_KEY_LENGTH)
00133 #define dtls_kb_server_iv(Param)                    \
00134   (dtls_kb_client_iv(Param) + DTLS_IV_LENGTH)
00135 #define dtls_kb_remote_iv(Param)                \
00136   ((Param)->role == DTLS_CLIENT                 \
00137    ? dtls_kb_client_iv(Param)                   \
00138    : dtls_kb_server_iv(Param))
00139 #define dtls_kb_local_iv(Param)                 \
00140   ((Param)->role == DTLS_SERVER                 \
00141    ? dtls_kb_client_iv(Param)                   \
00142    : dtls_kb_server_iv(Param))
00143 #define dtls_kb_iv_size(Param) DTLS_IV_LENGTH
00144 
00145 #define dtls_kb_size(Param)                 \
00146   (2 * (dtls_kb_mac_secret_size(Param) +            \
00147     dtls_kb_key_size(Param) + dtls_kb_iv_size(Param)))
00148 
00149 /* just for consistency */
00150 #define dtls_kb_digest_size(Param) DTLS_MAC_LENGTH
00151 
00152 /** 
00153  * Expands the secret and key to a block of DTLS_HMAC_MAX 
00154  * size according to the algorithm specified in section 5 of
00155  * RFC 4346.
00156  *
00157  * \param h       Identifier of the hash function to use.
00158  * \param key     The secret.
00159  * \param keylen  Length of \p key.
00160  * \param seed    The seed. 
00161  * \param seedlen Length of \p seed.
00162  * \param buf     Output buffer where the result is XORed into
00163  *                The buffe must be capable to hold at least
00164  *                \p buflen bytes.
00165  * \return The actual number of bytes written to \p buf or 0
00166  * on error.
00167  */
00168 size_t dtls_p_hash(dtls_hashfunc_t h, 
00169            const unsigned char *key, size_t keylen,
00170            const unsigned char *label, size_t labellen,
00171            const unsigned char *random1, size_t random1len,
00172            const unsigned char *random2, size_t random2len,
00173            unsigned char *buf, size_t buflen);
00174 
00175 /**
00176  * This function implements the TLS PRF for DTLS_VERSION. For version
00177  * 1.0, the PRF is P_MD5 ^ P_SHA1 while version 1.2 uses
00178  * P_SHA256. Currently, the actual PRF is selected at compile time.
00179  */
00180 size_t dtls_prf(const unsigned char *key, size_t keylen,
00181         const unsigned char *label, size_t labellen,
00182         const unsigned char *random1, size_t random1len,
00183         const unsigned char *random2, size_t random2len,
00184         unsigned char *buf, size_t buflen);
00185 
00186 /**
00187  * Calculates MAC for record + cleartext packet and places the result
00188  * in \p buf. The given \p hmac_ctx must be initialized with the HMAC
00189  * function to use and the proper secret. As the DTLS mac calculation
00190  * requires data from the record header, \p record must point to a
00191  * buffer of at least \c sizeof(dtls_record_header_t) bytes. Usually,
00192  * the remaining packet will be encrypted, therefore, the cleartext
00193  * is passed separately in \p packet.
00194  * 
00195  * \param hmac_ctx  The HMAC context to use for MAC calculation.
00196  * \param record    The record header.
00197  * \param packet    Cleartext payload to apply the MAC to.
00198  * \param length    Size of \p packet.
00199  * \param buf       A result buffer that is large enough to hold
00200  *                  the generated digest.
00201  */
00202 void dtls_mac(dtls_hmac_context_t *hmac_ctx, 
00203           const unsigned char *record,
00204           const unsigned char *packet, size_t length,
00205           unsigned char *buf);
00206 
00207 /** 
00208  * Encrypts the specified \p src of given \p length, writing the
00209  * result to \p buf. The cipher implementation may add more data to
00210  * the result buffer such as an initialization vector or padding
00211  * (e.g. for block cipers in CBC mode). The caller therefore must
00212  * ensure that \p buf provides sufficient storage to hold the result.
00213  * Usually this means ( 2 + \p length / blocksize ) * blocksize.  The
00214  * function returns a value less than zero on error or otherwise the
00215  * number of bytes written.
00216  *
00217  * \param ctx    The cipher context to use.
00218  * \param src    The data to encrypt.
00219  * \param length The actual size of of \p src.
00220  * \param buf    The result buffer. \p src and \p buf must not 
00221  *               overlap.
00222  * \param aad    additional data for AEAD ciphers
00223  * \param aad_length actual size of @p aad
00224  * \return The number of encrypted bytes on success, less than zero
00225  *         otherwise. 
00226  */
00227 int dtls_encrypt(dtls_cipher_context_t *ctx, 
00228          const unsigned char *src, size_t length,
00229          unsigned char *buf,
00230          const unsigned char *aad, size_t aad_length);
00231 
00232 /** 
00233  * Decrypts the given buffer \p src of given \p length, writing the
00234  * result to \p buf. The function returns \c -1 in case of an error,
00235  * or the number of bytes written. Note that for block ciphers, \p
00236  * length must be a multiple of the cipher's block size. A return
00237  * value between \c 0 and the actual length indicates that only \c n-1
00238  * block have been processed. Unlike dtls_encrypt(), the source
00239  * and destination of dtls_decrypt() may overlap. 
00240  * 
00241  * \param ctx     The cipher context to use.
00242  * \param src     The buffer to decrypt.
00243  * \param length  The length of the input buffer. 
00244  * \param buf     The result buffer.
00245  * \param aad     additional authentication data for AEAD ciphers
00246  * \param aad_length actual size of @p aad
00247  * \return Less than zero on error, the number of decrypted bytes 
00248  *         otherwise.
00249  */
00250 int dtls_decrypt(dtls_cipher_context_t *ctx, 
00251          const unsigned char *src, size_t length,
00252          unsigned char *buf,
00253          const unsigned char *a_data, size_t a_data_length);
00254 
00255 /* helper functions */
00256 
00257 /** 
00258  * Generates pre_master_sercet from given PSK and fills the result
00259  * according to the "plain PSK" case in section 2 of RFC 4279.
00260  * Diffie-Hellman and RSA key exchange are currently not supported.
00261  *
00262  * @param key    The shared key.
00263  * @param keylen Length of @p key in bytes.
00264  * @param result The derived pre master secret.
00265  * @return The actual length of @p result.
00266  */
00267 size_t dtls_pre_master_secret(unsigned char *key, size_t keylen,
00268                   unsigned char *result);
00269 
00270 /**
00271  * Creates a new dtls_cipher_context_t object for given @c cipher.
00272  * The storage allocated for this object must be released using 
00273  * dtls_cipher_free().
00274  *
00275  * @param code  Code of the requested cipher (host byte order)
00276  * @param key     The encryption and decryption key.
00277  * @param keylen  Actual length of @p key.
00278  * @return A new dtls_cipher_context_t object or @c NULL in case
00279  *         something went wrong (e.g. insufficient memory or wrong
00280  *         key length)
00281  */
00282 dtls_cipher_context_t *dtls_cipher_new(dtls_cipher_t code,
00283                        unsigned char *key, size_t keylen);
00284 
00285 /** 
00286  * Releases the storage allocated by dtls_cipher_new() for @p cipher_context 
00287  */
00288 void dtls_cipher_free(dtls_cipher_context_t *cipher_context);
00289 
00290 
00291 /** 
00292  * Initializes the given cipher context @p ctx with the initialization
00293  * vector @p iv of length @p length. */
00294 void dtls_cipher_set_iv(dtls_cipher_context_t *ctx,
00295             unsigned char *iv, size_t length);
00296 
00297 #endif /* _CRYPTO_H_ */
00298