Version 0.5.0 of tinydtls

Dependents:   tinydtls_test_cellular tinydtls_test_ethernet tiny-dtls

Committer:
ashleymills
Date:
Wed Feb 12 09:30:16 2014 +0000
Revision:
1:598a56fe116e
Parent:
0:ff9ebe0cf0e9
Explicitly removed something instead of relying on MACRO to disable it. Mbed can't use it.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:ff9ebe0cf0e9 1 /* dtls -- a very basic DTLS implementation
ashleymills 0:ff9ebe0cf0e9 2 *
ashleymills 0:ff9ebe0cf0e9 3 * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
ashleymills 0:ff9ebe0cf0e9 4 *
ashleymills 0:ff9ebe0cf0e9 5 * Permission is hereby granted, free of charge, to any person
ashleymills 0:ff9ebe0cf0e9 6 * obtaining a copy of this software and associated documentation
ashleymills 0:ff9ebe0cf0e9 7 * files (the "Software"), to deal in the Software without
ashleymills 0:ff9ebe0cf0e9 8 * restriction, including without limitation the rights to use, copy,
ashleymills 0:ff9ebe0cf0e9 9 * modify, merge, publish, distribute, sublicense, and/or sell copies
ashleymills 0:ff9ebe0cf0e9 10 * of the Software, and to permit persons to whom the Software is
ashleymills 0:ff9ebe0cf0e9 11 * furnished to do so, subject to the following conditions:
ashleymills 0:ff9ebe0cf0e9 12 *
ashleymills 0:ff9ebe0cf0e9 13 * The above copyright notice and this permission notice shall be
ashleymills 0:ff9ebe0cf0e9 14 * included in all copies or substantial portions of the Software.
ashleymills 0:ff9ebe0cf0e9 15 *
ashleymills 0:ff9ebe0cf0e9 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
ashleymills 0:ff9ebe0cf0e9 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
ashleymills 0:ff9ebe0cf0e9 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ashleymills 0:ff9ebe0cf0e9 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
ashleymills 0:ff9ebe0cf0e9 20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ashleymills 0:ff9ebe0cf0e9 21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
ashleymills 0:ff9ebe0cf0e9 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
ashleymills 0:ff9ebe0cf0e9 23 * SOFTWARE.
ashleymills 0:ff9ebe0cf0e9 24 */
ashleymills 0:ff9ebe0cf0e9 25
ashleymills 0:ff9ebe0cf0e9 26 #ifndef _GLOBAL_H_
ashleymills 0:ff9ebe0cf0e9 27 #define _GLOBAL_H_
ashleymills 0:ff9ebe0cf0e9 28
ashleymills 0:ff9ebe0cf0e9 29 #include "config.h"
ashleymills 0:ff9ebe0cf0e9 30
ashleymills 0:ff9ebe0cf0e9 31 #ifdef HAVE_ASSERT_H
ashleymills 0:ff9ebe0cf0e9 32 #include <assert.h>
ashleymills 0:ff9ebe0cf0e9 33 #else
ashleymills 0:ff9ebe0cf0e9 34 #ifndef assert
ashleymills 0:ff9ebe0cf0e9 35 #warning "assertions are disabled"
ashleymills 0:ff9ebe0cf0e9 36 # define assert(x)
ashleymills 0:ff9ebe0cf0e9 37 #endif
ashleymills 0:ff9ebe0cf0e9 38 #endif
ashleymills 0:ff9ebe0cf0e9 39
ashleymills 0:ff9ebe0cf0e9 40 #include <string.h>
ashleymills 0:ff9ebe0cf0e9 41
ashleymills 0:ff9ebe0cf0e9 42 #ifdef HAVE_SYS_TYPES_H
ashleymills 0:ff9ebe0cf0e9 43 #include <sys/types.h>
ashleymills 0:ff9ebe0cf0e9 44 #endif
ashleymills 0:ff9ebe0cf0e9 45
ashleymills 0:ff9ebe0cf0e9 46 #ifndef MBED
ashleymills 0:ff9ebe0cf0e9 47
ashleymills 0:ff9ebe0cf0e9 48 #ifdef HAVE_SYS_SOCKET_H
ashleymills 0:ff9ebe0cf0e9 49 #include <sys/socket.h>
ashleymills 0:ff9ebe0cf0e9 50 #endif
ashleymills 0:ff9ebe0cf0e9 51 #ifdef HAVE_NETINET_IN_H
ashleymills 0:ff9ebe0cf0e9 52 #include <netinet/in.h>
ashleymills 0:ff9ebe0cf0e9 53 #endif
ashleymills 0:ff9ebe0cf0e9 54 #ifdef HAVE_ARPA_INET_H
ashleymills 0:ff9ebe0cf0e9 55 #include <arpa/inet.h>
ashleymills 0:ff9ebe0cf0e9 56 #endif
ashleymills 0:ff9ebe0cf0e9 57
ashleymills 0:ff9ebe0cf0e9 58 #else
ashleymills 0:ff9ebe0cf0e9 59 #include "lwip/sockets.h"
ashleymills 0:ff9ebe0cf0e9 60 #include "lwip/netdb.h"
ashleymills 0:ff9ebe0cf0e9 61 #endif
ashleymills 0:ff9ebe0cf0e9 62
ashleymills 0:ff9ebe0cf0e9 63 #ifndef DTLSv12
ashleymills 0:ff9ebe0cf0e9 64 /* The current version of tinyDTLS supports DTLSv1.2 only. */
ashleymills 0:ff9ebe0cf0e9 65 #define DTLSv12 1
ashleymills 0:ff9ebe0cf0e9 66 #endif
ashleymills 0:ff9ebe0cf0e9 67
ashleymills 0:ff9ebe0cf0e9 68 #ifndef WITH_SHA256
ashleymills 0:ff9ebe0cf0e9 69 /* The current version of tinyDTLS supports DTLSv1.2 with SHA256 PRF
ashleymills 0:ff9ebe0cf0e9 70 only. */
ashleymills 0:ff9ebe0cf0e9 71 #define WITH_SHA256 1
ashleymills 0:ff9ebe0cf0e9 72 #endif
ashleymills 0:ff9ebe0cf0e9 73
ashleymills 0:ff9ebe0cf0e9 74 #ifndef WITH_CONTIKI
ashleymills 0:ff9ebe0cf0e9 75 typedef unsigned int clock_time_t;
ashleymills 0:ff9ebe0cf0e9 76 #else /* WITH_CONTIKI */
ashleymills 0:ff9ebe0cf0e9 77 #include "uip.h"
ashleymills 0:ff9ebe0cf0e9 78 typedef struct {
ashleymills 0:ff9ebe0cf0e9 79 unsigned char size;
ashleymills 0:ff9ebe0cf0e9 80 uip_ipaddr_t addr;
ashleymills 0:ff9ebe0cf0e9 81 unsigned short port;
ashleymills 0:ff9ebe0cf0e9 82 int ifindex;
ashleymills 0:ff9ebe0cf0e9 83 } __uip_session_t;
ashleymills 0:ff9ebe0cf0e9 84 #define session_t __uip_session_t
ashleymills 0:ff9ebe0cf0e9 85
ashleymills 0:ff9ebe0cf0e9 86 #define _dtls_address_equals_impl(A,B) \
ashleymills 0:ff9ebe0cf0e9 87 ((A)->size == (B)->size \
ashleymills 0:ff9ebe0cf0e9 88 && (A)->port == (B)->port \
ashleymills 0:ff9ebe0cf0e9 89 && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)) \
ashleymills 0:ff9ebe0cf0e9 90 && (A)->ifindex == (B)->ifindex)
ashleymills 0:ff9ebe0cf0e9 91
ashleymills 0:ff9ebe0cf0e9 92 #endif /* WITH_CONTIKI */
ashleymills 0:ff9ebe0cf0e9 93
ashleymills 0:ff9ebe0cf0e9 94 /** multi-purpose address abstraction */
ashleymills 0:ff9ebe0cf0e9 95 #ifndef session_t
ashleymills 0:ff9ebe0cf0e9 96 typedef struct __session_t {
ashleymills 0:ff9ebe0cf0e9 97 socklen_t size; /**< size of addr */
ashleymills 0:ff9ebe0cf0e9 98 union {
ashleymills 0:ff9ebe0cf0e9 99 struct sockaddr sa;
ashleymills 0:ff9ebe0cf0e9 100 //struct sockaddr_storage st;
ashleymills 0:ff9ebe0cf0e9 101 struct sockaddr_in sin;
ashleymills 0:ff9ebe0cf0e9 102 //struct sockaddr_in6 sin6;
ashleymills 0:ff9ebe0cf0e9 103 } addr;
ashleymills 0:ff9ebe0cf0e9 104 uint8_t ifindex;
ashleymills 0:ff9ebe0cf0e9 105 } __session_t;
ashleymills 0:ff9ebe0cf0e9 106
ashleymills 0:ff9ebe0cf0e9 107 #define session_t __session_t
ashleymills 0:ff9ebe0cf0e9 108
ashleymills 0:ff9ebe0cf0e9 109 static inline int
ashleymills 0:ff9ebe0cf0e9 110 _dtls_address_equals_impl(const session_t *a,
ashleymills 0:ff9ebe0cf0e9 111 const session_t *b) {
ashleymills 0:ff9ebe0cf0e9 112 if (a->ifindex != b->ifindex ||
ashleymills 0:ff9ebe0cf0e9 113 a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
ashleymills 0:ff9ebe0cf0e9 114 return 0;
ashleymills 0:ff9ebe0cf0e9 115
ashleymills 0:ff9ebe0cf0e9 116 /* need to compare only relevant parts of sockaddr_in6 */
ashleymills 0:ff9ebe0cf0e9 117 switch (a->addr.sa.sa_family) {
ashleymills 0:ff9ebe0cf0e9 118 case AF_INET:
ashleymills 0:ff9ebe0cf0e9 119 return
ashleymills 0:ff9ebe0cf0e9 120 a->addr.sin.sin_port == b->addr.sin.sin_port &&
ashleymills 0:ff9ebe0cf0e9 121 memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr,
ashleymills 0:ff9ebe0cf0e9 122 sizeof(struct in_addr)) == 0;
ashleymills 0:ff9ebe0cf0e9 123 /*
ashleymills 0:ff9ebe0cf0e9 124 case AF_INET6:
ashleymills 0:ff9ebe0cf0e9 125 return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port &&
ashleymills 0:ff9ebe0cf0e9 126 memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr,
ashleymills 0:ff9ebe0cf0e9 127 sizeof(struct in6_addr)) == 0;
ashleymills 0:ff9ebe0cf0e9 128 */
ashleymills 0:ff9ebe0cf0e9 129 default: /* fall through and signal error */
ashleymills 0:ff9ebe0cf0e9 130 ;
ashleymills 0:ff9ebe0cf0e9 131 }
ashleymills 0:ff9ebe0cf0e9 132 return 0;
ashleymills 0:ff9ebe0cf0e9 133 }
ashleymills 0:ff9ebe0cf0e9 134 #endif /* session_t */
ashleymills 0:ff9ebe0cf0e9 135
ashleymills 0:ff9ebe0cf0e9 136 /* Define our own types as at least uint32_t does not work on my amd64. */
ashleymills 0:ff9ebe0cf0e9 137
ashleymills 0:ff9ebe0cf0e9 138 typedef unsigned char uint8;
ashleymills 0:ff9ebe0cf0e9 139 typedef unsigned char uint16[2];
ashleymills 0:ff9ebe0cf0e9 140 typedef unsigned char uint24[3];
ashleymills 0:ff9ebe0cf0e9 141 typedef unsigned char uint32[4];
ashleymills 0:ff9ebe0cf0e9 142 typedef unsigned char uint48[6];
ashleymills 0:ff9ebe0cf0e9 143
ashleymills 0:ff9ebe0cf0e9 144 #ifndef HAVE_STR
ashleymills 0:ff9ebe0cf0e9 145 typedef struct {
ashleymills 0:ff9ebe0cf0e9 146 size_t length; /* length of string */
ashleymills 0:ff9ebe0cf0e9 147 unsigned char *s; /* string data */
ashleymills 0:ff9ebe0cf0e9 148 } str;
ashleymills 0:ff9ebe0cf0e9 149 #endif
ashleymills 0:ff9ebe0cf0e9 150
ashleymills 0:ff9ebe0cf0e9 151 #ifndef DTLS_MAX_BUF
ashleymills 0:ff9ebe0cf0e9 152 /** Maximum size of DTLS message. */
ashleymills 0:ff9ebe0cf0e9 153 #define DTLS_MAX_BUF 256 + 64
ashleymills 0:ff9ebe0cf0e9 154 #endif
ashleymills 0:ff9ebe0cf0e9 155
ashleymills 0:ff9ebe0cf0e9 156 #ifndef DTLS_DEFAULT_MAX_RETRANSMIT
ashleymills 0:ff9ebe0cf0e9 157 /** Number of message retransmissions. */
ashleymills 0:ff9ebe0cf0e9 158 #define DTLS_DEFAULT_MAX_RETRANSMIT 5
ashleymills 0:ff9ebe0cf0e9 159 #endif
ashleymills 0:ff9ebe0cf0e9 160
ashleymills 0:ff9ebe0cf0e9 161 /** Known cipher suites.*/
ashleymills 0:ff9ebe0cf0e9 162 typedef enum {
ashleymills 0:ff9ebe0cf0e9 163 TLS_NULL_WITH_NULL_NULL = 0x0000, /**< NULL cipher */
ashleymills 0:ff9ebe0cf0e9 164 TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */
ashleymills 0:ff9ebe0cf0e9 165 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AC /**< TODO: replace with values from draft-mcgrew-tls-aes-ccm-ecc */
ashleymills 0:ff9ebe0cf0e9 166 } dtls_cipher_t;
ashleymills 0:ff9ebe0cf0e9 167
ashleymills 0:ff9ebe0cf0e9 168 /** Known compression suites.*/
ashleymills 0:ff9ebe0cf0e9 169 typedef enum {
ashleymills 0:ff9ebe0cf0e9 170 TLS_COMPRESSION_NULL = 0x0000 /* NULL compression */
ashleymills 0:ff9ebe0cf0e9 171 } dtls_compression_t;
ashleymills 0:ff9ebe0cf0e9 172
ashleymills 0:ff9ebe0cf0e9 173 #define TLS_EXT_ELLIPTIC_CURVES 10 /* see RFC 4492 */
ashleymills 0:ff9ebe0cf0e9 174 #define TLS_EXT_EC_POINT_FORMATS 11 /* see RFC 4492 */
ashleymills 0:ff9ebe0cf0e9 175 #define TLS_EXT_SIG_HASH_ALGO 13 /* see RFC 5246 */
ashleymills 0:ff9ebe0cf0e9 176 #define TLS_EXT_CLIENT_CERIFICATE_TYPE 122 /* TODO: replcae with values from draft-ietf-tls-oob-pubkey */
ashleymills 0:ff9ebe0cf0e9 177 #define TLS_EXT_SERVER_CERIFICATE_TYPE 123 /* TODO: replcae with values from draft-ietf-tls-oob-pubkey */
ashleymills 0:ff9ebe0cf0e9 178
ashleymills 0:ff9ebe0cf0e9 179 #define TLS_CERT_TYPE_OOB 2 /* replcae with values from draft-ietf-tls-oob-pubkey */
ashleymills 0:ff9ebe0cf0e9 180
ashleymills 0:ff9ebe0cf0e9 181 #define TLS_EXT_ELLIPTIC_CURVES_SECP256R1 23 /* see RFC 4492 */
ashleymills 0:ff9ebe0cf0e9 182
ashleymills 0:ff9ebe0cf0e9 183 #define TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED 0 /* see RFC 4492 */
ashleymills 0:ff9ebe0cf0e9 184
ashleymills 0:ff9ebe0cf0e9 185 #define TLS_EXT_SIG_HASH_ALGO_SHA256 4 /* see RFC 5246 */
ashleymills 0:ff9ebe0cf0e9 186 #define TLS_EXT_SIG_HASH_ALGO_ECDSA 3 /* see RFC 5246 */
ashleymills 0:ff9ebe0cf0e9 187
ashleymills 0:ff9ebe0cf0e9 188 /**
ashleymills 0:ff9ebe0cf0e9 189 * XORs \p n bytes byte-by-byte starting at \p y to the memory area
ashleymills 0:ff9ebe0cf0e9 190 * starting at \p x. */
ashleymills 0:ff9ebe0cf0e9 191 static inline void
ashleymills 0:ff9ebe0cf0e9 192 memxor(unsigned char *x, const unsigned char *y, size_t n) {
ashleymills 0:ff9ebe0cf0e9 193 while(n--) {
ashleymills 0:ff9ebe0cf0e9 194 *x ^= *y;
ashleymills 0:ff9ebe0cf0e9 195 x++; y++;
ashleymills 0:ff9ebe0cf0e9 196 }
ashleymills 0:ff9ebe0cf0e9 197 }
ashleymills 0:ff9ebe0cf0e9 198
ashleymills 0:ff9ebe0cf0e9 199 #ifdef HAVE_FLS
ashleymills 0:ff9ebe0cf0e9 200 #define dtls_fls(i) fls(i)
ashleymills 0:ff9ebe0cf0e9 201 #else
ashleymills 0:ff9ebe0cf0e9 202 static inline int
ashleymills 0:ff9ebe0cf0e9 203 dtls_fls(unsigned int i) {
ashleymills 0:ff9ebe0cf0e9 204 int n;
ashleymills 0:ff9ebe0cf0e9 205 for (n = 0; i; n++)
ashleymills 0:ff9ebe0cf0e9 206 i >>= 1;
ashleymills 0:ff9ebe0cf0e9 207 return n;
ashleymills 0:ff9ebe0cf0e9 208 }
ashleymills 0:ff9ebe0cf0e9 209 #endif /* HAVE_FLS */
ashleymills 0:ff9ebe0cf0e9 210
ashleymills 0:ff9ebe0cf0e9 211 /**
ashleymills 0:ff9ebe0cf0e9 212 * Resets the given session_t object @p sess to its default
ashleymills 0:ff9ebe0cf0e9 213 * values. In particular, the member rlen must be initialized to the
ashleymills 0:ff9ebe0cf0e9 214 * available size for storing addresses.
ashleymills 0:ff9ebe0cf0e9 215 *
ashleymills 0:ff9ebe0cf0e9 216 * @param sess The session_t object to initialize.
ashleymills 0:ff9ebe0cf0e9 217 */
ashleymills 0:ff9ebe0cf0e9 218 static inline void
ashleymills 0:ff9ebe0cf0e9 219 dtls_session_init(session_t *sess) {
ashleymills 0:ff9ebe0cf0e9 220 assert(sess);
ashleymills 0:ff9ebe0cf0e9 221 memset(sess, 0, sizeof(session_t));
ashleymills 0:ff9ebe0cf0e9 222 sess->size = sizeof(sess->addr);
ashleymills 0:ff9ebe0cf0e9 223 }
ashleymills 0:ff9ebe0cf0e9 224
ashleymills 0:ff9ebe0cf0e9 225 static inline int
ashleymills 0:ff9ebe0cf0e9 226 dtls_session_equals(const session_t *a, const session_t *b) {
ashleymills 0:ff9ebe0cf0e9 227 assert(a); assert(b);
ashleymills 0:ff9ebe0cf0e9 228 return _dtls_address_equals_impl(a, b);
ashleymills 0:ff9ebe0cf0e9 229 }
ashleymills 0:ff9ebe0cf0e9 230 #endif /* _GLOBAL_H_ */