[Assignment-7] add SGX sample code from VM
All checks were successful
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m2s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (push) Successful in 1m3s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (push) Successful in 1m0s
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 30s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 10s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 8s
All checks were successful
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m2s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (push) Successful in 1m3s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (push) Successful in 1m0s
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 30s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 10s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 8s
This commit is contained in:
parent
5616ddc4e5
commit
ba8e969470
163 changed files with 24030 additions and 0 deletions
|
|
@ -0,0 +1,151 @@
|
|||
######## SGX SDK Settings ########
|
||||
SGX_SDK ?= /opt/intel/sgxsdk
|
||||
SGX_MODE ?= SIM
|
||||
SGX_ARCH ?= x64
|
||||
|
||||
ifeq ($(shell getconf LONG_BIT), 32)
|
||||
SGX_ARCH := x86
|
||||
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
|
||||
SGX_ARCH := x86
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_ARCH), x86)
|
||||
SGX_COMMON_CFLAGS := -m32
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
|
||||
else
|
||||
SGX_COMMON_CFLAGS := -m64
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
ifeq ($(SGX_PRERELEASE), 1)
|
||||
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
SGX_COMMON_CFLAGS += -O0 -g
|
||||
else
|
||||
SGX_COMMON_CFLAGS += -O2
|
||||
endif
|
||||
|
||||
ifeq ($(SUPPLIED_KEY_DERIVATION), 1)
|
||||
SGX_COMMON_CFLAGS += -DSUPPLIED_KEY_DERIVATION
|
||||
endif
|
||||
|
||||
|
||||
######## App Settings ########
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
Urts_Library_Name := sgx_urts_sim
|
||||
else
|
||||
Urts_Library_Name := sgx_urts
|
||||
endif
|
||||
|
||||
App_Cpp_Files := isv_app/isv_app.cpp ../Util/LogBase.cpp ../Networking/NetworkManager.cpp \
|
||||
../Networking/Session.cpp ../Networking/Client.cpp ../Networking/Server.cpp isv_app/VerificationManager.cpp ../Networking/NetworkManagerClient.cpp \
|
||||
../GoogleMessages/Messages.pb.cpp ../Networking/AbstractNetworkOps.cpp ../Util/UtilityFunctions.cpp ../WebService/WebService.cpp \
|
||||
../Util/Base64.cpp
|
||||
|
||||
App_Include_Paths := -Iservice_provider -I$(SGX_SDK)/include -Iheaders -I../Util -I../Networking -Iisv_app -I../GoogleMessages -I/usr/local/include -I../WebService
|
||||
|
||||
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
|
||||
|
||||
# Three configuration modes - Debug, prerelease, release
|
||||
# Debug - Macro DEBUG enabled.
|
||||
# Prerelease - Macro NDEBUG and EDEBUG enabled.
|
||||
# Release - Macro NDEBUG enabled.
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
|
||||
else ifeq ($(SGX_PRERELEASE), 1)
|
||||
App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
|
||||
else
|
||||
App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
|
||||
endif
|
||||
|
||||
App_Cpp_Flags := $(App_C_Flags) -std=c++11 -DEnableClient
|
||||
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -L. -lsgx_ukey_exchange -lpthread -lservice_provider \
|
||||
-Wl,-rpath=$(CURDIR)/sample_libcrypto -Wl,-rpath=$(CURDIR) -llog4cpp -lboost_system -L/usr/lib -lssl -lcrypto -lboost_thread -lprotobuf -L /usr/local/lib -ljsoncpp -lcurl
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
App_Link_Flags += -lsgx_uae_service_sim
|
||||
else
|
||||
App_Link_Flags += -lsgx_uae_service
|
||||
endif
|
||||
|
||||
App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
|
||||
|
||||
App_Name := app
|
||||
|
||||
|
||||
|
||||
######## Service Provider Settings ########
|
||||
ServiceProvider_Cpp_Files := service_provider/ecp.cpp ../Util/LogBase.cpp \
|
||||
service_provider/ias_ra.cpp ../Util/UtilityFunctions.cpp ../WebService/WebService.cpp service_provider/ServiceProvider.cpp
|
||||
|
||||
ServiceProvider_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -Isample_libcrypto
|
||||
|
||||
ServiceProvider_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes -I$(SGX_SDK)/include -Isample_libcrypto -I/usr/local/include -I../GoogleMessages -I../Util \
|
||||
-I../WebService -I../Networking
|
||||
|
||||
ServiceProvider_Cpp_Flags := $(ServiceProvider_C_Flags) -std=c++11
|
||||
ServiceProvider_Link_Flags := -shared $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -lsample_libcrypto -Lsample_libcrypto -llog4cpp
|
||||
|
||||
ServiceProvider_Cpp_Objects := $(ServiceProvider_Cpp_Files:.cpp=.o)
|
||||
|
||||
.PHONY: all run
|
||||
|
||||
all: libservice_provider.so $(App_Name)
|
||||
|
||||
|
||||
|
||||
######## App Objects ########
|
||||
isv_app/%.o: isv_app/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
../Util/%.o: ../Util/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
../Networking/%.o: ../Networking/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
../GoogleMessages/%.o: ../GoogleMessages/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
../WebService/%.o: ../WebService/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
CertificateHandler/%.o: CertificateHandler/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
$(App_Name): $(App_Cpp_Objects)
|
||||
@$(CXX) $^ -o $@ $(App_Link_Flags)
|
||||
@echo "LINK => $@"
|
||||
|
||||
|
||||
|
||||
######## Service Provider Objects ########
|
||||
service_provider/%.o: service_provider/%.cpp
|
||||
@$(CXX) $(ServiceProvider_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
libservice_provider.so: $(ServiceProvider_Cpp_Objects)
|
||||
@$(CXX) $^ -o $@ $(ServiceProvider_Link_Flags)
|
||||
@echo "LINK => $@"
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) isv_app/isv_enclave_u.* $(Enclave_Cpp_Objects) isv_enclave/isv_enclave_t.* libservice_provider.* $(ServiceProvider_Cpp_Objects)
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
#include "VerificationManager.h"
|
||||
#include "../GeneralSettings.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
using namespace util;
|
||||
using namespace std;
|
||||
|
||||
VerificationManager* VerificationManager::instance = NULL;
|
||||
|
||||
VerificationManager::VerificationManager() {
|
||||
this->nm = NetworkManagerClient::getInstance(Settings::rh_port, Settings::rh_host);
|
||||
this->ws = WebService::getInstance();
|
||||
this->ws->init();
|
||||
this->sp = new ServiceProvider(this->ws);
|
||||
}
|
||||
|
||||
|
||||
VerificationManager::~VerificationManager() {}
|
||||
|
||||
|
||||
VerificationManager* VerificationManager::getInstance() {
|
||||
if (instance == NULL) {
|
||||
instance = new VerificationManager();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
int VerificationManager::init() {
|
||||
if (this->sp) {
|
||||
delete this->sp;
|
||||
this->sp = new ServiceProvider(this->ws);
|
||||
}
|
||||
|
||||
this->nm->Init();
|
||||
this->nm->connectCallbackHandler([this](string v, int type) {
|
||||
return this->incomingHandler(v, type);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void VerificationManager::start() {
|
||||
this->nm->startService();
|
||||
Log("Remote attestation done");
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::handleMSG0(Messages::MessageMsg0 msg) {
|
||||
Log("MSG0 received");
|
||||
|
||||
if (msg.status() != TYPE_TERMINATE) {
|
||||
uint32_t extended_epid_group_id = msg.epid();
|
||||
int ret = this->sp->sp_ra_proc_msg0_req(extended_epid_group_id);
|
||||
|
||||
if (ret == 0) {
|
||||
msg.set_status(TYPE_OK);
|
||||
return nm->serialize(msg);
|
||||
}
|
||||
} else {
|
||||
Log("Termination received!");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::handleMSG1(Messages::MessageMSG1 msg1) {
|
||||
Log("MSG1 received");
|
||||
|
||||
Messages::MessageMSG2 msg2;
|
||||
msg2.set_type(RA_MSG2);
|
||||
|
||||
int ret = this->sp->sp_ra_proc_msg1_req(msg1, &msg2);
|
||||
|
||||
if (ret != 0) {
|
||||
Log("Error, processing MSG1 failed");
|
||||
} else {
|
||||
Log("MSG1 processed correctly and MSG2 created");
|
||||
return nm->serialize(msg2);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::handleMSG3(Messages::MessageMSG3 msg) {
|
||||
Log("MSG3 received");
|
||||
|
||||
Messages::AttestationMessage att_msg;
|
||||
att_msg.set_type(RA_ATT_RESULT);
|
||||
|
||||
int ret = this->sp->sp_ra_proc_msg3_req(msg, &att_msg);
|
||||
|
||||
if (ret == -1) {
|
||||
Log("Error, processing MSG3 failed");
|
||||
} else {
|
||||
Log("MSG3 processed correctly and attestation result created");
|
||||
return nm->serialize(att_msg);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::handleAppAttOk() {
|
||||
Log("APP attestation result received");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::prepareVerificationRequest() {
|
||||
Log("Prepare Verification request");
|
||||
|
||||
Messages::InitialMessage msg;
|
||||
msg.set_type(RA_VERIFICATION);
|
||||
|
||||
return nm->serialize(msg);
|
||||
}
|
||||
|
||||
|
||||
string VerificationManager::createInitMsg(int type, string msg) {
|
||||
Messages::InitialMessage init_msg;
|
||||
init_msg.set_type(type);
|
||||
init_msg.set_size(msg.size());
|
||||
|
||||
return nm->serialize(init_msg);
|
||||
}
|
||||
|
||||
|
||||
vector<string> VerificationManager::incomingHandler(string v, int type) {
|
||||
vector<string> res;
|
||||
|
||||
if (!v.empty()) {
|
||||
string s;
|
||||
bool ret;
|
||||
|
||||
switch (type) {
|
||||
case RA_MSG0: {
|
||||
Messages::MessageMsg0 msg0;
|
||||
ret = msg0.ParseFromString(v);
|
||||
if (ret && (msg0.type() == RA_MSG0)) {
|
||||
s = this->handleMSG0(msg0);
|
||||
res.push_back(to_string(RA_MSG0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RA_MSG1: {
|
||||
Messages::MessageMSG1 msg1;
|
||||
ret = msg1.ParseFromString(v);
|
||||
if (ret && (msg1.type() == RA_MSG1)) {
|
||||
s = this->handleMSG1(msg1);
|
||||
res.push_back(to_string(RA_MSG2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RA_MSG3: {
|
||||
Messages::MessageMSG3 msg3;
|
||||
ret = msg3.ParseFromString(v);
|
||||
if (ret && (msg3.type() == RA_MSG3)) {
|
||||
s = this->handleMSG3(msg3);
|
||||
res.push_back(to_string(RA_ATT_RESULT));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RA_APP_ATT_OK: {
|
||||
Messages::SecretMessage sec_msg;
|
||||
ret = sec_msg.ParseFromString(v);
|
||||
if (ret) {
|
||||
if (sec_msg.type() == RA_APP_ATT_OK) {
|
||||
this->handleAppAttOk();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log("Unknown type: %d", type, log::error);
|
||||
break;
|
||||
}
|
||||
|
||||
res.push_back(s);
|
||||
} else { //after handshake
|
||||
res.push_back(to_string(RA_VERIFICATION));
|
||||
res.push_back(this->prepareVerificationRequest());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef VERIFICATIONMANAGER_H
|
||||
#define VERIFICATIONMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ServiceProvider.h"
|
||||
#include "NetworkManagerClient.h"
|
||||
#include "LogBase.h"
|
||||
#include "Messages.pb.h"
|
||||
#include "WebService.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class VerificationManager {
|
||||
|
||||
public:
|
||||
static VerificationManager* getInstance();
|
||||
virtual ~VerificationManager();
|
||||
int init();
|
||||
vector<string> incomingHandler(string v, int type);
|
||||
void start();
|
||||
|
||||
private:
|
||||
VerificationManager();
|
||||
string prepareVerificationRequest();
|
||||
string handleMSG0(Messages::MessageMsg0 m);
|
||||
string handleMSG1(Messages::MessageMSG1 msg);
|
||||
string handleMSG3(Messages::MessageMSG3 msg);
|
||||
string createInitMsg(int type, string msg);
|
||||
string handleAppAttOk();
|
||||
|
||||
private:
|
||||
static VerificationManager* instance;
|
||||
NetworkManagerClient *nm = NULL;
|
||||
ServiceProvider *sp = NULL;
|
||||
WebService *ws = NULL;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "LogBase.h"
|
||||
#include "NetworkManager.h"
|
||||
#include "VerificationManager.h"
|
||||
#include "UtilityFunctions.h"
|
||||
|
||||
using namespace util;
|
||||
|
||||
int Main(int argc, char *argv[]) {
|
||||
LogBase::Inst();
|
||||
|
||||
int ret = 0;
|
||||
|
||||
VerificationManager *vm = VerificationManager::getInstance();
|
||||
vm->init();
|
||||
vm->start();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
try {
|
||||
int ret = Main(argc, argv);
|
||||
return ret;
|
||||
} catch (std::exception & e) {
|
||||
Log("exception: %s", e.what());
|
||||
} catch (...) {
|
||||
Log("unexpected exception");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* File: sample_libcrypto.h
|
||||
* Description:
|
||||
* Interface for generic crypto library APIs.
|
||||
* Do NOT use this library in your actual product.
|
||||
* The purpose of this sample library is to aid the debugging of a
|
||||
* remote attestation service.
|
||||
* To achieve that goal, the sample remote attestation application
|
||||
* will use this sample library to generate reproducible messages.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLE_LIBCRYPTO_H
|
||||
#define SAMPLE_LIBCRYPTO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum sample_status_t
|
||||
{
|
||||
SAMPLE_SUCCESS = 0,
|
||||
|
||||
SAMPLE_ERROR_UNEXPECTED , // Unexpected error
|
||||
SAMPLE_ERROR_INVALID_PARAMETER , // The parameter is incorrect
|
||||
SAMPLE_ERROR_OUT_OF_MEMORY , // Not enough memory is available to complete this operation
|
||||
|
||||
} sample_status_t;
|
||||
|
||||
#define SAMPLE_SHA256_HASH_SIZE 32
|
||||
#define SAMPLE_ECP256_KEY_SIZE 32
|
||||
#define SAMPLE_NISTP_ECP256_KEY_SIZE (SAMPLE_ECP256_KEY_SIZE/sizeof(uint32_t))
|
||||
#define SAMPLE_AESGCM_IV_SIZE 12
|
||||
#define SAMPLE_AESGCM_KEY_SIZE 16
|
||||
#define SAMPLE_AESGCM_MAC_SIZE 16
|
||||
#define SAMPLE_CMAC_KEY_SIZE 16
|
||||
#define SAMPLE_CMAC_MAC_SIZE 16
|
||||
#define SAMPLE_AESCTR_KEY_SIZE 16
|
||||
|
||||
typedef struct sample_ec256_dh_shared_t
|
||||
{
|
||||
uint8_t s[SAMPLE_ECP256_KEY_SIZE];
|
||||
} sample_ec256_dh_shared_t;
|
||||
|
||||
typedef struct sample_ec256_private_t
|
||||
{
|
||||
uint8_t r[SAMPLE_ECP256_KEY_SIZE];
|
||||
} sample_ec256_private_t;
|
||||
|
||||
typedef struct sample_ec256_public_t
|
||||
{
|
||||
uint8_t gx[SAMPLE_ECP256_KEY_SIZE];
|
||||
uint8_t gy[SAMPLE_ECP256_KEY_SIZE];
|
||||
} sample_ec256_public_t;
|
||||
|
||||
typedef struct sample_ec256_signature_t
|
||||
{
|
||||
uint32_t x[SAMPLE_NISTP_ECP256_KEY_SIZE];
|
||||
uint32_t y[SAMPLE_NISTP_ECP256_KEY_SIZE];
|
||||
} sample_ec256_signature_t;
|
||||
|
||||
typedef void* sample_sha_state_handle_t;
|
||||
typedef void* sample_cmac_state_handle_t;
|
||||
typedef void* sample_ecc_state_handle_t;
|
||||
|
||||
typedef uint8_t sample_sha256_hash_t[SAMPLE_SHA256_HASH_SIZE];
|
||||
|
||||
typedef uint8_t sample_aes_gcm_128bit_key_t[SAMPLE_AESGCM_KEY_SIZE];
|
||||
typedef uint8_t sample_aes_gcm_128bit_tag_t[SAMPLE_AESGCM_MAC_SIZE];
|
||||
typedef uint8_t sample_cmac_128bit_key_t[SAMPLE_CMAC_KEY_SIZE];
|
||||
typedef uint8_t sample_cmac_128bit_tag_t[SAMPLE_CMAC_MAC_SIZE];
|
||||
typedef uint8_t sample_aes_ctr_128bit_key_t[SAMPLE_AESCTR_KEY_SIZE];
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C
|
||||
#endif
|
||||
|
||||
#define SAMPLE_LIBCRYPTO_API EXTERN_C
|
||||
|
||||
/* Rijndael AES-GCM
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Inputs: sample_aes_gcm_128bit_key_t *p_key - Pointer to key used in encryption/decryption operation
|
||||
* uint8_t *p_src - Pointer to input stream to be encrypted/decrypted
|
||||
* uint32_t src_len - Length of input stream to be encrypted/decrypted
|
||||
* uint8_t *p_iv - Pointer to initialization vector to use
|
||||
* uint32_t iv_len - Length of initialization vector
|
||||
* uint8_t *p_aad - Pointer to input stream of additional authentication data
|
||||
* uint32_t aad_len - Length of additional authentication data stream
|
||||
* sample_aes_gcm_128bit_tag_t *p_in_mac - Pointer to expected MAC in decryption process
|
||||
* Output: uint8_t *p_dst - Pointer to cipher text. Size of buffer should be >= src_len.
|
||||
* sample_aes_gcm_128bit_tag_t *p_out_mac - Pointer to MAC generated from encryption process
|
||||
* NOTE: Wrapper is responsible for confirming decryption tag matches encryption tag */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_rijndael128GCM_encrypt(const sample_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
|
||||
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
|
||||
sample_aes_gcm_128bit_tag_t *p_out_mac);
|
||||
|
||||
/* Message Authentication - Rijndael 128 CMAC
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Inputs: sample_cmac_128bit_key_t *p_key - Pointer to key used in encryption/decryption operation
|
||||
* uint8_t *p_src - Pointer to input stream to be MAC
|
||||
* uint32_t src_len - Length of input stream to be MAC
|
||||
* Output: sample_cmac_gcm_128bit_tag_t *p_mac - Pointer to resultant MAC */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_rijndael128_cmac_msg(const sample_cmac_128bit_key_t *p_key, const uint8_t *p_src,
|
||||
uint32_t src_len, sample_cmac_128bit_tag_t *p_mac);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Elliptic Curve Crytpography - Based on GF(p), 256 bit
|
||||
*/
|
||||
/* Allocates and initializes ecc context
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS or failure as defined SAMPLE_Error.h.
|
||||
* Output: sample_ecc_state_handle_t ecc_handle - Handle to ECC crypto system */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_ecc256_open_context(sample_ecc_state_handle_t* ecc_handle);
|
||||
|
||||
/* Cleans up ecc context
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS or failure as defined SAMPLE_Error.h.
|
||||
* Output: sample_ecc_state_handle_t ecc_handle - Handle to ECC crypto system */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_ecc256_close_context(sample_ecc_state_handle_t ecc_handle);
|
||||
|
||||
/* Populates private/public key pair - caller code allocates memory
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Inputs: sample_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
|
||||
* Outputs: sample_ec256_private_t *p_private - Pointer to the private key
|
||||
* sample_ec256_public_t *p_public - Pointer to the public key */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_ecc256_create_key_pair(sample_ec256_private_t *p_private,
|
||||
sample_ec256_public_t *p_public,
|
||||
sample_ecc_state_handle_t ecc_handle);
|
||||
|
||||
/* Computes DH shared key based on private B key (local) and remote public Ga Key
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Inputs: sample_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
|
||||
* sample_ec256_private_t *p_private_b - Pointer to the local private key - LITTLE ENDIAN
|
||||
* sample_ec256_public_t *p_public_ga - Pointer to the remote public key - LITTLE ENDIAN
|
||||
* Output: sample_ec256_dh_shared_t *p_shared_key - Pointer to the shared DH key - LITTLE ENDIAN
|
||||
x-coordinate of (privKeyB - pubKeyA) */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_ecc256_compute_shared_dhkey(sample_ec256_private_t *p_private_b,
|
||||
sample_ec256_public_t *p_public_ga,
|
||||
sample_ec256_dh_shared_t *p_shared_key,
|
||||
sample_ecc_state_handle_t ecc_handle);
|
||||
|
||||
|
||||
/* Computes signature for data based on private key
|
||||
*
|
||||
* A message digest is a fixed size number derived from the original message with
|
||||
* an applied hash function over the binary code of the message. (SHA256 in this case)
|
||||
* The signer's private key and the message digest are used to create a signature.
|
||||
*
|
||||
* A digital signature over a message consists of a pair of large numbers, 256-bits each,
|
||||
* which the given function computes.
|
||||
*
|
||||
* The scheme used for computing a digital signature is of the ECDSA scheme,
|
||||
* an elliptic curve of the DSA scheme.
|
||||
*
|
||||
* The keys can be generated and set up by the function: sgx_ecc256_create_key_pair.
|
||||
*
|
||||
* The elliptic curve domain parameters must be created by function:
|
||||
* sample_ecc256_open_context
|
||||
*
|
||||
* Return: If context, private key, signature or data pointer is NULL,
|
||||
* SAMPLE_ERROR_INVALID_PARAMETER is returned.
|
||||
* If the signature creation process fails then SAMPLE_ERROR_UNEXPECTED is returned.
|
||||
*
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS, success, error code otherwise.
|
||||
* Inputs: sample_ecc_state_handle_t ecc_handle - Handle to the ECC crypto system
|
||||
* sample_ec256_private_t *p_private - Pointer to the private key - LITTLE ENDIAN
|
||||
* uint8_t *p_data - Pointer to the data to be signed
|
||||
* uint32_t data_size - Size of the data to be signed
|
||||
* Output: ec256_signature_t *p_signature - Pointer to the signature - LITTLE ENDIAN */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_ecdsa_sign(const uint8_t *p_data,
|
||||
uint32_t data_size,
|
||||
sample_ec256_private_t *p_private,
|
||||
sample_ec256_signature_t *p_signature,
|
||||
sample_ecc_state_handle_t ecc_handle);
|
||||
|
||||
/* Allocates and initializes sha256 state
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Output: sample_sha_state_handle_t sha_handle - Handle to the SHA256 state */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_sha256_init(sample_sha_state_handle_t* p_sha_handle);
|
||||
|
||||
/* Updates sha256 has calculation based on the input message
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS or failure.
|
||||
* Input: sample_sha_state_handle_t sha_handle - Handle to the SHA256 state
|
||||
* uint8_t *p_src - Pointer to the input stream to be hashed
|
||||
* uint32_t src_len - Length of the input stream to be hashed */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_sha256_update(const uint8_t *p_src, uint32_t src_len, sample_sha_state_handle_t sha_handle);
|
||||
|
||||
/* Returns Hash calculation
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Input: sample_sha_state_handle_t sha_handle - Handle to the SHA256 state
|
||||
* Output: sample_sha256_hash_t *p_hash - Resultant hash from operation */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_sha256_get_hash(sample_sha_state_handle_t sha_handle, sample_sha256_hash_t *p_hash);
|
||||
|
||||
/* Cleans up sha state
|
||||
* Parameters:
|
||||
* Return: sample_status_t - SAMPLE_SUCCESS on success, error code otherwise.
|
||||
* Input: sample_sha_state_handle_t sha_handle - Handle to the SHA256 state */
|
||||
SAMPLE_LIBCRYPTO_API sample_status_t sample_sha256_close(sample_sha_state_handle_t sha_handle);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,557 @@
|
|||
#include "ServiceProvider.h"
|
||||
#include "sample_libcrypto.h"
|
||||
#include "../GeneralSettings.h"
|
||||
#include "sgx_tcrypto.h"
|
||||
|
||||
// This is the private EC key of SP, the corresponding public EC key is
|
||||
// hard coded in isv_enclave. It is based on NIST P-256 curve.
|
||||
static const sample_ec256_private_t g_sp_priv_key = {
|
||||
{
|
||||
0x90, 0xe7, 0x6c, 0xbb, 0x2d, 0x52, 0xa1, 0xce,
|
||||
0x3b, 0x66, 0xde, 0x11, 0x43, 0x9c, 0x87, 0xec,
|
||||
0x1f, 0x86, 0x6a, 0x3b, 0x65, 0xb6, 0xae, 0xea,
|
||||
0xad, 0x57, 0x34, 0x53, 0xd1, 0x03, 0x8c, 0x01
|
||||
}
|
||||
};
|
||||
|
||||
ServiceProvider::ServiceProvider(WebService *ws) : ws(ws) {}
|
||||
|
||||
ServiceProvider::~ServiceProvider() {}
|
||||
|
||||
|
||||
int ServiceProvider::sp_ra_proc_msg0_req(const uint32_t id) {
|
||||
int ret = -1;
|
||||
|
||||
if (!this->g_is_sp_registered || (this->extended_epid_group_id != id)) {
|
||||
Log("Received extended EPID group ID: %d", id);
|
||||
|
||||
extended_epid_group_id = id;
|
||||
this->g_is_sp_registered = true;
|
||||
ret = SP_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ServiceProvider::sp_ra_proc_msg1_req(Messages::MessageMSG1 msg1, Messages::MessageMSG2 *msg2) {
|
||||
ra_samp_response_header_t **pp_msg2;
|
||||
int ret = 0;
|
||||
ra_samp_response_header_t* p_msg2_full = NULL;
|
||||
sgx_ra_msg2_t *p_msg2 = NULL;
|
||||
sample_ecc_state_handle_t ecc_state = NULL;
|
||||
sample_status_t sample_ret = SAMPLE_SUCCESS;
|
||||
bool derive_ret = false;
|
||||
|
||||
if (!g_is_sp_registered) {
|
||||
return SP_UNSUPPORTED_EXTENDED_EPID_GROUP;
|
||||
}
|
||||
|
||||
do {
|
||||
//===================== RETRIEVE SIGRL FROM IAS =======================
|
||||
uint8_t GID[4];
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
GID[i] = msg1.gid(i);
|
||||
|
||||
reverse(begin(GID), end(GID));
|
||||
|
||||
string sigRl;
|
||||
bool error = false;
|
||||
error = this->ws->getSigRL(ByteArrayToString(GID, 4), &sigRl);
|
||||
|
||||
if (error)
|
||||
return SP_RETRIEVE_SIGRL_ERROR;
|
||||
|
||||
uint8_t *sig_rl;
|
||||
uint32_t sig_rl_size = StringToByteArray(sigRl, &sig_rl);
|
||||
//=====================================================================
|
||||
|
||||
uint8_t gaXLittleEndian[32];
|
||||
uint8_t gaYLittleEndian[32];
|
||||
|
||||
for (int i=0; i<32; i++) {
|
||||
gaXLittleEndian[i] = msg1.gax(i);
|
||||
gaYLittleEndian[i] = msg1.gay(i);
|
||||
}
|
||||
|
||||
sample_ec256_public_t client_pub_key = {{0},{0}};
|
||||
|
||||
for (int x=0; x<DH_SHARED_KEY_LEN; x++) {
|
||||
client_pub_key.gx[x] = gaXLittleEndian[x];
|
||||
client_pub_key.gy[x] = gaYLittleEndian[x];
|
||||
}
|
||||
|
||||
// Need to save the client's public ECCDH key to local storage
|
||||
if (memcpy_s(&g_sp_db.g_a, sizeof(g_sp_db.g_a), &client_pub_key, sizeof(client_pub_key))) {
|
||||
Log("Error, cannot do memcpy", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate the Service providers ECCDH key pair.
|
||||
sample_ret = sample_ecc256_open_context(&ecc_state);
|
||||
if(SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, cannot get ECC context", log::error);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
sample_ec256_public_t pub_key = {{0},{0}};
|
||||
sample_ec256_private_t priv_key = {{0}};
|
||||
sample_ret = sample_ecc256_create_key_pair(&priv_key, &pub_key, ecc_state);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, cannot get key pair", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Need to save the SP ECCDH key pair to local storage.
|
||||
if (memcpy_s(&g_sp_db.b, sizeof(g_sp_db.b), &priv_key,sizeof(priv_key)) ||
|
||||
memcpy_s(&g_sp_db.g_b, sizeof(g_sp_db.g_b), &pub_key,sizeof(pub_key))) {
|
||||
Log("Error, cannot do memcpy", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate the client/SP shared secret
|
||||
sample_ec_dh_shared_t dh_key = {{0}};
|
||||
|
||||
sample_ret = sample_ecc256_compute_shared_dhkey(&priv_key, (sample_ec256_public_t *)&client_pub_key,
|
||||
(sample_ec256_dh_shared_t *)&dh_key,
|
||||
ecc_state);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, compute share key fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// smk is only needed for msg2 generation.
|
||||
derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SMK, &g_sp_db.smk_key);
|
||||
if (derive_ret != true) {
|
||||
Log("Error, derive key fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// The rest of the keys are the shared secrets for future communication.
|
||||
derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_MK, &g_sp_db.mk_key);
|
||||
if (derive_ret != true) {
|
||||
Log("Error, derive key fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SK, &g_sp_db.sk_key);
|
||||
if (derive_ret != true) {
|
||||
Log("Error, derive key fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_VK, &g_sp_db.vk_key);
|
||||
if (derive_ret != true) {
|
||||
Log("Error, derive key fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
uint32_t msg2_size = sizeof(sgx_ra_msg2_t) + sig_rl_size;
|
||||
p_msg2_full = (ra_samp_response_header_t*)malloc(msg2_size + sizeof(ra_samp_response_header_t));
|
||||
|
||||
if (!p_msg2_full) {
|
||||
Log("Error, Error, out of memory", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(p_msg2_full, 0, msg2_size + sizeof(ra_samp_response_header_t));
|
||||
p_msg2_full->type = RA_MSG2;
|
||||
p_msg2_full->size = msg2_size;
|
||||
|
||||
p_msg2_full->status[0] = 0;
|
||||
p_msg2_full->status[1] = 0;
|
||||
p_msg2 = (sgx_ra_msg2_t *) p_msg2_full->body;
|
||||
|
||||
|
||||
uint8_t *spidBa;
|
||||
HexStringToByteArray(Settings::spid, &spidBa);
|
||||
|
||||
for (int i=0; i<16; i++)
|
||||
p_msg2->spid.id[i] = spidBa[i];
|
||||
|
||||
|
||||
// Assemble MSG2
|
||||
if(memcpy_s(&p_msg2->g_b, sizeof(p_msg2->g_b), &g_sp_db.g_b, sizeof(g_sp_db.g_b))) {
|
||||
Log("Error, memcpy failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
p_msg2->quote_type = SAMPLE_QUOTE_LINKABLE_SIGNATURE;
|
||||
p_msg2->kdf_id = AES_CMAC_KDF_ID;
|
||||
|
||||
// Create gb_ga
|
||||
sgx_ec256_public_t gb_ga[2];
|
||||
if (memcpy_s(&gb_ga[0], sizeof(gb_ga[0]), &g_sp_db.g_b, sizeof(g_sp_db.g_b)) ||
|
||||
memcpy_s(&gb_ga[1], sizeof(gb_ga[1]), &g_sp_db.g_a, sizeof(g_sp_db.g_a))) {
|
||||
Log("Error, memcpy failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Sign gb_ga
|
||||
sample_ret = sample_ecdsa_sign((uint8_t *)&gb_ga, sizeof(gb_ga),
|
||||
(sample_ec256_private_t *)&g_sp_priv_key,
|
||||
(sample_ec256_signature_t *)&p_msg2->sign_gb_ga,
|
||||
ecc_state);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, sign ga_gb fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Generate the CMACsmk for gb||SPID||TYPE||KDF_ID||Sigsp(gb,ga)
|
||||
uint8_t mac[SAMPLE_EC_MAC_SIZE] = {0};
|
||||
uint32_t cmac_size = offsetof(sgx_ra_msg2_t, mac);
|
||||
sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.smk_key, (uint8_t *)&p_msg2->g_b, cmac_size, &mac);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, cmac fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcpy_s(&p_msg2->mac, sizeof(p_msg2->mac), mac, sizeof(mac))) {
|
||||
Log("Error, memcpy failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcpy_s(&p_msg2->sig_rl[0], sig_rl_size, sig_rl, sig_rl_size)) {
|
||||
Log("Error, memcpy failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
p_msg2->sig_rl_size = sig_rl_size;
|
||||
|
||||
} while(0);
|
||||
|
||||
|
||||
if (ret) {
|
||||
*pp_msg2 = NULL;
|
||||
SafeFree(p_msg2_full);
|
||||
} else {
|
||||
|
||||
//================= SET MSG2 Fields ================
|
||||
msg2->set_size(p_msg2_full->size);
|
||||
|
||||
for (auto x : p_msg2->g_b.gx)
|
||||
msg2->add_public_key_gx(x);
|
||||
|
||||
for (auto x : p_msg2->g_b.gy)
|
||||
msg2->add_public_key_gy(x);
|
||||
|
||||
for (auto x : p_msg2->spid.id)
|
||||
msg2->add_spid(x);
|
||||
|
||||
msg2->set_quote_type(SAMPLE_QUOTE_LINKABLE_SIGNATURE);
|
||||
msg2->set_cmac_kdf_id(AES_CMAC_KDF_ID);
|
||||
|
||||
for (auto x : p_msg2->sign_gb_ga.x) {
|
||||
msg2->add_signature_x(x);
|
||||
}
|
||||
|
||||
for (auto x : p_msg2->sign_gb_ga.y)
|
||||
msg2->add_signature_y(x);
|
||||
|
||||
for (auto x : p_msg2->mac)
|
||||
msg2->add_smac(x);
|
||||
|
||||
msg2->set_size_sigrl(p_msg2->sig_rl_size);
|
||||
|
||||
for (int i=0; i<p_msg2->sig_rl_size; i++)
|
||||
msg2->add_sigrl(p_msg2->sig_rl[i]);
|
||||
//=====================================================
|
||||
}
|
||||
|
||||
if (ecc_state) {
|
||||
sample_ecc256_close_context(ecc_state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
sgx_ra_msg3_t* ServiceProvider::assembleMSG3(Messages::MessageMSG3 msg) {
|
||||
sgx_ra_msg3_t *p_msg3 = (sgx_ra_msg3_t*) malloc(msg.size());
|
||||
|
||||
for (int i=0; i<SGX_MAC_SIZE; i++)
|
||||
p_msg3->mac[i] = msg.sgx_mac(i);
|
||||
|
||||
for (int i=0; i<SGX_ECP256_KEY_SIZE; i++) {
|
||||
p_msg3->g_a.gx[i] = msg.gax_msg3(i);
|
||||
p_msg3->g_a.gy[i] = msg.gay_msg3(i);
|
||||
}
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
p_msg3->ps_sec_prop.sgx_ps_sec_prop_desc[i] = msg.sec_property(i);
|
||||
|
||||
for (int i=0; i<1116; i++)
|
||||
p_msg3->quote[i] = msg.quote(i);
|
||||
|
||||
return p_msg3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Process remote attestation message 3
|
||||
int ServiceProvider::sp_ra_proc_msg3_req(Messages::MessageMSG3 msg, Messages::AttestationMessage *att_msg) {
|
||||
int ret = 0;
|
||||
sample_status_t sample_ret = SAMPLE_SUCCESS;
|
||||
const uint8_t *p_msg3_cmaced = NULL;
|
||||
sgx_quote_t *p_quote = NULL;
|
||||
sample_sha_state_handle_t sha_handle = NULL;
|
||||
sample_report_data_t report_data = {0};
|
||||
sample_ra_att_result_msg_t *p_att_result_msg = NULL;
|
||||
ra_samp_response_header_t* p_att_result_msg_full = NULL;
|
||||
uint32_t i;
|
||||
sgx_ra_msg3_t *p_msg3 = NULL;
|
||||
uint32_t att_result_msg_size;
|
||||
int len_hmac_nonce = 0;
|
||||
|
||||
p_msg3 = assembleMSG3(msg);
|
||||
|
||||
// Check to see if we have registered?
|
||||
if (!g_is_sp_registered) {
|
||||
Log("Unsupported extended EPID group", log::error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
// Compare g_a in message 3 with local g_a.
|
||||
if (memcmp(&g_sp_db.g_a, &p_msg3->g_a, sizeof(sgx_ec256_public_t))) {
|
||||
Log("Error, g_a is not same", log::error);
|
||||
ret = SP_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
//Make sure that msg3_size is bigger than sample_mac_t.
|
||||
uint32_t mac_size = msg.size() - sizeof(sample_mac_t);
|
||||
p_msg3_cmaced = reinterpret_cast<const uint8_t*>(p_msg3);
|
||||
p_msg3_cmaced += sizeof(sample_mac_t);
|
||||
|
||||
// Verify the message mac using SMK
|
||||
sample_cmac_128bit_tag_t mac = {0};
|
||||
sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.smk_key, p_msg3_cmaced, mac_size, &mac);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, cmac fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(&p_msg3->mac, mac, sizeof(mac))) {
|
||||
Log("Error, verify cmac fail", log::error);
|
||||
ret = SP_INTEGRITY_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcpy_s(&g_sp_db.ps_sec_prop, sizeof(g_sp_db.ps_sec_prop), &p_msg3->ps_sec_prop, sizeof(p_msg3->ps_sec_prop))) {
|
||||
Log("Error, memcpy fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
p_quote = (sgx_quote_t *) p_msg3->quote;
|
||||
|
||||
|
||||
// Verify the report_data in the Quote matches the expected value.
|
||||
// The first 32 bytes of report_data are SHA256 HASH of {ga|gb|vk}.
|
||||
// The second 32 bytes of report_data are set to zero.
|
||||
sample_ret = sample_sha256_init(&sha_handle);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
Log("Error, init hash failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.g_a), sizeof(g_sp_db.g_a), sha_handle);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
Log("Error, udpate hash failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.g_b), sizeof(g_sp_db.g_b), sha_handle);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
Log("Error, udpate hash failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sample_ret = sample_sha256_update((uint8_t *)&(g_sp_db.vk_key), sizeof(g_sp_db.vk_key), sha_handle);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
Log("Error, udpate hash failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sample_ret = sample_sha256_get_hash(sha_handle, (sample_sha256_hash_t *)&report_data);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
Log("Error, Get hash failed", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp((uint8_t *)&report_data, (uint8_t *)&(p_quote->report_body.report_data), sizeof(report_data))) {
|
||||
Log("Error, verify hash failed", log::error);
|
||||
ret = SP_INTEGRITY_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify quote with attestation server.
|
||||
ias_att_report_t attestation_report = {0};
|
||||
ret = ias_verify_attestation_evidence(p_msg3->quote, p_msg3->ps_sec_prop.sgx_ps_sec_prop_desc, &attestation_report, ws);
|
||||
|
||||
if (0 != ret) {
|
||||
ret = SP_IAS_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
Log("Atestation Report:");
|
||||
Log("\tid: %s", attestation_report.id);
|
||||
Log("\tstatus: %d", attestation_report.status);
|
||||
Log("\trevocation_reason: %u", attestation_report.revocation_reason);
|
||||
Log("\tpse_status: %d", attestation_report.pse_status);
|
||||
|
||||
Log("Enclave Report:");
|
||||
Log("\tSignature Type: 0x%x", p_quote->sign_type);
|
||||
Log("\tSignature Basename: %s", ByteArrayToNoHexString(p_quote->basename.name, 32));
|
||||
Log("\tattributes.flags: 0x%0lx", p_quote->report_body.attributes.flags);
|
||||
Log("\tattributes.xfrm: 0x%0lx", p_quote->report_body.attributes.xfrm);
|
||||
Log("\tmr_enclave: %s", ByteArrayToString(p_quote->report_body.mr_enclave.m, SGX_HASH_SIZE));
|
||||
Log("\tmr_signer: %s", ByteArrayToString(p_quote->report_body.mr_signer.m, SGX_HASH_SIZE));
|
||||
Log("\tisv_prod_id: 0x%0x", p_quote->report_body.isv_prod_id);
|
||||
Log("\tisv_svn: 0x%0x", p_quote->report_body.isv_svn);
|
||||
|
||||
|
||||
// Respond the client with the results of the attestation.
|
||||
att_result_msg_size = sizeof(sample_ra_att_result_msg_t);
|
||||
|
||||
p_att_result_msg_full = (ra_samp_response_header_t*) malloc(att_result_msg_size + sizeof(ra_samp_response_header_t) + sizeof(validation_result));
|
||||
if (!p_att_result_msg_full) {
|
||||
Log("Error, out of memory", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(p_att_result_msg_full, 0, att_result_msg_size + sizeof(ra_samp_response_header_t) + sizeof(validation_result));
|
||||
p_att_result_msg_full->type = RA_ATT_RESULT;
|
||||
p_att_result_msg_full->size = att_result_msg_size;
|
||||
|
||||
if (IAS_QUOTE_OK != attestation_report.status) {
|
||||
p_att_result_msg_full->status[0] = 0xFF;
|
||||
}
|
||||
|
||||
if (IAS_PSE_OK != attestation_report.pse_status) {
|
||||
p_att_result_msg_full->status[1] = 0xFF;
|
||||
}
|
||||
|
||||
p_att_result_msg = (sample_ra_att_result_msg_t *)p_att_result_msg_full->body;
|
||||
|
||||
bool isv_policy_passed = true;
|
||||
|
||||
p_att_result_msg->platform_info_blob = attestation_report.info_blob;
|
||||
|
||||
// Generate mac based on the mk key.
|
||||
mac_size = sizeof(ias_platform_info_blob_t);
|
||||
sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.mk_key,
|
||||
(const uint8_t*)&p_att_result_msg->platform_info_blob,
|
||||
mac_size,
|
||||
&p_att_result_msg->mac);
|
||||
|
||||
if (SAMPLE_SUCCESS != sample_ret) {
|
||||
Log("Error, cmac fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate shared secret and encrypt it with SK, if attestation passed.
|
||||
uint8_t aes_gcm_iv[SAMPLE_SP_IV_SIZE] = {0};
|
||||
p_att_result_msg->secret.payload_size = MAX_VERIFICATION_RESULT;
|
||||
|
||||
if ((IAS_QUOTE_OK == attestation_report.status) &&
|
||||
(IAS_PSE_OK == attestation_report.pse_status) &&
|
||||
(isv_policy_passed == true)) {
|
||||
memset(validation_result, '\0', MAX_VERIFICATION_RESULT);
|
||||
validation_result[0] = 0;
|
||||
validation_result[1] = 1;
|
||||
|
||||
ret = sample_rijndael128GCM_encrypt(&g_sp_db.sk_key,
|
||||
&validation_result[0],
|
||||
p_att_result_msg->secret.payload_size,
|
||||
p_att_result_msg->secret.payload,
|
||||
&aes_gcm_iv[0],
|
||||
SAMPLE_SP_IV_SIZE,
|
||||
NULL,
|
||||
0,
|
||||
&p_att_result_msg->secret.payload_tag);
|
||||
}
|
||||
|
||||
} while(0);
|
||||
|
||||
if (ret) {
|
||||
SafeFree(p_att_result_msg_full);
|
||||
return -1;
|
||||
} else {
|
||||
att_msg->set_size(att_result_msg_size);
|
||||
|
||||
ias_platform_info_blob_t platform_info_blob = p_att_result_msg->platform_info_blob;
|
||||
att_msg->set_epid_group_status(platform_info_blob.sample_epid_group_status);
|
||||
att_msg->set_tcb_evaluation_status(platform_info_blob.sample_tcb_evaluation_status);
|
||||
att_msg->set_pse_evaluation_status(platform_info_blob.pse_evaluation_status);
|
||||
|
||||
for (int i=0; i<PSVN_SIZE; i++)
|
||||
att_msg->add_latest_equivalent_tcb_psvn(platform_info_blob.latest_equivalent_tcb_psvn[i]);
|
||||
|
||||
for (int i=0; i<ISVSVN_SIZE; i++)
|
||||
att_msg->add_latest_pse_isvsvn(platform_info_blob.latest_pse_isvsvn[i]);
|
||||
|
||||
for (int i=0; i<PSDA_SVN_SIZE; i++)
|
||||
att_msg->add_latest_psda_svn(platform_info_blob.latest_psda_svn[i]);
|
||||
|
||||
for (int i=0; i<GID_SIZE; i++)
|
||||
att_msg->add_performance_rekey_gid(platform_info_blob.performance_rekey_gid[i]);
|
||||
|
||||
for (int i=0; i<SAMPLE_NISTP256_KEY_SIZE; i++) {
|
||||
att_msg->add_ec_sign256_x(platform_info_blob.signature.x[i]);
|
||||
att_msg->add_ec_sign256_y(platform_info_blob.signature.y[i]);
|
||||
}
|
||||
|
||||
for (int i=0; i<SAMPLE_MAC_SIZE; i++)
|
||||
att_msg->add_mac_smk(p_att_result_msg->mac[i]);
|
||||
|
||||
att_msg->set_result_size(p_att_result_msg->secret.payload_size);
|
||||
|
||||
for (int i=0; i<12; i++)
|
||||
att_msg->add_reserved(p_att_result_msg->secret.reserved[i]);
|
||||
|
||||
for (int i=0; i<16; i++)
|
||||
att_msg->add_payload_tag(p_att_result_msg->secret.payload_tag[i]);
|
||||
|
||||
for (int i=0; i<p_att_result_msg->secret.payload_size; i++)
|
||||
att_msg->add_payload(p_att_result_msg->secret.payload[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef SERVICE_PROVIDER_H
|
||||
#define SERVICE_PROVIDER_H
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <algorithm> // std::reverse
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "Messages.pb.h"
|
||||
#include "UtilityFunctions.h"
|
||||
#include "LogBase.h"
|
||||
#include "Network_def.h"
|
||||
#include "WebService.h"
|
||||
|
||||
#include "remote_attestation_result.h"
|
||||
#include "sgx_key_exchange.h"
|
||||
#include "ias_ra.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define DH_HALF_KEY_LEN 32
|
||||
#define DH_SHARED_KEY_LEN 32
|
||||
#define SAMPLE_SP_IV_SIZE 12
|
||||
|
||||
|
||||
enum sp_ra_msg_status_t {
|
||||
SP_OK,
|
||||
SP_UNSUPPORTED_EXTENDED_EPID_GROUP,
|
||||
SP_INTEGRITY_FAILED,
|
||||
SP_QUOTE_VERIFICATION_FAILED,
|
||||
SP_IAS_FAILED,
|
||||
SP_INTERNAL_ERROR,
|
||||
SP_PROTOCOL_ERROR,
|
||||
SP_QUOTE_VERSION_ERROR,
|
||||
SP_RETRIEVE_SIGRL_ERROR
|
||||
};
|
||||
|
||||
typedef struct _sp_db_item_t {
|
||||
sgx_ec256_public_t g_a;
|
||||
sgx_ec256_public_t g_b;
|
||||
sgx_ec_key_128bit_t vk_key; // Shared secret key for the REPORT_DATA
|
||||
sgx_ec_key_128bit_t mk_key; // Shared secret key for generating MAC's
|
||||
sgx_ec_key_128bit_t sk_key; // Shared secret key for encryption
|
||||
sgx_ec_key_128bit_t smk_key; // Used only for SIGMA protocol
|
||||
sample_ec_priv_t b;
|
||||
sgx_ps_sec_prop_desc_t ps_sec_prop;
|
||||
} sp_db_item_t;
|
||||
|
||||
|
||||
class ServiceProvider {
|
||||
|
||||
public:
|
||||
ServiceProvider(WebService *ws);
|
||||
virtual ~ServiceProvider();
|
||||
int sp_ra_proc_msg0_req(const uint32_t extended_epid_group_id);
|
||||
int sp_ra_proc_msg1_req(Messages::MessageMSG1 msg1, Messages::MessageMSG2 *msg2);
|
||||
int sp_ra_proc_msg3_req(Messages::MessageMSG3 msg, Messages::AttestationMessage *att_msg);
|
||||
sgx_ra_msg3_t* assembleMSG3(Messages::MessageMSG3 msg);
|
||||
int sp_ra_proc_app_att_hmac(Messages::SecretMessage *new_msg, string hmac_key, string hmac_key_filename);
|
||||
|
||||
private:
|
||||
WebService *ws = NULL;
|
||||
bool g_is_sp_registered = false;
|
||||
uint32_t extended_epid_group_id;
|
||||
sp_db_item_t g_sp_db;
|
||||
const uint16_t AES_CMAC_KDF_ID = 0x0001;
|
||||
uint8_t validation_result[MAX_VERIFICATION_RESULT];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ecp.h"
|
||||
|
||||
#include "sample_libcrypto.h"
|
||||
|
||||
|
||||
#define MAC_KEY_SIZE 16
|
||||
|
||||
errno_t memcpy_s(
|
||||
void *dest,
|
||||
size_t numberOfElements,
|
||||
const void *src,
|
||||
size_t count) {
|
||||
if(numberOfElements<count)
|
||||
return -1;
|
||||
memcpy(dest, src, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool verify_cmac128(
|
||||
sample_ec_key_128bit_t mac_key,
|
||||
const uint8_t *p_data_buf,
|
||||
uint32_t buf_size,
|
||||
const uint8_t *p_mac_buf) {
|
||||
uint8_t data_mac[SAMPLE_EC_MAC_SIZE];
|
||||
sample_status_t sample_ret;
|
||||
|
||||
sample_ret = sample_rijndael128_cmac_msg((sample_cmac_128bit_key_t*)mac_key,
|
||||
p_data_buf,
|
||||
buf_size,
|
||||
(sample_cmac_128bit_tag_t *)data_mac);
|
||||
if(sample_ret != SAMPLE_SUCCESS)
|
||||
return false;
|
||||
// In real implementation, should use a time safe version of memcmp here,
|
||||
// in order to avoid side channel attack.
|
||||
if(!memcmp(p_mac_buf, data_mac, SAMPLE_EC_MAC_SIZE))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SUPPLIED_KEY_DERIVATION
|
||||
|
||||
#pragma message ("Supplied key derivation function is used.")
|
||||
|
||||
typedef struct _hash_buffer_t {
|
||||
uint8_t counter[4];
|
||||
sample_ec_dh_shared_t shared_secret;
|
||||
uint8_t algorithm_id[4];
|
||||
} hash_buffer_t;
|
||||
|
||||
const char ID_U[] = "SGXRAENCLAVE";
|
||||
const char ID_V[] = "SGXRASERVER";
|
||||
|
||||
// Derive two keys from shared key and key id.
|
||||
bool derive_key(
|
||||
const sample_ec_dh_shared_t *p_shared_key,
|
||||
uint8_t key_id,
|
||||
sample_ec_key_128bit_t *first_derived_key,
|
||||
sample_ec_key_128bit_t *second_derived_key) {
|
||||
sample_status_t sample_ret = SAMPLE_SUCCESS;
|
||||
hash_buffer_t hash_buffer;
|
||||
sample_sha_state_handle_t sha_context;
|
||||
sample_sha256_hash_t key_material;
|
||||
|
||||
memset(&hash_buffer, 0, sizeof(hash_buffer_t));
|
||||
|
||||
/* counter in big endian */
|
||||
hash_buffer.counter[3] = key_id;
|
||||
|
||||
/*convert from little endian to big endian */
|
||||
for (size_t i = 0; i < sizeof(sample_ec_dh_shared_t) ; i++) {
|
||||
hash_buffer.shared_secret.s[i] = p_shared_key->s[sizeof(p_shared_key->s) - 1 - i];
|
||||
}
|
||||
|
||||
sample_ret = sample_sha256_init(&sha_context);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
sample_ret = sample_sha256_update((uint8_t*)&hash_buffer, sizeof(hash_buffer_t), sha_context);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
sample_sha256_close(sha_context);
|
||||
return false;
|
||||
}
|
||||
sample_ret = sample_sha256_update((uint8_t*)ID_U, sizeof(ID_U), sha_context);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
sample_sha256_close(sha_context);
|
||||
return false;
|
||||
}
|
||||
sample_ret = sample_sha256_update((uint8_t*)ID_V, sizeof(ID_V), sha_context);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
sample_sha256_close(sha_context);
|
||||
return false;
|
||||
}
|
||||
sample_ret = sample_sha256_get_hash(sha_context, &key_material);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
sample_sha256_close(sha_context);
|
||||
return false;
|
||||
}
|
||||
sample_ret = sample_sha256_close(sha_context);
|
||||
|
||||
static_assert(sizeof(sample_ec_key_128bit_t)* 2 == sizeof(sample_sha256_hash_t), "structure size mismatch.");
|
||||
memcpy(first_derived_key, &key_material, sizeof(sample_ec_key_128bit_t));
|
||||
memcpy(second_derived_key, (uint8_t*)&key_material + sizeof(sample_ec_key_128bit_t), sizeof(sample_ec_key_128bit_t));
|
||||
|
||||
// memset here can be optimized away by compiler, so please use memset_s on
|
||||
// windows for production code and similar functions on other OSes.
|
||||
memset(&key_material, 0, sizeof(sample_sha256_hash_t));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#pragma message ("Default key derivation function is used.")
|
||||
|
||||
#define EC_DERIVATION_BUFFER_SIZE(label_length) ((label_length) +4)
|
||||
|
||||
const char str_SMK[] = "SMK";
|
||||
const char str_SK[] = "SK";
|
||||
const char str_MK[] = "MK";
|
||||
const char str_VK[] = "VK";
|
||||
|
||||
// Derive key from shared key and key id.
|
||||
// key id should be sample_derive_key_type_t.
|
||||
bool derive_key(
|
||||
const sample_ec_dh_shared_t *p_shared_key,
|
||||
uint8_t key_id,
|
||||
sample_ec_key_128bit_t* derived_key) {
|
||||
sample_status_t sample_ret = SAMPLE_SUCCESS;
|
||||
uint8_t cmac_key[MAC_KEY_SIZE];
|
||||
sample_ec_key_128bit_t key_derive_key;
|
||||
|
||||
memset(&cmac_key, 0, MAC_KEY_SIZE);
|
||||
|
||||
sample_ret = sample_rijndael128_cmac_msg(
|
||||
(sample_cmac_128bit_key_t *)&cmac_key,
|
||||
(uint8_t*)p_shared_key,
|
||||
sizeof(sample_ec_dh_shared_t),
|
||||
(sample_cmac_128bit_tag_t *)&key_derive_key);
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
// memset here can be optimized away by compiler, so please use memset_s on
|
||||
// windows for production code and similar functions on other OSes.
|
||||
memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *label = NULL;
|
||||
uint32_t label_length = 0;
|
||||
switch (key_id) {
|
||||
case SAMPLE_DERIVE_KEY_SMK:
|
||||
label = str_SMK;
|
||||
label_length = sizeof(str_SMK) -1;
|
||||
break;
|
||||
case SAMPLE_DERIVE_KEY_SK:
|
||||
label = str_SK;
|
||||
label_length = sizeof(str_SK) -1;
|
||||
break;
|
||||
case SAMPLE_DERIVE_KEY_MK:
|
||||
label = str_MK;
|
||||
label_length = sizeof(str_MK) -1;
|
||||
break;
|
||||
case SAMPLE_DERIVE_KEY_VK:
|
||||
label = str_VK;
|
||||
label_length = sizeof(str_VK) -1;
|
||||
break;
|
||||
default:
|
||||
// memset here can be optimized away by compiler, so please use memset_s on
|
||||
// windows for production code and similar functions on other OSes.
|
||||
memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
/* derivation_buffer = counter(0x01) || label || 0x00 || output_key_len(0x0080) */
|
||||
uint32_t derivation_buffer_length = EC_DERIVATION_BUFFER_SIZE(label_length);
|
||||
uint8_t *p_derivation_buffer = (uint8_t *)malloc(derivation_buffer_length);
|
||||
if (p_derivation_buffer == NULL) {
|
||||
// memset here can be optimized away by compiler, so please use memset_s on
|
||||
// windows for production code and similar functions on other OSes.
|
||||
memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
return false;
|
||||
}
|
||||
memset(p_derivation_buffer, 0, derivation_buffer_length);
|
||||
|
||||
/*counter = 0x01 */
|
||||
p_derivation_buffer[0] = 0x01;
|
||||
/*label*/
|
||||
memcpy(&p_derivation_buffer[1], label, label_length);
|
||||
/*output_key_len=0x0080*/
|
||||
uint16_t *key_len = (uint16_t *)(&(p_derivation_buffer[derivation_buffer_length - 2]));
|
||||
*key_len = 0x0080;
|
||||
|
||||
|
||||
sample_ret = sample_rijndael128_cmac_msg(
|
||||
(sample_cmac_128bit_key_t *)&key_derive_key,
|
||||
p_derivation_buffer,
|
||||
derivation_buffer_length,
|
||||
(sample_cmac_128bit_tag_t *)derived_key);
|
||||
free(p_derivation_buffer);
|
||||
// memset here can be optimized away by compiler, so please use memset_s on
|
||||
// windows for production code and similar functions on other OSes.
|
||||
memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
if (sample_ret != SAMPLE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef _ECP_H
|
||||
#define _ECP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "remote_attestation_result.h"
|
||||
|
||||
#ifndef SAMPLE_FEBITSIZE
|
||||
#define SAMPLE_FEBITSIZE 256
|
||||
#endif
|
||||
|
||||
#define SAMPLE_ECP_KEY_SIZE (SAMPLE_FEBITSIZE/8)
|
||||
|
||||
typedef struct sample_ec_priv_t {
|
||||
uint8_t r[SAMPLE_ECP_KEY_SIZE];
|
||||
} sample_ec_priv_t;
|
||||
|
||||
typedef struct sample_ec_dh_shared_t {
|
||||
uint8_t s[SAMPLE_ECP_KEY_SIZE];
|
||||
} sample_ec_dh_shared_t;
|
||||
|
||||
typedef uint8_t sample_ec_key_128bit_t[16];
|
||||
|
||||
#define SAMPLE_EC_MAC_SIZE 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _ERRNO_T_DEFINED
|
||||
#define _ERRNO_T_DEFINED
|
||||
typedef int errno_t;
|
||||
#endif
|
||||
errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src,
|
||||
size_t count);
|
||||
|
||||
|
||||
#ifdef SUPPLIED_KEY_DERIVATION
|
||||
|
||||
typedef enum _sample_derive_key_type_t {
|
||||
SAMPLE_DERIVE_KEY_SMK_SK = 0,
|
||||
SAMPLE_DERIVE_KEY_MK_VK,
|
||||
} sample_derive_key_type_t;
|
||||
|
||||
bool derive_key(
|
||||
const sample_ec_dh_shared_t *p_shared_key,
|
||||
uint8_t key_id,
|
||||
sample_ec_key_128bit_t *first_derived_key,
|
||||
sample_ec_key_128bit_t *second_derived_key);
|
||||
|
||||
#else
|
||||
|
||||
typedef enum _sample_derive_key_type_t {
|
||||
SAMPLE_DERIVE_KEY_SMK = 0,
|
||||
SAMPLE_DERIVE_KEY_SK,
|
||||
SAMPLE_DERIVE_KEY_MK,
|
||||
SAMPLE_DERIVE_KEY_VK,
|
||||
} sample_derive_key_type_t;
|
||||
|
||||
bool derive_key(
|
||||
const sample_ec_dh_shared_t *p_shared_key,
|
||||
uint8_t key_id,
|
||||
sample_ec_key_128bit_t *derived_key);
|
||||
|
||||
#endif
|
||||
|
||||
bool verify_cmac128(
|
||||
sample_ec_key_128bit_t mac_key,
|
||||
const uint8_t *p_data_buf,
|
||||
uint32_t buf_size,
|
||||
const uint8_t *p_mac_buf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
#include "ServiceProvider.h"
|
||||
#include "sample_libcrypto.h"
|
||||
#include "ecp.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "ias_ra.h"
|
||||
#include "UtilityFunctions.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#if !defined(SWAP_ENDIAN_DW)
|
||||
#define SWAP_ENDIAN_DW(dw) ((((dw) & 0x000000ff) << 24) \
|
||||
| (((dw) & 0x0000ff00) << 8) \
|
||||
| (((dw) & 0x00ff0000) >> 8) \
|
||||
| (((dw) & 0xff000000) >> 24))
|
||||
#endif
|
||||
#if !defined(SWAP_ENDIAN_32B)
|
||||
#define SWAP_ENDIAN_32B(ptr) \
|
||||
{\
|
||||
unsigned int temp = 0; \
|
||||
temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[0]); \
|
||||
((unsigned int*)(ptr))[0] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[7]); \
|
||||
((unsigned int*)(ptr))[7] = temp; \
|
||||
temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[1]); \
|
||||
((unsigned int*)(ptr))[1] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[6]); \
|
||||
((unsigned int*)(ptr))[6] = temp; \
|
||||
temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[2]); \
|
||||
((unsigned int*)(ptr))[2] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[5]); \
|
||||
((unsigned int*)(ptr))[5] = temp; \
|
||||
temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[3]); \
|
||||
((unsigned int*)(ptr))[3] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[4]); \
|
||||
((unsigned int*)(ptr))[4] = temp; \
|
||||
}
|
||||
#endif
|
||||
|
||||
// This is the ECDSA NIST P-256 private key used to sign platform_info_blob.
|
||||
// This private
|
||||
// key and the public key in SDK untrusted KElibrary should be a temporary key
|
||||
// pair. For production parts an attestation server will sign the platform_info_blob with the
|
||||
// production private key and the SDK untrusted KE library will have the public
|
||||
// key for verifcation.
|
||||
|
||||
static const sample_ec256_private_t g_rk_priv_key = {
|
||||
{
|
||||
0x63,0x2c,0xd4,0x02,0x7a,0xdc,0x56,0xa5,
|
||||
0x59,0x6c,0x44,0x3e,0x43,0xca,0x4e,0x0b,
|
||||
0x58,0xcd,0x78,0xcb,0x3c,0x7e,0xd5,0xb9,
|
||||
0xf2,0x91,0x5b,0x39,0x0d,0xb3,0xb5,0xfb
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Simulates the attestation server function for verifying the quote produce by
|
||||
// the ISV enclave. It doesn't decrypt or verify the quote in
|
||||
// the simulation. Just produces the attestaion verification
|
||||
// report with the platform info blob.
|
||||
//
|
||||
// @param p_isv_quote Pointer to the quote generated by the ISV
|
||||
// enclave.
|
||||
// @param pse_manifest Pointer to the PSE manifest if used.
|
||||
// @param p_attestation_verification_report Pointer the outputed
|
||||
// verification report.
|
||||
//
|
||||
// @return int
|
||||
|
||||
int ias_verify_attestation_evidence(
|
||||
uint8_t *p_isv_quote,
|
||||
uint8_t* pse_manifest,
|
||||
ias_att_report_t* p_attestation_verification_report,
|
||||
WebService *ws) {
|
||||
int ret = 0;
|
||||
sample_ecc_state_handle_t ecc_state = NULL;
|
||||
|
||||
vector<pair<string, string>> result;
|
||||
bool error = ws->verifyQuote(p_isv_quote, pse_manifest, NULL, &result);
|
||||
|
||||
|
||||
if (error || (NULL == p_isv_quote) || (NULL == p_attestation_verification_report)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
string report_id;
|
||||
uintmax_t test;
|
||||
ias_quote_status_t quoteStatus;
|
||||
string timestamp, epidPseudonym, isvEnclaveQuoteStatus;
|
||||
|
||||
for (auto x : result) {
|
||||
if (x.first == "id") {
|
||||
report_id = x.second;
|
||||
} else if (x.first == "timestamp") {
|
||||
timestamp = x.second;
|
||||
} else if (x.first == "epidPseudonym") {
|
||||
epidPseudonym = x.second;
|
||||
} else if (x.first == "isvEnclaveQuoteStatus") {
|
||||
if (x.second == "OK")
|
||||
quoteStatus = IAS_QUOTE_OK;
|
||||
else if (x.second == "SIGNATURE_INVALID")
|
||||
quoteStatus = IAS_QUOTE_SIGNATURE_INVALID;
|
||||
else if (x.second == "GROUP_REVOKED")
|
||||
quoteStatus = IAS_QUOTE_GROUP_REVOKED;
|
||||
else if (x.second == "SIGNATURE_REVOKED")
|
||||
quoteStatus = IAS_QUOTE_SIGNATURE_REVOKED;
|
||||
else if (x.second == "KEY_REVOKED")
|
||||
quoteStatus = IAS_QUOTE_KEY_REVOKED;
|
||||
else if (x.second == "SIGRL_VERSION_MISMATCH")
|
||||
quoteStatus = IAS_QUOTE_SIGRL_VERSION_MISMATCH;
|
||||
else if (x.second == "GROUP_OUT_OF_DATE")
|
||||
quoteStatus = IAS_QUOTE_GROUP_OUT_OF_DATE;
|
||||
}
|
||||
}
|
||||
|
||||
report_id.copy(p_attestation_verification_report->id, report_id.size());
|
||||
p_attestation_verification_report->status = quoteStatus;
|
||||
p_attestation_verification_report->revocation_reason = IAS_REVOC_REASON_NONE;
|
||||
|
||||
//this is only sent back from the IAS if something bad happened for reference please see
|
||||
//https://software.intel.com/sites/default/files/managed/3d/c8/IAS_1_0_API_spec_1_1_Final.pdf
|
||||
//for testing purposes we assume the world is nice and sunny
|
||||
p_attestation_verification_report->info_blob.sample_epid_group_status =
|
||||
0 << IAS_EPID_GROUP_STATUS_REVOKED_BIT_POS
|
||||
| 0 << IAS_EPID_GROUP_STATUS_REKEY_AVAILABLE_BIT_POS;
|
||||
p_attestation_verification_report->info_blob.sample_tcb_evaluation_status =
|
||||
0 << IAS_TCB_EVAL_STATUS_CPUSVN_OUT_OF_DATE_BIT_POS
|
||||
| 0 << IAS_TCB_EVAL_STATUS_ISVSVN_OUT_OF_DATE_BIT_POS;
|
||||
p_attestation_verification_report->info_blob.pse_evaluation_status =
|
||||
0 << IAS_PSE_EVAL_STATUS_ISVSVN_OUT_OF_DATE_BIT_POS
|
||||
| 0 << IAS_PSE_EVAL_STATUS_EPID_GROUP_REVOKED_BIT_POS
|
||||
| 0 << IAS_PSE_EVAL_STATUS_PSDASVN_OUT_OF_DATE_BIT_POS
|
||||
| 0 << IAS_PSE_EVAL_STATUS_SIGRL_OUT_OF_DATE_BIT_POS
|
||||
| 0 << IAS_PSE_EVAL_STATUS_PRIVRL_OUT_OF_DATE_BIT_POS;
|
||||
|
||||
memset(p_attestation_verification_report->info_blob.latest_equivalent_tcb_psvn, 0, PSVN_SIZE);
|
||||
memset(p_attestation_verification_report->info_blob.latest_pse_isvsvn, 0, ISVSVN_SIZE);
|
||||
memset(p_attestation_verification_report->info_blob.latest_psda_svn, 0, PSDA_SVN_SIZE);
|
||||
memset(p_attestation_verification_report->info_blob.performance_rekey_gid, 0, GID_SIZE);
|
||||
|
||||
// Generate the Service providers ECCDH key pair.
|
||||
do {
|
||||
ret = sample_ecc256_open_context(&ecc_state);
|
||||
if (SAMPLE_SUCCESS != ret) {
|
||||
Log("Error, cannot get ECC context", log::error);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
// Sign
|
||||
ret = sample_ecdsa_sign((uint8_t *)&p_attestation_verification_report->info_blob.sample_epid_group_status,
|
||||
sizeof(ias_platform_info_blob_t) - sizeof(sample_ec_sign256_t),
|
||||
(sample_ec256_private_t *)&g_rk_priv_key,
|
||||
(sample_ec256_signature_t *)&p_attestation_verification_report->info_blob.signature,
|
||||
ecc_state);
|
||||
|
||||
if (SAMPLE_SUCCESS != ret) {
|
||||
Log("Error, sign ga_gb fail", log::error);
|
||||
ret = SP_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
SWAP_ENDIAN_32B(p_attestation_verification_report->info_blob.signature.x);
|
||||
SWAP_ENDIAN_32B(p_attestation_verification_report->info_blob.signature.y);
|
||||
|
||||
} while (0);
|
||||
|
||||
if (ecc_state) {
|
||||
sample_ecc256_close_context(ecc_state);
|
||||
}
|
||||
|
||||
p_attestation_verification_report->pse_status = IAS_PSE_OK;
|
||||
|
||||
// For now, don't simulate the policy reports.
|
||||
p_attestation_verification_report->policy_report_size = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef _IAS_RA_H
|
||||
#define _IAS_RA_H
|
||||
|
||||
#include "ecp.h"
|
||||
#include "sgx_quote.h"
|
||||
|
||||
#include "LogBase.h"
|
||||
#include "WebService.h"
|
||||
|
||||
using namespace util;
|
||||
|
||||
typedef enum {
|
||||
IAS_QUOTE_OK,
|
||||
IAS_QUOTE_SIGNATURE_INVALID,
|
||||
IAS_QUOTE_GROUP_REVOKED,
|
||||
IAS_QUOTE_SIGNATURE_REVOKED,
|
||||
IAS_QUOTE_KEY_REVOKED,
|
||||
IAS_QUOTE_SIGRL_VERSION_MISMATCH,
|
||||
IAS_QUOTE_GROUP_OUT_OF_DATE,
|
||||
} ias_quote_status_t;
|
||||
|
||||
// These status should align with the definition in IAS API spec(rev 0.6)
|
||||
typedef enum {
|
||||
IAS_PSE_OK,
|
||||
IAS_PSE_DESC_TYPE_NOT_SUPPORTED,
|
||||
IAS_PSE_ISVSVN_OUT_OF_DATE,
|
||||
IAS_PSE_MISCSELECT_INVALID,
|
||||
IAS_PSE_ATTRIBUTES_INVALID,
|
||||
IAS_PSE_MRSIGNER_INVALID,
|
||||
IAS_PS_HW_GID_REVOKED,
|
||||
IAS_PS_HW_PRIVKEY_RLVER_MISMATCH,
|
||||
IAS_PS_HW_SIG_RLVER_MISMATCH,
|
||||
IAS_PS_HW_CA_ID_INVALID,
|
||||
IAS_PS_HW_SEC_INFO_INVALID,
|
||||
IAS_PS_HW_PSDA_SVN_OUT_OF_DATE,
|
||||
} ias_pse_status_t;
|
||||
|
||||
// Revocation Reasons from RFC5280
|
||||
typedef enum {
|
||||
IAS_REVOC_REASON_NONE,
|
||||
IAS_REVOC_REASON_KEY_COMPROMISE,
|
||||
IAS_REVOC_REASON_CA_COMPROMISED,
|
||||
IAS_REVOC_REASON_SUPERCEDED,
|
||||
IAS_REVOC_REASON_CESSATION_OF_OPERATION,
|
||||
IAS_REVOC_REASON_CERTIFICATE_HOLD,
|
||||
IAS_REVOC_REASON_PRIVILEGE_WITHDRAWN,
|
||||
IAS_REVOC_REASON_AA_COMPROMISE,
|
||||
} ias_revoc_reason_t;
|
||||
|
||||
// These status should align with the definition in IAS API spec(rev 0.6)
|
||||
#define IAS_EPID_GROUP_STATUS_REVOKED_BIT_POS 0x00
|
||||
#define IAS_EPID_GROUP_STATUS_REKEY_AVAILABLE_BIT_POS 0x01
|
||||
|
||||
#define IAS_TCB_EVAL_STATUS_CPUSVN_OUT_OF_DATE_BIT_POS 0x00
|
||||
#define IAS_TCB_EVAL_STATUS_ISVSVN_OUT_OF_DATE_BIT_POS 0x01
|
||||
|
||||
#define IAS_PSE_EVAL_STATUS_ISVSVN_OUT_OF_DATE_BIT_POS 0x00
|
||||
#define IAS_PSE_EVAL_STATUS_EPID_GROUP_REVOKED_BIT_POS 0x01
|
||||
#define IAS_PSE_EVAL_STATUS_PSDASVN_OUT_OF_DATE_BIT_POS 0x02
|
||||
#define IAS_PSE_EVAL_STATUS_SIGRL_OUT_OF_DATE_BIT_POS 0x03
|
||||
#define IAS_PSE_EVAL_STATUS_PRIVRL_OUT_OF_DATE_BIT_POS 0x04
|
||||
|
||||
// These status should align with the definition in IAS API spec(rev 0.6)
|
||||
#define ISVSVN_SIZE 2
|
||||
#define PSDA_SVN_SIZE 4
|
||||
#define GID_SIZE 4
|
||||
#define PSVN_SIZE 18
|
||||
|
||||
#define SAMPLE_HASH_SIZE 32 // SHA256
|
||||
#define SAMPLE_MAC_SIZE 16 // Message Authentication Code
|
||||
// - 16 bytes
|
||||
|
||||
#define SAMPLE_REPORT_DATA_SIZE 64
|
||||
|
||||
typedef uint8_t sample_measurement_t[SAMPLE_HASH_SIZE];
|
||||
typedef uint8_t sample_mac_t[SAMPLE_MAC_SIZE];
|
||||
typedef uint8_t sample_report_data_t[SAMPLE_REPORT_DATA_SIZE];
|
||||
typedef uint16_t sample_prod_id_t;
|
||||
|
||||
#define SAMPLE_CPUSVN_SIZE 16
|
||||
|
||||
typedef uint8_t sample_cpu_svn_t[SAMPLE_CPUSVN_SIZE];
|
||||
typedef uint16_t sample_isv_svn_t;
|
||||
|
||||
typedef struct sample_attributes_t {
|
||||
uint64_t flags;
|
||||
uint64_t xfrm;
|
||||
} sample_attributes_t;
|
||||
|
||||
typedef struct sample_report_body_t {
|
||||
sample_cpu_svn_t cpu_svn; // ( 0) Security Version of the CPU
|
||||
uint8_t reserved1[32]; // ( 16)
|
||||
sample_attributes_t attributes; // ( 48) Any special Capabilities
|
||||
// the Enclave possess
|
||||
sample_measurement_t mr_enclave; // ( 64) The value of the enclave's
|
||||
// ENCLAVE measurement
|
||||
uint8_t reserved2[32]; // ( 96)
|
||||
sample_measurement_t mr_signer; // (128) The value of the enclave's
|
||||
// SIGNER measurement
|
||||
uint8_t reserved3[32]; // (160)
|
||||
sample_measurement_t mr_reserved1; // (192)
|
||||
sample_measurement_t mr_reserved2; // (224)
|
||||
sample_prod_id_t isv_prod_id; // (256) Product ID of the Enclave
|
||||
sample_isv_svn_t isv_svn; // (258) Security Version of the
|
||||
// Enclave
|
||||
uint8_t reserved4[60]; // (260)
|
||||
sample_report_data_t report_data; // (320) Data provided by the user
|
||||
} sample_report_body_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct _ias_att_report_t {
|
||||
char id[100];
|
||||
ias_quote_status_t status;
|
||||
uint32_t revocation_reason;
|
||||
ias_platform_info_blob_t info_blob;
|
||||
ias_pse_status_t pse_status;
|
||||
uint32_t policy_report_size;
|
||||
uint8_t policy_report[];// IAS_Q: Why does it specify a list of reports?
|
||||
} ias_att_report_t;
|
||||
|
||||
#define SAMPLE_QUOTE_UNLINKABLE_SIGNATURE 0
|
||||
#define SAMPLE_QUOTE_LINKABLE_SIGNATURE 1
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ias_verify_attestation_evidence(uint8_t* p_isv_quote, uint8_t* pse_manifest, ias_att_report_t* attestation_verification_report, WebService *ws);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef _REMOTE_ATTESTATION_RESULT_H_
|
||||
#define _REMOTE_ATTESTATION_RESULT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SAMPLE_MAC_SIZE 16 /* Message Authentication Code*/
|
||||
/* - 16 bytes*/
|
||||
typedef uint8_t sample_mac_t[SAMPLE_MAC_SIZE];
|
||||
|
||||
#ifndef SAMPLE_FEBITSIZE
|
||||
#define SAMPLE_FEBITSIZE 256
|
||||
#endif
|
||||
|
||||
#define SAMPLE_NISTP256_KEY_SIZE (SAMPLE_FEBITSIZE/ 8 /sizeof(uint32_t))
|
||||
|
||||
typedef struct sample_ec_sign256_t {
|
||||
uint32_t x[SAMPLE_NISTP256_KEY_SIZE];
|
||||
uint32_t y[SAMPLE_NISTP256_KEY_SIZE];
|
||||
} sample_ec_sign256_t;
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
#define SAMPLE_SP_TAG_SIZE 16
|
||||
|
||||
typedef struct sp_aes_gcm_data_t {
|
||||
uint32_t payload_size; /* 0: Size of the payload which is*/
|
||||
/* encrypted*/
|
||||
uint8_t reserved[12]; /* 4: Reserved bits*/
|
||||
uint8_t payload_tag[SAMPLE_SP_TAG_SIZE];
|
||||
/* 16: AES-GMAC of the plain text,*/
|
||||
/* payload, and the sizes*/
|
||||
uint8_t payload[]; /* 32: Ciphertext of the payload*/
|
||||
/* followed by the plain text*/
|
||||
} sp_aes_gcm_data_t;
|
||||
|
||||
|
||||
#define ISVSVN_SIZE 2
|
||||
#define PSDA_SVN_SIZE 4
|
||||
#define GID_SIZE 4
|
||||
#define PSVN_SIZE 18
|
||||
|
||||
/* @TODO: Modify at production to use the values specified by an Production*/
|
||||
/* attestation server API*/
|
||||
typedef struct ias_platform_info_blob_t {
|
||||
uint8_t sample_epid_group_status;
|
||||
uint16_t sample_tcb_evaluation_status;
|
||||
uint16_t pse_evaluation_status;
|
||||
uint8_t latest_equivalent_tcb_psvn[PSVN_SIZE];
|
||||
uint8_t latest_pse_isvsvn[ISVSVN_SIZE];
|
||||
uint8_t latest_psda_svn[PSDA_SVN_SIZE];
|
||||
uint8_t performance_rekey_gid[GID_SIZE];
|
||||
sample_ec_sign256_t signature;
|
||||
} ias_platform_info_blob_t;
|
||||
|
||||
|
||||
typedef struct sample_ra_att_result_msg_t {
|
||||
ias_platform_info_blob_t platform_info_blob;
|
||||
sample_mac_t mac; /* mac_smk(attestation_status)*/
|
||||
sp_aes_gcm_data_t secret;
|
||||
} sample_ra_att_result_msg_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue