-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
init/tee: Add snp_attest() and KBS CHALLENGE
The initial phase of a KBS attestation is the CHALLENGE. The CHALLENGE serves as the function that an attestation server uses to generate an ephermal nonce and send it back to the client for inclusion in the SNP attestation report. Signed-off-by: Tyler Fanelli <[email protected]>
- Loading branch information
1 parent
742c212
commit eace3c8
Showing
8 changed files
with
352 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef _KBS | ||
#define _KBS | ||
|
||
#include <curl/curl.h> | ||
|
||
// kbs_util.c | ||
char *tee_str(int); | ||
|
||
/* | ||
* Identifiers for all possible TEE architectures. | ||
*/ | ||
enum tee { | ||
TEE_SEV, | ||
TEE_SGX, | ||
TEE_SNP, | ||
TEE_TDX, | ||
}; | ||
|
||
/* | ||
* The type of KBS operation to be performed. | ||
*/ | ||
enum curl_post_type { | ||
KBS_CURL_REQ, | ||
}; | ||
|
||
// kbs_types.c | ||
int kbs_request_marshal(char *, int, char *); | ||
int kbs_challenge(CURL *, char *, char *, char *); | ||
|
||
// kbs_curl.c | ||
int kbs_curl_post(CURL *, char *, char *, char *, int); | ||
|
||
#endif /* _KBS */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <curl/curl.h> | ||
|
||
#include "kbs.h" | ||
|
||
static CURLcode kbs_curl_set_headers(CURL *, char *); | ||
static int KBS_CURL_ERR(char *); | ||
size_t curl_write(void *, size_t, size_t, void *); | ||
|
||
static int kbs_curl_post_request(CURL *, char *, char *, char *); | ||
|
||
/* | ||
* Complete a cURL POST request. POST the "in" string and retrieve the contents | ||
* of the POST request "out" string. | ||
* | ||
* Depending on the type of request, some extra headers may need to be set. | ||
* For example, on a KBS REQUEST, no session ID has been retrieved from the | ||
* attestation server so far. Yet, during a KBS_ATTEST request, a session ID | ||
* has been given from the server and must be added to the headers. | ||
*/ | ||
int | ||
kbs_curl_post(CURL *curl, char *url, char *in, char *out, int type) | ||
{ | ||
CURLcode code; | ||
|
||
/* | ||
* Neither the input or output strings should be invalid/NULL. | ||
*/ | ||
if (!in) | ||
return KBS_CURL_ERR("Input argument NULL"); | ||
|
||
if (!out) | ||
return KBS_CURL_ERR("Output argument NULL"); | ||
|
||
/* | ||
* Specify the following cURL operations/attributes: | ||
* * Headers | ||
* * POST operation | ||
* * Write function | ||
*/ | ||
code = kbs_curl_set_headers(curl, NULL); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_HTTPHEADER"); | ||
|
||
code = curl_easy_setopt(curl, CURLOPT_POST, 1L); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_POST"); | ||
|
||
code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_WRITEFUNCTION"); | ||
|
||
/* | ||
* Based on the operation TYPE, there will need to be some additional | ||
* cURL attributes set. These will also perform the cURL request. | ||
*/ | ||
switch (type) { | ||
case KBS_CURL_REQ: | ||
return kbs_curl_post_request(curl, url, in, out); | ||
default: | ||
return KBS_CURL_ERR("Type argument invalid"); | ||
} | ||
} | ||
|
||
/* | ||
* Set the cURL headers. If the session args is not NULL, that indicates that | ||
* the session ID has been retrieved from attestation server before, and that | ||
* session ID should be included in the headers. | ||
*/ | ||
static CURLcode | ||
kbs_curl_set_headers(CURL *curl, char *session) | ||
{ | ||
struct curl_slist *slist; | ||
char session_buf[100]; | ||
|
||
slist = NULL; | ||
slist = curl_slist_append(slist, "Accept: application/json"); | ||
slist = curl_slist_append(slist, | ||
"Content-Type: application/json; charset=utf-8"); | ||
|
||
/* | ||
* Add the session ID cookie if the session ID exists. | ||
*/ | ||
if (session) { | ||
sprintf(session_buf, "Cookie: session_id=%s", session); | ||
curl_slist_append(slist, session_buf); | ||
} | ||
|
||
/* | ||
* Set the headers. | ||
*/ | ||
return curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); | ||
} | ||
|
||
/* | ||
* POST a KBS REQUEST and attempt to retrieve a nonce from the attestation | ||
* server. | ||
*/ | ||
static int | ||
kbs_curl_post_request(CURL *curl, char *url, char *req, char *nonce) | ||
{ | ||
CURLcode code; | ||
char req_url[100]; | ||
|
||
/* | ||
* Set the cURL POST URL to $URL/kbs/v0/auth. | ||
*/ | ||
sprintf(req_url, "%s/kbs/v0/auth", url); | ||
|
||
code = curl_easy_setopt(curl, CURLOPT_URL, req_url); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_URL"); | ||
|
||
/* | ||
* Set the KBS REQUEST size and data. | ||
*/ | ||
code = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(req)); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_POSTFIELDSIZE"); | ||
|
||
code = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_POSTFIELDS"); | ||
|
||
/* | ||
* We would like the nonce written to the "nonce" argument. | ||
*/ | ||
code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, nonce); | ||
if (code != CURLE_OK) | ||
return KBS_CURL_ERR("CURLOPT_WRITEDATA"); | ||
|
||
code = curl_easy_perform(curl); | ||
if (code != CURLE_OK && code != CURLE_WRITE_ERROR) | ||
return KBS_CURL_ERR("CURL_EASY_PERFORM"); | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* Based on the given cURL error, print the KBS error and return an error | ||
* indicator. | ||
*/ | ||
static int | ||
KBS_CURL_ERR(char *errmsg) | ||
{ | ||
printf("ERROR (kbs_curl_post): %s\n", errmsg); | ||
|
||
return -1; | ||
} | ||
|
||
/* | ||
* Simple strcpy() for attestation server responses. Required by a cURL | ||
* operation that writes data. | ||
*/ | ||
size_t | ||
curl_write(void *data, size_t size, size_t nmemb, void *userp) | ||
{ | ||
strcpy((char *) userp, (char *) data); | ||
|
||
return size; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <stdio.h> | ||
|
||
#include "kbs.h" | ||
|
||
/* | ||
* Given a TEE architecture and workload ID, write the JSON string of the | ||
* KBS REQUEST. | ||
*/ | ||
int | ||
kbs_request_marshal(char *json_request, int tee, char *workload_id) | ||
{ | ||
char *teestr; | ||
|
||
/* | ||
* Retrieve the KBS string equivalent of the TEE enum value. | ||
*/ | ||
teestr = tee_str(tee); | ||
if (teestr == NULL) | ||
return -1; | ||
|
||
/* | ||
* Build the KBS REQUEST JSON string. | ||
*/ | ||
sprintf(json_request, | ||
"{\"extra-params\":\"{\\\"workload_id\\\":\\\"%s\\\"}\",\"tee\":\"%s\",\"version\":\"0.0.0\"}", | ||
workload_id, | ||
teestr); | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* Peform a KBS CHALLENGE. | ||
* | ||
* "json_request" is the JSON string of the KBS REQUEST. | ||
* "nonce" is the output argument to be retrieved from the attestation server. | ||
*/ | ||
int | ||
kbs_challenge(CURL *curl, char *url, char *json_request, char *nonce) | ||
{ | ||
int ret; | ||
|
||
ret = kbs_curl_post(curl, url, (void *) json_request, (void *) nonce, KBS_CURL_REQ); | ||
if (ret < 0) { | ||
printf("ERROR: could not complete KBS challenge\n"); | ||
return -1; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <stdio.h> | ||
|
||
#include "kbs.h" | ||
|
||
/* | ||
* Return the string identifier of the inputted TEE architecture. | ||
*/ | ||
char * | ||
tee_str(int tee) | ||
{ | ||
switch (tee) { | ||
case TEE_SEV: | ||
return "sev"; | ||
case TEE_SGX: | ||
return "sgx"; | ||
case TEE_SNP: | ||
return "snp"; | ||
case TEE_TDX: | ||
return "tdx"; | ||
|
||
/* | ||
* No other TEE architecture is supported. | ||
*/ | ||
default: | ||
printf("ERROR: tee_str(): Invalid input\n"); | ||
return NULL; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <stdio.h> | ||
#include <stddef.h> | ||
|
||
#include "snp_attest.h" | ||
#include "kbs/kbs.h" | ||
|
||
#define NONCE_MAX 1024 | ||
#define JSON_MAX 1024 | ||
|
||
static int SNP_ATTEST_ERR(char *); | ||
|
||
int | ||
snp_attest(char *pass, char *url, char *wid) | ||
{ | ||
CURL *curl; | ||
char nonce[NONCE_MAX], json[JSON_MAX]; | ||
|
||
if (kbs_request_marshal(json, TEE_SNP, wid) < 0) | ||
return SNP_ATTEST_ERR("Unable to marshal KBS REQUEST"); | ||
|
||
curl = curl_easy_init(); | ||
if (curl == NULL) | ||
return SNP_ATTEST_ERR("Unable to initialize cURL instance"); | ||
|
||
if (kbs_challenge(curl, url, json, nonce) < 0) | ||
return SNP_ATTEST_ERR("Unable to retrieve nonce from server"); | ||
|
||
return 0; | ||
} | ||
|
||
static int | ||
SNP_ATTEST_ERR(char *errmsg) | ||
{ | ||
printf("SNP ATTEST ERROR: %s\n", errmsg); | ||
|
||
return -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef _SNP_ATTEST | ||
#define _SNP_ATTEST | ||
|
||
// snp_attest.c | ||
int snp_attest(char *, char *, char *); | ||
|
||
#endif /* _SNP_ATTEST */ |