Version 0.5.0 of tinydtls
Dependents: tinydtls_test_cellular tinydtls_test_ethernet tiny-dtls
global.h@0:ff9ebe0cf0e9, 2013-10-18 (annotated)
- Committer:
- ashleymills
- Date:
- Fri Oct 18 13:18:30 2013 +0000
- Revision:
- 0:ff9ebe0cf0e9
Upgraded to tinydtls 0.5.0
Who changed what in which revision?
User | Revision | Line number | New 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_ */ |