{
	"id": "02e86d4c-a025-412c-80f3-e0a2a0e263f3",
	"created_at": "2026-04-06T00:21:58.084145Z",
	"updated_at": "2026-04-10T03:22:05.360808Z",
	"deleted_at": null,
	"sha1_hash": "defe5d06c6841b14d984e768e5f371f8de681ec5",
	"title": "Extracting Qualcomm's KeyMaster Keys - Breaking Android Full Disk Encryption",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 471978,
	"plain_text": "Extracting Qualcomm's KeyMaster Keys - Breaking Android Full\r\nDisk Encryption\r\nArchived: 2026-04-05 21:41:51 UTC\r\nAfter covering a TrustZone kernel vulnerability and exploit in the previous blog post, I thought this time it might\r\nbe interesting to explore some of the implications of code-execution within the TrustZone kernel. In this blog post,\r\nI'll demonstrate how TrustZone kernel code-execution can be used to effectively break Android's Full Disk\r\nEncryption (FDE) scheme. We'll also see some of the inherent issues stemming from the design of Android's FDE\r\nscheme, even without any TrustZone vulnerability.\r\nI've been in contact with Qualcomm regarding the issue prior to the release of this post, and have let them review\r\nthe blog post. As always, they've been very helpful and fast to respond. Unfortunately, it seems as though fixing\r\nthe issue is not simple, and might require hardware changes.\r\nIf you aren't interested in the technical details and just want to read the conclusions - feel free to jump right to the\r\n\"Conclusions\" section. In the same vein, if you're only interested in the code, jump directly to the \"Code\" section.\r\n[UPDATE: I've made a factual mistake in the original blog post, and have corrected it in the post below.\r\nApparently Qualcomm are not able to sign firmware images, only OEMs can do so. As such, they cannot be\r\ncoerced to create a custom TrustZone image. I apologise for the mistake.]\r\nAnd now without further ado, let's get to it!\r\nSetting the Stage \r\nA couple of months ago the highly-publicised case of Apple vs. FBI brought attention to the topic of privacy -\r\nespecially in the context of mobile devices. Following the 2015 San Bernardino terrorist attack, the FBI seized a\r\nmobile phone belonging to the shooter, Syed Farook, with the intent to search it for any additional evidence or\r\nleads related to the ongoing investigation. However, despite being in possession of the device, the FBI were\r\nunable to unlock the phone and access its contents.\r\nThis may sound puzzling at first. \"Surely if the FBI has access to the phone, could they not extract the user data\r\nstored on it using forensic tools?\". Well, the answer is not that simple. You see, the device in question was an\r\niPhone 5c, running iOS 9.\r\nAs you may well know, starting with iOS 8, Apple has automatically enabled Full Disk Encryption (FDE) using\r\nan encryption key which is\r\nderived from the user's password\r\n. In order to access the data on the device, the FBI would have to crack that encryption. Barring any errors in\r\ncryptographic design, this would most probably be achieved by cracking the user's password.\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 1 of 18\n\n\"So why not just brute-force the password?\". That sounds like a completely valid approach - especially since most\r\nusers are notoriously bad at choosing strong passwords, even more so when it comes to mobile devices.\r\nHowever, the engineers at Apple were not oblivious to this concern when designing their FDE scheme. In order to\r\ntry and mitigate this kind of attack, they've designed the encryption scheme so that the generated encryption key is\r\nbound to the hardware of the device. \r\nIn short, each device has an immutable 256-bit unique key called the UID, which is randomly generated and fused\r\ninto the device's hardware at the factory. The key is stored in a way which completely prevents access to it using\r\nsoftware or firmware (it can only be set as a key for the AES Engine), meaning that\r\neven Apple cannot extract it from the device\r\nonce it's been set. This device-specific key is then used in combination with the provided user's password in order\r\nto generate the resulting encryption key used to protect the data on the device. This effectively 'tangles' the\r\npassword and the UID key.\r\nApple's FDE KDF\r\nBinding the encryption key to the device's hardware allows Apple to make the job\r\nmuch harder\r\nfor would-be attackers. It essentially forces attackers to use the device for each cracking attempt. This, in turn,\r\nallows Apple to introduce a whole array of defences that would make cracking attempts on the device unattractive.\r\nFor starters, the key-derivation function shown above is engineered in such a way so that it would take a\r\nsubstantial amount of time to compute on the device. Specifically, Apple chose the function's parameters so that a\r\nsingle key derivation would take approximately 80 milliseconds. This delay would make cracking short\r\nalphanumeric passwords slow (~2 weeks for a 4-character alphanumeric password), and cracking longer\r\npasswords completely infeasible.\r\nIn order to further mitigate brute-force attacks on the device itself, Apple has also introduced an incrementally\r\nincreasingly delay between subsequent password guesses. On the iPhone 5c, this delay was facilitated completely\r\nusing software. Lastly, Apple has allowed for an option to completely erase all of the information stored on the\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 2 of 18\n\ndevice after 10 failed password attempts. This configuration, coupled with the software-induced delays, made\r\ncracking the password on the device itself rather infeasible as well.\r\nWith this in mind, it's a lot more reasonable that the FBI were unable to crack the device's encryption.\r\nHad they been able to extract the UID key, they could have used as much (specialized) hardware as needed in\r\norder to rapidly guess many passwords, which would most probably allow them to eventually guess the correct\r\npassword. However, seeing as the UID key cannot be extracted by means of software or firmware, that option is\r\nruled out.\r\nAs for cracking the password on the device, the software-induced delays between password attempts and the\r\npossibility of obliterating all the data on the device made that option rather unattractive. That is, unless they could\r\nbypass the software protections... However, this is where the story gets rather irrelevant to this blog post, so we'll\r\nkeep it at that.\r\nIf you'd like to read more, you can check out Dan Guido's superb post about the technical aspects of Apple v. FBI,\r\nor Matthew Green's great overview on Apple's FDE, or better yet, the iOS Security Guide.\r\nGoing back to the issue at hand - we can see that Apple has cleverly designed their FDE scheme in order to make\r\nit very difficult to crack. Android, being the mature operating system that it is, was not one to lag behind. In fact,\r\nAndroid has also offered full disk encryption, which has been enabled by default since Android 5.0.\r\nSo how does Android's FDE scheme fare? Let's find out.\r\nStarting with Android 5.0, Android devices automatically protect all of the user's information by enabling full disk\r\nencryption.\r\nAndroid FDE is based on a Linux Kernel subsystem called dm-crypt, which is widely deployed and researched.\r\nOff the bat, this is already good news - dm-crypt has withstood the test of time, and as such seems like a great\r\ncandidate for an FDE implementation. However, while the encryption scheme may be robust, the system is only as\r\nstrong as the key being used to encrypt the information. Additionally, mobile devices tend to cause users to choose\r\npoorer passwords in general. This means the key derivation function is hugely important in this setting.\r\nSo how is the encryption key generated?\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 3 of 18\n\nThis process is described in great detail in the official documentation of Android FDE, and in even greater detail\r\nin Nikolay Elenkov's blog, \"Android Explorations\". In short, the device generates a randomly-chosen 128-bit\r\nmaster key (which we'll refer to as the Device Encryption Key - DEK) and a 128-bit randomly-chosen salt. The\r\nDEK is then protected using an elaborate key derivation scheme, which uses the user's provided unlock credentials\r\n(PIN/Password/Pattern) in order to derive a key which will ultimately encrypt the DEK. The encrypted DEK is\r\nthen stored on the device, inside a special unencrypted structure called the \"crypto footer\".\r\nThe encrypted disk can then be decrypted by simply taking the user's provided credentials, passing them through\r\nthe key derivation function, and using the resulting key to decrypt the stored DEK. Once the DEK is decrypted, it\r\ncan be used to decrypt user's information.\r\nHowever, this is where it gets interesting! Just like Apple's FDE scheme, Android FDE seeks to prevent brute-force cracking attacks; both on the device and especially off of it.\r\nNaturally, in order to prevent on-device cracking attacks, Android introduced delays between decryption attempts\r\nand an option to wipe the user's information after a few subsequent failed decryption attempts (just like iOS). But\r\nwhat about preventing off-device brute-force attacks? Well, this is achieved by introducing a step in the key\r\nderivation scheme which\r\nbinds the key to the device's hardware\r\n. This binding is performed using Android's Hardware-Backed Keystore - KeyMaster.\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 4 of 18\n\nKeyMaster\r\nThe KeyMaster module is intended to assure the protection of cryptographic keys generated by applications. In\r\norder to guarantee that this protection cannot be tampered with, the KeyMaster module runs in a Trusted\r\nExecution Environment (TEE), which is completely separate from the Android operating system. In keeping with\r\nthe TrustZone terminology, we'll refer to the Android operating system as the \"Non-Secure World\", and to the TEE\r\nas the \"Secure World\".\r\nPut simply, the KeyMaster module can be used to generate encryption keys, and to perform cryptographic\r\noperations on them, without ever revealing the keys to the Non-Secure World.\r\nOnce the keys are generated in the KeyMaster module, they are encrypted using a hardware-backed encryption\r\nkey, and returned to Non-Secure World. Whenever the Non-Secure World wishes to perform an operation using the\r\ngenerated keys, it must supply the encrypted \"key blob\" to the KeyMaster module. The KeyMaster module can\r\nthen decrypt the stored key, use it to perform the wanted cryptographic operation, and finally return the result to\r\nthe Non-Secure World.\r\nSince this is all done without ever revealing the cryptographic keys used to protect the key blobs to the Non-Secure World, this means that all cryptographic operations performed using key blobs must be handled by the\r\nKeyMaster module, directly on the device itself.\r\nWith this in mind, let's see exactly how KeyMaster is used in Android's FDE scheme. We'll do so by taking a\r\ncloser look at the hardware-bound key derivation function used in Android's FDE scheme. Here's a short\r\nschematic detailing the KDF (based on a similar schematic created by Nikolay Elenkov):\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 5 of 18\n\nAndroid FDE's KDF\r\nAs you can see, in order to bind the KDF to the hardware of the device, an additional field is stored in the crypto\r\nfooter - a KeyMaster-generated key blob. This key blob contains a KeyMaster-encrypted RSA-2048 private key,\r\nwhich is used to sign the encryption key in an intermediate step in the KDF - thus requiring the use of the\r\nKeyMaster module in order to produce the intermediate key used decrypt the DEK in each decryption attempt.\r\nMoreover, the crypto footer also contains an additional field that doesn't serve any direct purpose in the decryption\r\nprocess; the value returned from running scrypt on the final intermediate key (IK3). This value is referred to as the\r\n\"scrypted_intermediate_key\" (Scrypted IK in the diagram above). It is used to verify the validity of the supplied\r\nFDE password in case of errors during the decryption process. This is important since it allows Android to know\r\nwhen a given encryption key is valid but the disk itself is faulty. However, knowing this value still shouldn't help\r\nthe attacker \"reverse\" it to retrieve the IK3, so it still can't be used to help attackers aiming to guess the password\r\noff the device.\r\nAs we've seen, the Android FDE's KDF is \"bound\" to the hardware of the device by the intermediate KeyMaster\r\nsignature. But how secure is the KeyMaster module? How are the key blobs protected? Unfortunately, this is hard\r\nto say. The implementation of the KeyMaster module is provided by the SoC OEMs and, as such, is completely\r\nundocumented (essentially a black-box). We could try and rely on the official Android documentation, which\r\nstates that the KeyMaster module: \"...offers an opportunity for Android devices to provide hardware-backed,\r\nstrong security services...\". But surely that's not enough.\r\nSo... Are you pondering what I'm pondering?\r\nReversing Qualcomm's KeyMaster\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 6 of 18\n\nAs we've seen in the previous blog posts, Qualcomm provides a Trusted Execution Environment called QSEE\r\n(Qualcomm Secure Execution Environment). The QSEE environment allows small applications, called\r\n\"Trustlets\", to execute on a dedicated secured processor within the \"Secure World\" of TrustZone. One such QSEE\r\ntrustlet running in the \"Secure World\" is the KeyMaster application. As we've already seen how to reverse-engineer QSEE trustlets, we can simply apply the same techniques in order to reverse engineer the KeyMaster\r\nmodule and gain some insight into its inner workings.\r\nFirst, let's take a look at the Android source code which is used to interact with the KeyMaster application. Doing\r\nso reveals that the trustlet only supports four different commands:\r\nAs we're interested in the protections guarding the generated key blobs, let's take a look at the\r\nKEYMASTER_SIGN_DATA command. This command receives a previously encrypted key blob and somehow\r\nperforms an operation using the encapsulated cryptographic key. Ergo, by reverse-engineering this function, we\r\nshould be able to deduce how the encrypted key blobs are decapsulated by the KeyMaster module.\r\nThe command's signature is exactly as you'd imagine - the user provides an encrypted key blob, the signature\r\nparameters, and the address and length of the data to be signed. The trustlet then decapsulates the key, calculates\r\nthe signature, and writes it into the shared result buffer.\r\nAs luck would have it, the key blob's structure is actually defined in the supplied header files. Here's what it looks\r\nlike:\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 7 of 18\n\nOkay! This is pretty interesting.\r\nFirst, we can see that the key blob contains the unencrypted modulus and public exponent of the generated RSA\r\nkey. However, the private exponent seems to be encrypted in some way. Not only that, but the whole key blob's\r\nauthenticity is verified by using an HMAC. So where is the encryption key stored? Where is the HMAC key\r\nstored? We'll have to reverse-engineer the KeyMaster module to find out.\r\nLet's take a look at the KeyMaster trustlet's implementation of the KEYMASTER_SIGN_DATA command. The\r\nfunction starts with some boilerplate validations in order to make sure the supplied parameters are valid. We'll skip\r\nthose, since they aren't the focus of this post. After verifying all the parameters, the function maps-in the user-supplied data buffer, so that it will be accessible to the \"Secure World\". Eventually, we reach the \"core\" logic of\r\nthe function:\r\nOkay, we're definitely getting somewhere!\r\nFirst of all, we can see that the code calls some function which I've taken the liberty of calling\r\nget_some_kind_of_buffer, and stores the results in the variables buffer_0 and buffer_1. Immediately after\r\nretrieving these buffers, the code calls the qsee_hmac function in order to calculate the HMAC of the first 0x624\r\nbytes of the user-supplied key blob. This makes sense, since the size of the key blob structure we've seen before is\r\nexactly 0x624 bytes (without the HMAC field).\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 8 of 18\n\nBut wait! We've already seen the qsee_hmac function before - in the Widevine application. Specifically, we know\r\nit receives the following arguments:\r\nThe variable that we've called buffer_1 is passed in as the fourth argument to qsee_hmac. This can only mean one\r\nthing... It is in fact the HMAC key!\r\nWhat about buffer_0? We can already see that it is used in the function do_something_with_keyblob. Not only\r\nthat, but immediately after calling that function, the signature is calculated and written to the destination buffer.\r\nHowever, as we've previously seen, the private exponent is\r\nencrypted\r\nin the key blob. Obviously the RSA signature cannot be calculated until the private exponent is decrypted... So\r\nwhat does do_something_with_keyblob do? Let's see:\r\nAha! Just as we suspected. The function do_something_with_keyblob simply decrypts the private exponent, using\r\nbuffer_0 as the encryption key!\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 9 of 18\n\nFinally, let's take a look at the function that was used to retrieve the HMAC and encryption keys (now bearing a\r\nmore appropriate name):\r\nAs we can see in the code above, the HMAC key and the encryption key are both generated using some kind of\r\nkey derivation function. Each key is generated by invoking the KDF using a pair of hard-coded strings as inputs.\r\nThe resulting derived key is then stored in the KeyMaster application's global buffer, and the pointer to the key is\r\nreturned to the caller. Moreover, if we are to trust the provided strings, the internal key derivation function uses an\r\nactual hardware key, called the SHK, which would no doubt be hard to extract using software...\r\n...But this is all irrelevant! The decapsulation code we have just reverse-engineered has revealed a very important\r\nfact.\r\nInstead of creating a scheme which directly uses the hardware key without ever divulging it to software or\r\nfirmware, the code above performs the encryption and validation of the key blobs using keys which are\r\ndirectly available to the TrustZone software\r\n! Note that the keys are also\r\nconstant\r\n- they are directly derived from the SHK (which is fused into the hardware) and from two \"hard-coded\" strings.\r\nLet's take a moment to explore some of the implications of this finding.\r\nConclusions\r\nThe key derivation is not hardware bound. Instead of using a real hardware key which cannot be\r\nextracted by software (for example, the SHK), the KeyMaster application uses a key derived from the SHK\r\nand directly available to TrustZone.\r\nOEMs can comply with law enforcement to break Full Disk Encryption. Since the key is available to\r\nTrustZone, OEMs could simply create and sign a TrustZone image which extracts the KeyMaster keys and\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 10 of 18\n\nflash it to the target device. This would allow law enforcement to easily brute-force the FDE password off\r\nthe device using the leaked keys.\r\nPatching TrustZone vulnerabilities does not necessarily protect you from this issue. Even on patched\r\ndevices, if an attacker can obtain the encrypted disk image (e.g. by using forensic tools), they can then\r\n\"downgrade\" the device to a vulnerable version, extract the key by exploiting TrustZone, and use them to\r\nbrute-force the encryption. Since the key is derived directly from the SHK, and the SHK cannot be\r\nmodified, this renders all down-gradable devices directly vulnerable.\r\nAndroid FDE is only as strong as the TrustZone kernel or KeyMaster. Finding a TrustZone kernel\r\nvulnerability or a vulnerability in the KeyMaster trustlet, directly leads to the disclosure of the KeyMaster\r\nkeys, thus enabling off-device attacks on Android FDE.\r\nDuring my communication with Qualcomm I voiced concerns about the usage of a software-accessible key\r\nderived from the SHK. I suggested using the SHK (or another hardware key) directly. As far as I know, the SHK\r\ncannot be extracted from software\r\n, and is only available to the cryptographic processors (similarly to Apple's UID). Therefore, using it would thwart\r\nany attempt at off-device brute force attacks (barring the use of specialized hardware to extract the key).\r\nHowever, reality is not that simple. The SHK is used for many different purposes. Allowing the user to directly\r\nencrypt data using the SHK would compromise those use-cases. Not only that, but the KeyMaster application is\r\nwidely used in the Android operating-system. Modifying its behaviour could \"break\" applications which rely on it.\r\nLastly, the current design of the KeyMaster application doesn't differentiate between requests which use the\r\nKeyMaster application for Android FDE and other requests for different use-cases. This makes it harder to\r\nincorporate a fix which only modifies the KeyMaster application. \r\nRegardless, I believe this issue underscores the need for a solution that entangles the full disk encryption key with\r\nthe device's hardware in a way which cannot be bypassed using software. Perhaps that means redesigning the\r\nFDE's KDF. Perhaps this can be addressed using additional hardware. I think this is something Google and OEMs\r\nshould definitely get together and think about.\r\nExtracting the KeyMaster Keys\r\nNow that we've set our sights on the KeyMaster keys, we are still left with the challenge of extracting the keys\r\ndirectly from TrustZone.\r\nPreviously on the zero-to-TrustZone series of blog posts, we've discovered an exploit which allowed us to achieve\r\ncode-execution within QSEE, namely, within the Widevine DRM application. However, is that enough?\r\nPerhaps we could read the keys directly from the KeyMaster trustlet's memory from the context of the hijacked\r\nWidevine trustlet? Unfortunately, the answer is no. Any attempt to access a different QSEE application's memory\r\ncauses an XPU violation, and subsequently crashes the violating trustlet (even when switching to a kernel\r\ncontext). What about calling the same KDF used by the KeyMaster module to generate the keys from the context\r\nof the Widevine trustlet? Unfortunately the answer is no once again. The KDF is only present in the KeyMaster\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 11 of 18\n\napplication's code segment, and QSEE applications cannot modify their own code or allocate new executable\r\npages.\r\nLuckily, we've also previously discovered an additional privilege escalation from QSEE to the TrustZone kernel.\r\nSurely code execution within the TrustZone kernel would allow us to hijack any QSEE application! Then, once we\r\ncontrol the KeyMaster application, we can simply use it to leak the HMAC and encryption keys and call it a day.\r\nRecall that in the previous blog post we reverse-engineered the mechanism behind the invocation of system calls\r\nin the TrustZone kernel. Doing so revealed that most system-calls are invoked indirectly by using a set of\r\nglobally-stored pointers, each of which pointing to a different table of supported system-calls. Each system-call\r\ntable simply contained a bunch of consecutive 64-bit entries; a 32-bit value representing the syscall number,\r\nfollowed by a 32-bit pointer to the syscall handler function itself. Here is one such table:\r\nSince these tables are used by all QSEE trustlets, they could serve as a highly convenient entry point in order to\r\nhijack the code execution within the KeyMaster application!\r\nAll we would need to do is to overwrite a system-call handler entry in the table, and point it to a function of our\r\nown. Then, once the KeyMaster application invokes the target system-call, it would execute our own handler\r\ninstead of the original one! This also enables us not to worry about restoring execution after executing our code,\r\nwhich is a nice added bonus. \r\nBut there's a tiny snag - in order to direct the handler at a function of our own, we need some way to allocate a\r\nchunk of code which will be globally available in the \"Secure World\". This is because, as mentioned above,\r\ndifferent QSEE applications cannot access each other's memory segments. This renders our previous method of\r\noverwriting the code segments of the Widevine application useless in this case. However, as we've seen in the\r\npast, the TrustZone Kernel's code segments (which are accessible to all QSEE application when executing in\r\nkernel context) are protected using a special hardware component called an XPU. Therefore, even when running\r\nwithin the TrustZone kernel and disabling access protection faults in the ARM MMU, we are still unable to\r\nmodify them.\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 12 of 18\n\nThis is where some brute-force comes in handy... I've written a small snippet of code that quickly iterates over all\r\nof the TrustZone Kernel's code segments, and attempts to modify them. If there is any (mistakenly?) XPU-unprotected region, we will surely find it. Indeed, after iterating through the code segments, one rather large\r\nsegment, ranging from addresses 0xFE806000 to 0xFE810000, appeared to be unprotected!\r\nSince we don't want to disrupt the regular operation of the TrustZone kernel, it would be wise to find a small code-cave in that region, or a small chunk of code that would be harmless to overwrite. Searching around for a bit\r\nreveals a small bunch of logging strings in the segment - surely we can overwrite them without any adverse\r\neffects:\r\nNow that we have a modifiable code cave in the TrustZone kernel, we can proceed to write a small stub that, when\r\ncalled, will exfiltrate the KeyMaster keys directly from the KeyMaster trustlet's memory!\r\nLastly, we need a simple way to cause the KeyMaster application to execute the hijacked system-call. Remember,\r\nwe can easily send commands to the KeyMaster application which, in turn, will cause the KeyMaster application\r\nto call quite a few system-calls. Reviewing the KeyMaster's key-generation command reveals that one good\r\ncandidate to hijack would be the \"qsee_hmac\" system-call:\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 13 of 18\n\nKeyMaster's \"Generate Key\" Flow\r\nWhere qsee_hmac's signature is:\r\nThis is a good candidate for a few reasons:\r\n1. The \"data\" argument that's passed in is a buffer that's shared with the non-secure world. This means\r\nwhatever we write to it can easily retrieved after returning from the \"Secure World\".\r\n2. The qsee_hmac function is not called very often, so hijacking it for a couple of seconds would probably be\r\nharmless.\r\n3. The function receives the address of the HMAC key as one of the arguments. This saves us the need to find\r\nthe KeyMaster application's address dynamically and calculate the addresses of the keys in memory.\r\nFinally, all our shellcode would have to do is to read the HMAC and encryption keys from the KeyMaster\r\napplication's global buffer (at the locations we saw earlier on), and \"leak\" them into the shared buffer. After\r\nreturning from the command request, we could then simply fish-out the leaked keys from the shared buffer. Here's\r\na small snippet of THUMB assembly that does just that:\r\nShellcode which leaks KeyMaster Keys\r\nPutting it all together\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 14 of 18\n\nFinally, we have all the pieces of the puzzle. All we need to do in order to extract the KeyMaster keys is to:\r\nEnable the DACR in the TrustZone kernel to allow us to modify the code cave.\r\nWrite a small shellcode stub in the code cave which reads the keys from the KeyMaster application.\r\nHijack the \"qsee_hmac\" system-call and point it at our shellcode stub.\r\nCall the KeyMaster's key-generation command, causing it to trigger the poisoned system-call and exfiltrate\r\nthe keys into the shared buffer.\r\nRead the leaked keys from the shared buffer. \r\nHere's a diagram detailing all of these steps:\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 15 of 18\n\nThe Code\r\nFinally, as always, I've provided the full source code for the attack described above. The code builds upon the two\r\npreviously disclosed issues in the zero-to-TrustZone series, and allows you to leak the KeyMaster keys directly\r\nfrom your device! After successfully executing the exploit, the KeyMaster keys should be printed to the console,\r\nlike so:\r\nYou can find the full source code of the exploit here:\r\nhttps://github.com/laginimaineb/ExtractKeyMaster\r\nI've also written a set of python scripts which can be used to brute-force Android full disk encryption off the\r\ndevice. You can find the scripts here:\r\nhttps://github.com/laginimaineb/android_fde_bruteforce\r\nSimply invoke the python script fde_bruteforce.py using:\r\nThe crypto footer from the device\r\nThe leaked KeyMaster keys\r\nThe word-list containing possible passwords\r\nCurrently, the script simply enumerates each password from a given word-list, and attempts to match the\r\nencryption result with the \"scrypted intermediate key\" stored in the crypto footer. That is, it passes each word in\r\nthe word-list through the Android FDE KDF, scrypts the result, and compares it to the value stored in the crypto\r\nfooter. Since the implementation is fully in python, it is rather slow... However, those seeking speed could port it\r\nto a much faster platform, such as hashcat/oclHashcat.\r\nHere's what it looks like after running it on my own Nexus 6, encrypted using the password \"secret\":\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 16 of 18\n\nLastly, I've also written a script which can be used to decrypt already-generated KeyMaster key blobs. If you\r\nsimply have a KeyMaster key blob that you'd like to decrypt using the leaked keys, you can do so by invoking the\r\nscript km_keymaster.py, like so:\r\nFinal Thoughts\r\nFull disk encryption is used world-wide, and can sometimes be instrumental to ensuring the privacy of people's\r\nmost intimate pieces of information. As such, I believe the encryption scheme should be designed to be as \"bullet-proof\" as possible, against all types of adversaries. As we've seen, the current encryption scheme is far from\r\nbullet-proof, and can be hacked by an adversary or even broken by the OEMs themselves (if they are coerced to\r\ncomply with law enforcement).\r\nI hope that by shedding light on the subject, this research will motivate OEMs and Google to come together and\r\nthink of a more robust solution for FDE. I realise that in the Android ecosystem this is harder to guarantee, due to\r\nthe multitude of OEMs. However, I believe a concentrated effort on both sides can help the next generation of\r\nAndroid devices be truly \"uncrackable\".\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 17 of 18\n\nSource: https://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nhttps://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html\r\nPage 18 of 18",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://bits-please.blogspot.in/2016/06/extracting-qualcomms-keymaster-keys.html"
	],
	"report_names": [
		"extracting-qualcomms-keymaster-keys.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434918,
	"ts_updated_at": 1775791325,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/defe5d06c6841b14d984e768e5f371f8de681ec5.pdf",
		"text": "https://archive.orkl.eu/defe5d06c6841b14d984e768e5f371f8de681ec5.txt",
		"img": "https://archive.orkl.eu/defe5d06c6841b14d984e768e5f371f8de681ec5.jpg"
	}
}