From fc0438e5dd0f8f4689170b0a05cbc82c3679a9c7 Mon Sep 17 00:00:00 2001 From: Sascha Tommasone Date: Sun, 7 Jul 2024 22:33:11 +0200 Subject: [PATCH] [Assignment-7] final --- 7-SGX_Hands-on/src/app/embedded_device.c | 25 +++++++- 7-SGX_Hands-on/src/app/embedded_device.h | 13 +++++ 7-SGX_Hands-on/src/enclave/enclave.c | 51 +++++++++++----- 7-SGX_Hands-on/src/enclave/enclave.edl | 4 +- 7-SGX_Hands-on/src/enclave/enclave.h | 67 ++++++++++++++++++++- 7-SGX_Hands-on/src/simulate | 74 ++++++++++++++++++++++++ 7-SGX_Hands-on/src/simulate.sh | 38 ------------ 7 files changed, 212 insertions(+), 60 deletions(-) create mode 100755 7-SGX_Hands-on/src/simulate delete mode 100755 7-SGX_Hands-on/src/simulate.sh diff --git a/7-SGX_Hands-on/src/app/embedded_device.c b/7-SGX_Hands-on/src/app/embedded_device.c index 23fe486..3565de0 100644 --- a/7-SGX_Hands-on/src/app/embedded_device.c +++ b/7-SGX_Hands-on/src/app/embedded_device.c @@ -28,6 +28,9 @@ char *embedded_device_syntax(void) { " -firm path of to firmware binary\n"; } +/* + * read secp256r1 public key and return it as EVP_PKEY* + */ static EVP_PKEY *read_public_key(char *public_key_file_path, EVP_PKEY **key) { if(public_key_file_path == NULL) { fprintf(stderr, "public_key_file_path is a null pointer!\n"); @@ -46,6 +49,9 @@ static EVP_PKEY *read_public_key(char *public_key_file_path, EVP_PKEY **key) { return *key; } +/* + * hash the firmware + */ static void hash_firmware(uint8_t *firmware_path, EVP_MD_CTX **ctx) { if(firmware_path == NULL) { fprintf(stderr, "firmware_path is a null pointer!\n"); @@ -68,11 +74,13 @@ static void hash_firmware(uint8_t *firmware_path, EVP_MD_CTX **ctx) { } int handle_embedded_device(int argc, char **argv) { + uint8_t status = EXIT_SUCCESS; embedded_device_args args = { .firmware_path = NULL, .public_key_path = NULL }; + // parse parameters for(int i = 0; i < argc; i += 2) { if((strcmp(argv[i], "-ppub") == 0) && (argc - i >= 2)) { args.public_key_path = argv[i+1]; @@ -83,42 +91,53 @@ int handle_embedded_device(int argc, char **argv) { } } + // handle invalid parameters if((args.firmware_path == NULL) || (args.public_key_path == NULL)) { fprintf(stderr, "failed to parse arguments"); exit(EXIT_FAILURE); } + // read the public key of the enclave + // normally, key would be hardcoded during production EVP_PKEY *key = NULL; if(read_public_key(args.public_key_path, &key) == NULL) { fprintf(stderr, "failed to import public key"); + status = EXIT_FAILURE; goto clean; } + // initialize the context EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, key) != 1) { fprintf(stderr, "failed to initialize context\n"); + status = EXIT_FAILURE; goto clean; } + // read the firmwares signature uint8_t signature[BUFSIZE] = {0}; size_t signature_size = read(0, signature, BUFSIZE); if(signature_size < 70) { fprintf(stderr, "failed to read firmware signature\n"); + status = EXIT_FAILURE; goto clean; } + // hash the firmware and verify the signature hash_firmware(args.firmware_path, &ctx); if (EVP_DigestVerifyFinal(ctx, signature, signature_size) != 1) { - fprintf(stderr, "failed to verify firmware signature\n"); + fprintf(stderr, "failed to verify firmware signature or signature invalid\n"); + status = EXIT_FAILURE; }else { - printf("successfully verified firmware signature\n"); + printf("Firmware is valid! Update starts in 5 4 3...\n"); } + // cleanup clean: ; if(key != NULL) EVP_PKEY_free(key); if(ctx != NULL) EVP_MD_CTX_free(ctx); - return 0; + return status; } diff --git a/7-SGX_Hands-on/src/app/embedded_device.h b/7-SGX_Hands-on/src/app/embedded_device.h index 28ab514..c8eca52 100644 --- a/7-SGX_Hands-on/src/app/embedded_device.h +++ b/7-SGX_Hands-on/src/app/embedded_device.h @@ -3,8 +3,21 @@ #include +/* + * @brief getter for embedded subcommand syntax string + * + * @returns null-terminated syntax string + */ char *embedded_device_syntax(void); +/* + * @brief CLI implementation for the "embedded" subcommand + * + * @param argc number of arguments with command and subcommand stripped + * @param argv arguments with command and subcommand stripped + * + * @returns 0 on success, else error with output on stderr + */ int handle_embedded_device(int argc, char **argv); #endif \ No newline at end of file diff --git a/7-SGX_Hands-on/src/enclave/enclave.c b/7-SGX_Hands-on/src/enclave/enclave.c index 2cd3a80..23d2771 100644 --- a/7-SGX_Hands-on/src/enclave/enclave.c +++ b/7-SGX_Hands-on/src/enclave/enclave.c @@ -58,11 +58,23 @@ #define SI_SIZE 2*SK_SIZE #endif - +/* +* Bobs and Alices public keys +*/ const sgx_ec256_public_t authorized[2] = { { - 0, - 0 + .gx = { + 0x9c, 0x72, 0x2b, 0x52, 0x0e, 0xff, 0x07, 0xdc, + 0x7a, 0x32, 0x19, 0xbb, 0xd8, 0x41, 0x94, 0x2c, + 0xee, 0x17, 0xb2, 0xf6, 0x2e, 0x08, 0x61, 0xab, + 0xbc, 0x50, 0xaf, 0xb6, 0x2e, 0xf9, 0x2c, 0xee + }, + .gy = { + 0x8c, 0x84, 0x2f, 0xb5, 0x94, 0xca, 0x60, 0x94, + 0xb0, 0xdc, 0x8a, 0xcf, 0x17, 0x91, 0xd3, 0xab, + 0x29, 0x0e, 0x81, 0x8c, 0xf6, 0x95, 0xc6, 0x92, + 0x87, 0x0e, 0x1d, 0x76, 0x56, 0xba, 0x51, 0xbb + } }, { .gx = { @@ -101,6 +113,9 @@ int get_private_key_size() { return SK_SIZE; } +/* + * seals a key pair + */ static sgx_status_t seal_key_pair(const sgx_ec256_private_t *private, const sgx_ec256_public_t *public, uint8_t **sealed) { // allocate temporary buffers on stack uint8_t pk[PK_SIZE] = {0}; @@ -114,6 +129,9 @@ static sgx_status_t seal_key_pair(const sgx_ec256_private_t *private, const sgx_ return sgx_seal_data(PK_SIZE, (const uint8_t *)pk, SK_SIZE, (const uint8_t *)sk, get_sealed_size(), (sgx_sealed_data_t *) *sealed); } +/* + * unseals a key pair + */ static sgx_status_t unseal_key_pair(const uint8_t *sealed, sgx_ec256_private_t *private, sgx_ec256_public_t *public) { // invalid parameter handling if(sealed == NULL) { @@ -166,12 +184,12 @@ sgx_status_t generate_key_pair(uint8_t *sealed, uint32_t sealed_size) { return status; } - // create ecc keypair + // create ecc key pair if((status = sgx_ecc256_create_key_pair(&private, &public, ecc_handle)) != SGX_SUCCESS) { goto exit; } - // seal keypair + // seal key pair status = seal_key_pair(&private, &public, &sealed); exit: ; @@ -197,9 +215,12 @@ sgx_status_t get_public_key(const uint8_t *sealed, uint32_t sealed_size, uint8_t return status; } -static sgx_status_t verify_signature(const uint8_t *data, uint32_t data_size, const sgx_ec256_public_t *public, const sgx_ec256_signature_t* ecc_signature) { +/* + * verifies an ecdsa signature + */ +static sgx_status_t verify_signature(const uint8_t *firmware, uint32_t firmware_size, const sgx_ec256_public_t *public, const sgx_ec256_signature_t* ecc_signature) { // invalid parameter handling - if((data == NULL) || (data_size == 0) || (public == NULL) || (ecc_signature == NULL)) { + if((firmware == NULL) || (firmware_size == 0) || (public == NULL) || (ecc_signature == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } @@ -214,7 +235,7 @@ static sgx_status_t verify_signature(const uint8_t *data, uint32_t data_size, co // verify signature uint8_t result; - sgx_status_t verification_status = sgx_ecdsa_verify(data, data_size, public, ecc_signature, &result, ecc_handle); + sgx_status_t verification_status = sgx_ecdsa_verify(firmware, firmware_size, public, ecc_signature, &result, ecc_handle); // handle failed verification process if(verification_status != SGX_SUCCESS) { @@ -226,9 +247,9 @@ static sgx_status_t verify_signature(const uint8_t *data, uint32_t data_size, co return result; } -sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature) { +sgx_status_t sign_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature) { // invalid parameter handling - if((data == NULL) || (data_size == 0)) { + if((firmware == NULL) || (firmware_size == 0)) { return SGX_ERROR_INVALID_PARAMETER; } else if((public_key == NULL) || (signature == NULL)) { return SGX_ERROR_INVALID_PARAMETER; @@ -258,7 +279,7 @@ sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, const uint8_ } // verify request - if((status = verify_signature(data, data_size, (const sgx_ec256_public_t *)public_key, (const sgx_ec256_signature_t *)signature)) != SGX_EC_VALID) { + if((status = verify_signature(firmware, firmware_size, (const sgx_ec256_public_t *)public_key, (const sgx_ec256_signature_t *)signature)) != SGX_EC_VALID) { goto exit; } @@ -268,7 +289,7 @@ sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, const uint8_ } // create signature - if((status = sgx_ecdsa_sign(data, data_size, &private, &ecc_signature, ecc_handle)) != SGX_SUCCESS) { + if((status = sgx_ecdsa_sign(firmware, firmware_size, &private, &ecc_signature, ecc_handle)) != SGX_SUCCESS) { goto exit; } @@ -281,9 +302,9 @@ sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, const uint8_ return status; } -sgx_status_t verify_firmware(const uint8_t *data, uint32_t data_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature) { +sgx_status_t verify_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature) { // invalid parameter handling - if((data == NULL) || (data_size == 0) || (signature == NULL)) { + if((firmware == NULL) || (firmware_size == 0) || (signature == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } else if((sealed == NULL) && (public_key == NULL)) { return SGX_ERROR_INVALID_PARAMETER; @@ -318,5 +339,5 @@ sgx_status_t verify_firmware(const uint8_t *data, uint32_t data_size, const uint } // verify signature and return result - return verify_signature(data, data_size, &public, (const sgx_ec256_signature_t *)signature); + return verify_signature(firmware, firmware_size, &public, (const sgx_ec256_signature_t *)signature); } \ No newline at end of file diff --git a/7-SGX_Hands-on/src/enclave/enclave.edl b/7-SGX_Hands-on/src/enclave/enclave.edl index c2647c7..258b2f7 100644 --- a/7-SGX_Hands-on/src/enclave/enclave.edl +++ b/7-SGX_Hands-on/src/enclave/enclave.edl @@ -47,8 +47,8 @@ enclave { public int get_private_key_size(); public sgx_status_t generate_key_pair([out, size=sealed_size]uint8_t *sealed, uint32_t sealed_size); public sgx_status_t get_public_key([in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [out, size=64]uint8_t *public_key); - public sgx_status_t sign_firmware([in, size=data_size]const uint8_t *data, uint32_t data_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, out, size=64]uint8_t *public_key, [in, out, size=64]uint8_t *signature); - public sgx_status_t verify_firmware([in, size=data_size]const uint8_t *data, uint32_t data_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, size=64]const uint8_t *public_key, [in, size=64]const uint8_t *signature); + public sgx_status_t sign_firmware([in, size=firmware_size]const uint8_t *firmware, uint32_t firmware_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, out, size=64]uint8_t *public_key, [in, out, size=64]uint8_t *signature); + public sgx_status_t verify_firmware([in, size=firmware_size]const uint8_t *firmware, uint32_t firmware_size, [in, size=sealed_size]const uint8_t *sealed, uint32_t sealed_size, [in, size=64]const uint8_t *public_key, [in, size=64]const uint8_t *signature); }; /* diff --git a/7-SGX_Hands-on/src/enclave/enclave.h b/7-SGX_Hands-on/src/enclave/enclave.h index 17ad535..546f4bb 100644 --- a/7-SGX_Hands-on/src/enclave/enclave.h +++ b/7-SGX_Hands-on/src/enclave/enclave.h @@ -36,15 +36,78 @@ #include #include +/* + * returns the size of the sealed key pair + */ int get_sealed_size(); + +/* + * returns the length of the hash used in the signature + */ int get_digest_size(); + +/* + * returns the size of the signature created by the enclave + */ int get_signature_size(); + +/* + * returns the size of the public key + */ int get_public_key_size(); + +/* + * returns the size of the private key + */ int get_private_key_size(); +/* + * @brief generates a secp256r1 key pair and returns it sealed by the TEE + * + * @param sealed buffer to hold the sealed key pair + * @param sealed_size size of the sealed key pair + * + * @returns SGX_SUCCESS on success, else sgx error code + */ sgx_status_t generate_key_pair(uint8_t *sealed, uint32_t sealed_size); + +/* + * @brief returns the public key of the sealed key pair provided to the enclave + * + * @param sealed buffer containing the sealed key pair + * @param sealed_size size of the sealed key pair + * @param public_key buffer to hold the public key + * + * @returns SGX_SUCCESS on success, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code + */ sgx_status_t get_public_key(const uint8_t *sealed, const uint32_t sealed_size, uint8_t *public_key); -sgx_status_t sign_firmware(const uint8_t *data, uint32_t data_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature); -sgx_status_t verify_firmware(const uint8_t *data, uint32_t data_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature); + +/* + * @brief signs the firmware provided by an authorized employee + * + * @param firmware buffer containing the firmware + * @param firmware_size size of the sealed key pair + * @param sealed buffer containing the sealed key pair + * @param sealed_size size of the sealed key pair + * @param public_key buffer with the employees public key; holds enclaves public key after successful signing + * @param signature buffer with the employees signature; holds the enclaves signature after successful signing + * + * @returns SGX_SUCCESS on success, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code + */ +sgx_status_t sign_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, uint8_t *public_key, uint8_t *signature); + +/* + * @brief verifies a firmware signature provided by an authorized employee or enclave + * + * @param firmware buffer containing the firmware + * @param firmware_size size of the sealed key pair or NULL + * @param sealed buffer containing the sealed key pair + * @param sealed_size size of the sealed key pair + * @param public_key buffer with the employees public key or NULL + * @param signature buffer with the employees signature + * + * @returns SGX_EC_VALID on success, SGX_EC_INVALID for invalid signatures, SGX_ERROR_INVALID_PARAMETER for invalid parameters, else sgx error code + */ +sgx_status_t verify_firmware(const uint8_t *firmware, uint32_t firmware_size, const uint8_t *sealed, uint32_t sealed_size, const uint8_t *public_key, const uint8_t *signature); #endif /* !_ENCLAVE_H_ */ \ No newline at end of file diff --git a/7-SGX_Hands-on/src/simulate b/7-SGX_Hands-on/src/simulate new file mode 100755 index 0000000..6933392 --- /dev/null +++ b/7-SGX_Hands-on/src/simulate @@ -0,0 +1,74 @@ +#!/usr/bin/env sh +set -u + +# colors +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +# helper function +print_and_execute() { + local color=$1 + shift + echo "⚡ ${color}$@${NC}" + eval "$@" + return $? +} + +# setup +TMP=/tmp/signatureproxy +KEYDIR=../employee_keys +mkdir -p $TMP + +########### Disclaimer ################# +# Die Story wurde von ChatGPT erstellt # +######################################## + +# simulation +print_and_execute "$GREEN" "./signatureproxy proxysetup -pkey $TMP/proxy_private.bin > $TMP/proxy_public.pem" + +echo "At Embedded Solutions Inc., security was paramount. The company specialized in creating firmware for a wide range of embedded devices used in critical industries, from medical equipment to automotive systems. To protect their firmware, they had implemented a sophisticated signature proxy system using Intel's SGX enclave technology." +echo "One bright morning, Alice, a senior engineer known for her meticulous work, arrived at her desk. She was tasked with signing the latest stable version of a critical medical device firmware that she had finished the previous night." + +echo "With the proxy ready, Alice compiled their latest stable version. This firmware would soon run on life-saving medical devices, a fact that weighed heavily on her as she meticulously checked every detail." +print_and_execute "$GREEN" "dd if=/dev/urandom of=$TMP/firmware.bin bs=1M count=1 2> /dev/null" + +echo "Once satisfied with the build, Alice signed the firmware with her private key as an assurance to the company that the firmware came from a trusted source." +print_and_execute "$GREEN" "./signatureproxy employee -ekey $KEYDIR/alice_private.pem -firm $TMP/firmware.bin > $TMP/signature_alice.der" + +echo "The firmware, along with Alice's signature, was then sent to the signature proxy. The proxy, acting as a vigilant guardian, verified Alice's signature against a list of authorized keys. Her identity confirmed, the proxy resigned the firmware with its own private key." +print_and_execute "$GREEN" "cat $TMP/signature_alice.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/alice_public.pem -firm $TMP/firmware.bin > $TMP/signature_for_alice.der" + +echo "The final step was crucial: verifying the signed firmware to ensure it was ready for deployment. The team couldn't afford any mistakes, knowing the firmware's destination were life-saving medical devices." +print_and_execute "$GREEN" "cat $TMP/signature_for_alice.der | ./signatureproxy embedded -ppub $TMP/proxy_public.pem -firm $TMP/firmware.bin > /dev/null" + +echo "\nMeanwhile, in a dark corner of the tech world, Oskar, a disgruntled former employee, was plotting his revenge. He had managed to get his hands on an old private key. With malicious intent, he set out to sign a modified version of the firmware, hoping to bypass the security measures." + +echo "Oskar, driven by his vendetta, signed the firmware with his old private key, intending to trick the system and cause havoc." +print_and_execute "$RED" "./signatureproxy employee -ekey $KEYDIR/oskar_private.pem -firm $TMP/firmware.bin > $TMP/signature_oskar.der" + +echo "With a smug grin, he tried to pass his signed firmware through the proxy. But the system was built to withstand such threats. The proxy, ever vigilant, scrutinized the incoming data." +print_and_execute "$RED" "cat $TMP/signature_oskar.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/oskar_public.pem -firm $TMP/firmware.bin > $TMP/signature_for_oskar.der" +status=$? +if [ $status -eq 0 ]; then + echo "Oskar's firmware signing attempt seemed successful. :(" + exit 1 +else + echo "The proxy detected Oskar's unauthorized key and rejected the firmware. His malicious intent was thwarted, and the firmware remained secure." +fi + +echo "With Oskar's attempt foiled, Embedded Solutions could breathe a sigh of relief. The integrity of their firmware was intact, safeguarded by the robust security measures of their signature proxy system. Alice and her team could continue their work with confidence, knowing that their systems were safe from internal and external threats." + +echo "\nIn the meantime, Bob, another trusted engineer, was working on a firmware update for the automotive sector. This update was equally critical and needed the same level of security scrutiny." +print_and_execute "$GREEN" "dd if=/dev/urandom of=$TMP/firmware2.bin bs=1M count=1 2> /dev/null" + +echo "Bob finished his work and, following the security protocols, signed the new firmware with his private key." +print_and_execute "$GREEN" "./signatureproxy employee -ekey $KEYDIR/bob_private.pem -firm $TMP/firmware2.bin > $TMP/signature_bob.der" + +echo "The signed firmware was then sent to the signature proxy. As expected, the proxy verified Bob's signature and signed the firmware with its private key, ensuring the update's authenticity." +print_and_execute "$GREEN" "cat $TMP/signature_bob.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/bob_public.pem -firm $TMP/firmware2.bin > $TMP/signature_for_bob.der" + +echo "The final verification process confirmed that Bob's firmware update was secure and ready for deployment." +print_and_execute "$GREEN" "cat $TMP/signature_for_bob.der | ./signatureproxy embedded -ppub $TMP/proxy_public.pem -firm $TMP/firmware2.bin > /dev/null" + +echo "This concludes the story of Alice, Oskar, Bob, and the secure firmware signing process at Embedded Solutions Inc. Through the diligent efforts of trusted employees and advanced security technology, the integrity and safety of their embedded devices were preserved." \ No newline at end of file diff --git a/7-SGX_Hands-on/src/simulate.sh b/7-SGX_Hands-on/src/simulate.sh deleted file mode 100755 index 54a0943..0000000 --- a/7-SGX_Hands-on/src/simulate.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env sh -set -eu - -TMP=/tmp/signatureproxy -KEYDIR=../employee_keys -mkdir -p $TMP - -echo "At Embedded Solutions Inc., security was paramount. The company specialized in creating firmware for a wide range of embedded devices used in critical industries, from medical equipment to automotive systems. To protect their firmware, they had implemented a sophisticated signature proxy system using Intel's SGX enclave technology." - -echo "One bright morning, Alice, a senior engineer known for her meticulous work, arrived at her desk. She was tasked with signing the latest stable version of a critical medical device firmware that she had finished engineering the previous night." - -echo "As she settled in, the IT team, always vigilant, prepared the signature proxy. They initialized it with a secret key stored securely within the enclave, ensuring that only authorized firmware could pass through." -./signatureproxy proxysetup -pkey $TMP/proxy_private.bin > $TMP/proxy_public.pem -echo "The proxy was now ready to guard the integrity of their firmware." - -echo "With the proxy ready, Alice compiled the latest stable version of the firmware. This firmware would soon run on life-saving medical devices, a fact that weighed heavily on her as she meticulously checked every detail." -dd if=/dev/urandom of=$TMP/firmware.bin bs=1M count=1 2> /dev/null - -echo "Once satisfied with the build, Alice signed the firmware with her private key. This was her mark, an assurance to the company that the firmware came from a trusted source." -./signatureproxy employee -ekey $KEYDIR/alice_private.pem -firm $TMP/firmware.bin > $TMP/signature_alice.der - -echo "The signed firmware, along with Alice's signature, was then sent to the signature proxy. The proxy, acting as a vigilant guardian, verified Alice's signature against a list of authorized keys. Her identity confirmed, the proxy signed the firmware with its own private key, adding an extra layer of security." -cat $TMP/signature_alice.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/alice_public.pem -firm $TMP/firmware.bin > $TMP/signature_for_alice.der - -echo "The final step was crucial: verifying the signed firmware to ensure it was ready for deployment. The team couldn't afford any mistakes, knowing the firmware's destination were life-saving medical devices." -cat $TMP/signature_for_alice.der | ./signatureproxy embedded -ppub $TMP/proxy_public.pem -firm $TMP/firmware.bin - -echo "Meanwhile, in a dark corner of the tech world, Oskar, a disgruntled former employee, was plotting his revenge. He had managed to get his hands on an old private key. With malicious intent, he set out to sign a modified version of the firmware, hoping to bypass the security measures." - -echo "Oskar, driven by his vendetta, signed the firmware with his private key, intending to trick the system and cause havoc." -./signatureproxy employee -ekey $KEYDIR/oskar_private.pem -firm $TMP/firmware.bin > $TMP/signature_oskar.der - -echo "With a smug grin, he tried to pass his signed firmware through the proxy. But the system was built to withstand such threats. The proxy, ever vigilant, scrutinized the incoming data." -cat $TMP/signature_oskar.der | ./signatureproxy proxy -pkey $TMP/proxy_private.bin -epub $KEYDIR/oskar_public.pem -firm $TMP/firmware.bin > $TMP/signature_oskar.der 2> /dev/null && echo "Oskar's firmware signing attempt seemed successful. (This should not happen in a secure system!)" || echo "The proxy detected Oskar's unauthorized key and rejected the firmware. His malicious intent was thwarted, and the firmware remained secure." - -echo "With Oskar's attempt foiled, Embedded Solutions could breathe a sigh of relief. The integrity of their firmware was intact, safeguarded by the robust security measures of their signature proxy system. Alice and her team could continue their work with confidence, knowing that their systems were safe from internal and external threats." - -echo "This concludes the story of Alice, Oskar, and the secure firmware signing process at Embedded Solutions Inc. Through the diligent efforts of trusted employees and advanced security technology, the integrity and safety of their embedded devices were preserved." \ No newline at end of file