Using Cryptokit.SecureEnclave API from a Launch Daemon

We are interested in using a hardware-bound key in a launch daemon. In a previous post, Quinn explicitly told me this is not possible to use an SE keypair outside of the system context and my reading of the Apple documentation also supports that.

That said, we have gotten the following key-creation and persistence flow to work, so we have some questions as to how this fits in with the above.

(1) In a launch daemon (running thus as root), we do:

let key = SecureEnclave.P256.Signing.PrivateKey()

(2) We then use

key.dataRepresentation

to store a reference to the key in the system keychain as a kSecClassGenericPassword.

(3) When we want to use the key, we fetch the data representation from system keychain and we "rehydrate" the key using:

SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: data)

(4) We then use the output of the above to sign whatever we want.

My questions:

  • in the above flow, are we actually getting a hardware-bound key from the Secure Enclave or is this working because it's actually defaulting to a non-hardware-backed key?
  • if it is an SE key, is it that the Apple documentation stating that you can only use the SE with the Data Protection Keychain in the user context is outdated (or wrong)?
  • does the above work, but is not an approach sanctioned by Apple?

Any feedback on this would be greatly appreciated.

Answered by DTS Engineer in 857190022

Using the SE from a launchd daemon is not supported. Please don’t go down this path.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

Using the SE from a launchd daemon is not supported. Please don’t go down this path.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks very much for the quick reply - it is very helpful!

To follow-up, am I correct in that the problem is that we are storing the raw representation in the system - and thus a file system-based - keychain?

In another post, you directed someone to a post on storing CryptoKit keys. That post discusses storing the raw representation in the keychain, so I'm inferring that the problem with our approach is the choice of keychain. In digging through the code, I see that the raw representation is stored using

kSecUseDataProtectionKeychain: true,

Since we are storing in the system keychain, we obviously don't use the Data Protection Keychain.

Thus, what I'm taking away from your response is that the fact that we are not using the DPK is the fundamental problem with our approach?

And the fact that we don't use the DPK compromises the security of our approach?

Or are there other problems as well?

Thanks in advance for your help on this!

Using Cryptokit.SecureEnclave API from a Launch Daemon
 
 
Q