Introduction: The Black Swan Project

About: Hi, my name is Max. I'm a self-proclaimed Embedded Systems Engineer. I like making convenient devices. I know that nothing is perfect, but some things are far better than the others, for that reason I'm provid…

The Black Swan Project is an ESP8266-based, secure, one-way communication channel.

It might be superfluous in the current conditions. But let's suppose that a black swan event occured, causing the nationwide blackout, complete failure of the mobile network, or other unpleasant consequences.

It might seem like all electronic means of communication have disappeared (maybe except for radios and Bluetooth). Well, not all.

Don't get me wrong, I'm not trying to tell you that this device will immediately fix the situation and bring the paradise to the earth, but at least it can be "a beam of hope in the sea of darkness," at least you will be able to text your neigbhor.

In addition to that, this device utilizes a cryptographically strong encryption algorithm that is resistant to both eavesdroping and tampering.

Once set up, this device can work completely autonomously, without a need to ever be connected to the computer.

Supplies

Supplies for the transmitter:

  • ESP8266 x1
  • 1.77 Inch TFT LCD with ST7735 x1
  • Arduino Nano/Uno/Compatible board x1
  • PS/2 Keyboard x1
  • PS/2 Port x1
  • 580 ohm resistor x1

Supplies for the receiver:

  • ESP8266 x1
  • Nokia 5110 display x1

Step 1: Encryption Algorithm

Let's start with the fact that the encryption algorithm utilized by this device is symmetric. It means that the same key is used to both encrypt and decrypt the data. So whether I refer to the key - I refer to both encryption and decryption keys.

I did my best to ensure that the data that's being sent over the air can't be decrypted or modified by a third party. Even if the third party gets a chance to capture the package and resend it later (perform the replay attack) while being able to look at the screen of the receiver (without having access to the device's memory) - the device won't decrypt the captured package, because IVs have already changed.

When it comes to implementing the chosen-plaintext attack, good luck with that too. Even if you encrypt the same plaintext multiple times, you'll get different ciphertexts every time. To achieve that, I've combined three cryptographically strong encryption algorithms with Rijndael S-boxes and four initialization vectors.

Ok, let's split the encryption algorithm into its constitutes to make it easier for you to understand.

  • 3DES (which is a cascaded encryption algorithm by itself), AES-256, and Serpent are well-known encryption algorithms. Just google any of them, and you'll find a lot of information on each of them.
  • Rijndael (AES) S-box is a part of the AES. I just utilized it as a separate element. The purpose of it is to increase the entropy of the ciphertext.
  • The initialization vector (IV) is a number that is used in both the encryption and decryption process. Its primary purpose - is to eliminate the possibility of a replay attack. Other than that, IV "kinda" serves as a part of the key.
  • XOR. Just google it.

The encryption process goes as follows:

1) Plaintext is split into the 64-bit - long (8 chars.) blocks, if the block length is less than 64 bits, then the padding is applied. Blocks are then passed to the encryption algorithm that begins on the step N2 one after another (first come first served);

2) The block is split into the eight equal parts;

3) Each part is passed through the forward Rijndael S-box;

4) The eight outputs from the s-boxes are "glued together" and XORed with the first IV;

5) The 64-bit value taken from the previous step is encrypted with 3DES;

6) Then the value produced by the 3DES is split into 8 equal parts (8 bits each), and goes through the eight s-boxes;

7) The eight outputs from the s-boxes taken from the previous step are "glued together" and XORed with the second IV;

8) Now, 64 random bits are concatenated to the 64 bits from the previous step;

9) The resulted 128-bit value is encrypted with AES-256;

10) The value produced by the AES-256 is split into two 64 bit halves;

11) Left half of the value produced by the AES-256 is XORed with the third IV, while the right half of the value produced by the AES-256 is XORed with the fourth IV;

12) 64 random bits are concatenated to each half XORed with IV, therefore making two 128 bit values;

13) Each 128-bit value is encrypted Serpent;

14) The values produced by the Serpent are simultaneously sent to the receiver;

15) Increment the AES and 3DES keys, and increment IVs. If it's not the last block, then get back to step N2 and give the encryption algorithm the next block.

Step 2: Install Drivers and Configure Arduino IDE *Optional

If you've never flashed ESP8266 before you'll need to configure Arduino IDE and install drivers to upload the firmware to the boards, you can find drivers here:

CH340 driver: https://sparks.gogo.co.nz/ch340.html

CP210x driver: https://www.silabs.com/developers/usb-to-uart-brid...

In case you don't have Arduino IDE, you can download it here:

https://www.arduino.cc/en/software/

Configuring IDE isn't a part of this tutorial, you can read about it here:

https://randomnerdtutorials.com/how-to-install-esp...

Step 3: Download Firmware From GitHub

You can download firmware here: https://github.com/Northstrix/Black_Swan

Step 4: Download and Install the Libraries

ESP8266TrueRandom: https://github.com/marvinroger/ESP8266TrueRandom

Adafruit-ST7735-Library: https://github.com/adafruit/Adafruit-ST7735-Librar...

Adafruit-GFX-Library: https://github.com/adafruit/Adafruit-GFX-Library

Adafruit_BusIO: https://github.com/adafruit/Adafruit_BusIO

DES_Library : https://github.com/fcgdam/DES_Library

nokia-5110-lcd-library: https://github.com/platisd/nokia-5110-lcd-library

PS2Keyboard: https://github.com/PaulStoffregen/PS2Keyboard

The process of unpacking libraries is typical. You can unpack the content of the archive into the folder: ...\Arduino\libraries. Or open the Arduino IDE, click to the Sketch -> Include Library -> Add .ZIP Library... and select every archive with libraries.

Other required libraries are already present in one way or another.

Step 5: Generate the Five 8-digit Numbers

This device requires five 8-digit numbers to function, four IVs, and one initialization number.

You can generate the numbers by any means possible. I've decided to throw 20-sided dice. The algorithm is simple: after throwing the dice, write down the last digit if you got a double-digit number, and just write the number down if it's a single-digit number.

Eventually, I've generated these 8-digit numbers:

46201651

60523847

13453694

31216946

40282533


The maximum value of the number is 99 999 999. If you've generated something more than 92 000 000, I would advise you to either change the first digit or generate the new IV. I would also advise you to avoid using "0" as the first digit of any of these numbers.

Step 6: Upload the Newly Generated Numbers Into Both ESPs

Open the sketch called "Set_IVs" and replace all five numbers in the sketch with the ones you've generated.

After that, upload the modified sketch into both ESPs.

If everything went right, you should see the IVs in the Serial Monitor.

Step 7: Get the Receiver's MAC Address

To get the receiver's MAC address, upload this code into the ESP8266 that you're going to use to receive the data.

#include <ESP8266WiFi.h>

void setup(){
Serial.begin(115200);
Serial.println();
Serial.println(WiFi.macAddress());
}

void loop(){

}

Then open the Serial Monitor, and reboot the board.

If done correctly, you should see the MAC address in the console.

The MAC address of this board is 5C:CF:7F:FD:85:1D

Step 8: Generate Keys

In my opinion, throwing dice, as time-consuming as it can be, is one of the best options to generate the keys. But I've also left a quicker option for you. I modified one of my previous projects to work as a random number generator. The resulted output seems "random enough" for me, but I haven't run any tests. So, I can't guarantee that it's random.

Use it at your own risk.

To generate the keys - launch gen.exe from the Untested RNG folder, and then click the "Generate keys for the Black Swan project" button.

Step 9: Modify the Firmware

Open the files Firmware_for_the_transmitter.ino and Firmware_for_the_receiver.ino and then replace my keys with those you've generated.

Make sure that the keys are the same in both sketches.

Don't forget to replace the receiver's MAC address in the line

uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0xFD, 0x85, 0x1D}; // Receiver's MAC address

in the file: Firmware_for_the_transmitter.ino

Step 10: Flash the Arduino

Upload the firmware from the folder Firmware_for_the_Arduino into the Arduino.

Step 11: Flash the Transmitter Board

Upload the firmware from the folder Firmware_for_the_transmitter into the transmitter board.

Step 12: Flash the Receiver Board

Upload the firmware from the folder Firmware_for_the_receiver into the receiver board.

Step 13: Assemble the Transmitter

Assembling the transmitter shouldn't be hard. In my opinion, the most tangled part of it is to connect the PS/2 port in the right way.

Step 14: Circuit Diagram for the Transmitter

Step 15: Assemble the Receiver

The receiver is even easier to assemble. Just connect the Nokia 5110 display to the ESP8266.

Note that some versions of this display require the BL pin to be connected to the 3.3V.

Step 16: Circuit Diagram for the Receiver

Step 17: Test the Deive

Ok, It's time to test this device.

Power up the receiver first, It's important.

The receiver requires a key setup and IV adjustment every time it's powered up. I did that to make the device more secure and to make sure that two blocks will never be encrypted with the same key (if you consider IV as a part of the key).

Let me explain how it works. After being powered up, the receiver waits for the initialization package that contains the so-called "initialization number." After being powered up, the transmitter sends the initialization package to the receiver. The receiver then decrypts the initialization package and extracts the value of the "initialization number" from it. If the value of the received "initialization number" is more than the value of the "initialization number" that's stored in the receiver's memory, but no more than the value of the "initialization number" + 5000, then this number is accepted and used in the key setup and IV adjustment processes, otherwise, the receiver will throw this error: "Failed to set up secure communication channel. Reboot the device and try again." Hopefully, that was clear enough for the most basic understanding of the initial setup.

Anyway, if you have any questions don't hesitate to ask them in the comment section.

After powering the receiver up, you should see the inscription "Waiting for the initialization package to arrive."

Now, power up the transmitter. You should see the inscription "Keys and IVs set up successfully."

To send a text to the receiver - type it on the keyboard connected to the transmitter, and press the "Enter" button. If you want to send the text from the Serial Monitor, press the "Tab" button on the keyboard connected to the transmitter.

The receiver also prints all received data into the Serial Monitor.

Step 18: Final Thoughts

I did my best to make the black swan as unhackable as possible.

Performing a brute force attack on this device is infeasible because there are 2^936 possible key combinations (maybe a bit less if you take into account that IVs only have numbers from 0 to 9), and when it comes to the not-so barbaric attacks, like chosen plaintext and replay attacks, I wouldn't be worrying about them too, because the encryption algorithm is resistant to these kinds of things.

Now, let's get to the sad part, the distance between both ESPs can barely reach 650 feet (200 meters), and the so-called "unhackability" of the encryption algorithm doesn't mean that the device can't be hacked by other means. If a third party gets one of the devices into its physical possession or obtains the firmware of one of the ESPs, it might be able to eavesdrop on you, or even tamper with the data that's being sent.

While the first case is obvious, the second one might need a better explanation. If the computer that you've used to modify the firmware and/or upload the firmware into the ESPs is compromised in any way, someone from the other side of the screen can obtain the keys and IVs that you've uploaded into the ESPs and later on use it against you. Beware of it! On that note, I would like to finish this tutorial.

I hope you will find a good use for this device.

If you like this tutorial, please share it.

Thank you for reading this tutorial.