build/packages/bsp/jethub/jethubj80/jethub_get_efuse_raw_key.h

137 lines
3.8 KiB
C++

#include <algorithm>
#include <cstddef>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
using Bytes = std::vector<std::byte>;
std::string loadFileAsLine(const std::string& path) {
std::string result;
std::ifstream file(path);
if (file) {
std::getline(file, result, '\0');
} else {
std::cerr << "Unable to read file " << path << std::endl;
exit(EXIT_FAILURE);
}
return result;
}
Bytes readBlock(std::uint32_t offset, std::uint32_t length, std::string const &filename)
{
Bytes result;
std::ifstream is(filename, std::ios::binary);
if (is) {
is.seekg(offset);
result.resize(length);
is.read(reinterpret_cast<char*>(result.data()), length);
result.resize(is.gcount());
} else {
std::cerr << "Unable to read file " << filename << std::endl;
exit(EXIT_FAILURE);
}
return result;
}
Bytes loadBinaryFile(std::string const &path)
{
std::ifstream ifs(path, std::ios::binary | std::ios::ate);
if(ifs) {
auto end = ifs.tellg();
ifs.seekg(0, std::ios::beg);
auto size = std::size_t(end - ifs.tellg());
if(size > 0) { // avoid undefined behavior
Bytes buffer(size);
if(ifs.read((char*)buffer.data(), buffer.size())) {
return buffer;
}
}
} else {
std::cerr << "Unable to read file " << path << std::endl;
exit(EXIT_FAILURE);
}
return {};
}
uint32_t castBytesInFile(const std::string &path) {
Bytes offset = loadBinaryFile(path);
if (offset.size() == 4) {
std::reverse(offset.begin(), offset.end());
return *reinterpret_cast<uint32_t*>(offset.data());
}
return 0;
}
uint32_t castBytesInFile(const std::string &path, std::uint32_t offset) {
Bytes data = readBlock(offset, sizeof(uint32_t), path);
if (data.size()== 4) {
std::reverse(data.begin(), data.end());
return *reinterpret_cast<uint32_t*>(data.data());
}
return 0;
}
std::string getKey(const std::string &key)
{
std::string result;
const std::string efusekeyPathStr = "/sys/firmware/devicetree/base/efuse";
const std::filesystem::path path { efusekeyPathStr };
std::error_code ec;
for (const auto& dirEntry : std::filesystem::directory_iterator(path, ec)) {
if (ec) {
std::cerr << "Error when iterate " << efusekeyPathStr << ": error code:" << ec.value() << " error message: " << ec.message() << std::endl;
exit(EXIT_FAILURE);
continue;
}
const auto filenameStr = dirEntry.path().filename().string();
//std::cout << "Iterating " << filenameStr << " and flag: " << startsWithKeyUnderscore << std::endl;
if (dirEntry.is_directory()) {
const auto keynamePathStr = (efusekeyPathStr + "/" + filenameStr + "/name");
const auto keyname = loadFileAsLine(keynamePathStr);
//std::cout << keynamePathStr << " == '" << keyname << "'" << std::endl;
if (keyname == key) {
const uint32_t offset = castBytesInFile(efusekeyPathStr + "/" + filenameStr + "/reg", 0);
const uint32_t size = castBytesInFile(efusekeyPathStr + "/" + filenameStr + "/reg", 4);
//std::cout << "offset == " << offset << std::endl;
//std::cout << "size == " << size << std::endl;
if (!(offset == 0 && size == 0)) {
Bytes keyValue = readBlock(offset, size, "/sys/devices/platform/efuse/efuse0/nvmem");
if (keyValue.size() > 0) {
result.resize(keyValue.size(), '\0');
std::transform(
keyValue.begin(), keyValue.end(), result.begin(),
[] (std::byte b) {
return std::to_integer<char>(b);
}
);
result = result;
}
}
break;
}
}
}
if (ec) {
std::cerr << "Error when iterate " << efusekeyPathStr << ": error code:" << ec.value() << " error message: " << ec.message() << std::endl;
exit(EXIT_FAILURE);
}
return result;
}