Skip to content

Commit 2691bc7

Browse files
committed
🐢 TurtlPass Firmware
0 parents  commit 2691bc7

26 files changed

+3208
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.DS_Store
2+
/.idea
3+
/build
4+
/app/build
5+
/.gradle
6+
/local.properties
7+
/app/plugins/internal/build/
8+
/app/plugins/internal/.gradle/
9+
/turtlpass-firmware/Seed.cpp

LICENSE

Lines changed: 673 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<p align="center">
2+
<img src="assets/icon.png" alt="logo" width=90>
3+
<h3 align="center">TurtlPass Firmware</h3>
4+
<p align="center">
5+
TurtlPass Firmware provides a simple and secure way of generating passwords using a deterministic key derivation function (HKDF) as specified in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.</p>
6+
<p align="center">
7+
<a href="https://github.com/TurtlPass/turtlpass-firmware-arduino/releases"><img src="https://img.shields.io/badge/Arduino%20Firmware-v1.0.0-green?logo=arduino" alt="Releases"/></a>
8+
</p>
9+
<p align="center">
10+
<a href="https://github.com/TurtlPass/turtlpass-android"><img src="https://img.shields.io/badge/Android%20App-v1.0.0-blue?logo=android" alt="Android Repo"/></a>
11+
<a href="https://github.com/TurtlPass/turtlpass-chrome-extension"><img src="https://img.shields.io/badge/Chrome%20Extension-v1.0.0-blue?logo=googlechrome" alt="Chrome Extension Repo"/></a>
12+
</p>
13+
14+
15+
## ⚡ Features
16+
17+
* Generates unique, secure passwords from a simple input hash
18+
* 100 characters long, including a combination of lowercase and uppercase letters, as well as numbers
19+
* Uses a seed stored in flash memory for added security
20+
* Automatically types the password for you, so you don't have to
21+
* Erases the password from memory after use, for extra peace of mind
22+
* Easy to integrate into your existing projects with USB serial port connectivity
23+
24+
25+
## 🏗️ Hardware
26+
27+
<img src="assets/rpi-picos.jpg" width="100%">
28+
29+
1. **Raspberry Pi Pico**
30+
2. **OTG Cable**: micro-USB (male) to USB-C (male)
31+
3. **Cover/Case** (optional)
32+
33+
34+
## 💡 LED State
35+
36+
* `ON`
37+
* Operational (default)
38+
* `PULSING`
39+
* Password ready to type
40+
* `BLINKING`
41+
* Typing... (fast blink)
42+
* `OFF`
43+
* No power input
44+
45+
46+
## 🔧 Generate your own seed
47+
48+
1. Run the bash script `./generate_seed_file.sh` to generate a new seed file `Seed.cpp.<timestamp>` on a computer with macOS or Linux.
49+
50+
2. Rename the generated file to `Seed.cpp`.
51+
52+
53+
## ⬆️ Upload sketch
54+
55+
56+
1. Open `turtlpass-firmware.ino` with Arduino IDE on a computer.
57+
58+
> If the first time, select the appropriate **Board** and **Serial Port** in the Arduino menu `Tools`.
59+
60+
2. Connect the Raspberry Pico to a computer with a micro-USB to USB-C cable.
61+
62+
> To upload your first sketch, you will need to hold the `BOOTSEL` button down while plugging in the Pico to a computer.
63+
64+
3. Click in the `Upload` icon to upload the sketch to the Pico
65+
66+
4. The sketch should be transferred and start to run.
67+
68+
69+
## 🐞 Debugging
70+
71+
1. Open the **Serial Monitor** console
72+
> Settings: `Newline` and `115200` baud rate
73+
74+
2. Type, for example, `/0` and send it
75+
76+
3. You should get a response saying `OK` and the LED should be `PULSING`
77+
78+
4. Now press the button on Pico and the password should be typed (wherever the focus is on)
79+
80+
81+
## 🛡️ Security
82+
83+
As a precaution, it is crucial to note that an individual with physical access to the device may potentially be able to compromise it, given sufficient time and effort.
84+
85+
<details>
86+
<summary>Raspberry Pi Pico</summary>
87+
88+
While the [Raspberry Pi Pico](https://thepihut.com/products/raspberry-pi-pico) (RP2040) is a useful device for development, it is not recommended for use in production settings. Due to the external ROM it utilizes, it is relatively easy to extract the firmware binary using [picotool](https://github.com/raspberrypi/picotool), making it challenging to protect against unauthorized access.
89+
90+
Example on how to do just that:
91+
92+
```
93+
$ picotool save firmware.uf2
94+
Saving file: [==============================] 100%
95+
Wrote 369000 bytes to firmware.uf2
96+
```
97+
</details>
98+
99+
<details>
100+
<summary>Arduino RP2040 Connect</summary>
101+
102+
The [Arduino RP2040 Connect](https://thepihut.com/products/arduino-nano-rp2040-connect) features the **ATECC608A Cryptographic Co-processor** that includes hardware storage for cryptographic keys however to access certain features on this chip we need to contact Microchip and sign an NDA contract.</details>
103+
104+
<details>
105+
<summary>Other devices</summary>
106+
107+
I am continuously exploring and evaluating new hardware options for this project. As more information and resources become available, I will keep you updated on my progress.
108+
</details>
109+
110+
111+
## 📚 Libraries
112+
113+
* [Raspberry Pi Pico Arduino core](https://github.com/earlephilhower/arduino-pico)
114+
* Port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem.
115+
* It uses the bare Raspberry Pi Pico SDK and a custom GCC 10.3/Newlib 4.0 toolchain.
116+
* _LGPL 2.1 license_
117+
* [Arduino Cryptography Library](https://github.com/rweather/arduinolibs)
118+
* Libraries to perform cryptography operations on Arduino devices
119+
* _MIT license_
120+
* [Keyboard Library for Arduino](https://github.com/arduino-libraries/Keyboard)
121+
* Library allows an Arduino board with USB capabilities to act as a keyboard
122+
* _LGPL 3.0 license_
123+
124+
125+
## 📄 License
126+
127+
TurtlPass Firmware is released under the [GPL 3.0 license](https://github.com/TurtlPass/turtlpass-firmware-arduino/blob/main/LICENSE).

assets/icon.png

29.8 KB
Loading

assets/rpi-picos.jpg

259 KB
Loading

generate_seed_file.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
# chmod +x generate_seed_file.sh
3+
4+
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
5+
echo ">>> Generating Seed.cpp file"
6+
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
7+
8+
# Generate a new private key
9+
openssl genrsa -out seed.tmp 4096
10+
11+
# Skip the first and last line of the private key file
12+
TOTAL_LINES=$(wc -l seed.tmp | awk '{print $1}')
13+
14+
# Store the output of the tail and head commands in the SEED variable
15+
SEED=$(tail -n +2 seed.tmp | head -n $((TOTAL_LINES - 2)))
16+
17+
# Create the timestamp
18+
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
19+
20+
# Create the output file
21+
FILE_NAME="turtlpass-firmware/Seed.cpp.${TIMESTAMP}"
22+
touch "$FILE_NAME"
23+
24+
# Write the contents of the file
25+
cat > "$FILE_NAME" << EOF
26+
#include "Seed.h"
27+
28+
const char* seed PROGMEM = R"key(
29+
$SEED
30+
)key";
31+
EOF
32+
33+
# Clean up
34+
rm seed.tmp
35+
36+
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
37+
echo "$SEED"
38+
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
39+
echo ">>> Generated file: $FILE_NAME"
40+
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
41+
echo "Done"

turtlpass-firmware/Crypto/Crypto.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included
12+
* in all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#include "Crypto.h"
24+
25+
/**
26+
* \brief Cleans a block of bytes.
27+
*
28+
* \param dest The destination block to be cleaned.
29+
* \param size The size of the destination to be cleaned in bytes.
30+
*
31+
* Unlike memset(), this function attempts to prevent the compiler
32+
* from optimizing away the clear on a memory buffer.
33+
*/
34+
void clean(void *dest, size_t size)
35+
{
36+
// Force the use of volatile so that we actually clear the memory.
37+
// Otherwise the compiler might optimise the entire contents of this
38+
// function away, which will not be secure.
39+
volatile uint8_t *d = (volatile uint8_t *)dest;
40+
while (size > 0) {
41+
*d++ = 0;
42+
--size;
43+
}
44+
}
45+
46+
/**
47+
* \fn void clean(T &var)
48+
* \brief Template function that cleans a variable.
49+
*
50+
* \param var A reference to the variable to clean.
51+
*
52+
* The variable will be cleared to all-zeroes in a secure manner.
53+
* Unlike memset(), this function attempts to prevent the compiler
54+
* from optimizing away the variable clear.
55+
*/
56+
57+
/**
58+
* \brief Compares two memory blocks for equality.
59+
*
60+
* \param data1 Points to the first memory block.
61+
* \param data2 Points to the second memory block.
62+
* \param len The size of the memory blocks in bytes.
63+
*
64+
* Unlike memcmp(), this function attempts to compare the two memory blocks
65+
* in a way that will not reveal the contents in the instruction timing.
66+
* In particular, this function will not stop early if a byte is different.
67+
* It will instead continue onto the end of the array.
68+
*/
69+
bool secure_compare(const void *data1, const void *data2, size_t len)
70+
{
71+
uint8_t result = 0;
72+
const uint8_t *d1 = (const uint8_t *)data1;
73+
const uint8_t *d2 = (const uint8_t *)data2;
74+
while (len > 0) {
75+
result |= (*d1++ ^ *d2++);
76+
--len;
77+
}
78+
return (bool)((((uint16_t)0x0100) - result) >> 8);
79+
}
80+
81+
/**
82+
* \brief Calculates the CRC-8 value over an array in memory.
83+
*
84+
* \param tag Starting tag to distinguish this calculation.
85+
* \param data The data to checksum.
86+
* \param size The number of bytes to checksum.
87+
* \return The CRC-8 value over the data.
88+
*
89+
* This function does not provide any real security. It is a simple
90+
* check that seed values have been initialized within EEPROM or Flash.
91+
* If the CRC-8 check fails, then it is assumed that the EEPROM/Flash
92+
* contents are invalid and should be re-initialized.
93+
*
94+
* Reference: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html#ch4
95+
*/
96+
uint8_t crypto_crc8(uint8_t tag, const void *data, unsigned size)
97+
{
98+
const uint8_t *d = (const uint8_t *)data;
99+
uint8_t crc = 0xFF ^ tag;
100+
uint8_t bit;
101+
while (size > 0) {
102+
crc ^= *d++;
103+
for (bit = 0; bit < 8; ++bit) {
104+
// if (crc & 0x80)
105+
// crc = (crc << 1) ^ 0x1D;
106+
// else
107+
// crc = (crc << 1);
108+
uint8_t generator = (uint8_t)((((int8_t)crc) >> 7) & 0x1D);
109+
crc = (crc << 1) ^ generator;
110+
}
111+
--size;
112+
}
113+
return crc;
114+
}

turtlpass-firmware/Crypto/Crypto.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included
12+
* in all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#ifndef CRYPTO_h
24+
#define CRYPTO_h
25+
26+
#include <inttypes.h>
27+
#include <stddef.h>
28+
29+
void clean(void *dest, size_t size);
30+
31+
template <typename T>
32+
inline void clean(T &var)
33+
{
34+
clean(&var, sizeof(T));
35+
}
36+
37+
bool secure_compare(const void *data1, const void *data2, size_t len);
38+
39+
#if defined(ESP8266)
40+
extern "C" void system_soft_wdt_feed(void);
41+
#define crypto_feed_watchdog() system_soft_wdt_feed()
42+
#else
43+
#define crypto_feed_watchdog() do { ; } while (0)
44+
#endif
45+
46+
#endif

0 commit comments

Comments
 (0)