Code Monkey home page Code Monkey logo

tinydtls's People

Contributors

benpicco avatar boaks avatar cladmi avatar ffontaine avatar fjmolinas avatar hendrikve avatar jimmybjorklund avatar jkrhb avatar leandrolanzieri avatar miri64 avatar mrdeep1 avatar nmeum avatar obgm avatar pokgak avatar pulsastrix avatar rfuentess avatar sbernard31 avatar sebastianschueller avatar smlng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinydtls's Issues

complie error

when i make it in the tests, the error happen:/usr/bin/ld: cannot find -ltinydtls, my os is ubuntu 20.04
how can i solve it
thanks

using libcoap with tinydtls - make uninstall fails

sudo make uninstall
Making uninstall in ext/tinydtls
make[1]: Verzeichnis „..../libcoap/ext/tinydtls“ wird betreten
make[1]: *** Keine Regel, um „uninstall“ zu erstellen. Schluss.
make[1]: Verzeichnis „..../libcoap/ext/tinydtls“ wird verlassen
Makefile:1070: recipe for target 'uninstall-recursive' failed
make: *** [uninstall-recursive] Error 1

Seems, that tinydtls provides "install", but has no target to "uninstall".

commit 7f8c86e in the tinydtls repository.

Message Sequence Non-conformance bug

Description

  • Type: Non-conformance Bug
  • Priority: Minor

Non-conformance Bug

Version: development branch

Expected behavior
The DTLS RFC specifies the following requirement regarding the message sequence number:

The first message each side transmits in each handshake always has message_seq = 0. Whenever each new message is generated, the message_seq value is incremented by one.

Actual behavior
One can complete a handshake with the following values for the message sequence:

CH0.sequence_number = 255
CH2.sequence_number = 191
CKE.sequence_number = 192
Finished.sequence_number = 193

The problem also exists when the server sends records with non-compliant sequence numbers.

I have attached the handshake trace for the mentioned non-conformance. You clearly see that the handshake proceeds while the message_sequence is invalid.
capture.zip

DTLS server application crashes on receiving unexpected ChangeCipherSpec

We generated models for eclipse's TinyDTLS server application (dtls-server) using state fuzzing. On analyzing the models, one of the glaring problems we could identify was that the application can crash on receiving an unexpected ChangeCipherSpec. By unexpected, I mean that it is received at the wrong point in the handshake.

For example, it crashes if it receives ChangeCipherSpec (CCS) while listening, or any time before the ClientHello - ServerHello exchange. It does not crash afterwards. While you wouldn't expect to receive such messages from conforming DTLS clients, I think the behavior is still problematic, as it allows any adversary to crash the server application.

Attached at the end of this message is a .zip archive containing a raw CCS and a pcap version of it which can be viewed in Wireshark.

Just start the server:
./tests/dtls-server -p 20000

Then send the raw CCS packet via bash:
cat < ccs > /dev/udp/127.0.0.1/20000

The server should crash.

ccs.zip

Pre-configured server public key

Hi,
I'm working with embedded devices and CoAP (libCoap) with RPK. Using your library I made a working prototype.
Now I'm working on an optimization: I would like to configure public server key on device memory so It hasn't to be exchange on every handshake. Is it possible? Right now I made it work by manually editing dtls.c:

case DTLS_HT_SERVER_KEY_EXCHANGE:

if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
  if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
    //return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
  }
  ..... add check_server_certificate with my server public key ....
  err = check_server_key_exchange_ecdsa(ctx, peer, data, data_length);
}

Thanks a lot,
Flavio

Using retransmission timer

How is the retransmission of handshake messages done in tinydtls? Based on my testing (by dropping a handshake message manually on the client), there is currently no retransmission done automatically.

Do I need to call dtls_check_retransmit() after a certain period after sending the handshake message?

Also, I found the following in dtls.c. Does this mean that retransmitting handshake messages is still not supported?

tinydtls/dtls.c

Lines 1649 to 1651 in d99fb8c

/* FIXME: copy to peer's sendqueue (after fragmentation if
* necessary) and initialize retransmit timer */
res = CALL(ctx, write, session, sendbuf, len);

Failed Assertion (dtls_send_client_key_exchange)

Description

  • Type: Failing Assertion
  • Priority: Medium
  • The bug affects the develop branch

How to trigger
During a handshake, when a client expects a server hello message, if a maliciously crafted message with the handshake type 0x0c (server key exchange) is sent to the client followed by a server hello done, the client first processes the message as a server key exchange. This successful processing of the server key exchange message changes the state of the client to DTLS_STATE_WAIT_SERVERHELLODONE. Later, when the server hello done message is processed, the dtls_send_client_key_exchange function is invoked. In this step, based on the handshake->cipher, different functionalities are activated. Since the client and server did not agree on any cipher (no server hello is received by the client), the assertion under the case TLS_NULL_WITH_NULL_NULL will be failed.

Take the following maliciously crafted message:

Screen

This message was originally a server hello message. We only changed the handshake type to 0x0c (server key exchange). This modification will trigger the assertion.

I attached the maliciously crafted message in the following:
malicious-message2.zip

Undefined Behavior Due to Over-shift of Record Sequence Number

Hello again,

The bug occurs in the part that is responsible for checking the validity of the record sequence number. This bug is found by employing symbolic execution technique. When a packet is being processed (in dtls_handle_message()), if a peer is initialized (dtls_peer_t *peer), TinyDTLS checks for the validity of the record sequence number. In the case that (pkt_seq_nr > security->cseq.cseq), we have shift operations as the following:

security->cseq.bitfield <<= (pkt_seq_nr-security->cseq.cseq);  
security->cseq.bitfield |= 1<<((pkt_seq_nr-security->cseq.cseq)-1); 

we know that cseq.bitfield is an unsigned long (64-bit) and 1 is an unsigned integer (32-bit). Therefore, if the value of pkt_seq_nr-security->cseq.cseq is greater equal to 64 there is an over-shift for the first statement and for the values of pkt_seq_nr-security->cseq.cseq greater equal to 32 there is an over-shift for the second statement. Finally, since pkt_seq_nr-security->cseq.cseq refers to the Record Sequence Number in a dtls record, for the Record Sequence Number > 32, we will have an over-shift.
I have attached the means to reproduce the mentioned bug. To do so, after downloading the suite, in tinydtls-master-witness/tests, execute the script setupserver.sh to compile TinyDTLS with Undefined Behavior Sanitizor. Note that, I have de-randomized TinyDTLS for this demonstration and the patch is available in tinydtls-master-witness/tests/patches. Successful execution of setupserver.sh will run the dtls-server on port 20220. Now, executing ./reproduce.sh in tinydtls-master-witness/tests should result in the following run-time error from the sanitizer:

image

I hope I could explain it understandably. I appreciate the confirmation of the bug.
tinydtls-master-witness.zip

Best,
Hooman Asadian

There may be some null-dereference bugs in dtls.c

In handle_handshake_msg(), the variable peer is checked in:
if (peer) {
dtls_stop_retransmission(ctx, peer);
}
This indicates that peer can be NULL.
If so, some null-dereference bugs will occur in handle_handshake_msg().
peer is also checked in line 3436:
if (peer && !peer->handshake_params)
and it is dereferenced in line 3451:
peer->state = DTLS_STATE_CLIENTHELLO;

DTLS_STATE_CLOSING may block session slots

RIOT-OS/RIOT#16422 correctly states that calling dtls_close() may result in a session held in state DTLS_STATE_CLOSING forever if no alert messages from the peer are received. Reasons for this might be dropped packets or a crashed/gone peer. A viable solution could include triggering cleanup (either through dtls_reset_peer() or dtls_destroy_peer()) after some timeout.

Changing the development process, branch renaming

@boaks has proposed a new development process which I support. The changes will include renaming the master branch to main.

  • In the future, the branch main will contain contributions that have been reviewed by two different team members.
  • Releases will be created from tagged versions in the main branch.
  • The development branch will contain contributions in an early stage, possibly reviewed by only one team member.

Renaming the default branch will need a slight change on your local working copies as described here. You can do the change at your convenience as for the time being a redirect will be in place.

Processing Application Data before Finish

Analyzing recent comment on issue #79, I realized, that there is no protection from processing Application Data before the Finish is processed and verified successful.

application_records_before_finish.pcapng.gz

Logs:

Dec 22 15:00:48 DEBG client_random: (32 bytes): 61C32F903B60B0299900EAEA040FD2FDD729B5E40288958F478AC4574926B658
Dec 22 15:00:48 DEBG server_random: (32 bytes): 000000009EA0AE8BC1941D81E2098E2303FEA853190F79F98FB564DB8CE4F395
Dec 22 15:00:48 DEBG pre_master_secret: (22 bytes): 0009000000000000000000000973656372657450534B
Dec 22 15:00:48 DEBG extended_master_secret: (48 bytes): 9676115C2189E53D285E460A6C34D02477EFB693DAC29E104FF4BD80A42377072C7F8860931717D782113CC67D6D0157
Dec 22 15:00:48 DEBG key_block (40 bytes):
Dec 22 15:00:48 DEBG client_MAC_secret: (0 bytes):
Dec 22 15:00:48 DEBG server_MAC_secret: (0 bytes):
Dec 22 15:00:48 DEBG client_write_key: (16 bytes): C1E640D693A53D39DEB4CE7FE50527C6
Dec 22 15:00:48 DEBG server_write_key: (16 bytes): 4DDFF99804421A14FA431852E450100F
Dec 22 15:00:48 DEBG client_IV: (4 bytes): 18B4A717
Dec 22 15:00:48 DEBG server_IV: (4 bytes): B4ECA47F

Dec 22 15:00:48.227 DEBG * [::ffff:127.0.0.1]:5684 <-> [::ffff:127.0.0.1]:58926 (if1) DTLS: received 56 bytes
Dec 22 15:00:48 INFO received message of type 23, epoch 1
Dec 22 15:00:48 DEBG dtls_handle_message: FOUND PEER
Dec 22 15:00:48 DEBG got 'application_data' epoch 1 sequence 1 (56 bytes)
Dec 22 15:00:48 DEBG nonce: (16 bytes): 18B4A717000100000000000100000000
Dec 22 15:00:48 DEBG key: (16 bytes): C1E640D693A53D39DEB4CE7FE50527C6
Dec 22 15:00:48 DEBG ciphertext: (35 bytes): EC9D188E8376AE0A198B5A49CEC58F5FAF95C4E212B786A5E3B452A4AB9AAA0AE30E88
Dec 22 15:00:48 DEBG decrypt_verify(): found 27 bytes cleartext
Dec 22 15:00:48 DEBG cleartext: (27 bytes): 4801FCB65074B39ACC7951E9396C6F63616C686F73748474696D65
Dec 22 15:00:48 DEBG new bitfield is 1 sequence base 1
Dec 22 15:00:48 DEBG receive header: (13 bytes):
00000000 17 FE FD 00 01 00 00 00 00 00 01 00 2B
Dec 22 15:00:48 DEBG receive unencrypted: (27 bytes):
00000000 48 01 FC B6 50 74 B3 9A CC 79 51 E9 39 6C 6F 63
00000010 61 6C 68 6F 73 74 84 74 69 6D 65
Dec 22 15:00:48 INFO ** application data:
v:1 t:CON c:GET i:fcb6 {5074b39acc7951e9} [ Uri-Host:localhost, Uri-Path:time ]
Dec 22 15:00:48.227 DEBG call custom handler for resource 'time'

Sending data back is blocked, but for me, the received Application Data must be dropped as well.
The same applies to Alert, that receiving an Alert after CCS before Finish should be dropped.

initial hs_state.mseq_s value

According RFC6347, 4.2.1. Denial-of-Service Countermeasures, page 17

When the second ClientHello is received, the server can verify that
the Cookie is valid and that the client can receive packets at the
given IP address. In order to avoid sequence number duplication in
case of multiple cookie exchanges, the server MUST use the record
sequence number in the ClientHello as the record sequence number in
its initial ServerHello. Subsequent ServerHellos will only be sent
after the server has created state and MUST increment normally.

The implementation in dtls.c, handle_handshake_msg, line 3631 uses

peer->handshake_params->hs_state.mseq_r = dtls_uint16_to_int(hs_header->message_seq);
peer->handshake_params->hs_state.mseq_s = 1;

I think, the initial value for hs_state.mseq_s value should be also dtls_uint16_to_int(hs_header->message_seq). A test, with an expired cookie and second hello_verify should demonstrate, if my assumption is right.

New release?

It has been a very long time since tinydtls has an official release (0.8.2 was released in 2015: https://sourceforge.net/projects/tinydtls/files/r5/tinydtls-0.8.2.tar.gz/download).

tinydtls eclipse website states that 0.9 was released in November 2017: https://projects.eclipse.org/projects/iot.tinydtls. However, I can't find this version anywhere.

From my understanding, develop branch fixes CVE-2017-7243 (#12) as well as other security issues:
68a1cda, 494a40d and 2d9f0a8

So it would be really nice to have a new version to be able to use it in distros (buildroot being one of those).

Invalid decrypt_error response connected to unreliability of the Handshake protocol

Non-conformance Bug affecting usability of the library

OS
Linux, Ubuntu 20
develop branch, commit c20c632
Affects both clients and servers

Non-conformance

According to the RFC, decrypt_error alerts should be generated when:

A handshake cryptographic operation failed, including being unable
to correctly verify a signature or validate a Finished message.

None of these happen in the below capture. Therein, the client receives an unencrypted HelloVerifyRequest with epoch 1 is received. The message is unencrypted. The fact that it has epoch 1 should mean that it should not be processed/should instead be discarded/ rejected.

etinydtls_invalid_decrypt_error_alert

The issue also affects servers. In the capture below, an ClientKeyExchange with epoch 1 elicits a decrypt_error response from the server for no good reason.

etinydtls_server

Abruptly terminating the handshake on receiving a record with an epoch for which a session has not been established has a more severe implication. In case Finished (epoch 1) is received before ChangeCipherSpec (epoch 0) or ClientKeyExchange (epoch 0), the TinyDTLS client/server will abruptly terminate the handshake. This can happen in real world due to reordering. A capture of this is shown below exposing the problem on clients. Notice that the ChangeCipherSpec of the server is sent before Finished, to mimic this scenario. Finished appears as an "Encrypted Handshake Message" in the capture, as it cannot be decrypted by Wireshark.

etinydtls_decrypt_reorder

Steps to Reproduce
I attached files necessary for reproduction using DTLS-Fuzzer, a Java-based tool for testing DTLS libraries. Also included in the archive the captures of the interaction show above. DTLS-Fuzzer requires the JDK for Java 8. On Ubuntu, this can be installed by running:
sudo apt-get install openjdk-8-jdk

Unpack the archive, cd to resulting folder and run bash reproduce.sh test_sequence_decrypt or bash reproduce.sh test_sequence_reorder, while running an instance of Wireshark on the side. The reproduction script will:

  • setup eclipse TinyDTLS and DTLS-Fuzzer
  • launch the TinyDTLS client using the 'tests/dtls-client utility;
  • launch DTLS-Fuzzer to execute the input sequences 'test_sequence_decrypt' or 'test_sequence_reorder' which expose the two problems.

I also added the test sequence 'test_sequence_handshake'. This is similar to the reordering sequence, but without the reordering. By executing this sequence via bash reproduce.sh test_sequence_handshake, you should complete the handshake with the client.

Note that the problems affect both clients and servers. On request, I can provide reproduction scripts also for servers. I am guessing fixing the problem for clients will also do it for servers.

Thanks!

reproduction.tar.gz

sha256-ecdsa signature encoding

branch: development
commit: 290c48d with PR #52 and PR #53 cherry picked

(I assume, this is not related to this exact version.)

Running Eclipse Californium Interoperability Tests continuously, I faced rare failures using RPK.

Starting with one of the reported failure:

Mar 23 01:17:48 DEBG got packet 22 (98 bytes)
Mar 23 01:17:48 DEBG new packet arrived with seq_nr: 4
Mar 23 01:17:48 DEBG new bitfield is               : b
Mar 23 01:17:48 DEBG receive header: (13 bytes):
00000000 16 FE FD 00 00 00 00 00  00 00 04 00 55 
Mar 23 01:17:48 DEBG receive unencrypted: (85 bytes):
00000000 0F 00 00 49 00 04 00 00  00 00 00 49 04 03 00 45 
00000010 30 43 02 1F 4C E9 93 20  8C B2 18 B2 33 C2 CF 99 
00000020 C8 C1 AA 16 FA FA 86 8C  9C 23 3D DA 4C 8D 70 B7 
00000030 16 ED 5D 02 20 67 0F B5  2A 8B 58 BE 31 96 D5 D6 
00000040 BB 19 02 EA 52 9C 5B 4D  F1 47 72 28 8E F1 EC BC 
00000050 96 2F FF A2 DC 
Mar 23 01:17:48 DEBG received handshake packet of type: certificate_verify (15)
Mar 23 01:17:48 DEBG handle handshake packet of type: certificate_verify (15)
Mar 23 01:17:48 ALRT the packet length does not match the expected
Mar 23 01:17:48 WARN error in check_client_certificate_verify err: -562

I recognized, that tinydtls seems to assume, that the SHA256-ECDSA signature has a fixed length (86 bytes).
According Shouldn't a signature using ECDSA be exactly 96 bytes, not 102 or 103? the length of such a signature may be encoded in a variable way.

I got additionally faced similar failures:

Mar 21 11:22:28 DEBG got packet 22 (99 bytes)
Mar 21 11:22:28 DEBG new packet arrived with seq_nr: 4
Mar 21 11:22:28 DEBG new bitfield is               : b
Mar 21 11:22:28 DEBG receive header: (13 bytes):
00000000 16 FE FD 00 00 00 00 00  00 00 04 00 56 
Mar 21 11:22:28 DEBG receive unencrypted: (86 bytes):
00000000 0F 00 00 4A 00 04 00 00  00 00 00 4A 04 03 00 46 
00000010 30 44 02 1F 22 1A F7 1E  EE 84 DB 50 51 4A DC C9 
00000020 16 67 A9 16 56 CC B0 79  73 A2 80 7B 6C C4 74 44 
00000030 A1 C3 D7 02 21 00 99 AC  0A 91 80 09 6B 8A D2 DA 
00000040 32 7A E0 C0 2F 1D 9F 92  4C EA 2B BE 89 9F D7 09 
00000050 3F E6 AE 7C 91 37 
Mar 21 11:22:28 DEBG received handshake packet of type: certificate_verify (15)
Mar 21 11:22:28 DEBG handle handshake packet of type: certificate_verify (15)
Mar 21 11:22:28 ALRT wrong signature err: -1
Mar 21 11:22:28 WARN error in check_client_certificate_verify err: -552

where the total length is 86, but the keys have different lengths. Generally, zero-bytes seems to be removed, if the next byte has less than 0x7f. Otherwise one 0x00 is kept for values 0x80 and larger.

client server example in RIOT failed with latest develop branch

I encountered this when testing PR #19 with the latest develop branch. Using the RIOT dtls-echo example, sending a packet from a client to a server will fail.

How to reproduce

Apply the diff to the RIOT repository and run the dtls-echo example.

Use latest develop tinydtls branch on RIOT and enable debug by applying this diff:

diff --git a/examples/dtls-echo/Makefile b/examples/dtls-echo/Makefile
index 325078eac..91a51bc93 100644
--- a/examples/dtls-echo/Makefile
+++ b/examples/dtls-echo/Makefile
@@ -42,7 +42,7 @@ CFLAGS += -DDTLS_DEFAULT_PORT=$(DTLS_PORT)
 
 # NOTE: If not cipher suite is selected, DTLS_PSK is used by default.
 # This adds support for TLS_PSK_WITH_AES_128_CCM_8
-# CFLAGS += -DDTLS_PSK
+CFLAGS += -DDTLS_PSK
 # This adds support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
 # CFLAGS += -DDTLS_ECC
 
@@ -52,7 +52,7 @@ TINYDTLS_LOG ?= 0
 
 # Enable this line for setting tinyDTLS in debug mode.
 # This overrides TINYDTLS_LOG to 6
-# CFLAGS += -DTINYDTLS_DEBUG
+CFLAGS += -DTINYDTLS_DEBUG
 
 # FIXME: This is a temporary patch
 # TinyDTLS <= 0.8.6 requires around 426 bytes in RAM.
diff --git a/pkg/tinydtls/Makefile b/pkg/tinydtls/Makefile
index e1a8483d0..802c5bc70 100644
--- a/pkg/tinydtls/Makefile
+++ b/pkg/tinydtls/Makefile
@@ -1,6 +1,6 @@
 PKG_NAME=tinydtls
 PKG_URL=https://github.com/eclipse/tinydtls.git
-PKG_VERSION=dcac93f1b38e74f0a57b5df47647943f3df005c2
+PKG_VERSION=494a40dfbb174930ca616e560532d52549736b42
 PKG_LICENSE=EPL-1.0,EDL-1.0
 
 CFLAGS += -Wno-implicit-fallthrough
Server log:

> dtlss start
dtlss start
> Oct 02 15:31:34 DEBG dtls_handle_message: PEER NOT FOUND
Oct 02 15:31:34 DEBG got packet 22 (95 bytes)
Oct 02 15:31:34 DEBG receive header: (13 bytes):
00000000 16 FE FF 00 00 00 00 00 00 00 00 00 52  
Oct 02 15:31:34 DEBG receive unencrypted: (82 bytes):
00000000 01 00 00 46 00 00 00 00 00 00 00 46 FE FD 00 00  
00000010 00 05 E9 CC A0 AC 1C C1 EB E4 52 EB 47 70 CC 83  
00000020 A1 0C C9 D1 C9 69 5E 0D 28 01 1F F1 C6 05 00 00  
00000030 00 02 C0 AE 01 00 00 1A 00 13 00 02 01 02 00 14  
00000040 00 02 01 02 00 0A 00 04 00 02 00 17 00 0B 00 02  
00000050 01 00 
Oct 02 15:31:34 DEBG received handshake packet of type: client_hello (1)
Oct 02 15:31:34 DEBG handle handshake packet of type: client_hello (1)
Oct 02 15:31:34 WARN error in dtls_verify_peer err: -552
Oct 02 15:31:34 WARN error while handling handshake packet
Oct 02 15:33:24 DEBG dtls_handle_message: PEER NOT FOUND
Oct 02 15:33:24 DEBG got packet 21 (15 bytes)
Oct 02 15:33:24 DEBG receive header: (13 bytes):
00000000 15 FE FD 00 00 00 00 00 00 00 01 00 02  
Oct 02 15:33:24 DEBG receive unencrypted: (2 bytes):
00000000 02 00 
Oct 02 15:33:24 INFO ** Alert: level 2, description 0
Oct 02 15:33:24 WARN got an alert for an unknown peer, we probably already removed it, ignore it
Client log:

> dtlsc fe80::2051:47ff:fec8:edcf heyyy
dtlsc fe80::2051:47ff:fec8:edcf heyyy
Oct 02 15:31:34 DEBG DTLSv12: initialize HASH_SHA256
Oct 02 15:31:34 DEBG send handshake packet of type: client_hello (1)
Oct 02 15:31:34 DEBG send header: (13 bytes):
00000000 16 FE FF 00 00 00 00 00 00 00 00 00 52  
Oct 02 15:31:34 DEBG send unencrypted: (12 bytes):
00000000 01 00 00 46 00 00 00 00 00 00 00 46  
Oct 02 15:31:34 DEBG send unencrypted: (70 bytes):
00000000 FE FD 00 00 00 05 E9 CC A0 AC 1C C1 EB E4 52 EB  
00000010 47 70 CC 83 A1 0C C9 D1 C9 69 5E 0D 28 01 1F F1  
00000020 C6 05 00 00 00 02 C0 AE 01 00 00 1A 00 13 00 02  
00000030 01 02 00 14 00 02 01 02 00 0A 00 04 00 02 00 17  
00000040 00 0B 00 02 01 00 
Oct 02 15:33:24 DEBG send header: (13 bytes):
00000000 15 FE FD 00 00 00 00 00 00 00 01 00 02  
Oct 02 15:33:24 DEBG send unencrypted: (2 bytes):
00000000 02 00 

Fragment Length, Fragment Offset Non-conformance bug

Description

  • Type: Non-conformance Bug
  • Priority: Minor

Non-conformance Bug

Version: development branch

Expected behavior
The DTLS RFC specifies the following requirement regarding the fragment offset and fragment length when fragmentation is not present:

An unfragmented message is a degenerate case with fragment_offset=0 and fragment_length=length

Actual behavior
One can complete a handshake with the following values for the fragment_offset and fragment_length:

CKE.message_length = 17
CKE.fragment_length = 16777198
CKE.fragment_offset = 255

The problem also exists when the server sends records with non-compliant Fragment_offset and fragment_length.

I have attached the handshake trace for the mentioned non-conformance. You clearly see that the handshake proceeds while the Fragment_offset and fragment_length are invalid.
capture.zip

Incorrect handling over-large packets at dtls_ccm_decrypt_message()

Hello,

In both the master branch and develop branch, an illegal over-read bug has been found when the server handles a malicious message with the following values for the mentioned fields:

  1. Fragment length may be a larger number like 8143, whose value can be up to (2^24-1) bytes theoretically.
  2. the peer exists and is not null.

After the server handles this message in the normal way as follows(in the master branch), we enter into the function dtls_ccm_decrypt_message() at ccm.c:264.
1. 0x4e4b33 in dtls_ccm_decrypt_message /home/Research/benchmarks/tinydtls/ccm.c:264:5
2. 0x4dd76a in dtls_ccm_decrypt /home/Research/benchmarks/tinydtls/crypto.c:301:9
3. 0x4dd76a in dtls_decrypt /home/Research/benchmarks/tinydtls/crypto.c:561:9
4. 0x4cbfe7 in decrypt_verify /home/Research/benchmarks/tinydtls/dtls.c:3035:12
5. 0x4c9bbc in dtls_handle_message /home/Research/benchmarks/tinydtls/dtls.c:3746:25
6. 0x4c67bc in dtls_handle_read /home/Research/benchmarks/tinydtls/tests/dtls-server.c:177:10
7. 0x4c67bc in main /home/Research/benchmarks/tinydtls/tests/dtls-server.c:352:2
8. 0x7f8454dbb0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
9. 0x41c3bd in _start (/home/Research/benchmarks/tinydtls/tests/dtls-server+0x41c3bd)

In the function dtls_ccm_decrypt_message(), the value of variable lm is larger than the length of the current packet, whose value is less than 1400. Hence, an illegal memory access bug appears, which leads to the server crashing, memory leak and other effects.

From DTLS12 RFC, the server should have the ability to fragment large packets. If not, over-large packets should be refused.

In current both master and develop branches, this bug could be reproduced with this packet: ReproduciablePacket.

Could you kindly have a check? Thanks a lot.

Buffer Over-read Affecting Fragmentation Feature

Hello,

I have tried to submit this through Eclipse Bugzilla. However, apparently, the dedicated page for TinyDTLS has been removed or I did not have access to it. The following over-read has been found by using symbolic execution technique. Suppose you have a Client Key Exchange message with the following values for the mentioned fields:

  • length in the record layer = 25
  • length in the handshake layer = 51
  • fragment length = 16
  • fragment offset = 0

When we are handling the message (in dtls_handle_message()), data_length = decrypt_verify(peer, msg, rlen, &data) is called. It returns a pointer to the first offset of the handshake layer (uint8 *data) and the real size of the handshake layer (data_length = 25). Later, as we have packet_length=51 > fragment_length=16, we start the reassembling process. the message also pass fragment_offset=0 + fragment_length=16 <= packet_length=51 check. Finally, after allocating memory on the heap (peer->handshake_params->reassemble_buf->data), when we are going to copy the message (memcpy) into the newly allocated buffer, we use the combination of fragment offset and fragment length to derive the size of the handshake message and the pointer (data) as it points to the first offset of the handshake layer. Let me remind you that the valid range for data is 25 (=data_length). However, in this scenario, the size (fragment_length=16 + handshake_header_size=12) is 28. Therefore, there is a 3-byte overread happening.
I have attached the means to reproduce the mentioned bug. To do so, after downloading the suite, in tinydtls-witness/tests, execute the script setupserver.sh to compile TinyDTLS. Note that, I have de-randomized TinyDTLS for this demonstration and the patch is available in tinydtls-witness/tests/patches. Successful execution of setupserver.sh will run dtls-server on port 20220. Now, executing ./reproduce.sh in tinydtls-witness/tests should cause dtls-server to crash.
Screenshot from 2021-03-19 18-44-03

The malformed Client Key Exchange can be found in tinydtls-witness/tests/testcases.

I hope I could explain it understandably.
tinydtls-witness.zip

Best wishes,
Hooman Asadian

32bit overflow does not work

dtls_time.h seems to be uint32_t aware:

typedef uint32_t clock_time_t;

but these lines may produce problems with 32bit overflow:

these calculate possibly overflowing time stamps:

tinydtls/dtls.c

Line 1763 in 68b2521

n->t = now + 2 * CLOCK_SECOND;

tinydtls/dtls.c

Line 4534 in 68b2521

node->t = now + (node->timeout << node->retransmit_cnt);

these do not deal with overflowing timestamps:
calculating if the timeout happend: (timestamp passed by)

tinydtls/dtls.c

Line 4596 in 68b2521

while (node && node->t <= now) {

inserting (sorted) into the netq

while(p && p->t <= node->t) {

In #123 @boaks and me pointed that out

reference / line number are current develop branch

Over-read Affecting dtls_check_tls_extension()

Hello,

In this case, the server sends a server_hello to the client where the record_length is smaller than the value it is supposed to be like the following (24 instead of 50):

image

Therefore, data_length will wrap-around here and later is used to read the extensions here which causes the client to crash.

image

I have attached the means to reproduce the mentioned bug. To do so, after downloading the suite, in tinydtls-develop/tests, execute the script setupserver.sh to compile TinyDTLS and simple-udp-server. Note that, I have de-randomized TinyDTLS for this demonstration. Successful execution of setupserver.sh will run simple-udp-server on port 20220. Now, if you execute reproduce.sh, it will initiate a handshake with simple-udp-server and crashes the client.

tinydtls-develop.zip

Best,
Hooman Asadian

DTLS server allows a handshake to be completed with invalid epochs

The dtls-server application will complete a handshake wherein the first two ClientHello carrying records sent by the client have epochs 1, while the rest have regular epochs (ClientKeyExchange and ChangeCipherSpec have epochs 0, Finished has epoch 1).

Attached at the end of the message is an archive containing a Wireshark capture of the invalid handshake. I am also posting an image of how this capture looks like, so that the interaction becomes clear.

Note that the server was configured to use the PSK password 1234 (you can input this in wireshark in order to decrypt the last finished messages).
bad_handshake

Cheers, Paul.

bad_handshake.zip

Infinite Loop Bug Affecting handling ClientHello Handkshake message

Hello,

In the project master branch, an infinite loop bug had been found during handling ClientHello Handshake message. Suppose you have a malicious ClientHello message with the following values for the mentioned fields:
1. Cipher Suites Length is an odd number like 3 (this is a malicious number)
2. Two Suites whose length is 4 bytes
3. Extension Length whose length is not zero like 26 bytes

After handling this message in the normal handling way as follows, we enter into the function dtls_update_parameters() at the dtls.c:980.
1. 0x4e2b02 in dtls_update_parameters /home/etinydtls/dtls.c:1024:22
2. 0x4e2b02 in handle_handshake_msg /home/etinydtls/dtls.c:3403:11
3. 0x4cb1ce in handle_handshake /home/etinydtls/dtls.c:3493:14
4. 0x4cb1ce in dtls_handle_message /home/etinydtls/dtls.c:3881:13
5. 0x4c4efc in dtls_handle_read /home/etinydtls/tests/dtls-server.c:177:10
6. 0x4c4efc in main /home/etinydtls/tests/dtls-server.c:352:2
7. 0x7fb176ab10b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
8. 0x41c45d in _start (/home/etinydtls/tests/dtls-server+0x41c45d)

When coming to dtls.c:1005 in the function dtls_update_parameters(), variable i is assigned to a int number, which stands for all cipher suites' length 3 in this message. After that, the condition data_length < i + sizeof(uint16) cannot refuse this packet cannot exclude this packet, as 4+26 < 3+2 is no satisfied. Hence, we come to the loop of confirming suites at the dtls.c:1023, where i is decreased by 2 each loop. The ending loop condition includes (i == 0), while the initial value of i is 3 thereby this condition will not be satisfied. Unfortunately, one infinite loop incurs, which lets the server loop forever until consuming all resources.

Here is a message packet to reproduce this bug: [https://github.com/jerrytesting/dtls-infiniteLoop.git]

I hope I could explain it clearly. Could you kindly have a check? Thanks a lot.

Kind Regards,
Jerry

Cookie Exchange Bypass Bug

Hi,

This bug occurs when the server is unable to retrieve the cookie from a ClientHello.
Suppose that we send the following ClientHello to the server:

image

As you can see, the Handshake version has an invalid value. This causes the server to fail to fetch the cookie here. The problem is that the server returns the err here instead of the len and the value for err is zero (because of here). returning zero short circuits the cookie check and causes the server to proceed with the handshake by sending the ServerHello and ServerHelloDone. This makes TinyDTLS servers susceptible to Denial of Service attack.

I have attached the handshake trace in which we bypassed the cookie exchange mechanism by providing invalid values for the Handshake version.

ch_inv_version.zip

Buffer Over-read Affecting dtls_create_cookie()

Hello again,

This bug occurs when the server receives a malformed Client Hello to initialize a handshake and it affects the master branch. This bug is found by employing symbolic execution technique. Suppose you have a malformed Client Hello where the length field in the handshake layer is 0. When the mentioned Client Hello is received by the server, dtls_verify_peer() calls dtls_create_cookie() for cookie generation. Inside dtls_create_cookie(), TinyDTLS defines e which is unsigned (size_t). Later, when we call the following update function:

dtls_hmac_update(&hmac_context, 
		   msg + DTLS_HS_LENGTH + e,
		   dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)) - e);

the macro dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)) will return 0. Therefore, since e is unsigned, dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)) - e will wrap around and evaluates to a very huge number(e.g 18446744073709551580). This huge value, in turns will cause a memory over-read in the memcpy in sha2.c.
I have attached the means to reproduce the mentioned bug. To do so, after downloading the suite, in tinydtls-master-witness/tests, execute the script setupserver.sh to compile TinyDTLS. I have not changed anything in the code for the sake of this demonstration. Successful execution of setupserver.sh will run the dtls-server on port 20220. Now, executing ./reproduce.sh in tinydtls-master-witness/tests should crash the server as shown in the following figure:

image

I hope I could explain it understandably and I appreciate your confirmation of the bug.
tinydtls-master-witness.zip

Best,
Hooman Asadian

Fuzzing Hello_Extensions?

@bathooman

Just to mention: the HELLO_EXTENSIONs are also including lengths.
Did you already checked that?
I really appreciate tinydtls gets hardened.

PSK Authentication

The PSK authentication with ciphersuite TLS_PSK_WITH_AES_128_CCM_8, carries PSK ID:
memcpy(p, handshake->keyx.psk.identity, handshake->keyx.psk.id_length);
p += handshake->keyx.psk.id_length;

So does i mean it serves as client authentication ?? -- If server posses the psk mapped to that psk_id it goes on with handshake, if not reports error.

Or is it server authentication by client which checks if server has the psk mapped to that psk_id, client can verify if the server is indeed in possession of psk mapped to the psk_id it sent, if and only if server sends a finished message, which client can authenticate correctly.

Record Sequence Number non-conformance bug

Description

  • Type: Non-conformance Bug
  • Priority: Minor

Non-conformance Bug

Version: development branch

Expected behavior
The DTLS RFC specifies the following regarding the record sequence number:

For each received record, the receiver MUST verify that the record contains a sequence number that does not duplicate the sequence number of any other record received during the life of this session. Duplicates are rejected through the use of a sliding receive window. The "right" edge of the window represents the highest validated sequence number value received on this session. Records that contain sequence numbers lower than the "left" edge of the window are rejected.

Actual behavior
One can complete a handshake with the following values for the record sequence number:

CH0.sequence_number = 0
CH2.sequence_number = 68
CKE.sequence_number = 0
CCC.sequence_number = 0

The problem also exists when the server sends records with non-unique record sequence numbers.

I have attached the completed handshake trace for the mentioned non-conformance.

invalid-RSN.zip

Client proceeds in handshake after receiving consecutive CertificateRequest messages

Non-conformance Bug

OS
Linux, Ubuntu 20
develop branch, commit c20c632

Expected behavior
The client should not proceed with a handshake where it receives distinct consecutive CertificateRequest messages.

Actual Behavior
Our testing shows that the client upon receiving these messages proceeds with the handshake as normal; upon receiving ServerHelloDone, it generates the next flight of messages as can be seen in the capture below taken on my machine.

etinydtls_multiple_certreq

Note that the later CertificateRequest is not a retransmission of the former. Its message_sequence value differs, so it should have been processed as a distinct handshake message.

Steps to Reproduce
I attached files necessary for reproduction using DTLS-Fuzzer, a Java-based tool for testing DTLS libraries. Also included in the archive is a capture of the interaction show above. DTLS-Fuzzer requires the JDK for Java 8. On Ubuntu, this can be installed by running:
sudo apt-get install openjdk-8-jdk

Unpack the archive, cd to resulting folder and run bash reproduce.sh, while running an instance of Wireshark on the side. The reproduction script will:

  • setup eclipse TinyDTLS and DTLS-Fuzzer
  • launch the TinyDTLS client using the 'tests/dtls-client utility;
  • launch DTLS-Fuzzer to execute the input sequence 'test_sequence' which exposes the bug.

Thanks!

reproduction.tar.gz

HELLO_VERIFY_REQUEST - Protocol Version

Adapting Eclipse Californium to my interpretation of RFC 6347 - Section 4.2.1 using 1.0 for the protocol version in the record header and in the server_version field of the hello_verify_request, that caused trouble with not compliant clients.

Investigating, it seems that RFC6347 is ambiguous about that. I wrote a e-mail to the IETF TLS mailing list,
see RFC 6347 - Section 4.2.1 - used version in a HelloVerifyRequest.

As far as I understand, tinydtls is using 1.0 for the record protocol version and 1.2 for the server_version in the hello_verify_request. There is a comment in dtls.c

Signal DTLS version 1.0 in the record layer of ClientHello and
HelloVerifyRequest handshake messages according to Section 4.2.1
of RFC 6347.

This does not apply to a renegotation Client Hello

Are there any additional references about that?

Just to mention:
openssl: 1.0 for both
gnutls: 1.0 for both
mbedtls: 1.2 for both.

No cipher nor compression, ok for renegotiation?

in develop-branch, dtls.c, dtls_update_parameters:

   /* Looks like we do not have a cipher nor compression. This is ok
     * for renegotiation, but not for the initial handshake. */

Logical/functional it seems to be OK for me.
But do you have also a RFC cite for that?

RFC5246 - 7.4.1.2. Client Hello

CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;

FMPOV, that implies at least 2 and 1 byte must be used, empty would be <0...

If the
session_id field is not empty (implying a session resumption
request), this vector MUST include at least the cipher_suite from
that session.

...

If the session_id field is not empty
(implying a session resumption request), it MUST include the
compression_method from that session. This vector MUST contain,
and all implementations MUST support, CompressionMethod.null.
Thus, a client and server will always be able to agree on a
compression method.

That refers to a resumption, so it may not apply. But I miss similar statements for renegotiation.

Out of bound pointer (dtls_handle_message)

Description

  • Type: Out of bound pointer
  • Priority: High
  • The bug affects the develop branch
  • This affects both the processing of the messages on the server-side and the client-side. However, for brevity, we only give an example of an attack scenario for a server.

How to trigger
When the server is expecting a change cipher spec record during the handshake, if a maliciously crafted record with the content type 0x15 (Alert) is sent to the server, the server identifies it as an Alert record. the server then processes the record as an Alert and based on the output value of the handle_alert and the type of the Alert, shows a warning. Accessing the out-of-bound pointer occurs when the server accesses the type of the Alert.

Take the following maliciously crafted record:

screentshot3

This record was originally a change cipher spec record. We only changed the content type to 0x15 (Alert). Notice that there is only one byte in the record (Length = 1). When this record is sent to the server, after the server processes it as an Alert, it attempts to identify the type of Alert by accessing data[1] that is out-of-bound access.

I attached the maliciously crafted message in the following:
malicious-message3.zip

Buffer Over-read Affecting check_server_hello()

Hello again,

The following over-read happens when you send a fragmented Server Hello message to the client. The bug is found employing symbolic execution technique. Suppose you have a Server Hello message with the following values for certain fields:

  • length in the record layer = 46
  • length in the handshake layer = 0
  • fragment length = 128

When we are handling the message (in dtls_handle_message()), data_length = decrypt_verify(peer, msg, rlen, &data) is called. It returns a pointer to the first offset of the handshake layer (uint8 *data) and the real size of the handshake layer (data_length = 46). Later inside check_server_hello(ctx, peer, data, data_length), Tiny tries to read different fields of the Server Hello message. It happens by advancing the pointer data and deducting the data_length. As I previously mentioned, the Server Hello is fragmented and it contains only up to the random field (handshake header = 12 bytes + handshake version = 2 bytes + random = 32 bytes). Therefore, after advancing the pointer (data) for 46 bytes, Tiny tries to skip the Session ID by calling the Macro (SKIP_VAR_FIELD(data, data_length, uint8)). However, Tiny already has advanced the pointer (data) for 46 bytes, and the pointer (data) is currently pointing to invalid memory. Therefore, here we have a one-byte over-read. I have added the assertion (assert(data_length > 0)) before SKIP_VAR_FIELD(data, data_length, uint8) to reveal the invalid read. For reproducing the bug, I have written a small UDP server that plays the role of a DTLS-server.
I have attached the means to reproduce the mentioned bug. To do so, after downloading the suite, in tinydtls-witness/tests, execute the script setupserver.sh to compile TinyDTLS and simple-udp-server. Note that, I have de-randomized TinyDTLS for this demonstration and the patch is available in tinydtls-witness/tests/patches. Successful execution of setupserver.sh will run simple-udp-server on port 20220. Now, if you execute reproduce.sh, it will initiate a handshake with simple-udp-server and when it gets the Server Hello, the assertion that I added will fail.

image

I hope I could explain it understandably. I appreciate the confirmation of the reported bugs.

Best,
Hooman Asadian
tinydtls-witness.zip

DTLS server allows insecure renegotiation without indicating renegotiation options in ClientHello

Hello,

The dtls-server application allows completing the second handshake without indicating renegotiation options in the first handshake message, which is prohibited according to RFC 5746.

We could use Wireshark to capture these two handshake processes shown as follows.
renegotiation

This creates the opportunity for an attack in which the attacker who can intercept a client's transport layer connection can inject traffic of his own as a prefix to the client's interaction with the server(cited from RFC 5746).

Could you kindly have a check? Thanks a lot.

Kind Regards,
Jerry

Buffer Over-read Affecting dtls_send_client_hello()

Hi,

In this case, a Hello_verify_request contains a 16-byte cookie but the cookie_length is specified 32.

image

When the Hello_verify_request is received, we use the cookie_length to read from the memory in here. It means we have a 16-byte memory over-read. I have attached the malformed Hello_verify_request for further investigations.

HVR.zip

Best,
Hooman Asadian

RFC7627 - client side only for ecdsa ?

I currently implement the RFC7627/"extended master secret" for Eclipse/Californium.

First interoperability tests shows, that the tinydtls client of the "develop" branch uses the "extended_master_secret" only for rpk, not for psk. The tinydtls server responses to that extension for both rpk and psk.

Is this behavior, that the client only send "extended_master_secret" for rpk intended?

6lbr CoAP-DTLS on Sensortag CC2650

Hello

I am currently implementing the tinyDTLS in 6lbr with the Sensortag CC2650. Has anyone had success with doing this?

How to compiling and configuring tinyDTLS in 6lbr and Sensortag CC2650?

How to flash the tinyDTLS in Sensortag CC2650?

I am really confused about where to start.

Thank you!

HELLO_REQUEST epoch 0

According hs_attempt_with_existing_peer a DTLS_HT_HELLO_REQUEST is processed for epoch 0 (mean unencrypted, maybe spoofed). Is that really wanted/intended?

If so, I would prefer a "compile-time switch", because in my opinion such a function makes DTLS vulnerable.

Out of bound pointer (dtls_create_cookie)

Description

  • Type: Out of bound pointer
  • Priority: High
  • The bug affects the develop branch

How to trigger
During the handshake, when the client expects a handshake message (hello_verify_request, server_hello, server_hello_done), if the server sends a maliciously crafted message with the handshake type 0x01 (client_hello), the client attempts to handle the message by invoking the function handle_0_client_hello. Later, to verify the peer, the function dtls_0_verify_peer is called. Notice that the client has mistaken the message as a client hello message at this point; therefore, dtls_create_cookie is called for cookie generation. Inside this function, the variable e is initialized to DTLS_CH_LENGTH. Since the length of this message can be shorter than a legitimate client hello message, in the next line, msg + DTLS_HS_LENGTH + e points to an out of bound address.
Take the following maliciously crafted message:

Screensho

This message was originally a hello verify request message. We only changed the handshake type to 0x01 (client hello). As you notice, all other values such as fragment_length, record_length, and handshake_length are correct. Therefore, all the checks will be successfully passed. When it comes to cookie generation, as it is explained, a memory error occurs. Notice that the check here is too late. I attached the maliciously crafted message in the following.

malicious-message.zip

dtls_connect_peer() does not correspond to the API description

The description of dtls_connect_peer() states that it returns 0 when the channel already exists:

tinydtls/dtls.h

Line 269 in 7068882

* This function returns @c 0 if that channel already exists, a value

But from looking at the code it does not. If the peer is found, dtls_renegotiate() is called which then tries to do a new handshake, but only when the session is established. So either the function would have to check if the connection exists and return 0, or the description doesn't fit, and it needs to be change that it does a re-connect in this case.
To change behavior the following lines instead of

tinydtls/dtls.c

Line 4010 in 7068882

dtls_debug("found peer, try to re-connect\n");
would fix that.

if (peer->state == DTLS_STATE_CONNECTED) {
      return 0;
}

Or am I misunderstanding something here?

Renegotiation fails with test client/server application

Using the given dtls-client and dtls-server program in tests/, the server will fail when the client sends client:renegotiate.

Snippet from the server debug log (full log):

Dec 18 17:27:48 WARN decryption failed
Dec 18 17:27:48 INFO decrypt_verify() failed

After sending the command, the client also does not react anymore to new inputs from stdin.

Clarify const-ness of nonce and key in dtls_encrypt/_decrypt

In dtls_encrypt and dtls_decrypt, key and nonce are declared mutable (not const). That is unusual for AEAD operations as to my understanding.

Please consider clarifying this, descendingly preferably by

  • making it const
  • documenting that it's practically const (and save to cast to such) but not const for whichever reason, or
  • documenting that (and why) key and nonce get changed.

Fragmentation

I was trying to send CKE with some additional data[21000] which is obviously very large. Fragmentation at IP layer doesnt work properly and CKE is never exchanged.

Do you have a code with supported fragmentation in tinyDTLS.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.