Skip to content

Commit

Permalink
FHMQV-C-based remote attestation
Browse files Browse the repository at this point in the history
  • Loading branch information
kkrentz committed Sep 20, 2024
1 parent cd54860 commit fc02f98
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
6 changes: 6 additions & 0 deletions sdk/include/shared/attestation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef __ATTESTATION_H__
#define __ATTESTATION_H__

#define WITH_TRAP 1

#endif // __ATTESTATION_H__
8 changes: 8 additions & 0 deletions sdk/include/verifier/Report.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@
#include <iostream>
#include <string>
#include "Keys.hpp"
#include "shared/attestation.h"
#include "verifier/json11.h"

struct enclave_report_t {
byte hash[MDSIZE];
uint64_t data_len;
byte data[ATTEST_DATA_MAXLEN];
#if WITH_TRAP
byte ephemeral_public_key_compressed[PUBLIC_KEY_COMPRESSED_SIZE];
byte fhmqv_key[MDSIZE];
byte servers_fhmqv_mic[MDSIZE];
byte clients_fhmqv_mic[MDSIZE];
#else /* WITH_TRAP */
byte signature[SIGNATURE_SIZE];
#endif /* WITH_TRAP */
};

struct sm_report_t {
Expand Down
26 changes: 26 additions & 0 deletions sdk/src/verifier/Report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,15 @@ Report::fromJson(std::string jsonstr) {
report.enclave.data_len = json["enclave"]["datalen"].int_value();
std::string enclave_data = json["enclave"]["data"].string_value();
HexToBytes(report.enclave.data, report.enclave.data_len, enclave_data);
#if WITH_TRAP
std::string servers_fhmqv_mic = json["enclave"]["servers_fhmqv_mic"].string_value();
HexToBytes(report.enclave.servers_fhmqv_mic, sizeof(report.enclave.servers_fhmqv_mic), servers_fhmqv_mic);
std::string clients_fhmqv_mic = json["enclave"]["clients_fhmqv_mic"].string_value();
HexToBytes(report.enclave.clients_fhmqv_mic, sizeof(report.enclave.clients_fhmqv_mic), clients_fhmqv_mic);
#else /* WITH_TRAP */
std::string enclave_signature = json["enclave"]["signature"].string_value();
HexToBytes(report.enclave.signature, SIGNATURE_SIZE, enclave_signature);
#endif /* WITH_TRAP */
}

void
Expand Down Expand Up @@ -88,8 +95,15 @@ Report::stringfy() {
{"datalen", static_cast<int>(report.enclave.data_len)},
{"data",
BytesToHex(report.enclave.data, report.enclave.data_len)},
#if WITH_TRAP
{"servers_fhmqv_mic",
BytesToHex(report.enclave.servers_fhmqv_mic, sizeof(report.enclave.servers_fhmqv_mic))},
{"clients_fhmqv_mic",
BytesToHex(report.enclave.clients_fhmqv_mic, sizeof(report.enclave.clients_fhmqv_mic))},
#else /* WITH_TRAP */
{"signature",
BytesToHex(report.enclave.signature, SIGNATURE_SIZE)},
#endif /* WITH_TRAP */
},
},
};
Expand All @@ -112,8 +126,16 @@ Report::printPretty() {
<< std::endl;
std::cout << std::endl << "\t\t=== Enclave Application ===" << std::endl;
std::cout << "Hash: " << BytesToHex(report.enclave.hash, MDSIZE) << std::endl;
#if WITH_TRAP
std::cout << "Server's FHMQV MIC: "
<< BytesToHex(report.enclave.servers_fhmqv_mic, sizeof(report.enclave.servers_fhmqv_mic))
<< std::endl;
std::cout << "Client's FHMQV MIC: "
<< BytesToHex(report.enclave.clients_fhmqv_mic, sizeof(report.enclave.clients_fhmqv_mic))
#else /* WITH_TRAP */
std::cout << "Signature: "
<< BytesToHex(report.enclave.signature, SIGNATURE_SIZE)
#endif /* WITH_TRAP */
<< std::endl;
std::cout << "Enclave Data: "
<< BytesToHex(report.enclave.data, report.enclave.data_len)
Expand Down Expand Up @@ -161,11 +183,15 @@ Report::checkSignaturesOnly(const byte* dev_public_key) {
sm_valid = uECC_verify(dev_public_key, md, MDSIZE, report.sm.signature, uECC_CURVE());

/* verify Enclave report */
#if WITH_TRAP
enclave_valid = 1;
#else /* WITH_TRAP */
uECC_decompress(report.sm.public_key, sm_public_key, uECC_CURVE());
memcpy(scratchpad, report.enclave.hash, MDSIZE);
memcpy(scratchpad + MDSIZE, report.enclave.data, report.enclave.data_len);
SHA_256.hash(scratchpad, MDSIZE + report.enclave.data_len, md);
enclave_valid = uECC_verify(sm_public_key, md, MDSIZE, report.enclave.signature, uECC_CURVE());
#endif /* WITH_TRAP */

return sm_valid && enclave_valid;
}
Expand Down
8 changes: 8 additions & 0 deletions sm/src/enclave.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ unsigned long attest_enclave(uintptr_t report_ptr, uintptr_t data, uintptr_t siz
sbi_memcpy(report.sm.signature, sm_signature, SIGNATURE_SIZE);
sbi_memcpy(report.enclave.hash, enclaves[eid].hash, MDSIZE);

#if WITH_TRAP
if (!report.enclave.data_len) {
/* this is for printing hashes at start up */
} else if (sm_fhmqv(&report.enclave)) {
return SBI_ERR_SM_ENCLAVE_UNKNOWN_ERROR;
}
#else /* WITH_TRAP */
{
byte digest[MDSIZE];
hash_ctx ctx;
Expand All @@ -648,6 +655,7 @@ unsigned long attest_enclave(uintptr_t report_ptr, uintptr_t data, uintptr_t siz
return SBI_ERR_SM_ENCLAVE_UNKNOWN_ERROR;
}
}
#endif /* WITH_TRAP */

spin_lock(&encl_lock);

Expand Down
7 changes: 7 additions & 0 deletions sm/src/enclave.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,14 @@ struct enclave_report
byte hash[MDSIZE];
uint64_t data_len;
byte data[ATTEST_DATA_MAXLEN];
#if WITH_TRAP
byte ephemeral_public_key_compressed[PUBLIC_KEY_COMPRESSED_SIZE];
byte fhmqv_key[MDSIZE];
byte servers_fhmqv_mic[MDSIZE];
byte clients_fhmqv_mic[MDSIZE];
#else /* WITH_TRAP */
byte signature[SIGNATURE_SIZE];
#endif /* WITH_TRAP */
};
struct sm_report
{
Expand Down
82 changes: 82 additions & 0 deletions sm/src/sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,88 @@ static int osm_init(void)
return region;
}

#if WITH_TRAP
int sm_fhmqv(struct enclave_report *enclave_report)
{
const uint8_t *spka; /* client's static public key */
uint8_t epka[PUBLIC_KEY_SIZE]; /* clients ephemeral public key */
uint8_t epkb[PUBLIC_KEY_SIZE];
hash_ctx ctx;
byte d[MDSIZE];
byte e[MDSIZE];
uint8_t eskb[PRIVATE_KEY_SIZE];
uint8_t sigma[MDSIZE];
uint8_t ikm[4 * PUBLIC_KEY_SIZE];
uint8_t okm[2 * MDSIZE];
sha_256_hmac_context_t hmac_ctx;

if (enclave_report->data_len
!= (PUBLIC_KEY_SIZE + PUBLIC_KEY_COMPRESSED_SIZE)) {
return -1;
}
spka = enclave_report->data;
uECC_decompress(enclave_report->data + PUBLIC_KEY_SIZE, epka, uECC_CURVE());
if (!uECC_make_key(epkb, eskb, uECC_CURVE())) {
return -1;
}
uECC_compress(epkb,
enclave_report->ephemeral_public_key_compressed,
uECC_CURVE());

hash_init(&ctx);
hash_extend(&ctx, epka, sizeof(epka));
hash_extend(&ctx, epkb, sizeof(epkb));
hash_extend(&ctx, spka, PUBLIC_KEY_SIZE);
hash_extend(&ctx, sm_public_key, sizeof(sm_public_key));

hash_finalize(d, &ctx);
sbi_memcpy(e + (sizeof(e) / 2), d, sizeof(e) / 2);
sbi_memset(e, 0, sizeof(e) / 2);
sbi_memset(d, 0, sizeof(d) / 2);

if (!uECC_shared_fhmqv_secret(sigma,
sm_private_key,
eskb,
spka,
epka,
e,
d,
uECC_CURVE())) {
return -1;
}
sbi_memcpy(ikm, spka, PUBLIC_KEY_SIZE);
sbi_memcpy(ikm + PUBLIC_KEY_SIZE,
sm_public_key,
sizeof(sm_public_key));
sbi_memcpy(ikm + PUBLIC_KEY_SIZE + sizeof(sm_public_key),
epka,
sizeof(epka));
sbi_memcpy(ikm + PUBLIC_KEY_SIZE + sizeof(sm_public_key) + sizeof(epka),
epkb,
sizeof(epkb));
kdf(
NULL, 0, /* TODO use salt */
sigma, sizeof(sigma),
ikm, sizeof(ikm),
okm, sizeof(okm));
sbi_memcpy(enclave_report->fhmqv_key,
okm + sizeof(okm) / 2,
sizeof(okm) / 2);
sha_256_hmac_init(&hmac_ctx, okm, sizeof(okm) / 2);
sha_256_hmac_update(&hmac_ctx, sm_public_key, sizeof(sm_public_key));
sha_256_hmac_update(&hmac_ctx, epkb, sizeof(epkb));
sha_256_hmac_update(&hmac_ctx,
enclave_report->hash,
sizeof(enclave_report->hash));
sha_256_hmac_finish(&hmac_ctx, enclave_report->servers_fhmqv_mic);
sha_256_hmac_init(&hmac_ctx, okm, sizeof(okm) / 2);
sha_256_hmac_update(&hmac_ctx, spka, PUBLIC_KEY_SIZE);
sha_256_hmac_update(&hmac_ctx, epka, sizeof(epka));
sha_256_hmac_finish(&hmac_ctx, enclave_report->clients_fhmqv_mic);
return 0;
}
#endif /* WITH_TRAP */

int sm_sign(void* signature, byte digest[MDSIZE])
{
if (!uECC_sign(sm_private_key, digest, MDSIZE, signature, uECC_CURVE())) {
Expand Down
5 changes: 5 additions & 0 deletions sm/src/sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "sm-sbi.h"
#include <sbi/riscv_encoding.h>

#include "attestation.h"
#include "sm_call.h"
#include "sm_err.h"

Expand All @@ -19,6 +20,10 @@ void sm_init(bool cold_boot);
/* platform specific functions */
#define ATTESTATION_KEY_LENGTH 64
void sm_retrieve_pubkey(void* dest);
#if WITH_TRAP
struct enclave_report;
int sm_fhmqv(struct enclave_report *enclave_report);
#endif /* WITH_TRAP */
int sm_sign(void* signature, byte digest[MDSIZE]);
int sm_derive_sealing_key(unsigned char *key,
const unsigned char *key_ident,
Expand Down

0 comments on commit fc02f98

Please sign in to comment.