#include #include #include #include #include #include #include "employee.h" #include "util.h" #include #include #include #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 "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 file path of the PEM encoded private key of the employee\n" " -firm 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); }