Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Build-Depends: debhelper-compat (= 13),
libgpiod-dev,
libcryptsetup-dev [!nocryptsetup],
librpifwcrypto-dev,
libblockdeviceid-dev,
git
Standards-Version: 4.7.2
Homepage: https://www.raspberrypi.com/
Expand All @@ -38,7 +39,8 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
xxd,
raspi-utils-core,
kpartx,
librpifwcrypto0
librpifwcrypto0,
libblockdeviceid1
Suggests: net-tools,
iproute2,
gpiod,
Expand Down
3 changes: 3 additions & 0 deletions fastboot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pkg_check_modules(FDISK REQUIRED fdisk)
pkg_check_modules(URING REQUIRED liburing)
pkg_check_modules(SYSTEMD REQUIRED libsystemd)
find_package(rpifwcrypto REQUIRED)
find_package(blockdeviceid REQUIRED)

# GPIO control via libgpiod (optional - falls back to command if not available)
pkg_check_modules(GPIOD libgpiod)
Expand Down Expand Up @@ -101,6 +102,7 @@ target_include_directories(fastbootd PRIVATE
${GPIOD_INCLUDE_DIRS}
${CRYPTSETUP_INCLUDE_DIRS}
${RPIFWCRYPTO_INCLUDE_DIRS}
${BLOCKDEVICEID_INCLUDE_DIRS}
${CMAKE_CURRENT_LIST_DIR}/../rpiparted/include
)

Expand All @@ -114,6 +116,7 @@ target_link_libraries(fastbootd PRIVATE
${GPIOD_LIBRARIES}
${CRYPTSETUP_LIBRARIES}
${RPIFWCRYPTO_LIBRARIES}
${BLOCKDEVICEID_LIBRARIES}
OpenSSL::Crypto
asyncio
cutils
Expand Down
68 changes: 12 additions & 56 deletions fastboot/device/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
// librpifwcrypto
#include <rpifwcrypto.h>

// libblockdevicedid
extern "C" {
#include <block_device_id.h>
}

#include <openssl/evp.h>

#include <iostream>
Expand Down Expand Up @@ -223,62 +228,13 @@ static bool pathExists(const std::string& path) {
}

static std::string getDeviceId(const std::string& block_device) {
std::string device = block_device;
if (device.find("/dev/") == 0) {
device = device.substr(5);
}

// Extract base device name (remove partition)
std::string base_device = device;
if (device.find("mmcblk") != std::string::npos) {
size_t p_pos = device.find("p");
if (p_pos != std::string::npos) {
base_device = device.substr(0, p_pos);
}
} else if (device.find("nvme") != std::string::npos) {
size_t p_pos = device.find_last_of("p");
if (p_pos != std::string::npos) {
base_device = device.substr(0, p_pos);
}
} else {
// SATA/SCSI: sda1 -> sda
while (!base_device.empty() && std::isdigit(base_device.back())) {
base_device.pop_back();
}
}

std::string sys_block_path = "/sys/class/block/" + base_device;

// Try MMC/SD Card CID first
std::string device_id = readSysFile(sys_block_path + "/device/cid");
if (!device_id.empty()) {
return device_id;
}

// Try NVMe EUI
device_id = readSysFile(sys_block_path + "/eui");
if (!device_id.empty()) {
return device_id;
}

// Try device serial
device_id = readSysFile(sys_block_path + "/device/serial");
if (!device_id.empty()) {
return device_id;
}

// Check if this is a USB device - return error
if (pathExists(sys_block_path + "/device")) {
char resolved_path[PATH_MAX];
std::string device_link = sys_block_path + "/device";
if (realpath(device_link.c_str(), resolved_path) != nullptr) {
std::string device_path = resolved_path;
if (device_path.find("/usb") != std::string::npos) {
return "ERROR_USB_NOT_SUPPORTED";
}
}
}

char id[256];
int ret;

ret = bdi_get_id(block_device.c_str(), id, sizeof(id));
if (!ret)
return std::string(id);

return "";
}

Expand Down
3 changes: 2 additions & 1 deletion rpiidp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ if(IDP_FASTBOOT)
set_property(TARGET rpiidp PROPERTY CXX_STANDARD 23)
set_property(TARGET rpiidp PROPERTY CXX_STANDARD_REQUIRED ON)
find_package(rpifwcrypto REQUIRED)
find_package(blockdeviceid REQUIRED)
target_include_directories(rpiidp PRIVATE /usr/include/android ${CMAKE_SOURCE_DIR}/fastboot)
target_include_directories(rpiidp PRIVATE ${CMAKE_SOURCE_DIR}/rpiparted/include)
target_link_libraries(rpiidp PUBLIC ${RPIFWCRYPTO_LIBRARIES})
target_link_libraries(rpiidp PUBLIC ${RPIFWCRYPTO_LIBRARIES} ${BLOCKDEVICEID_LIBRARIES})
else()
add_subdirectory(../rpiparted rpiparted)
endif()
Expand Down
63 changes: 9 additions & 54 deletions rpiidp/src/crypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include "device/utility.h"
#endif

extern "C" {
#include <block_device_id.h>
}

// Exception thrown when secure keyfile generation fails
class SecureKeyfileError : public std::runtime_error {
public:
Expand Down Expand Up @@ -199,61 +203,12 @@ bool SecureKeyfile::pathExists(const std::string& path) {

// Get unique device ID from sysfs (based on getDeviceId from commands.cpp)
std::string SecureKeyfile::getDeviceId(const std::string& block_device) {
std::string device = block_device;
if (device.find("/dev/") == 0) {
device = device.substr(5);
}

// Extract base device name (remove partition)
std::string base_device = device;
if (device.find("mmcblk") != std::string::npos) {
size_t p_pos = device.find("p");
if (p_pos != std::string::npos) {
base_device = device.substr(0, p_pos);
}
} else if (device.find("nvme") != std::string::npos) {
size_t p_pos = device.find_last_of("p");
if (p_pos != std::string::npos) {
base_device = device.substr(0, p_pos);
}
} else {
// SATA/SCSI: sda1 -> sda
while (!base_device.empty() && std::isdigit(base_device.back())) {
base_device.pop_back();
}
}

std::string sys_block_path = "/sys/class/block/" + base_device;
char id[256];
int ret;

// Try MMC/SD Card CID first
std::string device_id = readSysFile(sys_block_path + "/device/cid");
if (!device_id.empty()) {
return device_id;
}

// Try NVMe EUI
device_id = readSysFile(sys_block_path + "/eui");
if (!device_id.empty()) {
return device_id;
}

// Try device serial
device_id = readSysFile(sys_block_path + "/device/serial");
if (!device_id.empty()) {
return device_id;
}

// Check if this is a USB device - return error
if (pathExists(sys_block_path + "/device")) {
char resolved_path[PATH_MAX];
std::string device_link = sys_block_path + "/device";
if (realpath(device_link.c_str(), resolved_path) != nullptr) {
std::string device_path = resolved_path;
if (device_path.find("/usb") != std::string::npos) {
return "ERROR_USB_NOT_SUPPORTED";
}
}
}
ret = bdi_get_id(block_device.c_str(), id, sizeof(id));
if (!ret)
return std::string(id);

return "";
}
Expand Down