mbed port of tinydtls
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Thu Jul 14 2022 20:00:56 by 1.7.2