2022-03-29 10:26:33 +03:00

199 lines
5.7 KiB
C++
Executable File

//
// kern_nvram.hpp
// Lilu
//
// Copyright © 2017 vit9696. All rights reserved.
//
#ifndef kern_nvram_hpp
#define kern_nvram_hpp
#include <Headers/kern_util.hpp>
#include <IOKit/IOService.h>
#include <libkern/c++/OSSymbol.h>
#include <libkern/libkern.h>
#include <stdint.h>
/**
* Some of the most common GUIDs used for variable storage on macOS
*/
#define NVRAM_GLOBAL_GUID "8BE4DF61-93CA-11D2-AA0D-00E098032B8C"
#define NVRAM_APPLE_BOOT_GUID "7C436110-AB2A-4BBB-A880-FE41995C9F82"
#define NVRAM_APPLE_VENDOR_GUID "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14"
#define NVRAM_APPLE_FILEVAULT_GUID "8D63D4FE-BD3C-4AAD-881D-86FD974BC1DF"
#define NVRAM_APPLE_PASSWORD_UI_GUID "9EBA2D25-BBE3-4AC2-A2C6-C87F44A1278C"
/**
* Custom GUIDs used for Lilu preferences
* Must be kept in sync to OcSupportPkg/Include/Guid/OcVariables.h
*/
#define LILU_VENDOR_GUID "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"
#define LILU_READ_ONLY_GUID "E09B9297-7928-4440-9AAB-D1F8536FBF0A"
#define LILU_WRITE_ONLY_GUID "F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1"
/**
* Prefix variable name with a GUID
*/
#define NVRAM_PREFIX(x, y) x ":" y
class NVStorage {
/**
* Local nvram controller reference
*/
IORegistryEntry *dtEntry {nullptr};
public:
/**
* Compress data with a default compression algorithm
*
* @param src source data
* @param size data size (updated with new size)
* @param sensitive contains sensitive data
*
* @return compressed data (must be freed with Buffer::deleter) or nullptr
*/
EXPORT uint8_t *compress(const uint8_t *src, uint32_t &size, bool sensitive=false);
/**
* Decompress data compressed with compress
*
* @param src compressed data
* @param size data size (updated with new size)
* @param sensitive contains sensitive data
*
* @return decompressed data (must be freed with Buffer::deleter) or nullptr
*/
EXPORT uint8_t *decompress(const uint8_t *src, uint32_t &size, bool sensitive=false);
/**
* Value storage options
*/
enum Options {
OptAuto = 0, // Default options
OptRaw = 1, // i/o as raw buffer
OptCompressed = 2, // Apply compression (see kern_compression.hpp)
OptEncrypted = 4, // Apply encryption with device-unique key (see kern_crypto.hpp)
OptChecksum = 8, // Append CRC32 checksum to the end
OptSensitive = 16 // Value contains sensitive data
};
/**
* Prepended value header unless OptRaw is used
* After the header the following fields should go:
* uint8_t iv[16]; aes initialisation vector (if OptEncrypted is set)
* uint32_t size; decryption size (if OptEncrypted is set, encrypted)
* uint32_t size; decompression size (if OptCompressed is set, encrypted if OptEncrypted)
* uint8_t data[]; content data (encrypted if OptEncrypted)
* uint32_t crc32; CRC32 cheksum (if OptChecksum is set)
*/
struct PACKED Header {
static constexpr uint16_t Magic = 0xC717;
static constexpr uint8_t MaxVer = 1;
using Checksum = uint32_t;
uint16_t magic {Magic};
uint8_t version {MaxVer};
uint8_t opts {OptAuto};
};
/**
* Attempt to connect to active nvram, may fail at early stages
*
* @return true on success
*/
EXPORT bool init();
/**
* Relinquish resources used, must be called regardless of the init error
*/
EXPORT void deinit();
/**
* Read data from nvram
*
* @param key key name
* @param size amount of data read
* @param opts bitmask of Options, may set option requirements
* @param enckey encryption key (platform-defined if OptEncrypted is set)
*
* @return pointer to data (must be freed via Buffer::deleter), nullptr on failure
*/
EXPORT uint8_t *read(const char *key, uint32_t &size, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
/**
* Read data from nvram
*
* @param key key name
* @param opts bitmask of Options, may set option requirements
* @param enckey encryption key (platform-defined if OptEncrypted is set)
*
* @return pointer to data (must be freed via OSData::release), nullptr on failure
*/
EXPORT OSData *read(const char *key, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
/**
* Write data to nvram
*
* @param key key name
* @param src source buffer
* @param size buffer size
* @param opts bitmask of Options
* @param enckey encryption key (platform-defined if OptEncrypted is set)
*
* @return true on success
*/
EXPORT bool write(const char *key, const uint8_t *src, uint32_t sz, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
/**
* Write data to nvram
*
* @param key key name
* @param data data object to write
* @param opts bitmask of Options
* @param enckey encryption key (platform-defined if OptEncrypted is set)
*
* @return true on success
*/
EXPORT bool write(const char *key, const OSData *data, uint8_t opts=OptAuto, const uint8_t *enckey=nullptr);
/**
* Delete key from nvram
*
* @param key key name
* @param sensitive sensitive data
*
* @return true on successful deletion or if key is missing
*/
EXPORT bool remove(const char *key, bool sensitive=false);
/**
* Synchronize with nvram controller
* This method might fail if synchronisation was done recently.
*
* @return true if synchronised
*/
EXPORT bool sync();
/**
* Exports nvram to a plist file
*
* @param filename file path
* @oaram max max output size
* @param sensitive contains sensitive data
*
* @return true if saved
*/
EXPORT bool save(const char *filename, uint32_t max=0x20000, bool sensitive=false);
/**
* Check whether key exists
*
* @param key key name
*
* @return true if key exists
*/
EXPORT bool exists(const char *key);
};
#endif /* kern_nvram_hpp */