Skip to content

Commit 0fcce1d

Browse files
committed
rpifwcrypto: Initial revision
Client side library and application for the Raspberry Pi firmware cryptography service. The firmware mailbox based crypto service provides limited support for cryptographic operations using a ECDSA P-256 stored in OTP (using rpi-otp-private-key). The current operations are * Get number of OTP keys * Get status for key * Set status for a key (runtime lock) * ECDSA SHA256 signature * HMAC SHA256 (max message size 2KB) e.g. LUKS passphrase = HMAC(device-unique-ley, serial64 + EMMC CID) rpifwcrypto is a command line application designed to allow the crypto operations to be easily used in shell scripts. rpifwcrypto.h provides a library interface so that this can be embedded in other applications. Direct usage of mailbox API (vcmailbox) is not recommended because this is a new feature and the mailbox API is not frozen.
1 parent b7651d8 commit 0fcce1d

File tree

7 files changed

+873
-1
lines changed

7 files changed

+873
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ add_subdirectory(raspinfo)
1515
add_subdirectory(vcgencmd)
1616
add_subdirectory(vclog)
1717
add_subdirectory(vcmailbox)
18+
add_subdirectory(rpifwcrypto)

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ A collection of scripts and simple applications
1818
* [piolib](piolib/) - A library for accessing the Pi 5's PIO hardware.
1919
* [raspinfo](raspinfo/) - A short script to dump information about the Pi. Intended for
2020
the submission of bug reports.
21+
* [rpifwcrypto](rpifwcrypto/) - A command line application and shared library for the
22+
firmware cryptography service. Intended for use with Raspberry Pi Connect and
23+
secure-boot provisioner.
2124
* [vclog](vclog/) - A tool to get VideoCore 'assert' or 'msg' logs
2225
with optional -f to wait for new logs to arrive.
2326

2427

2528
**Build Instructions**
2629

27-
Install the prerequisites with "sudo apt install cmake device-tree-compiler libfdt-dev" - you need at least version 3.10 of cmake. Run the following commands to build and install everything, or see the README files in the subdirectories to just build utilities individually:
30+
Install the prerequisites with "sudo apt install cmake device-tree-compiler libfdt-dev libgnutls28-dev" - you need at least version 3.10 of cmake. Run the following commands to build and install everything, or see the README files in the subdirectories to just build utilities individually:
2831

2932
- *cmake .*
3033
N.B. Use *cmake -DBUILD_SHARED_LIBS=1 .* to build the libraries in the subprojects (libdtovl, gpiolib and piolib) as shared (as opposed to static) libraries.

rpifwcrypto/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cmake_minimum_required(VERSION 3.10...3.27)
2+
include(GNUInstallDirs)
3+
4+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")
5+
6+
# Set project name
7+
project(rpifwcrypto)
8+
9+
# Find GnuTLS package
10+
find_package(GnuTLS REQUIRED)
11+
12+
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
13+
14+
# Create the shared library
15+
add_library(rpifwcrypto rpifwcrypto.c)
16+
target_sources(rpifwcrypto PUBLIC rpifwcrypto.h)
17+
set_target_properties(rpifwcrypto PROPERTIES PUBLIC_HEADER rpifwcrypto.h)
18+
set_target_properties(rpifwcrypto PROPERTIES SOVERSION 0)
19+
20+
# Create the executable
21+
add_executable(rpi-fw-crypto main.c)
22+
target_link_libraries(rpi-fw-crypto rpifwcrypto ${GNUTLS_LIBRARIES})
23+
target_include_directories(rpi-fw-crypto PRIVATE ${GNUTLS_INCLUDE_DIRS})
24+
25+
# Install rules
26+
install(TARGETS rpi-fw-crypto RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
27+
install(TARGETS rpifwcrypto
28+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
29+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

rpifwcrypto/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
# rpifwcrypto
3+
4+
The Raspberry Pi Firmware Cryptography service is a mailbox based API
5+
that allows a limited set of cryptographic operations to be performed
6+
by the firmware without exposing private keys to userspace.
7+
8+
The initial implementation is designed to support PiConnect and
9+
provides an ECDSA P-256 SHA256 signature API.
10+
11+
A SHA256 HMAC API is provided to provide basic support for derived keys
12+
instead of using the raw device unique private key
13+
e.g. HMAC(serial-number + EMMC CID) could be used for a LUKS passphrase.
14+
15+
Although this service can be used via raw vcmailbox commands the
16+
recommended API is either the command line rpi-fw-crypto application
17+
or the librpifwcrypto.so shared library.
18+
19+
**Build Instructions**
20+
Install prerequisites with "sudo apt install cmake libgnutls28-dev"" - you need at least version 3.10.
21+
22+
- *mkdir build*
23+
- *cd build*
24+
- *cmake ..*
25+
- *make*
26+
- *sudo make install*
27+
28+
**Usage**
29+
30+
* rpi-fw-crypto -h (Displays usage instructions for all operations)
31+
* rpi-fw-crypto get-num-otp-keys (Returns the number of OTP key slots)
32+
* rpi-fw-crypto sign --in message.bin --key-id 1 --alg ec --out sig.bin (Signs message.bin with the device unique OTP key (id 1))
33+
* rpi-fw-crypto get-key-status 1 (Gets the status of key-id 1)
34+
* rpi-fw-crypto set-key-status 1 LOCKED (Blocks the raw OTP read API on this key until the device is rebooted)
35+
* rpi-fw-crypto hmac --in message.bin --key-id 1 --out hmac.bin (Generates the SHA256 HMAC of message.bin and OTP key id 1)
36+
37+
** Notes **
38+
The device unique private key can be provisioned with the `rpi-otp-private-key` utility.
39+
This MUST be a raw ECDSA P-256 key and not just a random number.
40+
41+
This service is not a hardware security module and the current implementation
42+
does not protect the key and/or OTP from being accessed directly with root level privileges.
43+
It just removes the need to expose the key to userspace (e.g. initramfs) scripts.

0 commit comments

Comments
 (0)