-
Notifications
You must be signed in to change notification settings - Fork 196
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
[Pal/Linux-SGX] RFC: Support for Microsoft Azure Attestation #626
Comments
I like this proposal as it keeps attestation library preloaded in Gramine very simple where its sole job is to send the attestation evidence (quote) offer an RA-TLS channel to trusted Relying party. For full solution we will likely need to integrate with AKV as I can see that the next step after verification is to extract the secret from AKV using the token and sending to Gramine over RA-TLS channel. I guess that can be a new sample secret provisioning library. While this works, I wonder if MSFT plans to provide a sample relying party/client implementation? Otherwise each of the LibOS implementation will have their own sample Relying party code. |
For the RA-TLS use case, it makes perfect sense to me to have both the Client and the Relying Party role in the verify lib. All assumptions taken here seem correct to me. If you ever want Gramine to directly provide the JWT attestation token (e.g., developers should be able to write Relying Parties without requiring your libs), you can probably move the Client code to the enclave host, so that you don't have to add dependencies within the enclave or increase its TCB. |
Some updates
Reply to @monavij
Yes, this is exactly my plan. It actually fits nicely with the current Gramine libs:
There is this sample implementation: https://github.com/azure-samples/microsoft-azure-attestation/. It has the samples for OpenEnclave and Intel SGX SDK. However, these samples are written in a rather ad-hoc way and in C# language. Reply to @thomasten
This sounds cumbersome to implement for these reasons:
We could add this in the future, when JWT becomes a real standard. But for now we will try the path of no-modifications to core Gramine, when we add support for each new cloud-vendor-specific attestation scheme. After all, the application on top of Gramine can implement all this logic -- get the SGX quote via |
This is wrong. We don't need to add TODO: edit the root comment here. UPDATE: done. |
TODO: I was wrong about the UPDATE: done. |
@dimakuv |
No, the client side performs an MAA flow, as part of the RA-TLS flow. So, during RA-TLS handshake, the client side extracts the SGX quote and sends it to MAA for verification and gets back from MAA the attestation token.
The attesting backend (the Gramine SGX enclave) is never an "MAA type". There is no such thing as an "MAA SGX quote". The attesting backend generates the classic DCAP SGX quote -- this is what the MAA attestation scheme uses (it was always like that). So, the attesting backend has no changes at all, it just generates the classic DCAP SGX quote, as it used to do. The attestating backend knows nothing about MAA at all. |
Apologies- i mixed up the terminology. I meant to say - the host enclave - performs a regular RA-TLS flow unaware of what flow the verifier is going to take (MAA or directly use DCAP libs). |
Yes, this is exactly correct. |
I added a |
Microsoft Azure Attestation (MAA)
Microsoft Azure cloud provides its own service to attest enclaves, called Microsoft Azure Attestation (MAA), or simply Azure Attestation. MAA is a generic service that works on different TEEs, but we concentrate only on Intel SGX enclaves here.
Concepts and definitions
MAA contains several concepts. For purposes of integration with Gramine, we need to understand the following concepts:
attest/
), to get/set signing certificates for attestation tokens (certs/
), to get/set/reset attestation policies (policies/
), to get/set signing certificates for attestation policies (certificates/
). We only care about the first two endpoint APIs (attest/
andcerts/
) here.sgx_quote.sgx_report.user_report_data
."x-ms-sgx-is-debuggable": true
and"x-ms-sgx-mrsigner": <SGX enclave msrigner value>
.certs/
, see here for details.xxx.yyy.zzz
wherexxx
is the JWT header,yyy
is the JWT payload andzzz
is the JWT signature. All three parts are encoded in Base64Url. For the case of RS256 algorithm, the signature looks like this:RSA(SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload)), rsa-private-key)
and the signature verification looks like this:RSA(SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload)), rsa-public-key)
.And we can ignore the following concepts:
We ignore attestation policies because they are set up by users before deploying Gramine SGX enclaves. This setup happens through other means -- typically through the web-based Azure Portal or CLI-based
az
tool. In other words, management of attestation policies is orthogonal to Gramine execution.MAA flows
Here is a diagram that illustrates the flows, taken from the Intel SGX enclave validation workflow docs of MAA:
One important point here is that the Client and the Relying Party can be the same entity (located on the trusted remote-user machine). This is the "deployment" that we will assume for Gramine, because it is similar to how Gramine currently performs IAS EPID attestation: the enclave machine sends the SGX quote to the relying party/client, and the latter sends this SGX quote in the attestation request to IAS and receives back the attestation response.
Another important point here is the
OpenID Metadata Endpoint
in step 4. This is actually thecerts/
REST endpoint of the attestation provider. What happens in this step is actually:GET https://mytenant.attest.azure.net/certs
HTTPS request. Note that the relying party/client must start a TLS (HTTPS) connection with the attestation provider, and verify that the X.509 cert chain of the attestation provider ends up in the root Microsoft Azure certificate.keys
. Eachkey
has a fieldx5c
-- a JSON array of base64url-encoded DER certificates. In the end, one of the returned certificates must be the attestation signing certificate (that signed the JWT).Comparison with Intel Attestation Service (IAS)
The MAA attestation flow is similar to the EPID (IAS) attestation flow:
/attestation/v3/report
endpoint. See the details here.attest/
endpoint. See the details here.certs/
REST endpoint.certs/
endpoint is accessed via the GET request and returns a set ofkeys
.keys
has a string fieldkid
. The JWT also has a string fieldkid
. The JWT is signed with the key that has the matchingkid
.keys
, the first certificate in thex5c
array of certificates should be extracted, base64-decoded, and it will be a properly formatted self-signed X.509 certificate.Example from Edgeless EGo
Edgeless EGo has a nice example that shows yet another deployment for MAA:
I do not like this deployment: it requires that the SGX enclave not only generates the SGX Quote, but also that it establishes an HTTPS connection to the MS Azure attestation provider. Implementing this case in Gramine would add many dependencies: curl with HTTPS, a JSON parser, maybe a JWT/JWK parser. This unnecessarily increases the TCB.
Proposed changes for Gramine
This is my vision for MAA integration:
My proposal shifts all burden of communication with Microsoft Azure Attestation (with the attestation provider's
attest/
andcerts/
endpoints) to the relying party/client.This means that Gramine itself (the SGX enclave) only does the same thing as it did before: generates the SGX quote.
Similarly, the RA-TLS "attest" library inside the SGX enclave does the same thing as it did before: stashes the generated SGX quote into the generated self-signed X.509 certificate, and uses this certificate for the TLS handshake with the relying party/client.
Therefore, we don't need any changes to the core Gramine, and we add a new "verify" library to RA-TLS. For the context, this is how the RA-TLS libraries look today:
And with my proposed changes, we will add a new library:
Implementation steps
sgx.remote_attestation = true
withsgx.remote_attestation = "none" | "epid" | "dcap"
sgx.remote_attestation = "[none|epid|dcap]"
#638/dev/attestation/type
that will return one ofnone
,epid
ordcap
g_pal_public_state
, populated during SGX PAL init and read by LibOSsgx.remote_attestation = "[none|epid|dcap]"
#638libra_tls_verify_maa.so
to RA-TLSlibra_tls_attest.so
library that executes inside the SGX enclave is left unmodified)RA_TLS_MAA_PROVIDER_URL
(no default, must be provided)RA_TLS_MAA_PROVIDER_API_VERSION
(default is2020-10-01
)attest/
requestcerts/
requestra-tls-mbedtls
to support MAA modera-tls-secretprov
to support MAA modeTesting on MS Azure
To test MAA, we need a proper MS Azure subscription. After signing in with this subscription, we should prepare the SGX environment like this:
az-dcap-client
) manually, it will be installed together with OpenEnclave in the next step.I tested this on Azure CC VM and Ubuntu 18.04. For the first step, I followed the Intel internal guide to create CC VMs. For step 5, I had to slightly change the PATH setting:
export PATH=/usr/local/go/bin:$PATH
, otherwise Ubuntu picked the system-wide installed old version of Go. The rest was easy.sharedcus.cus.attest.azure.net
regional shared attestation provider.shareduks.uks.attest.azure.net
regional shared attestation provider.Useful links
Official Microsoft documentation:
MAA example code:
Previous attempts
I experimented with MAA almost two years ago, but that effort was abandoned for several reasons:
Here are the relevant issues/PRs from those times:
Some other related issues:
The text was updated successfully, but these errors were encountered: