10 #define TRANSPORT_HEADER_SIZE (14+20+8) /* Ethernet + IP + UDP */
12 /* the pre_master_secret is generated from the PSK at startup */
13 unsigned char pre_master_secret[60];
14 size_t pre_master_len = 0;
16 unsigned char master_secret[DTLS_MASTER_SECRET_LENGTH];
17 size_t master_secret_len = 0;
19 dtls_security_parameters_t security_params[2];
21 unsigned int epoch[2] = { 0, 0 };
23 #if DTLS_VERSION == 0xfeff
24 dtls_hash_t hs_hash[2];
25 #elif DTLS_VERSION == 0xfefd
26 dtls_hash_t hs_hash[1];
30 update_hash(uint8 *record, size_t rlength,
31 uint8 *data, size_t data_length) {
37 for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i) {
38 dtls_hash_update(hs_hash[i], data, data_length);
43 finalize_hash(uint8 *buf) {
44 #if DTLS_VERSION == 0xfeff
45 unsigned char statebuf[sizeof(md5_state_t) + sizeof(SHA_CTX)];
46 #elif DTLS_VERSION == 0xfefd
47 unsigned char statebuf[sizeof(dtls_sha256_ctx)];
53 /* temporarily store hash status for roll-back after finalize */
54 #if DTLS_VERSION == 0xfeff
55 memcpy(statebuf, hs_hash[0], sizeof(md5_state_t));
56 memcpy(statebuf + sizeof(md5_state_t),
59 #elif DTLS_VERSION == 0xfefd
60 memcpy(statebuf, hs_hash[0], sizeof(statebuf));
63 dtls_hash_finalize(buf, hs_hash[0]);
64 #if DTLS_VERSION == 0xfeff
65 dtls_hash_finalize(buf + 16, hs_hash[1]);
68 /* restore hash status */
69 #if DTLS_VERSION == 0xfeff
70 memcpy(hs_hash[0], statebuf, sizeof(md5_state_t));
72 statebuf + sizeof(md5_state_t),
74 #elif DTLS_VERSION == 0xfefd
75 memcpy(hs_hash[0], statebuf, sizeof(statebuf));
83 for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i)
85 memset(hs_hash, 0, sizeof(hs_hash));
91 #define CURRENT_CONFIG (&security_params[config])
92 #define OTHER_CONFIG (&security_params[!(config & 0x01)])
93 #define SWITCH_CONFIG (config = !(config & 0x01))
96 pcap_verify(dtls_security_parameters_t *sec,
98 const unsigned char *record, size_t record_length,
99 const unsigned char *cleartext, size_t cleartext_length) {
101 unsigned char mac[DTLS_HMAC_MAX];
102 dtls_hmac_context_t hmac_ctx;
105 if (cleartext_length < dtls_kb_digest_size(sec))
108 dtls_hmac_init(&hmac_ctx,
110 ? dtls_kb_client_mac_secret(sec)
111 : dtls_kb_server_mac_secret(sec),
112 dtls_kb_mac_secret_size(sec));
114 cleartext_length -= dtls_kb_digest_size(sec);
116 /* calculate MAC even if padding is wrong */
118 record, /* the pre-filled record header */
119 cleartext, cleartext_length,
122 ok = memcmp(mac, cleartext + cleartext_length,
123 dtls_kb_digest_size(sec)) == 0;
125 printf("MAC (%s): ", ok ? "valid" : "invalid");
126 dump(mac, dtls_kb_digest_size(sec));
133 decrypt_verify(int is_client, const uint8 *packet, size_t length,
134 uint8 **cleartext, size_t *clen) {
136 dtls_cipher_context_t *cipher;
138 static unsigned char buf[1000];
140 switch (CURRENT_CONFIG->cipher) {
141 case AES128: /* TLS_PSK_WITH_AES128_CBC_SHA */
143 *clen = length - sizeof(dtls_record_header_t);
146 cipher = CURRENT_CONFIG->read_cipher;
148 cipher = CURRENT_CONFIG->write_cipher;
150 res = dtls_decrypt(cipher,
151 (uint8 *)packet + sizeof(dtls_record_header_t), *clen,
155 warn("decryption failed!\n");
157 ok = pcap_verify(CURRENT_CONFIG, is_client, (uint8 *)packet, length,
161 *clen = res - dtls_kb_digest_size(CURRENT_CONFIG);
164 default: /* no cipher suite selected */
165 *cleartext = (uint8 *)packet + sizeof(dtls_record_header_t);
166 *clen = length - sizeof(dtls_record_header_t);
172 printf("verify OK\n");
174 printf("verification failed!\n");
178 #define SKIP_ETH_HEADER(M,L) \
186 #define SKIP_IP_HEADER(M,L) \
187 if (((M)[0] & 0xF0) == 0x40) { /* IPv4 */ \
188 (M) += (M[0] & 0x0F) * 4; \
189 (L) -= (M[0] & 0x0F) * 4; \
191 if (((M)[0] & 0xF0) == 0x60) { /* IPv6 */ \
196 #define SKIP_UDP_HEADER(M,L) { \
202 handle_packet(const u_char *packet, int length) {
204 static unsigned char initial_hello[] = {
205 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
208 size_t data_length, rlen;
210 #if DTLS_VERSION == 0xfeff
211 #ifndef SHA1_DIGEST_LENGTH
212 #define SHA1_DIGEST_LENGTH 20
214 uint8 hash_buf[16 + SHA1_DIGEST_LENGTH];
215 #elif DTLS_VERSION == 0xfefd
216 uint8 hash_buf[DTLS_SHA256_DIGEST_LENGTH];
218 #define verify_data_length 12
222 SKIP_ETH_HEADER(packet, length);
223 SKIP_IP_HEADER(packet, length);
225 /* determine from port if this is a client */
226 is_client = dtls_uint16_to_int(packet) != 20220;
228 SKIP_UDP_HEADER(packet, length);
231 rlen = dtls_uint16_to_int(packet + 11) + sizeof(dtls_record_header_t);
234 fprintf(stderr, "invalid length!\n");
238 /* skip packet if it is from a different epoch */
239 if (dtls_uint16_to_int(packet + 3) != epoch[is_client])
242 res = decrypt_verify(is_client, packet, rlen,
243 &data, &data_length);
248 printf("packet %d (from %s):\n", n, is_client ? "client" : "server");
249 hexdump(packet, sizeof(dtls_record_header_t));
251 hexdump(data, data_length);
254 if (packet[0] == 22 && data[0] == 1) { /* ClientHello */
255 if (memcmp(packet, initial_hello, sizeof(initial_hello)) == 0)
258 memcpy(dtls_kb_client_iv(OTHER_CONFIG), data + 14, 32);
261 #if DTLS_VERSION == 0xfeff
262 hs_hash[0] = dtls_new_hash(HASH_MD5);
263 hs_hash[1] = dtls_new_hash(HASH_SHA1);
265 hs_hash[0]->init(hs_hash[0]->data);
266 hs_hash[1]->init(hs_hash[1]->data);
267 #elif DTLS_VERSION == 0xfefd
268 dtls_hash_init(hs_hash[0]);
272 if (packet[0] == 22 && data[0] == 2) { /* ServerHello */
273 memcpy(dtls_kb_server_iv(OTHER_CONFIG), data + 14, 32);
274 /* FIXME: search in ciphers */
275 OTHER_CONFIG->cipher = TLS_PSK_WITH_AES_128_CCM_8;
278 if (packet[0] == 20 && data[0] == 1) { /* ChangeCipherSpec */
279 printf("client random: ");
280 dump(dtls_kb_client_iv(OTHER_CONFIG), 32);
281 printf("\nserver random: ");
282 dump(dtls_kb_server_iv(OTHER_CONFIG), 32);
285 dtls_prf(pre_master_secret, pre_master_len,
286 (unsigned char *)"master secret", 13,
287 dtls_kb_client_iv(OTHER_CONFIG), 32,
288 dtls_kb_server_iv(OTHER_CONFIG), 32,
289 master_secret, DTLS_MASTER_SECRET_LENGTH);
291 printf("master_secret:\n ");
292 for(i = 0; i < master_secret_len; i++)
293 printf("%02x", master_secret[i]);
296 /* create key_block from master_secret
297 * key_block = PRF(master_secret,
298 "key expansion" + server_random + client_random) */
299 dtls_prf(master_secret, master_secret_len,
300 (unsigned char *)"key expansion", 13,
301 dtls_kb_server_iv(OTHER_CONFIG), 32,
302 dtls_kb_client_iv(OTHER_CONFIG), 32,
303 OTHER_CONFIG->key_block,
304 dtls_kb_size(OTHER_CONFIG));
306 OTHER_CONFIG->read_cipher =
307 dtls_cipher_new(OTHER_CONFIG->cipher,
308 dtls_kb_client_write_key(OTHER_CONFIG),
309 dtls_kb_key_size(OTHER_CONFIG));
311 if (!OTHER_CONFIG->read_cipher) {
312 warn("cannot create read cipher\n");
314 dtls_cipher_set_iv(OTHER_CONFIG->read_cipher,
315 dtls_kb_client_iv(OTHER_CONFIG),
316 dtls_kb_iv_size(OTHER_CONFIG));
319 OTHER_CONFIG->write_cipher =
320 dtls_cipher_new(OTHER_CONFIG->cipher,
321 dtls_kb_server_write_key(OTHER_CONFIG),
322 dtls_kb_key_size(OTHER_CONFIG));
324 if (!OTHER_CONFIG->write_cipher) {
325 warn("cannot create write cipher\n");
327 dtls_cipher_set_iv(OTHER_CONFIG->write_cipher,
328 dtls_kb_server_iv(OTHER_CONFIG),
329 dtls_kb_iv_size(OTHER_CONFIG));
336 printf("key_block:\n");
337 printf(" client_MAC_secret:\t");
338 dump(dtls_kb_client_mac_secret(CURRENT_CONFIG),
339 dtls_kb_mac_secret_size(CURRENT_CONFIG));
342 printf(" server_MAC_secret:\t");
343 dump(dtls_kb_server_mac_secret(CURRENT_CONFIG),
344 dtls_kb_mac_secret_size(CURRENT_CONFIG));
347 printf(" client_write_key:\t");
348 dump(dtls_kb_client_write_key(CURRENT_CONFIG),
349 dtls_kb_key_size(CURRENT_CONFIG));
352 printf(" server_write_key:\t");
353 dump(dtls_kb_server_write_key(CURRENT_CONFIG),
354 dtls_kb_key_size(CURRENT_CONFIG));
357 printf(" client_IV:\t\t");
358 dump(dtls_kb_client_iv(CURRENT_CONFIG),
359 dtls_kb_iv_size(CURRENT_CONFIG));
362 printf(" server_IV:\t\t");
363 dump(dtls_kb_server_iv(CURRENT_CONFIG),
364 dtls_kb_iv_size(CURRENT_CONFIG));
369 if (packet[0] == 22) {
370 if (data[0] == 20) { /* Finished */
371 finalize_hash(hash_buf);
374 update_hash((unsigned char *)packet, sizeof(dtls_record_header_t),
377 dtls_prf(master_secret, master_secret_len,
379 ? (unsigned char *)"client finished"
380 : (unsigned char *)"server finished"
382 hash_buf, sizeof(hash_buf),
384 data + sizeof(dtls_handshake_header_t),
386 printf("verify_data:\n");
387 dump(data, data_length);
390 update_hash((unsigned char *)packet, sizeof(dtls_record_header_t),
395 if (packet[0] == 23) { /* Application Data */
396 printf("Application Data:\n");
397 dump(data, data_length);
408 memset(security_params, 0, sizeof(security_params));
409 CURRENT_CONFIG->cipher = -1;
411 memset(hs_hash, 0, sizeof(hs_hash));
413 /* set pre_master_secret to default if no PSK was given */
414 if (!pre_master_len) {
415 /* unsigned char psk[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; */
417 dtls_pre_master_secret((unsigned char *)"secretPSK", 9,
422 int main(int argc, char **argv) {
424 char errbuf[PCAP_ERRBUF_SIZE];
425 struct pcap_pkthdr *pkthdr;
426 const u_char *packet;
428 int c, option_index = 0;
430 static struct option opts[] = {
431 { "psk", 1, 0, 'p' },
435 /* handle command line options */
437 c = getopt_long(argc, argv, "p:", opts, &option_index);
443 pre_master_len = dtls_pre_master_secret((unsigned char *)optarg,
444 strlen(optarg), pre_master_secret);
449 if (argc <= optind) {
450 fprintf(stderr, "usage: %s [-p|--psk PSK] pcapfile\n", argv[0]);
456 pcap = pcap_open_offline(argv[optind], errbuf);
458 fprintf(stderr, "pcap_open_offline: %s\n", errbuf);
463 res = pcap_next_ex(pcap, &pkthdr, &packet);
467 case -1: pcap_perror(pcap, "read packet"); break;
468 case 1: handle_packet(packet, pkthdr->caplen); break;