summaryrefslogtreecommitdiffstats
path: root/src/detection/bootmgr/bootmgr_apple.c
blob: d2b24e00e84c61bc66fe325c25fcf3953ec245ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "bootmgr.h"
#include "common/io.h"
#include "common/apple/cf_helpers.h"

#include <IOKit/IOKitLib.h>

static const char* detectSecureBoot(bool* result) {
#if __aarch64__
    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
    if (!entryDevice) {
        return "IORegistryEntryFromPath() failed";
    }

    FF_CFTYPE_AUTO_RELEASE CFTypeRef prop = IORegistryEntryCreateCFProperty(entryDevice, CFSTR("secure-boot"), kCFAllocatorDefault, kNilOptions);
    if (!prop) {
        return "IORegistryEntryCreateCFProperty() failed";
    }

    if (CFGetTypeID(prop) != CFDataGetTypeID() || CFDataGetLength((CFDataRef) prop) == 0) {
        return "Invalid secure-boot property";
    }

    *result = (bool) *CFDataGetBytePtr((CFDataRef) prop);
#else
    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/options");
    if (!entryDevice) {
        return "IORegistryEntryFromPath() failed";
    }

    FF_CFTYPE_AUTO_RELEASE CFTypeRef prop = IORegistryEntryCreateCFProperty(entryDevice, CFSTR("94b73556-2197-4702-82a8-3e1337dafbfb:AppleSecureBootPolicy"), kCFAllocatorDefault, 0);
    if (!prop) {
        return "IORegistryEntryCreateCFProperty() failed";
    }

    if (CFGetTypeID(prop) != CFDataGetTypeID() || CFDataGetLength((CFDataRef) prop) == 0) {
        return "Invalid secure-boot property";
    }

    *result = *CFDataGetBytePtr((CFDataRef) prop) != 0x02 /* Permissive Security */;
#endif

    return NULL;
}

const char* ffDetectBootmgr(FFBootmgrResult* result) {
    if (ffPathExists("/System/Library/CoreServices/boot.efi", FF_PATHTYPE_FILE)) {
        ffStrbufSetStatic(&result->firmware, "/System/Library/CoreServices/boot.efi");
    }

    #ifdef __aarch64__
    FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceChosen = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
    if (deviceChosen) {
        FF_CFTYPE_AUTO_RELEASE CFStringRef tag = IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("iboot-stage-two-tag"), kCFAllocatorDefault, kNilOptions)
            ?: IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("system-firmware-version"), kCFAllocatorDefault, kNilOptions);
        if (tag) {
            ffCfStrGetString(tag, &result->name);
            ffStrbufSubstrBeforeFirstC(&result->name, '-');
        }
    }
    #endif

    if (!result->name.length) {
        ffStrbufSetStatic(&result->name, "iBoot");
    }

    detectSecureBoot(&result->secureBoot);

    return NULL;
}