Skip to content

Commit

Permalink
feat(hss-payload-gen): Add verify to code signing
Browse files Browse the repository at this point in the history
Add ability to verify code signing to hss-payload-generator.
This allows the specification of a public key (in DER format)
when either performing payload generator or payload inspection.

Signed-off-by: Ivan Griffin <[email protected]>
  • Loading branch information
griffini authored and Ivan Griffin committed Oct 14, 2024
1 parent bda2fed commit f91740f
Show file tree
Hide file tree
Showing 20 changed files with 374 additions and 49 deletions.
1 change: 1 addition & 0 deletions tools/hss-payload-generator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SRCS=\
generate_payload.c \
dump_payload.c \
debug_printf.c \
verify_payload.c \

OBJS := $(patsubst %.c,$(build_dir)/%.o,$(SRCS))

Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/blob_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/blob_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/crc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/crc32.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/debug_printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/debug_printf.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
16 changes: 13 additions & 3 deletions tools/hss-payload-generator/dump_payload.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down Expand Up @@ -43,6 +43,7 @@
#include "debug_printf.h"
#include "dump_payload.h"
#include "crc32.h"
#include "verify_payload.h"

#define PRV_U (0u)
#define PRV_S (1u)
Expand Down Expand Up @@ -85,7 +86,7 @@ static char const * privModeToString(uint8_t privMode)
return result;
}

void dump_payload(const char *filename_input)
void dump_payload(const char *filename_input, const char *public_key_filename)
{
printf("opening >>%s<<\n", filename_input);
int fdIn = open(filename_input, O_RDONLY);
Expand All @@ -94,8 +95,12 @@ void dump_payload(const char *filename_input)
size_t fileSize = getFileSize(filename_input);

struct HSS_BootImage *pBootImage;
void *raw_image;

pBootImage = mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fdIn, 0);
raw_image = mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fdIn, 0);
debug_printf(6, "Mapped %d (%x) bytes at %p (to %p)\n", fileSize, fileSize, raw_image, ((uint8_t*)raw_image) + fileSize);

pBootImage = (struct HSS_BootImage *)raw_image;
assert(pBootImage);
if (pBootImage == MAP_FAILED) {
perror("mmap()");
Expand Down Expand Up @@ -236,6 +241,11 @@ void dump_payload(const char *filename_input)

// skipping binary file array

if (public_key_filename) {
bool result = HSS_Boot_Secure_CheckCodeSigning(raw_image, public_key_filename);
printf("Public Key Specified so verifying signature... %s\n\n", result ? "passed" : "failed");
}

munmap(pBootImage, fileSize);
close(fdIn);
}
4 changes: 2 additions & 2 deletions tools/hss-payload-generator/dump_payload.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand All @@ -32,6 +32,6 @@
#include <stddef.h>
#include <stdint.h>

void dump_payload(char const * filename);
void dump_payload(char const * filename, char const * public_key_filename);

#endif
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/elf_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/elf_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/elf_strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
2 changes: 1 addition & 1 deletion tools/hss-payload-generator/elf_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down
85 changes: 62 additions & 23 deletions tools/hss-payload-generator/generate_payload.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down Expand Up @@ -35,6 +35,7 @@
#include <libgen.h>
#include "crc32.h"
#include "debug_printf.h"
#include "verify_payload.h"

#include <openssl/ec.h>
#include <openssl/ecdsa.h>
Expand Down Expand Up @@ -118,7 +119,8 @@ static void generate_header(FILE *pFileOut, struct HSS_BootImage *pBootImage) __
static void generate_chunks(FILE *pFileOut) __attribute__((nonnull));
static void generate_ziChunks(FILE *pFileOut) __attribute__((nonnull));
static void generate_blobs(FILE *pFileOut) __attribute__((nonnull));
static void sign_payload(FILE *pFileOut, char const * const private_key_filename) __attribute__((nonnull(1)));
static void sign_payload(FILE *pFileOut, char const * const private_key_filename,
char const * const public_key_filename) __attribute__((nonnull(1)));

extern struct HSS_BootImage bootImage;

Expand Down Expand Up @@ -210,7 +212,7 @@ static void generate_chunks(FILE *pFileOut)
cumulativeBlobSize += chunkTable[i].chunk.size
+ calculate_padding(chunkTable[i].chunk.size, PAD_SIZE);

off_t posn = ftello(pFileOut);
off_t posn = ftello(pFileOut);
debug_printf(4, "\t- Processing chunk %lu (%lu bytes) at file position %lu "
"(blob is expected at %lu)\n",
i, chunkTable[i].chunk.size, posn, chunkTable[i].chunk.loadAddr);
Expand Down Expand Up @@ -259,7 +261,7 @@ static void generate_ziChunks(FILE *pFileOut)
+ calculate_padding(sizeof(struct HSS_BootChunkDesc) * (numChunks+1), PAD_SIZE));

for (size_t i = 0u; i < numZIChunks; i++) {
off_t posn = ftello(pFileOut);
off_t posn = ftello(pFileOut);
debug_printf(4, "\t- Processing ziChunk %lu (%lu bytes) at file position %lu\n",
i, ziChunkTable[i].ziChunk.size, posn);

Expand Down Expand Up @@ -302,7 +304,7 @@ static void generate_blobs(FILE *pFileOut)
+ calculate_padding(sizeof(struct HSS_BootZIChunkDesc) * (numZIChunks +1), PAD_SIZE));

for (size_t i = 0u; i < numChunks; i++) {
off_t posn = ftello(pFileOut);
off_t posn = ftello(pFileOut);
debug_printf(4, "\t- Processing blob %lu (%lu bytes) at file position %lu\n",
i, chunkTable[i].chunk.size, posn);
debug_printf(4, "\t\tCRC32: %x\n",
Expand All @@ -323,7 +325,8 @@ static void generate_blobs(FILE *pFileOut)
assert(pFileOut);
}

static void sign_payload(FILE *pFileOut, char const * const private_key_filename)
static void sign_payload(FILE *pFileOut, char const * const private_key_filename,
char const * const public_key_filename)
{
if (private_key_filename) {
//
Expand Down Expand Up @@ -352,22 +355,29 @@ static void sign_payload(FILE *pFileOut, char const * const private_key_filename

EVP_PKEY *pPrivKey = PEM_read_PrivateKey(privKeyFileIn, NULL, NULL, NULL);
assert(pPrivKey != NULL);
fclose(privKeyFileIn);
fclose(privKeyFileIn);

// create the signature by using SHA384 digest and signing with our SECP384r1 private key
//
EVP_MD_CTX *pCtx = EVP_MD_CTX_new();
assert(pCtx != NULL);

assert(EVP_DigestInit_ex(pCtx, EVP_sha384(), NULL) == 1);

uint8_t digest[EVP_MAX_MD_SIZE];
unsigned int digest_len = 0;
assert(EVP_DigestUpdate(pCtx, pEntirePayloadBuffer, bootImage.bootImageLength) == 1);
assert(EVP_DigestFinal_ex(pCtx, digest, &digest_len) == 1);

assert(EVP_DigestSignInit(pCtx, NULL, EVP_sha384(), NULL, pPrivKey) == 1);

size_t sigLen = 0u;
assert(EVP_DigestSign(pCtx, NULL, &sigLen, pEntirePayloadBuffer, bootImage.bootImageLength) == 1);

unsigned char *pSignatureBuffer = OPENSSL_malloc(sigLen);
assert(pSignatureBuffer);
assert(EVP_DigestSign(pCtx, pSignatureBuffer, &sigLen, pEntirePayloadBuffer, bootImage.bootImageLength) == 1);

free(pEntirePayloadBuffer);

// copy the signature to the boot image header...
// OpenSSL will output the signature is in ASN.1 format, as described in
// https://datatracker.ietf.org/doc/html/rfc5480
Expand Down Expand Up @@ -403,24 +413,26 @@ static void sign_payload(FILE *pFileOut, char const * const private_key_filename
ECDSA_SIG *pSig = d2i_ECDSA_SIG(NULL, &sig_ptr, (long)sigLen);
assert(pSig != NULL);

// the signature is in an opaque ECDSA_SIG structure, which contains two
// BIGNUMs, r and s. These are max half the curve size in bytes
// => 384 / (8*2) = 48 bytes each... but they may be less, and need to be
// zero padded, so extract separately...
const BIGNUM *pR = NULL;
const BIGNUM *pS = NULL;
ECDSA_SIG_get0(pSig, &pR, &pS);
// the signature is in an opaque ECDSA_SIG structure, which contains two
// BIGNUMs, r and s. These are max half the curve size in bytes
// => 384 / (8*2) = 48 bytes each... but they may be less, and need to be
// zero padded, so extract separately...
const BIGNUM *pR = NULL;
const BIGNUM *pS = NULL;
ECDSA_SIG_get0(pSig, &pR, &pS);

const int rBytes = BN_num_bytes(pR);
const int sBytes = BN_num_bytes(pS);
const int rBytes = BN_num_bytes(pR);
const int sBytes = BN_num_bytes(pS);

assert(rBytes == sBytes);
assert(rBytes == 48);

memset(pSignatureBuffer, 0, 96);
BN_bn2bin(pR, pSignatureBuffer + 48 - rBytes);
BN_bn2bin(pS, pSignatureBuffer + 96 - sBytes);
memset(pSignatureBuffer, 0, 96);
BN_bn2bin(pR, pSignatureBuffer + 48 - rBytes);
BN_bn2bin(pS, pSignatureBuffer + 96 - sBytes);
//

memcpy(bootImage.signature.digest, digest, 48u);
memcpy(bootImage.signature.ecdsaSig, pSignatureBuffer, 48u);
memcpy(bootImage.signature.ecdsaSig + 48u, pSignatureBuffer + 48u, 48u);

Expand All @@ -435,13 +447,40 @@ static void sign_payload(FILE *pFileOut, char const * const private_key_filename
EVP_MD_CTX_free(pCtx);
EVP_PKEY_free(pPrivKey);
OPENSSL_free(pSignatureBuffer);

// if a public key was provided, we'll cross-check the signature against it
//
if (public_key_filename) {
// refresh payload from file, as we just rewrote the header to include the signature
if (fseek(pFileOut, 0, SEEK_SET) != 0) {
perror("fseek()");
exit(EXIT_SUCCESS);
}

fileSize = fread((void *)pEntirePayloadBuffer, 1u, bootImage.bootImageLength, pFileOut);
assert(fileSize == bootImage.bootImageLength);

// now perform the cross-check
bool result = HSS_Boot_Secure_CheckCodeSigning((struct HSS_BootImage *)pEntirePayloadBuffer, public_key_filename);

printf("Signature validation using public key ... %s\n\n", result ? "passed":"failed");

}

free(pEntirePayloadBuffer);
}
}

void generate_payload(char const * const filename_output, char const * const private_key_filename)
void generate_payload(char const * const filename_output, char const * const private_key_filename, char const * const public_key_filename)
{
assert(filename_output);
printf("Output filename is >>%s<<\n", filename_output);
if (private_key_filename) {
printf("private_key_filename is >>%s<<\n", private_key_filename);
}
if (public_key_filename) {
printf("public_key_filename is >>%s<<\n", public_key_filename);
}

FILE *pFileOut = fopen(filename_output, "w+");
if (!pFileOut) {
Expand All @@ -466,7 +505,7 @@ void generate_payload(char const * const filename_output, char const * const pri

generate_header(pFileOut, &bootImage); // rewrite header for CRC...

sign_payload(pFileOut, private_key_filename);
sign_payload(pFileOut, private_key_filename, public_key_filename);

if (fclose(pFileOut) != 0) {
perror("fclose()");
Expand Down
4 changes: 2 additions & 2 deletions tools/hss-payload-generator/generate_payload.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* MPFS HSS Embedded Software - tools/hss-payload-generator
*
* Copyright 2020-2022 Microchip FPGA Embedded Systems Solutions.
* Copyright 2020-2024 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
Expand Down Expand Up @@ -34,7 +34,7 @@

#include "hss_types.h"

void generate_payload(char const * const filename_output, char const * const private_key_filename);
void generate_payload(char const * const filename_output, char const * const private_key_filename, char const * const public_key_filename);
void generate_init(void);

size_t generate_add_chunk(struct HSS_BootChunkDesc chunk, void *buffer) __attribute__((nonnull));
Expand Down
Loading

0 comments on commit f91740f

Please sign in to comment.