Adding Security to Microcontroller Ruby (original) (raw)

available at:
https:/
/speakerdeck.c...")

3
")

that is more relevant to this ta...")
talk: Freelance web developer focused on Digital Identity and Security Worked/ing on writing/editing and implementing standards HTTPS in Local Network CG / Web of Things WG @ W3C, OAuth / Messaging Layer Security WG @ IETF Worked as an Officer of Internet Society Japan Chapter (2020-23) 5

")

microcontro...")

9
")

(All of the...")
done by @hasumikin) https:/ /github.com/picoruby/picoruby : Ruby implementation https:/ /github.com/picoruby/R2P2 : Shell system for Pi Pico (W) Well-known usage: "PRK Firmware: Keyboard is Essentially Ruby" (RubyKaigi 2021 Takeout) https:/ /www.youtube.com/watch? v=5unMW_BAd4A 10

Adding
Security to
Microcontroller
Ruby...")

Adding
SSL/TLS to
Microcontroller
Rub...")

Adding
Networking to
Microcontroller
Ruby
15
")

")

Cryptography in PicoRuby
20
")

There are cr...")
cryptographic libraries for embedded systems Mbed TLS, wolfSSL Pico SDK uses Mbed TLS Mbed TLS has build options to only include needed functionality See R2P2/include/mbedtls_config.h 24

require 'mbedtls'
re...")
key = Base64.decode64 "aGB7hvLWxE60PsxbPS9wsA==" iv = Base64.decode64 "J4b4xJuIHry/aUpVeyRIJw==" cipher = MbedTLS::Cipher.new(:aes_128_cbc, key, :encrypt) cipher.set_iv(iv) s = cipher.update('asdfasdfasdfasdfasdf') s << cipher.finish Base64.encode64 s 26

or Introduction to mruby...")

We can wrap C values inside a ...")
Ruby object CRuby: RTYPEDDATA_DATA(obj) mruby/c: create an instance with mrbc_instance_new(vm, v->cls, sizeof(C_VAL_TO_WRAP)) Here, we want to wrap the "context" struct created by OpenSSL or mbed TLS 30

c_mbedtls_digest__init_ctx(mrbc_vm ...")
(snip) argument check */ mrbc_value algorithm = GET_ARG(1); mrbc_value self = mrbc_instance_new(vm, v->cls, sizeof(mbedtls_md_context_t)); mbedtls_md_context_t *ctx = (mbedtls_md_context_t *)self.instance->data; mbedtls_md_init(ctx); const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( c_mbedtls_digest_algorithm_name(mrbc_integer(algorithm)) ); int ret; ret = mbedtls_md_setup(ctx, md_info, 0); // error check ret = mbedtls_md_starts(ctx); // error check SET_RETURN(self); } picoruby/mrbgems/picoruby-mbedtls/src/digest.c 32

It reduces s...")
significantly cf. PlayStation 3's code signing key leak (ECDSA) We need a Random Number Generator But do we have /dev/random ... No! We use the Ring Oscillator (ROSC) to extract random bits You can use this through the RNG gem 35

/datasheets.raspberrypi.com/rp2040/rp20...")

")

Networking
39
")

The cyw43_driver and lwI...")
and these are handled in two different modes: pico_cyw43_arch_lwip_poll The program polls the WiFi driver periodically to call callbacks and move data pico_cyw43_arch_lwip_threadsafe_background (used here) Handling of the WiFi driver and TCP/IP stack is handled in the background, and is multi-core/thread/task safe. 44

CYW43.init('JP')
CYW43.enable_s...")

ip_addr_t *result = (ip_addr_t *)arg; if (ip) { ip4_addr_copy(*result, *ip); } else { ip4_addr_set_loopback(result); } return; } err_t get_ip_impl(const char *name, ip_addr_t *ip) { cyw43_arch_lwip_begin(); err_t err = dns_gethostbyname(name, ip, dns_found, ip); cyw43_arch_lwip_end(); return err; } picoruby/mrbgems/picoruby-net/ports/rp2040/net.c 48

")

err) { tcp_connection_state *cs = (tcp_connection_state *)arg; if (pbuf != NULL) { char *tmpbuf = mrbc_alloc(cs->vm, pbuf->tot_len + 1); struct pbuf *current_pbuf = pbuf; int offset = 0; while (current_pbuf != NULL) { pbuf_copy_partial(current_pbuf, tmpbuf + offset, current_pbuf->len, 0); offset += current_pbuf->len; current_pbuf = current_pbuf->next; } tmpbuf[pbuf->tot_len] = '\0'; mrbc_string_append_cbuf(cs->recv_data, tmpbuf, pbuf->tot_len); mrbc_free(cs->vm, tmpbuf); altcp_recved(pcb, pbuf->tot_len); cs->state = NET_TCP_STATE_PACKET_RECVED; pbuf_free(pbuf); } else { cs->state = NET_TCP_STATE_FINISHED; } return ERR_OK; } picoruby/mrbgems/picoruby-net/ports/rp2040/net.c 53

bool is_tls) { ip_addr_t ip; mrbc_value ret; get_ip(host, &ip); if(!ip4_addr_isloopback(&ip)) { char ip_str[16]; ipaddr_ntoa_r(&ip, ip_str, 16); mrbc_value recv_data = mrbc_string_new(vm, NULL, 0); tcp_connection_state *cs = TCPClient_connect_impl(&ip, host, port, send_data, &recv_data, vm, is_tls); while(TCPClient_poll_impl(&cs)) { sleep_ms(200); } // recv_data is ready after connection is complete ret = recv_data; } else { ret = mrbc_nil_value(); } return ret; } picoruby/mrbgems/picoruby-net/ports/rp2040/net.c 54

If the PCB is ...")
TLS PCB: When you send data, after TCP sending functions are called, TLS callbacks will be called to encrypt data When you receive data, TLS callbacks will be called to decrypt data, then the TCP callbacks will be called As such, cryptography implemented in Part 1 is not used here. 57

I skipped over...")
many things for brevity, such as (but not limited to): Hardware driver's "periodic servicing" part How to read data and load it onto memory, and such TCP handshake, TLS handshake Sending/Receiving large chunks of data Short story: Don't do it. 60

")

Possible Future Work
62
")

")

67
")

68
")

Symmetric crypto is ...")
but asymmetric crypto is very slow Performance numbers from similar environments: STM32L562E Cortex-M33 at 110 MHz, wolfSSL RSA 2048 Signing: 9.208 ops/sec RSA 2048 Verification: 0.155 ops/sec ECDHE 256 Key agreement: 0.661 ops/sec 72

Also, without a trus...")
store, we will get encryption through TLS, but we will not get the authentication part of TLS. For these reasons, depending on your security needs, it would be enough to just use symmetric crypto between the gateway and use TLS from there. Note that your WiFi password exists in your Pico to connect! 73

these devices work in co...")

79
")

Twitter: @s01 or Fediver...")