From 46f37527658dcde826e271eaa77b9cfd718774be Mon Sep 17 00:00:00 2001 From: chen zheng Date: Fri, 20 Oct 2023 10:12:46 +0800 Subject: [PATCH 1/8] format code --- attestation/tee/tverlib/verifier/common.h | 73 +- .../tee/tverlib/verifier/teeverifier.c | 3168 ++++++++--------- .../tee/tverlib/verifier/teeverifier.h | 19 +- 3 files changed, 1590 insertions(+), 1670 deletions(-) diff --git a/attestation/tee/tverlib/verifier/common.h b/attestation/tee/tverlib/verifier/common.h index e60198a..bb56ed2 100644 --- a/attestation/tee/tverlib/verifier/common.h +++ b/attestation/tee/tverlib/verifier/common.h @@ -9,14 +9,14 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ -#include -#include +#include "teeverifier.h" #include -#include -#include -#include #include -#include "teeverifier.h" +#include +#include +#include +#include +#include #define USER_DATA_SIZE 64 #define NODE_LEN 8 @@ -37,24 +37,22 @@ See the Mulan PSL v2 for more details. #define RA_INTEGER (1 << KEY_TAG_TYPE_MOVE_BITS) #define RA_BYTES (2 << KEY_TAG_TYPE_MOVE_BITS) -#define RA_SCENARIO_NO_AS "sce_no_as" -#define RA_SCENARIO_AS_NO_DAA "sce_as_no_daa" -#define RA_SCENARIO_AS_WITH_DAA "sce_as_with_daa" -#define RA_SCENARIO_NO_AS_INT 0 -#define RA_SCENARIO_AS_NO_DAA_INT 1 +#define RA_SCENARIO_NO_AS "sce_no_as" +#define RA_SCENARIO_AS_NO_DAA "sce_as_no_daa" +#define RA_SCENARIO_AS_WITH_DAA "sce_as_with_daa" +#define RA_SCENARIO_NO_AS_INT 0 +#define RA_SCENARIO_AS_NO_DAA_INT 1 #define RA_SCENARIO_AS_WITH_DAA_INT 2 -#define RA_HASH_ALG_SHA256 "HS256" -#define RA_SIGN_ALG_RSA4096 "PS256" -#define RA_VERSION "TEE.RA.1.0" +#define RA_HASH_ALG_SHA256 "HS256" +#define RA_SIGN_ALG_RSA4096 "PS256" +#define RA_VERSION "TEE.RA.1.0" -struct ra_data_offset -{ +struct ra_data_offset { uint32_t data_len; uint32_t data_offset; }; -enum ra_alg_types -{ +enum ra_alg_types { RA_ALG_RSA_3072 = 0x20000, RA_ALG_RSA_4096 = 0x20001, // PSS padding RA_ALG_SHA_256 = 0x20002, @@ -66,8 +64,7 @@ enum ra_alg_types RA_ALG_SM3 = 0x20008, }; -enum ra_tags -{ +enum ra_tags { /*Integer Type*/ RA_TAG_SIGN_TYPE = RA_INTEGER | 0, RA_TAG_HASH_TYPE = RA_INTEGER | 1, @@ -85,18 +82,15 @@ enum ra_tags RA_TAG_CERT_AK = RA_BYTES | 9, }; -struct __attribute__((__packed__)) ra_params -{ +struct __attribute__((__packed__)) ra_params { uint32_t tags; - union - { + union { uint32_t integer; struct ra_data_offset blob; } data; }; -typedef struct tee_uuid -{ +typedef struct tee_uuid { uint32_t timeLow; uint16_t timeMid; uint16_t timeHiAndVersion; @@ -104,8 +98,7 @@ typedef struct tee_uuid } TEE_UUID; // the content of *buf(in buffer_data) be like... -typedef struct __attribute__((__packed__)) report_response -{ +typedef struct __attribute__((__packed__)) report_response { uint32_t version; uint64_t ts; uint8_t nonce[USER_DATA_SIZE]; @@ -122,8 +115,7 @@ typedef struct __attribute__((__packed__)) report_response */ } report_get; -typedef struct -{ +typedef struct { uint8_t version[VERSION_SIZE]; uint8_t timestamp[TS_SIZE]; uint8_t nonce[USER_DATA_SIZE]; @@ -141,8 +133,7 @@ typedef struct } TA_report; #define KEY_PURPOSE_SIZE 32 // test -struct ak_cert -{ +struct ak_cert { uint32_t version; uint64_t ts; char purpose[KEY_PURPOSE_SIZE]; @@ -158,10 +149,10 @@ struct ak_cert */ } __attribute__((__packed__)); -//static int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, char *filename); -//static int tee_verify_report2(buffer_data *buf_data, int type, base_value *baseval); -//static int tee_validate_report(buffer_data *buf_data, buffer_data *nonce); -static bool tee_verify_nonce(buffer_data *buf_data,buffer_data *nonce); +// static int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, char *filename); +// static int tee_verify_report2(buffer_data *buf_data, int type, base_value *baseval); +// static int tee_validate_report(buffer_data *buf_data, buffer_data *nonce); +static bool tee_verify_nonce(buffer_data *buf_data, buffer_data *nonce); static bool tee_verify_signature(buffer_data *report); static bool tee_verify(buffer_data *buf_data, int type, char *filename); static bool tee_verify2(buffer_data *bufdata, int type, base_value *baseval); @@ -182,17 +173,19 @@ static bool Compare(int type, TA_report *report, base_value *basevalue); static bool cmp_bytes(const uint8_t *a, const uint8_t *b, size_t size); static void test_print(uint8_t *printed, int printed_size, char *printed_name); static void save_basevalue(const base_value *bv); -//verifysig +// verifysig static bool verifysig(buffer_data *data, buffer_data *sign, buffer_data *akcert, uint32_t scenario); static bool translateBuf(buffer_data report, TA_report *tareport); -static bool getDataFromAkCert(buffer_data *akcert, buffer_data *signdata, buffer_data *signdrk, buffer_data *certdrk, buffer_data *akpub); +static bool getDataFromAkCert(buffer_data *akcert, buffer_data *signdata, buffer_data *signdrk, buffer_data *certdrk, + buffer_data *akpub); static EVP_PKEY *buildPubKeyFromModulus(buffer_data *pub); static EVP_PKEY *getPubKeyFromDrkIssuedCert(buffer_data *cert); static bool verifySigByKey(buffer_data *mhash, buffer_data *sign, EVP_PKEY *key); static EVP_PKEY *getPubKeyFromCert(buffer_data *cert, char *root_cert_pathname); static void dumpDrkCert(buffer_data *certdrk); static bool restorePEMCert(uint8_t *data, int data_len, buffer_data *certdrk); -static bool getDataFromReport(buffer_data *report,buffer_data *akcert,buffer_data *signak,buffer_data *signdata,uint32_t *scenario); +static bool getDataFromReport(buffer_data *report, buffer_data *akcert, buffer_data *signak, buffer_data *signdata, + uint32_t *scenario); static bool verifysig_x509cert(buffer_data *data, buffer_data *sign, buffer_data *cert, char *root_cert_pathname); static void uint82str(const uint8_t *source, int source_len, char *dest); @@ -201,7 +194,7 @@ static bool verifyCertByCert(buffer_data *cert, uint8_t *root_cert_pathname); static bool verifydatasig_bykey(buffer_data *data, buffer_data *sign, EVP_PKEY *key); static bool verifysig_drksignedcert(buffer_data *data, buffer_data *sign, buffer_data *cert); static void free_report(TA_report *report); -static TA_report * Convert(buffer_data *data); +static TA_report *Convert(buffer_data *data); static base_value *LoadQTABaseValue(const char *refval); static base_value *get_qta(buffer_data *akcert); static bool CompareBV(int type, base_value *value, base_value *basevalue); diff --git a/attestation/tee/tverlib/verifier/teeverifier.c b/attestation/tee/tverlib/verifier/teeverifier.c index ce60dd1..9aaf752 100644 --- a/attestation/tee/tverlib/verifier/teeverifier.c +++ b/attestation/tee/tverlib/verifier/teeverifier.c @@ -15,102 +15,113 @@ See the Mulan PSL v2 for more details. #include #include -#define _SHA256(d, n, md) \ - { \ - SHA256_CTX ctx; \ - SHA256_Init(&ctx); \ - SHA256_Update(&ctx, d, n); \ - SHA256_Final(md, &ctx); \ - } - -#define _SHA512(d, n, md) \ - { \ - SHA512_CTX ctx; \ - SHA512_Init(&ctx); \ - SHA512_Update(&ctx, d, n); \ - SHA512_Final(md, &ctx); \ - } +#define _SHA256(d, n, md) \ + { \ + SHA256_CTX ctx; \ + SHA256_Init(&ctx); \ + SHA256_Update(&ctx, d, n); \ + SHA256_Final(md, &ctx); \ + } + +#define _SHA512(d, n, md) \ + { \ + SHA512_CTX ctx; \ + SHA512_Init(&ctx); \ + SHA512_Update(&ctx, d, n); \ + SHA512_Final(md, &ctx); \ + } #define HW_IT_PRODUCT_CA_CERT_PATH "./Huawei IT Product CA.pem" #define TAS_ROOT_CERT_PATH "TAS Root Cert.pem" - -#define verifier_error(msg) { printf("%s\n", msg); return NULL;} -#define file_error(msg) { printf("Couldn't open file: %s\n", msg); return NULL;} -//static void free_report(TA_report *report); +#define verifier_error(msg) \ + { \ + printf("%s\n", msg); \ + return NULL; \ + } + +#define file_error(msg) \ + { \ + printf("Couldn't open file: %s\n", msg); \ + return NULL; \ + } + +// static void free_report(TA_report *report); // base64 encode url -void base64urlencode(const uint8_t *src, int src_len, uint8_t *cipher, int *dest_len) { - int cipLen = EVP_EncodeBlock((unsigned char*)cipher, (const unsigned char*)src, src_len); - //change "+" to "-", "/" to "_", remove "=". - for(int i = cipLen - 1; i >= 0; i--) { - if(*(cipher + i) == '+') - *(cipher + i) = '-'; - else if(*(cipher + i) == '/') - *(cipher + i) = '_'; - else if(*(cipher + i) == '=') - //*(cipher + i) = *(cipher + i + 1); - cipLen--; - } - *dest_len = cipLen; - //tlogd("%s", cipher); - return; +void base64urlencode(const uint8_t *src, int src_len, uint8_t *cipher, int *dest_len) +{ + int cipLen = EVP_EncodeBlock((unsigned char *)cipher, (const unsigned char *)src, src_len); + // change "+" to "-", "/" to "_", remove "=". + for (int i = cipLen - 1; i >= 0; i--) { + if (*(cipher + i) == '+') + *(cipher + i) = '-'; + else if (*(cipher + i) == '/') + *(cipher + i) = '_'; + else if (*(cipher + i) == '=') + //*(cipher + i) = *(cipher + i + 1); + cipLen--; + } + *dest_len = cipLen; + // tlogd("%s", cipher); + return; } // base64 decode url -uint8_t * base64urldecode(const uint8_t *src, int src_len, int *dest_len) { - // change "-" to "+", "_" to "/", add back "=". - size_t i = 0; - char *tail1 = "="; - char *tail2 = "=="; - uint8_t *b64 = malloc(sizeof(uint8_t) * (src_len + 3)); - //int dest_len = 0; - memcpy(b64, src, src_len); - for(i = 0; i < src_len; i++) { - if(*(b64 + i) == '-') - *(b64 + i) = '+'; - else if(*(b64 + i) == '_') - *(b64 + i) = '/'; - } - *(b64 + i) = '\0'; - if(src_len % 4 == 2) { - strcat(b64, tail2); - *dest_len = (src_len + 2) / 4 * 3 - 2; - } - else if(src_len % 4 == 3) { - strcat(b64, tail1); - *dest_len = (src_len + 1) / 4 * 3 - 1; - } - else if(src_len % 4 == 0) - *dest_len = src_len / 4 * 3; - - uint8_t *plain = (uint8_t *)malloc(sizeof(uint8_t) * (*dest_len + 6)); - int cipLen = EVP_DecodeBlock((unsigned char*)plain, (const unsigned char*)b64, strlen(b64)); - free(b64); - return plain; -} - -void uint82str(const uint8_t *source, int source_len, char *dest) { +uint8_t *base64urldecode(const uint8_t *src, int src_len, int *dest_len) +{ + // change "-" to "+", "_" to "/", add back "=". + size_t i = 0; + char *tail1 = "="; + char *tail2 = "=="; + uint8_t *b64 = malloc(sizeof(uint8_t) * (src_len + 3)); + // int dest_len = 0; + memcpy(b64, src, src_len); + for (i = 0; i < src_len; i++) { + if (*(b64 + i) == '-') + *(b64 + i) = '+'; + else if (*(b64 + i) == '_') + *(b64 + i) = '/'; + } + *(b64 + i) = '\0'; + if (src_len % 4 == 2) { + strcat(b64, tail2); + *dest_len = (src_len + 2) / 4 * 3 - 2; + } else if (src_len % 4 == 3) { + strcat(b64, tail1); + *dest_len = (src_len + 1) / 4 * 3 - 1; + } else if (src_len % 4 == 0) + *dest_len = src_len / 4 * 3; + + uint8_t *plain = (uint8_t *)malloc(sizeof(uint8_t) * (*dest_len + 6)); + int cipLen = EVP_DecodeBlock((unsigned char *)plain, (const unsigned char *)b64, strlen(b64)); + free(b64); + return plain; +} + +void uint82str(const uint8_t *source, int source_len, char *dest) +{ for (int32_t i = 0; i < source_len; i++) { if ((source[i] >> 4) <= 9) // 0x39 corresponds to the character '9' dest[2 * i] = (source[i] >> 4) + 0x30; else // Otherwise, it is a letter, and 7 symbols need to be skipped dest[2 * i] = (source[i] >> 4) + 0x37; - if ((source[i] % 16) <=9) + if ((source[i] % 16) <= 9) dest[2 * i + 1] = (source[i] % 16) + 0x30; else dest[2 * i + 1] = (source[i] % 16) + 0x37; } } -void str2uint8(const char *source, int dest_len, uint8_t *dest) { +void str2uint8(const char *source, int dest_len, uint8_t *dest) +{ uint8_t HighByte; uint8_t LowByte; for (int i = 0; i < dest_len; i++) { HighByte = toupper(source[i * 2]); LowByte = toupper(source[i * 2 + 1]); - if (HighByte <= 0x39) + if (HighByte <= 0x39) HighByte -= 0x30; else HighByte -= 0x37; @@ -123,259 +134,237 @@ void str2uint8(const char *source, int dest_len, uint8_t *dest) { } // base64 decode for akpub after xxx -bool decodeAKPubKey(cJSON *in, buffer_data *out) { - if (in == NULL) { - printf("akpub is null"); - return false; - } - cJSON *ktyjson = cJSON_GetObjectItemCaseSensitive(in, "kty"); - if (strcmp(ktyjson->valuestring, "RSA") == 0) { - cJSON *njson = cJSON_GetObjectItemCaseSensitive(in, "n"); - // njson needs urlbase64 decode!!!! - uint8_t *tmp1 = (uint8_t *)njson->valuestring; - out->buf = base64urldecode(tmp1, strlen(tmp1), &out->size); - } else if (strcmp(ktyjson->valuestring, "DAA") == 0) { - cJSON *qsjson = cJSON_GetObjectItemCaseSensitive(in, "qs"); - // qsjson needs urlbase64 decode!!!! - uint8_t *tmp2 = (uint8_t *)qsjson->valuestring; - out->buf = base64urldecode(tmp2, strlen(tmp2), &out->size); - } else { - printf("key type error!"); - return false; - } - - return true; -} - -EVP_PKEY * -buildPubKeyFromModulus(buffer_data *pub) -{ - EVP_PKEY *key = NULL; - BIGNUM *e = BN_new(); - BIGNUM *n = BN_new(); - RSA *rsapub = RSA_new(); - if (NULL == e || NULL == n || NULL == rsapub) - goto err; - - key = EVP_PKEY_new(); - if (NULL == key) - goto err; - - BN_set_word(e, 0x10001); - BN_bin2bn(pub->buf, pub->size, n); - - RSA_set0_key(rsapub, n, e, NULL); - EVP_PKEY_set1_RSA(key, rsapub); - RSA_free(rsapub); - return key; +bool decodeAKPubKey(cJSON *in, buffer_data *out) +{ + if (in == NULL) { + printf("akpub is null"); + return false; + } + cJSON *ktyjson = cJSON_GetObjectItemCaseSensitive(in, "kty"); + if (strcmp(ktyjson->valuestring, "RSA") == 0) { + cJSON *njson = cJSON_GetObjectItemCaseSensitive(in, "n"); + // njson needs urlbase64 decode!!!! + uint8_t *tmp1 = (uint8_t *)njson->valuestring; + out->buf = base64urldecode(tmp1, strlen(tmp1), &out->size); + } else if (strcmp(ktyjson->valuestring, "DAA") == 0) { + cJSON *qsjson = cJSON_GetObjectItemCaseSensitive(in, "qs"); + // qsjson needs urlbase64 decode!!!! + uint8_t *tmp2 = (uint8_t *)qsjson->valuestring; + out->buf = base64urldecode(tmp2, strlen(tmp2), &out->size); + } else { + printf("key type error!"); + return false; + } + + return true; +} + +EVP_PKEY *buildPubKeyFromModulus(buffer_data *pub) +{ + EVP_PKEY *key = NULL; + BIGNUM *e = BN_new(); + BIGNUM *n = BN_new(); + RSA *rsapub = RSA_new(); + if (NULL == e || NULL == n || NULL == rsapub) + goto err; + + key = EVP_PKEY_new(); + if (NULL == key) + goto err; + + BN_set_word(e, 0x10001); + BN_bin2bn(pub->buf, pub->size, n); + + RSA_set0_key(rsapub, n, e, NULL); + EVP_PKEY_set1_RSA(key, rsapub); + RSA_free(rsapub); + return key; err: - RSA_free(rsapub); - BN_free(n); - BN_free(e); - return NULL; + RSA_free(rsapub); + BN_free(n); + BN_free(e); + return NULL; } static bool verifyCertByCert(buffer_data *cert, uint8_t *root_cert_pathname) { - X509 *a = NULL; - EVP_PKEY *r = NULL; - BIO *bp = NULL; - bool res = false; - buffer_data root_cert = {0, NULL}; - size_t size = 0; - if (NULL == (root_cert.buf = file_to_buffer(root_cert_pathname, &size))) - { - goto err; - } - root_cert.size = (uint32_t)size; - - if (NULL == (r = getPubKeyFromCert(&root_cert, NULL))) - { - goto err; - } - - if (NULL == (bp = BIO_new_mem_buf(cert->buf, cert->size))) - { - goto err; - } - - if (NULL == (a = PEM_read_bio_X509(bp, NULL, NULL, NULL))) - { - printf("failed to get drkcert x509\n"); - goto err; - } - - if (1 != X509_verify(a, r)) - { - goto err; - } - - res = true; + X509 *a = NULL; + EVP_PKEY *r = NULL; + BIO *bp = NULL; + bool res = false; + buffer_data root_cert = {0, NULL}; + size_t size = 0; + if (NULL == (root_cert.buf = file_to_buffer(root_cert_pathname, &size))) { + goto err; + } + root_cert.size = (uint32_t)size; + + if (NULL == (r = getPubKeyFromCert(&root_cert, NULL))) { + goto err; + } + + if (NULL == (bp = BIO_new_mem_buf(cert->buf, cert->size))) { + goto err; + } + + if (NULL == (a = PEM_read_bio_X509(bp, NULL, NULL, NULL))) { + printf("failed to get drkcert x509\n"); + goto err; + } + + if (1 != X509_verify(a, r)) { + goto err; + } + + res = true; err: - X509_free(a); - BIO_vfree(bp); - EVP_PKEY_free(r); - if (root_cert.buf != NULL) - free(root_cert.buf); + X509_free(a); + BIO_vfree(bp); + EVP_PKEY_free(r); + if (root_cert.buf != NULL) + free(root_cert.buf); - return res; + return res; } // scenario: no as, parse akcert to get pubkey -EVP_PKEY * -getPubKeyFromDrkIssuedCert(buffer_data *cert) -{ - buffer_data datadrk, signdrk, certdrk, akpub; - bool rt; - EVP_PKEY *key = NULL; - - rt = getDataFromAkCert(cert, &datadrk, &signdrk, &certdrk, &akpub); - if (!rt) - { - printf("get NOAS data is failed!\n"); - goto err; - //return false; - } - - // verify the integrity of data in drk issued cert - rt = verifysig_x509cert(&datadrk, &signdrk, &certdrk, HW_IT_PRODUCT_CA_CERT_PATH); - if (!rt) - { - printf("validate drk signed ak cert failed!\n"); - goto err; - //return NULL; - } - - // build a pub key with the modulus carried in drk issued cert - key = buildPubKeyFromModulus(&akpub); +EVP_PKEY *getPubKeyFromDrkIssuedCert(buffer_data *cert) +{ + buffer_data datadrk, signdrk, certdrk, akpub; + bool rt; + EVP_PKEY *key = NULL; + + rt = getDataFromAkCert(cert, &datadrk, &signdrk, &certdrk, &akpub); + if (!rt) { + printf("get NOAS data is failed!\n"); + goto err; + // return false; + } + + // verify the integrity of data in drk issued cert + rt = verifysig_x509cert(&datadrk, &signdrk, &certdrk, HW_IT_PRODUCT_CA_CERT_PATH); + if (!rt) { + printf("validate drk signed ak cert failed!\n"); + goto err; + // return NULL; + } + + // build a pub key with the modulus carried in drk issued cert + key = buildPubKeyFromModulus(&akpub); err: - if (datadrk.buf != NULL) - free(datadrk.buf); - if (signdrk.buf != NULL) - free(signdrk.buf); - if (certdrk.buf != NULL) - free(certdrk.buf); - if (akpub.buf != NULL) - free(akpub.buf); - return key; + if (datadrk.buf != NULL) + free(datadrk.buf); + if (signdrk.buf != NULL) + free(signdrk.buf); + if (certdrk.buf != NULL) + free(certdrk.buf); + if (akpub.buf != NULL) + free(akpub.buf); + return key; } bool verifySigByKey(buffer_data *mhash, buffer_data *sign, EVP_PKEY *key) { - if (EVP_PKEY_base_id(key) != EVP_PKEY_RSA) - { - printf("the pub key type is not in supported type list(rsa)\n"); - return false; - } - - uint8_t buf[512] = {0,}; - int rt = RSA_public_decrypt(sign->size, sign->buf, buf, - EVP_PKEY_get1_RSA(key), RSA_NO_PADDING); - if (rt == -1) - { - printf("RSA public decrypt is failed with error %s\n", - ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - // rt = RSA_verify_PKCS1_PSS_mgf1(EVP_PKEY_get1_RSA(key), mhash->buf, - // EVP_sha256(), EVP_sha256(), buf, -2); - rt = RSA_verify_PKCS1_PSS(EVP_PKEY_get1_RSA(key), mhash->buf, - EVP_sha256(), buf, -2); - // rt = RSA_verify(EVP_PKEY_RSA_PSS, mhash->buf, SHA256_DIGEST_LENGTH, - // signdrk.buf, signdrk.size, EVP_PKEY_get1_RSA(key)); - if (rt != 1) - { - printf("verify sign is failed with error %s\n", - ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -EVP_PKEY * -getPubKeyFromCert(buffer_data *cert, char *root_cert_pathname) -{ - EVP_PKEY *key = NULL; - X509 *c = NULL; - - if (NULL != root_cert_pathname && !verifyCertByCert(cert, root_cert_pathname)) - { - printf("WARNING: failed to verify x509 cert\n"); - } - - BIO *bp = BIO_new_mem_buf(cert->buf, cert->size); - if (NULL == bp) - return NULL; - - c = PEM_read_bio_X509(bp, NULL, NULL, NULL); - BIO_vfree(bp); - if (c == NULL) - { - printf("failed to get x509 cert\n"); - return NULL; - } - - key = X509_get_pubkey(c); - X509_free(c); - if (key == NULL) - { - printf("Error getting public key from certificate\n"); - } - - return key; -} - -static bool -verifydatasig_bykey(buffer_data *data, buffer_data *sign, EVP_PKEY *key) -{ - // caculate the digest of the data - uint8_t digest[SHA256_DIGEST_LENGTH]; - _SHA256(data->buf, data->size, digest); - - // perform signature verification - buffer_data mhash = {sizeof(digest), digest}; - bool rt = verifySigByKey(&mhash, sign, key); - - return rt; + if (EVP_PKEY_base_id(key) != EVP_PKEY_RSA) { + printf("the pub key type is not in supported type list(rsa)\n"); + return false; + } + + uint8_t buf[512] = {0}; + int rt = RSA_public_decrypt(sign->size, sign->buf, buf, EVP_PKEY_get1_RSA(key), RSA_NO_PADDING); + if (rt == -1) { + printf("RSA public decrypt is failed with error %s\n", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + // rt = RSA_verify_PKCS1_PSS_mgf1(EVP_PKEY_get1_RSA(key), mhash->buf, + // EVP_sha256(), EVP_sha256(), buf, -2); + rt = RSA_verify_PKCS1_PSS(EVP_PKEY_get1_RSA(key), mhash->buf, EVP_sha256(), buf, -2); + // rt = RSA_verify(EVP_PKEY_RSA_PSS, mhash->buf, SHA256_DIGEST_LENGTH, + // signdrk.buf, signdrk.size, EVP_PKEY_get1_RSA(key)); + if (rt != 1) { + printf("verify sign is failed with error %s\n", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +EVP_PKEY *getPubKeyFromCert(buffer_data *cert, char *root_cert_pathname) +{ + EVP_PKEY *key = NULL; + X509 *c = NULL; + + if (NULL != root_cert_pathname && !verifyCertByCert(cert, root_cert_pathname)) { + printf("WARNING: failed to verify x509 cert\n"); + } + + BIO *bp = BIO_new_mem_buf(cert->buf, cert->size); + if (NULL == bp) + return NULL; + + c = PEM_read_bio_X509(bp, NULL, NULL, NULL); + BIO_vfree(bp); + if (c == NULL) { + printf("failed to get x509 cert\n"); + return NULL; + } + + key = X509_get_pubkey(c); + X509_free(c); + if (key == NULL) { + printf("Error getting public key from certificate\n"); + } + + return key; +} + +static bool verifydatasig_bykey(buffer_data *data, buffer_data *sign, EVP_PKEY *key) +{ + // caculate the digest of the data + uint8_t digest[SHA256_DIGEST_LENGTH]; + _SHA256(data->buf, data->size, digest); + + // perform signature verification + buffer_data mhash = {sizeof(digest), digest}; + bool rt = verifySigByKey(&mhash, sign, key); + + return rt; } // scenario: no as -static bool -verifysig_drksignedcert(buffer_data *data, buffer_data *sign, - buffer_data *cert) +static bool verifysig_drksignedcert(buffer_data *data, buffer_data *sign, buffer_data *cert) { - // get the key for signature verification - EVP_PKEY *key = getPubKeyFromDrkIssuedCert(cert); - if (key == NULL) - return false; + // get the key for signature verification + EVP_PKEY *key = getPubKeyFromDrkIssuedCert(cert); + if (key == NULL) + return false; - bool rt = verifydatasig_bykey(data, sign, key); - EVP_PKEY_free(key); + bool rt = verifydatasig_bykey(data, sign, key); + EVP_PKEY_free(key); - return rt; + return rt; } static void trim_ending_0(uint8_t *buf, int *size) { - for (; *size > 0 && buf[*size - 1] == 0; (*size)--); + for (; *size > 0 && buf[*size - 1] == 0; (*size)--) + ; } // scenario: as no daa -static bool -verifysig_x509cert(buffer_data *data, buffer_data *sign, buffer_data *cert, char *root_cert_pathname) +static bool verifysig_x509cert(buffer_data *data, buffer_data *sign, buffer_data *cert, char *root_cert_pathname) { - // get the key for signature verification - EVP_PKEY *key = getPubKeyFromCert(cert, root_cert_pathname); - if (key == NULL) - return false; + // get the key for signature verification + EVP_PKEY *key = getPubKeyFromCert(cert, root_cert_pathname); + if (key == NULL) + return false; - bool rt = verifydatasig_bykey(data, sign, key); - EVP_PKEY_free(key); + bool rt = verifydatasig_bykey(data, sign, key); + EVP_PKEY_free(key); - return rt; + return rt; } // file format of daa issuer pubkey, in HEX strings: @@ -389,492 +378,472 @@ verifysig_x509cert(buffer_data *data, buffer_data *sign, buffer_data *cert, char // [Y.y1]\n char *DEFAULT_DAA_ISSUER_PUBKEY_FILE = "./daa-pubkey"; -typedef struct -{ - ECP_FP512BN *a; - ECP_FP512BN *b; - ECP_FP512BN *c; - ECP_FP512BN *d; +typedef struct { + ECP_FP512BN *a; + ECP_FP512BN *b; + ECP_FP512BN *c; + ECP_FP512BN *d; } daa_ak_cert; -typedef struct -{ - BIG_512_60 h2; - BIG_512_60 s; - BIG_512_60 nm; - ECP_FP512BN *j; - ECP_FP512BN *k; +typedef struct { + BIG_512_60 h2; + BIG_512_60 s; + BIG_512_60 nm; + ECP_FP512BN *j; + ECP_FP512BN *k; } daa_signature; -typedef struct -{ - ECP2_FP512BN *x; - ECP2_FP512BN *y; +typedef struct { + ECP2_FP512BN *x; + ECP2_FP512BN *y; } daa_pub; -static int -hex2bin_append(const char *hexbuf, size_t *offset, size_t buflen, octet *oct) +static int hex2bin_append(const char *hexbuf, size_t *offset, size_t buflen, octet *oct) { - char *p = strchr(hexbuf + *offset, '\n'); - if (p == NULL) - return 0; + char *p = strchr(hexbuf + *offset, '\n'); + if (p == NULL) + return 0; - if (p - hexbuf - *offset != 128) - return 0; + if (p - hexbuf - *offset != 128) + return 0; - if (oct->len + 64 > oct->max) - return 0; + if (oct->len + 64 > oct->max) + return 0; - str2hex(hexbuf + *offset, 64, oct->val + oct->len); + str2hex(hexbuf + *offset, 64, oct->val + oct->len); - *offset += 128 + 1; - oct->len += 64; - return 64; + *offset += 128 + 1; + oct->len += 64; + return 64; } -static ECP2_FP512BN * -get_p2_from_fbuf(char *buf, size_t *offset, size_t buflen) +static ECP2_FP512BN *get_p2_from_fbuf(char *buf, size_t *offset, size_t buflen) { - ECP2_FP512BN *pt = malloc(sizeof(ECP2_FP512BN)); - if (pt == NULL) - goto err1; - uint8_t val[64 * 4 + 1]; - octet oct = {0, sizeof(val), val}; + ECP2_FP512BN *pt = malloc(sizeof(ECP2_FP512BN)); + if (pt == NULL) + goto err1; + uint8_t val[64 * 4 + 1]; + octet oct = {0, sizeof(val), val}; - val[0] = 0x04; - oct.len = 1; - int i; - for (i = 0; i < 4; i++) - { - if (64 != hex2bin_append(buf, offset, buflen, &oct)) - goto err2; - } + val[0] = 0x04; + oct.len = 1; + int i; + for (i = 0; i < 4; i++) { + if (64 != hex2bin_append(buf, offset, buflen, &oct)) + goto err2; + } - FP2_FP512BN x, y; - BIG_512_60 x0, x1, y0, y1; - BIG_512_60_fromBytes(x0, oct.val+1); - BIG_512_60_fromBytes(x1, oct.val+1+64); - BIG_512_60_fromBytes(y0, oct.val+1+128); - BIG_512_60_fromBytes(y1, oct.val+1+192); - FP2_FP512BN_from_BIGs(&x, x0, x1); - FP2_FP512BN_from_BIGs(&y, y0, y1); - ECP2_FP512BN_set(pt, &x, &y); - //ECP2_FP512BN_fromOctet(pt, &oct); + FP2_FP512BN x, y; + BIG_512_60 x0, x1, y0, y1; + BIG_512_60_fromBytes(x0, oct.val + 1); + BIG_512_60_fromBytes(x1, oct.val + 1 + 64); + BIG_512_60_fromBytes(y0, oct.val + 1 + 128); + BIG_512_60_fromBytes(y1, oct.val + 1 + 192); + FP2_FP512BN_from_BIGs(&x, x0, x1); + FP2_FP512BN_from_BIGs(&y, y0, y1); + ECP2_FP512BN_set(pt, &x, &y); + // ECP2_FP512BN_fromOctet(pt, &oct); - return pt; + return pt; err2: - free(pt); + free(pt); err1: - return NULL; + return NULL; } -static void -free_daa_pub(daa_pub *pub) +static void free_daa_pub(daa_pub *pub) { - if (pub == NULL) - return; + if (pub == NULL) + return; - if (pub->x != NULL) - free(pub->x); - if (pub->y != NULL) - free(pub->y); - free(pub); + if (pub->x != NULL) + free(pub->x); + if (pub->y != NULL) + free(pub->y); + free(pub); } -static daa_pub * -daa_get_issuer_pub() +static daa_pub *daa_get_issuer_pub() { - daa_pub *pub = malloc(sizeof(daa_pub)); - if (pub == NULL) - goto err1; - pub->x = NULL; - pub->y = NULL; + daa_pub *pub = malloc(sizeof(daa_pub)); + if (pub == NULL) + goto err1; + pub->x = NULL; + pub->y = NULL; - size_t buflen = 0; - char *buf = file_to_buffer(DEFAULT_DAA_ISSUER_PUBKEY_FILE, &buflen); - if (buf == NULL) - goto err2; + size_t buflen = 0; + char *buf = file_to_buffer(DEFAULT_DAA_ISSUER_PUBKEY_FILE, &buflen); + if (buf == NULL) + goto err2; - size_t offset = 0; - pub->x = get_p2_from_fbuf(buf, &offset, buflen); - if (pub->x == NULL) - goto err3; - pub->y = get_p2_from_fbuf(buf, &offset, buflen); - if (pub->y == NULL) - goto err3; + size_t offset = 0; + pub->x = get_p2_from_fbuf(buf, &offset, buflen); + if (pub->x == NULL) + goto err3; + pub->y = get_p2_from_fbuf(buf, &offset, buflen); + if (pub->y == NULL) + goto err3; - free(buf); - return pub; + free(buf); + return pub; err3: - free(buf); + free(buf); err2: - free_daa_pub(pub); + free_daa_pub(pub); err1: - return NULL; + return NULL; } -static void -free_p1(ECP_FP512BN *p1) +static void free_p1(ECP_FP512BN *p1) { - if (p1 == NULL) - return; + if (p1 == NULL) + return; - free(p1); + free(p1); } -static int -unmarshal_bn_from_bd(BIG_512_60 bn, buffer_data *bd, uint32_t *offset) +static int unmarshal_bn_from_bd(BIG_512_60 bn, buffer_data *bd, uint32_t *offset) { - if (*offset >= bd->size || *offset + 0x44 > bd->size) - goto err1; + if (*offset >= bd->size || *offset + 0x44 > bd->size) + goto err1; - uint32_t size = 0; - memcpy((void *)&size, bd->buf + *offset, sizeof(uint32_t)); - if (size != 0x40) - goto err1; - *offset += sizeof(uint32_t); - BIG_512_60_fromBytes(bn, bd->buf + *offset); - *offset += size; + uint32_t size = 0; + memcpy((void *)&size, bd->buf + *offset, sizeof(uint32_t)); + if (size != 0x40) + goto err1; + *offset += sizeof(uint32_t); + BIG_512_60_fromBytes(bn, bd->buf + *offset); + *offset += size; - return 1; + return 1; err1: - return 0; + return 0; } -static ECP_FP512BN * -unmarshal_p1_from_bd(buffer_data *bd, uint32_t *offset) +static ECP_FP512BN *unmarshal_p1_from_bd(buffer_data *bd, uint32_t *offset) { - if (*offset >= bd->size || *offset + 0x8c > bd->size) - goto err1; + if (*offset >= bd->size || *offset + 0x8c > bd->size) + goto err1; - ECP_FP512BN *p1 = malloc(sizeof(ECP_FP512BN)); - if (p1 == NULL) - goto err1; + ECP_FP512BN *p1 = malloc(sizeof(ECP_FP512BN)); + if (p1 == NULL) + goto err1; - uint32_t size = 0; - memcpy((void *)&size, bd->buf + *offset, sizeof(uint32_t)); - *offset += sizeof(uint32_t); - if (size != 0x88) - goto err2; - BIG_512_60 x, y; - if (unmarshal_bn_from_bd(x, bd, offset) == 0) - goto err2; - if (unmarshal_bn_from_bd(y, bd, offset) == 0) - goto err2; + uint32_t size = 0; + memcpy((void *)&size, bd->buf + *offset, sizeof(uint32_t)); + *offset += sizeof(uint32_t); + if (size != 0x88) + goto err2; + BIG_512_60 x, y; + if (unmarshal_bn_from_bd(x, bd, offset) == 0) + goto err2; + if (unmarshal_bn_from_bd(y, bd, offset) == 0) + goto err2; - if (0 == ECP_FP512BN_set(p1, x, y)) - goto err2; + if (0 == ECP_FP512BN_set(p1, x, y)) + goto err2; - return p1; + return p1; err2: - free_p1(p1); + free_p1(p1); err1: - return NULL; -} - -static void -free_daa_ak_cert(daa_ak_cert *cert) -{ - if (cert == NULL) - return; - - if (cert->a != NULL) - free(cert->a); - if (cert->b != NULL) - free(cert->b); - if (cert->c != NULL) - free(cert->c); - if (cert->d != NULL) - free(cert->d); - free(cert); -} - -static daa_ak_cert * -unmarshal_daa_ak_cert(buffer_data *cert) -{ - daa_ak_cert *akcert = malloc(sizeof(daa_ak_cert)); - if (akcert == NULL) - goto err1; - - akcert->a = NULL; - akcert->b = NULL; - akcert->c = NULL; - akcert->d = NULL; - - uint32_t offset = 0; - akcert->a = unmarshal_p1_from_bd(cert, &offset); - if (akcert->a == NULL) - goto err2; - akcert->b = unmarshal_p1_from_bd(cert, &offset); - if (akcert->b == NULL) - goto err2; - akcert->c = unmarshal_p1_from_bd(cert, &offset); - if (akcert->c == NULL) - goto err2; - akcert->d = unmarshal_p1_from_bd(cert, &offset); - if (akcert->d == NULL) - goto err2; - - return akcert; + return NULL; +} + +static void free_daa_ak_cert(daa_ak_cert *cert) +{ + if (cert == NULL) + return; + + if (cert->a != NULL) + free(cert->a); + if (cert->b != NULL) + free(cert->b); + if (cert->c != NULL) + free(cert->c); + if (cert->d != NULL) + free(cert->d); + free(cert); +} + +static daa_ak_cert *unmarshal_daa_ak_cert(buffer_data *cert) +{ + daa_ak_cert *akcert = malloc(sizeof(daa_ak_cert)); + if (akcert == NULL) + goto err1; + + akcert->a = NULL; + akcert->b = NULL; + akcert->c = NULL; + akcert->d = NULL; + + uint32_t offset = 0; + akcert->a = unmarshal_p1_from_bd(cert, &offset); + if (akcert->a == NULL) + goto err2; + akcert->b = unmarshal_p1_from_bd(cert, &offset); + if (akcert->b == NULL) + goto err2; + akcert->c = unmarshal_p1_from_bd(cert, &offset); + if (akcert->c == NULL) + goto err2; + akcert->d = unmarshal_p1_from_bd(cert, &offset); + if (akcert->d == NULL) + goto err2; + + return akcert; err2: - free_daa_ak_cert(akcert); + free_daa_ak_cert(akcert); err1: - return NULL; -} - -static void -free_daa_signature(daa_signature *sign) -{ - if (sign == NULL) - return; - - if (sign->j != NULL) - free(sign->j); - if (sign->k != NULL) - free(sign->k); - free(sign); -} - -static daa_signature * -unmarshal_daa_signature(buffer_data *sign) -{ - daa_signature *sig = malloc(sizeof(daa_signature)); - if (sig == NULL) - goto err1; - - sig->j = NULL; - sig->k = NULL; - - cJSON *cj = cJSON_ParseWithLength(sign->buf, sign->size); - if (cj == NULL) { - verifier_error("cjson parse daa signature error."); - } - cJSON *bsnjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.bsn"); - cJSON *jjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.j"); - cJSON *kjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.k"); - cJSON *h2json = cJSON_GetObjectItemCaseSensitive(cj, "sign.h2"); - cJSON *sjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.s"); - cJSON *nmjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.nm"); - if (bsnjson == NULL || jjson == NULL || kjson == NULL || h2json == NULL || sjson == NULL || nmjson == NULL) { - verifier_error("cjson parse daa signature error"); - } - // base64 decode - buffer_data j, k, h2, s, nm; - if (strcmp(bsnjson->valuestring, "")) { - j.buf = base64urldecode(jjson->valuestring, strlen(jjson->valuestring), &j.size); - k.buf = base64urldecode(kjson->valuestring, strlen(kjson->valuestring), &k.size); - } - h2.buf = base64urldecode(h2json->valuestring, strlen(h2json->valuestring), &h2.size); - s.buf = base64urldecode(sjson->valuestring, strlen(sjson->valuestring), &s.size); - nm.buf = base64urldecode(nmjson->valuestring, strlen(nmjson->valuestring), &nm.size); - - //h2, s, nm - BIG_512_60_fromBytes(sig->h2, h2.buf); - BIG_512_60_fromBytes(sig->s, s.buf); - BIG_512_60_fromBytes(sig->nm, nm.buf); - - //j, k - if (strcmp(bsnjson->valuestring, "")) { - uint32_t offset = 0; - sig->j = unmarshal_p1_from_bd(&j, &offset); - offset = 0; - sig->k = unmarshal_p1_from_bd(&k, &offset); - } - - cJSON_Delete(cj); - return sig; + return NULL; +} + +static void free_daa_signature(daa_signature *sign) +{ + if (sign == NULL) + return; + + if (sign->j != NULL) + free(sign->j); + if (sign->k != NULL) + free(sign->k); + free(sign); +} + +static daa_signature *unmarshal_daa_signature(buffer_data *sign) +{ + daa_signature *sig = malloc(sizeof(daa_signature)); + if (sig == NULL) + goto err1; + + sig->j = NULL; + sig->k = NULL; + + cJSON *cj = cJSON_ParseWithLength(sign->buf, sign->size); + if (cj == NULL) { + verifier_error("cjson parse daa signature error."); + } + cJSON *bsnjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.bsn"); + cJSON *jjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.j"); + cJSON *kjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.k"); + cJSON *h2json = cJSON_GetObjectItemCaseSensitive(cj, "sign.h2"); + cJSON *sjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.s"); + cJSON *nmjson = cJSON_GetObjectItemCaseSensitive(cj, "sign.nm"); + if (bsnjson == NULL || jjson == NULL || kjson == NULL || h2json == NULL || sjson == NULL || nmjson == NULL) { + verifier_error("cjson parse daa signature error"); + } + // base64 decode + buffer_data j, k, h2, s, nm; + if (strcmp(bsnjson->valuestring, "")) { + j.buf = base64urldecode(jjson->valuestring, strlen(jjson->valuestring), &j.size); + k.buf = base64urldecode(kjson->valuestring, strlen(kjson->valuestring), &k.size); + } + h2.buf = base64urldecode(h2json->valuestring, strlen(h2json->valuestring), &h2.size); + s.buf = base64urldecode(sjson->valuestring, strlen(sjson->valuestring), &s.size); + nm.buf = base64urldecode(nmjson->valuestring, strlen(nmjson->valuestring), &nm.size); + + // h2, s, nm + BIG_512_60_fromBytes(sig->h2, h2.buf); + BIG_512_60_fromBytes(sig->s, s.buf); + BIG_512_60_fromBytes(sig->nm, nm.buf); + + // j, k + if (strcmp(bsnjson->valuestring, "")) { + uint32_t offset = 0; + sig->j = unmarshal_p1_from_bd(&j, &offset); + offset = 0; + sig->k = unmarshal_p1_from_bd(&k, &offset); + } + + cJSON_Delete(cj); + return sig; err1: - return NULL; + return NULL; } -static bool -verify_daacert(daa_ak_cert *cert) +static bool verify_daacert(daa_ak_cert *cert) { - bool rt = false; - daa_pub *ispubkey = daa_get_issuer_pub(); - if (ispubkey == NULL) - goto err1; + bool rt = false; + daa_pub *ispubkey = daa_get_issuer_pub(); + if (ispubkey == NULL) + goto err1; - ECP2_FP512BN p2; - ECP2_FP512BN_generator(&p2); + ECP2_FP512BN p2; + ECP2_FP512BN_generator(&p2); - FP12_FP512BN lhs, rhs; + FP12_FP512BN lhs, rhs; - PAIR_FP512BN_ate(&lhs, ispubkey->y, cert->a); - PAIR_FP512BN_fexp(&lhs); + PAIR_FP512BN_ate(&lhs, ispubkey->y, cert->a); + PAIR_FP512BN_fexp(&lhs); - PAIR_FP512BN_ate(&rhs, &p2, cert->b); - PAIR_FP512BN_fexp(&rhs); + PAIR_FP512BN_ate(&rhs, &p2, cert->b); + PAIR_FP512BN_fexp(&rhs); - if (!FP12_FP512BN_equals(&lhs, &rhs)) - goto err2; + if (!FP12_FP512BN_equals(&lhs, &rhs)) + goto err2; - ECP_FP512BN ptemp; + ECP_FP512BN ptemp; - ECP_FP512BN_copy(&ptemp, cert->d); - ECP_FP512BN_add(&ptemp, cert->a); - PAIR_FP512BN_ate(&lhs, ispubkey->x, &ptemp); - PAIR_FP512BN_fexp(&lhs); + ECP_FP512BN_copy(&ptemp, cert->d); + ECP_FP512BN_add(&ptemp, cert->a); + PAIR_FP512BN_ate(&lhs, ispubkey->x, &ptemp); + PAIR_FP512BN_fexp(&lhs); - PAIR_FP512BN_ate(&rhs, &p2, cert->c); - PAIR_FP512BN_fexp(&rhs); + PAIR_FP512BN_ate(&rhs, &p2, cert->c); + PAIR_FP512BN_fexp(&rhs); - if (!FP12_FP512BN_equals(&lhs, &rhs)) - goto err2; + if (!FP12_FP512BN_equals(&lhs, &rhs)) + goto err2; - rt = true; + rt = true; err2: - free_daa_pub(ispubkey); + free_daa_pub(ispubkey); err1: - return rt; + return rt; } static void hash_update_buf(SHA512_CTX *ctx, char *buf, int size) { - SHA512_Update(ctx, (char *)&size, sizeof(int)); - if (size > 0) - SHA512_Update(ctx, buf, size); + SHA512_Update(ctx, (char *)&size, sizeof(int)); + if (size > 0) + SHA512_Update(ctx, buf, size); } static void hash_update_p1(SHA512_CTX *ctx, ECP_FP512BN *p1) { - BIG_512_60 x, y; - char v_tmp[SHA512_DIGEST_LENGTH]; - int p1_size = 2 * (sizeof(v_tmp) + sizeof(int)); - - ECP_FP512BN_get(x, y, p1); - - SHA512_Update(ctx, (char *)&p1_size, sizeof(int)); - BIG_512_60_toBytes(v_tmp, x); - hash_update_buf(ctx, v_tmp, sizeof(v_tmp)); - BIG_512_60_toBytes(v_tmp, y); - hash_update_buf(ctx, v_tmp, sizeof(v_tmp)); -} - -static bool -verify_daasig(buffer_data *mhash, daa_signature *sig, daa_ak_cert *cert) -{ - ECP_FP512BN l, e, s_j, h2_k, s_b, h2_d; - - // may need additional step to verify J while bsn is available - // s1,y1=Hs(bsn); verify J=(Hp(s1),y1) - - // skip J, K, L caculation while J is null. - if (sig->j != NULL) - { - ECP_FP512BN_copy(&s_j, sig->j); - ECP_FP512BN_mul(&s_j, sig->s); - ECP_FP512BN_copy(&h2_k, sig->k); - ECP_FP512BN_mul(&h2_k, sig->h2); - ECP_FP512BN_copy(&l, &s_j); - ECP_FP512BN_sub(&l, &h2_k); - } - - ECP_FP512BN_copy(&s_b, cert->b); - ECP_FP512BN_mul(&s_b, sig->s); - ECP_FP512BN_copy(&h2_d, cert->d); - ECP_FP512BN_mul(&h2_d, sig->h2); - ECP_FP512BN_copy(&e, &s_b); - ECP_FP512BN_sub(&e, &h2_d); - - // calculate c=H(H(m),A,B,C,D,J,K,L,E)) - SHA512_CTX ctx; - SHA512_Init(&ctx); - // H(m) - hash_update_buf(&ctx, mhash->buf, mhash->size); - // A - hash_update_p1(&ctx, cert->a); - // B - hash_update_p1(&ctx, cert->b); - // C - hash_update_p1(&ctx, cert->c); - // D - hash_update_p1(&ctx, cert->d); - if (sig->j != NULL) - { - // J - hash_update_p1(&ctx, sig->j); - // K - hash_update_p1(&ctx, sig->k); - // L - hash_update_p1(&ctx, &l); - } else { - hash_update_buf(&ctx, NULL, 0); - hash_update_buf(&ctx, NULL, 0); - hash_update_buf(&ctx, NULL, 0); - } - // E - hash_update_p1(&ctx, &e); - - uint8_t c[SHA512_DIGEST_LENGTH]; - SHA512_Final(c, &ctx); - - octet tmp = {SHA512_DIGEST_LENGTH, SHA512_DIGEST_LENGTH, mhash->buf}; - - // caclulate h1=H(c); h2=Hn(nm || h1) - uint8_t h1[SHA512_DIGEST_LENGTH]; - _SHA512(c, sizeof(c), h1); - - SHA512_Init(&ctx); - - uint8_t nm[SHA512_DIGEST_LENGTH]; - BIG_512_60_toBytes(nm, sig->nm); - hash_update_buf(&ctx, nm, sizeof(nm)); - hash_update_buf(&ctx, h1, sizeof(h1)); - - uint8_t h2[SHA512_DIGEST_LENGTH]; - SHA512_Final(h2, &ctx); - - BIG_512_60 b_h2, n; - BIG_512_60_fromBytes(b_h2, h2); - BIG_512_60_rcopy(n, CURVE_Order_FP512BN); - BIG_512_60_mod(b_h2, n); - - if (BIG_512_60_comp(b_h2, sig->h2) != 0) - return false; - - return true; -} - -static bool -verifysig_daacert(buffer_data *data, buffer_data *sign, buffer_data *cert) -{ - bool rt = false; - - // parse daa ak cert - daa_ak_cert *akcert = unmarshal_daa_ak_cert(cert); - if (akcert == NULL) - goto err1; - - // parse daa signature - daa_signature *sig = unmarshal_daa_signature(sign); - if (sig == NULL) - goto err2; - - // verify daa ak cert - rt = verify_daacert(akcert); - if (!rt) - goto err3; - - // caculate the digest of the data - uint8_t digest[SHA512_DIGEST_LENGTH]; - _SHA512(data->buf, data->size, digest); - - // perform signature verification - buffer_data mhash = {sizeof(digest), digest}; - rt = verify_daasig(&mhash, sig, akcert); + BIG_512_60 x, y; + char v_tmp[SHA512_DIGEST_LENGTH]; + int p1_size = 2 * (sizeof(v_tmp) + sizeof(int)); + + ECP_FP512BN_get(x, y, p1); + + SHA512_Update(ctx, (char *)&p1_size, sizeof(int)); + BIG_512_60_toBytes(v_tmp, x); + hash_update_buf(ctx, v_tmp, sizeof(v_tmp)); + BIG_512_60_toBytes(v_tmp, y); + hash_update_buf(ctx, v_tmp, sizeof(v_tmp)); +} + +static bool verify_daasig(buffer_data *mhash, daa_signature *sig, daa_ak_cert *cert) +{ + ECP_FP512BN l, e, s_j, h2_k, s_b, h2_d; + + // may need additional step to verify J while bsn is available + // s1,y1=Hs(bsn); verify J=(Hp(s1),y1) + + // skip J, K, L caculation while J is null. + if (sig->j != NULL) { + ECP_FP512BN_copy(&s_j, sig->j); + ECP_FP512BN_mul(&s_j, sig->s); + ECP_FP512BN_copy(&h2_k, sig->k); + ECP_FP512BN_mul(&h2_k, sig->h2); + ECP_FP512BN_copy(&l, &s_j); + ECP_FP512BN_sub(&l, &h2_k); + } + + ECP_FP512BN_copy(&s_b, cert->b); + ECP_FP512BN_mul(&s_b, sig->s); + ECP_FP512BN_copy(&h2_d, cert->d); + ECP_FP512BN_mul(&h2_d, sig->h2); + ECP_FP512BN_copy(&e, &s_b); + ECP_FP512BN_sub(&e, &h2_d); + + // calculate c=H(H(m),A,B,C,D,J,K,L,E)) + SHA512_CTX ctx; + SHA512_Init(&ctx); + // H(m) + hash_update_buf(&ctx, mhash->buf, mhash->size); + // A + hash_update_p1(&ctx, cert->a); + // B + hash_update_p1(&ctx, cert->b); + // C + hash_update_p1(&ctx, cert->c); + // D + hash_update_p1(&ctx, cert->d); + if (sig->j != NULL) { + // J + hash_update_p1(&ctx, sig->j); + // K + hash_update_p1(&ctx, sig->k); + // L + hash_update_p1(&ctx, &l); + } else { + hash_update_buf(&ctx, NULL, 0); + hash_update_buf(&ctx, NULL, 0); + hash_update_buf(&ctx, NULL, 0); + } + // E + hash_update_p1(&ctx, &e); + + uint8_t c[SHA512_DIGEST_LENGTH]; + SHA512_Final(c, &ctx); + + octet tmp = {SHA512_DIGEST_LENGTH, SHA512_DIGEST_LENGTH, mhash->buf}; + + // caclulate h1=H(c); h2=Hn(nm || h1) + uint8_t h1[SHA512_DIGEST_LENGTH]; + _SHA512(c, sizeof(c), h1); + + SHA512_Init(&ctx); + + uint8_t nm[SHA512_DIGEST_LENGTH]; + BIG_512_60_toBytes(nm, sig->nm); + hash_update_buf(&ctx, nm, sizeof(nm)); + hash_update_buf(&ctx, h1, sizeof(h1)); + + uint8_t h2[SHA512_DIGEST_LENGTH]; + SHA512_Final(h2, &ctx); + + BIG_512_60 b_h2, n; + BIG_512_60_fromBytes(b_h2, h2); + BIG_512_60_rcopy(n, CURVE_Order_FP512BN); + BIG_512_60_mod(b_h2, n); + + if (BIG_512_60_comp(b_h2, sig->h2) != 0) + return false; + + return true; +} + +static bool verifysig_daacert(buffer_data *data, buffer_data *sign, buffer_data *cert) +{ + bool rt = false; + + // parse daa ak cert + daa_ak_cert *akcert = unmarshal_daa_ak_cert(cert); + if (akcert == NULL) + goto err1; + + // parse daa signature + daa_signature *sig = unmarshal_daa_signature(sign); + if (sig == NULL) + goto err2; + + // verify daa ak cert + rt = verify_daacert(akcert); + if (!rt) + goto err3; + + // caculate the digest of the data + uint8_t digest[SHA512_DIGEST_LENGTH]; + _SHA512(data->buf, data->size, digest); + + // perform signature verification + buffer_data mhash = {sizeof(digest), digest}; + rt = verify_daasig(&mhash, sig, akcert); err3: - free_daa_signature(sig); + free_daa_signature(sig); err2: - free_daa_ak_cert(akcert); + free_daa_ak_cert(akcert); err1: - return rt; + return rt; } /* @@ -888,243 +857,231 @@ verifysig will verify the signature in report scenario: 0, 1 or 2. refer to the description above. return value: true if the sigature verification succeeded, else false. */ -bool verifysig(buffer_data *data, buffer_data *sign, buffer_data *cert, - uint32_t scenario) +bool verifysig(buffer_data *data, buffer_data *sign, buffer_data *cert, uint32_t scenario) { - if (data->size <= 0 || sign->size <= 0 || cert->size <= 0 || scenario > 2) - { - return false; - } + if (data->size <= 0 || sign->size <= 0 || cert->size <= 0 || scenario > 2) { + return false; + } - switch (scenario) - { - case 0: - return verifysig_drksignedcert(data, sign, cert); - case 1: - return verifysig_x509cert(data, sign, cert, TAS_ROOT_CERT_PATH); - case 2: - return verifysig_daacert(data, sign, cert); - } + switch (scenario) { + case 0: + return verifysig_drksignedcert(data, sign, cert); + case 1: + return verifysig_x509cert(data, sign, cert, TAS_ROOT_CERT_PATH); + case 2: + return verifysig_daacert(data, sign, cert); + } - return false; + return false; } void dumpDrkCert(buffer_data *certdrk) { - FILE *f = fopen("drk.crt", "wb"); - if (!f) - { - fprintf(stderr, "unable to open: %s\n", "test.cert"); - return; - } - fwrite(certdrk->buf, sizeof(char), certdrk->size, f); - fclose(f); + FILE *f = fopen("drk.crt", "wb"); + if (!f) { + fprintf(stderr, "unable to open: %s\n", "test.cert"); + return; + } + fwrite(certdrk->buf, sizeof(char), certdrk->size, f); + fclose(f); } bool restorePEMCert(uint8_t *data, int data_len, buffer_data *certdrk) { - uint8_t head[] = "-----BEGIN CERTIFICATE-----\n"; - uint8_t end[] = "-----END CERTIFICATE-----\n"; - - // trim ending '\0' from data - trim_ending_0(data, &data_len); - - // calculate out len and check out buffer size - int out_len = data_len + (data_len + 63)/64 + strlen(head) + strlen(end); - if (out_len > certdrk->size) { - printf("failed to restore drk cert: drk cert is too large.\n"); - return false; - } - - // copy head - uint8_t *dst = certdrk->buf; - out_len = strlen(head); - memcpy(dst, head, out_len); - dst += out_len; - - //copy data - uint8_t *src = data; - int loop = data_len / 64; - int rem = data_len % 64; - int i; - - for (i = 0; i < loop; i++, src += 64, dst += 65) - { - memcpy(dst, src, 64); - dst[64] = '\n'; - } - if (rem > 0) - { - memcpy(dst, src, rem); - dst[rem] = '\n'; - dst += rem + 1; - } - - // copy end - out_len = strlen(end); - memcpy(dst, end, out_len); - certdrk->size = dst + out_len - certdrk->buf; - - return true; + uint8_t head[] = "-----BEGIN CERTIFICATE-----\n"; + uint8_t end[] = "-----END CERTIFICATE-----\n"; + + // trim ending '\0' from data + trim_ending_0(data, &data_len); + + // calculate out len and check out buffer size + int out_len = data_len + (data_len + 63) / 64 + strlen(head) + strlen(end); + if (out_len > certdrk->size) { + printf("failed to restore drk cert: drk cert is too large.\n"); + return false; + } + + // copy head + uint8_t *dst = certdrk->buf; + out_len = strlen(head); + memcpy(dst, head, out_len); + dst += out_len; + + // copy data + uint8_t *src = data; + int loop = data_len / 64; + int rem = data_len % 64; + int i; + + for (i = 0; i < loop; i++, src += 64, dst += 65) { + memcpy(dst, src, 64); + dst[64] = '\n'; + } + if (rem > 0) { + memcpy(dst, src, rem); + dst[rem] = '\n'; + dst += rem + 1; + } + + // copy end + out_len = strlen(end); + memcpy(dst, end, out_len); + certdrk->size = dst + out_len - certdrk->buf; + + return true; } void free_report(TA_report *report) { - if (NULL == report) - return; + if (NULL == report) + return; - if (NULL != report->signature) - { - if (NULL != report->signature->buf) - free(report->signature->buf); - free(report->signature); - } + if (NULL != report->signature) { + if (NULL != report->signature->buf) + free(report->signature->buf); + free(report->signature); + } - if (NULL != report->cert) - { - if (NULL != report->cert->buf) - free(report->cert->buf); - free(report->cert); - } + if (NULL != report->cert) { + if (NULL != report->cert->buf) + free(report->cert->buf); + free(report->cert); + } - free(report); + free(report); } // getDataFromReport get some data which have akcert & signak & signdata & // scenario from report -bool getDataFromReport(buffer_data *data, buffer_data *akcert, - buffer_data *signak, buffer_data *signdata, +bool getDataFromReport(buffer_data *data, buffer_data *akcert, buffer_data *signak, buffer_data *signdata, uint32_t *scenario) { - if (data->buf == NULL) { - printf("report is null"); - return false; - } - TA_report *report; - report = Convert(data); - if (report == NULL) { - printf("failed to parse the report\n"); - return false; - } - *scenario = report->scenario; - akcert->size = report->cert->size; - akcert->buf = malloc(akcert->size); - memcpy(akcert->buf, report->cert->buf, report->cert->size); - signak->size = report->signature->size; - signak->buf = malloc(signak->size); - memcpy(signak->buf, report->signature->buf, report->signature->size); - - // get payload - cJSON *cj = cJSON_ParseWithLength(data->buf, data->size); - if (cj == NULL) { - verifier_error("cjson parse report error."); - } - - cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); - uint8_t *tmp = cJSON_Print(pljson); - signdata->size = strlen(tmp) / 3 * 4 + 4 + 1; - signdata->buf = malloc(signdata->size); - base64urlencode(tmp, strlen(tmp), signdata->buf, &signdata->size); - - cJSON_Delete(cj); - free_report(report); - cJSON_free(tmp); - return true; + if (data->buf == NULL) { + printf("report is null"); + return false; + } + TA_report *report; + report = Convert(data); + if (report == NULL) { + printf("failed to parse the report\n"); + return false; + } + *scenario = report->scenario; + akcert->size = report->cert->size; + akcert->buf = malloc(akcert->size); + memcpy(akcert->buf, report->cert->buf, report->cert->size); + signak->size = report->signature->size; + signak->buf = malloc(signak->size); + memcpy(signak->buf, report->signature->buf, report->signature->size); + + // get payload + cJSON *cj = cJSON_ParseWithLength(data->buf, data->size); + if (cj == NULL) { + verifier_error("cjson parse report error."); + } + + cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); + uint8_t *tmp = cJSON_Print(pljson); + signdata->size = strlen(tmp) / 3 * 4 + 4 + 1; + signdata->buf = malloc(signdata->size); + base64urlencode(tmp, strlen(tmp), signdata->buf, &signdata->size); + + cJSON_Delete(cj); + free_report(report); + cJSON_free(tmp); + return true; } // get some data which have signdata signdrk certdrk and akpub from akcert -bool getDataFromAkCert(buffer_data *akcert, buffer_data *signdata, - buffer_data *signdrk, buffer_data *certdrk, +bool getDataFromAkCert(buffer_data *akcert, buffer_data *signdata, buffer_data *signdrk, buffer_data *certdrk, buffer_data *akpub) { - bool rt = false; - if (akcert->buf == NULL) { - printf("akcert is null"); - return rt; - } - - // parse akcert - cJSON *cj = cJSON_ParseWithLength((char *)akcert->buf, akcert->size); - if (cj == NULL) { - printf("cjson parse akcert error!\n"); - return rt; - } - // get payload and signature - cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); - cJSON *sigjson = cJSON_GetObjectItemCaseSensitive(cj, "signature"); - if (pljson == NULL || sigjson == NULL) { - printf("cjson parse akcert error, failed to get payload and signature!\n"); - goto err; - //return false; - } - // get akpub, signdrk, certdrk, signdata - cJSON *akpubjson = cJSON_GetObjectItemCaseSensitive(pljson, "ak_pub"); - cJSON *signdrkjson = cJSON_GetObjectItemCaseSensitive(sigjson, "drk_sign"); - cJSON *certdrkjson = cJSON_GetObjectItemCaseSensitive(sigjson, "drk_cert"); - if (akpubjson == NULL || signdrkjson == NULL || certdrkjson == NULL) { - printf("cjson parse akcert error, failed to get akpub, signdrk and certdrk!\n"); - goto err; - //return false; - } - /* - akpub->buf: AK_PUB_TYPE. outdata is the same as previous - signdrk->buf*: BASE64_TYPE, DRK signature for "payload". outdata has been decoded already - certdrk->buf: BASE64_TYPE, BASE 64 of DRK cert. outdata is the same as previous - signdata->buf*: payload, outdata can be directly used to hash - */ - - // ak_pub: build a pub key with the modulus carried in drk issued cert - rt = decodeAKPubKey(akpubjson, akpub); - if (!rt) { - printf("base64 decode ak public key failed!\n"); - goto err; - //return NULL; - } - - // drk_sign: base64 decoded - uint8_t *tmp1 = (uint8_t *)signdrkjson->valuestring; - signdrk->buf = base64urldecode(tmp1, strlen(tmp1), &signdrk->size); - - // signdata: base64 encoded (can be directly used to hash) - uint8_t *signdatatmp = (uint8_t *)cJSON_Print(pljson); - signdata->size = 4096; - signdata->buf = (uint8_t *)malloc(sizeof(uint8_t) * signdata->size); - base64urlencode(signdatatmp, strlen(signdatatmp), signdata->buf, &signdata->size); - - // drk_cert: base64 decoded & restore - buffer_data certdrktmp1; - uint8_t *tmp2 = (uint8_t *)certdrkjson->valuestring; - certdrktmp1.buf = base64urldecode(tmp2, strlen(tmp2), &certdrktmp1.size); - certdrk->size = 4300; - certdrk->buf = (uint8_t *)malloc(sizeof(uint8_t) * certdrk->size); - rt = restorePEMCert(certdrktmp1.buf, certdrktmp1.size, certdrk); - - free(certdrktmp1.buf); - cJSON_free(signdatatmp); + bool rt = false; + if (akcert->buf == NULL) { + printf("akcert is null"); + return rt; + } + + // parse akcert + cJSON *cj = cJSON_ParseWithLength((char *)akcert->buf, akcert->size); + if (cj == NULL) { + printf("cjson parse akcert error!\n"); + return rt; + } + // get payload and signature + cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); + cJSON *sigjson = cJSON_GetObjectItemCaseSensitive(cj, "signature"); + if (pljson == NULL || sigjson == NULL) { + printf("cjson parse akcert error, failed to get payload and signature!\n"); + goto err; + // return false; + } + // get akpub, signdrk, certdrk, signdata + cJSON *akpubjson = cJSON_GetObjectItemCaseSensitive(pljson, "ak_pub"); + cJSON *signdrkjson = cJSON_GetObjectItemCaseSensitive(sigjson, "drk_sign"); + cJSON *certdrkjson = cJSON_GetObjectItemCaseSensitive(sigjson, "drk_cert"); + if (akpubjson == NULL || signdrkjson == NULL || certdrkjson == NULL) { + printf("cjson parse akcert error, failed to get akpub, signdrk and certdrk!\n"); + goto err; + // return false; + } + /* + akpub->buf: AK_PUB_TYPE. outdata is the same as previous + signdrk->buf*: BASE64_TYPE, DRK signature for "payload". outdata has been decoded already + certdrk->buf: BASE64_TYPE, BASE 64 of DRK cert. outdata is the same as previous + signdata->buf*: payload, outdata can be directly used to hash + */ + + // ak_pub: build a pub key with the modulus carried in drk issued cert + rt = decodeAKPubKey(akpubjson, akpub); + if (!rt) { + printf("base64 decode ak public key failed!\n"); + goto err; + // return NULL; + } + + // drk_sign: base64 decoded + uint8_t *tmp1 = (uint8_t *)signdrkjson->valuestring; + signdrk->buf = base64urldecode(tmp1, strlen(tmp1), &signdrk->size); + + // signdata: base64 encoded (can be directly used to hash) + uint8_t *signdatatmp = (uint8_t *)cJSON_Print(pljson); + signdata->size = 4096; + signdata->buf = (uint8_t *)malloc(sizeof(uint8_t) * signdata->size); + base64urlencode(signdatatmp, strlen(signdatatmp), signdata->buf, &signdata->size); + + // drk_cert: base64 decoded & restore + buffer_data certdrktmp1; + uint8_t *tmp2 = (uint8_t *)certdrkjson->valuestring; + certdrktmp1.buf = base64urldecode(tmp2, strlen(tmp2), &certdrktmp1.size); + certdrk->size = 4300; + certdrk->buf = (uint8_t *)malloc(sizeof(uint8_t) * certdrk->size); + rt = restorePEMCert(certdrktmp1.buf, certdrktmp1.size, certdrk); + + free(certdrktmp1.buf); + cJSON_free(signdatatmp); err: - cJSON_Delete(cj); - return rt; + cJSON_Delete(cj); + return rt; } bool tee_verify_signature(buffer_data *report) { - // get akcert signak signdata from report - buffer_data akcert, signak, signdata; - uint32_t scenario; - bool rt = getDataFromReport(report, &akcert, &signak, &signdata, &scenario); - if (!rt) - { - printf("get Data From Report is failed\n"); - return false; - } - rt = verifysig(&signdata, &signak, &akcert, scenario); - if (!rt) - { - printf("verify signature is failed\n"); - return false; - } - printf("Verify signature success!\n"); - return true; + // get akcert signak signdata from report + buffer_data akcert, signak, signdata; + uint32_t scenario; + bool rt = getDataFromReport(report, &akcert, &signak, &signdata, &scenario); + if (!rt) { + printf("get Data From Report is failed\n"); + return false; + } + rt = verifysig(&signdata, &signak, &akcert, scenario); + if (!rt) { + printf("verify signature is failed\n"); + return false; + } + printf("Verify signature success!\n"); + return true; } /* @@ -1142,240 +1099,241 @@ void file_error(const char *s) */ void test_print(uint8_t *printed, int printed_size, char *printed_name) { - printf("%s:\n", printed_name); - for (int i = 0; i < printed_size; i++) - { - printf("%02X", printed[i]); - if (i % 32 == 31) - { - printf("\n"); - } - } - printf("\n"); + printf("%s:\n", printed_name); + for (int i = 0; i < printed_size; i++) { + printf("%02X", printed[i]); + if (i % 32 == 31) { + printf("\n"); + } + } + printf("\n"); }; bool tee_verify(buffer_data *bufdata, int type, char *filename) { - TA_report *report = Convert(bufdata); - base_value *baseval = LoadBaseValue(report, filename); - - bool verified; - if ((report == NULL) || (baseval == NULL)) - { - printf("Pointer Error!\n"); - verified = false; - } - else - verified = Compare(type, report, - baseval); // compare the report with the basevalue - - free_report(report); - free(baseval); - return verified; -} - -bool get_nonce_from_payload(cJSON *pljson, TA_report *tr) { - // get nonce: base64 -> uint8_t* - cJSON *njson = cJSON_GetObjectItemCaseSensitive(pljson, "nonce"); - if (njson == NULL) { - printf("cjson parse nonce from report error"); - return false; - } - int len = 0; - uint8_t *tmp = base64urldecode(njson->valuestring, strlen(njson->valuestring), &len); - memset(tr->nonce, 0, 64); - memcpy(tr->nonce, tmp, len); - return true; -} - -bool get_uuid_from_payload(cJSON *pljson, TA_report *tr) { - // get uuid: string -> uint8_t* - cJSON *ujson = cJSON_GetObjectItemCaseSensitive(pljson, "uuid"); - if (ujson == NULL) { - printf("cjson parse uuid from report error"); - return false; - } - str_to_uuid(ujson->valuestring, tr->uuid); - - return true; -} - -bool get_hash_from_payload(cJSON *pljson, TA_report *tr) { - // get img&mem hash: base64 -> uint8_t* - cJSON *imgjson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_img"); - cJSON *memjson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_mem"); - if (imgjson == NULL || memjson == NULL) { - printf("cjson parse hash from report error"); - return false; - } - - int len = 0; - uint8_t *tmp1 = base64urldecode(imgjson->valuestring, strlen(imgjson->valuestring), &len); - memcpy(tr->image_hash, tmp1, 32); - - uint8_t *tmp2 = base64urldecode(memjson->valuestring, strlen(memjson->valuestring), &len); - memcpy(tr->hash, tmp2, 32); - - free(tmp1); - free(tmp2); - return true; -} - -bool get_scenario_from_report(cJSON *pljson, cJSON *signjson, cJSON* acjson, TA_report *tr) { - if (pljson == NULL || signjson == NULL || acjson == NULL || tr == NULL) { - printf("invalid input parameter\n"); - return false; - } - cJSON *scejson = cJSON_GetObjectItemCaseSensitive(pljson, "scenario"); - if (scejson == NULL) { - printf("cjson parse scenario from report error\n"); - return false; - } - tr->signature = malloc(sizeof(buffer_data)); - tr->cert = malloc(sizeof(buffer_data)); - if (strcmp(scejson->valuestring, RA_SCENARIO_NO_AS) == 0) { - tr->scenario = RA_SCENARIO_NO_AS_INT; - // signature: no as - cJSON *noasjson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_no_as"); - tr->signature->buf = base64urldecode(noasjson->valuestring, strlen(noasjson->valuestring), &tr->signature->size); - // akcert: no as (parse needed) - cJSON *c1json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_no_as"); - tr->cert->buf = cJSON_Print(c1json); - tr->cert->size = strlen(tr->cert->buf); - - } else if (strcmp(scejson->valuestring, RA_SCENARIO_AS_NO_DAA) == 0) { - tr->scenario = RA_SCENARIO_AS_NO_DAA_INT; - // signature: as no daa - cJSON *asjson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_as_no_daa"); - tr->signature->buf = base64urldecode(asjson->valuestring, strlen(asjson->valuestring), &tr->signature->size); - // akcert: as no daa - cJSON *c2json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_as_no_daa"); - tr->cert->buf = base64urldecode(c2json->valuestring, strlen(c2json->valuestring), &tr->cert->size); - - } else if (strcmp(scejson->valuestring, RA_SCENARIO_AS_WITH_DAA) == 0) { - tr->scenario = RA_SCENARIO_AS_WITH_DAA_INT; - // signature: daa (parse needed) - cJSON *daajson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_as_with_daa"); - tr->signature->buf = cJSON_Print(daajson); - tr->signature->size = strlen(tr->signature->buf); - // akcert: daa - cJSON *c3json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_as_with_daa"); - tr->cert->buf = base64urldecode(c3json->valuestring, strlen(c3json->valuestring), &tr->cert->size); - - } else { - printf("invalid scenario"); - return false; - } - return true; -} - -bool get_alg_from_payload(cJSON *pljson, TA_report *tr) { - // get hash&sign algorithm: string -> uint32_t - cJSON *sjson = cJSON_GetObjectItemCaseSensitive(pljson, "sign_alg"); - cJSON *hjson = cJSON_GetObjectItemCaseSensitive(pljson, "hash_alg"); - if (hjson == NULL || sjson == NULL) { - printf("cjson parse algorithm from report error"); - return false; - } - - if (strcmp(sjson->valuestring, RA_SIGN_ALG_RSA4096) == 0) { - tr->sig_alg = RA_ALG_RSA_4096; - } - if (strcmp(hjson->valuestring, RA_HASH_ALG_SHA256) == 0) { - tr->hash_alg = RA_ALG_SHA_256; - } - return true; -} - -bool get_other_params_from_report(cJSON *pljson, TA_report *tr) { - // get version, timestamp, ta_attr - cJSON *vjson = cJSON_GetObjectItemCaseSensitive(pljson, "version"); - cJSON *tsjson = cJSON_GetObjectItemCaseSensitive(pljson, "timestamp"); - cJSON *reservejson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_attr"); - if (vjson == NULL || tsjson == NULL || reservejson == NULL) { - printf("cjson parse algorithm from report error"); - return false; - } - - memcpy(tr->timestamp, tsjson->valuestring, strlen(tsjson->valuestring)); - memcpy(tr->reserve, reservejson->valuestring, strlen(reservejson->valuestring)); - memcpy(tr->version, vjson->valuestring, strlen(vjson->valuestring)); - - return true; -} - -TA_report * -Convert(buffer_data *data) -{ - TA_report *report = NULL; - - // determine whether the buffer is legal - if (data == NULL) - verifier_error("illegal buffer data pointer."); - if (data->size > DATABUFMAX || data->size < DATABUFMIN) - verifier_error("size of buffer is illegal."); - - // parse report - // printf(data->buf); - cJSON *cj = cJSON_ParseWithLength(data->buf, data->size); - if (cj == NULL) { - verifier_error("cjson parse report error."); - } - // get payload, report_sign, akcert - cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); - cJSON *sigjson = cJSON_GetObjectItemCaseSensitive(cj, "report_sign"); - cJSON *acjson = cJSON_GetObjectItemCaseSensitive(cj, "akcert"); - if (pljson == NULL || sigjson == NULL || acjson == NULL) { - printf("cjson parse report error"); - goto err1; - } - report = (TA_report *)calloc(1, sizeof(TA_report)); - if (report == NULL) { - printf("out of memory."); - goto err1; - } - - bool rt = get_nonce_from_payload(pljson, report); - if (!rt) { - printf("get nonce from report error"); - goto err2; - } - rt = get_uuid_from_payload(pljson, report); - if (!rt) { - printf("get uuid from report error"); - goto err2; - } - rt = get_hash_from_payload(pljson, report); - if (!rt) { - printf("get hash from report error"); - goto err2; - } - rt = get_alg_from_payload(pljson, report); - if (!rt) { - printf("get hash & sign algorithm from report error"); - goto err2; - } - rt = get_other_params_from_report(pljson, report); - if (!rt) { - printf("get version & timestamp & ta_attr from report error"); - goto err2; - } - // get scenario & sign & cert from report - rt = get_scenario_from_report(pljson, sigjson, acjson, report); - if (!rt) { - printf("get scenario & sign & cert from report error"); - goto err2; - } - // signature & cert are different from the previous data - cJSON_Delete(cj); - return report; + TA_report *report = Convert(bufdata); + base_value *baseval = LoadBaseValue(report, filename); + + bool verified; + if ((report == NULL) || (baseval == NULL)) { + printf("Pointer Error!\n"); + verified = false; + } else + verified = Compare(type, report, + baseval); // compare the report with the basevalue + + free_report(report); + free(baseval); + return verified; +} + +bool get_nonce_from_payload(cJSON *pljson, TA_report *tr) +{ + // get nonce: base64 -> uint8_t* + cJSON *njson = cJSON_GetObjectItemCaseSensitive(pljson, "nonce"); + if (njson == NULL) { + printf("cjson parse nonce from report error"); + return false; + } + int len = 0; + uint8_t *tmp = base64urldecode(njson->valuestring, strlen(njson->valuestring), &len); + memset(tr->nonce, 0, 64); + memcpy(tr->nonce, tmp, len); + return true; +} + +bool get_uuid_from_payload(cJSON *pljson, TA_report *tr) +{ + // get uuid: string -> uint8_t* + cJSON *ujson = cJSON_GetObjectItemCaseSensitive(pljson, "uuid"); + if (ujson == NULL) { + printf("cjson parse uuid from report error"); + return false; + } + str_to_uuid(ujson->valuestring, tr->uuid); + + return true; +} + +bool get_hash_from_payload(cJSON *pljson, TA_report *tr) +{ + // get img&mem hash: base64 -> uint8_t* + cJSON *imgjson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_img"); + cJSON *memjson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_mem"); + if (imgjson == NULL || memjson == NULL) { + printf("cjson parse hash from report error"); + return false; + } + + int len = 0; + uint8_t *tmp1 = base64urldecode(imgjson->valuestring, strlen(imgjson->valuestring), &len); + memcpy(tr->image_hash, tmp1, 32); + + uint8_t *tmp2 = base64urldecode(memjson->valuestring, strlen(memjson->valuestring), &len); + memcpy(tr->hash, tmp2, 32); + + free(tmp1); + free(tmp2); + return true; +} + +bool get_scenario_from_report(cJSON *pljson, cJSON *signjson, cJSON *acjson, TA_report *tr) +{ + if (pljson == NULL || signjson == NULL || acjson == NULL || tr == NULL) { + printf("invalid input parameter\n"); + return false; + } + cJSON *scejson = cJSON_GetObjectItemCaseSensitive(pljson, "scenario"); + if (scejson == NULL) { + printf("cjson parse scenario from report error\n"); + return false; + } + tr->signature = malloc(sizeof(buffer_data)); + tr->cert = malloc(sizeof(buffer_data)); + if (strcmp(scejson->valuestring, RA_SCENARIO_NO_AS) == 0) { + tr->scenario = RA_SCENARIO_NO_AS_INT; + // signature: no as + cJSON *noasjson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_no_as"); + tr->signature->buf = + base64urldecode(noasjson->valuestring, strlen(noasjson->valuestring), &tr->signature->size); + // akcert: no as (parse needed) + cJSON *c1json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_no_as"); + tr->cert->buf = cJSON_Print(c1json); + tr->cert->size = strlen(tr->cert->buf); + + } else if (strcmp(scejson->valuestring, RA_SCENARIO_AS_NO_DAA) == 0) { + tr->scenario = RA_SCENARIO_AS_NO_DAA_INT; + // signature: as no daa + cJSON *asjson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_as_no_daa"); + tr->signature->buf = base64urldecode(asjson->valuestring, strlen(asjson->valuestring), &tr->signature->size); + // akcert: as no daa + cJSON *c2json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_as_no_daa"); + tr->cert->buf = base64urldecode(c2json->valuestring, strlen(c2json->valuestring), &tr->cert->size); + + } else if (strcmp(scejson->valuestring, RA_SCENARIO_AS_WITH_DAA) == 0) { + tr->scenario = RA_SCENARIO_AS_WITH_DAA_INT; + // signature: daa (parse needed) + cJSON *daajson = cJSON_GetObjectItemCaseSensitive(signjson, "sce_as_with_daa"); + tr->signature->buf = cJSON_Print(daajson); + tr->signature->size = strlen(tr->signature->buf); + // akcert: daa + cJSON *c3json = cJSON_GetObjectItemCaseSensitive(acjson, "sce_as_with_daa"); + tr->cert->buf = base64urldecode(c3json->valuestring, strlen(c3json->valuestring), &tr->cert->size); + + } else { + printf("invalid scenario"); + return false; + } + return true; +} + +bool get_alg_from_payload(cJSON *pljson, TA_report *tr) +{ + // get hash&sign algorithm: string -> uint32_t + cJSON *sjson = cJSON_GetObjectItemCaseSensitive(pljson, "sign_alg"); + cJSON *hjson = cJSON_GetObjectItemCaseSensitive(pljson, "hash_alg"); + if (hjson == NULL || sjson == NULL) { + printf("cjson parse algorithm from report error"); + return false; + } + + if (strcmp(sjson->valuestring, RA_SIGN_ALG_RSA4096) == 0) { + tr->sig_alg = RA_ALG_RSA_4096; + } + if (strcmp(hjson->valuestring, RA_HASH_ALG_SHA256) == 0) { + tr->hash_alg = RA_ALG_SHA_256; + } + return true; +} + +bool get_other_params_from_report(cJSON *pljson, TA_report *tr) +{ + // get version, timestamp, ta_attr + cJSON *vjson = cJSON_GetObjectItemCaseSensitive(pljson, "version"); + cJSON *tsjson = cJSON_GetObjectItemCaseSensitive(pljson, "timestamp"); + cJSON *reservejson = cJSON_GetObjectItemCaseSensitive(pljson, "ta_attr"); + if (vjson == NULL || tsjson == NULL || reservejson == NULL) { + printf("cjson parse algorithm from report error"); + return false; + } + + memcpy(tr->timestamp, tsjson->valuestring, strlen(tsjson->valuestring)); + memcpy(tr->reserve, reservejson->valuestring, strlen(reservejson->valuestring)); + memcpy(tr->version, vjson->valuestring, strlen(vjson->valuestring)); + + return true; +} + +TA_report *Convert(buffer_data *data) +{ + TA_report *report = NULL; + + // determine whether the buffer is legal + if (data == NULL) + verifier_error("illegal buffer data pointer."); + if (data->size > DATABUFMAX || data->size < DATABUFMIN) + verifier_error("size of buffer is illegal."); + + // parse report + // printf(data->buf); + cJSON *cj = cJSON_ParseWithLength(data->buf, data->size); + if (cj == NULL) { + verifier_error("cjson parse report error."); + } + // get payload, report_sign, akcert + cJSON *pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); + cJSON *sigjson = cJSON_GetObjectItemCaseSensitive(cj, "report_sign"); + cJSON *acjson = cJSON_GetObjectItemCaseSensitive(cj, "akcert"); + if (pljson == NULL || sigjson == NULL || acjson == NULL) { + printf("cjson parse report error"); + goto err1; + } + report = (TA_report *)calloc(1, sizeof(TA_report)); + if (report == NULL) { + printf("out of memory."); + goto err1; + } + + bool rt = get_nonce_from_payload(pljson, report); + if (!rt) { + printf("get nonce from report error"); + goto err2; + } + rt = get_uuid_from_payload(pljson, report); + if (!rt) { + printf("get uuid from report error"); + goto err2; + } + rt = get_hash_from_payload(pljson, report); + if (!rt) { + printf("get hash from report error"); + goto err2; + } + rt = get_alg_from_payload(pljson, report); + if (!rt) { + printf("get hash & sign algorithm from report error"); + goto err2; + } + rt = get_other_params_from_report(pljson, report); + if (!rt) { + printf("get version & timestamp & ta_attr from report error"); + goto err2; + } + // get scenario & sign & cert from report + rt = get_scenario_from_report(pljson, sigjson, acjson, report); + if (!rt) { + printf("get scenario & sign & cert from report error"); + goto err2; + } + // signature & cert are different from the previous data + cJSON_Delete(cj); + return report; err2: - free_report(report); + free_report(report); err1: - cJSON_Delete(cj); - return NULL; - + cJSON_Delete(cj); + return NULL; } // void parse_uuid(uint8_t *uuid, TEE_UUID bufuuid) { @@ -1388,604 +1346,574 @@ err1: // NODE_LEN, uuid, &offset); // } -void read_bytes(void *input, size_t size, size_t nmemb, uint8_t *output, - size_t *offset) -{ - memcpy(output + *offset, input, size * nmemb); - *offset += size * nmemb; -} - -base_value * -LoadBaseValue(const TA_report *report, char *filename) -{ - base_value *baseval = NULL; - size_t fbuf_len = 0; // if needed - - if (report == NULL) - verifier_error("illegal report pointer!"); - char *fbuf = file_to_buffer(filename, &fbuf_len); - - /* - base_value *baseval_tmp = NULL; - size_t fbuf_offset = 0; - while(fbuf_offset < fbuf_len) { - baseval_tmp = (base_value *)(fbuf+fbuf_offset); - if (cmp_bytes(report->uuid, baseval_tmp->uuid, UUID_SIZE)) break; - fbuf_offset += sizeof(base_value); - } - - baseval = (base_value *)calloc(1, sizeof(base_value)); - memcpy(baseval->uuid, baseval_tmp->uuid, UUID_SIZE*sizeof(uint8_t)); - memcpy(baseval->valueinfo[0], baseval_tmp->valueinfo[0], - HASH_SIZE*sizeof(uint8_t)); memcpy(baseval->valueinfo[1], - baseval_tmp->valueinfo[1], HASH_SIZE*sizeof(uint8_t)); - - baseval_tmp = NULL; - **/ - - // fbuf is string stream. - char *line = NULL; - line = strtok(fbuf, "\n"); - - baseval = (base_value *)calloc(1, sizeof(base_value)); - char uuid_str[37]; - char image_hash_str[65]; - char hash_str[65]; - int num = 0; - while (line != NULL) - { - ++num; - sscanf(line, "%36s %64s %64s", uuid_str, image_hash_str, hash_str); - str_to_uuid(uuid_str, baseval->uuid); - if (cmp_bytes(report->uuid, baseval->uuid, UUID_SIZE)) - { - str_to_hash(image_hash_str, baseval->valueinfo[0]); - str_to_hash(hash_str, baseval->valueinfo[1]); - break; - } - - line = strtok(NULL, "\n"); - } - - free(fbuf); - return baseval; +void read_bytes(void *input, size_t size, size_t nmemb, uint8_t *output, size_t *offset) +{ + memcpy(output + *offset, input, size * nmemb); + *offset += size * nmemb; +} + +base_value *LoadBaseValue(const TA_report *report, char *filename) +{ + base_value *baseval = NULL; + size_t fbuf_len = 0; // if needed + + if (report == NULL) + verifier_error("illegal report pointer!"); + char *fbuf = file_to_buffer(filename, &fbuf_len); + + /* + base_value *baseval_tmp = NULL; + size_t fbuf_offset = 0; + while(fbuf_offset < fbuf_len) { + baseval_tmp = (base_value *)(fbuf+fbuf_offset); + if (cmp_bytes(report->uuid, baseval_tmp->uuid, UUID_SIZE)) break; + fbuf_offset += sizeof(base_value); + } + + baseval = (base_value *)calloc(1, sizeof(base_value)); + memcpy(baseval->uuid, baseval_tmp->uuid, UUID_SIZE*sizeof(uint8_t)); + memcpy(baseval->valueinfo[0], baseval_tmp->valueinfo[0], + HASH_SIZE*sizeof(uint8_t)); memcpy(baseval->valueinfo[1], + baseval_tmp->valueinfo[1], HASH_SIZE*sizeof(uint8_t)); + + baseval_tmp = NULL; + **/ + + // fbuf is string stream. + char *line = NULL; + line = strtok(fbuf, "\n"); + + baseval = (base_value *)calloc(1, sizeof(base_value)); + char uuid_str[37]; + char image_hash_str[65]; + char hash_str[65]; + int num = 0; + while (line != NULL) { + ++num; + sscanf(line, "%36s %64s %64s", uuid_str, image_hash_str, hash_str); + str_to_uuid(uuid_str, baseval->uuid); + if (cmp_bytes(report->uuid, baseval->uuid, UUID_SIZE)) { + str_to_hash(image_hash_str, baseval->valueinfo[0]); + str_to_hash(hash_str, baseval->valueinfo[1]); + break; + } + + line = strtok(NULL, "\n"); + } + + free(fbuf); + return baseval; } void reverse(uint8_t *bytes, int size) { - for (int i = 0; i < size / 2; i++) - { - int tmp = bytes[i]; - bytes[i] = bytes[size - 1 - i]; - bytes[size - 1 - i] = tmp; - } + for (int i = 0; i < size / 2; i++) { + int tmp = bytes[i]; + bytes[i] = bytes[size - 1 - i]; + bytes[size - 1 - i] = tmp; + } } void str_to_uuid(const char *str, uint8_t *uuid) { - char substr1[9]; - char substr2[5]; - char substr3[5]; - char substr4[5]; - char substr5[13]; - // 8-4-4-4-12 - sscanf(str, "%8[^-]-%4[^-]-%4[^-]-%4[^-]-%12[^-]", substr1, substr2, - substr3, substr4, substr5); - str2hex(substr1, 4, uuid); - reverse(uuid, 4); - str2hex(substr2, 2, uuid + 4); - reverse(uuid + 4, 2); - str2hex(substr3, 2, uuid + 4 + 2); - reverse(uuid + 4 + 2, 2); - str2hex(substr4, 2, uuid + 4 + 2 + 2); - str2hex(substr5, 6, uuid + 4 + 2 + 2 + 2); + char substr1[9]; + char substr2[5]; + char substr3[5]; + char substr4[5]; + char substr5[13]; + // 8-4-4-4-12 + sscanf(str, "%8[^-]-%4[^-]-%4[^-]-%4[^-]-%12[^-]", substr1, substr2, substr3, substr4, substr5); + str2hex(substr1, 4, uuid); + reverse(uuid, 4); + str2hex(substr2, 2, uuid + 4); + reverse(uuid + 4, 2); + str2hex(substr3, 2, uuid + 4 + 2); + reverse(uuid + 4 + 2, 2); + str2hex(substr4, 2, uuid + 4 + 2 + 2); + str2hex(substr5, 6, uuid + 4 + 2 + 2 + 2); } void uuid_to_str(const uint8_t *uuid, char *str) { - uint8_t tmp[4]; - // 8- - memcpy(tmp, uuid, 4); - reverse(tmp, 4); - hex2str(tmp, 4, str); - strcpy(str + 4 * 2, "-"); - // str[4*2] = "-"; - // 8-4- - memcpy(tmp, uuid + 4, 2); - reverse(tmp, 2); - hex2str(tmp, 2, str + 9); - strcpy(str + 9 + 2 * 2, "-"); - // str[9+2*2] = "-"; - // 8-4-4- - memcpy(tmp, uuid + 4 + 2, 2); - reverse(tmp, 2); - hex2str(tmp, 2, str + 14); - strcpy(str + 14 + 2 * 2, "-"); - // str[14+2*2] = "-"; - // 8-4-4-4- - hex2str(uuid + 4 + 2 + 2, 2, str + 19); - strcpy(str + 19 + 2 * 2, "-"); - // str[19+2*2] = "-"; - // 8-4-4-4-12 - hex2str(uuid + 4 + 2 + 2 + 2, 6, str + 24); + uint8_t tmp[4]; + // 8- + memcpy(tmp, uuid, 4); + reverse(tmp, 4); + hex2str(tmp, 4, str); + strcpy(str + 4 * 2, "-"); + // str[4*2] = "-"; + // 8-4- + memcpy(tmp, uuid + 4, 2); + reverse(tmp, 2); + hex2str(tmp, 2, str + 9); + strcpy(str + 9 + 2 * 2, "-"); + // str[9+2*2] = "-"; + // 8-4-4- + memcpy(tmp, uuid + 4 + 2, 2); + reverse(tmp, 2); + hex2str(tmp, 2, str + 14); + strcpy(str + 14 + 2 * 2, "-"); + // str[14+2*2] = "-"; + // 8-4-4-4- + hex2str(uuid + 4 + 2 + 2, 2, str + 19); + strcpy(str + 19 + 2 * 2, "-"); + // str[19+2*2] = "-"; + // 8-4-4-4-12 + hex2str(uuid + 4 + 2 + 2 + 2, 6, str + 24); } void str_to_hash(const char *str, uint8_t *hash) { - // 64 bit -> 32 bit - str2hex(str, HASH_SIZE, hash); + // 64 bit -> 32 bit + str2hex(str, HASH_SIZE, hash); } void hash_to_str(const uint8_t *hash, char *str) { - // 32 bit -> 64 bit - hex2str(hash, HASH_SIZE, str); + // 32 bit -> 64 bit + hex2str(hash, HASH_SIZE, str); } void hex2str(const uint8_t *source, int source_len, char *dest) { - int i; - unsigned char HighByte; - unsigned char LowByte; + int i; + unsigned char HighByte; + unsigned char LowByte; - for (i = 0; i < source_len; i++) - { - HighByte = source[i] >> 4; // get high 4bit from a byte - LowByte = source[i] & 0x0f; // get low 4bit + for (i = 0; i < source_len; i++) { + HighByte = source[i] >> 4; // get high 4bit from a byte + LowByte = source[i] & 0x0f; // get low 4bit - HighByte += 0x30; // Get the corresponding char, and skip 7 symbols if - // it's a letter - if (HighByte <= 0x39) // number - dest[i * 2] = HighByte; - else // letter - dest[i * 2] = HighByte + 0x07; // Get the char and save it to the corresponding position + HighByte += 0x30; // Get the corresponding char, and skip 7 symbols if + // it's a letter + if (HighByte <= 0x39) // number + dest[i * 2] = HighByte; + else // letter + dest[i * 2] = HighByte + 0x07; // Get the char and save it to the corresponding position - LowByte += 0x30; - if (LowByte <= 0x39) - dest[i * 2 + 1] = LowByte; - else - dest[i * 2 + 1] = LowByte + 0x07; - } + LowByte += 0x30; + if (LowByte <= 0x39) + dest[i * 2 + 1] = LowByte; + else + dest[i * 2 + 1] = LowByte + 0x07; + } } void str2hex(const char *source, int source_len, uint8_t *dest) { - int i; - unsigned char HighByte; - unsigned char LowByte; - - for (i = 0; i < source_len; i++) - { - HighByte = toupper(source[i * 2]); // If lower case is encountered, - // uppercase processing is performed - LowByte = toupper(source[i * 2 + 1]); - - if (HighByte <= 0x39) // 0x39 corresponds to the character '9', where it - // is a number - HighByte -= 0x30; - - else // Otherwise, it is a letter, and 7 symbols need to be skipped - HighByte -= 0x37; - - if (LowByte <= 0x39) - LowByte -= 0x30; - - else - LowByte -= 0x37; - - /* - * Let's say the string "3c" - * HighByte = 0x03, binary is 0000 0011 - * LowByte = 0x0c, binary is 0000 1100 - * - * HighByte << 4 = 0011 0000 - * HighByte | LowByte : - * - * 0011 0000 - * 0000 1100 - * ------------- - * 0011 1100 - * - * that is 0x3c - * - **/ - dest[i] = (HighByte << 4) | LowByte; - } -} - -char * -file_to_buffer(char *file, size_t *file_length) -{ - FILE *f = NULL; - char *buffer = NULL; - - f = fopen(file, "rb"); - if (!f) - { - printf("Couldn't open file: %s\n", file); - return NULL; - } - fseek(f, 0L, SEEK_END); - *file_length = ftell(f); - rewind(f); - buffer = (char *)malloc(*file_length + 1); - if (NULL == buffer) - { - goto err; - } - size_t result = fread(buffer, 1, *file_length, f); - if (result != *file_length) - { - free(buffer); - buffer = NULL; - } + int i; + unsigned char HighByte; + unsigned char LowByte; + + for (i = 0; i < source_len; i++) { + HighByte = toupper(source[i * 2]); // If lower case is encountered, + // uppercase processing is performed + LowByte = toupper(source[i * 2 + 1]); + + if (HighByte <= 0x39) // 0x39 corresponds to the character '9', where it + // is a number + HighByte -= 0x30; + + else // Otherwise, it is a letter, and 7 symbols need to be skipped + HighByte -= 0x37; + + if (LowByte <= 0x39) + LowByte -= 0x30; + + else + LowByte -= 0x37; + + /* + * Let's say the string "3c" + * HighByte = 0x03, binary is 0000 0011 + * LowByte = 0x0c, binary is 0000 1100 + * + * HighByte << 4 = 0011 0000 + * HighByte | LowByte : + * + * 0011 0000 + * 0000 1100 + * ------------- + * 0011 1100 + * + * that is 0x3c + * + **/ + dest[i] = (HighByte << 4) | LowByte; + } +} + +char *file_to_buffer(char *file, size_t *file_length) +{ + FILE *f = NULL; + char *buffer = NULL; + + f = fopen(file, "rb"); + if (!f) { + printf("Couldn't open file: %s\n", file); + return NULL; + } + fseek(f, 0L, SEEK_END); + *file_length = ftell(f); + rewind(f); + buffer = (char *)malloc(*file_length + 1); + if (NULL == buffer) { + goto err; + } + size_t result = fread(buffer, 1, *file_length, f); + if (result != *file_length) { + free(buffer); + buffer = NULL; + } err: - fclose(f); - return buffer; + fclose(f); + return buffer; } bool Compare(int type, TA_report *report, base_value *basevalue) { - bool compared; - /* - test_print(report->image_hash, HASH_SIZE, "report->image_hash"); - test_print(report->hash, HASH_SIZE, "report->hash"); - test_print(basevalue->valueinfo[0], HASH_SIZE, "basevalue->valueinfo[0]"); - test_print(basevalue->valueinfo[1], HASH_SIZE, "basevalue->valueinfo[1]"); - test_print(report->uuid, 16, "report->uuid"); - test_print(basevalue->uuid, 16, "basevalue->uuid"); - */ - switch (type) - { - case 1: - printf("%s\n", "Compare image measurement.."); - compared = cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE); - break; - case 2: - printf("%s\n", "Compare hash measurement.."); - compared = cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE); - break; - case 3: - printf("%s\n", "Compare image & hash measurement.."); - compared = (cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE) & cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE)); - break; - default: - printf("%s\n", "Type is incorrect."); - compared = false; - } - - printf("%s\n", "Finish Comparation"); - return compared; + bool compared; + /* + test_print(report->image_hash, HASH_SIZE, "report->image_hash"); + test_print(report->hash, HASH_SIZE, "report->hash"); + test_print(basevalue->valueinfo[0], HASH_SIZE, "basevalue->valueinfo[0]"); + test_print(basevalue->valueinfo[1], HASH_SIZE, "basevalue->valueinfo[1]"); + test_print(report->uuid, 16, "report->uuid"); + test_print(basevalue->uuid, 16, "basevalue->uuid"); + */ + switch (type) { + case 1: + printf("%s\n", "Compare image measurement.."); + compared = cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE); + break; + case 2: + printf("%s\n", "Compare hash measurement.."); + compared = cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE); + break; + case 3: + printf("%s\n", "Compare image & hash measurement.."); + compared = (cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE) & + cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE)); + break; + default: + printf("%s\n", "Type is incorrect."); + compared = false; + } + + printf("%s\n", "Finish Comparation"); + return compared; } bool cmp_bytes(const uint8_t *a, const uint8_t *b, size_t size) { - for (size_t i = 0; i < size; i++) - { - if (*(a + i) != *(b + i)) - return false; - } + for (size_t i = 0; i < size; i++) { + if (*(a + i) != *(b + i)) + return false; + } - return true; + return true; } void save_basevalue(const base_value *bv) { - // char **temp = (char **)malloc(sizeof(char*) * 3); - // temp[0] = (char *)malloc(sizeof(char) * (32+4)); - // temp[1] = (char *)malloc(sizeof(char) * 64); - // temp[2] = (char *)malloc(sizeof(char) * 64); - char uuid_str[37]; - char image_hash_str[65]; - char hash_str[65]; - memset(uuid_str, '\0', sizeof(uuid_str)); - memset(image_hash_str, '\0', sizeof(image_hash_str)); - memset(hash_str, '\0', sizeof(hash_str)); - - uuid_to_str(bv->uuid, uuid_str); - hash_to_str(bv->valueinfo[0], image_hash_str); - hash_to_str(bv->valueinfo[1], hash_str); - - const int bvbuf_len = 200; - char bvbuf[bvbuf_len]; // 32+4+2+64+64+1=167 < 200 - memset(bvbuf, '\0', sizeof(bvbuf)); - strcpy(bvbuf, uuid_str); - strcat(bvbuf, " "); - strcat(bvbuf, image_hash_str); - strcat(bvbuf, " "); - strcat(bvbuf, hash_str); - strcat(bvbuf, "\n"); - printf("%s\n", bvbuf); - - FILE *fp_output = fopen("basevalue.txt", "w"); - fwrite(bvbuf, strnlen(bvbuf, sizeof(bvbuf)), 1, fp_output); - fclose(fp_output); + // char **temp = (char **)malloc(sizeof(char*) * 3); + // temp[0] = (char *)malloc(sizeof(char) * (32+4)); + // temp[1] = (char *)malloc(sizeof(char) * 64); + // temp[2] = (char *)malloc(sizeof(char) * 64); + char uuid_str[37]; + char image_hash_str[65]; + char hash_str[65]; + memset(uuid_str, '\0', sizeof(uuid_str)); + memset(image_hash_str, '\0', sizeof(image_hash_str)); + memset(hash_str, '\0', sizeof(hash_str)); + + uuid_to_str(bv->uuid, uuid_str); + hash_to_str(bv->valueinfo[0], image_hash_str); + hash_to_str(bv->valueinfo[1], hash_str); + + const int bvbuf_len = 200; + char bvbuf[bvbuf_len]; // 32+4+2+64+64+1=167 < 200 + memset(bvbuf, '\0', sizeof(bvbuf)); + strcpy(bvbuf, uuid_str); + strcat(bvbuf, " "); + strcat(bvbuf, image_hash_str); + strcat(bvbuf, " "); + strcat(bvbuf, hash_str); + strcat(bvbuf, "\n"); + printf("%s\n", bvbuf); + + FILE *fp_output = fopen("basevalue.txt", "w"); + fwrite(bvbuf, strnlen(bvbuf, sizeof(bvbuf)), 1, fp_output); + fclose(fp_output); } bool tee_verify_nonce(buffer_data *buf_data, buffer_data *nonce) { - if (nonce == NULL || nonce->size > USER_DATA_SIZE) - { - printf("the nonce-value is invalid\n"); - return false; - } - TA_report *report; - report = Convert(buf_data); - if (report == NULL) - { - printf("failed to parse the report\n"); - return false; - } - - uint8_t tmp[64] = {0}; - bool vn = false; - - if (nonce->size > sizeof(report->nonce)) { - printf("nonce length error, verify nonce failed.\n"); - free_report(report); - return false; - } else { // nonce->size <= sizeof(report->nonce) - memcpy(tmp, nonce->buf, nonce->size); - } - - //vn = cmp_bytes(report->nonce, nonce->buf, nonce->size); - vn = cmp_bytes(report->nonce, tmp, sizeof(report->nonce)); - - free_report(report); - return vn; -} - -int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, - char *filename) -{ - bool vn = tee_verify_nonce(buf_data, nonce); - if (vn == false) - { - return TVS_VERIFIED_NONCE_FAILED; - } - bool vs = tee_verify_signature(buf_data); - if (vs == false) - { - return TVS_VERIFIED_SIGNATURE_FAILED; - } - bool v = tee_verify(buf_data, type, filename); - if (v == false) - { - return TVS_VERIFIED_HASH_FAILED; - } - return TVS_ALL_SUCCESSED; + if (nonce == NULL || nonce->size > USER_DATA_SIZE) { + printf("the nonce-value is invalid\n"); + return false; + } + TA_report *report; + report = Convert(buf_data); + if (report == NULL) { + printf("failed to parse the report\n"); + return false; + } + + uint8_t tmp[64] = {0}; + bool vn = false; + + if (nonce->size > sizeof(report->nonce)) { + printf("nonce length error, verify nonce failed.\n"); + free_report(report); + return false; + } else { // nonce->size <= sizeof(report->nonce) + memcpy(tmp, nonce->buf, nonce->size); + } + + // vn = cmp_bytes(report->nonce, nonce->buf, nonce->size); + vn = cmp_bytes(report->nonce, tmp, sizeof(report->nonce)); + + free_report(report); + return vn; +} + +int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, char *filename) +{ + bool vn = tee_verify_nonce(buf_data, nonce); + if (vn == false) { + return TVS_VERIFIED_NONCE_FAILED; + } + bool vs = tee_verify_signature(buf_data); + if (vs == false) { + return TVS_VERIFIED_SIGNATURE_FAILED; + } + bool v = tee_verify(buf_data, type, filename); + if (v == false) { + return TVS_VERIFIED_HASH_FAILED; + } + return TVS_ALL_SUCCESSED; } bool tee_verify2(buffer_data *bufdata, int type, base_value *baseval) { - TA_report *report = Convert(bufdata); + TA_report *report = Convert(bufdata); - bool verified; - if ((report == NULL) || (baseval == NULL)) - { - printf("%s\n", "Pointer Error!"); - verified = false; - } - else - verified = Compare(type, report, - baseval); // compare the report with the basevalue + bool verified; + if ((report == NULL) || (baseval == NULL)) { + printf("%s\n", "Pointer Error!"); + verified = false; + } else + verified = Compare(type, report, + baseval); // compare the report with the basevalue - free_report(report); - return verified; + free_report(report); + return verified; } int tee_validate_report(buffer_data *buf_data, buffer_data *nonce) { - bool vn = tee_verify_nonce(buf_data, nonce); - if (vn == false) - { - return TVS_VERIFIED_NONCE_FAILED; - } - - bool vs = tee_verify_signature(buf_data); - if (vs == false) - { - return TVS_VERIFIED_SIGNATURE_FAILED; - } + bool vn = tee_verify_nonce(buf_data, nonce); + if (vn == false) { + return TVS_VERIFIED_NONCE_FAILED; + } + + bool vs = tee_verify_signature(buf_data); + if (vs == false) { + return TVS_VERIFIED_SIGNATURE_FAILED; + } - return TVS_ALL_SUCCESSED; + return TVS_ALL_SUCCESSED; } int tee_validate_report2(buffer_data *buf_data, buffer_data *nonce) { - // bypass nonce verification - bool vs = tee_verify_signature(buf_data); - if (vs == false) - { - return TVS_VERIFIED_SIGNATURE_FAILED; - } + // bypass nonce verification + bool vs = tee_verify_signature(buf_data); + if (vs == false) { + return TVS_VERIFIED_SIGNATURE_FAILED; + } - return TVS_ALL_SUCCESSED; + return TVS_ALL_SUCCESSED; } -int tee_verify_report2(buffer_data *buf_data, int type, - base_value *baseval) +int tee_verify_report2(buffer_data *buf_data, int type, base_value *baseval) { - bool v = tee_verify2(buf_data, type, baseval); - if (v == false) - { - return TVS_VERIFIED_HASH_FAILED; - } - return TVS_ALL_SUCCESSED; + bool v = tee_verify2(buf_data, type, baseval); + if (v == false) { + return TVS_VERIFIED_HASH_FAILED; + } + return TVS_ALL_SUCCESSED; } static base_value *LoadQTABaseValue(const char *refval) { - base_value *baseval = (base_value *)calloc(1, sizeof(base_value)); - if (baseval == NULL) - return NULL; + base_value *baseval = (base_value *)calloc(1, sizeof(base_value)); + if (baseval == NULL) + return NULL; - char image_hash_str[65]; - char hash_str[65]; - if (EOF == sscanf(refval,"%64s %64s", image_hash_str, hash_str)) - { - free(baseval); - return NULL; - } - str_to_hash(image_hash_str, baseval->valueinfo[0]); - str_to_hash(hash_str, baseval->valueinfo[1]); - return baseval; + char image_hash_str[65]; + char hash_str[65]; + if (EOF == sscanf(refval, "%64s %64s", image_hash_str, hash_str)) { + free(baseval); + return NULL; + } + str_to_hash(image_hash_str, baseval->valueinfo[0]); + str_to_hash(hash_str, baseval->valueinfo[1]); + return baseval; } static base_value *get_qta(buffer_data *akcert) { - if (akcert->buf == NULL) { - printf("akcert is null"); - return NULL; - } - cJSON *pljson = NULL; - cJSON *qimgjson = NULL; - cJSON *qmemjson = NULL; - buffer_data qimg; - buffer_data qmem; - base_value *qta = (base_value *)calloc(1, sizeof(base_value)); - if (qta == NULL) { - return NULL; - } - // parse akcert - cJSON *cj = cJSON_Parse(akcert->buf); - if (cj == NULL) { - printf("cjson parse akcert error"); - goto err1; - } - // get payload - pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); - if (pljson == NULL) { - printf("cjson parse akcert error"); - goto err2; - } - // get qta_img, qta_mem - qimgjson = cJSON_GetObjectItemCaseSensitive(pljson, "qta_img"); - qmemjson = cJSON_GetObjectItemCaseSensitive(pljson, "qta_mem"); - if (qimgjson == NULL || qmemjson == NULL) { - printf("cjson parse akcert error"); - goto err2; - } - /* - "qta_img": BASE64_TYPE, BASE64 of TA's img hash - "qta_mem": BASE64_TYPE, BASE64 of TA's mem hash - */ - // str2uint8(qimgjson->valuestring, strlen(qimgjson->valuestring)/2, qimgtmp); - - qimg.buf = base64urldecode(qimgjson->valuestring, strlen(qimgjson->valuestring), &qimg.size); - // str2uint8(qmemjson->valuestring, strlen(qmemjson->valuestring)/2, qmemtmp); - qmem.buf = base64urldecode(qmemjson->valuestring, strlen(qmemjson->valuestring), &qmem.size); - memcpy(qta->valueinfo[0], qimg.buf, qimg.size); - memcpy(qta->valueinfo[1], qmem.buf, qmem.size); - - if (qimg.buf != NULL) - free(qimg.buf); - if (qmem.buf != NULL) - free(qmem.buf); - - cJSON_Delete(cj); - return qta; + if (akcert->buf == NULL) { + printf("akcert is null"); + return NULL; + } + cJSON *pljson = NULL; + cJSON *qimgjson = NULL; + cJSON *qmemjson = NULL; + buffer_data qimg; + buffer_data qmem; + base_value *qta = (base_value *)calloc(1, sizeof(base_value)); + if (qta == NULL) { + return NULL; + } + // parse akcert + cJSON *cj = cJSON_Parse(akcert->buf); + if (cj == NULL) { + printf("cjson parse akcert error"); + goto err1; + } + // get payload + pljson = cJSON_GetObjectItemCaseSensitive(cj, "payload"); + if (pljson == NULL) { + printf("cjson parse akcert error"); + goto err2; + } + // get qta_img, qta_mem + qimgjson = cJSON_GetObjectItemCaseSensitive(pljson, "qta_img"); + qmemjson = cJSON_GetObjectItemCaseSensitive(pljson, "qta_mem"); + if (qimgjson == NULL || qmemjson == NULL) { + printf("cjson parse akcert error"); + goto err2; + } + /* + "qta_img": BASE64_TYPE, BASE64 of TA's img hash + "qta_mem": BASE64_TYPE, BASE64 of TA's mem hash + */ + // str2uint8(qimgjson->valuestring, strlen(qimgjson->valuestring)/2, qimgtmp); + + qimg.buf = base64urldecode(qimgjson->valuestring, strlen(qimgjson->valuestring), &qimg.size); + // str2uint8(qmemjson->valuestring, strlen(qmemjson->valuestring)/2, qmemtmp); + qmem.buf = base64urldecode(qmemjson->valuestring, strlen(qmemjson->valuestring), &qmem.size); + memcpy(qta->valueinfo[0], qimg.buf, qimg.size); + memcpy(qta->valueinfo[1], qmem.buf, qmem.size); + + if (qimg.buf != NULL) + free(qimg.buf); + if (qmem.buf != NULL) + free(qmem.buf); + + cJSON_Delete(cj); + return qta; err2: - cJSON_Delete(cj); + cJSON_Delete(cj); err1: - free(qta); - return NULL; + free(qta); + return NULL; } static bool CompareBV(int type, base_value *value, base_value *basevalue) { - bool compared; - switch (type) - { - case 1: - printf("%s\n", "Compare image measurement.."); - compared = cmp_bytes(value->valueinfo[0], basevalue->valueinfo[0], HASH_SIZE); - break; - case 2: - printf("%s\n", "Compare hash measurement.."); - compared = cmp_bytes(value->valueinfo[1], basevalue->valueinfo[1], HASH_SIZE); - break; - case 3: - printf("%s\n", "Compare image & hash measurement.."); - compared = cmp_bytes(value->valueinfo[0], basevalue->valueinfo[0], HASH_SIZE) && cmp_bytes(value->valueinfo[1], basevalue->valueinfo[1], HASH_SIZE); - break; - default: - printf("%s\n", "Type is incorrect."); - compared = false; - } - - printf("%s\n", "Finish Comparation"); - return compared; + bool compared; + switch (type) { + case 1: + printf("%s\n", "Compare image measurement.."); + compared = cmp_bytes(value->valueinfo[0], basevalue->valueinfo[0], HASH_SIZE); + break; + case 2: + printf("%s\n", "Compare hash measurement.."); + compared = cmp_bytes(value->valueinfo[1], basevalue->valueinfo[1], HASH_SIZE); + break; + case 3: + printf("%s\n", "Compare image & hash measurement.."); + compared = cmp_bytes(value->valueinfo[0], basevalue->valueinfo[0], HASH_SIZE) && + cmp_bytes(value->valueinfo[1], basevalue->valueinfo[1], HASH_SIZE); + break; + default: + printf("%s\n", "Type is incorrect."); + compared = false; + } + + printf("%s\n", "Finish Comparation"); + return compared; } static bool verify_qta(buffer_data *akcert, int type, const char *refval) { - base_value *qta_val = get_qta(akcert); - base_value *baseval = LoadQTABaseValue(refval); + base_value *qta_val = get_qta(akcert); + base_value *baseval = LoadQTABaseValue(refval); - bool verified = false; - if ((qta_val == NULL) || (baseval == NULL)) - printf("Pointer Error!\n"); - else - verified = CompareBV(type, qta_val, baseval); + bool verified = false; + if ((qta_val == NULL) || (baseval == NULL)) + printf("Pointer Error!\n"); + else + verified = CompareBV(type, qta_val, baseval); - free(qta_val); - free(baseval); - return verified; + free(qta_val); + free(baseval); + return verified; } bool tee_verify_akcert(buffer_data *akcert, int type, const char *refval) { - buffer_data datadrk, signdrk, certdrk, akpub; - bool rt = false; - - rt = getDataFromAkCert(akcert, &datadrk, &signdrk, &certdrk, &akpub); - if (!rt) - { - printf("failed to get data from ak cert!\n"); - goto err; - } - - // verify the integrity of data in drk issued cert - rt = verifysig_x509cert(&datadrk, &signdrk, &certdrk, NULL); - if (!rt) - { - printf("validate ak cert failed!\n"); - goto err; - } - - rt = verify_qta(akcert, type, refval); - if (!rt) - { - printf("validate ak cert failed, qta verify error!\n"); - goto err; - } + buffer_data datadrk, signdrk, certdrk, akpub; + bool rt = false; + + rt = getDataFromAkCert(akcert, &datadrk, &signdrk, &certdrk, &akpub); + if (!rt) { + printf("failed to get data from ak cert!\n"); + goto err; + } + + // verify the integrity of data in drk issued cert + rt = verifysig_x509cert(&datadrk, &signdrk, &certdrk, NULL); + if (!rt) { + printf("validate ak cert failed!\n"); + goto err; + } + + rt = verify_qta(akcert, type, refval); + if (!rt) { + printf("validate ak cert failed, qta verify error!\n"); + goto err; + } err: - if (datadrk.buf != NULL) - free(datadrk.buf); - if (signdrk.buf != NULL) - free(signdrk.buf); - if (certdrk.buf != NULL) - free(certdrk.buf); - if (akpub.buf != NULL) - free(akpub.buf); - return rt; + if (datadrk.buf != NULL) + free(datadrk.buf); + if (signdrk.buf != NULL) + free(signdrk.buf); + if (certdrk.buf != NULL) + free(certdrk.buf); + if (akpub.buf != NULL) + free(akpub.buf); + return rt; } bool tee_get_akcert_data(buffer_data *akcert, buffer_data *akpub, buffer_data *drkcrt) { - buffer_data datadrk, signdrk; - bool rt = getDataFromAkCert(akcert, &datadrk, &signdrk, drkcrt, akpub); - if (!rt) { - printf("failed to get data from ak cert!\n"); - } - - if (datadrk.buf != NULL) - free(datadrk.buf); - if (signdrk.buf != NULL) - free(signdrk.buf); - return rt; + buffer_data datadrk, signdrk; + bool rt = getDataFromAkCert(akcert, &datadrk, &signdrk, drkcrt, akpub); + if (!rt) { + printf("failed to get data from ak cert!\n"); + } + + if (datadrk.buf != NULL) + free(datadrk.buf); + if (signdrk.buf != NULL) + free(signdrk.buf); + return rt; } diff --git a/attestation/tee/tverlib/verifier/teeverifier.h b/attestation/tee/tverlib/verifier/teeverifier.h index 6d8ee47..598e672 100644 --- a/attestation/tee/tverlib/verifier/teeverifier.h +++ b/attestation/tee/tverlib/verifier/teeverifier.h @@ -12,24 +12,23 @@ See the Mulan PSL v2 for more details. #ifndef __VERIFIER_LIB__ #define __VERIFIER_LIB__ -#include -#include -#include +#include #include #include #include -#include +#include +#include +#include #define UUID_SIZE 16 #define HASH_SIZE 32 -//Attester will send the report by this type -typedef struct{ +// Attester will send the report by this type +typedef struct { uint32_t size; uint8_t *buf; } buffer_data; -typedef struct -{ +typedef struct { uint8_t uuid[UUID_SIZE]; uint8_t valueinfo[2][HASH_SIZE]; // valueinfo[0]=img measurement and valueinfo[1]=mem measurement } base_value; @@ -41,9 +40,9 @@ enum error_status_code { TVS_VERIFIED_HASH_FAILED = -3, }; -int tee_verify_report(buffer_data *data_buf,buffer_data *nonce,int type, char *filename); +int tee_verify_report(buffer_data *data_buf, buffer_data *nonce, int type, char *filename); int tee_validate_report(buffer_data *buf_data, buffer_data *nonce); -int tee_verify_report2(buffer_data *buf_data, int type,base_value *baseval); +int tee_verify_report2(buffer_data *buf_data, int type, base_value *baseval); int tee_validate_report2(buffer_data *buf_data, buffer_data *nonce); bool tee_verify_akcert(buffer_data *akcert, int type, const char *refval); bool tee_get_akcert_data(buffer_data *akcert, buffer_data *akpub, buffer_data *drkcrt); -- Gitee From de127e5415fc9ed25d07ac97253f1d7f96306ed3 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Sat, 21 Oct 2023 11:29:02 +0800 Subject: [PATCH 2/8] libteeverifier.so support ta_attr compare 1. TA_report add ta_addr info 2. auto compare ta_attr when report data contain container info --- attestation/tee/tverlib/verifier/common.h | 28 +- .../tee/tverlib/verifier/teeverifier.c | 369 +++++++++++++++--- .../tee/tverlib/verifier/teeverifier.h | 7 +- 3 files changed, 349 insertions(+), 55 deletions(-) diff --git a/attestation/tee/tverlib/verifier/common.h b/attestation/tee/tverlib/verifier/common.h index bb56ed2..2ffe643 100644 --- a/attestation/tee/tverlib/verifier/common.h +++ b/attestation/tee/tverlib/verifier/common.h @@ -115,6 +115,26 @@ typedef struct __attribute__((__packed__)) report_response { */ } report_get; +/* container info storaged in ta_attr*/ +typedef struct { + buffer_data id; + buffer_data type; + uint8_t img_hash[HASH_SIZE]; + uint8_t mem_hash[HASH_SIZE]; +} Container_attr; + +typedef struct { + /* + * 0, reserve + * 1, container info + */ + uint8_t type; + union { + Container_attr *container; + buffer_data *reserve; + } data; +} TA_attr; + typedef struct { uint8_t version[VERSION_SIZE]; uint8_t timestamp[TS_SIZE]; @@ -125,7 +145,7 @@ typedef struct { uint32_t hash_alg; // Hash algorithm type uint8_t image_hash[HASH_SIZE]; uint8_t hash[HASH_SIZE]; - uint8_t reserve[HASH_SIZE]; + TA_attr ta_attr; // uint8_t signature[SIG_SIZE]; // uint8_t cert[CERT_SIZE]; //AK cert buffer_data *signature; @@ -154,14 +174,14 @@ struct ak_cert { // static int tee_validate_report(buffer_data *buf_data, buffer_data *nonce); static bool tee_verify_nonce(buffer_data *buf_data, buffer_data *nonce); static bool tee_verify_signature(buffer_data *report); -static bool tee_verify(buffer_data *buf_data, int type, char *filename); +static bool tee_verify(buffer_data *buf_data, container_info *info, int type, char *filename); static bool tee_verify2(buffer_data *bufdata, int type, base_value *baseval); static void verifier_error(const char *msg); static void file_error(const char *s); static TA_report *Convert(buffer_data *buf_data); // static void parse_uuid(uint8_t *uuid, TEE_UUID buf_uuid); static void read_bytes(void *input, size_t size, size_t nmemb, uint8_t *output, size_t *offset); -static base_value *LoadBaseValue(const TA_report *report, char *filename); +static base_value *LoadBaseValue(const TA_report *report, char *filename, base_value **qta_report_baseval); static void str_to_uuid(const char *str, uint8_t *uuid); static void uuid_to_str(const uint8_t *uuid, char *str); static void str_to_hash(const char *str, uint8_t *hash); @@ -169,7 +189,7 @@ static void hash_to_str(const uint8_t *hash, char *str); static void hex2str(const uint8_t *source, int source_len, char *dest); static void str2hex(const char *source, int source_len, uint8_t *dest); static char *file_to_buffer(char *file, size_t *file_length); -static bool Compare(int type, TA_report *report, base_value *basevalue); +static bool Compare(int type, TA_report *report, base_value *basevalue, base_value *qta_baseval); static bool cmp_bytes(const uint8_t *a, const uint8_t *b, size_t size); static void test_print(uint8_t *printed, int printed_size, char *printed_name); static void save_basevalue(const base_value *bv); diff --git a/attestation/tee/tverlib/verifier/teeverifier.c b/attestation/tee/tverlib/verifier/teeverifier.c index 9aaf752..d556ec8 100644 --- a/attestation/tee/tverlib/verifier/teeverifier.c +++ b/attestation/tee/tverlib/verifier/teeverifier.c @@ -931,6 +931,30 @@ bool restorePEMCert(uint8_t *data, int data_len, buffer_data *certdrk) return true; } +void free_ta_attr(TA_attr *attr) +{ + if (attr == NULL) + return; + if (attr->type == 0) { + if (attr->data.reserve == NULL) + return; + if (attr->data.reserve->buf) + free(attr->data.reserve->buf); + free(attr->data.reserve); + return; + } + if (attr->type == 1) { + if (attr->data.container == NULL) + return; + if (attr->data.container->id.buf) + free(attr->data.container->id.buf); + if (attr->data.container->type.buf) + free(attr->data.container->type.buf); + free(attr->data.container); + return; + } +} + void free_report(TA_report *report) { if (NULL == report) @@ -948,6 +972,8 @@ void free_report(TA_report *report) free(report->cert); } + free_ta_attr(&(report->ta_attr)); + free(report); } @@ -1109,21 +1135,68 @@ void test_print(uint8_t *printed, int printed_size, char *printed_name) printf("\n"); }; -bool tee_verify(buffer_data *bufdata, int type, char *filename) +static bool compare_buffer_data(buffer_data *a, buffer_data *b) +{ + if (a == NULL || b == NULL || a->buf == NULL || b->buf == NULL) { + printf("buffer_data input is invalid\n"); + return false; + } + + if (a->size != b->size) { + return false; + } + + return cmp_bytes(a->buf, b->buf, a->size); +} + +static bool compare_container_info(container_info *info, TA_report *report) +{ + if (report == NULL) { + printf("report input is invalid\n"); + return false; + } + + /* no need to compare container info when report not contain container info */ + if (report->ta_attr.type != 1) { + return true; + } + + if (info == NULL || report->ta_attr.data.container == NULL) { + printf("report ta_attr or container info is invalid\n"); + return false; + } + + return compare_buffer_data(&(info->id), &(report->ta_attr.data.container->id)) && + compare_buffer_data(&(info->type), &(report->ta_attr.data.container->type)); +} + + +bool tee_verify(buffer_data *bufdata, container_info *info, int type, char *filename) { TA_report *report = Convert(bufdata); - base_value *baseval = LoadBaseValue(report, filename); + base_value *qta_report_baseval = NULL; + base_value *baseval = LoadBaseValue(report, filename, &qta_report_baseval); - bool verified; + bool verified = false; if ((report == NULL) || (baseval == NULL)) { printf("Pointer Error!\n"); - verified = false; - } else - verified = Compare(type, report, - baseval); // compare the report with the basevalue + goto end; + } - free_report(report); - free(baseval); + if (!compare_container_info(info, report)) { + printf("compare container id or type failed\n"); + goto end; + } + + verified = Compare(type, report, baseval, qta_report_baseval); // compare the report with the basevalue + +end: + if (report) + free_report(report); + if (baseval) + free(baseval); + if (qta_report_baseval) + free(qta_report_baseval); return verified; } @@ -1246,6 +1319,118 @@ bool get_alg_from_payload(cJSON *pljson, TA_report *tr) return true; } +static bool base64urldecode_copy(char *src, uint8_t *dst, int dstMax_len) +{ + if (src == NULL || dst == NULL || dstMax_len <= 0) { + printf("input params error\n"); + return false; + } + + int len = 0; + uint8_t *tmp = base64urldecode(src, strlen(src), &len); + if (len > dstMax_len) { + printf("base64urldecode len is overflow\n"); + free(tmp); + return false; + } + memcpy(dst, tmp, len); + free(tmp); + return true; +} + +static bool create_copy_buf(char *src, buffer_data *dst) +{ + if (src == NULL || dst == NULL) { + printf("input params error\n"); + return false; + } + + dst->size = 0; + dst->buf = NULL; + + dst->size = strlen(src); + if (dst->size == 0) { + return true; + } + + dst->buf = (uint8_t *)malloc(dst->size); + if (dst->buf== NULL) { + printf("malloc buf failed\n"); + return false; + } + + memcpy(dst->buf, src, dst->size); + return true; +} + +static bool get_complex_ta_attr(cJSON *attr_json, TA_report *tr) +{ + if (attr_json == NULL || tr == NULL || attr_json->child == NULL) { + printf("input params error\n"); + return false; + } + + tr->ta_attr.type = 1; + cJSON *id = cJSON_GetObjectItemCaseSensitive(attr_json, "container_id"); + cJSON *type = cJSON_GetObjectItemCaseSensitive(attr_json, "container_type"); + cJSON *imgjson = cJSON_GetObjectItemCaseSensitive(attr_json, "qta_report_img_hash"); + cJSON *memjson = cJSON_GetObjectItemCaseSensitive(attr_json, "qta_report_mem_hash"); + if (id == NULL || type == NULL || imgjson == NULL || memjson == NULL) { + printf("cjson parse attr data from report error\n"); + return false; + } + + Container_attr *ta_attr = (Container_attr *)calloc(1, sizeof(Container_attr)); + if (ta_attr == NULL) { + printf("malloc ta_attr node failed\n"); + return false; + } + + if (!base64urldecode_copy(imgjson->valuestring, ta_attr->img_hash, HASH_SIZE) || + !base64urldecode_copy(memjson->valuestring, ta_attr->mem_hash, HASH_SIZE)) { + printf("decode qta_report hash failed\n"); + free(ta_attr); + return false; + } + + if (!create_copy_buf(id->valuestring, &ta_attr->id) || !create_copy_buf(type->valuestring, &ta_attr->type)) { + printf("read and copy container info failed\n"); + free(ta_attr); + return false; + } + + tr->ta_attr.data.container = ta_attr; + return true; +} + +static bool get_ta_attr(cJSON *attr_json, TA_report *tr) +{ + if (attr_json == NULL || tr == NULL) { + printf("input params error\n"); + return false; + } + + if (attr_json->child == NULL) { + tr->ta_attr.type = 0; + buffer_data *buf_node = (buffer_data *)calloc(1, sizeof(buffer_data)); + if (buf_node == NULL) { + printf("malloc reserve node failed\n"); + return false; + } + + /* ta_attr data storaged in buf */ + if (!create_copy_buf(attr_json->valuestring, buf_node)) { + printf("read and copy reserve buf failed\n"); + free(buf_node); + return false; + } + tr->ta_attr.data.reserve = buf_node; + return true; + } + + return get_complex_ta_attr(attr_json, tr); +} + bool get_other_params_from_report(cJSON *pljson, TA_report *tr) { // get version, timestamp, ta_attr @@ -1258,9 +1443,13 @@ bool get_other_params_from_report(cJSON *pljson, TA_report *tr) } memcpy(tr->timestamp, tsjson->valuestring, strlen(tsjson->valuestring)); - memcpy(tr->reserve, reservejson->valuestring, strlen(reservejson->valuestring)); memcpy(tr->version, vjson->valuestring, strlen(vjson->valuestring)); + if (!get_ta_attr(reservejson, tr)) { + printf("cjson parse ta_attr error\n"); + return false; + } + return true; } @@ -1352,55 +1541,114 @@ void read_bytes(void *input, size_t size, size_t nmemb, uint8_t *output, size_t *offset += size * nmemb; } -base_value *LoadBaseValue(const TA_report *report, char *filename) +static uint8_t g_qta_report_uuid[UUID_SIZE] = {0xe0, 0xc0, 0x84, 0x4f, 0x3f, 0x4c, 0x2f, 0x42, + 0x97, 0xdc, 0x14, 0xbf, 0xa2, 0x31, 0x4a, 0xd1}; + +static base_value *create_basevalue(const uint8_t *uuid, char *img_str, char *mem_str) { - base_value *baseval = NULL; - size_t fbuf_len = 0; // if needed + if (uuid == NULL || img_str == NULL || mem_str == NULL) { + printf("invalid input\n"); + return NULL; + } - if (report == NULL) - verifier_error("illegal report pointer!"); - char *fbuf = file_to_buffer(filename, &fbuf_len); + base_value *baseval = (base_value *)calloc(1, sizeof(base_value)); + if (baseval == NULL) { + printf("calloc basevalue failed\n"); + return NULL; + } - /* - base_value *baseval_tmp = NULL; - size_t fbuf_offset = 0; - while(fbuf_offset < fbuf_len) { - baseval_tmp = (base_value *)(fbuf+fbuf_offset); - if (cmp_bytes(report->uuid, baseval_tmp->uuid, UUID_SIZE)) break; - fbuf_offset += sizeof(base_value); - } - - baseval = (base_value *)calloc(1, sizeof(base_value)); - memcpy(baseval->uuid, baseval_tmp->uuid, UUID_SIZE*sizeof(uint8_t)); - memcpy(baseval->valueinfo[0], baseval_tmp->valueinfo[0], - HASH_SIZE*sizeof(uint8_t)); memcpy(baseval->valueinfo[1], - baseval_tmp->valueinfo[1], HASH_SIZE*sizeof(uint8_t)); - - baseval_tmp = NULL; - **/ + memcpy(baseval->uuid, uuid, UUID_SIZE); + str_to_hash(img_str, baseval->valueinfo[0]); + str_to_hash(mem_str, baseval->valueinfo[1]); + return baseval; +} +static bool found_baseval(char *fbuf, const uint8_t *ta_uuid, base_value **ta, base_value **qta_report, bool need_qta_report) +{ + if (fbuf == NULL || ta_uuid == NULL || ta == NULL || qta_report == NULL) { + printf("invalid input\n"); + return false; + } + + *ta = NULL; + *qta_report = NULL; // fbuf is string stream. char *line = NULL; line = strtok(fbuf, "\n"); - baseval = (base_value *)calloc(1, sizeof(base_value)); - char uuid_str[37]; - char image_hash_str[65]; - char hash_str[65]; - int num = 0; + char uuid_str[37], image_hash_str[65], hash_str[65]; + uint8_t cur_uuid[UUID_SIZE] = {0}; + bool found_ta = false, found_qta_report = !need_qta_report; + while (line != NULL) { - ++num; sscanf(line, "%36s %64s %64s", uuid_str, image_hash_str, hash_str); - str_to_uuid(uuid_str, baseval->uuid); - if (cmp_bytes(report->uuid, baseval->uuid, UUID_SIZE)) { - str_to_hash(image_hash_str, baseval->valueinfo[0]); - str_to_hash(hash_str, baseval->valueinfo[1]); - break; + str_to_uuid(uuid_str, cur_uuid); + if (cmp_bytes(ta_uuid, cur_uuid, UUID_SIZE)) { + *ta = create_basevalue(ta_uuid, image_hash_str, hash_str); + if (*ta == NULL) { + printf("found ta basevalue, but malloc basevalue failed\n"); + goto err; + } + found_ta = true; + if (found_qta_report) + break; + } + if (need_qta_report) { + if (cmp_bytes(g_qta_report_uuid, cur_uuid, UUID_SIZE)) { + *qta_report = create_basevalue(g_qta_report_uuid, image_hash_str, hash_str); + if (*qta_report == NULL) { + printf("found qta_report basevalue, but malloc basevalue failed\n"); + goto err; + } + found_qta_report = true; + if (found_ta) + break; + } } line = strtok(NULL, "\n"); } + if (!found_ta || !found_qta_report) { + printf("not found the ta basevalue\n"); + goto err; + } + return true; + +err: + if (*ta) { + free(*ta); + *ta = NULL; + } + if (*qta_report) { + free(*qta_report); + *qta_report = NULL; + } + return false; +} + +base_value *LoadBaseValue(const TA_report *report, char *filename, base_value **qta_report_baseval) +{ + if (report == NULL || filename == NULL || qta_report_baseval == NULL) { + printf("input argument is invalid\n"); + return NULL; + } + + base_value *baseval = NULL; + size_t fbuf_len = 0; // if needed + + char *fbuf = file_to_buffer(filename, &fbuf_len); + if (fbuf == NULL) { + printf("read basevalue file %d failed\n", filename); + return NULL; + } + + bool is_container = (report->ta_attr.type == 1); + if (!found_baseval(fbuf, report->uuid, &baseval, qta_report_baseval, is_container)) { + printf("found basevalue failed\n"); + } + +end: free(fbuf); return baseval; } @@ -1571,9 +1819,20 @@ err: return buffer; } -bool Compare(int type, TA_report *report, base_value *basevalue) +bool Compare(int type, TA_report *report, base_value *basevalue, base_value *qta_baseval) { - bool compared; + if (report == NULL || basevalue == NULL) { + printf("invalid input\n"); + return false; + } + bool is_container = (report->ta_attr.type == 1); + if (is_container && (qta_baseval == NULL || report->ta_attr.data.container == NULL)) { + printf("need qta_report basevalue and hash\n"); + return false; + } + Container_attr *attr = report->ta_attr.data.container; + + bool compared = false, qta_compared = !is_container; /* test_print(report->image_hash, HASH_SIZE, "report->image_hash"); test_print(report->hash, HASH_SIZE, "report->hash"); @@ -1586,15 +1845,25 @@ bool Compare(int type, TA_report *report, base_value *basevalue) case 1: printf("%s\n", "Compare image measurement.."); compared = cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE); + if (is_container) { + qta_compared = cmp_bytes(attr->img_hash, qta_baseval->valueinfo[0], HASH_SIZE); + } break; case 2: printf("%s\n", "Compare hash measurement.."); compared = cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE); + if (is_container) { + qta_compared = cmp_bytes(attr->mem_hash, qta_baseval->valueinfo[1], HASH_SIZE); + } break; case 3: printf("%s\n", "Compare image & hash measurement.."); compared = (cmp_bytes(report->image_hash, basevalue->valueinfo[0], HASH_SIZE) & cmp_bytes(report->hash, basevalue->valueinfo[1], HASH_SIZE)); + if (is_container) { + qta_compared = (cmp_bytes(attr->img_hash, qta_baseval->valueinfo[0], HASH_SIZE) & + cmp_bytes(attr->mem_hash, qta_baseval->valueinfo[1], HASH_SIZE)); + } break; default: printf("%s\n", "Type is incorrect."); @@ -1602,7 +1871,7 @@ bool Compare(int type, TA_report *report, base_value *basevalue) } printf("%s\n", "Finish Comparation"); - return compared; + return compared && qta_compared; } bool cmp_bytes(const uint8_t *a, const uint8_t *b, size_t size) @@ -1679,7 +1948,7 @@ bool tee_verify_nonce(buffer_data *buf_data, buffer_data *nonce) return vn; } -int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, char *filename) +int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, container_info *info, int type, char *filename) { bool vn = tee_verify_nonce(buf_data, nonce); if (vn == false) { @@ -1689,7 +1958,7 @@ int tee_verify_report(buffer_data *buf_data, buffer_data *nonce, int type, char if (vs == false) { return TVS_VERIFIED_SIGNATURE_FAILED; } - bool v = tee_verify(buf_data, type, filename); + bool v = tee_verify(buf_data, info, type, filename); if (v == false) { return TVS_VERIFIED_HASH_FAILED; } @@ -1706,7 +1975,7 @@ bool tee_verify2(buffer_data *bufdata, int type, base_value *baseval) verified = false; } else verified = Compare(type, report, - baseval); // compare the report with the basevalue + baseval, NULL); // compare the report with the basevalue free_report(report); return verified; diff --git a/attestation/tee/tverlib/verifier/teeverifier.h b/attestation/tee/tverlib/verifier/teeverifier.h index 598e672..0f4e6c8 100644 --- a/attestation/tee/tverlib/verifier/teeverifier.h +++ b/attestation/tee/tverlib/verifier/teeverifier.h @@ -40,7 +40,12 @@ enum error_status_code { TVS_VERIFIED_HASH_FAILED = -3, }; -int tee_verify_report(buffer_data *data_buf, buffer_data *nonce, int type, char *filename); +typedef struct { + buffer_data id; + buffer_data type; +} container_info; + +int tee_verify_report(buffer_data *data_buf, buffer_data *nonce, container_info *info, int type, char *filename); int tee_validate_report(buffer_data *buf_data, buffer_data *nonce); int tee_verify_report2(buffer_data *buf_data, int type, base_value *baseval); int tee_validate_report2(buffer_data *buf_data, buffer_data *nonce); -- Gitee From 7dd993409aa2bfc7aebdf54fca62d7b4cfbb8f49 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Sun, 22 Oct 2023 11:17:00 +0800 Subject: [PATCH 3/8] ra_client support specify container info and send info to ra_server --- .../attestertools/attestertools.go | 128 ++++++++++++--- attestation/tee/demo/qca_demo/qapi/api.pb.go | 152 ++++++++++++++---- attestation/tee/demo/qca_demo/qapi/api.proto | 5 + .../tee/demo/qca_demo/qapi/api_grpc.pb.go | 12 +- attestation/tee/demo/qca_demo/qapi/qapi.go | 16 +- .../tee/demo/qca_demo/qcatools/qcatools.go | 20 ++- 6 files changed, 270 insertions(+), 63 deletions(-) diff --git a/attestation/tee/demo/attester_demo/attestertools/attestertools.go b/attestation/tee/demo/attester_demo/attestertools/attestertools.go index 4c56cdd..bb4c509 100644 --- a/attestation/tee/demo/attester_demo/attestertools/attestertools.go +++ b/attestation/tee/demo/attester_demo/attestertools/attestertools.go @@ -26,8 +26,10 @@ import ( "context" "crypto/rand" "encoding/base64" + "fmt" "log" "os" + "strings" "unsafe" "gitee.com/openeuler/kunpengsecl/attestation/tee/demo/qca_demo/qapi" @@ -63,6 +65,12 @@ const ( lflagTest = "test" sflagTest = "T" helpTest = "set a fixed nonce value for test" + // container info + sflagConId = "id" + helpConId = "specify the container id where ta running" + sflagConType = "type" + helpConType = "specify the container type where ta running" + // app name appAttester = "attester" // ConfName means config file name @@ -81,7 +89,9 @@ const ( // Mspolicy means attesterconfig mspolicy Mspolicy = "attesterconfig.mspolicy" // Uuid means attesterconfig uuid - Uuid = "attesterconfig.uuid" + Uuid = "attesterconfig.uuid" + ConIdKey = "attesterconfig.container.id" + ConTypeKey = "attesterconfig.container.type" ) type ( @@ -91,12 +101,16 @@ type ( usrdata []byte report []byte withtcb bool + conId string + conType string } attesterConfig struct { server string basevalue string mspolicy int uuid string + conId string + conType string } ) @@ -108,6 +122,8 @@ var ( usrdata: []byte{}, report: []byte{}, withtcb: false, + conId: "", + conType: "", } verify_result int = 1 defaultPaths = []string{ @@ -126,10 +142,12 @@ var ( // UuidFlag means uuid flag UuidFlag *string = nil // TestFlag means test flag - TestFlag *bool = nil + TestFlag *bool = nil + // Container Flag + ConIdFlag *string = nil + ConTypeFlag *string = nil + attesterConf *attesterConfig = nil - up_rep_buf unsafe.Pointer - up_non_buf unsafe.Pointer ) // InitFlags inits the server command flags. @@ -141,6 +159,8 @@ func InitFlags() { MspolicyFlag = pflag.IntP(lflagMeasure, sflagMeasure, -1, helpMeasure) UuidFlag = pflag.StringP(lflagUuid, sflagUuid, "", helpUuid) TestFlag = pflag.BoolP(lflagTest, sflagTest, false, helpTest) + ConIdFlag = pflag.String(sflagConId, "", helpConId) + ConTypeFlag = pflag.String(sflagConType, "", helpConType) pflag.Parse() } @@ -165,6 +185,8 @@ func LoadConfigs() { attesterConf.basevalue = viper.GetString(Basevalue) attesterConf.mspolicy = viper.GetInt(Mspolicy) attesterConf.uuid = viper.GetString(Uuid) + attesterConf.conId = viper.GetString(ConIdKey) + attesterConf.conType = viper.GetString(ConTypeKey) } // HandleFlags handles the command flags. @@ -190,6 +212,14 @@ func HandleFlags() { attesterConf.uuid = *UuidFlag log.Printf("TEE Uuid: %s", attesterConf.uuid) // just for test! } + if ConIdFlag != nil && *ConIdFlag != "" { + attesterConf.conId = *ConIdFlag + log.Printf("TEE container id: %s", attesterConf.conId) // just for test! + } + if ConTypeFlag != nil && *ConTypeFlag != "" { + attesterConf.conType = *ConTypeFlag + log.Printf("TEE container type: %s", attesterConf.conType) // just for test! + } if TestFlag != nil && *TestFlag { testmode = true // var s_nonce string = "challenge" // 换成获取到的nonce(不是string,要先base64解码) @@ -210,9 +240,10 @@ func StartAttester() { test_ta, err := iniTAParameter(test_ta, testmode) if err != nil { log.Printf("Init TA parameter failed! %v", err) + return } test_ta.report = getReport(test_ta) - verify_result = tee_verify(test_ta.report, test_ta.usrdata, attesterConf.mspolicy, attesterConf.basevalue) + verify_result = tee_verify(test_ta, attesterConf.mspolicy, attesterConf.basevalue) switch verify_result { case 0: log.Print("tee verify succeeded!") @@ -227,40 +258,81 @@ func StartAttester() { log.Print("Stop Attester......") } +func chenckContainerInfo(id, ctype string) error { + // no container info input is valid + if id == "" && ctype == "" { + return nil + } + + if id == "" || ctype == "" { + return fmt.Errorf("id or type lacked") + } + switch strings.ToLower(ctype) { + case "docker": + if len(id) != 64 { + return fmt.Errorf("invalid id length %d", len(id)) + } + default: + return fmt.Errorf("not supported container type") + } + return nil +} + // iniTAParameter initializes the parameters of TA func iniTAParameter(ta *trustApp, m bool) (*trustApp, error) { id, err := uuid.Parse(attesterConf.uuid) if err != nil { - return test_ta, err + return nil, err } ta.uuid, err = id.MarshalBinary() if err != nil { - return test_ta, err + return nil, err } // create nonce value to defend against replay attacks if !m { nonce := make([]byte, 64) _, err = rand.Read(nonce) if err != nil { - return test_ta, err + return nil, err } ta.usrdata = nonce } + + err = chenckContainerInfo(attesterConf.conId, attesterConf.conType) + if err != nil { + return nil, err + } + ta.conId = attesterConf.conId + ta.conType = attesterConf.conType return ta, nil } // remote invoke qca api to get the TA's info func getReport(ta *trustApp) []byte { + if ta == nil { + log.Printf("invalid input ta") + return nil + } + + var info *qapi.GetReportRequest_ContainerInfo + if ta.conId != "" || ta.conType != "" { + info = &qapi.GetReportRequest_ContainerInfo{ + Id: ta.conId, + Type: ta.conType, + } + } + reqID := qapi.GetReportRequest{ Uuid: ta.uuid, Nonce: ta.usrdata, WithTcb: ta.withtcb, + Info: info, } rpyID, err := qapi.DoGetTeeReport(attesterConf.server, &reqID) if err != nil { log.Printf("Get TA infomation failed, error: %v", err) - return ta.report + return nil } log.Print("Get TA report succeeded!") ta.report = rpyID.GetTeeReport() @@ -268,19 +340,37 @@ func getReport(ta *trustApp) []byte { } // invoke verifier lib to verify -func tee_verify(rep []byte, nonce []byte, mtype int, bv string) int { +// int tee_verify_report(buffer_data *data_buf, buffer_data *nonce, container_info *info, int type, char *filename); +func tee_verify(ta *trustApp, mtype int, bv string) int { + // construct C data_buf var crep C.buffer_data + crepByte := C.CBytes(ta.report) + defer C.free(crepByte) + crep.buf, crep.size = (*C.uchar)(crepByte), C.__uint32_t(len(ta.report)) + + // construct C nonce var cnonce C.buffer_data + cnonByte := C.CBytes(ta.usrdata) + defer C.free(cnonByte) + cnonce.buf, cnonce.size = (*C.uchar)(cnonByte), C.__uint32_t(len(ta.usrdata)) + + // construct C info + var cinfo *C.container_info = nil + if ta.conId != "" && ta.conType != "" { + var tmpInfo C.container_info + cid := C.CString(ta.conId) + defer C.free(unsafe.Pointer(cid)) + ctype := C.CString(ta.conType) + defer C.free(unsafe.Pointer(ctype)) + tmpInfo.id.buf, tmpInfo.id.size = (*C.uchar)(cid), C.__uint32_t(len(ta.conId)) + tmpInfo._type.buf, tmpInfo._type.size = (*C.uchar)(ctype), C.__uint32_t(len(ta.conType)) + cinfo = &tmpInfo + } + + // construct C filename cbv := C.CString(bv) defer C.free(unsafe.Pointer(cbv)) - crep.size = C.__uint32_t(len(rep)) - up_rep_buf = C.CBytes(rep) - defer C.free(up_rep_buf) - crep.buf = (*C.uchar)(up_rep_buf) - cnonce.size = C.__uint32_t(len(nonce)) - up_non_buf = C.CBytes(nonce) - defer C.free(up_non_buf) - cnonce.buf = (*C.uchar)(up_non_buf) - result := C.tee_verify_report(&crep, &cnonce, C.int(mtype), cbv) + + result := C.tee_verify_report(&crep, &cnonce, cinfo, C.int(mtype), cbv) return int(result) } diff --git a/attestation/tee/demo/qca_demo/qapi/api.pb.go b/attestation/tee/demo/qca_demo/qapi/api.pb.go index ea0d980..efcddd9 100644 --- a/attestation/tee/demo/qca_demo/qapi/api.pb.go +++ b/attestation/tee/demo/qca_demo/qapi/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.6.1 +// protoc-gen-go v1.27.1 +// protoc v3.14.0 // source: qca_demo/qapi/api.proto package qapi @@ -25,9 +25,10 @@ type GetReportRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` - WithTcb bool `protobuf:"varint,3,opt,name=with_tcb,json=withTcb,proto3" json:"with_tcb,omitempty"` + Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` + Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` + WithTcb bool `protobuf:"varint,3,opt,name=with_tcb,json=withTcb,proto3" json:"with_tcb,omitempty"` + Info *GetReportRequest_ContainerInfo `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` } func (x *GetReportRequest) Reset() { @@ -83,6 +84,13 @@ func (x *GetReportRequest) GetWithTcb() bool { return false } +func (x *GetReportRequest) GetInfo() *GetReportRequest_ContainerInfo { + if x != nil { + return x.Info + } + return nil +} + type GetReportReply struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -130,28 +138,90 @@ func (x *GetReportReply) GetTeeReport() []byte { return nil } +type GetReportRequest_ContainerInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` +} + +func (x *GetReportRequest_ContainerInfo) Reset() { + *x = GetReportRequest_ContainerInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_qca_demo_qapi_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetReportRequest_ContainerInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetReportRequest_ContainerInfo) ProtoMessage() {} + +func (x *GetReportRequest_ContainerInfo) ProtoReflect() protoreflect.Message { + mi := &file_qca_demo_qapi_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetReportRequest_ContainerInfo.ProtoReflect.Descriptor instead. +func (*GetReportRequest_ContainerInfo) Descriptor() ([]byte, []int) { + return file_qca_demo_qapi_api_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *GetReportRequest_ContainerInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetReportRequest_ContainerInfo) GetType() string { + if x != nil { + return x.Type + } + return "" +} + var File_qca_demo_qapi_api_proto protoreflect.FileDescriptor var file_qca_demo_qapi_api_proto_rawDesc = []byte{ 0x0a, 0x17, 0x71, 0x63, 0x61, 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, 0x2f, - 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x57, 0x0a, 0x10, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, 0x5f, - 0x74, 0x63, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x69, 0x74, 0x68, 0x54, - 0x63, 0x62, 0x22, 0x2f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x65, 0x65, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x32, 0x38, 0x0a, 0x03, 0x51, 0x63, 0x61, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, - 0x3e, 0x67, 0x69, 0x74, 0x65, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x65, - 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x6b, 0x75, 0x6e, 0x70, 0x65, 0x6e, 0x67, 0x73, 0x65, 0x63, 0x6c, - 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x6d, - 0x6f, 0x2f, 0x71, 0x63, 0x61, 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc1, 0x01, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, + 0x5f, 0x74, 0x63, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x69, 0x74, 0x68, + 0x54, 0x63, 0x62, 0x12, 0x33, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x33, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2f, 0x0a, + 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x32, 0x38, + 0x0a, 0x03, 0x51, 0x63, 0x61, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x65, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x75, 0x6c, 0x65, 0x72, 0x2f, + 0x6b, 0x75, 0x6e, 0x70, 0x65, 0x6e, 0x67, 0x73, 0x65, 0x63, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x63, 0x61, + 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -166,19 +236,21 @@ func file_qca_demo_qapi_api_proto_rawDescGZIP() []byte { return file_qca_demo_qapi_api_proto_rawDescData } -var file_qca_demo_qapi_api_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_qca_demo_qapi_api_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_qca_demo_qapi_api_proto_goTypes = []interface{}{ - (*GetReportRequest)(nil), // 0: GetReportRequest - (*GetReportReply)(nil), // 1: GetReportReply + (*GetReportRequest)(nil), // 0: GetReportRequest + (*GetReportReply)(nil), // 1: GetReportReply + (*GetReportRequest_ContainerInfo)(nil), // 2: GetReportRequest.ContainerInfo } var file_qca_demo_qapi_api_proto_depIdxs = []int32{ - 0, // 0: Qca.GetReport:input_type -> GetReportRequest - 1, // 1: Qca.GetReport:output_type -> GetReportReply - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 2, // 0: GetReportRequest.info:type_name -> GetReportRequest.ContainerInfo + 0, // 1: Qca.GetReport:input_type -> GetReportRequest + 1, // 2: Qca.GetReport:output_type -> GetReportReply + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_qca_demo_qapi_api_proto_init() } @@ -211,6 +283,18 @@ func file_qca_demo_qapi_api_proto_init() { return nil } } + file_qca_demo_qapi_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetReportRequest_ContainerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -218,7 +302,7 @@ func file_qca_demo_qapi_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_qca_demo_qapi_api_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 1, }, diff --git a/attestation/tee/demo/qca_demo/qapi/api.proto b/attestation/tee/demo/qca_demo/qapi/api.proto index 1af2616..a66f30e 100644 --- a/attestation/tee/demo/qca_demo/qapi/api.proto +++ b/attestation/tee/demo/qca_demo/qapi/api.proto @@ -10,6 +10,11 @@ message GetReportRequest { bytes uuid = 1; bytes nonce = 2; bool with_tcb = 3; + message ContainerInfo { + string id = 1; + string type = 2; + } + ContainerInfo info = 4; } message GetReportReply { diff --git a/attestation/tee/demo/qca_demo/qapi/api_grpc.pb.go b/attestation/tee/demo/qca_demo/qapi/api_grpc.pb.go index ba925eb..176a6c2 100644 --- a/attestation/tee/demo/qca_demo/qapi/api_grpc.pb.go +++ b/attestation/tee/demo/qca_demo/qapi/api_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.14.0 +// source: qca_demo/qapi/api.proto package qapi @@ -14,6 +18,10 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + Qca_GetReport_FullMethodName = "/Qca/GetReport" +) + // QcaClient is the client API for Qca service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +39,7 @@ func NewQcaClient(cc grpc.ClientConnInterface) QcaClient { func (c *qcaClient) GetReport(ctx context.Context, in *GetReportRequest, opts ...grpc.CallOption) (*GetReportReply, error) { out := new(GetReportReply) - err := c.cc.Invoke(ctx, "/Qca/GetReport", in, out, opts...) + err := c.cc.Invoke(ctx, Qca_GetReport_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -76,7 +84,7 @@ func _Qca_GetReport_Handler(srv interface{}, ctx context.Context, dec func(inter } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Qca/GetReport", + FullMethod: Qca_GetReport_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QcaServer).GetReport(ctx, req.(*GetReportRequest)) diff --git a/attestation/tee/demo/qca_demo/qapi/qapi.go b/attestation/tee/demo/qca_demo/qapi/qapi.go index fb3e24e..548bb6d 100644 --- a/attestation/tee/demo/qca_demo/qapi/qapi.go +++ b/attestation/tee/demo/qca_demo/qapi/qapi.go @@ -58,12 +58,26 @@ var ( srv *grpc.Server = nil ) +func getContainerInfo(in *GetReportRequest) *qcatools.ContainerInfo { + info := in.GetInfo() + if info == nil { + return nil + } + + return &qcatools.ContainerInfo{ + Id: info.GetId(), + Type: info.GetType(), + } +} + // GetReport gets report from report request. func (s *service) GetReport(ctx context.Context, in *GetReportRequest) (*GetReportReply, error) { countConnections() _ = ctx // ignore the unused warning Usrdata := in.GetNonce() - rep, err := qcatools.GetTAReport(in.GetUuid(), Usrdata, in.WithTcb) + info := getContainerInfo(in) + + rep, err := qcatools.GetTAReport(in.GetUuid(), Usrdata, in.WithTcb, info) if err != nil { log.Print("Get TA Report failed!") return nil, err diff --git a/attestation/tee/demo/qca_demo/qcatools/qcatools.go b/attestation/tee/demo/qca_demo/qcatools/qcatools.go index 7771a5e..bf41ffe 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcatools.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcatools.go @@ -289,13 +289,18 @@ func adapt2TAUUID(uuid []byte) { } type ( + ContainerInfo struct { + Id string `json:"id,omitempty"` + Type string `json:"type,omitempty"` + } reportInPl struct { - Version string `json:"version,omitempty"` // VERSION_TYPE - Nonce string `json:"nonce,omitempty"` // BASE64_TYPE - Uuid string `json:"uuid,omitempty"` // 待证明的TA UUID的hex字符串描述,字母小写,如"e08f7eca-e875-440e-9ab0-5f381136c600" - Hash_alg string `json:"hash_alg,omitempty"` // HASH_ALG_TYPE - With_tcb bool `json:"with_tcb,omitempty"` // BOOLEAN_TYPE, 当前只能是 “FALSE” - Daa_bsn *string `json:"daa_bsn,omitempty"` // BASE64_TYPE, BASE64 of DAA用户挑选出来的basename + Version string `json:"version,omitempty"` // VERSION_TYPE + Nonce string `json:"nonce,omitempty"` // BASE64_TYPE + Uuid string `json:"uuid,omitempty"` // 待证明的TA UUID的hex字符串描述,字母小写,如"e08f7eca-e875-440e-9ab0-5f381136c600" + Hash_alg string `json:"hash_alg,omitempty"` // HASH_ALG_TYPE + With_tcb bool `json:"with_tcb,omitempty"` // BOOLEAN_TYPE, 当前只能是 “FALSE” + Daa_bsn *string `json:"daa_bsn,omitempty"` // BASE64_TYPE, BASE64 of DAA用户挑选出来的basename + Info *ContainerInfo `json:"container_info,omitempty"` } reportInParam struct { Handler string `json:"handler,omitempty"` @@ -304,7 +309,7 @@ type ( ) // GetTAReport gets TA trusted report information. -func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool) ([]byte, error) { +func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *ContainerInfo) ([]byte, error) { n := base64.RawURLEncoding.EncodeToString(usr_data) id, err := uuid.FromBytes(ta_uuid) if err != nil { @@ -320,6 +325,7 @@ func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool) ([]byte, error) Hash_alg: RA_HASH_ALG_SHA256, With_tcb: with_tcb, // false Daa_bsn: nil, // line73 only support basename = NULL now + Info: info, } inparam := reportInParam{ Handler: RAReportInHandler, -- Gitee From d27e250903cb66c7b37be2d38c36bca4b4705613 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Mon, 23 Oct 2023 11:07:18 +0800 Subject: [PATCH 4/8] ra_server forward request by container info --- attestation/go.mod | 20 +- attestation/tee/demo/qca_demo/cmd/config.yaml | 3 + attestation/tee/demo/qca_demo/qapi/qapi.go | 13 +- .../tee/demo/qca_demo/qcatools/qcatools.go | 88 ++-- .../tee/demo/qca_demo/qcatools/qcautils.go | 432 ++++++++++++++++++ attestation/tee/tverlib/simulator/Makefile | 2 +- attestation/tee/tverlib/simulator/teeqca.c | 56 ++- attestation/tee/tverlib/simulator/teeqca.h | 76 ++- 8 files changed, 587 insertions(+), 103 deletions(-) create mode 100644 attestation/tee/demo/qca_demo/qcatools/qcautils.go diff --git a/attestation/go.mod b/attestation/go.mod index 6981468..8b909e5 100644 --- a/attestation/go.mod +++ b/attestation/go.mod @@ -22,17 +22,23 @@ require ( github.com/stretchr/testify v1.7.0 github.com/tjfoc/gmsm v1.4.1 go.uber.org/zap v1.21.0 - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd + golang.org/x/net v0.17.0 google.golang.org/grpc v1.44.0 google.golang.org/protobuf v1.27.1 miracl v0.0.0 ) require ( + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ansel1/merry v1.6.2 // indirect github.com/ansel1/merry/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v1.13.0 // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/gemalto/flume v0.13.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -40,7 +46,7 @@ require ( github.com/go-openapi/swag v0.21.1 // indirect github.com/goccy/go-json v0.7.10 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -57,6 +63,7 @@ require ( github.com/mattn/go-isatty v0.0.14 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -68,11 +75,14 @@ require ( github.com/valyala/fasttemplate v1.2.1 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20220209195652-db638375bc3a // indirect - golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/genproto v0.0.0-20220208230804-65c12eb4c068 // indirect + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect gopkg.in/ini.v1 v1.51.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/attestation/tee/demo/qca_demo/cmd/config.yaml b/attestation/tee/demo/qca_demo/cmd/config.yaml index 2917332..e51b217 100644 --- a/attestation/tee/demo/qca_demo/cmd/config.yaml +++ b/attestation/tee/demo/qca_demo/cmd/config.yaml @@ -4,4 +4,7 @@ qcaconfig: scenario: 0 nodaaacfile: ./nodaa-ac.crt daaacfile: ./daa-ac.crt + virtual: + server: 0.0.0.0:90000 + healthcheck: 10 # minute, <0 no health check, max is 7 day \ No newline at end of file diff --git a/attestation/tee/demo/qca_demo/qapi/qapi.go b/attestation/tee/demo/qca_demo/qapi/qapi.go index 548bb6d..f6839ca 100644 --- a/attestation/tee/demo/qca_demo/qapi/qapi.go +++ b/attestation/tee/demo/qca_demo/qapi/qapi.go @@ -18,6 +18,7 @@ package qapi import ( "context" "errors" + "fmt" "io/ioutil" "log" "net" @@ -60,7 +61,7 @@ var ( func getContainerInfo(in *GetReportRequest) *qcatools.ContainerInfo { info := in.GetInfo() - if info == nil { + if info == nil || (info.GetId() == "" && info.GetType() == "") { return nil } @@ -74,6 +75,9 @@ func getContainerInfo(in *GetReportRequest) *qcatools.ContainerInfo { func (s *service) GetReport(ctx context.Context, in *GetReportRequest) (*GetReportReply, error) { countConnections() _ = ctx // ignore the unused warning + if in == nil { + return nil, fmt.Errorf("invalid request input") + } Usrdata := in.GetNonce() info := getContainerInfo(in) @@ -105,10 +109,15 @@ func StartServer() { createAKCert(qcatools.Qcacfg.Scenario) } + if qcatools.Qcacfg.VirtSupport { + go qcatools.StartQcaDaemonServer(qcatools.VirtServer) + go qcatools.CheckConnAlive(qcatools.VirtHealthChk) + } + if err = srv.Serve(listen); err != nil { log.Fatalf("Server: fail to serve %v", err) } - + qcatools.Done <- true log.Print("Stop Server......") } diff --git a/attestation/tee/demo/qca_demo/qcatools/qcatools.go b/attestation/tee/demo/qca_demo/qcatools/qcatools.go index bf41ffe..3667b98 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcatools.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcatools.go @@ -16,7 +16,7 @@ Description: invoke qca lib to get info of given TA package qcatools /* -#cgo CFLAGS: -I../../../tverlib/simulator +#cgo CFLAGS: -I../../../tverlib/simulator -I../../../../rac/ka/teesimulator #cgo LDFLAGS: -L${SRCDIR}/../../../tverlib/simulator -lqca -lteec #include "teeqca.h" #include @@ -94,8 +94,10 @@ import ( "encoding/base64" "encoding/json" "errors" + "fmt" "log" "os" + "strings" "unsafe" "github.com/google/uuid" @@ -122,6 +124,9 @@ const ( NoDaaACFile = "qcaconfig.nodaaacfile" // DaaACFile means qcaconfig daaacfile DaaACFile = "qcaconfig.daaacfile" + // virtual server to support virtual remote attest + VirtServer = "qcaconfig.virtual.server" + VirtHealthChk = "qcaconfig.virtual.healthcheck" /*** cmd flags ***/ // server open ip:port lflagServer = "server" @@ -131,6 +136,13 @@ const ( lflagScenario = "scenario" sflagScenario = "C" helpScenario = "set the app usage scenario" + // specify virtual server to support virtual remote attest + lflagVirtSupport = "virtual" + sflagVirtSupport = "V" + helpVirtSupport = "is support remote attest" + lflagVirtServer = "virtualserver" + sflagVirtServer = "A" + helpVirtServer = "virtual server addr" // RemoteAttest Handler RAProvisionInHandler = "provisioning-input" RAProvisionOutHandler = "provisioning-output" @@ -196,11 +208,14 @@ type ( Buf []uint8 } qcaConfig struct { - Server string - AKServer string - Scenario int32 - NoDaaACFile string - DaaACFile string + Server string + AKServer string + Scenario int32 + NoDaaACFile string + DaaACFile string + VirtSupport bool + VirtServer string + VirtHealthChk uint32 } ) @@ -216,7 +231,9 @@ var ( // ServerFlag means server flag ServerFlag *string = nil // ScenarioFlag means scenario flag - ScenarioFlag *int32 = nil + ScenarioFlag *int32 = nil + VirtSupportFlag *bool = nil + VirtServerFlag *string = nil ) // InitFlags inits the qca server command flags. @@ -224,6 +241,8 @@ func InitFlags() { log.Print("Init qca flags......") ServerFlag = pflag.StringP(lflagServer, sflagServer, "", helpServer) ScenarioFlag = pflag.Int32P(lflagScenario, sflagScenario, 0, helpScenario) + VirtSupportFlag = pflag.BoolP(lflagVirtSupport, sflagVirtSupport, false, helpVirtSupport) + VirtServerFlag = pflag.StringP(lflagVirtServer, sflagVirtServer, "", helpVirtServer) pflag.Parse() } @@ -249,6 +268,8 @@ func LoadConfigs() { Qcacfg.Scenario = viper.GetInt32(Scenario) Qcacfg.NoDaaACFile = viper.GetString(NoDaaACFile) Qcacfg.DaaACFile = viper.GetString(DaaACFile) + Qcacfg.VirtServer = viper.GetString(VirtServer) + Qcacfg.VirtHealthChk = viper.GetInt32(VirtHealthChk) } // HandleFlags handles the command flags. @@ -261,6 +282,13 @@ func HandleFlags() { if ScenarioFlag != nil && *ScenarioFlag != 0 { Qcacfg.Scenario = *ScenarioFlag } + + if VirtSupportFlag != nil { + Qcacfg.VirtSupport = *VirtSupportFlag + } + if VirtServerFlag != nil && *VirtServerFlag != "" { + Qcacfg.VirtServer = *VirtServerFlag + } } // GetQcaServer returns the qca service server configuration. @@ -308,6 +336,32 @@ type ( } ) +func forwardReportReq(inparam []byte, out_len uint32, info *ContainerInfo) ([]byte, error) { + var report []byte + var err error + switch { + // host request + case info == nil || (info.Id == "" && info.Type == ""): + report, err = CallCRemoteAttest(inparam, out_len) + if err != nil { + log.Printf("Get host ta report failed, %v", err) + return nil, err + } + // docker request + case strings.ToLower(info.Type) == "docker": + report, err = dealDockerTAReq(info.Id, inparam) + if err != nil { + log.Printf("Get docker ta report failed, %v", err) + return nil, err + } + default: + return nil, fmt.Errorf("not support container type %v", info.Type) + } + + log.Print("Generate TA report succeeded!") + return report, nil +} + // GetTAReport gets TA trusted report information. func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *ContainerInfo) ([]byte, error) { n := base64.RawURLEncoding.EncodeToString(usr_data) @@ -336,26 +390,8 @@ func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *Container log.Printf("Encode GetTAReport json message error, %v", err) return nil, err } - /*** format conversion: Go -> C ***/ - // in parameter conversion - c_in := C.struct_ra_buffer_data{} - c_in.size = C.__uint32_t(len(inparamjson)) - up_c_in := C.CBytes(inparamjson) - c_in.buf = (*C.uchar)(up_c_in) - defer C.free(up_c_in) - - c_out := C.struct_ra_buffer_data{} - c_out.size = 0x3000 - c_out.buf = (*C.uint8_t)(C.malloc(C.ulong(c_out.size))) - - teec_result := C.RemoteAttest(&c_in, &c_out) - if int(teec_result) != 0 { - return nil, errors.New("Invoke remoteAttest failed, Get TA report failed") - } - log.Print("Generate TA report succeeded!") - report := []byte(C.GoBytes(unsafe.Pointer(c_out.buf), C.int(c_out.size))) - return report, nil + return forwardReportReq(inparamjson, 0x3000, info) } /* diff --git a/attestation/tee/demo/qca_demo/qcatools/qcautils.go b/attestation/tee/demo/qca_demo/qcatools/qcautils.go new file mode 100644 index 0000000..ecb9b24 --- /dev/null +++ b/attestation/tee/demo/qca_demo/qcatools/qcautils.go @@ -0,0 +1,432 @@ +package qcatools + +/* +#cgo CFLAGS: -I../../../../rac/ka/teesimulator -I../../../tverlib/simulator +#cgo LDFLAGS: -L${SRCDIR}/../../../tverlib/simulator -lteec_adaptor -lteec -lqca -ldl + +#include "teeqca.h" +#include "tee.h" +#include "teeqca.h" + +static const TEEC_UUID g_qta_uuid = { + 0xe08f7eca, 0xe875, 0x440e, {0x9a, 0xb0, 0x5f, 0x38, 0x11, 0x36, 0xc6, 0x00} +}; + +uint32_t InitCtxAndOpenSess(TEEC_Context *ctx, TEEC_Session *sess) +{ + uint32_t ret = TEEC_InitializeContext(NULL, ctx); + if (ret) { + printf("[c] init context failed, ret = %x\n", ret); + return ret; + } + TEEC_Operation opt = {0}; + opt.started = 1; + opt.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_OpenSession(ctx, sess, &g_qta_uuid, TEEC_LOGIN_IDENTIFY, NULL, &opt, NULL); + if (ret) { + printf("[c] open session failed, ret = %x\n", ret); + TEEC_FinalizeContext(ctx); + } + return ret; +} + +uint32_t MallocCtxAndSess() + + +void CloseSessAndCtx(TEEC_Context *ctx, TEEC_Session *sess) +{ + TEEC_CloseSession(sess); + TEEC_FinalizeContext(ctx); +} +*/ +import "C" + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log" + "net" + "os" + "regexp" + "strconv" + "strings" + "sync" + "sync/atomic" + "syscall" + "time" + "unsafe" + + "github.com/docker/docker/client" +) + +const ( + MAX_CONN_CNT = 512 + MAX_OUTBUF_SIZE = 0x3000 + MAX_REGBUF_SIZE = 512 + DOCKER_ID_LEN = 64 + RET_SUCCESS = 0 + MAX_HEALTH_CHECK = 7 * 24 * 60 // 7 day +) + +var ( + connMap sync.Map + curConnCnt int32 + ValidNsid = regexp.MustCompile(`\[([0-9]+)\]`) + Done = make(chan bool) +) + +type ( + ContRegistInfo struct { + Id string `json:"container_id"` + Nsid int `json:"nsid"` + } + + ClientInfo struct { + Id string `json:"id"` // docker and kvm return 64 bytes string + Type string `json:"type"` + } + + ConnWrapMsg struct { + Ret int `json:"ret"` + Data string `json:"data,omitempty"` + } +) + +func findConnClient(id string) net.Conn { + if id == "" { + return nil + } + + conn, ok := connMap.Load(id) + if ok == false { + return nil + } + return conn.(net.Conn) +} + +func addConnClient(id string, conn net.Conn) error { + if id == "" || conn == nil { + return fmt.Errorf("invalid input") + } + + _, ok := connMap.Load(id) + if ok == false { + if atomic.LoadInt32(&curConnCnt) >= MAX_CONN_CNT { + return fmt.Errorf("too much connect for ra_server") + } + atomic.AddInt32(&curConnCnt, 1) + } + connMap.Store(id, conn) + return nil +} + +func deleteConnClient(id string) { + if id == "" { + return + } + + conn, ok := connMap.Load(id) + if ok == false { + return + } + atomic.AddInt32(&curConnCnt, -1) + connMap.Delete(id) + conn.(net.Conn).Close() +} + +func CheckConnAlive(check int32) { + if check <= 0 || check > MAX_HEALTH_CHECK { + return + } + ticker := time.NewTicker(check * time.Minute) + for { + select { + case <-done: + connMap.Range(func(id, conn interface{}) bool { + conn.(net.Conn).Close() + return true + }) + return + + case <-ticker.C: + connMap.Range(func(id, conn interface{}) bool { + err := connCheck(conn.(net.Conn)) + if err != nil { + atomic.AddInt32(&curConnCnt, -1) + connMap.Delete(id) + conn.(net.Conn).Close() + } + return true + }) + } + } +} + +func connCheck(conn net.Conn) error { + var sysErr error + + sysConn, ok := conn.(syscall.Conn) + if !ok { + return nil + } + rawConn, err := sysConn.SyscallConn() + if err != nil { + return err + } + + err = rawConn.Read(func(fd uintptr) bool { + var buf [1]byte + n, err := syscall.Read(int(fd), buf[:]) + switch { + case n == 0 && err == nil: + sysErr = io.EOF + case n > 0: + sysErr = fmt.Errorf("unexpected read from socket") + case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: + sysErr = nil + default: + sysErr = err + } + return true + }) + if err != nil { + return err + } + + return sysErr +} + +func getNsidByPid(pid int) (int, error) { + if pid <= 0 { + return -1, fmt.Errorf("get invalid pid") + } + + cont, err := os.Readlink("/proc/" + strconv.Itoa(pid) + "/ns/pid") + if err != nil { + return -1, fmt.Errorf("readlink failed, %v", err) + } + + match := ValidNsid.FindStringSubmatch(cont) + if len(match) == 2 { + if nsid, err := strconv.Atoi(match[1]); err != nil { + return -1, fmt.Errorf("convert to int failed, %v", err) + } + return nsid, nil + } + return -1, fmt.Errorf("regexp not match") +} + +func getDockerNsidById(id string) (int, error) { + if len(id) != DOCKER_ID_LEN { + return -1, fmt.Errorf("invalid docker container id") + } + + cli, err := client.NewEnvClient() + if err != nil { + return -1, fmt.Errorf("create docker client failed, %v", err) + } + defer cli.Close() + + ctx := context.Background() + id = strings.ToLower(id) + conInfo, err := cli.ContainerInspect(ctx, id) + if err != nil { + return -1, fmt.Errorf("get container info failed, %v", err) + } + + if conInfo.State.Running == false { + return -1, fmt.Errorf("container is not running") + } + + return getNsidByPid(conInfo.State.Pid) +} + +func SendData(conn net.Conn, data interface{}, errno int) error { + err := connCheck(conn) + if err != nil { + return fmt.Errorf("conn is not alive, %v", err) + } + + datajs, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("data marshl failed, %v", err) + } + + cwmsg := ConnWrapMsg{ + Ret: errno, + Data: string(datajs), + } + injson, err := json.Marshal(cwmsg) + if err != nil { + return fmt.Errorf("message marshl failed, %v", err) + } + + n, err := conn.Write(injson) + if err != nil || n != len(injson) { + return fmt.Errorf("send data failed, %v", err) + } + + return nil +} + +func RecvData(conn net.Conn, outData interface{}) error { + err := connCheck(conn) + if err != nil { + return fmt.Errorf("conn is not alive, %v", err) + } + + var buf [MAX_OUTBUF_SIZE]byte + n, err := conn.Read(buf[:]) + if err != nil || n == 0 { + return fmt.Errorf("read data failed, %v", err) + } + + var data ConnWrapMsg + if err = json.Unmarshal(buf[:n], &data); err != nil { + return fmt.Errorf("message unmarshal failed, %v\n", err) + } + if data.Ret != 0 { + return fmt.Errorf("remote return err, %d\n", data.Ret) + } + + if err = json.Unmarshal([]byte(data.Data), &outData); err != nil { + return fmt.Errorf("data unmarshal failed, %v\n", err) + } + return nil +} + +func dealQcaDaemonClient(conn net.Conn) { + var cliInfo ClientInfo + err := RecvData(conn, &cliInfo) + if err != nil { + log.Printf("recv client regist info failed, %v\n", err) + goto close + } + + err = addConnClient(cliInfo.Id, conn) + if err != nil { + log.Printf("save conn to map failed, %v\n", err) + goto close + } + + log.Println("client register success\n") + return + +close: + conn.Close() +} + +func StartQcaDaemonServer(saddr string) { + listen, err := net.Listen("tcp", saddr) + if err != nil { + log.Fatalf("listen %v failed, %v", saddr, err) + } + for { + select { + case <-done: + return + default: + conn, err := listen.Accept() + if err != nil { + log.Printf("accept failed, %v", err) + continue + } + go dealQcaDaemonClient(conn) + } + } +} + +func dealDockerTAReq(id string, data []byte) ([]byte, error) { + id = strings.ToLower(id) + if len(id) != DOCKER_ID_LEN { + return nil, fmt.Errorf("docker ta request, docker id len invalid %v", len(id)) + } + conn := findConnClient(id) + if conn == nil { + return nil, fmt.Errorf("can't find client") + } + + nsid, err := getDockerNsidById(id) + if err != nil { + return nil, fmt.Errorf("get docker nsid failed, %v", err) + } + + info := &ContRegistInfo{ + Id: id, + Nsid: nsid, + } + + inparamjson, err := json.Marshal(info) + if err != nil { + return nil, fmt.Errorf("encode docker regist json message error, %v", err) + } + + ctx := C.TEEC_Context{} + sess := C.TEEC_Session{} + ret := C.InitCtxAndOpenSess(&ctx, &sess) + if ret != 0 { + return nil, fmt.Errorf("Init tee context or open session failed %v", ret) + } + defer C.CloseSessAndCtx(&ctx, &sess) + + if err = callCRegisterContainer(inparamjson, &ctx, &sess); err != nil { + return nil, err + } + + if err = SendData(conn, data, RET_SUCCESS); err != nil { + return nil, fmt.Errorf("forward req to qca_daemon failed, %v", err) + } + var report []byte + if err = RecvData(conn, &report); err != nil { + return nil, fmt.Errorf("get qca_daemon resp failed, %v", err) + } + return report, nil +} + +func callCRegisterContainer(js_input []byte, ctx *C.TEEC_Context, sess *C.TEEC_Session) error { + c_in := C.struct_ra_buffer_data{} + c_in.size = C.__uint32_t(len(js_input)) + up_c_in := C.CBytes(js_input) + c_in.buf = (*C.uchar)(up_c_in) + defer C.free(up_c_in) + + c_ori := C.__uint32_t(0) + + ret := C.RegisterContainer(&c_in, ctx, sess, &c_ori) + if ret != 0 { + return fmt.Errorf("call libqca register container failed, ret %v, origin %v", ret, c_ori) + } + return nil +} + +func CallCRemoteAttest(js_input []byte, out_len uint32) ([]byte, error) { + if js_input == nil || out_len == 0 { + return nil, errors.New("invalid json input or lens") + } + + /*** format conversion: Go -> C ***/ + // in parameter conversion + c_in := C.struct_ra_buffer_data{} + c_in.size = C.__uint32_t(len(js_input)) + up_c_in := C.CBytes(js_input) + c_in.buf = (*C.uchar)(up_c_in) + defer C.free(up_c_in) + + c_out := C.struct_ra_buffer_data{} + c_out.size = C.__uint32_t(out_len) + up_c_out := C.malloc(C.ulong(c_out.size)) + c_out.buf = (*C.uint8_t)(up_c_out) + defer C.free(up_c_out) + + teec_result := C.RemoteAttest(&c_in, &c_out) + if int(teec_result) != 0 { + return nil, errors.New("Invoke remoteAttest failed") + } + + output := []byte(C.GoBytes(unsafe.Pointer(c_out.buf), C.int(c_out.size))) + + return output, nil +} diff --git a/attestation/tee/tverlib/simulator/Makefile b/attestation/tee/tverlib/simulator/Makefile index 9747a49..c2cf32f 100644 --- a/attestation/tee/tverlib/simulator/Makefile +++ b/attestation/tee/tverlib/simulator/Makefile @@ -6,7 +6,7 @@ DOCTAR = /usr/share/doc/attestation all build: build-libqca build-libteec build-libqca: teeqca.c teeqca.h - gcc -fPIC -shared -o libqca.so teeqca.c -lcjson + gcc -fPIC -shared -o libqca.so teeqca.c -lcjson -I../../../rac/ka/teesimulator build-libteec: teec.c gcc -fPIC -shared -o libteec.so teec.c diff --git a/attestation/tee/tverlib/simulator/teeqca.c b/attestation/tee/tverlib/simulator/teeqca.c index 7fcb460..35c29db 100644 --- a/attestation/tee/tverlib/simulator/teeqca.c +++ b/attestation/tee/tverlib/simulator/teeqca.c @@ -13,11 +13,11 @@ See the Mulan PSL v2 for more details. #include "teeqca.h" #include "testdata.h" -#include #include +#include - -#define NODAAREP "{\ +#define NODAAREP \ + "{\ \"report_sign\": {\ \"sce_as_no_daa\": \"jsXI4_rBHPY-9zbNqVVwnn1W1-n5lRxG37hwSpqNCPgbPnVE87sKfeB9sD-VA1nJct8BpkUVg3PsZ1EhqVGnmiRGevsTDacimzan_HKuUrA8L69JsT7EQauObFQFJvsZWnbg6ixB-KiAXvHbJrbsPok-s-3M-wg9fmFMcRfRfoUtuI2LLRofDgYB0wfNWdc7xhWr9u6h8dzjbq4Lof2jsbVB2vZLu7tWkixWXsGHPhjT31ejGXcGT8cI6HMXvnbWfHOrMTCAQ3tcd6-JTKtjgmcFSMb_DrXpjdvgNE0j8LwMpOa2bErsZzLfYspOyvdjatQr5s4ZwW2533Q3gq296Phy-MYMh3ByW9HDBJY5UGAszQ0eVWN0tGBbvTxHBGljL1p_9x4t2pNnZT1T6c393B8bg-XdA3Q1cz60cQzYG6JxCf2OdCfRtSbBvO8c0KAoO8zHFCbZpsyOaRtcZ-UaUI3uMMcMV0ooZVt54aToMeztP1L7PgMVfY0evacr_ECOWo_vN3Deh1PwRQmAHhMDeCOhcAXy7SsSTbT1RM5JTcOsaHFvTizdhqfzDMndUa5kBuRZZKbxDk6d5lWG1yExJoJ-qOobtVrIGXh9QrzqNCH6v16W7K37QmuAV1TKfHfrsTvkys8smSd--njeZUy4rS-s0q-ATwEKbsk_BTxBDok\"\ },\ @@ -40,8 +40,7 @@ See the Mulan PSL v2 for more details. \"handler\": \"report-output\"\ }" -char nodaaprovision[] = -"{\ +char nodaaprovision[] = "{\ \"signature\": {\ \"drk_cert\": \"TUlJRWtqQ0NBM3FnQXdJQkFnSVJFVk9HdExqeldMKzk2WEpGeWlYSVEwOHdEUVlKS29aSWh2Y05BUUVMQlFBd1BURUxNQWtHQTFVRUJoTUNRMDR4RHpBTkJnTlZCQW9UQmtoMVlYZGxhVEVkTUJzR0ExVUVBeE1VU0hWaGQyVnBJRWxVSUZCeWIyUjFZM1FnUTBFd0hoY05Nakl3TkRFeE1EWXpOVEF5V2hjTk16Y3dOREEzTURZek5UQXlXakE2TVFzd0NRWURWUVFHRXdKRFRqRVBNQTBHQTFVRUNoTUdTSFZoZDJWcE1Sb3dHQVlEVlFRREV4RXdNalpRVUZZeE1FdERNREEwTVRjNVZEQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU5uOGJ6SXJneGFBNFh6RkZYSzhZYUhOVU5IZ2hoRzJZeEg4Znc4a0lTL1BaY3NkZXo2WTVLZ3BNVDJ0ZTRkVkpYa2FDeFVld1IxZm1Vb1AwZStsaWtYeVlaZm1xeDF6SVZoazRtM2tuK0lYN3g5c3RMeitvR0NaYXg2MXMrdURhNnBITGN4VDVKWUZZaFVHZ2FlbE1wS2lxamEvSFo2aHRCUW1oZ1YvNFFxTHl0ellKSlc2ZVFoRnMrQW9URUx5RmFBa0JXUlkzaVFRbE55NmhsV2xGa0xUQkdYSWYvZ0E2MmgyeE5wd3BPVkdjRi9mL2ZrdTBlR3JVZHVZUG04YVRlNnNITzZIOVdhY0xwU28wd1Nqc2hoME8xUzdrcWVJUTFLdWhDY0lkQnJKRWNyalA5RFUzQnJweGxzck5JKytHeTV0ays5Q3RZTzVsTktVbTJHUVpDUlZKaDFxUWNXb3hQWTZUYkNJZTZiMi9oaFJGdHVJM2VYcGczLzlmWW1NYllKb3ZTb1dxekErUzZCL092dmdCVjFhNzNod2kvQldiWjg5bWM3WG52S3I1MVBFeUIrTnMrRUpxczVXWTNnVy93VWlmajh3VWVSS2VqV3hnQzVwSkJVRzlPWWNyc2JZaExzdFAycHdvSHFaK2RFa1kxbytPY2hvWm5XYVl5ZHdYZDgwQWNiNWNkOU1RMUgyc1ZkMUxUb3BXMEt2SGhHUVE1OE1rTVFVSWdPRjVXam1pWExVc0NhcER3bHZrREdwc282UGFpN3VRTmZFOS95TjZRWlg4VXFscE5oNTAvVzcrK0ZrNUtKWWE3b1lDU2Q4Zk9tVElHTFpuUWRxNUFTWlZWM0d4Y2RxUDVGcmdwVVIzUUIvT3dUNzdWZjhMNlJBbjg0aU9Ec2ZQREJ6QWdNQkFBR2pnWTh3Z1l3d0h3WURWUjBqQkJnd0ZvQVVFb28zN1BselY5ZmtnN3ExYndQczNhNFJUczh3Q3dZRFZSMFBCQVFEQWdQNE1Gd0dDQ3NHQVFVRkJ3RUJCRkF3VGpBb0JnZ3JCZ0VGQlFjd0FvWWNhSFIwY0Rvdkx6RXlOeTR3TGpBdU1TOWpZV2x6YzNWbExtaDBiVEFpQmdnckJnRUZCUWN3QVlZV2FIUjBjRG92THpFeU55NHdMakF1TVRveU1EUTBNekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBSFc1OWZtTGNVMmQraWNuY2FHWGVoU3JlSEVjUThVbWRYWDE1a3E3eStnWTNJZklpTUgxSUNNVFZLL1hEbFZZR3ltMXFvUXdiV3hPSi9GOEFnOEFZVk1YcVpHZWtRRThCZGZNTk1tQmdnOWh6R3VoWEl2K2xzN3g5dVJBbEpEVlYyNWtOOWFNWC82RVBZNmk5cUgxTzlKdzdRRWd3T2JlTE5FM1VaY245bE90Q1BXZFhnWENROTlnNm1iSTA3Sng3Zlk0UStzVUpOQkxqNDVicy9JSUNjUGpBUS9HYjd6NEhScEtDREIzU3R6NmZaM0hjUlZiVy9BMmN3MUh3UDI3bXBuWXE4b290d216S1lydFpzbCs4YjhYQnFvME1zbWlYNmpHcTFJSi9hdjNDcUMxN0VGK2NwU3RrbXZacWFlZGdaVndPc1M2ZG83MXh4K0JnUFZlMnpnPT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\ \"drk_sign\": \"0HbdRwbUdPKtIFH8tCNioT50pDhT4TFwi7HPCZEdyBaFBEjK9HIRNiiX9x4QXTMdgW7-jo2-Z0fvzd9a9mgOzdXBSkT-8277Hvzq_yxMsVUlsrRU2oXpMWJFXDdlYu8piMftr6VGRg8M0Vy5Tr0O0PP7CpRujklkGgDkqNScpNO7taI8Yn44saEvGhR3P0MluC9MsvVQRQiMk1mmbgyxFpYo-NHBNam5G67Az55CqmdmSGE88qQAhBnRc5bp4pubpVlsA0Or7SG6QMHHq0Tx9pbXjlgcVtNDz7cmXSX7ITZ3p8kcq5vy3RLV3JdXN454e356KmOjhZlCeoRw_fHl1h2lfroUWqQbDpB_FBp5hsNCtqNa94x-J8OM-VvryKrmp-anwqx4RJ3b4FVwtTRU_2EIfgPeidU1Uh2sbdTKkhLw8msf215NfcgcN9J-nPhQtjsUhfjUiYDpbDILqiBabn_VIf0MckyZXdQSD6TKvctOY7SesMUhRx24f3LFOSmIH1yLlu7celsKr5zfDvO4lH4g_HdxlYzJRdM33EE13xkXohGCrpLyjJ4hbP7nrmwKpGJNdM6GcHQj55UowUkCkuFlZfZJz8r3iPUwcg1Gb8SqLqvP1MLAxO7O4JwccdiR8uNo-iEug796_AmOsvqRhiH9oF7V1xa3H84ry0RH-ME\"\ @@ -64,8 +63,7 @@ char nodaaprovision[] = \"handler\": \"provisioning-output\"\ }"; -char daaprovision[] = -"{\ +char daaprovision[] = "{\ \"signature\": {\ \"drk_cert\": \"TUlJRWtqQ0NBM3FnQXdJQkFnSVJFVk9HdExqeldMKzk2WEpGeWlYSVEwOHdEUVlKS29aSWh2Y05BUUVMQlFBd1BURUxNQWtHQTFVRUJoTUNRMDR4RHpBTkJnTlZCQW9UQmtoMVlYZGxhVEVkTUJzR0ExVUVBeE1VU0hWaGQyVnBJRWxVSUZCeWIyUjFZM1FnUTBFd0hoY05Nakl3TkRFeE1EWXpOVEF5V2hjTk16Y3dOREEzTURZek5UQXlXakE2TVFzd0NRWURWUVFHRXdKRFRqRVBNQTBHQTFVRUNoTUdTSFZoZDJWcE1Sb3dHQVlEVlFRREV4RXdNalpRVUZZeE1FdERNREEwTVRjNVZEQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQU5uOGJ6SXJneGFBNFh6RkZYSzhZYUhOVU5IZ2hoRzJZeEg4Znc4a0lTL1BaY3NkZXo2WTVLZ3BNVDJ0ZTRkVkpYa2FDeFVld1IxZm1Vb1AwZStsaWtYeVlaZm1xeDF6SVZoazRtM2tuK0lYN3g5c3RMeitvR0NaYXg2MXMrdURhNnBITGN4VDVKWUZZaFVHZ2FlbE1wS2lxamEvSFo2aHRCUW1oZ1YvNFFxTHl0ellKSlc2ZVFoRnMrQW9URUx5RmFBa0JXUlkzaVFRbE55NmhsV2xGa0xUQkdYSWYvZ0E2MmgyeE5wd3BPVkdjRi9mL2ZrdTBlR3JVZHVZUG04YVRlNnNITzZIOVdhY0xwU28wd1Nqc2hoME8xUzdrcWVJUTFLdWhDY0lkQnJKRWNyalA5RFUzQnJweGxzck5JKytHeTV0ays5Q3RZTzVsTktVbTJHUVpDUlZKaDFxUWNXb3hQWTZUYkNJZTZiMi9oaFJGdHVJM2VYcGczLzlmWW1NYllKb3ZTb1dxekErUzZCL092dmdCVjFhNzNod2kvQldiWjg5bWM3WG52S3I1MVBFeUIrTnMrRUpxczVXWTNnVy93VWlmajh3VWVSS2VqV3hnQzVwSkJVRzlPWWNyc2JZaExzdFAycHdvSHFaK2RFa1kxbytPY2hvWm5XYVl5ZHdYZDgwQWNiNWNkOU1RMUgyc1ZkMUxUb3BXMEt2SGhHUVE1OE1rTVFVSWdPRjVXam1pWExVc0NhcER3bHZrREdwc282UGFpN3VRTmZFOS95TjZRWlg4VXFscE5oNTAvVzcrK0ZrNUtKWWE3b1lDU2Q4Zk9tVElHTFpuUWRxNUFTWlZWM0d4Y2RxUDVGcmdwVVIzUUIvT3dUNzdWZjhMNlJBbjg0aU9Ec2ZQREJ6QWdNQkFBR2pnWTh3Z1l3d0h3WURWUjBqQkJnd0ZvQVVFb28zN1BselY5ZmtnN3ExYndQczNhNFJUczh3Q3dZRFZSMFBCQVFEQWdQNE1Gd0dDQ3NHQVFVRkJ3RUJCRkF3VGpBb0JnZ3JCZ0VGQlFjd0FvWWNhSFIwY0Rvdkx6RXlOeTR3TGpBdU1TOWpZV2x6YzNWbExtaDBiVEFpQmdnckJnRUZCUWN3QVlZV2FIUjBjRG92THpFeU55NHdMakF1TVRveU1EUTBNekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBSFc1OWZtTGNVMmQraWNuY2FHWGVoU3JlSEVjUThVbWRYWDE1a3E3eStnWTNJZklpTUgxSUNNVFZLL1hEbFZZR3ltMXFvUXdiV3hPSi9GOEFnOEFZVk1YcVpHZWtRRThCZGZNTk1tQmdnOWh6R3VoWEl2K2xzN3g5dVJBbEpEVlYyNWtOOWFNWC82RVBZNmk5cUgxTzlKdzdRRWd3T2JlTE5FM1VaY245bE90Q1BXZFhnWENROTlnNm1iSTA3Sng3Zlk0UStzVUpOQkxqNDVicy9JSUNjUGpBUS9HYjd6NEhScEtDREIzU3R6NmZaM0hjUlZiVy9BMmN3MUh3UDI3bXBuWXE4b290d216S1lydFpzbCs4YjhYQnFvME1zbWlYNmpHcTFJSi9hdjNDcUMxN0VGK2NwU3RrbXZacWFlZGdaVndPc1M2ZG83MXh4K0JnUFZlMnpnPT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\ \"drk_sign\": \"JHaNmOryJBMjKZvMzn3fjevD-DBTpfejTxktYo9yPKry4JmVjjaRJL3f8hRGUaY49hRwukL4oWuqHnfD4pnbtvUzlqrmJmm3v6j8BtOMik0cOnL_54UGjq7G2z8J-Fe-nREuDfa5FKpBBN-Vt9LpRfbHFJdGTJlPkdvwVSUmWUC97pDN4rBM-ZQAU1poyycHHCGbLM8SxoWA-BzQHwIrowBjLtNPJ-EWHFoVK2VrYI1yX1wK_6_CB0f-4w7y2Lv2c8oxyS52Up2w69E7eMlWUn21VvBw4hInFto0H6uT-PC5sTxjOctLvIUT5VCuHQx4LGLRT90j4I2C23mQmEMZI1YPxBGx5gNUI8zv5aZBnRVLME_UoBFp3j3aM1Varkc1eh1i-Bs3eT2TRw3MUYjPYiLwYo_O5sGdCA23OPEqo1Kl53gGYIMZa5uS4udNJeAtdQrQerldz0Yt8Fo5oInz-zBmiQAY9T3SGIQr112qRL9QK-Msfn0onS2RTymxzk2ALBXUbX8hFrWmY07aBea-HbbOFfs0W0DXuJN2um_RTWUOUf7tDbDjNIlaiOidUf8Li0AMlWAu-Sgqr1ackfnq0MwQOoSd6BXqaFnH9RSQGjy3d8E_hD7BFkHr-3diqJ9x-Ie-pvIFcedv4C-jqlJhAuse0jB1nigkIae8u3xL18U\"\ @@ -88,17 +86,13 @@ char daaprovision[] = }"; struct ra_buffer_data_s test_provision_array[] = { - {// case1: report-no as - 0, NULL}, - {// case2: report-as no daa - //sizeof(nodaaprovision), nodaaprovision}, - sizeof(nodaaprovision), nodaaprovision}, - {// case3: report-as with daa, without bsn - sizeof(daaprovision), daaprovision}, + {0, NULL}, // case1: report-no as + {sizeof(nodaaprovision), nodaaprovision}, // case2: report-as no daa + {sizeof(daaprovision), daaprovision}, // case3: report-as with daa, without bsn + }; -char noasreport[] = -"{ \ +char noasreport[] = "{ \ \"report_sign\": { \ \"sce_no_as\": \"RIipRRfPKYILcAVDNr5F0Y13Y4tV2XH9MJD54VkAweVLeVLfUmkhAzVCN65yAts6pk51_nQiSZWcwMFePEMC5e93Mgkvls1f1pqnkDa6UcXUO-7Mm3gm1sDXr1lp5pClUQ_xGleOlHxRl7KiPwVCNm5dShgF2zrXk_F4dhrf06o4GU12HwTMhvs7m2CCp2VF76CBoJaveiZDUpZA6tHebtvqIWEUtqEyIuAVtOGee7bSoGJC54CtZmy_YzkB3W3RaWtPMus2vVdV1JZgEcdni_VVw1mBkicON9O2g1Vk2S8y75wql3q7-MgHyR13Pc9hgvXZYg8Lts3yo0CdvD9NPsKgA2LoB_rRHjd3PLe87mXYNhOErHnZotTTmD3GKOiU0fPnfyXCqGXOCS6by3hpiY9QclSP8inYUjGtxElTyzDJaXM-y1iExxvMdj1zQPkcSpk32ZAakDEH2fOEiCmU0cYTcdJTzEoBTw8hGoNb0FOFUMc-YVQCx9VzMjYF_-wD0xmyLzmVrWuwytQ6Dg8tIacILlt27bV8PZnLoyS0vOMIGjJ7A-NpmJSJRL5WGs7Hx-5WTVOR9Xg3p6z7jJypB61FMdkvpgltw89eYt7TVjyyrCovpJUg-zKg2YbET2_-GyjHoCLNutuVvGqPNEH9I4Kh9MZEKzZiiKKutJUhF_E\"\ },\ @@ -144,8 +138,7 @@ char noasreport[] = char nodaareport[] = NODAAREP; -char daareport[] = -"{\ +char daareport[] = "{\ \"report_sign\": {\ \"sce_as_with_daa\": {\ \"sign.bsn\": \"\",\ @@ -176,19 +169,18 @@ char daareport[] = }"; struct ra_buffer_data test_report_array[] = { - {// case1: report-no as - sizeof(noasreport), (uint8_t *)noasreport}, - {// case2: report-as no daa - sizeof(nodaareport), (uint8_t *)nodaareport}, - {// case3: report-as with daa, without bsn - sizeof(daareport), (uint8_t *)daareport}, + {sizeof(noasreport), (uint8_t *)noasreport}, // case1: report-no as + {sizeof(nodaareport), (uint8_t *)nodaareport}, // case2: report-as no daa + {sizeof(daareport), (uint8_t *)daareport}, // case3: report-as with daa, without bsn + }; static int g_scenario = RA_SCENARIO_NO_AS; // default noas mode static char newreport[20000] = NODAAREP; -bool set_secnario(char *s) { +bool set_secnario(char *s) +{ if (strcmp(s, "sce_no_as") == 0) { g_scenario = RA_SCENARIO_NO_AS; } else if (strcmp(s, "sce_as_no_daa") == 0) { @@ -259,7 +251,7 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *o printf("invoke RemoteAttest succeeded, get report successfully! scenario:%d\n", g_scenario); return 0; } - + out_data->size = test_report_array[g_scenario].size; memcpy(out_data->buf, test_report_array[g_scenario].buf, out_data->size); printf("invoke RemoteAttest succeeded, get report successfully! scenario:%d\n", g_scenario); @@ -268,14 +260,14 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *o } else if (strcmp(h->valuestring, "saveakcert-input") == 0) { out_data->buf = NULL; out_data->size = 0; - + if (g_scenario == 1) { cJSON *ac = cJSON_GetObjectItemCaseSensitive(pl, "akcert"); cJSON *root = cJSON_ParseWithLength(nodaareport, strlen(nodaareport)); - cJSON_ReplaceItemInObject(root, "akcert", ac); + cJSON_ReplaceItemInObject(root, "akcert", ac); uint8_t *tmp = cJSON_Print(root); memcpy(newreport, tmp, strlen(tmp)); - cJSON_Delete(root); + cJSON_Delete(root); cJSON_free(tmp); } printf("invoke RemoteAttest succeeded, save AK Cert successfully! scenario:%d\n", g_scenario); @@ -289,3 +281,9 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *o cJSON_Delete(cj); return 0; } + +TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Context *context, TEEC_Session *session, + uint32_t *origin) +{ + return 0; +} \ No newline at end of file diff --git a/attestation/tee/tverlib/simulator/teeqca.h b/attestation/tee/tverlib/simulator/teeqca.h index 5b9d8f4..b901991 100644 --- a/attestation/tee/tverlib/simulator/teeqca.h +++ b/attestation/tee/tverlib/simulator/teeqca.h @@ -14,48 +14,49 @@ See the Mulan PSL v2 for more details. #ifndef __QCA_LIB__ #define __QCA_LIB__ -#include -#include +#include "tee.h" #include #include +#include +#include #define KEY_TAG_TYPE_MOVE_BITS 28 #define RA_INTEGER (1 << KEY_TAG_TYPE_MOVE_BITS) -#define RA_BYTES (2 << KEY_TAG_TYPE_MOVE_BITS) +#define RA_BYTES (2 << KEY_TAG_TYPE_MOVE_BITS) /* scenario number */ -#define RA_SCENARIO_NO_AS 0 -#define RA_SCENARIO_AS_NO_DAA 1 -#define RA_SCENARIO_AS_WITH_DAA 2 +#define RA_SCENARIO_NO_AS 0 +#define RA_SCENARIO_AS_NO_DAA 1 +#define RA_SCENARIO_AS_WITH_DAA 2 enum ra_alg_types { - RA_ALG_RSA_3072 = 0x20000, - RA_ALG_RSA_4096 = 0x20001, // PSS padding - RA_ALG_SHA_256 = 0x20002, - RA_ALG_SHA_384 = 0x20003, - RA_ALG_SHA_512 = 0x20004, - RA_ALG_ECDSA = 0x20005, - RA_ALG_ED25519 = 0x20006, - RA_ALG_SM2_DSA_SM3 = 0x20007, - RA_ALG_SM3 = 0x20008, + RA_ALG_RSA_3072 = 0x20000, + RA_ALG_RSA_4096 = 0x20001, // PSS padding + RA_ALG_SHA_256 = 0x20002, + RA_ALG_SHA_384 = 0x20003, + RA_ALG_SHA_512 = 0x20004, + RA_ALG_ECDSA = 0x20005, + RA_ALG_ED25519 = 0x20006, + RA_ALG_SM2_DSA_SM3 = 0x20007, + RA_ALG_SM3 = 0x20008, }; enum ra_tags { - RA_TAG_SIGN_TYPE = RA_INTEGER | 0, - RA_TAG_HASH_TYPE = RA_INTEGER | 1, - RA_TAG_QTA_IMG_HASH = RA_BYTES | 0, - RA_TAG_TA_IMG_HASH = RA_BYTES | 1, - RA_TAG_QTA_MEM_HASH = RA_BYTES | 2, - RA_TAG_TA_MEM_HASH = RA_BYTES | 3, - RA_TAG_RESERVED = RA_BYTES | 4, - RA_TAG_AK_PUB = RA_BYTES | 5, - RA_TAG_SIGN_DRK = RA_BYTES | 6, - RA_TAG_SIGN_AK = RA_BYTES | 7, - RA_TAG_CERT_DRK = RA_BYTES | 8, - RA_TAG_CERT_AK = RA_BYTES | 9, - RA_TAG_CURVE_TYPE = RA_BYTES | 10, - RA_TAG_WITH_TCB = RA_INTEGER | 11, - RA_TAG_BASE_NAME = RA_BYTES | 12, + RA_TAG_SIGN_TYPE = RA_INTEGER | 0, + RA_TAG_HASH_TYPE = RA_INTEGER | 1, + RA_TAG_QTA_IMG_HASH = RA_BYTES | 0, + RA_TAG_TA_IMG_HASH = RA_BYTES | 1, + RA_TAG_QTA_MEM_HASH = RA_BYTES | 2, + RA_TAG_TA_MEM_HASH = RA_BYTES | 3, + RA_TAG_RESERVED = RA_BYTES | 4, + RA_TAG_AK_PUB = RA_BYTES | 5, + RA_TAG_SIGN_DRK = RA_BYTES | 6, + RA_TAG_SIGN_AK = RA_BYTES | 7, + RA_TAG_CERT_DRK = RA_BYTES | 8, + RA_TAG_CERT_AK = RA_BYTES | 9, + RA_TAG_CURVE_TYPE = RA_BYTES | 10, + RA_TAG_WITH_TCB = RA_INTEGER | 11, + RA_TAG_BASE_NAME = RA_BYTES | 12, }; struct ra_buffer_data { @@ -86,21 +87,16 @@ struct ra_params_set_t { struct ra_params params[0]; } __attribute__((__packed__)); -typedef int TEEC_Result; -typedef struct -{ - uint32_t timeLow; - uint16_t timeMid; - uint16_t timeHiAndVersion; - uint8_t clockSeqAndNode[8]; -} TEEC_UUID; - TEEC_Result RemoteAttestProvision(uint32_t scenario, struct ra_buffer_data *param_set, struct ra_buffer_data *out_data); -TEEC_Result RemoteAttestReport(TEEC_UUID ta_uuid, struct ra_buffer_data *usr_data, struct ra_buffer_data *param_set, struct ra_buffer_data *report, bool with_tcb); +TEEC_Result RemoteAttestReport(TEEC_UUID ta_uuid, struct ra_buffer_data *usr_data, struct ra_buffer_data *param_set, + struct ra_buffer_data *report, bool with_tcb); TEEC_Result RemoteAttestSaveAKCert(struct ra_buffer_data *akcert); TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *out_data); +TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Context *context, TEEC_Session *session, + uint32_t *origin); + #endif -- Gitee From 287f5f6d18d02c6e7964e15ee36f2eac2b85a1e2 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Thu, 26 Oct 2023 15:19:40 +0800 Subject: [PATCH 5/8] add qca_daemon code --- attestation/tee/demo/Makefile | 2 + attestation/tee/demo/qca_daemon/cmd/main.go | 16 ++ .../qca_daemon/daemontools/daemontools.go | 155 ++++++++++++++++++ .../tee/demo/qca_demo/qcatools/qcautils.go | 4 +- 4 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 attestation/tee/demo/qca_daemon/cmd/main.go create mode 100644 attestation/tee/demo/qca_daemon/daemontools/daemontools.go diff --git a/attestation/tee/demo/Makefile b/attestation/tee/demo/Makefile index dba33a6..0568cb0 100644 --- a/attestation/tee/demo/Makefile +++ b/attestation/tee/demo/Makefile @@ -6,6 +6,7 @@ ATOOLSPATH = ./attester_demo/attestertools QCAPATH = ./qca_demo/cmd QAPIPATH = ./qca_demo/qapi QTOOLSPATH = ./qca_demo/qcatools +QCADAEMONPATH =./qca_daemon/cmd ETCTAR = /etc/attestation SHARETAR = /usr/share/attestation DOCTAR = /usr/share/doc/attestation @@ -22,6 +23,7 @@ build: go build -mod=vendor -o $(PKGPATH)/qcaserver $(QCAPATH)/*.go go build -mod=vendor -o $(PKGPATH)/qapi $(QAPIPATH)/*.go go build -mod=vendor -o $(PKGPATH)/qtools $(QTOOLSPATH)/*.go + go build -mod=vendor -o $(PKGPATH)/qca_daemon $(QCADAEMONPATH)/*.go install: build mkdir -p $(DESTDIR)$(ETCTAR)/attester $(DESTDIR)$(SHARETAR)/attester $(DESTDIR)$(DOCTAR)/attester $(DESTDIR)$(BINTAR) diff --git a/attestation/tee/demo/qca_daemon/cmd/main.go b/attestation/tee/demo/qca_daemon/cmd/main.go new file mode 100644 index 0000000..bcbf2b3 --- /dev/null +++ b/attestation/tee/demo/qca_daemon/cmd/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "log" + + "gitee.com/openeuler/kunpengsecl/attestation/tee/demo/qca_daemon/daemontools" +) + +func main() { + daemontools.InitFlags() + info, err := daemontools.GetVirtualClientInfo() + if err != nil { + log.Fatalf("get virtual os info failed, %v", err) + } + daemontools.StartClientConn(*daemontools.HostServer, info) +} diff --git a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go new file mode 100644 index 0000000..2a034bd --- /dev/null +++ b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go @@ -0,0 +1,155 @@ +package daemontools + +import ( + "bufio" + "encoding/hex" + "fmt" + "io" + "log" + "net" + "os" + "regexp" + + "gitee.com/openeuler/kunpengsecl/attestation/tee/demo/qca_demo/qcatools" + "github.com/google/uuid" + "github.com/spf13/pflag" +) + +const ( + LOG_FILE = "./qca_daemon.log" + SELF_CGROUP_FILE = "/proc/self/cgroup" + DMI_PRODUCT_UUID = "/sys/class/dmi/id/product_uuid" + DMI_PRODUCT_NAME = "/sys/class/dmi/id/product_name" + KVM_NAME = "KVM Virtual Machine" + NOT_DOCKER_CONTAINER = "not docker container" + MAX_INPUT_SIZE = 0x3000 +) + +var ( + ValidDockerId = regexp.MustCompile(`/docker/([a-z0-9]{64})`) + Info *log.Logger + Error *log.Logger + + // cmd flags + HostServer *string +) + +// before main +func init() { + logFile, err := os.OpenFile(LOG_FILE, os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + log.Fatalf("open log file %v faild, %v", LOG_FILE, err) + } + + log.SetOutput(io.MultiWriter(logFile, os.Stdout)) +} + +func InitFlags() { + HostServer = pflag.stringP("hostserver", "H", "", "host server addr ip:port") + pflag.Parse() +} + +func readFirstLine(file string) (string, error) { + f, err := os.Open(file) + if err != nil { + return "", fmt.Errorf("open %v failed, %v", file, err) + } + defer f.Close() + + rd := bufio.NewReader(f) + con, _, err := rd.ReadLine() + if err != nil { + return "", fmt.Errorf("read file failed, %v", err) + } + return string(con), nil +} + +func getSelfDockerId() (string, error) { + con, err := readFirstLine(SELF_CGROUP_FILE) + if err != nil { + return "", err + } + match := ValidDockerId.FindStringSubmatch(string(con)) + if len(match) == 2 { + return match[1], nil + } + return "", fmt.Errorf(NOT_DOCKER_CONTAINER) +} + +// get kvm id and convert to 64 string id +func getSelfKvmId() (string, error) { + con, err := readFirstLine(DMI_PRODUCT_UUID) + if err != nil { + return "", fmt.Errorf("read kvm uuid failed, %v", err) + } + + uuid, err := uuid.Parse(con) + if err != nil { + return "", fmt.Errorf("uuid is invalid, %v", err) + } + + return hex.EncodeToString(uuid[:]), nil +} + +func GetVirtualClientInfo() (*qcatools.ClientInfo, error) { + con, err := readFirstLine(DMI_PRODUCT_NAME) + if err != nil { + return nil, fmt.Errorf("read kvm name failed, %v", err) + } + + // kvm container + if con == KVM_NAME { + id, err := getSelfKvmId() + if err != nil { + return nil, fmt.Errorf("get kvm id failed, %v", err) + } + return &qcatools.ClientInfo{ + Id: id, + Type: "kvm", + }, nil + } + + dockerId, err := getSelfDockerId() + if err == nil { + return &qcatools.ClientInfo{ + Id: dockerId, + Type: "docker", + }, nil + } + + return nil, err +} + +func StartClientConn(saddr string, info *qcatools.ClientInfo) { + conn, err := net.Dial("tcp", saddr) + if err != nil { + log.Fatalf("connect to server %v failed, %v\n", saddr, err) + } + defer conn.Close() + log.Printf("connect to server %v success\n", saddr) + + if err = qcatools.SendData(conn, info, qcatools.RET_SUCCESS); err != nil { + log.Fatalf("send register info to ra_server failed, %v", err) + } + log.Printf("register client info success\n", saddr) + + var retVal int + for { + reportIn := []byte{} + if err = qcatools.RecvData(conn, reportIn); err != nil { + log.Fatalf("read ra_server forward req data failed, %v", err) + } + + retVal = qcatools.RET_SUCCESS + report, err := qcatools.CallCRemoteAttest(reportIn, qcatools.MAX_OUTBUF_SIZE) + if err != nil { + log.Printf("get report from libqca-report failed, %v", err) + retVal = qcatools.RET_CALLCERR + } + + if err = qcatools.SendData(conn, report, retVal); err != nil { + log.Fatalf("send register info to ra_server failed, %v", err) + } + + } +} diff --git a/attestation/tee/demo/qca_demo/qcatools/qcautils.go b/attestation/tee/demo/qca_demo/qcatools/qcautils.go index ecb9b24..0fe7d70 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcautils.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcautils.go @@ -67,8 +67,10 @@ const ( MAX_OUTBUF_SIZE = 0x3000 MAX_REGBUF_SIZE = 512 DOCKER_ID_LEN = 64 - RET_SUCCESS = 0 MAX_HEALTH_CHECK = 7 * 24 * 60 // 7 day + + RET_SUCCESS = 0 + RET_CALLCERR = 1 ) var ( -- Gitee From 9331e1d80cba5c10a5e3efced164e17091373b8d Mon Sep 17 00:00:00 2001 From: chenzheng Date: Fri, 27 Oct 2023 00:23:52 +0800 Subject: [PATCH 6/8] adapte kvm virtual machine --- attestation/go.mod | 3 +- .../attestertools/attestertools.go | 105 ++++--- .../tee/demo/attester_demo/cmd/config.yaml | 3 + .../qca_daemon/daemontools/daemontools.go | 21 +- attestation/tee/demo/qca_demo/cmd/config.yaml | 2 +- attestation/tee/demo/qca_demo/qapi/api.pb.go | 80 ++--- attestation/tee/demo/qca_demo/qapi/api.proto | 4 +- attestation/tee/demo/qca_demo/qapi/qapi.go | 10 +- .../tee/demo/qca_demo/qcatools/qcatools.go | 62 ++-- .../tee/demo/qca_demo/qcatools/qcautils.go | 281 ++++++++++++++---- ...34\347\250\213\350\257\201\346\230\216.md" | 86 ++++++ 11 files changed, 459 insertions(+), 198 deletions(-) create mode 100644 "doc/\345\256\271\345\231\250\345\206\205\350\277\234\347\250\213\350\257\201\346\230\216.md" diff --git a/attestation/go.mod b/attestation/go.mod index 8b909e5..bd1e5f3 100644 --- a/attestation/go.mod +++ b/attestation/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/beevik/etree v1.1.0 github.com/deepmap/oapi-codegen v1.8.1 + github.com/docker/docker v1.13.0 github.com/gemalto/kmip-go v0.0.8 github.com/getkin/kin-openapi v0.89.0 github.com/google/go-tpm v0.3.2 @@ -36,7 +37,6 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v1.13.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect @@ -82,7 +82,6 @@ require ( golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/tools v0.14.0 // indirect google.golang.org/genproto v0.0.0-20220208230804-65c12eb4c068 // indirect - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect gopkg.in/ini.v1 v1.51.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/attestation/tee/demo/attester_demo/attestertools/attestertools.go b/attestation/tee/demo/attester_demo/attestertools/attestertools.go index bb4c509..9750724 100644 --- a/attestation/tee/demo/attester_demo/attestertools/attestertools.go +++ b/attestation/tee/demo/attester_demo/attestertools/attestertools.go @@ -66,10 +66,10 @@ const ( sflagTest = "T" helpTest = "set a fixed nonce value for test" // container info - sflagConId = "id" - helpConId = "specify the container id where ta running" - sflagConType = "type" - helpConType = "specify the container type where ta running" + sflagVirtGuestId = "id" + helpVirtGuestId = "specify the virtual guest id where ta running" + sflagVirtGuestType = "type" + helpVirtGuestType = "specify the virtual guest type where ta running" // app name appAttester = "attester" @@ -89,41 +89,41 @@ const ( // Mspolicy means attesterconfig mspolicy Mspolicy = "attesterconfig.mspolicy" // Uuid means attesterconfig uuid - Uuid = "attesterconfig.uuid" - ConIdKey = "attesterconfig.container.id" - ConTypeKey = "attesterconfig.container.type" + Uuid = "attesterconfig.uuid" + VirtGuestIdKey = "attesterconfig.virtualguest.id" + VirtGuestTypeKey = "attesterconfig.virtualguest.type" ) type ( trustApp struct { - ctx context.Context - uuid []byte - usrdata []byte - report []byte - withtcb bool - conId string - conType string + ctx context.Context + uuid []byte + usrdata []byte + report []byte + withtcb bool + VirtGuestId string + VirtGuestType string } attesterConfig struct { - server string - basevalue string - mspolicy int - uuid string - conId string - conType string + server string + basevalue string + mspolicy int + uuid string + VirtGuestId string + VirtGuestType string } ) var ( testmode bool = false test_ta *trustApp = &trustApp{ - ctx: context.Background(), - uuid: []byte{}, - usrdata: []byte{}, - report: []byte{}, - withtcb: false, - conId: "", - conType: "", + ctx: context.Background(), + uuid: []byte{}, + usrdata: []byte{}, + report: []byte{}, + withtcb: false, + VirtGuestId: "", + VirtGuestType: "", } verify_result int = 1 defaultPaths = []string{ @@ -144,8 +144,8 @@ var ( // TestFlag means test flag TestFlag *bool = nil // Container Flag - ConIdFlag *string = nil - ConTypeFlag *string = nil + VirtGuestIdFlag *string = nil + VirtGuestTypeFlag *string = nil attesterConf *attesterConfig = nil ) @@ -159,8 +159,8 @@ func InitFlags() { MspolicyFlag = pflag.IntP(lflagMeasure, sflagMeasure, -1, helpMeasure) UuidFlag = pflag.StringP(lflagUuid, sflagUuid, "", helpUuid) TestFlag = pflag.BoolP(lflagTest, sflagTest, false, helpTest) - ConIdFlag = pflag.String(sflagConId, "", helpConId) - ConTypeFlag = pflag.String(sflagConType, "", helpConType) + VirtGuestIdFlag = pflag.String(sflagVirtGuestId, "", helpVirtGuestId) + VirtGuestTypeFlag = pflag.String(sflagVirtGuestType, "", helpVirtGuestType) pflag.Parse() } @@ -185,8 +185,8 @@ func LoadConfigs() { attesterConf.basevalue = viper.GetString(Basevalue) attesterConf.mspolicy = viper.GetInt(Mspolicy) attesterConf.uuid = viper.GetString(Uuid) - attesterConf.conId = viper.GetString(ConIdKey) - attesterConf.conType = viper.GetString(ConTypeKey) + attesterConf.VirtGuestId = viper.GetString(VirtGuestIdKey) + attesterConf.VirtGuestType = viper.GetString(VirtGuestTypeKey) } // HandleFlags handles the command flags. @@ -212,13 +212,11 @@ func HandleFlags() { attesterConf.uuid = *UuidFlag log.Printf("TEE Uuid: %s", attesterConf.uuid) // just for test! } - if ConIdFlag != nil && *ConIdFlag != "" { - attesterConf.conId = *ConIdFlag - log.Printf("TEE container id: %s", attesterConf.conId) // just for test! + if VirtGuestIdFlag != nil && *VirtGuestIdFlag != "" { + attesterConf.VirtGuestId = *VirtGuestIdFlag } - if ConTypeFlag != nil && *ConTypeFlag != "" { - attesterConf.conType = *ConTypeFlag - log.Printf("TEE container type: %s", attesterConf.conType) // just for test! + if VirtGuestTypeFlag != nil && *VirtGuestTypeFlag != "" { + attesterConf.VirtGuestType = *VirtGuestTypeFlag } if TestFlag != nil && *TestFlag { testmode = true @@ -258,7 +256,7 @@ func StartAttester() { log.Print("Stop Attester......") } -func chenckContainerInfo(id, ctype string) error { +func checkVirtGuestInfo(id, ctype string) error { // no container info input is valid if id == "" && ctype == "" { return nil @@ -298,12 +296,12 @@ func iniTAParameter(ta *trustApp, m bool) (*trustApp, error) { ta.usrdata = nonce } - err = chenckContainerInfo(attesterConf.conId, attesterConf.conType) + err = checkVirtGuestInfo(attesterConf.VirtGuestId, attesterConf.VirtGuestType) if err != nil { return nil, err } - ta.conId = attesterConf.conId - ta.conType = attesterConf.conType + ta.VirtGuestId = attesterConf.VirtGuestId + ta.VirtGuestType = attesterConf.VirtGuestType return ta, nil } @@ -314,11 +312,11 @@ func getReport(ta *trustApp) []byte { return nil } - var info *qapi.GetReportRequest_ContainerInfo - if ta.conId != "" || ta.conType != "" { - info = &qapi.GetReportRequest_ContainerInfo{ - Id: ta.conId, - Type: ta.conType, + var info *qapi.GetReportRequest_VirtualGuestInfo + if ta.VirtGuestId != "" || ta.VirtGuestType != "" { + info = &qapi.GetReportRequest_VirtualGuestInfo{ + Id: ta.VirtGuestId, + Type: ta.VirtGuestType, } } @@ -340,7 +338,6 @@ func getReport(ta *trustApp) []byte { } // invoke verifier lib to verify -// int tee_verify_report(buffer_data *data_buf, buffer_data *nonce, container_info *info, int type, char *filename); func tee_verify(ta *trustApp, mtype int, bv string) int { // construct C data_buf var crep C.buffer_data @@ -356,14 +353,14 @@ func tee_verify(ta *trustApp, mtype int, bv string) int { // construct C info var cinfo *C.container_info = nil - if ta.conId != "" && ta.conType != "" { + if ta.VirtGuestId != "" && ta.VirtGuestType != "" { var tmpInfo C.container_info - cid := C.CString(ta.conId) + cid := C.CString(ta.VirtGuestId) defer C.free(unsafe.Pointer(cid)) - ctype := C.CString(ta.conType) + ctype := C.CString(ta.VirtGuestType) defer C.free(unsafe.Pointer(ctype)) - tmpInfo.id.buf, tmpInfo.id.size = (*C.uchar)(cid), C.__uint32_t(len(ta.conId)) - tmpInfo._type.buf, tmpInfo._type.size = (*C.uchar)(ctype), C.__uint32_t(len(ta.conType)) + tmpInfo.id.buf, tmpInfo.id.size = (*C.uchar)(cid), C.__uint32_t(len(ta.VirtGuestId)) + tmpInfo._type.buf, tmpInfo._type.size = (*C.uchar)(ctype), C.__uint32_t(len(ta.VirtGuestType)) cinfo = &tmpInfo } diff --git a/attestation/tee/demo/attester_demo/cmd/config.yaml b/attestation/tee/demo/attester_demo/cmd/config.yaml index 56839bf..c34f703 100644 --- a/attestation/tee/demo/attester_demo/cmd/config.yaml +++ b/attestation/tee/demo/attester_demo/cmd/config.yaml @@ -3,3 +3,6 @@ attesterconfig: basevalue: "./basevalue.txt" mspolicy: 2 uuid: 435dcafa-0029-4d53-97e8-a7a13a80c82e + virtualguest: + id: xxxxx(64) + type: docker diff --git a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go index 2a034bd..94a4652 100644 --- a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go +++ b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go @@ -45,7 +45,7 @@ func init() { } func InitFlags() { - HostServer = pflag.stringP("hostserver", "H", "", "host server addr ip:port") + HostServer = pflag.StringP("hostserver", "H", "", "host server addr ip:port") pflag.Parse() } @@ -91,7 +91,7 @@ func getSelfKvmId() (string, error) { return hex.EncodeToString(uuid[:]), nil } -func GetVirtualClientInfo() (*qcatools.ClientInfo, error) { +func GetVirtualClientInfo() (*qcatools.VirtualGuestInfo, error) { con, err := readFirstLine(DMI_PRODUCT_NAME) if err != nil { return nil, fmt.Errorf("read kvm name failed, %v", err) @@ -103,7 +103,7 @@ func GetVirtualClientInfo() (*qcatools.ClientInfo, error) { if err != nil { return nil, fmt.Errorf("get kvm id failed, %v", err) } - return &qcatools.ClientInfo{ + return &qcatools.VirtualGuestInfo{ Id: id, Type: "kvm", }, nil @@ -111,7 +111,7 @@ func GetVirtualClientInfo() (*qcatools.ClientInfo, error) { dockerId, err := getSelfDockerId() if err == nil { - return &qcatools.ClientInfo{ + return &qcatools.VirtualGuestInfo{ Id: dockerId, Type: "docker", }, nil @@ -120,7 +120,7 @@ func GetVirtualClientInfo() (*qcatools.ClientInfo, error) { return nil, err } -func StartClientConn(saddr string, info *qcatools.ClientInfo) { +func StartClientConn(saddr string, info *qcatools.VirtualGuestInfo) { conn, err := net.Dial("tcp", saddr) if err != nil { log.Fatalf("connect to server %v failed, %v\n", saddr, err) @@ -131,20 +131,27 @@ func StartClientConn(saddr string, info *qcatools.ClientInfo) { if err = qcatools.SendData(conn, info, qcatools.RET_SUCCESS); err != nil { log.Fatalf("send register info to ra_server failed, %v", err) } - log.Printf("register client info success\n", saddr) + + var ret []byte + if err = qcatools.RecvData(conn, &ret); err != nil { + log.Fatalf("read register reply failed, %v", err) + } + log.Printf("register client info success\n") var retVal int for { reportIn := []byte{} - if err = qcatools.RecvData(conn, reportIn); err != nil { + if err = qcatools.RecvData(conn, &reportIn); err != nil { log.Fatalf("read ra_server forward req data failed, %v", err) } + log.Println("get host forward report request") retVal = qcatools.RET_SUCCESS report, err := qcatools.CallCRemoteAttest(reportIn, qcatools.MAX_OUTBUF_SIZE) if err != nil { log.Printf("get report from libqca-report failed, %v", err) retVal = qcatools.RET_CALLCERR + report = []byte("get report by qta_report failed") } if err = qcatools.SendData(conn, report, retVal); err != nil { diff --git a/attestation/tee/demo/qca_demo/cmd/config.yaml b/attestation/tee/demo/qca_demo/cmd/config.yaml index e51b217..61b30ff 100644 --- a/attestation/tee/demo/qca_demo/cmd/config.yaml +++ b/attestation/tee/demo/qca_demo/cmd/config.yaml @@ -5,6 +5,6 @@ qcaconfig: nodaaacfile: ./nodaa-ac.crt daaacfile: ./daa-ac.crt virtual: - server: 0.0.0.0:90000 + server: 0.0.0.0:9000 healthcheck: 10 # minute, <0 no health check, max is 7 day \ No newline at end of file diff --git a/attestation/tee/demo/qca_demo/qapi/api.pb.go b/attestation/tee/demo/qca_demo/qapi/api.pb.go index efcddd9..8b3bc39 100644 --- a/attestation/tee/demo/qca_demo/qapi/api.pb.go +++ b/attestation/tee/demo/qca_demo/qapi/api.pb.go @@ -25,10 +25,10 @@ type GetReportRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` - WithTcb bool `protobuf:"varint,3,opt,name=with_tcb,json=withTcb,proto3" json:"with_tcb,omitempty"` - Info *GetReportRequest_ContainerInfo `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` + Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` + Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` + WithTcb bool `protobuf:"varint,3,opt,name=with_tcb,json=withTcb,proto3" json:"with_tcb,omitempty"` + Info *GetReportRequest_VirtualGuestInfo `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` } func (x *GetReportRequest) Reset() { @@ -84,7 +84,7 @@ func (x *GetReportRequest) GetWithTcb() bool { return false } -func (x *GetReportRequest) GetInfo() *GetReportRequest_ContainerInfo { +func (x *GetReportRequest) GetInfo() *GetReportRequest_VirtualGuestInfo { if x != nil { return x.Info } @@ -138,7 +138,7 @@ func (x *GetReportReply) GetTeeReport() []byte { return nil } -type GetReportRequest_ContainerInfo struct { +type GetReportRequest_VirtualGuestInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -147,8 +147,8 @@ type GetReportRequest_ContainerInfo struct { Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` } -func (x *GetReportRequest_ContainerInfo) Reset() { - *x = GetReportRequest_ContainerInfo{} +func (x *GetReportRequest_VirtualGuestInfo) Reset() { + *x = GetReportRequest_VirtualGuestInfo{} if protoimpl.UnsafeEnabled { mi := &file_qca_demo_qapi_api_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -156,13 +156,13 @@ func (x *GetReportRequest_ContainerInfo) Reset() { } } -func (x *GetReportRequest_ContainerInfo) String() string { +func (x *GetReportRequest_VirtualGuestInfo) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetReportRequest_ContainerInfo) ProtoMessage() {} +func (*GetReportRequest_VirtualGuestInfo) ProtoMessage() {} -func (x *GetReportRequest_ContainerInfo) ProtoReflect() protoreflect.Message { +func (x *GetReportRequest_VirtualGuestInfo) ProtoReflect() protoreflect.Message { mi := &file_qca_demo_qapi_api_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -174,19 +174,19 @@ func (x *GetReportRequest_ContainerInfo) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetReportRequest_ContainerInfo.ProtoReflect.Descriptor instead. -func (*GetReportRequest_ContainerInfo) Descriptor() ([]byte, []int) { +// Deprecated: Use GetReportRequest_VirtualGuestInfo.ProtoReflect.Descriptor instead. +func (*GetReportRequest_VirtualGuestInfo) Descriptor() ([]byte, []int) { return file_qca_demo_qapi_api_proto_rawDescGZIP(), []int{0, 0} } -func (x *GetReportRequest_ContainerInfo) GetId() string { +func (x *GetReportRequest_VirtualGuestInfo) GetId() string { if x != nil { return x.Id } return "" } -func (x *GetReportRequest_ContainerInfo) GetType() string { +func (x *GetReportRequest_VirtualGuestInfo) GetType() string { if x != nil { return x.Type } @@ -197,31 +197,31 @@ var File_qca_demo_qapi_api_proto protoreflect.FileDescriptor var file_qca_demo_qapi_api_proto_rawDesc = []byte{ 0x0a, 0x17, 0x71, 0x63, 0x61, 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, 0x2f, - 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc1, 0x01, 0x0a, 0x10, 0x47, 0x65, + 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x74, 0x63, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x69, 0x74, 0x68, - 0x54, 0x63, 0x62, 0x12, 0x33, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x33, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2f, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x65, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x32, 0x38, - 0x0a, 0x03, 0x51, 0x63, 0x61, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x65, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x75, 0x6c, 0x65, 0x72, 0x2f, - 0x6b, 0x75, 0x6e, 0x70, 0x65, 0x6e, 0x67, 0x73, 0x65, 0x63, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x63, 0x61, - 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x54, 0x63, 0x62, 0x12, 0x36, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x36, 0x0a, 0x10, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x2f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x65, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x32, 0x38, 0x0a, 0x03, 0x51, 0x63, 0x61, 0x12, 0x31, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x40, + 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x65, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x65, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x6b, 0x75, 0x6e, 0x70, 0x65, 0x6e, 0x67, 0x73, 0x65, 0x63, + 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, + 0x6d, 0x6f, 0x2f, 0x71, 0x63, 0x61, 0x5f, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x71, 0x61, 0x70, 0x69, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -238,12 +238,12 @@ func file_qca_demo_qapi_api_proto_rawDescGZIP() []byte { var file_qca_demo_qapi_api_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_qca_demo_qapi_api_proto_goTypes = []interface{}{ - (*GetReportRequest)(nil), // 0: GetReportRequest - (*GetReportReply)(nil), // 1: GetReportReply - (*GetReportRequest_ContainerInfo)(nil), // 2: GetReportRequest.ContainerInfo + (*GetReportRequest)(nil), // 0: GetReportRequest + (*GetReportReply)(nil), // 1: GetReportReply + (*GetReportRequest_VirtualGuestInfo)(nil), // 2: GetReportRequest.VirtualGuestInfo } var file_qca_demo_qapi_api_proto_depIdxs = []int32{ - 2, // 0: GetReportRequest.info:type_name -> GetReportRequest.ContainerInfo + 2, // 0: GetReportRequest.info:type_name -> GetReportRequest.VirtualGuestInfo 0, // 1: Qca.GetReport:input_type -> GetReportRequest 1, // 2: Qca.GetReport:output_type -> GetReportReply 2, // [2:3] is the sub-list for method output_type @@ -284,7 +284,7 @@ func file_qca_demo_qapi_api_proto_init() { } } file_qca_demo_qapi_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetReportRequest_ContainerInfo); i { + switch v := v.(*GetReportRequest_VirtualGuestInfo); i { case 0: return &v.state case 1: diff --git a/attestation/tee/demo/qca_demo/qapi/api.proto b/attestation/tee/demo/qca_demo/qapi/api.proto index a66f30e..ab16bcc 100644 --- a/attestation/tee/demo/qca_demo/qapi/api.proto +++ b/attestation/tee/demo/qca_demo/qapi/api.proto @@ -10,11 +10,11 @@ message GetReportRequest { bytes uuid = 1; bytes nonce = 2; bool with_tcb = 3; - message ContainerInfo { + message VirtualGuestInfo { string id = 1; string type = 2; } - ContainerInfo info = 4; + VirtualGuestInfo info = 4; } message GetReportReply { diff --git a/attestation/tee/demo/qca_demo/qapi/qapi.go b/attestation/tee/demo/qca_demo/qapi/qapi.go index f6839ca..3f5ec5e 100644 --- a/attestation/tee/demo/qca_demo/qapi/qapi.go +++ b/attestation/tee/demo/qca_demo/qapi/qapi.go @@ -59,13 +59,13 @@ var ( srv *grpc.Server = nil ) -func getContainerInfo(in *GetReportRequest) *qcatools.ContainerInfo { +func getVirtualGuestInfo(in *GetReportRequest) *qcatools.VirtualGuestInfo { info := in.GetInfo() if info == nil || (info.GetId() == "" && info.GetType() == "") { return nil } - return &qcatools.ContainerInfo{ + return &qcatools.VirtualGuestInfo{ Id: info.GetId(), Type: info.GetType(), } @@ -79,7 +79,7 @@ func (s *service) GetReport(ctx context.Context, in *GetReportRequest) (*GetRepo return nil, fmt.Errorf("invalid request input") } Usrdata := in.GetNonce() - info := getContainerInfo(in) + info := getVirtualGuestInfo(in) rep, err := qcatools.GetTAReport(in.GetUuid(), Usrdata, in.WithTcb, info) if err != nil { @@ -110,8 +110,8 @@ func StartServer() { } if qcatools.Qcacfg.VirtSupport { - go qcatools.StartQcaDaemonServer(qcatools.VirtServer) - go qcatools.CheckConnAlive(qcatools.VirtHealthChk) + go qcatools.StartQcaDaemonServer(qcatools.Qcacfg.VirtServer) + go qcatools.CheckConnAlive(qcatools.Qcacfg.VirtHealthChk) } if err = srv.Serve(listen); err != nil { diff --git a/attestation/tee/demo/qca_demo/qcatools/qcatools.go b/attestation/tee/demo/qca_demo/qcatools/qcatools.go index 3667b98..74f2fd5 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcatools.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcatools.go @@ -16,7 +16,7 @@ Description: invoke qca lib to get info of given TA package qcatools /* -#cgo CFLAGS: -I../../../tverlib/simulator -I../../../../rac/ka/teesimulator +#cgo CFLAGS: -I../../../tverlib/simulator #cgo LDFLAGS: -L${SRCDIR}/../../../tverlib/simulator -lqca -lteec #include "teeqca.h" #include @@ -94,10 +94,8 @@ import ( "encoding/base64" "encoding/json" "errors" - "fmt" "log" "os" - "strings" "unsafe" "github.com/google/uuid" @@ -137,12 +135,15 @@ const ( sflagScenario = "C" helpScenario = "set the app usage scenario" // specify virtual server to support virtual remote attest - lflagVirtSupport = "virtual" - sflagVirtSupport = "V" - helpVirtSupport = "is support remote attest" - lflagVirtServer = "virtualserver" - sflagVirtServer = "A" - helpVirtServer = "virtual server addr" + lflagVirtSupport = "virtual" + sflagVirtSupport = "V" + helpVirtSupport = "is support remote attest" + lflagVirtServer = "virtualserver" + sflagVirtServer = "A" + helpVirtServer = "virtual server addr" + lflagVirtHealthChk = "healthcheck" + sflagVirtHealthChk = "H" + helpVirtHealthChk = "virtual connect health check" // RemoteAttest Handler RAProvisionInHandler = "provisioning-input" RAProvisionOutHandler = "provisioning-output" @@ -215,7 +216,7 @@ type ( DaaACFile string VirtSupport bool VirtServer string - VirtHealthChk uint32 + VirtHealthChk int32 } ) @@ -231,9 +232,10 @@ var ( // ServerFlag means server flag ServerFlag *string = nil // ScenarioFlag means scenario flag - ScenarioFlag *int32 = nil - VirtSupportFlag *bool = nil - VirtServerFlag *string = nil + ScenarioFlag *int32 = nil + VirtSupportFlag *bool = nil + VirtServerFlag *string = nil + VirtHealthChkFlag *int32 = nil ) // InitFlags inits the qca server command flags. @@ -243,6 +245,7 @@ func InitFlags() { ScenarioFlag = pflag.Int32P(lflagScenario, sflagScenario, 0, helpScenario) VirtSupportFlag = pflag.BoolP(lflagVirtSupport, sflagVirtSupport, false, helpVirtSupport) VirtServerFlag = pflag.StringP(lflagVirtServer, sflagVirtServer, "", helpVirtServer) + VirtHealthChkFlag = pflag.Int32P(lflagVirtHealthChk, sflagVirtHealthChk, 0, helpVirtHealthChk) pflag.Parse() } @@ -289,6 +292,9 @@ func HandleFlags() { if VirtServerFlag != nil && *VirtServerFlag != "" { Qcacfg.VirtServer = *VirtServerFlag } + if VirtHealthChkFlag != nil && *VirtHealthChkFlag > 0 { + Qcacfg.VirtHealthChk = *VirtHealthChkFlag + } } // GetQcaServer returns the qca service server configuration. @@ -317,18 +323,18 @@ func adapt2TAUUID(uuid []byte) { } type ( - ContainerInfo struct { + VirtualGuestInfo struct { Id string `json:"id,omitempty"` Type string `json:"type,omitempty"` } reportInPl struct { - Version string `json:"version,omitempty"` // VERSION_TYPE - Nonce string `json:"nonce,omitempty"` // BASE64_TYPE - Uuid string `json:"uuid,omitempty"` // 待证明的TA UUID的hex字符串描述,字母小写,如"e08f7eca-e875-440e-9ab0-5f381136c600" - Hash_alg string `json:"hash_alg,omitempty"` // HASH_ALG_TYPE - With_tcb bool `json:"with_tcb,omitempty"` // BOOLEAN_TYPE, 当前只能是 “FALSE” - Daa_bsn *string `json:"daa_bsn,omitempty"` // BASE64_TYPE, BASE64 of DAA用户挑选出来的basename - Info *ContainerInfo `json:"container_info,omitempty"` + Version string `json:"version,omitempty"` // VERSION_TYPE + Nonce string `json:"nonce,omitempty"` // BASE64_TYPE + Uuid string `json:"uuid,omitempty"` // 待证明的TA UUID的hex字符串描述,字母小写,如"e08f7eca-e875-440e-9ab0-5f381136c600" + Hash_alg string `json:"hash_alg,omitempty"` // HASH_ALG_TYPE + With_tcb bool `json:"with_tcb,omitempty"` // BOOLEAN_TYPE, 当前只能是 “FALSE” + Daa_bsn *string `json:"daa_bsn,omitempty"` // BASE64_TYPE, BASE64 of DAA用户挑选出来的basename + Info *VirtualGuestInfo `json:"container_info,omitempty"` // 名字兼容tee里名字 } reportInParam struct { Handler string `json:"handler,omitempty"` @@ -336,26 +342,26 @@ type ( } ) -func forwardReportReq(inparam []byte, out_len uint32, info *ContainerInfo) ([]byte, error) { +func forwardReportReq(inparam []byte, out_len uint32, info *VirtualGuestInfo) ([]byte, error) { var report []byte var err error switch { // host request case info == nil || (info.Id == "" && info.Type == ""): + log.Println("Deal host TA report request") report, err = CallCRemoteAttest(inparam, out_len) if err != nil { log.Printf("Get host ta report failed, %v", err) return nil, err } - // docker request - case strings.ToLower(info.Type) == "docker": - report, err = dealDockerTAReq(info.Id, inparam) + // virtual guest request + default: + log.Println("Deal virtaul guest TA report request") + report, err = dealVirtualTAReq(info, inparam) if err != nil { log.Printf("Get docker ta report failed, %v", err) return nil, err } - default: - return nil, fmt.Errorf("not support container type %v", info.Type) } log.Print("Generate TA report succeeded!") @@ -363,7 +369,7 @@ func forwardReportReq(inparam []byte, out_len uint32, info *ContainerInfo) ([]by } // GetTAReport gets TA trusted report information. -func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *ContainerInfo) ([]byte, error) { +func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *VirtualGuestInfo) ([]byte, error) { n := base64.RawURLEncoding.EncodeToString(usr_data) id, err := uuid.FromBytes(ta_uuid) if err != nil { diff --git a/attestation/tee/demo/qca_demo/qcatools/qcautils.go b/attestation/tee/demo/qca_demo/qcatools/qcautils.go index 0fe7d70..de59916 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcautils.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcautils.go @@ -7,36 +7,168 @@ package qcatools #include "teeqca.h" #include "tee.h" #include "teeqca.h" +#include +#include -static const TEEC_UUID g_qta_uuid = { +#define MAX_INDEX 0x100000 + +static const TEEC_UUID g_qtaUuid = { 0xe08f7eca, 0xe875, 0x440e, {0x9a, 0xb0, 0x5f, 0x38, 0x11, 0x36, 0xc6, 0x00} }; -uint32_t InitCtxAndOpenSess(TEEC_Context *ctx, TEEC_Session *sess) +struct CtxSessList { + uint32_t index; + TEEC_Context ctx; + TEEC_Session sess; + struct CtxSessList *next; + struct CtxSessList *prev; +}; + +static uint32_t g_curIndex = 0; +static struct CtxSessList g_listHead; +static bool g_isInitList = false; +static pthread_mutex_t g_listLock = PTHREAD_MUTEX_INITIALIZER; + +static inline void initHead(struct CtxSessList *head) +{ + head->next = head; + head->prev = head; +} + +static inline void insertTail(struct CtxSessList *head, struct CtxSessList *node) +{ + struct CtxSessList *tail = head->prev; + tail->next = node; + node->prev = tail; + node->next = head; + head->prev = node; +} + +static inline struct CtxSessList *findNode(struct CtxSessList *head, uint32_t index) +{ + struct CtxSessList *cur = head->next; + for (; cur != head; cur = cur->next) { + if (cur->index == index) { + return cur; + } + } + return NULL; +} + +static inline void deleteNode(struct CtxSessList *node) +{ + if (node == &g_listHead) { + return; + } + struct CtxSessList *pre = node->prev; + pre->next = node->next; + node->next->prev = pre; +} + + +static struct CtxSessList *mallocAddList(void) +{ + struct CtxSessList *node = (struct CtxSessList *)calloc(1, sizeof(struct CtxSessList)); + if (node == NULL) { + printf("[c] calloc new node failed\n"); + return NULL; + } + + if (pthread_mutex_lock(&g_listLock) != 0) { + printf("[c] thread lock failed\n"); + free(node); + return NULL; + } + + g_curIndex++; + g_curIndex &= (MAX_INDEX - 1); + node->index = g_curIndex; + if (!g_isInitList) { + initHead(&g_listHead); + g_isInitList = true; + } + insertTail(&g_listHead, node); + + (void)pthread_mutex_unlock(&g_listLock); + return node; +} + +static struct CtxSessList *DeleteNodeList(uint32_t index) +{ + if (!g_isInitList) { + printf("[c] should use this after init\n"); + return NULL; + } + if (pthread_mutex_lock(&g_listLock) != 0) { + printf("[c] thread lock failed\n"); + return NULL; + } + + struct CtxSessList *node = findNode(&g_listHead, index); + if (node == NULL) { + printf("[c] not found the target node\n"); + (void)pthread_mutex_unlock(&g_listLock); + return NULL; + } + + deleteNode(node); + + (void)pthread_mutex_unlock(&g_listLock); + return node; +} + +void CloseCtxAndSess(uint32_t index) +{ + struct CtxSessList *node = DeleteNodeList(index); + if (node == NULL) { + return; + } + + TEEC_CloseSession(&node->sess); + TEEC_FinalizeContext(&node->ctx); + free(node); +} + +int RegisterVirtualGuest(struct ra_buffer_data *container_info) { - uint32_t ret = TEEC_InitializeContext(NULL, ctx); + struct CtxSessList *node = mallocAddList(); + if (node == NULL) { + printf("[c] malloc context and session failed\n"); + return -1; + } + int ret = TEEC_InitializeContext(NULL, &node->ctx); if (ret) { printf("[c] init context failed, ret = %x\n", ret); - return ret; + ret = -1; + goto end; } + TEEC_Operation opt = {0}; opt.started = 1; opt.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); - ret = TEEC_OpenSession(ctx, sess, &g_qta_uuid, TEEC_LOGIN_IDENTIFY, NULL, &opt, NULL); + ret = TEEC_OpenSession(&node->ctx, &node->sess, &g_qtaUuid, TEEC_LOGIN_IDENTIFY, NULL, &opt, NULL); if (ret) { printf("[c] open session failed, ret = %x\n", ret); - TEEC_FinalizeContext(ctx); + ret = -1; + TEEC_FinalizeContext(&node->ctx); + goto end; } - return ret; -} - -uint32_t MallocCtxAndSess() + uint32_t origin = 0; + ret = RegisterContainer(container_info, &node->ctx, &node->sess, &origin); + if (ret) { + printf("[c] register virtual guest failed, ret = %x, origin = %x\n", ret, origin); + ret = -1; + TEEC_CloseSession(&node->sess); + TEEC_FinalizeContext(&node->ctx); + goto end; + } + return node->index; -void CloseSessAndCtx(TEEC_Context *ctx, TEEC_Session *sess) -{ - TEEC_CloseSession(sess); - TEEC_FinalizeContext(ctx); +end: + (void)DeleteNodeList(node->index); + free(node); + return ret; } */ import "C" @@ -60,6 +192,7 @@ import ( "unsafe" "github.com/docker/docker/client" + //libvirt "github.com/libvirt/libvirt-go" ) const ( @@ -69,8 +202,11 @@ const ( DOCKER_ID_LEN = 64 MAX_HEALTH_CHECK = 7 * 24 * 60 // 7 day - RET_SUCCESS = 0 - RET_CALLCERR = 1 + RET_SUCCESS = 0 + RET_CALLCERR = 1 + RET_SAVECLIENTERR = 2 + + QEMU_URI = "qemu:///system" ) var ( @@ -81,16 +217,11 @@ var ( ) type ( - ContRegistInfo struct { - Id string `json:"container_id"` + RegVirtGuestInfo struct { + Id string `json:"container_id"` // 兼容tee Nsid int `json:"nsid"` } - ClientInfo struct { - Id string `json:"id"` // docker and kvm return 64 bytes string - Type string `json:"type"` - } - ConnWrapMsg struct { Ret int `json:"ret"` Data string `json:"data,omitempty"` @@ -143,10 +274,10 @@ func CheckConnAlive(check int32) { if check <= 0 || check > MAX_HEALTH_CHECK { return } - ticker := time.NewTicker(check * time.Minute) + ticker := time.NewTicker(time.Duration(check) * time.Minute) for { select { - case <-done: + case <-Done: connMap.Range(func(id, conn interface{}) bool { conn.(net.Conn).Close() return true @@ -154,6 +285,7 @@ func CheckConnAlive(check int32) { return case <-ticker.C: + log.Println("Start connect health check....") connMap.Range(func(id, conn interface{}) bool { err := connCheck(conn.(net.Conn)) if err != nil { @@ -213,7 +345,8 @@ func getNsidByPid(pid int) (int, error) { match := ValidNsid.FindStringSubmatch(cont) if len(match) == 2 { - if nsid, err := strconv.Atoi(match[1]); err != nil { + nsid, err := strconv.Atoi(match[1]) + if err != nil { return -1, fmt.Errorf("convert to int failed, %v", err) } return nsid, nil @@ -222,10 +355,6 @@ func getNsidByPid(pid int) (int, error) { } func getDockerNsidById(id string) (int, error) { - if len(id) != DOCKER_ID_LEN { - return -1, fmt.Errorf("invalid docker container id") - } - cli, err := client.NewEnvClient() if err != nil { return -1, fmt.Errorf("create docker client failed, %v", err) @@ -246,6 +375,21 @@ func getDockerNsidById(id string) (int, error) { return getNsidByPid(conInfo.State.Pid) } +func getKvmNsidByUuid(uuid string) (int, error) { + return -1, fmt.Errorf("not impliment") +} + +func getVirtGuestNsidById(info *VirtualGuestInfo) (int, error) { + switch info.Type { + case "docker": + return getDockerNsidById(info.Id) + case "kvm": + return getKvmNsidByUuid(info.Id) + default: + return -1, fmt.Errorf("not support type") + } +} + func SendData(conn net.Conn, data interface{}, errno int) error { err := connCheck(conn) if err != nil { @@ -291,7 +435,9 @@ func RecvData(conn net.Conn, outData interface{}) error { return fmt.Errorf("message unmarshal failed, %v\n", err) } if data.Ret != 0 { - return fmt.Errorf("remote return err, %d\n", data.Ret) + var msg []byte + json.Unmarshal([]byte(data.Data), &msg) + return fmt.Errorf("remote return err, %d, %v\n", data.Ret, string(msg)) } if err = json.Unmarshal([]byte(data.Data), &outData); err != nil { @@ -301,7 +447,7 @@ func RecvData(conn net.Conn, outData interface{}) error { } func dealQcaDaemonClient(conn net.Conn) { - var cliInfo ClientInfo + var cliInfo VirtualGuestInfo err := RecvData(conn, &cliInfo) if err != nil { log.Printf("recv client regist info failed, %v\n", err) @@ -311,10 +457,12 @@ func dealQcaDaemonClient(conn net.Conn) { err = addConnClient(cliInfo.Id, conn) if err != nil { log.Printf("save conn to map failed, %v\n", err) + SendData(conn, []byte("save conn to map falied"), RET_SAVECLIENTERR) goto close } - log.Println("client register success\n") + SendData(conn, []byte("client register success"), RET_SUCCESS) + log.Println("qca_daemon client register success\n") return close: @@ -328,7 +476,7 @@ func StartQcaDaemonServer(saddr string) { } for { select { - case <-done: + case <-Done: return default: conn, err := listen.Accept() @@ -341,42 +489,59 @@ func StartQcaDaemonServer(saddr string) { } } -func dealDockerTAReq(id string, data []byte) ([]byte, error) { - id = strings.ToLower(id) - if len(id) != DOCKER_ID_LEN { - return nil, fmt.Errorf("docker ta request, docker id len invalid %v", len(id)) +func checkVirtGuestInfo(info *VirtualGuestInfo) error { + info.Id, info.Type = strings.ToLower(info.Id), strings.ToLower(info.Type) + // no container info input is valid + if info.Id == "" && info.Type == "" { + return nil + } + + if info.Id == "" || info.Type == "" { + return fmt.Errorf("id or type lacked") + } + switch info.Type { + case "docker": + if len(info.Id) != 64 { + return fmt.Errorf("invalid id length %d", len(info.Id)) + } + default: + return fmt.Errorf("not supported container type") + } + return nil +} + +func dealVirtualTAReq(info *VirtualGuestInfo, data []byte) ([]byte, error) { + + err := checkVirtGuestInfo(info) + if err != nil { + return nil, fmt.Errorf("invalid client info, %v", err) } - conn := findConnClient(id) + + conn := findConnClient(info.Id) if conn == nil { return nil, fmt.Errorf("can't find client") } - nsid, err := getDockerNsidById(id) + nsid, err := getVirtGuestNsidById(info) if err != nil { return nil, fmt.Errorf("get docker nsid failed, %v", err) } - info := &ContRegistInfo{ - Id: id, + reginfo := &RegVirtGuestInfo{ + Id: info.Id, Nsid: nsid, } - inparamjson, err := json.Marshal(info) + inparamjson, err := json.Marshal(reginfo) if err != nil { return nil, fmt.Errorf("encode docker regist json message error, %v", err) } - ctx := C.TEEC_Context{} - sess := C.TEEC_Session{} - ret := C.InitCtxAndOpenSess(&ctx, &sess) - if ret != 0 { - return nil, fmt.Errorf("Init tee context or open session failed %v", ret) - } - defer C.CloseSessAndCtx(&ctx, &sess) - - if err = callCRegisterContainer(inparamjson, &ctx, &sess); err != nil { + index, err := callCRegisterContainer(inparamjson) + if err != nil { return nil, err } + defer C.CloseCtxAndSess(C.__uint32_t(index)) if err = SendData(conn, data, RET_SUCCESS); err != nil { return nil, fmt.Errorf("forward req to qca_daemon failed, %v", err) @@ -388,20 +553,18 @@ func dealDockerTAReq(id string, data []byte) ([]byte, error) { return report, nil } -func callCRegisterContainer(js_input []byte, ctx *C.TEEC_Context, sess *C.TEEC_Session) error { +func callCRegisterContainer(js_input []byte) (int, error) { c_in := C.struct_ra_buffer_data{} c_in.size = C.__uint32_t(len(js_input)) up_c_in := C.CBytes(js_input) c_in.buf = (*C.uchar)(up_c_in) defer C.free(up_c_in) - c_ori := C.__uint32_t(0) - - ret := C.RegisterContainer(&c_in, ctx, sess, &c_ori) - if ret != 0 { - return fmt.Errorf("call libqca register container failed, ret %v, origin %v", ret, c_ori) + ret := C.RegisterVirtualGuest(&c_in) + if ret < 0 { + return -1, fmt.Errorf("call libqca register container failed, ret %v", ret) } - return nil + return int(ret), nil } func CallCRemoteAttest(js_input []byte, out_len uint32) ([]byte, error) { diff --git "a/doc/\345\256\271\345\231\250\345\206\205\350\277\234\347\250\213\350\257\201\346\230\216.md" "b/doc/\345\256\271\345\231\250\345\206\205\350\277\234\347\250\213\350\257\201\346\230\216.md" new file mode 100644 index 0000000..f5f989f --- /dev/null +++ "b/doc/\345\256\271\345\231\250\345\206\205\350\277\234\347\250\213\350\257\201\346\230\216.md" @@ -0,0 +1,86 @@ +## 整体流程 +相比于主机上的远程证明,容器内远程证明增加了容器内运行的qca_daemon, libqca_report, qta_report,新增组件在容器中运行,可获取且只能本容器内ta的远程证明。 +整体的细节如下: +1. 启动as server,用于在有as服务场景下,对tee派生的AK密钥做签名。 +2. 启动ra server, 指定模式,调用libqca/qta在tee内生成ak密钥,若有as场景下,连接as server完成密钥的签名,并保存到tee。 +3. 启动容器,并在容器内启动qca_daemon, 其会与ra server建立连接,并注册自己的容器id。 +4. ra client发起挑战,指定容器信息表明获取容器内ta的度量报告,ra server接收到请求后,识别请求中的容器信息,无则认为是主机ta,走原逻辑,是走如下逻辑: + > 1. 获取容器在主机上对应的pid和nsid(命名空间), + > 2. 调用libqca将容器id和nsid注册到qta中。 + > 3. 将请求转发到容器里的qca_daemon, + > 4. qca_daemon调用libqca_report调用qta-report获取度量报告,(qta_report会自动向主机的qta验证容器id和nsid) + > 5. 获取到度量报告后,转发给主机上的ra server. +5. ra server将度量报告返回给ra client. +6. ra client调用libteeverifier.so完成度量报告的验证。如果度量报告中有容器信息,则会自动验证容器信息和qta_report的度量值。 + + + +## 配置: +### ra_client: +在原基础上增加ta运行的容器的id和type,以及qta_report的基准度量 +1. yaml配置文件修改,如果未配置则默认ta运行在主机上 +```yaml +attesterconfig: + .... + virtualguest: + id: xxxxx(64) # 运行ta的目标容器id, 64位 + type: docker # 运行ta的目标容器type, 目前只支持docker +``` +也可在命令行中指定 +```shell +--id xxxx #指定容器id +--type xxx #指定容器类型 +``` +2. basevalue.txt文件修改 +```txt +..... +qta_report_uuid img_hash mem_hash +``` + +### ra_server +需要在命令行中指明是否支持容器,在原基础上增加用于监听容器请求的服务端的地址配置和容器socket连接的健康检查, +1. 命令行支持 +```shell +-V true # 支持虚拟化容器远程证明。 +-A xxxxx # 用于接收容器请求的socket地址 ip:port +-H 10 # socket连接健康检查周期,单位分钟 +``` +2. yaml配置文件 +```yaml +qcaconfig: + ... + virtual: + server: 0.0.0.0:90000 + healthcheck: 10 # minute, <0 no health check, max is 7 day +``` + +### qca_daemon +1. 支持命令行指定host侧监听服务端地址 +```shell +-H ip:port # 容器可填写docker0的ip地址 +``` + +## 使用 +基本方式同特性指南中主机上的远程证明。增加的配置按如上配置。 +0. 编译 +```shell +cd kunpengsecl +make clean;make build +cp attestation/tee/tverlib/verifier/libteeverifier.so /usr/lib64 +``` +1. 启动ra_server +```shell +cd attestation/tee/demo/qca_demon/cmd +cp ../../pkg/qcaserver /vendor/bin +/vendor/bin/qcaserver -C 0 -V true -A 0.0.0.0:9000 +``` +2. 启动容器内qca_daemon +```shell +cp attestation/tee/demo/pkg/qca_daemon /vendor/bin +/vendor/bin/qca_daemon -H 172.17.0.1:9000 +``` +3. ra_client发起挑战,配置好容器信息。 +```shell +cd attestation/tee/demo/attester_demo/cmd +go run main.go +``` -- Gitee From 6a3773f32c648bc7f8e1aea09346787aac7baac6 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Fri, 3 Nov 2023 17:19:22 +0800 Subject: [PATCH 7/8] support kvm virtual machine --- .../attestertools/attestertools.go | 34 +++++++++++++++++-- .../qca_daemon/daemontools/daemontools.go | 7 ++-- .../tee/demo/qca_demo/qcatools/qcatools.go | 28 ++++++++++++++- .../tee/demo/qca_demo/qcatools/qcautils.go | 33 +++++++++++++++--- 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/attestation/tee/demo/attester_demo/attestertools/attestertools.go b/attestation/tee/demo/attester_demo/attestertools/attestertools.go index 9750724..078f4db 100644 --- a/attestation/tee/demo/attester_demo/attestertools/attestertools.go +++ b/attestation/tee/demo/attester_demo/attestertools/attestertools.go @@ -26,6 +26,7 @@ import ( "context" "crypto/rand" "encoding/base64" + "encoding/hex" "fmt" "log" "os" @@ -251,6 +252,8 @@ func StartAttester() { log.Print("tee verify signature failed!") case -3: log.Print("tee verify hash failed!") + case -4: + log.Print("tee verify get other error!") } log.Print("Stop Attester......") @@ -270,6 +273,10 @@ func checkVirtGuestInfo(id, ctype string) error { if len(id) != 64 { return fmt.Errorf("invalid id length %d", len(id)) } + case "kvm": + if len(id) != 36 { + return fmt.Errorf("invalid uuid length %d", len(id)) + } default: return fmt.Errorf("not supported container type") } @@ -300,8 +307,8 @@ func iniTAParameter(ta *trustApp, m bool) (*trustApp, error) { if err != nil { return nil, err } - ta.VirtGuestId = attesterConf.VirtGuestId - ta.VirtGuestType = attesterConf.VirtGuestType + ta.VirtGuestId = strings.ToLower(attesterConf.VirtGuestId) + ta.VirtGuestType = strings.ToLower(attesterConf.VirtGuestType) return ta, nil } @@ -313,7 +320,7 @@ func getReport(ta *trustApp) []byte { } var info *qapi.GetReportRequest_VirtualGuestInfo - if ta.VirtGuestId != "" || ta.VirtGuestType != "" { + if ta.VirtGuestId != "" && ta.VirtGuestType != "" { info = &qapi.GetReportRequest_VirtualGuestInfo{ Id: ta.VirtGuestId, Type: ta.VirtGuestType, @@ -337,8 +344,29 @@ func getReport(ta *trustApp) []byte { return ta.report } +func adaptkvm(ta *trustApp) error { + if ta == nil || ta.VirtGuestType != "kvm" { + return nil + } + + // convert uuid to 64 id and type to docker + ta.VirtGuestType = "docker" + uuid, err := uuid.Parse(ta.VirtGuestId) + if err != nil { + return fmt.Errorf("uuid is invalid, %v", err) + } + + ta.VirtGuestId = hex.EncodeToString(uuid[:]) + return nil +} + // invoke verifier lib to verify func tee_verify(ta *trustApp, mtype int, bv string) int { + // in report, type is docker, id is 64id + if err := adaptkvm(ta); err != nil { + log.Printf("adapt kvm info failed, %v\n", err) + return -4 + } // construct C data_buf var crep C.buffer_data crepByte := C.CBytes(ta.report) diff --git a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go index 94a4652..149e90a 100644 --- a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go +++ b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go @@ -2,7 +2,6 @@ package daemontools import ( "bufio" - "encoding/hex" "fmt" "io" "log" @@ -76,19 +75,19 @@ func getSelfDockerId() (string, error) { return "", fmt.Errorf(NOT_DOCKER_CONTAINER) } -// get kvm id and convert to 64 string id +// get kvm id func getSelfKvmId() (string, error) { con, err := readFirstLine(DMI_PRODUCT_UUID) if err != nil { return "", fmt.Errorf("read kvm uuid failed, %v", err) } - uuid, err := uuid.Parse(con) + _, err := uuid.Parse(con) if err != nil { return "", fmt.Errorf("uuid is invalid, %v", err) } - return hex.EncodeToString(uuid[:]), nil + return con, nil } func GetVirtualClientInfo() (*qcatools.VirtualGuestInfo, error) { diff --git a/attestation/tee/demo/qca_demo/qcatools/qcatools.go b/attestation/tee/demo/qca_demo/qcatools/qcatools.go index 74f2fd5..374e485 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcatools.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcatools.go @@ -92,8 +92,10 @@ import "C" import ( "encoding/base64" + "encoding/hex" "encoding/json" "errors" + "fmt" "log" "os" "unsafe" @@ -368,6 +370,23 @@ func forwardReportReq(inparam []byte, out_len uint32, info *VirtualGuestInfo) ([ return report, nil } +func adaptkvm(info *VirtualGuestInfo) (*VirtualGuestInfo, error) { + if info == nil || info.Type != "kvm" { + return info, nil + } + + // convert uuid to 64 id and type to docker + var newInfo VirtualGuestInfo + newInfo.Type = "docker" + uuid, err := uuid.Parse(info.Id) + if err != nil { + return nil, fmt.Errorf("uuid is invalid, %v", err) + } + + newInfo.Id = hex.EncodeToString(uuid[:]) + return &newInfo, nil +} + // GetTAReport gets TA trusted report information. func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *VirtualGuestInfo) ([]byte, error) { n := base64.RawURLEncoding.EncodeToString(usr_data) @@ -377,6 +396,13 @@ func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *VirtualGu return nil, err } + // in tee, only docker type is supported, report_input adapt + newInfo, err := adaptkvm(info) + if err != nil { + log.Printf("adapt kvm info failed, %v\n", err) + return nil, err + } + // in parameters pl := reportInPl{ Version: RA_VERSION, @@ -385,7 +411,7 @@ func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *VirtualGu Hash_alg: RA_HASH_ALG_SHA256, With_tcb: with_tcb, // false Daa_bsn: nil, // line73 only support basename = NULL now - Info: info, + Info: newInfo, } inparam := reportInParam{ Handler: RAReportInHandler, diff --git a/attestation/tee/demo/qca_demo/qcatools/qcautils.go b/attestation/tee/demo/qca_demo/qcatools/qcautils.go index de59916..bdc4659 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcautils.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcautils.go @@ -182,6 +182,7 @@ import ( "log" "net" "os" + "os/exec" "regexp" "strconv" "strings" @@ -192,7 +193,6 @@ import ( "unsafe" "github.com/docker/docker/client" - //libvirt "github.com/libvirt/libvirt-go" ) const ( @@ -206,7 +206,7 @@ const ( RET_CALLCERR = 1 RET_SAVECLIENTERR = 2 - QEMU_URI = "qemu:///system" + GET_QEMU_PID_FMT = "ps aux | grep qemu.*%s | grep -v grep | awk '{print $2}'" ) var ( @@ -375,8 +375,23 @@ func getDockerNsidById(id string) (int, error) { return getNsidByPid(conInfo.State.Pid) } +/* kvm nsid same as host, so current solution is use qemu pid replace nsid */ func getKvmNsidByUuid(uuid string) (int, error) { - return -1, fmt.Errorf("not impliment") + queryCmd := fmt.Sprintf(GET_QEMU_PID_FMT, uuid) + cmd := exec.Command("bash", "-c", queryCmd) + out, err := cmd.CombinedOutput() + if err != nil { + return -1, fmt.Errorf("exec query cmd failed, %v", err) + } + if len(out) == 0 { + return -1, fmt.Errorf("query target qemu pid failed, %v", err) + } + + pid, err := strconv.Atoi(out) + if err != nil { + return -1, fmt.Errorf("convert to int failed, %v", err) + } + return pid, nil } func getVirtGuestNsidById(info *VirtualGuestInfo) (int, error) { @@ -504,6 +519,10 @@ func checkVirtGuestInfo(info *VirtualGuestInfo) error { if len(info.Id) != 64 { return fmt.Errorf("invalid id length %d", len(info.Id)) } + case "kvm": + if len(id) != 36 { + return fmt.Errorf("invalid uuid length %d", len(id)) + } default: return fmt.Errorf("not supported container type") } @@ -527,8 +546,14 @@ func dealVirtualTAReq(info *VirtualGuestInfo, data []byte) ([]byte, error) { return nil, fmt.Errorf("get docker nsid failed, %v", err) } + // register info in qta adapt kvm + newInfo, err := adaptkvm(info) + if err != nil { + return nil, fmt.Errorf("adapt kvm machine failed, %v", err) + } + reginfo := &RegVirtGuestInfo{ - Id: info.Id, + Id: newInfo.Id, Nsid: nsid, } -- Gitee From dd4854008da5beffe2f6ef4490b5dce9ebbd5f19 Mon Sep 17 00:00:00 2001 From: chen zheng Date: Fri, 3 Nov 2023 19:42:04 +0800 Subject: [PATCH 8/8] libqca/qta add delete interface --- .../attestertools/attestertools.go | 6 +- .../tee/demo/attester_demo/cmd/config.yaml | 6 +- .../qca_daemon/daemontools/daemontools.go | 54 ++--- .../tee/demo/qca_demo/qcatools/qcatools.go | 17 +- .../tee/demo/qca_demo/qcatools/qcautils.go | 57 +++-- ...0001-libqca-qta-add-delete-interface.patch | 221 ++++++++++++++++++ attestation/tee/tverlib/simulator/teeqca.c | 10 + attestation/tee/tverlib/simulator/teeqca.h | 2 + 8 files changed, 310 insertions(+), 63 deletions(-) create mode 100644 attestation/tee/tverlib/simulator/0001-libqca-qta-add-delete-interface.patch diff --git a/attestation/tee/demo/attester_demo/attestertools/attestertools.go b/attestation/tee/demo/attester_demo/attestertools/attestertools.go index 078f4db..6991214 100644 --- a/attestation/tee/demo/attester_demo/attestertools/attestertools.go +++ b/attestation/tee/demo/attester_demo/attestertools/attestertools.go @@ -334,6 +334,8 @@ func getReport(ta *trustApp) []byte { Info: info, } + log.Printf("Virtual guest info: %v\n", info) + rpyID, err := qapi.DoGetTeeReport(attesterConf.server, &reqID) if err != nil { log.Printf("Get TA infomation failed, error: %v", err) @@ -356,7 +358,9 @@ func adaptkvm(ta *trustApp) error { return fmt.Errorf("uuid is invalid, %v", err) } - ta.VirtGuestId = hex.EncodeToString(uuid[:]) + id16 := uuid[:] + id32 := append(id16, id16...) + ta.VirtGuestId = hex.EncodeToString(id32) return nil } diff --git a/attestation/tee/demo/attester_demo/cmd/config.yaml b/attestation/tee/demo/attester_demo/cmd/config.yaml index c34f703..5fa54ec 100644 --- a/attestation/tee/demo/attester_demo/cmd/config.yaml +++ b/attestation/tee/demo/attester_demo/cmd/config.yaml @@ -3,6 +3,6 @@ attesterconfig: basevalue: "./basevalue.txt" mspolicy: 2 uuid: 435dcafa-0029-4d53-97e8-a7a13a80c82e - virtualguest: - id: xxxxx(64) - type: docker + #virtualguest: # if test docker or virtual guest attest, add these config + # id: xxxxx(64) # if docker, id is 64 container id; or kvm, id is 36 uuid + # type: docker # current support docker and kvm diff --git a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go index 149e90a..72cbefa 100644 --- a/attestation/tee/demo/qca_daemon/daemontools/daemontools.go +++ b/attestation/tee/demo/qca_daemon/daemontools/daemontools.go @@ -1,13 +1,13 @@ package daemontools import ( - "bufio" "fmt" "io" "log" "net" "os" "regexp" + "strings" "gitee.com/openeuler/kunpengsecl/attestation/tee/demo/qca_demo/qcatools" "github.com/google/uuid" @@ -25,7 +25,7 @@ const ( ) var ( - ValidDockerId = regexp.MustCompile(`/docker/([a-z0-9]{64})`) + ValidDockerId = regexp.MustCompile(`1:name=systemd:/docker/([a-z0-9]{64})`) Info *log.Logger Error *log.Logger @@ -37,7 +37,7 @@ var ( func init() { logFile, err := os.OpenFile(LOG_FILE, os.O_CREATE|os.O_WRONLY, 0666) if err != nil { - log.Fatalf("open log file %v faild, %v", LOG_FILE, err) + log.Fatalf("Open log file %v faild, %v", LOG_FILE, err) } log.SetOutput(io.MultiWriter(logFile, os.Stdout)) @@ -48,23 +48,16 @@ func InitFlags() { pflag.Parse() } -func readFirstLine(file string) (string, error) { - f, err := os.Open(file) - if err != nil { - return "", fmt.Errorf("open %v failed, %v", file, err) - } - defer f.Close() - - rd := bufio.NewReader(f) - con, _, err := rd.ReadLine() +func readFile(file string) (string, error) { + content, err := os.ReadFile(file) if err != nil { return "", fmt.Errorf("read file failed, %v", err) } - return string(con), nil + return string(content), nil } func getSelfDockerId() (string, error) { - con, err := readFirstLine(SELF_CGROUP_FILE) + con, err := readFile(SELF_CGROUP_FILE) if err != nil { return "", err } @@ -77,24 +70,25 @@ func getSelfDockerId() (string, error) { // get kvm id func getSelfKvmId() (string, error) { - con, err := readFirstLine(DMI_PRODUCT_UUID) + uuidstr, err := readFile(DMI_PRODUCT_UUID) if err != nil { return "", fmt.Errorf("read kvm uuid failed, %v", err) } - - _, err := uuid.Parse(con) + uuidstr = strings.Trim(uuidstr, "\n ") + _, err = uuid.Parse(uuidstr) if err != nil { return "", fmt.Errorf("uuid is invalid, %v", err) } - return con, nil + return uuidstr, nil } func GetVirtualClientInfo() (*qcatools.VirtualGuestInfo, error) { - con, err := readFirstLine(DMI_PRODUCT_NAME) + con, err := readFile(DMI_PRODUCT_NAME) if err != nil { return nil, fmt.Errorf("read kvm name failed, %v", err) } + con = strings.Trim(con, "\n ") // kvm container if con == KVM_NAME { @@ -122,39 +116,41 @@ func GetVirtualClientInfo() (*qcatools.VirtualGuestInfo, error) { func StartClientConn(saddr string, info *qcatools.VirtualGuestInfo) { conn, err := net.Dial("tcp", saddr) if err != nil { - log.Fatalf("connect to server %v failed, %v\n", saddr, err) + log.Fatalf("Connect to server %v failed, %v\n", saddr, err) } defer conn.Close() - log.Printf("connect to server %v success\n", saddr) + log.Printf("Connect to server %v success\n", saddr) if err = qcatools.SendData(conn, info, qcatools.RET_SUCCESS); err != nil { - log.Fatalf("send register info to ra_server failed, %v", err) + log.Fatalf("Send register info to ra_server failed, %v", err) } var ret []byte if err = qcatools.RecvData(conn, &ret); err != nil { - log.Fatalf("read register reply failed, %v", err) + log.Fatalf("Read register reply failed, %v", err) } - log.Printf("register client info success\n") + log.Println("Register client info success\n") var retVal int for { reportIn := []byte{} if err = qcatools.RecvData(conn, &reportIn); err != nil { - log.Fatalf("read ra_server forward req data failed, %v", err) + log.Fatalf("Read ra_server forward request data failed, %v", err) } - log.Println("get host forward report request") + log.Println("Get host forward report request") retVal = qcatools.RET_SUCCESS report, err := qcatools.CallCRemoteAttest(reportIn, qcatools.MAX_OUTBUF_SIZE) if err != nil { - log.Printf("get report from libqca-report failed, %v", err) + log.Printf("Get report from libqca-report failed, %v", err) retVal = qcatools.RET_CALLCERR - report = []byte("get report by qta_report failed") + report = []byte("Get report by qta_report failed") + } else { + log.Println("Get TA report success") } if err = qcatools.SendData(conn, report, retVal); err != nil { - log.Fatalf("send register info to ra_server failed, %v", err) + log.Fatalf("Send register info to ra_server failed, %v", err) } } diff --git a/attestation/tee/demo/qca_demo/qcatools/qcatools.go b/attestation/tee/demo/qca_demo/qcatools/qcatools.go index 374e485..b2f8682 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcatools.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcatools.go @@ -356,17 +356,18 @@ func forwardReportReq(inparam []byte, out_len uint32, info *VirtualGuestInfo) ([ log.Printf("Get host ta report failed, %v", err) return nil, err } + log.Print("Get host TA report succeeded!") // virtual guest request default: - log.Println("Deal virtaul guest TA report request") + log.Printf("Deal virtaul guest TA report request, info: %v\n", info) report, err = dealVirtualTAReq(info, inparam) if err != nil { - log.Printf("Get docker ta report failed, %v", err) + log.Printf("Get virtual guest TA report failed, %v", err) return nil, err } + log.Print("Get virtual guest TA report succeeded!") } - log.Print("Generate TA report succeeded!") return report, nil } @@ -383,7 +384,9 @@ func adaptkvm(info *VirtualGuestInfo) (*VirtualGuestInfo, error) { return nil, fmt.Errorf("uuid is invalid, %v", err) } - newInfo.Id = hex.EncodeToString(uuid[:]) + id16 := uuid[:] + id32 := append(id16, id16...) + newInfo.Id = hex.EncodeToString(id32) return &newInfo, nil } @@ -392,14 +395,14 @@ func GetTAReport(ta_uuid []byte, usr_data []byte, with_tcb bool, info *VirtualGu n := base64.RawURLEncoding.EncodeToString(usr_data) id, err := uuid.FromBytes(ta_uuid) if err != nil { - log.Printf("wrong uuid in parameters, %v", err) + log.Printf("Wrong uuid in parameters, %v", err) return nil, err } - // in tee, only docker type is supported, report_input adapt + // in tee, only docker type is supported newInfo, err := adaptkvm(info) if err != nil { - log.Printf("adapt kvm info failed, %v\n", err) + log.Printf("Adapt kvm info failed, %v\n", err) return nil, err } diff --git a/attestation/tee/demo/qca_demo/qcatools/qcautils.go b/attestation/tee/demo/qca_demo/qcatools/qcautils.go index bdc4659..8711fc5 100644 --- a/attestation/tee/demo/qca_demo/qcatools/qcautils.go +++ b/attestation/tee/demo/qca_demo/qcatools/qcautils.go @@ -93,7 +93,7 @@ static struct CtxSessList *mallocAddList(void) return node; } -static struct CtxSessList *DeleteNodeList(uint32_t index) +static struct CtxSessList *deleteNodeList(uint32_t index) { if (!g_isInitList) { printf("[c] should use this after init\n"); @@ -117,13 +117,14 @@ static struct CtxSessList *DeleteNodeList(uint32_t index) return node; } -void CloseCtxAndSess(uint32_t index) +void CloseCtxAndSess(uint32_t index, char *id) { - struct CtxSessList *node = DeleteNodeList(index); + struct CtxSessList *node = deleteNodeList(index); if (node == NULL) { return; } + (void)UnRegisterContainerWithSess(id, &node->sess); TEEC_CloseSession(&node->sess); TEEC_FinalizeContext(&node->ctx); free(node); @@ -166,7 +167,7 @@ int RegisterVirtualGuest(struct ra_buffer_data *container_info) return node->index; end: - (void)DeleteNodeList(node->index); + (void)deleteNodeList(node->index); free(node); return ret; } @@ -268,6 +269,9 @@ func deleteConnClient(id string) { atomic.AddInt32(&curConnCnt, -1) connMap.Delete(id) conn.(net.Conn).Close() + cid := C.CString(id) + defer C.free(unsafe.Pointer(cid)) + C.UnRegisterContainer(cid) } func CheckConnAlive(check int32) { @@ -279,7 +283,7 @@ func CheckConnAlive(check int32) { select { case <-Done: connMap.Range(func(id, conn interface{}) bool { - conn.(net.Conn).Close() + deleteConnClient(id.(string)) return true }) return @@ -289,9 +293,8 @@ func CheckConnAlive(check int32) { connMap.Range(func(id, conn interface{}) bool { err := connCheck(conn.(net.Conn)) if err != nil { - atomic.AddInt32(&curConnCnt, -1) - connMap.Delete(id) - conn.(net.Conn).Close() + log.Printf("Close inactive connection %v\n", id) + deleteConnClient(id.(string)) } return true }) @@ -383,18 +386,20 @@ func getKvmNsidByUuid(uuid string) (int, error) { if err != nil { return -1, fmt.Errorf("exec query cmd failed, %v", err) } - if len(out) == 0 { + outstr := string(out) + outstr = strings.Trim(outstr, " \n") + if len(outstr) == 0 { return -1, fmt.Errorf("query target qemu pid failed, %v", err) } - pid, err := strconv.Atoi(out) + pid, err := strconv.Atoi(outstr) if err != nil { return -1, fmt.Errorf("convert to int failed, %v", err) } return pid, nil } -func getVirtGuestNsidById(info *VirtualGuestInfo) (int, error) { +func getVirtGuestNsidByInfo(info *VirtualGuestInfo) (int, error) { switch info.Type { case "docker": return getDockerNsidById(info.Id) @@ -465,19 +470,20 @@ func dealQcaDaemonClient(conn net.Conn) { var cliInfo VirtualGuestInfo err := RecvData(conn, &cliInfo) if err != nil { - log.Printf("recv client regist info failed, %v\n", err) + log.Printf("Recv client regist info failed, %v\n", err) goto close } + /* recive kvm id is 64 id */ err = addConnClient(cliInfo.Id, conn) if err != nil { - log.Printf("save conn to map failed, %v\n", err) + log.Printf("Save conn to map failed, %v\n", err) SendData(conn, []byte("save conn to map falied"), RET_SAVECLIENTERR) goto close } SendData(conn, []byte("client register success"), RET_SUCCESS) - log.Println("qca_daemon client register success\n") + log.Println("Regist qca_daemon client success\n") return close: @@ -487,8 +493,10 @@ close: func StartQcaDaemonServer(saddr string) { listen, err := net.Listen("tcp", saddr) if err != nil { - log.Fatalf("listen %v failed, %v", saddr, err) + log.Fatalf("Listen %v failed, %v", saddr, err) } + log.Printf("Start tcp server on %v\n", saddr) + for { select { case <-Done: @@ -496,7 +504,7 @@ func StartQcaDaemonServer(saddr string) { default: conn, err := listen.Accept() if err != nil { - log.Printf("accept failed, %v", err) + log.Printf("Accept failed, %v", err) continue } go dealQcaDaemonClient(conn) @@ -516,12 +524,12 @@ func checkVirtGuestInfo(info *VirtualGuestInfo) error { } switch info.Type { case "docker": - if len(info.Id) != 64 { + if len(info.Id) != DOCKER_ID_LEN { return fmt.Errorf("invalid id length %d", len(info.Id)) } case "kvm": - if len(id) != 36 { - return fmt.Errorf("invalid uuid length %d", len(id)) + if len(info.Id) != 36 { + return fmt.Errorf("invalid uuid length %d", len(info.Id)) } default: return fmt.Errorf("not supported container type") @@ -541,9 +549,9 @@ func dealVirtualTAReq(info *VirtualGuestInfo, data []byte) ([]byte, error) { return nil, fmt.Errorf("can't find client") } - nsid, err := getVirtGuestNsidById(info) + nsid, err := getVirtGuestNsidByInfo(info) if err != nil { - return nil, fmt.Errorf("get docker nsid failed, %v", err) + return nil, fmt.Errorf("get virtual guest nsid failed, %v", err) } // register info in qta adapt kvm @@ -559,14 +567,17 @@ func dealVirtualTAReq(info *VirtualGuestInfo, data []byte) ([]byte, error) { inparamjson, err := json.Marshal(reginfo) if err != nil { - return nil, fmt.Errorf("encode docker regist json message error, %v", err) + return nil, fmt.Errorf("encode containter register info error, %v", err) } index, err := callCRegisterContainer(inparamjson) if err != nil { return nil, err } - defer C.CloseCtxAndSess(C.__uint32_t(index)) + cid := C.CString(newInfo.Id) + /* defer exec order like stack */ + defer C.free(unsafe.Pointer(cid)) + defer C.CloseCtxAndSess(C.__uint32_t(index), cid) if err = SendData(conn, data, RET_SUCCESS); err != nil { return nil, fmt.Errorf("forward req to qca_daemon failed, %v", err) diff --git a/attestation/tee/tverlib/simulator/0001-libqca-qta-add-delete-interface.patch b/attestation/tee/tverlib/simulator/0001-libqca-qta-add-delete-interface.patch new file mode 100644 index 0000000..bf9f0e1 --- /dev/null +++ b/attestation/tee/tverlib/simulator/0001-libqca-qta-add-delete-interface.patch @@ -0,0 +1,221 @@ +From 978bb5d4f4032a3ebf302a10d31fbbef2a01c1c5 Mon Sep 17 00:00:00 2001 +From: chen zheng +Date: Fri, 3 Nov 2023 19:44:22 +0800 +Subject: [PATCH] libqca/qta add delete interface + +--- + test/CA/libqca/include/ra_client_api.h | 2 + + test/CA/libqca/src/ra_operate_api.c | 51 ++++++++++++++++++++++ + test/CA/libqca/src/ra_operate_api.h | 1 + + test/TA/qta/src/container/container_info.c | 28 ++++++++++++ + test/TA/qta/src/container/container_info.h | 1 + + test/TA/qta/src/container/dlist.h | 11 +++++ + test/TA/qta/src/tee_qta.c | 19 ++++++++ + test/TA/qta/src/tee_qta.h | 1 + + 8 files changed, 114 insertions(+) + +diff --git a/test/CA/libqca/include/ra_client_api.h b/test/CA/libqca/include/ra_client_api.h +index afa9e07..4e2e135 100644 +--- a/test/CA/libqca/include/ra_client_api.h ++++ b/test/CA/libqca/include/ra_client_api.h +@@ -22,6 +22,8 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *in, struct ra_buffer_data *out); + #ifdef HOST_QCA + TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Context *context, + TEEC_Session *session, uint32_t *origin); ++TEEC_Result UnRegisterContainer(char *id); ++TEEC_Result UnRegisterContainerWithSess(char *id, TEEC_Session *session); + #endif + + #endif +diff --git a/test/CA/libqca/src/ra_operate_api.c b/test/CA/libqca/src/ra_operate_api.c +index fea5142..4b09c8f 100644 +--- a/test/CA/libqca/src/ra_operate_api.c ++++ b/test/CA/libqca/src/ra_operate_api.c +@@ -201,4 +201,55 @@ TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Contex + } + return container_info_ops(container_info, REGISTER_CONTAINER_CMD, context, session, origin); + } ++ ++TEEC_Result UnRegisterContainerWithSess(char *id, TEEC_Session *session) ++{ ++ if (id == NULL || strlen(id) == 0 || session == NULL) { ++ tloge("invalid input\n"); ++ return TEEC_ERROR_BAD_PARAMETERS; ++ } ++ ++ TEEC_Operation operation = {0}; ++ uint32_t origin; ++ ++ operation.started = 1; ++ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); ++ operation.params[0].tmpref.buffer = id; ++ operation.params[0].tmpref.size = strlen(id); ++ ++ TEEC_Result result = TEEC_InvokeCommand(session, UNREGISTER_CONTAINER_CMD, &operation, &origin); ++ if (result != TEEC_SUCCESS) { ++ tloge("invoke command failed, result = 0x%x\n", result); ++ } ++ return result; ++} ++ ++TEEC_Result UnRegisterContainer(char *id) ++{ ++ TEEC_Context context = {0}; ++ TEEC_Session session = {0}; ++ TEEC_Operation operation = {0}; ++ TEEC_UUID uuid = g_tee_qta_uuid; ++ ++ TEEC_Result result = TEEC_InitializeContext(NULL, &context); ++ if (result != TEEC_SUCCESS) { ++ tloge("init context is failed, result is 0x%x\n", result); ++ return result; ++ } ++ ++ operation.started = 1; ++ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); ++ result = TEEC_OpenSession(&context, &session, &uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, NULL); ++ if (result != TEEC_SUCCESS) { ++ tloge("open session is failed, result is 0x%x\n", result); ++ goto cleanup_1; ++ } ++ ++ result = UnRegisterContainerWithSess(id, &session); ++ ++ TEEC_CloseSession(&session); ++cleanup_1: ++ TEEC_FinalizeContext(&context); ++ return result; ++} + #endif +diff --git a/test/CA/libqca/src/ra_operate_api.h b/test/CA/libqca/src/ra_operate_api.h +index 4925409..cdf740a 100644 +--- a/test/CA/libqca/src/ra_operate_api.h ++++ b/test/CA/libqca/src/ra_operate_api.h +@@ -22,6 +22,7 @@ + #define REMOTE_ATTEST_CMD (0x1001) + #ifdef HOST_QCA + #define REGISTER_CONTAINER_CMD (0x1002) ++#define UNREGISTER_CONTAINER_CMD (0x1004) + #endif + + #endif +diff --git a/test/TA/qta/src/container/container_info.c b/test/TA/qta/src/container/container_info.c +index 0e602ed..8aed3b5 100644 +--- a/test/TA/qta/src/container/container_info.c ++++ b/test/TA/qta/src/container/container_info.c +@@ -119,3 +119,31 @@ end: + (void)pthread_mutex_unlock(&g_container_list_mutex); + return ret; + } ++ ++TEE_Result unregister_container(char container_id[]) ++{ ++ /* default success, because qta may be unloaded. */ ++ TEE_Result ret = TEE_SUCCESS; ++ ++ if (!g_container_list_init) { ++ return ret; ++ } ++ ++ if (pthread_mutex_lock(&g_container_list_mutex) != 0) { ++ tloge("lock container list failed\n"); ++ return TEE_ERROR_GENERIC; ++ } ++ ++ /* if already registered, update nsid */ ++ struct container_info *info_node = NULL; ++ dlist_for_each_entry(info_node, &g_container_list, struct container_info, list) { ++ if (strcmp(info_node->container_id, container_id) == 0) { ++ dlist_delete(&info_node->list); ++ free(info_node); ++ break; ++ } ++ } ++ ++ (void)pthread_mutex_unlock(&g_container_list_mutex); ++ return ret; ++} +diff --git a/test/TA/qta/src/container/container_info.h b/test/TA/qta/src/container/container_info.h +index 7955e41..7faf99a 100644 +--- a/test/TA/qta/src/container/container_info.h ++++ b/test/TA/qta/src/container/container_info.h +@@ -19,4 +19,5 @@ + TEE_Result init_container_list(void); + TEE_Result get_nsid_by_container_id(char container_id[], uint32_t *nsid); + TEE_Result register_container(char container_id[], uint32_t nsid); ++TEE_Result unregister_container(char container_id[]); + #endif +diff --git a/test/TA/qta/src/container/dlist.h b/test/TA/qta/src/container/dlist.h +index 0c129eb..557abcd 100644 +--- a/test/TA/qta/src/container/dlist.h ++++ b/test/TA/qta/src/container/dlist.h +@@ -66,6 +66,17 @@ static inline void dlist_insert_head(struct dlist_node *node, struct dlist_node + dlist_insert(head, node); + } + ++static inline void dlist_delete(struct dlist_node *node) ++{ ++ struct dlist_node *tmp = NULL; ++ ++ tmp = node->prev; ++ tmp->next = node->next; ++ tmp = node->next; ++ tmp->prev = node->prev; ++ dlist_init(node); ++} ++ + /* get the address of the containing struct */ + #define dlist_entry(ptr, type, member) container_of(ptr, type, member) + +diff --git a/test/TA/qta/src/tee_qta.c b/test/TA/qta/src/tee_qta.c +index d84a5ba..fd875f5 100644 +--- a/test/TA/qta/src/tee_qta.c ++++ b/test/TA/qta/src/tee_qta.c +@@ -456,6 +456,22 @@ clean: + tloge("qta container info: handle cmd 0x%x failed\n", cmd_id); + return ret; + } ++ ++static TEE_Result handle_unregister_container(uint32_t param_types, TEE_Param *params) ++{ ++ bool check = check_param_type(param_types, TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); ++ if (!check || params == NULL) { ++ tloge("qta container info: check param type failed\n"); ++ return TEE_ERROR_BAD_PARAMETERS; ++ } ++ if (params[0].memref.buffer == NULL || params[0].memref.size == 0) { ++ tloge("qta container info: input param invalid\n"); ++ return TEE_ERROR_BAD_PARAMETERS; ++ } ++ char *id = params[0].memref.buffer; ++ return unregister_container(id); ++} + #endif + + static TEE_Result handle_remote_attest(uint32_t cmd_id, uint32_t param_types, TEE_Param *params) +@@ -495,6 +511,9 @@ TEE_Result TA_InvokeCommandEntryPoint(void *session_context, uint32_t cmd_id, + ret = handle_remote_attest(cmd_id, param_types, params); + break; + #ifdef CONFIG_HOST_QTA ++ case UNREGISTER_CONTAINER_CMD: ++ ret = handle_unregister_container(param_types, params); ++ break; + case REGISTER_CONTAINER_CMD: + ret = handle_container_info(cmd_id, param_types, params); + break; +diff --git a/test/TA/qta/src/tee_qta.h b/test/TA/qta/src/tee_qta.h +index 4246254..cc22090 100644 +--- a/test/TA/qta/src/tee_qta.h ++++ b/test/TA/qta/src/tee_qta.h +@@ -23,6 +23,7 @@ + #define REMOTE_ATTEST_CMD 0x1001 + #ifdef CONFIG_HOST_QTA + #define REGISTER_CONTAINER_CMD 0x1002 ++#define UNREGISTER_CONTAINER_CMD 0x1004 + #endif + #if defined(CONFIG_HOST_QTA) || defined(CONFIG_QTA_REPORT) + #define VERIFY_CONTAINER_CMD 0x1003 +-- +2.42.0.windows.2 + diff --git a/attestation/tee/tverlib/simulator/teeqca.c b/attestation/tee/tverlib/simulator/teeqca.c index 35c29db..c3f3948 100644 --- a/attestation/tee/tverlib/simulator/teeqca.c +++ b/attestation/tee/tverlib/simulator/teeqca.c @@ -284,6 +284,16 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *o TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Context *context, TEEC_Session *session, uint32_t *origin) +{ + return 0; +} + +TEEC_Result UnRegisterContainer(char *id) +{ + return 0; +} + +TEEC_Result UnRegisterContainerWithSess(char *id, TEEC_Session *session) { return 0; } \ No newline at end of file diff --git a/attestation/tee/tverlib/simulator/teeqca.h b/attestation/tee/tverlib/simulator/teeqca.h index b901991..896ec82 100644 --- a/attestation/tee/tverlib/simulator/teeqca.h +++ b/attestation/tee/tverlib/simulator/teeqca.h @@ -99,4 +99,6 @@ TEEC_Result RemoteAttest(struct ra_buffer_data *params, struct ra_buffer_data *o TEEC_Result RegisterContainer(struct ra_buffer_data *container_info, TEEC_Context *context, TEEC_Session *session, uint32_t *origin); +TEEC_Result UnRegisterContainer(char *id); +TEEC_Result UnRegisterContainerWithSess(char *id, TEEC_Session *session); #endif -- Gitee