-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provisioning support in IGPU #586
Comments
I'm reading through the resources linked to in the first post. It seems, by construction, what you're proposing is not possible. And if it is, it would be a major security vulnerability for Intel/Apple. From [2]:
My understanding from this is that for non-Apple devices, Intel acts as the EPID authority, and they issue the EPID private keys (and hold on to the EPID public keys used in the provisioning). For Apple devices, since they're using different certificates, I would assume they are acting as the EPID authority and does the key generation. That means your non-Apple board is fused with an EPID private keys for which Apple does not hold the public keys to. It also means that you will not be able to provision the group public key because you will not be able to obtain a group public key corresponding to your EPID private key that is ALSO signed by Apple's EPID authority certificate. I am guessing that iTunes DRM content would only be decrypt-able in a chain that eventually ends in an Apple held EPID group public key. Looking at this from another perspective, if you were a bad guy set on stealing iTunes DRM content and cannot bypass Boot Guard/T2, then why not just buy some random mobo, provision Apple's public keys onto it, and then freely decrypt iTunes DRM? This is precisely what EPID was designed to protect against (enable DRM while also protecting privacy). Please let me know if I'm misunderstanding this. |
@osy86 you get the point, but most likely it is not like that. Intel does not let anybody meddle with its rights as an authority, so private keys fused during the manufacturing process are basically random, and should be no different for Apple and non-Apple hardware. Decrypted ME 12 firmware containing Apple specific stuff, group key blobs containing basically all keys, flashed stock chipsets on MacBooks, and ME gladly accepting Apple certificate all that evidence imply that Apple supports all private keys, and it is unimportant whether it is Apple computer or not. As far as I know, recent iTunes versions on Windows do the same thing, just dynamically when they can. From my standpoint there is no security issue here, as each encryption session gets new session key, so transferring will be impossible. And replay will not be possible due to amount of private keys highly exceeding the amount of group keys (like 1000 times more for each generation). So it is not important whether Apple authorises its own computer or not, private keys will unlikely much even with ten different machines of the same mac model. To my eyes, the issue with this not working is not really about PAVP not understanding stuff, but rather PAVP not being initialised properly, as it freezes at any video playback, even non-DRM. |
Right, but from my (< 2 hours) research into EPID/DAA protocol, there is 1 unique private key but the corresponding public key is shared by all members of the group.
So in order for Apple's group public key to work, the EPID authority that generated the private key must be the same one that Apple uses. I'm not saying this is definitely not true, but I would be surprised if it is true. There are likely other issues in the way too resulting in video playback failing, but my point is that IF iTunes DRM depends on the EPID (which it could very well not, and only depend on a provisioned status) AND the EPID authority for Apple is different (which is probably is), then there's no way to ever get it working (even if all other problems are resolved).
I don't see that as evidence for Apple having a EPID public key that works for your chipset. The private key is stored in fuses and cannot be changed. If you flashed Apple certificates, the only time an error will show up is when you try to provision the public key and it fails the signature validation. So with the code in [9], what actually happens when you try to provision with an Apple public key (assuming they have one with your group number)? Is it an error? EDIT: In response to
I believe OEMs are allowed to program their own ME fuses. Probably not all fuses though. |
iTunes DRM does depend on EPID when IGPU is used, yes, this is certain. I did some reverse engineering in the past and figured that much. This is called com.apple.fps.2_X or com.apple.fps.3_X and implemented as AVFoundation private media source. Some vendors, such as Netflix, require FairPlay 2+, which can only work with hardware assistance (IGPU with EPID or AMD GPU). Apple itself for iTunes requires FairPlay 1+, but uses newest available, unless we forcibly claim we do not support 2+ (that's what WhateverGreen does).
So far all group keys returned by hardware (we tried 4 machines as you see) were found in Apple firmwares (each firmware supports a large number of group key ids). ME accepted that key and returned success. So indeed Apple certificate was created to work with these keys. This is how it looked basically (slightly older code):
Afterwards it will report "successfully provisioned:
The keys we got were 0x4DF (ASUS Z87 board), 0x4E0 (GIGABYTE Z87 board), 0x6AD (ASUS Haswell laptop), 0x37F (Dell Ivy Bridge board).
They can, yes, but hardly anybody does it. |
I see, that's good to know. So the current status is: EPID can be provisioned, but PAVP still does not work? Can you post relevant error logs when iTunes DRM protected content is played? |
Pretty much.
I can, but there is not much there. Apple killed most of things starting with 10.12 or 10.13. Formerly you could enable debugging with fp_trace, and there was a lot of good stuff MediaToolBox and AppleGVA, as explained in Shiki FAQ. The easiest to test it is by playing an encrypted QuickTime trailer (also linked in the FAQ). I could share some legacy idbs I guess. |
Regarding software decoder, I actually discovered that TV+ can use same old FP1, so it is possible to run it in software. I was unable to properly disable IGPU from being forcibly used so far for this type of media (encv), however, so the patches only work with IGPU disabled in firmware. Help appreciated :) |
I spent some time on this and I'll report some of my findings here. On my build, when attempting to load IGPU without any WG patches, I get the following log
By tracing uVar10 = *(uint *)(lVar13 + 0xc0f4);
puVar25 = (undefined *)(ulong)uVar10;
bVar26 = SUB41(uVar10,0);
if (uVar10 == 0x1ff) {
this_01 = (long *)(this_00 + 0x1208);
if ((local_54 & 1) != 0) {
*(int *)(this + 0x490) = local_64;
local_54 = 0;
}
goto start_xfer;
} From my understanding of how ME interfaces with the CPU, it doesn't seem like there's a way for the ME to enforce any security in GuC loading. For that to work, the ME would have to sit in between the data path from the CPU to the IGPU or somehow there would be a three-way handshake. However, looking at the Linux source, that does not appear to be the case. So it is likely the case that OSX is the one that checks the ME, which makes the message "Hash data from ME never returned" seem more reasonable. From there, I tried to patch out the ME checks and got farther in the GuC load process
The status register I would be curious if the error is due to some configuration issues (not enabling PAVP, no stolen memory, etc) and if this error code is unique (I found zero results on Google). My next test will be to see if I can get a different error code after provisioning PAVP. |
Hi, now that you mentioned it, I think I did exactly the same thing in older operating system versions. Indeed, Linux kernel does not document this code, we found no other firmware that does. We searched for any information regarding GuC firmware, and found some references that it is legacy OEM firmware introduced before GuC. I remember that it can actually be encrypted, and unlike the default Linux firmware, extra provisioning may be needed for this firmware to work. We failed to find any GuC keys in Apple firmwares though. As for authentication, is not GuC firmware executed on ME processor? |
The GuC runs its own processor. |
PAVP configThe PAVPC register is in PCI config for host bridge (offset 58h) as well as the MMIO config space for IGPU (offset 1082C0h). This is defined in vol 2 of the Kaby Lake H datasheet and afaik the IGPU registers are a mirror of the host bridge ones. On my I7-8809G machine, the register is read to be Additionally, on the Mac, when booting into OSX, and after setting up the IGPU will poll Those seems to be the only difference in the IGPU init code between my BIOS and the Kabylake Mac BIOS. Unfortunately because my BIOS locked the register (and has BIOS Guard and Boot Guard), I cannot test any modifications. I would be curious to see if setting the bits the same as the Mac would do anything. ProvisioningI had to make some modifications to get the HECI interface to work. Seems like the protocol has been updated in Skylake and beyond (haven't checked any earlier). However, it seems like by group id is not supported and Intel has already provisioned the IGPU from BIOS so it cannot be re-provisioned anyways. Here is my log
Anyways I think that's as much as I can do since I don't have another system to test with and it is pretty locked down on this one. |
Thanks for the research. I am not positive we can do much, but we will test it on some machines later and let you know if we find any good one. |
Ok, we tested it on ASUS Z170M-Plus, and got the following results.
PAVPC on Skylake is also locked, and provisioning is also done. It is likely that this group id key can be found in newer Apple firmwares, but resetting the provisioning and changing PAVPC values will require firmware modifications anyway. We could try this on Haswell, where we have more control, but the overall idea does not sound very promising in such state. |
I also moved the code to master into OcHeciLib / PavpProvision, so that one can play with this later if he wants (https://github.com/acidanthera/OcSupportPkg/tree/master/Application/PavpProvision). |
The group ids in |
Yes, that was dumped from a Haswell machine, if you dump the same file from a newer machine, it will contain higher IDs. Basically the values increase as the generation increases. |
Seems like Kabylake macs have 0xf81-0x1110. Coffeelake macs have 0x28af-0x2a3e. I wasn't able to find 0x1faf or 0x2024 anywhere in any of the firmware packages in the OSX updater. |
Wow, that is worrying. So in these days they even have separate group id ranges. In this case it may be beneficial to invest in porting GuC from Linux, that will at least fix the IGPU performance issues. As for DRM, I somehow get a feeling it is a dead end with recent Intel generations. While it is likely that generic chipsets with GIDs from Macs do exist, the fact that many if not all chipsets are provisioned and have incompatible GIDs pretty much defeats the research purpose in this direction. Perhaps, we should invest in getting AMD decoder to work and/or enabling software decoder. |
We confirmed testing that GuC firmwares successfully load on 9th generation mobile chipsets and newer, e.g. on Dell Inspiron 7590 with Core i7-9750H. To do this one can use igfxfw=2 boot-argument or inject PAVP/HDCP is still broken (causes cursor stuttering and lags during video playback). PAVP provisioning is also not possible, as the key is already provisioned:
Interestingly, this key is present in MacBookPro15,x+ firmwares, so if it was possible to reprovision by e.g. cleaning ME region, PAVP may have worked. Still, this is better than nothing, and probably the maximum we can achieve. Closing as resolved (to some level). REF: #748 |
How did we come up with the fact that 'GuC firmware will only load on 14nm chipsets'? Isn't the GuC firmware loaded on the iGPU coprocessor? And if that is truly the case, what is the behavior on Skylake chipsets on real Macs? Are these 14nm chipsets? Or is it an older node size and it resorts to using the host scheduler? |
There are many issues with the matter, and I want to try to raise some attention to the problem from potentially interested parties. I kindly ask people without technical information to ignore this issue.
Problems:
All these issues normally are solved supplemental hacks, as flashing the firmware requires some effort, and ME/HECI is quite a dark forest. Basically, for this to work the following needs to be achived:
What we know:
CMD_SEND_SAFEID_PUBKEY
,PAVP_EPID_API_VERSION_MAJOR
,PAVP_CMD_HEADER
,pavp_lib_session
on GitHub code.What we do not know:
Although we are not ready to continue the research at the moment, we believe that it might be helpful to share this information with others. Perhaps somebody wants to continue or has information to share. CC @0xFireWolf, @al3xtjames, @osy86, @platomav, @skochinsky.
[1] https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/dcmi-hi-1-0-spec.pdf
[2] https://link.springer.com/content/pdf/10.1007%2F978-1-4302-6572-6.pdf
[3] https://github.com/Intel-EPID-SDK/epid-sdk
[4] https://github.com/shreekantsingh/uefi/tree/master/drivers/misc/mei
[5] https://01.org/sites/default/files/documentation/skl_opregion_rev0p5.pdf
[6] https://twitter.com/platomaniac/status/1031990242545418242
[7] https://github.com/CHEF-KOCH/Intel-ME-Firmware-Repository/tree/master/12
[8] https://github.com/ptresearch/unME12
[9] https://github.com/acidanthera/OcSupportPkg/tree/master/Application/PavpProvision
[10] https://github.com/coreboot/coreboot/blob/master/src/soc/intel/apollolake/cse.c
[11] https://drive.google.com/file/d/12pQ5FFpdHdGOVV6jvbqEq2wmkpMKxsOF/view
[12] https://github.com/acidanthera/WhateverGreen/blob/533611b/WhateverGreen/kern_igfx.cpp#L266-L267
[13] https://github.com/acidanthera/WhateverGreen/blob/533611b/WhateverGreen/kern_igfx.cpp#L270
[14] https://github.com/acidanthera/WhateverGreen/blob/dcbb8d9/WhateverGreen/kern_shiki.cpp#L117
The text was updated successfully, but these errors were encountered: