From 344228a540ab3b1396849d8608872a880871be8c Mon Sep 17 00:00:00 2001 From: Ariel Mendelzon Date: Tue, 3 Dec 2024 02:08:27 +1300 Subject: [PATCH] SGX endorsement and platform library (#225) - Added endorsement initialisation and finalisation functions for SGX - Added system finalisation ecall, used within the untrusted code's finalisation routine - Removed old stubs for SGX's HAL platform and endorsement - Added der_utils library to aid with endorsement signature encoding - Implemented SGX endorsement library - Implemented SGX platform library - Adjusting sync acquire lock's function to account for different return types - Removed now unused hmac_sha256 library from SGX's HAL - Added SGX's HAL der_utils and endorsement unit tests --- firmware/src/hal/include/hal/endorsement.h | 16 +- firmware/src/hal/sgx/src/trusted/der_utils.c | 62 +++ firmware/src/hal/sgx/src/trusted/der_utils.h | 28 + .../src/hal/sgx/src/trusted/endorsement.c | 352 +++++++++---- .../src/hal/sgx/src/trusted/hmac_sha256.c | 1 - .../src/hal/sgx/src/trusted/hmac_sha256.h | 1 - firmware/src/hal/sgx/src/trusted/platform.c | 49 +- firmware/src/hal/sgx/test/der_utils/Makefile | 39 ++ .../hal/sgx/test/der_utils/test_der_utils.c | 148 ++++++ .../src/hal/sgx/test/endorsement/Makefile | 39 ++ firmware/src/hal/sgx/test/endorsement/mocks.c | 137 +++++ firmware/src/hal/sgx/test/endorsement/mocks.h | 482 ++++++++++++++++++ .../sgx/test/endorsement/test_endorsement.c | 299 +++++++++++ .../mock/openenclave/attestation/attester.h | 1 + .../openenclave/attestation/sgx/evidence.h | 1 + .../mock/openenclave/attestation/verifier.h | 1 + .../test/mock/openenclave/bits/attestation.h | 1 + .../hal/sgx/test/mock/openenclave/bits/defs.h | 1 + .../test/mock/openenclave/bits/sgx/sgxtypes.h | 1 + .../hal/sgx/test/mock/openenclave/common.h | 211 +++++++- firmware/src/hal/sgx/test/run-all.sh | 2 +- firmware/src/sgx/src/hsm.edl | 2 + firmware/src/sgx/src/trusted/ecall.c | 10 +- firmware/src/sgx/src/trusted/ecall.h | 5 + firmware/src/sgx/src/trusted/sync.h | 4 +- firmware/src/sgx/src/trusted/system.c | 5 + firmware/src/sgx/src/trusted/system.h | 5 + .../src/sgx/src/untrusted/enclave_proxy.c | 15 + .../src/sgx/src/untrusted/enclave_proxy.h | 5 + firmware/src/sgx/src/untrusted/main.c | 2 +- firmware/src/sgx/test/system/test_system.c | 4 + 31 files changed, 1815 insertions(+), 114 deletions(-) create mode 100644 firmware/src/hal/sgx/src/trusted/der_utils.c create mode 100644 firmware/src/hal/sgx/src/trusted/der_utils.h delete mode 120000 firmware/src/hal/sgx/src/trusted/hmac_sha256.c delete mode 120000 firmware/src/hal/sgx/src/trusted/hmac_sha256.h mode change 120000 => 100644 firmware/src/hal/sgx/src/trusted/platform.c create mode 100644 firmware/src/hal/sgx/test/der_utils/Makefile create mode 100644 firmware/src/hal/sgx/test/der_utils/test_der_utils.c create mode 100644 firmware/src/hal/sgx/test/endorsement/Makefile create mode 100644 firmware/src/hal/sgx/test/endorsement/mocks.c create mode 100644 firmware/src/hal/sgx/test/endorsement/mocks.h create mode 100644 firmware/src/hal/sgx/test/endorsement/test_endorsement.c create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/attestation/attester.h create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/attestation/sgx/evidence.h create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/attestation/verifier.h create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/bits/attestation.h create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/bits/defs.h create mode 120000 firmware/src/hal/sgx/test/mock/openenclave/bits/sgx/sgxtypes.h diff --git a/firmware/src/hal/include/hal/endorsement.h b/firmware/src/hal/include/hal/endorsement.h index 1e508e55..fbaa8adf 100644 --- a/firmware/src/hal/include/hal/endorsement.h +++ b/firmware/src/hal/include/hal/endorsement.h @@ -115,7 +115,7 @@ extern attestation_id_t attestation_id; */ bool endorsement_init(char* att_file_path); -#elif defined(HSM_PLATFORM_SGX) || defined(HSM_PLATFORM_LEDGER) +#elif defined(HSM_PLATFORM_LEDGER) /** * @brief Initializes the endorsement module @@ -124,6 +124,20 @@ bool endorsement_init(char* att_file_path); */ bool endorsement_init(); +#elif defined(HSM_PLATFORM_SGX) + +/** + * @brief Initializes the endorsement module + * + * @returns whether the initialisation succeeded + */ +bool endorsement_init(); + +/** + * @brief Finalises the endorsement module + */ +void endorsement_finalise(); + #endif // END of platform-dependent code diff --git a/firmware/src/hal/sgx/src/trusted/der_utils.c b/firmware/src/hal/sgx/src/trusted/der_utils.c new file mode 100644 index 00000000..f6841dfc --- /dev/null +++ b/firmware/src/hal/sgx/src/trusted/der_utils.c @@ -0,0 +1,62 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "der_utils.h" +#include +#include +#include + +// Helper function to encode a len-byte unsigned integer (R or S) in DER format +static size_t der_encode_uint(uint8_t* dest, uint8_t* src, size_t len) { + // Check if we need a leading zero byte + bool lz = src[0] & 0x80; + // Start of source: remove leading zeroes + size_t trim = 0; + while (!src[trim] && trim < (len - 1)) + trim++; + // Output + size_t off = 0; + dest[off++] = 0x02; // Integer tag + dest[off++] = len - trim + (lz ? 1 : 0); // Length byte + if (lz) + dest[off++] = 0x00; // Leading zero + memcpy(dest + off, src + trim, len - trim); // Actual integer + return (size_t)dest[1] + 2; +} + +uint8_t der_encode_signature(uint8_t* dest, sgx_ecdsa256_signature_t* sig) { + uint8_t r_encoded[sizeof(sig->r) + 2], + s_encoded[sizeof(sig->s) + 2]; // Temporary buffers for R and S + uint8_t r_len = (uint8_t)der_encode_uint(r_encoded, sig->r, sizeof(sig->r)); + uint8_t s_len = (uint8_t)der_encode_uint(s_encoded, sig->s, sizeof(sig->s)); + + // Start the sequence + dest[0] = 0x30; // Sequence tag + dest[1] = r_len + s_len; // Length of the sequence + memcpy(dest + 2, r_encoded, r_len); // Copy encoded R + memcpy(dest + 2 + r_len, s_encoded, s_len); // Copy encoded S + + // Return total length of DER encoded signature + return (uint8_t)(2 + r_len + s_len); +} diff --git a/firmware/src/hal/sgx/src/trusted/der_utils.h b/firmware/src/hal/sgx/src/trusted/der_utils.h new file mode 100644 index 00000000..9f30aaff --- /dev/null +++ b/firmware/src/hal/sgx/src/trusted/der_utils.h @@ -0,0 +1,28 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +uint8_t der_encode_signature(uint8_t* dest, sgx_ecdsa256_signature_t* sig); \ No newline at end of file diff --git a/firmware/src/hal/sgx/src/trusted/endorsement.c b/firmware/src/hal/sgx/src/trusted/endorsement.c index 2fd21e99..c5f4dc45 100644 --- a/firmware/src/hal/sgx/src/trusted/endorsement.c +++ b/firmware/src/hal/sgx/src/trusted/endorsement.c @@ -22,169 +22,315 @@ * IN THE SOFTWARE. */ -#include -#include -#include -// TODO: remove usage of secp256k1 here upon final implementation -// (only needed here for mock implementation) -#include - #include "hal/constants.h" #include "hal/endorsement.h" -#include "hal/seed.h" #include "hal/exceptions.h" #include "hal/log.h" +#include "der_utils.h" -#include "random.h" - -// TODO: remove HMAC-SHA256 entirely upon final implementation, -// (only needed for mock implementation) -#include "hmac_sha256.h" - -static secp256k1_context* sp_ctx = NULL; - -// Test key for mock implementation -static const uint8_t attestation_key[] = { - 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, - 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, - 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, -}; -// Test code hash for mock implementation -static const uint8_t attestation_code_hash[] = { - 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, -}; -static uint8_t attestation_pubkey[PUBKEY_UNCMP_LENGTH]; - -static size_t tweak_sign(const unsigned char* key, - const unsigned char* tweak, - const unsigned char* hash, - unsigned char* sig) { - unsigned char tweaked_key[PRIVATE_KEY_LENGTH]; - secp256k1_ecdsa_signature sp_sig; - size_t sig_serialized_size = MAX_SIGNATURE_LENGTH; - - // Tweak private key - memmove(tweaked_key, key, sizeof(tweaked_key)); - if (!secp256k1_ec_seckey_tweak_add(sp_ctx, tweaked_key, tweak)) - return 0; +#include - // Sign and serialize as DER - secp256k1_ecdsa_sign(sp_ctx, &sp_sig, hash, tweaked_key, NULL, NULL); - secp256k1_ecdsa_signature_serialize_der( - sp_ctx, sig, &sig_serialized_size, &sp_sig); +#include +#include +#include +#include +#include +#include + +#define RAW_ENVELOPE_BUFFER_SIZE (10 * 1024) + +static struct { + bool initialised; + // The format ID used for attestation. + // See openenclave/attestation/sgx/evidence.h for supported formats. + oe_uuid_t format_id; + // The format settings buffer for the selected format. + // This is returned by oe_verifier_get_format_settings. + uint8_t* format_settings; + // The size of the format settings buffer. + size_t format_settings_size; + // Current envelope + struct { + uint8_t raw[RAW_ENVELOPE_BUFFER_SIZE]; + size_t raw_size; + sgx_quote_t* quote; + sgx_quote_auth_data_t* quote_auth_data; + sgx_qe_auth_data_t qe_auth_data; + sgx_qe_cert_data_t qe_cert_data; + } envelope; +} G_endorsement_ctx; + +#define ENDORSEMENT_FORMAT OE_FORMAT_UUID_SGX_ECDSA + +#define ENDORSEMENT_CHECK(oe_result, error_msg) \ + { \ + if (OE_OK != oe_result) { \ + LOG(error_msg); \ + LOG(": result=%u (%s)\n", result, oe_result_str(oe_result)); \ + return false; \ + } \ + } - return (int)sig_serialized_size; +// Taken from OpenEnclave's common/sgx/quote.c +OE_INLINE uint16_t ReadUint16(const uint8_t* p) { + return (uint16_t)(p[0] | (p[1] << 8)); } -static uint8_t derive_pubkey_uncmp(const unsigned char* key, - unsigned char* dest) { - secp256k1_pubkey pubkey; - size_t dest_size = PUBKEY_UNCMP_LENGTH; +// Taken from OpenEnclave's common/sgx/quote.c +OE_INLINE uint32_t ReadUint32(const uint8_t* p) { + return (uint32_t)(p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); +} - // Calculate the public key and serialize it according to - // the compressed argument - if (!secp256k1_ec_pubkey_create(sp_ctx, &pubkey, key)) { - return 0; +// Generates an envelop with the provided message as a custom claim. +static bool generate_envelope(uint8_t* msg, size_t msg_size) { + if (!G_endorsement_ctx.initialised) { + LOG("Endorsement module has not been initialised\n"); + return false; } - secp256k1_ec_pubkey_serialize( - sp_ctx, dest, &dest_size, &pubkey, SECP256K1_EC_UNCOMPRESSED); + oe_result_t result = OE_FAILURE; + uint8_t* evidence_buffer = NULL; + size_t evidence_buffer_size = 0; + result = oe_get_evidence(&G_endorsement_ctx.format_id, + 0, + msg, + msg_size, + G_endorsement_ctx.format_settings, + G_endorsement_ctx.format_settings_size, + &evidence_buffer, + &evidence_buffer_size, + NULL, + NULL); + ENDORSEMENT_CHECK(result, "Envelope generation failed"); + if (evidence_buffer_size > sizeof(G_endorsement_ctx.envelope.raw)) { + LOG("Envelope generation failed: buffer needs %lu bytes but " + "only %ld available\n", + evidence_buffer_size, + sizeof(G_endorsement_ctx.envelope.raw)); + oe_free_evidence(evidence_buffer); + return false; + } - return (uint8_t)dest_size; + memcpy( + G_endorsement_ctx.envelope.raw, evidence_buffer, evidence_buffer_size); + G_endorsement_ctx.envelope.raw_size = evidence_buffer_size; + oe_free_evidence(evidence_buffer); + + return true; } -bool endorsement_init() { - // Init the secp256k1 context - if (!sp_ctx) - sp_ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - - // Compute attestation public key - if (derive_pubkey_uncmp(attestation_key, attestation_pubkey) != - PUBKEY_UNCMP_LENGTH) { - LOG("Error getting uncompressed public key for mock attestation key\n"); +// Based on OpenEnclave's common/sgx/quote.c::_parse_quote() +// No validation is performed. Left to the end user. +// Maybe we could do some minimal validation in the future. +static bool parse_envelope(uint8_t* msg, size_t msg_size) { + const uint8_t* p = G_endorsement_ctx.envelope.raw; + const uint8_t* const quote_end = p + G_endorsement_ctx.envelope.raw_size; + sgx_quote_t* _sgx_quote = (sgx_quote_t*)p; + G_endorsement_ctx.envelope.quote = _sgx_quote; + + if (quote_end < p) { + LOG("SGX quote parsing error. Pointer wrapper around\n"); + return false; + } + + p += sizeof(sgx_quote_t); + + if (p > quote_end) { + LOG("Parse error after parsing SGX quote, before signature\n"); + return false; + } + if (p + _sgx_quote->signature_len + msg_size != quote_end) { + LOG("Parse error after parsing SGX signature\n"); + return false; + } + + G_endorsement_ctx.envelope.quote_auth_data = (sgx_quote_auth_data_t*)p; + + p += sizeof(sgx_quote_auth_data_t); + + sgx_qe_auth_data_t* qe_auth_data = &G_endorsement_ctx.envelope.qe_auth_data; + qe_auth_data->size = ReadUint16(p); + p += 2; + qe_auth_data->data = (uint8_t*)p; + p += qe_auth_data->size; + + if (p > quote_end) { + LOG("Parse error after parsing QE authorization data\n"); + return false; + } + + sgx_qe_cert_data_t* qe_cert_data = &G_endorsement_ctx.envelope.qe_cert_data; + qe_cert_data->type = ReadUint16(p); + p += 2; + qe_cert_data->size = ReadUint32(p); + p += 4; + qe_cert_data->data = (uint8_t*)p; + p += qe_cert_data->size; + + if (memcmp(p, msg, msg_size)) { + LOG("Parse error: got inconsistent custom message\n"); + return false; + } + + p += msg_size; + + if (p != quote_end) { + LOG("Unexpected quote length while parsing\n"); return false; } - LOG("Loaded mock attestation key:\n"); - LOG_HEX("\tKey: ", attestation_key, sizeof(attestation_key)); - LOG_HEX("\tPublic key: ", attestation_pubkey, sizeof(attestation_pubkey)); return true; } -// TODO: Implement -uint8_t* endorsement_get_envelope() { - return NULL; +// ****************************************************** // +// ********** Public interface implemenetation ********** // +// ****************************************************** // + +bool endorsement_init() { + oe_result_t result = OE_FAILURE; + + explicit_bzero(&G_endorsement_ctx, sizeof(G_endorsement_ctx)); + + // Initialize modules + result = oe_attester_initialize(); + ENDORSEMENT_CHECK(result, "Failed to initialize attester"); + result = oe_verifier_initialize(); + ENDORSEMENT_CHECK(result, "Failed to initialize verifier"); + + // Make sure the desired format is supported and + // get the corresponding settings + const oe_uuid_t format_id = {ENDORSEMENT_FORMAT}; + result = + oe_attester_select_format(&format_id, 1, &G_endorsement_ctx.format_id); + ENDORSEMENT_CHECK(result, "Failed to select attestation format"); + + result = oe_verifier_get_format_settings( + &G_endorsement_ctx.format_id, + &G_endorsement_ctx.format_settings, + &G_endorsement_ctx.format_settings_size); + ENDORSEMENT_CHECK(result, "Format is not supported by verifier"); + + G_endorsement_ctx.initialised = true; + LOG("Attestation module initialized\n"); + return true; } -// TODO: Implement -size_t endorsement_get_envelope_length() { - return 0; +void endorsement_finalise() { + oe_verifier_shutdown(); + oe_attester_shutdown(); } bool endorsement_sign(uint8_t* msg, size_t msg_size, uint8_t* signature_out, uint8_t* signature_out_length) { - - uint8_t tweak[HMAC_SHA256_SIZE]; - uint8_t hash[HASH_LENGTH]; - if (*signature_out_length < MAX_SIGNATURE_LENGTH) { - return false; + LOG("Output buffer for signature too small: %u bytes\n", + *signature_out_length); + goto endorsement_sign_fail; } - sha256(msg, msg_size, hash, sizeof(hash)); - - if (hmac_sha256(attestation_code_hash, - sizeof(attestation_code_hash), - attestation_pubkey, - sizeof(attestation_pubkey), - tweak, - sizeof(tweak)) != sizeof(tweak)) { - LOG("Error computing tweak for endorsement\n"); - return false; + if (!generate_envelope(msg, msg_size)) { + LOG("Error generating envelope\n"); + goto endorsement_sign_fail; } - if (*signature_out_length < MAX_SIGNATURE_LENGTH) { - LOG("Output buffer for signature too small: %u bytes\n", - *signature_out_length); - return false; + if (!parse_envelope(msg, msg_size)) { + LOG("Error parsing envelope\n"); + goto endorsement_sign_fail; } - *signature_out_length = - tweak_sign(attestation_key, tweak, hash, signature_out); + // Output signature in DER format + sgx_ecdsa256_signature_t* sig = + &G_endorsement_ctx.envelope.quote_auth_data->signature; + *signature_out_length = der_encode_signature(signature_out, sig); return true; + +endorsement_sign_fail: + explicit_bzero(&G_endorsement_ctx.envelope, + sizeof(G_endorsement_ctx.envelope)); + return false; +} + +uint8_t* endorsement_get_envelope() { + if (G_endorsement_ctx.envelope.raw_size == 0) { + return 0; + } + return G_endorsement_ctx.envelope.raw; +} + +size_t endorsement_get_envelope_length() { + return G_endorsement_ctx.envelope.raw_size; } bool endorsement_get_code_hash(uint8_t* code_hash_out, uint8_t* code_hash_out_length) { + if (G_endorsement_ctx.envelope.raw_size == 0) { + LOG("No envelope available\n"); + return false; + } + + if (code_hash_out == NULL) { + LOG("Output buffer is NULL\n"); + return false; + } + if (*code_hash_out_length < HASH_LENGTH) { LOG("Output buffer for code hash too small: %u bytes\n", *code_hash_out_length); return false; } - memmove( - code_hash_out, attestation_code_hash, sizeof(attestation_code_hash)); - *code_hash_out_length = sizeof(attestation_code_hash); + memcpy(code_hash_out, + G_endorsement_ctx.envelope.quote->report_body.mrenclave, + sizeof(G_endorsement_ctx.envelope.quote->report_body.mrenclave)); + *code_hash_out_length = + sizeof(G_endorsement_ctx.envelope.quote->report_body.mrenclave); return true; } bool endorsement_get_public_key(uint8_t* public_key_out, uint8_t* public_key_out_length) { + if (G_endorsement_ctx.envelope.raw_size == 0) { + LOG("No envelope available\n"); + return false; + } + + if (public_key_out == NULL) { + LOG("Output buffer is NULL\n"); + return false; + } + if (*public_key_out_length < PUBKEY_UNCMP_LENGTH) { LOG("Output buffer for public key too small: %u bytes\n", *public_key_out_length); return false; } - memcpy(public_key_out, attestation_pubkey, sizeof(attestation_pubkey)); - *public_key_out_length = sizeof(attestation_pubkey); + size_t off = 0; + public_key_out[off++] = 0x04; + memcpy( + public_key_out + off, + G_endorsement_ctx.envelope.quote_auth_data->attestation_key.x, + sizeof(G_endorsement_ctx.envelope.quote_auth_data->attestation_key.x)); + off += + sizeof(G_endorsement_ctx.envelope.quote_auth_data->attestation_key.x); + memcpy( + public_key_out + off, + G_endorsement_ctx.envelope.quote_auth_data->attestation_key.y, + sizeof(G_endorsement_ctx.envelope.quote_auth_data->attestation_key.y)); + off += + sizeof(G_endorsement_ctx.envelope.quote_auth_data->attestation_key.y); + *public_key_out_length = off; + + // Sanity check + if (off != PUBKEY_UNCMP_LENGTH) { + LOG("Unexpected attestation public key length\n"); + return false; + } return true; -} \ No newline at end of file +} diff --git a/firmware/src/hal/sgx/src/trusted/hmac_sha256.c b/firmware/src/hal/sgx/src/trusted/hmac_sha256.c deleted file mode 120000 index f260ff64..00000000 --- a/firmware/src/hal/sgx/src/trusted/hmac_sha256.c +++ /dev/null @@ -1 +0,0 @@ -../../../x86/src/hmac_sha256.c \ No newline at end of file diff --git a/firmware/src/hal/sgx/src/trusted/hmac_sha256.h b/firmware/src/hal/sgx/src/trusted/hmac_sha256.h deleted file mode 120000 index 9fd6de87..00000000 --- a/firmware/src/hal/sgx/src/trusted/hmac_sha256.h +++ /dev/null @@ -1 +0,0 @@ -../../../x86/src/hmac_sha256.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/src/trusted/platform.c b/firmware/src/hal/sgx/src/trusted/platform.c deleted file mode 120000 index ddeafb2f..00000000 --- a/firmware/src/hal/sgx/src/trusted/platform.c +++ /dev/null @@ -1 +0,0 @@ -../../../x86/src/platform.c \ No newline at end of file diff --git a/firmware/src/hal/sgx/src/trusted/platform.c b/firmware/src/hal/sgx/src/trusted/platform.c new file mode 100644 index 00000000..42f10dab --- /dev/null +++ b/firmware/src/hal/sgx/src/trusted/platform.c @@ -0,0 +1,48 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "hal/platform.h" +#include "hal/log.h" + +#include + +void platform_memmove(void *dst, const void *src, unsigned int length) { + memmove(dst, src, length); +} + +void platform_request_exit() { + // Currently unsupported, just log the call + LOG("platform_request_exit called\n"); +} + +const char *platform_get_id() { + return "sgx"; +} + +uint64_t platform_get_timestamp() { + // Trusted way of getting current timestamp + // currently unsupported in OE/SGX, return zero + // for the time being + return (uint64_t)0; +} \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/der_utils/Makefile b/firmware/src/hal/sgx/test/der_utils/Makefile new file mode 100644 index 00000000..d9557131 --- /dev/null +++ b/firmware/src/hal/sgx/test/der_utils/Makefile @@ -0,0 +1,39 @@ +# The MIT License (MIT) +# +# Copyright (c) 2021 RSK Labs Ltd +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +include ../common/common.mk + +PROG = test.out +OBJS = der_utils.o test_der_utils.o +CFLAGS += -I. + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) $(COVFLAGS) -o $@ $^ + +.PHONY: clean test +clean: + rm -f $(PROG) *.o $(COVFILES) + +test: all + ./$(PROG) diff --git a/firmware/src/hal/sgx/test/der_utils/test_der_utils.c b/firmware/src/hal/sgx/test/der_utils/test_der_utils.c new file mode 100644 index 00000000..493314a0 --- /dev/null +++ b/firmware/src/hal/sgx/test/der_utils/test_der_utils.c @@ -0,0 +1,148 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include "der_utils.h" + +void test_der_encode(const sgx_ecdsa256_signature_t* sig, + const uint8_t* expected, + int expected_len) { + uint8_t dest[72]; // Buffer large enough for DER-encoded signature + int len = der_encode_signature(dest, (sgx_ecdsa256_signature_t*)sig); + + assert(len == expected_len); + assert(memcmp(dest, expected, expected_len) == 0); +} + +int main() { + printf("Test case 1: Standard values for R and S... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig1 = { + .r = {0x1c, 0x1e, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, 0xd3, 0x55, 0x4a, + 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, 0xa0, 0xb4, + 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f, 0x14, 0xa5}, + .s = {0x6f, 0x2a, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, + 0xe9, 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, + 0xf9, 0x4c, 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8, 0x6c}}; + uint8_t expected1[] = { + 0x30, 0x44, 0x02, 0x20, 0x1c, 0x1e, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, + 0xd3, 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, + 0xa0, 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f, 0x14, 0xa5, + 0x02, 0x20, 0x6f, 0x2a, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, + 0x32, 0xe9, 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, + 0xf9, 0x4c, 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8, 0x6c}; + test_der_encode(&sig1, expected1, sizeof(expected1)); + printf("Passed.\n"); + + printf("Test case 2: High bit set in R... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig2 = { + .r = {0x80, 0x00, 0x00, 0x01, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, 0xd3, + 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, + 0xa0, 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f}, + .s = {0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, 0xe9, 0xfa, + 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, 0x4c, + 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8, 0x6c, 0x12, 0x34}}; + uint8_t expected2[] = { + 0x30, 0x45, 0x02, 0x21, 0x00, 0x80, 0x00, 0x00, 0x01, 0x24, 0xf5, 0x8d, + 0x7b, 0xe5, 0xa0, 0xd3, 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, + 0x78, 0xae, 0x92, 0xa0, 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, + 0x1f, 0x02, 0x20, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, + 0xe9, 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, + 0x4c, 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8, 0x6c, 0x12, 0x34}; + test_der_encode(&sig2, expected2, sizeof(expected2)); + printf("Passed.\n"); + + printf("Test case 3: Leading zeroes in R... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig3 = { + .r = {0x00, 0x00, 0x00, 0x01, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, 0xd3, + 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, + 0xa0, 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f}, + .s = {0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, 0xe9, 0xfa, + 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, 0x4c, + 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8, 0x6c, 0x12, 0x34}}; + uint8_t expected3[] = { + 0x30, 0x41, 0x02, 0x1d, 0x01, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, 0xd3, + 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, 0xa0, + 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f, 0x02, 0x20, 0x0f, + 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, 0xe9, 0xfa, 0x28, 0xe7, + 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, 0x4c, 0x77, 0xb2, 0xf1, + 0xab, 0xf8, 0xd9, 0xf8, 0x6c, 0x12, 0x34}; + test_der_encode(&sig3, expected3, sizeof(expected3)); + printf("Passed.\n"); + + printf("Test case 4: Leading zeroes in S... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig4 = { + .r = {0x1c, 0x1e, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, 0xd3, 0x55, 0x4a, + 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, 0xa0, 0xb4, + 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f, 0x14, 0xa5}, + .s = {0x00, 0x00, 0x00, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, + 0x32, 0xe9, 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, + 0xf8, 0xf9, 0x4c, 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8}}; + uint8_t expected4[] = { + 0x30, 0x41, 0x02, 0x20, 0x1c, 0x1e, 0x24, 0xf5, 0x8d, 0x7b, 0xe5, 0xa0, + 0xd3, 0x55, 0x4a, 0x2f, 0x5f, 0x3e, 0x63, 0x3a, 0x8d, 0x78, 0xae, 0x92, + 0xa0, 0xb4, 0xa8, 0xc4, 0x95, 0xb1, 0xe3, 0x2d, 0x30, 0x1f, 0x14, 0xa5, + 0x02, 0x1d, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, 0x32, 0xe9, + 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, 0x4c, + 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8}; + test_der_encode(&sig4, expected4, sizeof(expected4)); + printf("Passed.\n"); + + printf("Test case 5: R is zero... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig5 = { + .r = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .s = {0x12, 0x34, 0x56, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, 0x0c, 0x95, + 0x32, 0xe9, 0xfa, 0x28, 0xe7, 0xbd, 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, + 0xf8, 0xf9, 0x4c, 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8}}; + uint8_t expected5[] = {0x30, 0x25, 0x02, 0x01, 0x00, 0x02, 0x20, 0x12, + 0x34, 0x56, 0x0f, 0x8b, 0x46, 0xd1, 0x27, 0x5c, + 0x0c, 0x95, 0x32, 0xe9, 0xfa, 0x28, 0xe7, 0xbd, + 0xf9, 0xcc, 0x7e, 0xf0, 0x2e, 0xf8, 0xf9, 0x4c, + 0x77, 0xb2, 0xf1, 0xab, 0xf8, 0xd9, 0xf8}; + test_der_encode(&sig5, expected5, sizeof(expected5)); + printf("Passed.\n"); + + printf("Test case 6: R and S are zero... "); + fflush(stdout); + sgx_ecdsa256_signature_t sig6 = { + .r = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .s = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + uint8_t expected6[] = {0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00}; + test_der_encode(&sig6, expected6, sizeof(expected6)); + printf("Passed.\n"); + + return 0; +} \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/endorsement/Makefile b/firmware/src/hal/sgx/test/endorsement/Makefile new file mode 100644 index 00000000..86c19dd9 --- /dev/null +++ b/firmware/src/hal/sgx/test/endorsement/Makefile @@ -0,0 +1,39 @@ +# The MIT License (MIT) +# +# Copyright (c) 2021 RSK Labs Ltd +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +include ../common/common.mk + +PROG = test.out +OBJS = endorsement.o test_endorsement.o mocks.o +CFLAGS += -I. + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) $(COVFLAGS) -o $@ $^ + +.PHONY: clean test +clean: + rm -f $(PROG) *.o $(COVFILES) + +test: all + ./$(PROG) diff --git a/firmware/src/hal/sgx/test/endorsement/mocks.c b/firmware/src/hal/sgx/test/endorsement/mocks.c new file mode 100644 index 00000000..98917046 --- /dev/null +++ b/firmware/src/hal/sgx/test/endorsement/mocks.c @@ -0,0 +1,137 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "mocks.h" + +mock_config_t G_mock_config; + +#define MOCK_RESULT(fn) return G_mock_config.result_##fn ? OE_OK : OE_FAILURE + +uint8_t mock_format_id[] = {11, 22, 33}; +uint8_t mock_format_settings[] = {44, 55, 66, 77}; +uint8_t mock_evidence[] = MOCK_EVIDENCE; + +uint8_t der_encode_signature(uint8_t* dest, sgx_ecdsa256_signature_t* sig) { + memcpy(dest, sig->r, sizeof(sig->r)); + memcpy(dest + sizeof(sig->r), sig->s, sizeof(sig->s)); + return sizeof(sig->r) + sizeof(sig->s); +} + +oe_result_t oe_attester_initialize(void) { + MOCK_RESULT(oe_attester_initialize); +} + +oe_result_t oe_attester_select_format(const oe_uuid_t* format_ids, + size_t format_ids_length, + oe_uuid_t* selected_format_id) { + + const uint8_t expected_format_id[] = OE_FORMAT_UUID_SGX_ECDSA; + const oe_uuid_t assigned_format_id = {.b = {11, 22, 33}}; + + assert(format_ids_length == 1); + assert(!memcmp( + format_ids[0].b, expected_format_id, sizeof(expected_format_id))); + *selected_format_id = assigned_format_id; + MOCK_RESULT(oe_attester_select_format); +} + +oe_result_t oe_verifier_get_format_settings(const oe_uuid_t* format_id, + uint8_t** settings, + size_t* settings_size) { + + const uint8_t expected_format_id[] = {11, 22, 33}; + assert( + !memcmp(format_id->b, expected_format_id, sizeof(expected_format_id))); + assert(settings_size != NULL); + *settings = mock_format_settings; + *settings_size = sizeof(mock_format_settings); + + MOCK_RESULT(oe_verifier_get_format_settings); +} + +oe_result_t oe_get_evidence(const oe_uuid_t* format_id, + uint32_t flags, + const void* custom_claims_buffer, + size_t custom_claims_buffer_size, + const void* optional_parameters, + size_t optional_parameters_size, + uint8_t** evidence_buffer, + size_t* evidence_buffer_size, + uint8_t** endorsements_buffer, + size_t* endorsements_buffer_size) { + + // Test parameters + assert(flags == 0); + assert(!memcmp(format_id, mock_format_id, sizeof(mock_format_id))); + assert(!memcmp(optional_parameters, + mock_format_settings, + sizeof(mock_format_settings))); + assert(optional_parameters_size == sizeof(mock_format_settings)); + assert(endorsements_buffer == NULL); + assert(endorsements_buffer_size == NULL); + + // Mock evidence + size_t sz = G_mock_config.oe_get_evidence_buffer_size > 0 + ? G_mock_config.oe_get_evidence_buffer_size + : (sizeof(mock_evidence) + custom_claims_buffer_size); + G_mock_config.oe_get_evidence_buffer = malloc(sz); + if (G_mock_config.oe_get_evidence_buffer_size == 0) { + memcpy(G_mock_config.oe_get_evidence_buffer, + mock_evidence, + sizeof(mock_evidence)); + memcpy(G_mock_config.oe_get_evidence_buffer + sizeof(mock_evidence), + custom_claims_buffer, + custom_claims_buffer_size); + ((sgx_quote_t*)G_mock_config.oe_get_evidence_buffer)->signature_len = + sz - sizeof(sgx_quote_t) - custom_claims_buffer_size; + } + + // Result + *evidence_buffer = G_mock_config.oe_get_evidence_buffer; + *evidence_buffer_size = sz; + + MOCK_RESULT(oe_get_evidence); +} + +oe_result_t oe_free_evidence(uint8_t* evidence_buffer) { + G_mock_config.oe_get_evidence_buffer_freed |= + evidence_buffer == G_mock_config.oe_get_evidence_buffer; + MOCK_RESULT(oe_free_evidence); +} + +oe_result_t oe_attester_shutdown(void) { + MOCK_RESULT(oe_attester_shutdown); +} + +oe_result_t oe_verifier_initialize(void) { + MOCK_RESULT(oe_verifier_initialize); +} + +oe_result_t oe_verifier_shutdown(void) { + MOCK_RESULT(oe_verifier_shutdown); +} \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/endorsement/mocks.h b/firmware/src/hal/sgx/test/endorsement/mocks.h new file mode 100644 index 00000000..b1aa745f --- /dev/null +++ b/firmware/src/hal/sgx/test/endorsement/mocks.h @@ -0,0 +1,482 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __MOCKS_H +#define __MOCKS_H + +#include + +typedef struct { + bool result_oe_attester_initialize; + bool result_oe_attester_shutdown; + bool result_oe_verifier_initialize; + bool result_oe_verifier_shutdown; + bool result_oe_free_evidence; + bool result_oe_verifier_get_format_settings; + bool result_oe_get_evidence; + bool result_oe_attester_select_format; + + uint8_t* oe_get_evidence_buffer; + size_t oe_get_evidence_buffer_size; + bool oe_get_evidence_buffer_freed; +} mock_config_t; + +extern mock_config_t G_mock_config; + +#define MOCK_EVIDENCE \ + { \ + 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0f, \ + 0x00, 0x93, 0x9a, 0x72, 0x33, 0xf7, 0x9c, 0x4c, 0xa9, 0x94, 0x0a, \ + 0x0d, 0xb3, 0x95, 0x7f, 0x06, 0x07, 0xce, 0xae, 0x35, 0x49, 0xbc, \ + 0x72, 0x73, 0xeb, 0x34, 0xd5, 0x62, 0xf4, 0x56, 0x4f, 0xc1, 0x82, \ + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x10, 0x0f, 0xff, 0xff, 0x01, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xd3, 0x26, 0x88, 0xd3, 0xc1, 0xf3, 0xdf, 0xcc, 0x8b, \ + 0x0b, 0x36, 0xea, 0xc7, 0xc8, 0x9d, 0x49, 0xaf, 0x33, 0x18, 0x00, \ + 0xbd, 0x56, 0x24, 0x80, 0x44, 0x16, 0x6f, 0xa6, 0x69, 0x94, 0x42, \ + 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x71, 0x8c, 0x2f, 0x1a, 0x0e, 0xfb, 0xd5, 0x13, 0xe0, 0x16, 0xfa, \ + 0xfd, 0x6c, 0xf6, 0x2a, 0x62, 0x44, 0x42, 0xf2, 0xd8, 0x37, 0x08, \ + 0xd4, 0xb3, 0x3a, 0xb5, 0xa8, 0xd8, 0xc1, 0xcd, 0x4d, 0xd0, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x95, 0xbb, 0x87, 0x5c, 0x1a, \ + 0x72, 0x80, 0x71, 0xf7, 0x0a, 0xd8, 0xc9, 0xd0, 0x3f, 0x17, 0x44, \ + 0xc1, 0x9a, 0xcb, 0x05, 0x80, 0x92, 0x1e, 0x61, 0x1a, 0xc9, 0x10, \ + 0x4f, 0x77, 0x01, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x2b, 0x03, 0xa7, \ + 0xbd, 0x6b, 0x5d, 0xd9, 0xfe, 0xee, 0xb3, 0x75, 0xbd, 0x59, 0x77, \ + 0x30, 0xd2, 0x87, 0x26, 0x43, 0xb4, 0x7a, 0xff, 0x4d, 0xd6, 0x41, \ + 0xc5, 0xc3, 0xa2, 0xb8, 0x01, 0x6e, 0xbb, 0xd2, 0x27, 0xf6, 0x7e, \ + 0x7c, 0x23, 0xbb, 0xdd, 0xeb, 0x4f, 0x8f, 0xdd, 0xee, 0x03, 0x1a, \ + 0x2b, 0x96, 0x15, 0x01, 0xd1, 0xc2, 0x8d, 0xda, 0x08, 0x26, 0x69, \ + 0xd7, 0xac, 0x86, 0x1e, 0x6c, 0xa0, 0x24, 0xcb, 0x34, 0xc9, 0x0e, \ + 0xa6, 0xa8, 0xf9, 0xf2, 0x18, 0x1c, 0x90, 0x20, 0xcb, 0xcc, 0x7c, \ + 0x07, 0x3e, 0x69, 0x98, 0x17, 0x33, 0xc8, 0xde, 0xed, 0x6f, 0x6c, \ + 0x45, 0x18, 0x22, 0xaa, 0x08, 0x37, 0x63, 0x50, 0xff, 0x7d, 0xa0, \ + 0x1f, 0x84, 0x2b, 0xb4, 0x0c, 0x63, 0x1c, 0xbb, 0x71, 0x1f, 0x8b, \ + 0x6f, 0x7a, 0x4f, 0xae, 0x39, 0x83, 0x20, 0xa3, 0x88, 0x47, 0x74, \ + 0xd2, 0x50, 0xad, 0x0e, 0x0e, 0x10, 0x0f, 0xff, 0xff, 0x01, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x96, 0xb3, 0x47, 0xa6, 0x4e, 0x5a, 0x04, 0x5e, 0x27, 0x36, \ + 0x9c, 0x26, 0xe6, 0xdc, 0xda, 0x51, 0xfd, 0x7c, 0x85, 0x0e, 0x9b, \ + 0x3a, 0x3a, 0x79, 0xe7, 0x18, 0xf4, 0x32, 0x61, 0xde, 0xe1, 0xe4, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, \ + 0x4f, 0x57, 0x75, 0xd7, 0x96, 0x50, 0x3e, 0x96, 0x13, 0x7f, 0x77, \ + 0xc6, 0x8a, 0x82, 0x9a, 0x00, 0x56, 0xac, 0x8d, 0xed, 0x70, 0x14, \ + 0x0b, 0x08, 0x1b, 0x09, 0x44, 0x90, 0xc5, 0x7b, 0xff, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe7, 0x21, 0xd0, 0x32, 0x29, 0x54, \ + 0x82, 0x15, 0x89, 0x23, 0x7f, 0xd2, 0x7e, 0xfb, 0x8f, 0xef, 0x1a, \ + 0xcb, 0x3e, 0xcd, 0x6b, 0x03, 0x52, 0xc3, 0x12, 0x71, 0x55, 0x0f, \ + 0xc7, 0x0f, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x1f, 0x14, 0xd5, 0x32, 0x27, 0x4c, 0x43, 0x85, 0xfc, \ + 0x00, 0x19, 0xca, 0x2a, 0x21, 0xe5, 0x3e, 0x17, 0x14, 0x3c, 0xb6, \ + 0x23, 0x77, 0xca, 0x4f, 0xcd, 0xd9, 0x7f, 0xa9, 0xfe, 0xf8, 0xfb, \ + 0x25, 0x95, 0xd4, 0xee, 0x27, 0x2c, 0xf3, 0xc5, 0x12, 0xe3, 0x67, \ + 0x79, 0xde, 0x67, 0xdc, 0x78, 0x14, 0x98, 0x2f, 0x11, 0x60, 0xd9, \ + 0x81, 0xd1, 0x38, 0xa3, 0x2b, 0x26, 0x5e, 0x92, 0x8a, 0x05, 0x62, \ + 0x20, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, \ + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, \ + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, \ + 0x1f, 0x05, 0x00, 0x62, 0x0e, 0x00, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, \ + 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, \ + 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, \ + 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x38, 0x7a, 0x43, 0x43, 0x42, \ + 0x4a, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, \ + 0x66, 0x72, 0x32, 0x64, 0x6c, 0x77, 0x4e, 0x34, 0x32, 0x44, 0x42, \ + 0x55, 0x41, 0x39, 0x43, 0x58, 0x49, 0x6b, 0x42, 0x6c, 0x47, 0x50, \ + 0x32, 0x76, 0x56, 0x33, 0x41, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4b, \ + 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x77, \ + 0x0a, 0x63, 0x44, 0x45, 0x69, 0x4d, 0x43, 0x41, 0x47, 0x41, 0x31, \ + 0x55, 0x45, 0x41, 0x77, 0x77, 0x5a, 0x53, 0x57, 0x35, 0x30, 0x5a, \ + 0x57, 0x77, 0x67, 0x55, 0x30, 0x64, 0x59, 0x49, 0x46, 0x42, 0x44, \ + 0x53, 0x79, 0x42, 0x51, 0x62, 0x47, 0x46, 0x30, 0x5a, 0x6d, 0x39, \ + 0x79, 0x62, 0x53, 0x42, 0x44, 0x51, 0x54, 0x45, 0x61, 0x4d, 0x42, \ + 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x52, 0x0a, \ + 0x53, 0x57, 0x35, 0x30, 0x5a, 0x57, 0x77, 0x67, 0x51, 0x32, 0x39, \ + 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, \ + 0x34, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, \ + 0x41, 0x63, 0x4d, 0x43, 0x31, 0x4e, 0x68, 0x62, 0x6e, 0x52, 0x68, \ + 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4a, 0x68, 0x4d, 0x51, 0x73, \ + 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x0a, 0x44, \ + 0x41, 0x4a, 0x44, 0x51, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, \ + 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, \ + 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x51, 0x77, 0x4d, 0x7a, \ + 0x49, 0x7a, 0x4d, 0x44, 0x51, 0x30, 0x4e, 0x6a, 0x49, 0x78, 0x57, \ + 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x45, 0x77, 0x4d, 0x7a, 0x49, 0x7a, \ + 0x4d, 0x44, 0x51, 0x30, 0x4e, 0x6a, 0x49, 0x78, 0x0a, 0x57, 0x6a, \ + 0x42, 0x77, 0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, \ + 0x51, 0x51, 0x44, 0x44, 0x42, 0x6c, 0x4a, 0x62, 0x6e, 0x52, 0x6c, \ + 0x62, 0x43, 0x42, 0x54, 0x52, 0x31, 0x67, 0x67, 0x55, 0x45, 0x4e, \ + 0x4c, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, \ + 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x52, 0x6f, 0x77, 0x47, \ + 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x0a, 0x44, 0x42, 0x46, \ + 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x62, 0x43, 0x42, 0x44, 0x62, 0x33, \ + 0x4a, 0x77, 0x62, 0x33, 0x4a, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, \ + 0x6a, 0x45, 0x55, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, \ + 0x42, 0x77, 0x77, 0x4c, 0x55, 0x32, 0x46, 0x75, 0x64, 0x47, 0x45, \ + 0x67, 0x51, 0x32, 0x78, 0x68, 0x63, 0x6d, 0x45, 0x78, 0x43, 0x7a, \ + 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x67, 0x4d, \ + 0x41, 0x6b, 0x4e, 0x42, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, \ + 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, \ + 0x42, 0x5a, 0x4d, 0x42, 0x4d, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53, \ + 0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, \ + 0x53, 0x4d, 0x34, 0x39, 0x41, 0x77, 0x45, 0x48, 0x41, 0x30, 0x49, \ + 0x41, 0x42, 0x4b, 0x6c, 0x37, 0x0a, 0x52, 0x44, 0x4e, 0x6c, 0x73, \ + 0x5a, 0x4b, 0x6b, 0x45, 0x74, 0x41, 0x63, 0x57, 0x37, 0x53, 0x66, \ + 0x43, 0x58, 0x31, 0x4a, 0x65, 0x67, 0x62, 0x76, 0x47, 0x71, 0x34, \ + 0x4f, 0x30, 0x72, 0x52, 0x55, 0x74, 0x30, 0x7a, 0x2f, 0x47, 0x36, \ + 0x66, 0x5a, 0x4a, 0x73, 0x4e, 0x6c, 0x70, 0x6d, 0x52, 0x77, 0x54, \ + 0x42, 0x34, 0x44, 0x59, 0x6b, 0x72, 0x67, 0x6b, 0x6d, 0x31, 0x74, \ + 0x2b, 0x39, 0x52, 0x70, 0x0a, 0x4c, 0x77, 0x78, 0x46, 0x58, 0x39, \ + 0x2f, 0x6b, 0x67, 0x68, 0x78, 0x69, 0x44, 0x51, 0x6d, 0x30, 0x6a, \ + 0x71, 0x6d, 0x6a, 0x67, 0x67, 0x4d, 0x4f, 0x4d, 0x49, 0x49, 0x44, \ + 0x43, 0x6a, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, \ + 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x56, 0x62, 0x31, \ + 0x33, 0x4e, 0x76, 0x52, 0x76, 0x68, 0x36, 0x55, 0x42, 0x4a, 0x79, \ + 0x64, 0x54, 0x30, 0x0a, 0x4d, 0x38, 0x34, 0x42, 0x56, 0x77, 0x76, \ + 0x65, 0x56, 0x44, 0x42, 0x72, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, \ + 0x38, 0x45, 0x5a, 0x44, 0x42, 0x69, 0x4d, 0x47, 0x43, 0x67, 0x58, \ + 0x71, 0x42, 0x63, 0x68, 0x6c, 0x70, 0x6f, 0x64, 0x48, 0x52, 0x77, \ + 0x63, 0x7a, 0x6f, 0x76, 0x4c, 0x32, 0x46, 0x77, 0x61, 0x53, 0x35, \ + 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x47, 0x56, 0x6b, 0x63, 0x32, \ + 0x56, 0x79, 0x0a, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58, 0x4d, 0x75, \ + 0x61, 0x57, 0x35, 0x30, 0x5a, 0x57, 0x77, 0x75, 0x59, 0x32, 0x39, \ + 0x74, 0x4c, 0x33, 0x4e, 0x6e, 0x65, 0x43, 0x39, 0x6a, 0x5a, 0x58, \ + 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, \ + 0x57, 0x39, 0x75, 0x4c, 0x33, 0x59, 0x30, 0x4c, 0x33, 0x42, 0x6a, \ + 0x61, 0x32, 0x4e, 0x79, 0x62, 0x44, 0x39, 0x6a, 0x59, 0x54, 0x31, \ + 0x77, 0x0a, 0x62, 0x47, 0x46, 0x30, 0x5a, 0x6d, 0x39, 0x79, 0x62, \ + 0x53, 0x5a, 0x6c, 0x62, 0x6d, 0x4e, 0x76, 0x5a, 0x47, 0x6c, 0x75, \ + 0x5a, 0x7a, 0x31, 0x6b, 0x5a, 0x58, 0x49, 0x77, 0x48, 0x51, 0x59, \ + 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x41, \ + 0x4c, 0x4b, 0x56, 0x35, 0x44, 0x46, 0x31, 0x36, 0x4b, 0x6e, 0x45, \ + 0x62, 0x53, 0x57, 0x35, 0x51, 0x4d, 0x39, 0x65, 0x63, 0x44, 0x71, \ + 0x0a, 0x42, 0x5a, 0x61, 0x48, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, \ + 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, \ + 0x77, 0x49, 0x47, 0x77, 0x44, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, \ + 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x41, 0x6a, 0x41, \ + 0x41, 0x4d, 0x49, 0x49, 0x43, 0x4f, 0x77, 0x59, 0x4a, 0x4b, 0x6f, \ + 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x0a, \ + 0x42, 0x49, 0x49, 0x43, 0x4c, 0x44, 0x43, 0x43, 0x41, 0x69, 0x67, \ + 0x77, 0x48, 0x67, 0x59, 0x4b, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, \ + 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x51, 0x51, 0x51, 0x74, \ + 0x74, 0x4a, 0x58, 0x75, 0x69, 0x51, 0x56, 0x77, 0x71, 0x4d, 0x34, \ + 0x73, 0x37, 0x34, 0x67, 0x2b, 0x48, 0x78, 0x66, 0x4b, 0x54, 0x43, \ + 0x43, 0x41, 0x57, 0x55, 0x47, 0x43, 0x69, 0x71, 0x47, 0x0a, 0x53, \ + 0x49, 0x62, 0x34, 0x54, 0x51, 0x45, 0x4e, 0x41, 0x51, 0x49, 0x77, \ + 0x67, 0x67, 0x46, 0x56, 0x4d, 0x42, 0x41, 0x47, 0x43, 0x79, 0x71, \ + 0x47, 0x53, 0x49, 0x62, 0x34, 0x54, 0x51, 0x45, 0x4e, 0x41, 0x51, \ + 0x49, 0x42, 0x41, 0x67, 0x45, 0x4f, 0x4d, 0x42, 0x41, 0x47, 0x43, \ + 0x79, 0x71, 0x47, 0x53, 0x49, 0x62, 0x34, 0x54, 0x51, 0x45, 0x4e, \ + 0x41, 0x51, 0x49, 0x43, 0x41, 0x67, 0x45, 0x4f, 0x0a, 0x4d, 0x42, \ + 0x41, 0x47, 0x43, 0x79, 0x71, 0x47, 0x53, 0x49, 0x62, 0x34, 0x54, \ + 0x51, 0x45, 0x4e, 0x41, 0x51, 0x49, 0x44, 0x41, 0x67, 0x45, 0x44, \ + 0x4d, 0x42, 0x41, 0x47, 0x43, 0x79, 0x71, 0x47, 0x53, 0x49, 0x62, \ + 0x34, 0x54, 0x51, 0x45, 0x4e, 0x41, 0x51, 0x49, 0x45, 0x41, 0x67, \ + 0x45, 0x44, 0x4d, 0x42, 0x45, 0x47, 0x43, 0x79, 0x71, 0x47, 0x53, \ + 0x49, 0x62, 0x34, 0x54, 0x51, 0x45, 0x4e, 0x0a, 0x41, 0x51, 0x49, \ + 0x46, 0x41, 0x67, 0x49, 0x41, 0x2f, 0x7a, 0x41, 0x52, 0x42, 0x67, \ + 0x73, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x2b, 0x45, 0x30, 0x42, 0x44, \ + 0x51, 0x45, 0x43, 0x42, 0x67, 0x49, 0x43, 0x41, 0x50, 0x38, 0x77, \ + 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, \ + 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x67, 0x63, 0x43, 0x41, 0x51, \ + 0x45, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x0a, 0x4b, 0x6f, 0x5a, 0x49, \ + 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x67, 0x67, \ + 0x43, 0x41, 0x51, 0x41, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, \ + 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, \ + 0x67, 0x6b, 0x43, 0x41, 0x51, 0x41, 0x77, 0x45, 0x41, 0x59, 0x4c, \ + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, \ + 0x42, 0x41, 0x67, 0x6f, 0x43, 0x0a, 0x41, 0x51, 0x41, 0x77, 0x45, \ + 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, \ + 0x41, 0x51, 0x30, 0x42, 0x41, 0x67, 0x73, 0x43, 0x41, 0x51, 0x41, \ + 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, \ + 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x67, 0x77, 0x43, 0x41, \ + 0x51, 0x41, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, \ + 0x68, 0x76, 0x68, 0x4e, 0x0a, 0x41, 0x51, 0x30, 0x42, 0x41, 0x67, \ + 0x30, 0x43, 0x41, 0x51, 0x41, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, \ + 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, \ + 0x41, 0x67, 0x34, 0x43, 0x41, 0x51, 0x41, 0x77, 0x45, 0x41, 0x59, \ + 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, \ + 0x30, 0x42, 0x41, 0x67, 0x38, 0x43, 0x41, 0x51, 0x41, 0x77, 0x45, \ + 0x41, 0x59, 0x4c, 0x0a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, \ + 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x68, 0x41, 0x43, 0x41, 0x51, \ + 0x41, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, \ + 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x68, 0x45, 0x43, \ + 0x41, 0x51, 0x30, 0x77, 0x48, 0x77, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, \ + 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, 0x68, \ + 0x49, 0x45, 0x0a, 0x45, 0x41, 0x34, 0x4f, 0x41, 0x77, 0x50, 0x2f, \ + 0x2f, 0x77, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, \ + 0x41, 0x41, 0x41, 0x41, 0x77, 0x45, 0x41, 0x59, 0x4b, 0x4b, 0x6f, \ + 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x41, \ + 0x77, 0x51, 0x43, 0x41, 0x41, 0x41, 0x77, 0x46, 0x41, 0x59, 0x4b, \ + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, \ + 0x42, 0x0a, 0x42, 0x41, 0x51, 0x47, 0x41, 0x47, 0x42, 0x71, 0x41, \ + 0x41, 0x41, 0x41, 0x4d, 0x41, 0x38, 0x47, 0x43, 0x69, 0x71, 0x47, \ + 0x53, 0x49, 0x62, 0x34, 0x54, 0x51, 0x45, 0x4e, 0x41, 0x51, 0x55, \ + 0x4b, 0x41, 0x51, 0x45, 0x77, 0x48, 0x67, 0x59, 0x4b, 0x4b, 0x6f, \ + 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x42, \ + 0x67, 0x51, 0x51, 0x44, 0x56, 0x65, 0x2f, 0x44, 0x58, 0x55, 0x56, \ + 0x0a, 0x45, 0x34, 0x67, 0x65, 0x6d, 0x74, 0x67, 0x4f, 0x35, 0x75, \ + 0x42, 0x70, 0x76, 0x44, 0x42, 0x45, 0x42, 0x67, 0x6f, 0x71, 0x68, \ + 0x6b, 0x69, 0x47, 0x2b, 0x45, 0x30, 0x42, 0x44, 0x51, 0x45, 0x48, \ + 0x4d, 0x44, 0x59, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x4b, 0x6f, 0x5a, \ + 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, 0x42, 0x42, 0x77, \ + 0x45, 0x42, 0x41, 0x66, 0x38, 0x77, 0x45, 0x41, 0x59, 0x4c, 0x0a, \ + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, 0x51, 0x30, \ + 0x42, 0x42, 0x77, 0x49, 0x42, 0x41, 0x51, 0x41, 0x77, 0x45, 0x41, \ + 0x59, 0x4c, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x68, 0x4e, 0x41, \ + 0x51, 0x30, 0x42, 0x42, 0x77, 0x4d, 0x42, 0x41, 0x51, 0x41, 0x77, \ + 0x43, 0x67, 0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, \ + 0x45, 0x41, 0x77, 0x49, 0x44, 0x53, 0x51, 0x41, 0x77, 0x0a, 0x52, \ + 0x67, 0x49, 0x68, 0x41, 0x4a, 0x46, 0x67, 0x66, 0x37, 0x38, 0x48, \ + 0x67, 0x67, 0x54, 0x42, 0x74, 0x76, 0x51, 0x50, 0x58, 0x5a, 0x4a, \ + 0x78, 0x2f, 0x33, 0x46, 0x6d, 0x37, 0x31, 0x76, 0x43, 0x4f, 0x6d, \ + 0x74, 0x38, 0x32, 0x70, 0x63, 0x65, 0x39, 0x31, 0x4d, 0x32, 0x5a, \ + 0x41, 0x49, 0x30, 0x41, 0x69, 0x45, 0x41, 0x69, 0x5a, 0x4d, 0x50, \ + 0x42, 0x62, 0x5a, 0x5a, 0x6d, 0x76, 0x52, 0x32, 0x0a, 0x76, 0x2b, \ + 0x31, 0x6d, 0x72, 0x73, 0x37, 0x36, 0x4a, 0x65, 0x67, 0x6c, 0x44, \ + 0x51, 0x2b, 0x70, 0x4b, 0x2f, 0x53, 0x4c, 0x4e, 0x39, 0x34, 0x6c, \ + 0x34, 0x2b, 0x6a, 0x4d, 0x35, 0x44, 0x41, 0x3d, 0x0a, 0x2d, 0x2d, \ + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, \ + 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, \ + 0x2d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, \ + 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, \ + 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, \ + 0x43, 0x6c, 0x6a, 0x43, 0x43, 0x41, 0x6a, 0x32, 0x67, 0x41, 0x77, \ + 0x49, 0x42, 0x41, 0x67, 0x49, 0x56, 0x41, 0x4a, 0x56, 0x76, 0x58, \ + 0x63, 0x32, 0x39, 0x47, 0x2b, 0x48, 0x70, 0x51, 0x45, 0x6e, 0x4a, \ + 0x31, 0x50, 0x51, 0x7a, 0x7a, 0x67, 0x46, 0x58, 0x43, 0x39, 0x35, \ + 0x55, 0x4d, 0x41, 0x6f, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, \ + 0x34, 0x39, 0x42, 0x41, 0x4d, 0x43, 0x0a, 0x4d, 0x47, 0x67, 0x78, \ + 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, \ + 0x4d, 0x45, 0x55, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x73, 0x49, 0x46, \ + 0x4e, 0x48, 0x57, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, \ + 0x45, 0x4e, 0x42, 0x4d, 0x52, 0x6f, 0x77, 0x47, 0x41, 0x59, 0x44, \ + 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x46, 0x4a, 0x62, 0x6e, 0x52, \ + 0x6c, 0x62, 0x43, 0x42, 0x44, 0x0a, 0x62, 0x33, 0x4a, 0x77, 0x62, \ + 0x33, 0x4a, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x55, \ + 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, \ + 0x4c, 0x55, 0x32, 0x46, 0x75, 0x64, 0x47, 0x45, 0x67, 0x51, 0x32, \ + 0x78, 0x68, 0x63, 0x6d, 0x45, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, \ + 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x41, 0x6b, 0x4e, 0x42, \ + 0x4d, 0x51, 0x73, 0x77, 0x0a, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, \ + 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x41, 0x65, 0x46, \ + 0x77, 0x30, 0x78, 0x4f, 0x44, 0x41, 0x31, 0x4d, 0x6a, 0x45, 0x78, \ + 0x4d, 0x44, 0x55, 0x77, 0x4d, 0x54, 0x42, 0x61, 0x46, 0x77, 0x30, \ + 0x7a, 0x4d, 0x7a, 0x41, 0x31, 0x4d, 0x6a, 0x45, 0x78, 0x4d, 0x44, \ + 0x55, 0x77, 0x4d, 0x54, 0x42, 0x61, 0x4d, 0x48, 0x41, 0x78, 0x49, \ + 0x6a, 0x41, 0x67, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, \ + 0x4d, 0x47, 0x55, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x73, 0x49, 0x46, \ + 0x4e, 0x48, 0x57, 0x43, 0x42, 0x51, 0x51, 0x30, 0x73, 0x67, 0x55, \ + 0x47, 0x78, 0x68, 0x64, 0x47, 0x5a, 0x76, 0x63, 0x6d, 0x30, 0x67, \ + 0x51, 0x30, 0x45, 0x78, 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, \ + 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x45, 0x55, 0x6c, 0x75, 0x64, 0x47, \ + 0x56, 0x73, 0x0a, 0x49, 0x45, 0x4e, 0x76, 0x63, 0x6e, 0x42, 0x76, \ + 0x63, 0x6d, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x52, 0x51, \ + 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, \ + 0x74, 0x54, 0x59, 0x57, 0x35, 0x30, 0x59, 0x53, 0x42, 0x44, 0x62, \ + 0x47, 0x46, 0x79, 0x59, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, \ + 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x43, 0x51, 0x30, 0x45, \ + 0x78, 0x0a, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, \ + 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x46, 0x6b, 0x77, \ + 0x45, 0x77, 0x59, 0x48, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, \ + 0x43, 0x41, 0x51, 0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, \ + 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x4e, \ + 0x53, 0x42, 0x2f, 0x37, 0x74, 0x32, 0x31, 0x6c, 0x58, 0x53, 0x4f, \ + 0x0a, 0x32, 0x43, 0x75, 0x7a, 0x70, 0x78, 0x77, 0x37, 0x34, 0x65, \ + 0x4a, 0x42, 0x37, 0x32, 0x45, 0x79, 0x44, 0x47, 0x67, 0x57, 0x35, \ + 0x72, 0x58, 0x43, 0x74, 0x78, 0x32, 0x74, 0x56, 0x54, 0x4c, 0x71, \ + 0x36, 0x68, 0x4b, 0x6b, 0x36, 0x7a, 0x2b, 0x55, 0x69, 0x52, 0x5a, \ + 0x43, 0x6e, 0x71, 0x52, 0x37, 0x70, 0x73, 0x4f, 0x76, 0x67, 0x71, \ + 0x46, 0x65, 0x53, 0x78, 0x6c, 0x6d, 0x54, 0x6c, 0x4a, 0x6c, 0x0a, \ + 0x65, 0x54, 0x6d, 0x69, 0x32, 0x57, 0x59, 0x7a, 0x33, 0x71, 0x4f, \ + 0x42, 0x75, 0x7a, 0x43, 0x42, 0x75, 0x44, 0x41, 0x66, 0x42, 0x67, \ + 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, \ + 0x42, 0x51, 0x69, 0x5a, 0x51, 0x7a, 0x57, 0x57, 0x70, 0x30, 0x30, \ + 0x69, 0x66, 0x4f, 0x44, 0x74, 0x4a, 0x56, 0x53, 0x76, 0x31, 0x41, \ + 0x62, 0x4f, 0x53, 0x63, 0x47, 0x72, 0x44, 0x42, 0x53, 0x0a, 0x42, \ + 0x67, 0x4e, 0x56, 0x48, 0x52, 0x38, 0x45, 0x53, 0x7a, 0x42, 0x4a, \ + 0x4d, 0x45, 0x65, 0x67, 0x52, 0x61, 0x42, 0x44, 0x68, 0x6b, 0x46, \ + 0x6f, 0x64, 0x48, 0x52, 0x77, 0x63, 0x7a, 0x6f, 0x76, 0x4c, 0x32, \ + 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, \ + 0x58, 0x52, 0x6c, 0x63, 0x79, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, \ + 0x64, 0x47, 0x56, 0x6b, 0x63, 0x32, 0x56, 0x79, 0x0a, 0x64, 0x6d, \ + 0x6c, 0x6a, 0x5a, 0x58, 0x4d, 0x75, 0x61, 0x57, 0x35, 0x30, 0x5a, \ + 0x57, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x30, 0x6c, 0x75, \ + 0x64, 0x47, 0x56, 0x73, 0x55, 0x30, 0x64, 0x59, 0x55, 0x6d, 0x39, \ + 0x76, 0x64, 0x45, 0x4e, 0x42, 0x4c, 0x6d, 0x52, 0x6c, 0x63, 0x6a, \ + 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, \ + 0x67, 0x51, 0x55, 0x6c, 0x57, 0x39, 0x64, 0x0a, 0x7a, 0x62, 0x30, \ + 0x62, 0x34, 0x65, 0x6c, 0x41, 0x53, 0x63, 0x6e, 0x55, 0x39, 0x44, \ + 0x50, 0x4f, 0x41, 0x56, 0x63, 0x4c, 0x33, 0x6c, 0x51, 0x77, 0x44, \ + 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f, \ + 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x42, 0x49, \ + 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, \ + 0x51, 0x49, 0x4d, 0x41, 0x59, 0x42, 0x0a, 0x41, 0x66, 0x38, 0x43, \ + 0x41, 0x51, 0x41, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4b, 0x6f, 0x5a, \ + 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x44, 0x52, 0x77, \ + 0x41, 0x77, 0x52, 0x41, 0x49, 0x67, 0x58, 0x73, 0x56, 0x6b, 0x69, \ + 0x30, 0x77, 0x2b, 0x69, 0x36, 0x56, 0x59, 0x47, 0x57, 0x33, 0x55, \ + 0x46, 0x2f, 0x32, 0x32, 0x75, 0x61, 0x58, 0x65, 0x30, 0x59, 0x4a, \ + 0x44, 0x6a, 0x31, 0x55, 0x65, 0x0a, 0x6e, 0x41, 0x2b, 0x54, 0x6a, \ + 0x44, 0x31, 0x61, 0x69, 0x35, 0x63, 0x43, 0x49, 0x43, 0x59, 0x62, \ + 0x31, 0x53, 0x41, 0x6d, 0x44, 0x35, 0x78, 0x6b, 0x66, 0x54, 0x56, \ + 0x70, 0x76, 0x6f, 0x34, 0x55, 0x6f, 0x79, 0x69, 0x53, 0x59, 0x78, \ + 0x72, 0x44, 0x57, 0x4c, 0x6d, 0x55, 0x52, 0x34, 0x43, 0x49, 0x39, \ + 0x4e, 0x4b, 0x79, 0x66, 0x50, 0x4e, 0x2b, 0x0a, 0x2d, 0x2d, 0x2d, \ + 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, \ + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, \ + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, \ + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, \ + 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, \ + 0x6a, 0x7a, 0x43, 0x43, 0x41, 0x6a, 0x53, 0x67, 0x41, 0x77, 0x49, \ + 0x42, 0x41, 0x67, 0x49, 0x55, 0x49, 0x6d, 0x55, 0x4d, 0x31, 0x6c, \ + 0x71, 0x64, 0x4e, 0x49, 0x6e, 0x7a, 0x67, 0x37, 0x53, 0x56, 0x55, \ + 0x72, 0x39, 0x51, 0x47, 0x7a, 0x6b, 0x6e, 0x42, 0x71, 0x77, 0x77, \ + 0x43, 0x67, 0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, \ + 0x45, 0x41, 0x77, 0x49, 0x77, 0x0a, 0x61, 0x44, 0x45, 0x61, 0x4d, \ + 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x52, \ + 0x53, 0x57, 0x35, 0x30, 0x5a, 0x57, 0x77, 0x67, 0x55, 0x30, 0x64, \ + 0x59, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, \ + 0x45, 0x78, 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, \ + 0x41, 0x6f, 0x4d, 0x45, 0x55, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x73, \ + 0x49, 0x45, 0x4e, 0x76, 0x0a, 0x63, 0x6e, 0x42, 0x76, 0x63, 0x6d, \ + 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x52, 0x51, 0x77, 0x45, \ + 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x74, 0x54, \ + 0x59, 0x57, 0x35, 0x30, 0x59, 0x53, 0x42, 0x44, 0x62, 0x47, 0x46, \ + 0x79, 0x59, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, \ + 0x55, 0x45, 0x43, 0x41, 0x77, 0x43, 0x51, 0x30, 0x45, 0x78, 0x43, \ + 0x7a, 0x41, 0x4a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, \ + 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, \ + 0x45, 0x34, 0x4d, 0x44, 0x55, 0x79, 0x4d, 0x54, 0x45, 0x77, 0x4e, \ + 0x44, 0x55, 0x78, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x51, 0x35, \ + 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b, \ + 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x61, 0x44, 0x45, 0x61, 0x4d, 0x42, \ + 0x67, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x52, \ + 0x53, 0x57, 0x35, 0x30, 0x5a, 0x57, 0x77, 0x67, 0x55, 0x30, 0x64, \ + 0x59, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, \ + 0x45, 0x78, 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, \ + 0x41, 0x6f, 0x4d, 0x45, 0x55, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x73, \ + 0x49, 0x45, 0x4e, 0x76, 0x63, 0x6e, 0x42, 0x76, 0x63, 0x6d, 0x46, \ + 0x30, 0x0a, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x52, 0x51, 0x77, 0x45, \ + 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x74, 0x54, \ + 0x59, 0x57, 0x35, 0x30, 0x59, 0x53, 0x42, 0x44, 0x62, 0x47, 0x46, \ + 0x79, 0x59, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, \ + 0x55, 0x45, 0x43, 0x41, 0x77, 0x43, 0x51, 0x30, 0x45, 0x78, 0x43, \ + 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, \ + 0x0a, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x46, 0x6b, 0x77, 0x45, 0x77, \ + 0x59, 0x48, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x43, 0x41, \ + 0x51, 0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x44, \ + 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x43, 0x36, 0x6e, \ + 0x45, 0x77, 0x4d, 0x44, 0x49, 0x59, 0x5a, 0x4f, 0x6a, 0x2f, 0x69, \ + 0x50, 0x57, 0x73, 0x43, 0x7a, 0x61, 0x45, 0x4b, 0x69, 0x37, 0x0a, \ + 0x31, 0x4f, 0x69, 0x4f, 0x53, 0x4c, 0x52, 0x46, 0x68, 0x57, 0x47, \ + 0x6a, 0x62, 0x6e, 0x42, 0x56, 0x4a, 0x66, 0x56, 0x6e, 0x6b, 0x59, \ + 0x34, 0x75, 0x33, 0x49, 0x6a, 0x6b, 0x44, 0x59, 0x59, 0x4c, 0x30, \ + 0x4d, 0x78, 0x4f, 0x34, 0x6d, 0x71, 0x73, 0x79, 0x59, 0x6a, 0x6c, \ + 0x42, 0x61, 0x6c, 0x54, 0x56, 0x59, 0x78, 0x46, 0x50, 0x32, 0x73, \ + 0x4a, 0x42, 0x4b, 0x35, 0x7a, 0x6c, 0x4b, 0x4f, 0x42, 0x0a, 0x75, \ + 0x7a, 0x43, 0x42, 0x75, 0x44, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, \ + 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x51, \ + 0x69, 0x5a, 0x51, 0x7a, 0x57, 0x57, 0x70, 0x30, 0x30, 0x69, 0x66, \ + 0x4f, 0x44, 0x74, 0x4a, 0x56, 0x53, 0x76, 0x31, 0x41, 0x62, 0x4f, \ + 0x53, 0x63, 0x47, 0x72, 0x44, 0x42, 0x53, 0x42, 0x67, 0x4e, 0x56, \ + 0x48, 0x52, 0x38, 0x45, 0x53, 0x7a, 0x42, 0x4a, 0x0a, 0x4d, 0x45, \ + 0x65, 0x67, 0x52, 0x61, 0x42, 0x44, 0x68, 0x6b, 0x46, 0x6f, 0x64, \ + 0x48, 0x52, 0x77, 0x63, 0x7a, 0x6f, 0x76, 0x4c, 0x32, 0x4e, 0x6c, \ + 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, \ + 0x6c, 0x63, 0x79, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x47, \ + 0x56, 0x6b, 0x63, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, \ + 0x58, 0x4d, 0x75, 0x61, 0x57, 0x35, 0x30, 0x0a, 0x5a, 0x57, 0x77, \ + 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x30, 0x6c, 0x75, 0x64, 0x47, \ + 0x56, 0x73, 0x55, 0x30, 0x64, 0x59, 0x55, 0x6d, 0x39, 0x76, 0x64, \ + 0x45, 0x4e, 0x42, 0x4c, 0x6d, 0x52, 0x6c, 0x63, 0x6a, 0x41, 0x64, \ + 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, \ + 0x55, 0x49, 0x6d, 0x55, 0x4d, 0x31, 0x6c, 0x71, 0x64, 0x4e, 0x49, \ + 0x6e, 0x7a, 0x67, 0x37, 0x53, 0x56, 0x0a, 0x55, 0x72, 0x39, 0x51, \ + 0x47, 0x7a, 0x6b, 0x6e, 0x42, 0x71, 0x77, 0x77, 0x44, 0x67, 0x59, \ + 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, \ + 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x42, 0x49, 0x47, 0x41, \ + 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x49, \ + 0x4d, 0x41, 0x59, 0x42, 0x41, 0x66, 0x38, 0x43, 0x41, 0x51, 0x45, \ + 0x77, 0x43, 0x67, 0x59, 0x49, 0x0a, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, \ + 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x44, 0x53, 0x51, 0x41, 0x77, \ + 0x52, 0x67, 0x49, 0x68, 0x41, 0x4f, 0x57, 0x2f, 0x35, 0x51, 0x6b, \ + 0x52, 0x2b, 0x53, 0x39, 0x43, 0x69, 0x53, 0x44, 0x63, 0x4e, 0x6f, \ + 0x6f, 0x77, 0x4c, 0x75, 0x50, 0x52, 0x4c, 0x73, 0x57, 0x47, 0x66, \ + 0x2f, 0x59, 0x69, 0x37, 0x47, 0x53, 0x58, 0x39, 0x34, 0x42, 0x67, \ + 0x77, 0x54, 0x77, 0x67, 0x0a, 0x41, 0x69, 0x45, 0x41, 0x34, 0x4a, \ + 0x30, 0x6c, 0x72, 0x48, 0x6f, 0x4d, 0x73, 0x2b, 0x58, 0x6f, 0x35, \ + 0x6f, 0x2f, 0x73, 0x58, 0x36, 0x4f, 0x39, 0x51, 0x57, 0x78, 0x48, \ + 0x52, 0x41, 0x76, 0x5a, 0x55, 0x47, 0x4f, 0x64, 0x52, 0x51, 0x37, \ + 0x63, 0x76, 0x71, 0x52, 0x58, 0x61, 0x71, 0x49, 0x3d, 0x0a, 0x2d, \ + 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, \ + 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, \ + 0x2d, 0x2d, 0x0a, 0x00 \ + } + +#endif // __MOCKS_H diff --git a/firmware/src/hal/sgx/test/endorsement/test_endorsement.c b/firmware/src/hal/sgx/test/endorsement/test_endorsement.c new file mode 100644 index 00000000..ce73f2a1 --- /dev/null +++ b/firmware/src/hal/sgx/test/endorsement/test_endorsement.c @@ -0,0 +1,299 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "hal/endorsement.h" +#include "hal/constants.h" + +#include +#include "mocks.h" + +uint8_t msg[] = "this is a message"; +uint8_t signature[MAX_SIGNATURE_LENGTH]; +uint8_t signature_length; +extern uint8_t mock_evidence[]; + +void setup_no_init() { + // This has the side effect of clearing the initialized state of the + // endorsement module + G_mock_config.result_oe_attester_initialize = false; + endorsement_init(); + + G_mock_config.result_oe_attester_initialize = true; + G_mock_config.result_oe_verifier_initialize = true; + G_mock_config.result_oe_attester_select_format = true; + G_mock_config.result_oe_verifier_get_format_settings = true; + G_mock_config.result_oe_get_evidence = true; + G_mock_config.oe_get_evidence_buffer_freed = false; + + signature_length = sizeof(signature); + if (G_mock_config.oe_get_evidence_buffer != NULL) { + free(G_mock_config.oe_get_evidence_buffer); + G_mock_config.oe_get_evidence_buffer = NULL; + } + G_mock_config.oe_get_evidence_buffer_size = 0; +} + +void setup() { + setup_no_init(); + assert(endorsement_init()); +} + +void setup_and_sign() { + setup(); + assert(endorsement_sign(msg, sizeof(msg), signature, &signature_length)); + assert(G_mock_config.oe_get_evidence_buffer_freed); +} + +void test_endorsement_init_ok() { + setup_no_init(); + assert(endorsement_init() == true); +} + +void test_endorsement_init_err_attinit() { + setup_no_init(); + G_mock_config.result_oe_attester_initialize = false; + assert(endorsement_init() == false); +} + +void test_endorsement_init_err_verinit() { + setup_no_init(); + G_mock_config.result_oe_verifier_initialize = false; + assert(endorsement_init() == false); +} + +void test_endorsement_init_err_selfmt() { + setup_no_init(); + G_mock_config.result_oe_attester_select_format = false; + assert(endorsement_init() == false); +} + +void test_endorsement_init_err_getfmt() { + setup_no_init(); + G_mock_config.result_oe_verifier_get_format_settings = false; + assert(endorsement_init() == false); +} + +void test_signature_ok() { + setup(); + + assert(endorsement_sign(msg, sizeof(msg), signature, &signature_length)); + + sgx_ecdsa256_signature_t* sig = + &((sgx_quote_auth_data_t*)(mock_evidence + sizeof(sgx_quote_t))) + ->signature; + assert(!memcmp(signature, sig->r, sizeof(sig->r))); + assert(!memcmp(signature + sizeof(sig->r), sig->s, sizeof(sig->s))); + assert(signature_length == sizeof(sig->r) + sizeof(sig->s)); + + assert(G_mock_config.oe_get_evidence_buffer_freed); +} + +void test_signature_err_notinit() { + setup_no_init(); + + assert(!endorsement_sign(msg, sizeof(msg), signature, &signature_length)); +} + +void test_signature_err_sigbuftoosmall() { + setup(); + + signature_length = 10; + assert(!endorsement_sign(msg, sizeof(msg), signature, &signature_length)); + + assert(!G_mock_config.oe_get_evidence_buffer_freed); +} + +void test_signature_err_evibuftoobig() { + setup(); + + G_mock_config.oe_get_evidence_buffer_size = 100000; + assert(!endorsement_sign(msg, sizeof(msg), signature, &signature_length)); + + assert(G_mock_config.oe_get_evidence_buffer_freed); +} + +void test_signature_err_evidencebroken() { + setup(); + + G_mock_config.oe_get_evidence_buffer_size = 1000; + assert(!endorsement_sign(msg, sizeof(msg), signature, &signature_length)); + + assert(G_mock_config.oe_get_evidence_buffer_freed); +} + +void test_get_envelope_ok() { + setup_and_sign(); + assert(!memcmp(endorsement_get_envelope(), + mock_evidence, + sizeof(sgx_quote_t) - sizeof(uint32_t))); + assert(!memcmp(endorsement_get_envelope() + sizeof(sgx_quote_t), + mock_evidence + sizeof(sgx_quote_t), + endorsement_get_envelope_length() - sizeof(sgx_quote_t) - + sizeof(msg))); + assert(!memcmp(endorsement_get_envelope() + + endorsement_get_envelope_length() - sizeof(msg), + msg, + sizeof(msg))); +} + +void test_get_envelope_nosignature() { + setup(); + assert(endorsement_get_envelope() == NULL); + assert(endorsement_get_envelope_length() == 0); +} + +void test_get_code_hash_ok() { + setup_and_sign(); + + uint8_t expected_code_hash[] = { + 0xd3, 0x26, 0x88, 0xd3, 0xc1, 0xf3, 0xdf, 0xcc, 0x8b, 0x0b, 0x36, + 0xea, 0xc7, 0xc8, 0x9d, 0x49, 0xaf, 0x33, 0x18, 0x00, 0xbd, 0x56, + 0x24, 0x80, 0x44, 0x16, 0x6f, 0xa6, 0x69, 0x94, 0x42, 0xc1}; + + uint8_t code_hash[sizeof(expected_code_hash) + 10]; + uint8_t code_hash_length = sizeof(code_hash); + + assert(endorsement_get_code_hash(code_hash, &code_hash_length)); + assert(code_hash_length == sizeof(expected_code_hash)); + assert(!memcmp(code_hash, expected_code_hash, sizeof(expected_code_hash))); +} + +void test_get_code_hash_err_nullbuf() { + setup_and_sign(); + + uint8_t* code_hash = NULL; + uint8_t code_hash_length = 100; + + assert(!endorsement_get_code_hash(code_hash, &code_hash_length)); + assert(code_hash_length == 100); +} + +void test_get_code_hash_err_nosignature() { + setup(); + + uint8_t code_hash[123]; + uint8_t code_hash_length = sizeof(code_hash); + + assert(!endorsement_get_code_hash(code_hash, &code_hash_length)); + assert(code_hash_length == sizeof(code_hash)); +} + +void test_get_code_hash_err_buftoosmall() { + setup_and_sign(); + + uint8_t code_hash[10]; + uint8_t code_hash_length = sizeof(code_hash); + + assert(!endorsement_get_code_hash(code_hash, &code_hash_length)); + assert(code_hash_length == sizeof(code_hash)); +} + +void test_get_public_key_ok() { + setup_and_sign(); + + uint8_t expected_public_key[] = { + 0x04, 0xa0, 0x24, 0xcb, 0x34, 0xc9, 0x0e, 0xa6, 0xa8, 0xf9, 0xf2, + 0x18, 0x1c, 0x90, 0x20, 0xcb, 0xcc, 0x7c, 0x07, 0x3e, 0x69, 0x98, + 0x17, 0x33, 0xc8, 0xde, 0xed, 0x6f, 0x6c, 0x45, 0x18, 0x22, 0xaa, + 0x08, 0x37, 0x63, 0x50, 0xff, 0x7d, 0xa0, 0x1f, 0x84, 0x2b, 0xb4, + 0x0c, 0x63, 0x1c, 0xbb, 0x71, 0x1f, 0x8b, 0x6f, 0x7a, 0x4f, 0xae, + 0x39, 0x83, 0x20, 0xa3, 0x88, 0x47, 0x74, 0xd2, 0x50, 0xad}; + + uint8_t public_key[sizeof(expected_public_key) + 10]; + uint8_t public_key_length = sizeof(public_key); + + assert(endorsement_get_public_key(public_key, &public_key_length)); + assert(public_key_length == sizeof(expected_public_key)); + assert( + !memcmp(public_key, expected_public_key, sizeof(expected_public_key))); +} + +void test_get_public_key_err_nullbuf() { + setup_and_sign(); + + uint8_t* public_key = NULL; + uint8_t public_key_length = 100; + + assert(!endorsement_get_public_key(public_key, &public_key_length)); + assert(public_key_length == 100); +} + +void test_get_public_key_err_nosignature() { + setup(); + + uint8_t public_key[123]; + uint8_t public_key_length = sizeof(public_key); + + assert(!endorsement_get_public_key(public_key, &public_key_length)); + assert(public_key_length == sizeof(public_key)); +} + +void test_get_public_key_err_buftoosmall() { + setup_and_sign(); + + uint8_t public_key[10]; + uint8_t public_key_length = sizeof(public_key); + + assert(!endorsement_get_public_key(public_key, &public_key_length)); + assert(public_key_length == sizeof(public_key)); +} + +int main() { + printf("Testing endorsement_init()...\n"); + test_endorsement_init_ok(); + test_endorsement_init_err_attinit(); + test_endorsement_init_err_verinit(); + test_endorsement_init_err_selfmt(); + test_endorsement_init_err_getfmt(); + + printf("Testing endorsement_sign()...\n"); + test_signature_ok(); + test_signature_err_notinit(); + test_signature_err_sigbuftoosmall(); + test_signature_err_evibuftoobig(); + test_signature_err_evidencebroken(); + + printf("Testing endorsement_get_envelope()...\n"); + test_get_envelope_ok(); + test_get_envelope_nosignature(); + + printf("Testing endorsement_get_code_hash()...\n"); + test_get_code_hash_ok(); + test_get_code_hash_err_nullbuf(); + test_get_code_hash_err_nosignature(); + test_get_code_hash_err_buftoosmall(); + + printf("Testing endorsement_get_public_key()...\n"); + test_get_public_key_ok(); + test_get_public_key_err_nullbuf(); + test_get_public_key_err_nosignature(); + test_get_public_key_err_buftoosmall(); +} diff --git a/firmware/src/hal/sgx/test/mock/openenclave/attestation/attester.h b/firmware/src/hal/sgx/test/mock/openenclave/attestation/attester.h new file mode 120000 index 00000000..98e8e7ca --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/attestation/attester.h @@ -0,0 +1 @@ +../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/attestation/sgx/evidence.h b/firmware/src/hal/sgx/test/mock/openenclave/attestation/sgx/evidence.h new file mode 120000 index 00000000..b84129c3 --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/attestation/sgx/evidence.h @@ -0,0 +1 @@ +../../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/attestation/verifier.h b/firmware/src/hal/sgx/test/mock/openenclave/attestation/verifier.h new file mode 120000 index 00000000..98e8e7ca --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/attestation/verifier.h @@ -0,0 +1 @@ +../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/bits/attestation.h b/firmware/src/hal/sgx/test/mock/openenclave/bits/attestation.h new file mode 120000 index 00000000..98e8e7ca --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/bits/attestation.h @@ -0,0 +1 @@ +../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/bits/defs.h b/firmware/src/hal/sgx/test/mock/openenclave/bits/defs.h new file mode 120000 index 00000000..98e8e7ca --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/bits/defs.h @@ -0,0 +1 @@ +../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/bits/sgx/sgxtypes.h b/firmware/src/hal/sgx/test/mock/openenclave/bits/sgx/sgxtypes.h new file mode 120000 index 00000000..b84129c3 --- /dev/null +++ b/firmware/src/hal/sgx/test/mock/openenclave/bits/sgx/sgxtypes.h @@ -0,0 +1 @@ +../../common.h \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/mock/openenclave/common.h b/firmware/src/hal/sgx/test/mock/openenclave/common.h index 54a3fc35..6d04665d 100644 --- a/firmware/src/hal/sgx/test/mock/openenclave/common.h +++ b/firmware/src/hal/sgx/test/mock/openenclave/common.h @@ -25,11 +25,220 @@ #ifndef __MOCK_OE_COMMON_H #define __MOCK_OE_COMMON_H -typedef enum oe_result { +#include +#include + +// Taken from OpenEnclave's include/openenclave/bits/defs.h + +#define OE_PACK_BEGIN _Pragma("pack(push, 1)") +#define OE_PACK_END _Pragma("pack(pop)") + +// Taken from OpenEnclave's include/openenclave/bits/result.h + +typedef enum _oe_result { OE_OK, OE_FAILURE, } oe_result_t; #define oe_result_str(result) ((result) == OE_OK ? "OE_OK" : "OE_FAILURE") +// Taken from OpenEnclave's include/openenclave/bits/sgx/sgxtypes.h + +#define SGX_USERDATA_SIZE 20 +#define OE_ZERO_SIZED_ARRAY +#define OE_SHA256_SIZE 32 +#define SGX_CPUSVN_SIZE 16 +#define OE_INLINE + +OE_PACK_BEGIN +typedef struct _sgx_report_data { + unsigned char field[64]; +} sgx_report_data_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_qe_auth_data { + uint16_t size; + uint8_t* data; +} sgx_qe_auth_data_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_qe_cert_data { + uint16_t type; + uint32_t size; + uint8_t* data; +} sgx_qe_cert_data_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_attributes { + uint64_t flags; + uint64_t xfrm; +} sgx_attributes_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_report_body { + /* (0) CPU security version */ + uint8_t cpusvn[SGX_CPUSVN_SIZE]; + + /* (16) Selector for which fields are defined in SSA.MISC */ + uint32_t miscselect; + + /* (20) Reserved */ + uint8_t reserved1[12]; + + /* (32) Enclave extended product ID */ + uint8_t isvextprodid[16]; + + /* (48) Enclave attributes */ + sgx_attributes_t attributes; + + /* (64) Enclave measurement */ + uint8_t mrenclave[OE_SHA256_SIZE]; + + /* (96) Reserved */ + uint8_t reserved2[32]; + + /* (128) The value of the enclave's SIGNER measurement */ + uint8_t mrsigner[OE_SHA256_SIZE]; + + /* (160) Reserved */ + uint8_t reserved3[32]; + + /* (192) Enclave Configuration ID*/ + uint8_t configid[64]; + + /* (256) Enclave product ID */ + uint16_t isvprodid; + + /* (258) Enclave security version */ + uint16_t isvsvn; + + /* (260) Enclave Configuration Security Version*/ + uint16_t configsvn; + + /* (262) Reserved */ + uint8_t reserved4[42]; + + /* (304) Enclave family ID */ + uint8_t isvfamilyid[16]; + + /* (320) User report data */ + sgx_report_data_t report_data; +} sgx_report_body_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_quote { + /* (0) */ + uint16_t version; + + /* (2) */ + uint16_t sign_type; + + /* (4) */ + uint32_t tee_type; + + /* (8) */ + uint16_t qe_svn; + + /* (10) */ + uint16_t pce_svn; + + /* (12) */ + uint8_t uuid[16]; + + /* (28) */ + uint8_t user_data[SGX_USERDATA_SIZE]; + + /* (48) */ + sgx_report_body_t report_body; + + /* (432) */ + uint32_t signature_len; + + /* (436) signature array (varying length) */ + OE_ZERO_SIZED_ARRAY uint8_t signature[]; +} sgx_quote_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_ecdsa256_signature { + uint8_t r[32]; + uint8_t s[32]; +} sgx_ecdsa256_signature_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_ecdsa256_key { + uint8_t x[32]; + uint8_t y[32]; +} sgx_ecdsa256_key_t; +OE_PACK_END + +OE_PACK_BEGIN +typedef struct _sgx_quote_auth_data { + /* (0) Pair of 256 bit ECDSA Signature. */ + sgx_ecdsa256_signature_t signature; + + /* (64) Pair of 256 bit ECDSA Key. */ + sgx_ecdsa256_key_t attestation_key; + + /* (128) Quoting Enclave Report Body */ + sgx_report_body_t qe_report_body; + + /* (512) Quoting Enclave Report Body Signature */ + sgx_ecdsa256_signature_t qe_report_body_signature; +} sgx_quote_auth_data_t; +OE_PACK_END + +// Taken from OpenEnclave's include/openenclave/bits/evidence.h + +#define OE_FORMAT_UUID_SGX_ECDSA \ + { \ + 0xa3, 0xa2, 0x1e, 0x87, 0x1b, 0x4d, 0x40, 0x14, 0xb7, 0x0a, 0xa1, \ + 0x25, 0xd2, 0xfb, 0xcd, 0x8c \ + } + +#define OE_UUID_SIZE 16 + +typedef struct _oe_uuid_t { + uint8_t b[OE_UUID_SIZE]; +} oe_uuid_t; + +// Taken from OpenEnclave's include/openenclave/attestation/attester.h + +oe_result_t oe_attester_initialize(void); + +oe_result_t oe_attester_select_format(const oe_uuid_t* format_ids, + size_t format_ids_length, + oe_uuid_t* selected_format_id); + +oe_result_t oe_get_evidence(const oe_uuid_t* format_id, + uint32_t flags, + const void* custom_claims_buffer, + size_t custom_claims_buffer_size, + const void* optional_parameters, + size_t optional_parameters_size, + uint8_t** evidence_buffer, + size_t* evidence_buffer_size, + uint8_t** endorsements_buffer, + size_t* endorsements_buffer_size); + +oe_result_t oe_free_evidence(uint8_t* evidence_buffer); + +oe_result_t oe_attester_shutdown(void); + +// Taken from OpenEnclave's include/openenclave/attestation/verifier.h + +oe_result_t oe_verifier_initialize(void); + +oe_result_t oe_verifier_get_format_settings(const oe_uuid_t* format_id, + uint8_t** settings, + size_t* settings_size); + +oe_result_t oe_verifier_shutdown(void); + #endif // #ifndef __MOCK_OE_COMMON_H \ No newline at end of file diff --git a/firmware/src/hal/sgx/test/run-all.sh b/firmware/src/hal/sgx/test/run-all.sh index d059b586..1016ef1b 100755 --- a/firmware/src/hal/sgx/test/run-all.sh +++ b/firmware/src/hal/sgx/test/run-all.sh @@ -2,7 +2,7 @@ if [[ $1 == "exec" ]]; then BASEDIR=$(realpath $(dirname $0)) - TESTDIRS="nvmem secret_store seed" + TESTDIRS="der_utils endorsement nvmem secret_store seed" for d in $TESTDIRS; do echo "******************************" echo "Testing $d..." diff --git a/firmware/src/sgx/src/hsm.edl b/firmware/src/sgx/src/hsm.edl index 9f62a8ba..6411e48a 100644 --- a/firmware/src/sgx/src/hsm.edl +++ b/firmware/src/sgx/src/hsm.edl @@ -9,6 +9,8 @@ enclave { trusted { public bool ecall_system_init(unsigned char *msg_buffer, size_t msg_buffer_size); + public void ecall_system_finalise(); + public unsigned int ecall_system_process_apdu(unsigned int rx); }; diff --git a/firmware/src/sgx/src/trusted/ecall.c b/firmware/src/sgx/src/trusted/ecall.c index cf5c89d4..97f66a76 100644 --- a/firmware/src/sgx/src/trusted/ecall.c +++ b/firmware/src/sgx/src/trusted/ecall.c @@ -32,14 +32,20 @@ #include "hal/log.h" bool ecall_system_init(unsigned char *msg_buffer, size_t msg_buffer_size) { - SYNC_AQUIRE_LOCK(); + SYNC_AQUIRE_LOCK(false); bool success = system_init(msg_buffer, msg_buffer_size); SYNC_RELEASE_LOCK(); return success; } -unsigned int ecall_system_process_apdu(unsigned int rx) { +void ecall_system_finalise() { SYNC_AQUIRE_LOCK(); + system_finalise(); + SYNC_RELEASE_LOCK(); +} + +unsigned int ecall_system_process_apdu(unsigned int rx) { + SYNC_AQUIRE_LOCK(0); unsigned int result = system_process_apdu(rx); SYNC_RELEASE_LOCK(); return result; diff --git a/firmware/src/sgx/src/trusted/ecall.h b/firmware/src/sgx/src/trusted/ecall.h index f5373272..c25910f1 100644 --- a/firmware/src/sgx/src/trusted/ecall.h +++ b/firmware/src/sgx/src/trusted/ecall.h @@ -37,6 +37,11 @@ */ bool ecall_system_init(unsigned char *msg_buffer, size_t msg_buffer_size); +/** + * @brief See system_finalise in system.h + */ +void ecall_system_finalise(); + /** * @brief See system_process_apdu in system.h */ diff --git a/firmware/src/sgx/src/trusted/sync.h b/firmware/src/sgx/src/trusted/sync.h index 853925ff..b079d280 100644 --- a/firmware/src/sgx/src/trusted/sync.h +++ b/firmware/src/sgx/src/trusted/sync.h @@ -28,10 +28,10 @@ #include #include "hal/log.h" -#define SYNC_AQUIRE_LOCK() \ +#define SYNC_AQUIRE_LOCK(err_res) \ if (!sync_try_aqcuire_lock()) { \ LOG("Failed to acquire lock, ecall %s was not executed!\n", __func__); \ - return false; \ + return err_res; \ } #define SYNC_RELEASE_LOCK() sync_release_lock() diff --git a/firmware/src/sgx/src/trusted/system.c b/firmware/src/sgx/src/trusted/system.c index 0f5d4a1b..09fe938c 100644 --- a/firmware/src/sgx/src/trusted/system.c +++ b/firmware/src/sgx/src/trusted/system.c @@ -233,3 +233,8 @@ bool system_init(unsigned char *msg_buffer, size_t msg_buffer_size) { return true; } + +void system_finalise() { + // Finalise modules + endorsement_finalise(); +} diff --git a/firmware/src/sgx/src/trusted/system.h b/firmware/src/sgx/src/trusted/system.h index e571e136..d07a1fd4 100644 --- a/firmware/src/sgx/src/trusted/system.h +++ b/firmware/src/sgx/src/trusted/system.h @@ -35,6 +35,11 @@ */ bool system_init(unsigned char *msg_buffer, size_t msg_buffer_size); +/** + * @brief Finalises the system module + */ +void system_finalise(); + /** * @brief Process an APDU message * diff --git a/firmware/src/sgx/src/untrusted/enclave_proxy.c b/firmware/src/sgx/src/untrusted/enclave_proxy.c index 6e402b56..ee901026 100644 --- a/firmware/src/sgx/src/untrusted/enclave_proxy.c +++ b/firmware/src/sgx/src/untrusted/enclave_proxy.c @@ -37,6 +37,21 @@ bool eprx_system_init(unsigned char *msg_buffer, size_t msg_buffer_size) { return result; } +void eprx_system_finalise() { + oe_enclave_t *enclave = epro_get_enclave(); + if (enclave == NULL) { + LOG("Failed to retrieve the enclave. " + "Unable to call system_finalise().\n"); + return; + } + + oe_result_t oe_result = ecall_system_finalise(enclave); + if (OE_OK != oe_result) { + LOG("Failed to call system_finalise(): oe_result=%u (%s)\n", + oe_result, oe_result_str(oe_result)); + } +} + unsigned int eprx_system_process_apdu(unsigned int rx) { oe_enclave_t *enclave = epro_get_enclave(); if (enclave == NULL) { diff --git a/firmware/src/sgx/src/untrusted/enclave_proxy.h b/firmware/src/sgx/src/untrusted/enclave_proxy.h index 4565ab12..43e59cd5 100644 --- a/firmware/src/sgx/src/untrusted/enclave_proxy.h +++ b/firmware/src/sgx/src/untrusted/enclave_proxy.h @@ -8,6 +8,11 @@ */ bool eprx_system_init(unsigned char *msg_buffer, size_t msg_buffer_size); +/** + * @brief See system_finalise in system.h within the trusted sources + */ +void eprx_system_finalise(); + /** * @brief See system_process_apdu in system.h within the trusted sources */ diff --git a/firmware/src/sgx/src/untrusted/main.c b/firmware/src/sgx/src/untrusted/main.c index 56dfc1fd..9251ef1a 100644 --- a/firmware/src/sgx/src/untrusted/main.c +++ b/firmware/src/sgx/src/untrusted/main.c @@ -96,8 +96,8 @@ static struct argp argp = { static void finalise_with(int exit_code) { printf("Terminating...\n"); + eprx_system_finalise(); io_finalise(); - // TODO: finalize enclave, i/o printf("Done. Bye.\n"); exit(exit_code); } diff --git a/firmware/src/sgx/test/system/test_system.c b/firmware/src/sgx/test/system/test_system.c index b0c0b760..d49fdf3d 100644 --- a/firmware/src/sgx/test/system/test_system.c +++ b/firmware/src/sgx/test/system/test_system.c @@ -276,6 +276,10 @@ bool endorsement_init() { return true; } +void endorsement_finalise() { + // Nothing to do here +} + void nvmem_init() { NUM_CALLS(nvmem_init)++; }