nihalpasham / rustdhipv2

A prototype implementation of the Host Identity Protocol v2 for bare-metal systems, written in pure-rust.
MIT License
37 stars 7 forks source link

Host Identity Protocol for bare-metal systems, using Rust

I've been evaluating TLS replacements in constrained environments for a while now. Embedded systems have fewer (yet precise) security requirements, owing to available resources or by design.

Embedded systems, unlike people dont need to talk to every other machine on the planet. They are designed to perform a specific set of functions. Functions that most likely require them to communicate with other machines.

The key point here is that the vast majority of embedded systems communicate with a known or predetermined set of peers. However, problem is that clearly identifying a networked machine (and its peers) is a non trivial undertaking, even today.

This repo implements the HIPv2 IETF standard which aims to solve this problem.

Why not TLS:

TLS is not exactly a good fit for a couple of reasons.

What's needed: - a simpler, easy-to-use, lightweight secure channel. A secure channel with just 2 pre-requisites. It must provide any 2 communicating parties the ability to mutually authenticate each other and encrypt all data end-end.

More importantly, both pre-requisites must be the default and not tacked-on.

HIPv2 is an IETF standard [rfc7401] that offers

The neat thing about HIPv2 is that it does NOT operate at the application-layer but rather is a part of a host's networking stack.

Advantages:

A few things to keep in mind if you'd like to contribute:

Note: This is a WIP

I'm a security consultant by profession. This is a first attempt at putting together a full fledged networking-related library. Please be feel free to chime-in if something's amiss.

HIP Overview

One key component that binds networking and security is the concept of an IP address. An IP address provides

This duality of the IP address is why we can't uniquely identify machines across different networks.

An IP address

Yet every piece of networking equipment - from firewalls to access controllers to IoT devices, all rely on an IP for location and identification.

I spent some time understanding the concept of a location-identity split. For starters, HIP is an IETF standard that's been in the making for over 15 years,

This simple change can help us build drastically different networks where secure internetworking is an inherent property of the system.

How it works -

HIP assigns a permanent, location-independent name to a host. HIP names are cryptographic identities that can be used to uniquely identify a host called host identity (it's essentially a public key). As public keys are quite long, usually it is more convenient to use a 128-bit fingerprint of the HI, which is called the Host Identity Tag (HIT). The HIT resembles an IPv6 address, and it gives the host a permanent name.

The Internet Assigned Numbers Authority (IANA) allocated an IPv6 address prefix for HITs (2001:0010::/28)

In HIP, when you call the OS's socket API, transport sockets (TCP/UDP) are bound to HITs rather than IP addresses. The networking stack translates the HITs to IP addresses before packet transmission on the wire. The reverse occurs on the host receiving HIP packets. When the host changes the network, the networking stack changes the IP address for the translation. The application doesn't notice the change because it is using the constant HIT. This is how HIP solves the problem of host mobility (which is a bonus if we were just looking for security).

HIP is a 2 round-trip, end-to-end Diffie-Hellman key-exchange protocol, called base-exchange with mobility updates and some additional messages. The networking stack triggers the base exchange automatically when an application tries to connect to an HIT.

During a base exchange, a client (initiator) and a server (responder) authenticate each other with their public keys and generate symmetric encryption keys. The data flow between them is encrypted by IPsec Encapsulating Security Payload (ESP) with the symmetric key set up by HIP. HIP introduces mechanisms, such as computational puzzles, that protect HIP responders (servers) against DoS attacks. The initiator must solve a computational puzzle. The responder selects the difficulty of the puzzle according to its load. When the responder is busy or under DoS attack, the responder can increase the puzzle difficulty level to delay new connections. Applications simply need to use HITs instead of IP addresses. Application source code does not need to be modified.

We can describe this process as follows:

DNS Lookup
I -->   DNS:   lookup R
I <--   DNS:   return R's address and HI/HIT
Base Exchange
I1 I --> R Hi, Here is my I1, let's talk with HIP
R1 R --> I OK, Here is my R1, solve this HIP puzzle
I2 I --> R Computing, here is my counter I2
R2 R --> I OK. Let's finish base exchange with my R2
Encrypted data
I -->   R (ESP protected data)
R -->   I (ESP protected data)

What's supported so far:

Note: This is a huge monolith for now. I do plan to re-factor this to make it more modular i.e. I'm thinking there should be a separate packet-processing logic block for each of the different packet-types. This should in theory make it easier to use rust's type-system to to enforce state-transition rules aka make invalid states un-representable.

HIP BEX examples:

The examples folder contains 2 examples

You can test these examples via the cargo run command. But before you do, you'll need to add a bridge and 2 tap interfaces. You can do this via the following commands

ip tuntap add name tap0 mode tap user {$USER}
ip tuntap add name tap1 mode tap user {$USER}
brctl addbr br0
brctl addif br0 tap0 tap1 
ip link set tap0 up
ip link set tap1 up
ip link set br0 up

check to see if everything's working via an ifconfig call. Once done, run the following in separate terminals.

This should produce initiator and responder logs. Reference logs are available in the logs folder.

If you're using VSCode, pull up the task-list and run the bridge tap interfaces task. This should run the above commands and set you up.

Conclusion: Identity based networking

We can now design networks where devices talk to each other without having to navigate the complex landscape of network security.

References