Systemsicherheit/7-SGX_Hands-on/src/app/employee.c

137 lines
3.3 KiB
C
Raw Normal View History

#include <errno.h>
#include <sgx_urts.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "employee.h"
#include "util.h"
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#define HASH_BYTES 32
#define HASH_CHUNK_BYTES 32
#define KEY_BYTES 32
struct EmployeeArgs {
char* key_path;
char* firmware_path;
};
char* employee_syntax(void) {
return
2024-07-06 18:06:12 +02:00
"employee mock up implementation of the employee binary\n"
" outputs signature on stdout\n"
" WARNING: output is in binary format, may mess up terminal\n"
" -ekey <path> file path of the PEM encoded private key of the employee\n"
" -firm <path> path of the firmware\n";
}
int handle_employee(int argc, char** argv) {
struct EmployeeArgs args = {
NULL,
NULL
};
FILE* key_file = NULL;
uint8_t* firmware_buf;
size_t firmware_len;
EVP_PKEY* key = NULL;
EVP_MD_CTX *mdctx = NULL;
size_t sig_len;
unsigned char* sig = NULL;
/*
* Parse Input
*/
int i = 0;
while(i < argc) {
if(strcmp(argv[i], "-ekey")==0 && argc-i >=2){
args.key_path = argv[i+1];
i += 2;
}else if(strcmp(argv[i], "-firm")==0 && argc-i >=2){
args.firmware_path = argv[i+1];
i += 2;
}else
syntax_exit();
}
if(args.key_path == NULL)
syntax_exit();
/*
* Load Signing Key
*/
key_file = fopen(args.key_path, "rb");
if(key_file == NULL){
perror("Error opening key file");
exit (EXIT_FAILURE);
}
key = PEM_read_PrivateKey(key_file, &key, NULL, NULL);
if(key == NULL) {
fprintf(stderr, "failed to read key\n");
exit (EXIT_FAILURE);
}
fclose(key_file);
/*
* Sign Firmware
*/
mdctx = EVP_MD_CTX_new();
if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key) != 1) {
fprintf(stderr, "Message digest initialization failed.\n");
exit (EXIT_FAILURE);
}
if (load_file(args.firmware_path, &firmware_buf, &firmware_len) != 0) {
fprintf(stderr, "failed to read firmware\n");
exit (EXIT_FAILURE);
}
if (EVP_DigestSignUpdate(mdctx, firmware_buf, firmware_len) != 1) {
printf("Message digest update failed.\n");
exit(EXIT_FAILURE);
}
free(firmware_buf);
// call with empty sig to get length
if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) != 1) {
printf("Message digest finalization failed.\n");
exit (EXIT_FAILURE);
}
// allocate signature buffer
sig = malloc(sizeof(unsigned char) * sig_len);
if(sig == NULL){
perror("could not initialize digest buffer");
exit (EXIT_FAILURE);
}
// load signature into buffer
if (EVP_DigestSignFinal(mdctx, sig, &sig_len) != 1) {
printf("Message digest finalization failed.\n");
exit (EXIT_FAILURE);
}
fwrite(sig, sig_len, 1, stdout);
if (ferror(stdout) != 0) {
fprintf(stdout, "failed to write signature to stdout\n");
exit (EXIT_FAILURE);
}
fflush(stdout);
// free all allocated resources
free(sig);
EVP_MD_CTX_free(mdctx);
EVP_PKEY_free(key);
exit (EXIT_SUCCESS);
}