// // kern_nvram.hpp // Lilu // // Copyright © 2017 vit9696. All rights reserved. // #ifndef kern_nvram_hpp #define kern_nvram_hpp #include #include #include #include #include /** * 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 */