diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/adapt_layer.h imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/adapt_layer.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/adapt_layer.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/adapt_layer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,318 +0,0 @@ -#ifndef ADAPT_LAYER_H -#define ADAPT_LAYER_H -/*===========================================================================*/ -/** - @file adapt_layer.h - - @brief CST adaptation layer interface - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011-2015 All rights reserved. - Copyright 2018-2019 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ -#include - -/*=========================================================================== - CONSTANTS -=============================================================================*/ - -/*=========================================================================== - MACROS -=============================================================================*/ -#define UNUSED(expr) (void)(expr) - -#define CAL_SUCCESS ( 0) /* Operation completed successfully */ -#define CAL_FILE_NOT_FOUND (-1) /* Error when file does not exist */ -#define CAL_INVALID_SIG_DATA_SIZE (-2) /* Error when sig data size invalid */ -#define CAL_FAILED_FILE_CREATE (-3) /* Error unable to create file */ -#define CAL_MAC_LEN_INCORRECT (-4) /* Error MAC len is incorrect */ -#define CAL_INVALID_ARGUMENT (-5) /* Error argument passed is invalid */ -#define CAL_CRYPTO_API_ERROR (-6) /* Error with openssl API */ -#define CAL_INSUFFICIENT_BUFFER_LEN (-7) /* Buffer length is not sufficient */ -#define CAL_DATA_COMPARE_FAILED (-8) /* Data comparison operation failed */ -#define CAL_RAND_SEED_ERROR (-9) /* Failure to run rand_seed */ -#define CAL_RAND_API_ERROR (-10) /* Failure in RAND_bytes */ -#define CAL_NO_CRYPTO_API_ERROR (-11) /* Error when Encryption is disabled*/ -#define CAL_INVALID_SIGNATURE (-12) /* Error when verifying isignature */ -#define CAL_LAST_ERROR (-100) /* Max error codes for adapt layer */ - -#define FILE_BUF_SIZE (1024) /* 1K buf for file read/file write */ - -#define MAX_AES_KEY_LENGTH (32) /* Max bytes in AES key */ -#define AES_BLOCK_BYTES (16) /**< Max. AES block bytes */ -#define FLAG_BYTES (1) /**< Bytes in Flag */ -#define BYTE_SIZE_BITS (8) /**< Number of bits in a byte */ - -#define SIG_REQ_FILENAME "sig_req.txt" /**< Signing request filename */ - -/*=========================================================================== - ENUMS -=============================================================================*/ -typedef enum func_mode_e -{ - MODE_UNDEF = 0, /**< Undefined functional mode */ - MODE_NOMINAL, /**< Execution in normal mode */ - MODE_HSM, /**< Execution in HSM mode */ -} func_mode_t; - -typedef enum _SIG_FMT -{ - SIG_FMT_UNDEF = 0, /**< Undefined signature format */ - SIG_FMT_PKCS1, /**< RAW PKCS#1 signature format */ - SIG_FMT_CMS, /**< CMS (PKCS#7) signature format */ - SIG_FMT_ECDSA, /**< ECDSA signature format. R|S concatanated */ - SIG_FMT_AEAD, /**< Proprietary AEAD MAC format */ -} sig_fmt_t; - - -/** Hash Digetst Algorithm */ -typedef enum hash_alg -{ - SHA_1 = 0, /**< SHA-1 Digest Algorithm */ - SHA_256, /**< SHA-256 Digest Algorithm */ - SHA_384, /**< SHA-384 Digest Algorithm */ - SHA_512, /**< SHA-512 Digest Algorithm */ - INVALID_DIGEST /**< Invalid Digest Algorithm */ -} hash_alg_t; - -/** AES key lengths supported */ -typedef enum aes_key_bits -{ - AES_KEY_LEN_128 = 128, /**< 128 bits */ - AES_KEY_LEN_192 = 192, /**< 192 bits */ - AES_KEY_LEN_256 = 256, /**< 256 bits */ -} aes_key_bits_t; - -/** Encryption algorithms supported */ -typedef enum aead_alg -{ - AES_CCM = 0, /**< Default encryption algorithm supported */ - AES_CBC -} aead_alg_t; - -/*=========================================================================== - STRUCTURES AND OTHER TYPEDEFS -=============================================================================*/ - -typedef struct _AEAD { - uint8_t *uch; -} AEAD_t; - -/*=========================================================================== - GLOBAL VARIABLE DECLARATIONS -=============================================================================*/ - -/*=========================================================================== - FUNCTION PROTOTYPES -=============================================================================*/ -#ifdef __cplusplus -extern "C" { -#endif - -/** Converts given digest value to equivalent OpenSSL string - * - * @param[in] hash_alg one of #hash_alg_t - * - * @returns Openssl string corresponding the given hash algorithm in - * @a hash_alg, if @a hash_alg is not valid #HASH_ALG_INVALID - * is returned. - */ -char * -get_digest_name(hash_alg_t hash_alg); - -/** Generate Signature Data - * - * Generates a signature for the given data file, signer certificate, - * hash algorithm and signature format. The signature data is returned - * in a buffer provided by caller. - * - * @param[in] in_file path to file with binary data to sign - * - * @param[in] cert_file path to signer certificate file - * - * @param[in] hash_alg hash algorithm in #hash_alg_t - * - * @param[in] sig_fmt signature format in #sig_fmt_t - * - * @param[out] sig_buf buffer to return signature data - * - * @param[in,out] sig_buf_bytes input size of sig_buf allocated by caller - * output size of signature data returned by API - * - * @post Errors are printed to STDERR - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments - * - * @retval #CAL_INVALID_SIG_DATA_SIZE size insufficient to generate sig data - * - * @retval #CAL_INVALID_ARGUMENT one of the input arguments is invalid - */ -int32_t gen_sig_data(const char* in_file, - const char* cert_file, - hash_alg_t hash_alg, - sig_fmt_t sig_fmt, - uint8_t* sig_buf, - size_t *sig_buf_bytes, - func_mode_t mode); - -/** Generate authenticated encrypted data - * - * API generates authenticated encrypted data for given plain-text data file - * - * @param[in] in_file plaintext, extracted and concatenated as for signing - * - * @param[out] out_file ciphertext (file name is input) - * - * @param[in] aead_alg only AES_CCM supported for now. - * - * @param[out] aad additional authenticated data - * - * @param[in] aad_bytes size of aad (additional authenticated data) - * - * @param[out] nonce nonce bytes to return - * - * @param[in] nonce_bytes size of nonce - * - * @param[out] mac output MAC - * - * @param[in] mac_bytes size of MAC - * - * @param[in] key_bytes size of symmetric key - * - * @param[in] cert_file certificate for DEK (data enctyption key) encryption - * - * @param[out] key_file encrypted symmetric key (file name is input) - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments - * - * @retval #CAL_FAILED_FILE_CREATE the output file cannot be created - * - * @retval #CAL_MAC_LEN_INCORRECT the mac_bytes is not correct - */ -int32_t gen_auth_encrypted_data(const char* in_file, - const char* out_file, - aead_alg_t aead_alg, - uint8_t *aad, - size_t aad_bytes, - uint8_t *nonce, - size_t nonce_bytes, - uint8_t *mac, - size_t mac_bytes, - size_t key_bytes, - const char* cert_file, - const char* key_file, - int reuse_dek); - -/** Computes hash digest from a given input file - * - * This function differs from the generate_hash() function in - * openssl_helper.c in that this function will hash an arbitrary amount of - * data contained in @in_file. The generate_hash expects the data in a - * contigous memory array with the data length already known. - * - * @param[in] in_file Character string holding the input data filename. - * - * @param[in] hash_alg Hash digest algorithm from #hash_alg_t - * - * @param[in,out] buf on input, used to read input data when computing - * hash value, on output holds the resulting hash value. - * - * @param[in,out] pbuf_bytes on input, holds the size of @a buf ib bytes, - * on output pbuf_bytes is updated to hold the size of the - * resulting hash in bytes. - * - * @pre @a in_file, @a buf, and @a pbuf_bytes must not be NULL - * - * @post On success @a buf is updated to hold the hash digest result and - * @a pbuf_bytes is updated to hold the length of the hash in bytes - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_INVALID_ARGUMENTif @a hash_alg contains an unsupported - * algorithm - * - * @retval #CAL_CRYPTO_API_ERROR otherwise - */ -int32_t -calculate_hash(const char *in_file, - hash_alg_t hash_alg, - uint8_t *buf, - int32_t *pbuf_bytes); - -/** Verify Signature Data - * - * Verifies a signature for the given data file, signer certificate, - * hash algorithm and signature format. The signature data is given - * in a buffer provided by caller. - * - * @param[in] in_file path to file with binary data to sign - * - * @param[in] cert_file path to signer certificate file - * - * @param[in] hash_alg hash algorithm in #hash_alg_t - * - * @param[in] sig_fmt signature format in #sig_fmt_t - * - * @param[in] sig_buf buffer to give signature data - * - * @param[in] sig_buf_bytes input size of sig_buf allocated by caller - * - * @post Errors are printed to STDERR - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments - * - * @retval #CAL_INVALID_SIGNATURE invalid signature - * - * @retval #CAL_INVALID_ARGUMENT one of the input arguments is invalid - */ -int32_t -ver_sig_data(const char *in_file, - const char *cert_file, - hash_alg_t hash_alg, - sig_fmt_t sig_fmt, - uint8_t *sig_buf, - size_t sig_buf_bytes); - -#ifdef __cplusplus -} -#endif - -#endif /* ADAPT_LAYER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/openssl_helper.h imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/openssl_helper.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/openssl_helper.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/openssl_helper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,351 +0,0 @@ -#ifndef __OPENSSL_HELPER_H -#define __OPENSSL_HELPER_H -/*===========================================================================*/ -/** - @file openssl_helper.h - - @brief Provide helper functions to ease openssl tasks and also defines - common macros that can used across different tools - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011, 2012. All rights reserved. - Copyright 2018-2019 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ -#include "adapt_layer.h" -#include -#include -#include - -/*=========================================================================== - CONSTANTS -=============================================================================*/ - -#define TRUE 1 /**< Success val returned by functions */ -#define FALSE 0 /**< Failure val returned by functions */ - -#define X509_UTCTIME_STRING_BYTES 13 /**< Expected length of validity period - * strings in X.509 certificates using - * UTCTime format - */ -#define X509_GENTIME_STRING_BYTES 15 /**< Expected length of validity period - * strings in X.509 certificates using - * Generalized Time format - */ -#define PEM_FILE_EXTENSION ".pem" /* PEM file extention */ -#define PEM_FILE_EXTENSION_BYTES 4 /* Length of pem extention */ - -/* Message digest string definitions */ -#define HASH_ALG_SHA1 "sha1" /**< String macro for sha1 */ -#define HASH_ALG_SHA256 "sha256" /**< String macro for sha256 */ -#define HASH_ALG_SHA384 "sha384" /**< String macro for sha384 */ -#define HASH_ALG_SHA512 "sha512" /**< String macro for sha512 */ -#define HASH_ALG_INVALID "null" /**< String macro for invalid hash */ - -/* Message digest length definitions */ -#define HASH_BYTES_SHA1 20 /**< Size of SHA1 output bytes */ -#define HASH_BYTES_SHA256 32 /**< Size of SHA256 output bytes */ -#define HASH_BYTES_SHA384 48 /**< Size of SHA384 output bytes */ -#define HASH_BYTES_SHA512 64 /**< Size of SHA512 output bytes */ -#define HASH_BYTES_MAX HASH_BYTES_SHA512 - -/* X509 certificate definitions */ -#define X509_USR_CERT 0x0 /**< User certificate */ -#define X509_CA_CERT 0x1 /**< CA certificate */ - -/*=========================================================================== - CONSTANTS -=============================================================================*/ - -/** Extracts a byte from a given 32 bit word value - * - * @param [in] val value to extract byte from - * - * @param [in] bit_shift Number of bits to shift @a val left before - * extracting the least significant byte - * - * @returns the least significant byte after shifting @a val to the left - * by @a bit_shift bits - */ -#define EXTRACT_BYTE(val, bit_shift) \ - (((val) >> (bit_shift)) & 0xFF) - -/*============================================================================ - ENUMS -=============================================================================*/ - -typedef enum cst_status -{ - CST_FAILURE = FALSE, - CST_SUCCESS = TRUE -} cst_status_t; - -/*============================================================================ - STRUCTURES AND OTHER TYPEDEFS -=============================================================================*/ - -/*============================================================================ - GLOBAL VARIABLE DECLARATIONS -=============================================================================*/ - -/*=========================================================================== - OPENSSL 1.0.2 SUPPORT -=============================================================================*/ - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - -#define OPENSSL_malloc_init CRYPTO_malloc_init -#define X509_get0_notBefore X509_get_notBefore -#define X509_get0_notAfter X509_get_notAfter - -void -ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); - -int -ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); - -void -EVP_MD_CTX_free(EVP_MD_CTX *ctx); - -EVP_MD_CTX * -EVP_MD_CTX_new(void); - -EC_KEY * -EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); - -RSA * -EVP_PKEY_get0_RSA(EVP_PKEY *pkey); - -void -RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); - -#endif - -/*============================================================================ - FUNCTION PROTOTYPES -=============================================================================*/ - -/** openssl_initialize - * - * Initializes the openssl library. This function must be called once - * by the program using any of the openssl helper functions - * - */ -extern void -openssl_initialize(); - -/** Computes hash digest - * - * Calls openssl API to generate hash for the given data in buf. - * - * @param[in] buf, binary data for hashing - * - * @param[in] msg_bytes, size in bytes for binary data - * - * @param[in] hash_alg, character string containing hash algorithm, - * "sha1" or "sha256" - * - * @param[out] hash_bytes, size of digest result in bytes - * - * @pre #openssl_initialize has been called previously - * - * @pre @a buf and @a hash_alg are not NULL. - * - * @post It is the responsibilty of the caller to free the memory allocated by - * this function holding the computed hash result. - * - * @returns The location of the digest result if successful, NULL otherwise - */ -extern uint8_t * -generate_hash(const uint8_t *buf, size_t msg_bytes, const char *hash_alg, - size_t *hash_bytes); - -/** get_bn - * - * Extracts data from an openssl BIGNUM type to a byte array. Used - * for extracting certificate data such as an RSA public key modulus. - * - * @param[in] a BIG_NUM structure - * - * @param[out] bytes size of resulting byte array - * - * @pre @a a and @a bytes are not NULL - * - * @post It is the responsibilty of the caller to free the memory allocated by - * this function holding the big number result. - * - * @returns location of resulting byte array or NULL if failed to alloc mem. - */ -extern uint8_t* -get_bn(const BIGNUM *a, size_t *bytes); - - -/** sign_data - * - * Signs a data buffer with a given private key - * - * @param[in] skey signer private key - * - * @param[in] bptr location of data buffer to digitally sign - * - * @param[in] hash_alg hash digest algorithm - * - * @param[out] sig_bytes size of resulting signature buffer - * - * @pre #openssl_initialize has been called previously - * - * @post It is the responsibilty of the caller to free the memory allocated by - * this function holding the signature result. - * - * @returns if successful returns location of resulting byte array otherwise - * NULL. - */ -extern uint8_t* -sign_data(const EVP_PKEY *skey, const BUF_MEM *bptr, hash_alg_t hash_alg, - size_t *sig_bytes); - -/** read_certificate - * - * Read X.509 certificate data from given certificate file - * - * @param[in] filename filename of certificate file - * - * @post if successful the contents of the certificate are extracted to X509 - * object. - * - * @pre #openssl_initialize has been called previously - * - * @post caller is responsible for releasing X.509 certificate memory. - * - * @returns if successful function returns location of X509 object - * otherwise NULL. - */ -extern X509* -read_certificate(const char* filename); - -/** get_der_encoded_certificate_data - * - * Read X.509 certificate data from given certificate file and calls openssl - * to encode X509 to DER format and returns DER formatted data located at - * @derder. - * - * @param[in] filename filename, function will work with both PEM and DER - * input certificate files. - * - * @param[out] der address to write der data - * - * @post if successful the contents of the certificate are written at address - * @a der. - * - * @pre #openssl_initialize has been called previously - * - * @post caller is responsible for releasing memory location returned in @a der - * - * @returns if successful function returns number of bytes written at address - * @a der, 0 otherwise. - */ -extern int32_t get_der_encoded_certificate_data(const char* filename, - uint8_t ** der); - -/** read_private_key - * - * Uses openssl API to read private key from given certificate file - * - * @param[in] filename filename of key file - * - * @param[in] password_cb callback fn to provide password for keyfile - * see openssl's pem.h for callback'e prototype - * - * @param[in] password password for keyfile - * - * @post if successful the contents of the private key are extracted to - * EVP_PKEY object. - * - * @pre #openssl_initialize has been called previously - * - * @post caller is responsible for releasing the private key memory. - * - * @returns if successful function returns location of EVP_PKEY object - * otherwise NULL. - */ -extern EVP_PKEY* -read_private_key(const char *filename, pem_password_cb *password_cb, - const char *password); - -/** seed_prng - * - * Calls openssl API to seed prng to given bytes randomness - * - * @param[in] bytes bytes to randomize the seed - * - * @pre None - * - * @post None - */ -uint32_t seed_prng(uint32_t bytes); - -/** gen_random_bytes - * - * Generates random bytes using openssl RAND_bytes - * - * @param[out] buf buf to return the random bytes - * - * @param[in] bytes size of the buf in bytes and number of random bytes - * to generate - * - * @pre None - * - * @post None - */ -int32_t gen_random_bytes(uint8_t *buf, size_t bytes); - -/** Diplays program license information to stdout - * - * @pre None - * - * @post None - */ -extern void -print_license(void); - -/** Diplays program version information to stdout - * - * @pre None - * - * @post None - */ -extern void -print_version(void); - -#endif /* __OPENSSL_HELPER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/pkey.h imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/pkey.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/pkey.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/pkey.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -#ifndef PKEY_H -#define PKEY_H -/*===========================================================================*/ -/** - @file pkey.h - - @brief CST private key and password provider API - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011,2012. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ - -/*=========================================================================== - CONSTANTS -=============================================================================*/ - -/*=========================================================================== - MACROS -=============================================================================*/ - -/*=========================================================================== - ENUMS -=============================================================================*/ - -/*=========================================================================== - STRUCTURES AND OTHER TYPEDEFS -=============================================================================*/ - -/*=========================================================================== - GLOBAL VARIABLE DECLARATIONS -=============================================================================*/ - -/*=========================================================================== - FUNCTION PROTOTYPES -=============================================================================*/ -#ifdef __cplusplus -extern "C" { -#endif - -/** get_passcode_to_key_file - * - * @par Purpose - * - * Callback to gte password for the encrypted key file. Default behavior - * can be overridden by customers by linking with their own implementation - * of libpw.a and this function - * - * @par Operation - * - * @param[out] buf, return buffer for the password - * - * @param[in] size, size of the buf in bytes - * - * @param[in] rwflag, not used - * - * @param[in] userdata, filename for a public key used in the CSF - * - * @retval returns size of password string - */ -int get_passcode_to_key_file(char *buf, int size, int rwflag, void *userdata); - -/** get_key_file - * - * @par Purpose - * - * This API extracts private key filename using cert filename. This API is - * moved to libpw to allow customers to change its implementation to better - * suit their needs. - * - * @par Operation - * - * @param[in] cert_file, filename for certificate - * - * @param[out] key_file, filename for private key for the input certificate - * - * @retval SUCCESS - */ -int32_t get_key_file(const char* cert_file, char* key_file); - -#ifdef __cplusplus -} -#endif - -#endif /* PKEY_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/ssl_wrapper.h imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/ssl_wrapper.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/ssl_wrapper.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/ssl_wrapper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -#ifndef SSL_WRAPPER_H -#define SSL_WRAPPER_H -/*=========================================================================== - - @file ssl_wrapper.h - -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018-2019 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -===========================================================================*/ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ -#ifndef REMOVE_ENCRYPTION -#include -#endif -#include - -/*=========================================================================== - MACROS -=============================================================================*/ -#define MAX_ERR_STR_BYTES (120) /**< Max. error string bytes */ - -/*=========================================================================== - FUNCTION PROTOTYPES -=============================================================================*/ -#ifdef __cplusplus -extern "C" { -#endif - -void handle_errors(char * str, int32_t *err_value, char *err_str); - -int32_t encryptccm(unsigned char *plaintext, int plaintext_len, unsigned char *aad, - int aad_len, unsigned char *key, int key_len, unsigned char *iv, - int iv_len, const char * out_file, unsigned char *tag, int tag_len, - int32_t *err_value, char *err_str); - -int32_t encryptcbc(unsigned char *plaintext, int plaintext_len, unsigned char *key, - int key_len, unsigned char *iv, const char *out_file, int32_t *err_value, char *err_str); - -#ifdef __cplusplus -} -#endif - -#endif /* SSL_WRAPPER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/version.h imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/version.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/hdr/version.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/hdr/version.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -#ifndef __VERSION_H -#define __VERSION_H -/*===========================================================================*/ -/** - @file version.h - - @brief Version of the tool to manually set at each release. - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -#define CST_VERSION "3.2.0" - -#endif /* __VERSION_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/adapt_layer_openssl.c imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/adapt_layer_openssl.c --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/adapt_layer_openssl.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/adapt_layer_openssl.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1104 +0,0 @@ -/*===========================================================================*/ -/** - @file adapt_layer_openssl.c - - @brief Implements Code Signing Tool's Adaptation Layer API for the - Freescale reference Code Signing Tool. This file may be - replaced in implementations using a Hardware Security Module - or a client/server based infrastructure. - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ -#include -#include -#include -#include -#include "ssl_wrapper.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "adapt_layer.h" -#include "openssl_helper.h" -#include "pkey.h" -#if (defined _WIN32 || defined __CYGWIN__) && defined USE_APPLINK -#include -#endif -/*=========================================================================== - LOCAL MACROS -=============================================================================*/ -#define MAX_CMS_DATA 4096 /**< Max bytes in CMS_ContentInfo */ -#define MAX_LINE_CHARS 1024 /**< Max. chars in output line */ - -/*=========================================================================== - LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) -=============================================================================*/ - -/*=========================================================================== - LOCAL FUNCTION PROTOTYPES -=============================================================================*/ - -/** Converts hash_alg to an equivalent NID value for OpenSSL - * - * @param[in] hash_alg Hash digest algorithm from #hash_alg_t - * - * @pre hash_alg is a valid value from #hash_alg_t - * - * @returns Openssl NID value corresponding to a valid value for @a hash_alg, - * NID_undef otherwise. - */ -static int32_t -get_NID(hash_alg_t hash_alg); - -/** Generate raw PKCS#1 Signature Data - * - * Generates a raw PKCS#1 v1.5 signature for the given data file, signer - * certificate, and hash algorithm. The signature data is returned in - * a buffer provided by caller. - * - * @param[in] in_file string containing path to file with data to sign - * - * @param[in] key_file string containing path to signing key - * - * @param[in] hash_alg hash algorithm from #hash_alg_t - * - * @param[out] sig_buf signature data buffer - * - * @param[in,out] sig_buf_bytes On input, contains size of @a sig_buf in bytes, - * On output, contains size of signature in bytes. - * - * @pre @a in_file, @a cert_file, @a key_file, @a sig_buf and @a sig_buf_bytes - * must not be NULL. - * - * @post On success @a sig_buf is updated to hold the resulting signature and - * @a sig_buf_bytes is updates to hold the length of the signature in - * bytes - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_CRYPTO_API_ERROR An Openssl related error has occured - */ -static int32_t -gen_sig_data_raw(const char *in_file, - const char *key_file, - hash_alg_t hash_alg, - uint8_t *sig_buf, - int32_t *sig_buf_bytes); - -/** Generate CMS Signature Data - * - * Generates a CMS signature for the given data file, signer certificate, and - * hash algorithm. The signature data is returned in a buffer provided by - * caller. Note that sign_data cannot be used here since that function - * requires an input buffer as an argument. For large files it becomes - * unreasonable to allocate a contigous block of memory. - * - * @param[in] in_file string containing path to file with data to sign - * - * @param[in] cert_file string constaining path to signer certificate - * - * @param[in] hash_alg hash algorithm from #hash_alg_t - * - * @param[out] sig_buf signature data buffer - * - * @param[in,out] sig_buf_bytes On input, contains size of @a sig_buf in bytes, - * On output, contains size of signature in bytes. - * - * @pre @a in_file, @a cert_file, @a key_file, @a sig_buf and @a sig_buf_bytes - * must not be NULL. - * - * @post On success @a sig_buf is updated to hold the resulting signature and - * @a sig_buf_bytes is updates to hold the length of the signature in - * bytes - * - * @retval #CAL_SUCCESS API completed its task successfully - * - * @retval #CAL_INVALID_ARGUMENT One of the input arguments is invalid - * - * @retval #CAL_CRYPTO_API_ERROR An Openssl related error has occured - */ -static int32_t -gen_sig_data_cms(const char *in_file, - const char *cert_file, - const char *key_file, - hash_alg_t hash_alg, - uint8_t *sig_buf, - size_t *sig_buf_bytes); - -/** Copies CMS Content Info with encrypted or signature data to buffer - * - * @param[in] cms CMS Content Info - * - * @param[in] bio_in input bio - * - * @param[out] data_buffer address to data buffer - * - * @param[in] data_buffer_size max size, [out] return size - * - * @param[in] flags CMS Flags - * - * @returns CAL_SUCCESS upon success - * - * @returns CAL_CRYPTO_API_ERROR when openssl BIO API fail - */ -int32_t cms_to_buf(CMS_ContentInfo *cms, BIO * bio_in, uint8_t * data_buffer, - size_t * data_buffer_size, int32_t flags); - -/** generate_dek_key - * - * Uses openssl API to generate a random 128 bit AES key - * - * @param[out] key buffer to store the key data - * - * @param[in] len length of the key to generate - * - * @post if successful the random bytes are placed into output buffer - * - * @pre #openssl_initialize has been called previously - * - * @returns if successful function returns location CAL_SUCCESS. - */ -int32_t generate_dek_key(uint8_t * key, int32_t len); - -/** write_plaintext_dek_key - * - * Writes the provide DEK to the give path. It will be encrypted - * under the certificate file if provided. - * - * @param[in] key input key data - * - * @param[in] key_bytes length of the input key - * - * @param[in] cert_file certificate to encrypt the DEK - * - * @param[in] enc_file destination file - * - * @post if successful the dek is written to the file - * - * @returns if successful function returns location CAL_SUCCESS. - */ -int32_t write_plaintext_dek_key(uint8_t * key, size_t key_bytes, - const char * cert_file, const char * enc_file); - -/** encrypt_dek_key - * - * Uses openssl API to encrypt the key. Saves the encrypted structure to a file - * - * @param[in] key input key data - * - * @param[in] key_bytes length of the input key - * - * @param[in] cert filename of the RSA certificate, dek will be encrypted with - * - * @param[in] file encrypted data saved in the file - * - * @post if successful the file is created with the encrypted data - * - * @pre #openssl_initialize has been called previously - * - * @returns if successful function returns location CAL_SUCCESS. - */ -int32_t encrypt_dek_key(uint8_t * key, size_t key_bytes, - const char * cert_file, const char * enc_file); - -/** Display error message - * - * Displays error message to STDERR - * - * @param[in] err Error string to display - * - * @pre @a err is not NULL - * - * @post None - */ -static void -display_error(const char *err); - -/*=========================================================================== - GLOBAL VARIABLES -=============================================================================*/ - -/*=========================================================================== - LOCAL FUNCTIONS -=============================================================================*/ - -/*-------------------------- - get_NID ----------------------------*/ -int32_t -get_NID(hash_alg_t hash_alg) -{ - return OBJ_txt2nid(get_digest_name(hash_alg)); -} - -/*-------------------------- - gen_sig_data_raw ----------------------------*/ -int32_t -gen_sig_data_raw(const char *in_file, - const char *key_file, - hash_alg_t hash_alg, - uint8_t *sig_buf, - int32_t *sig_buf_bytes) -{ - EVP_PKEY *key = NULL; /**< Ptr to read key data */ - RSA *rsa = NULL; /**< Ptr to rsa of key data */ - uint8_t *rsa_in = NULL; /**< Mem ptr for hash data of in_file */ - uint8_t *rsa_out = NULL; /**< Mem ptr for encrypted data */ - int32_t rsa_inbytes; /**< Holds the length of rsa_in buf */ - int32_t rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ - int32_t key_bytes; /**< Size of key data */ - int32_t hash_nid; /**< hash id needed for RSA_sign() */ - /** Array to hold error string */ - char err_str[MAX_ERR_STR_BYTES]; - /**< Holds the return error value */ - int32_t err_value = CAL_CRYPTO_API_ERROR; - - do - { - /* Read key */ - key = read_private_key(key_file, - (pem_password_cb *)get_passcode_to_key_file, - key_file); - if (!key) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot open key file %s", key_file); - display_error(err_str); - break; - } - - rsa = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - - if (!rsa) { - display_error("Unable to extract RSA key for RAW PKCS#1 signature"); - break; - } - - rsa_inbytes = HASH_BYTES_MAX; - rsa_in = OPENSSL_malloc(HASH_BYTES_MAX); - key_bytes = RSA_size(rsa); - rsa_out = OPENSSL_malloc(key_bytes); - - /* Generate hash data of data from in_file */ - err_value = calculate_hash(in_file, hash_alg, rsa_in, &rsa_inbytes); - if (err_value != CAL_SUCCESS) { - break; - } - - /* Compute signature. Note: RSA_sign() adds the appropriate DER - * encoded prefix internally. - */ - hash_nid = get_NID(hash_alg); - if (!RSA_sign(hash_nid, rsa_in, - rsa_inbytes, rsa_out, - (unsigned int *)&rsa_outbytes, rsa)) { - err_value = CAL_CRYPTO_API_ERROR; - display_error("Unable to generate signature"); - break; - } - else { - err_value = CAL_SUCCESS; - } - - /* Copy signature to sig_buf and update sig_buf_bytes */ - *sig_buf_bytes = rsa_outbytes; - memcpy(sig_buf, rsa_out, rsa_outbytes); - } while(0); - - if (err_value != CAL_SUCCESS) { - ERR_print_errors_fp(stderr); - } - - if (rsa) RSA_free(rsa); - if (rsa_in) OPENSSL_free(rsa_in); - if (rsa_out) OPENSSL_free(rsa_out); - return err_value; -} - -/*-------------------------- - cms_to_buf ----------------------------*/ -int32_t cms_to_buf(CMS_ContentInfo *cms, BIO * bio_in, uint8_t * data_buffer, - size_t * data_buffer_size, int32_t flags) -{ - int32_t err_value = CAL_SUCCESS; - BIO * bio_out = NULL; - BUF_MEM buffer_memory; /**< Used with BIO functions */ - - buffer_memory.length = 0; - buffer_memory.data = (char*)data_buffer; - buffer_memory.max = *data_buffer_size; - - do { - if (!(bio_out = BIO_new(BIO_s_mem()))) { - display_error("Unable to allocate CMS signature result memory"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - BIO_set_mem_buf(bio_out, &buffer_memory, BIO_NOCLOSE); - - /* Convert cms to der format */ - if (!i2d_CMS_bio_stream(bio_out, cms, bio_in, flags)) { - display_error("Unable to convert CMS signature to DER format"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Get the size of bio out in data_buffer_size */ - *data_buffer_size = BIO_ctrl_pending(bio_out); - }while(0); - - if (bio_out) - BIO_free(bio_out); - return err_value; -} - -/*-------------------------- - gen_sig_data_cms ----------------------------*/ -int32_t -gen_sig_data_cms(const char *in_file, - const char *cert_file, - const char *key_file, - hash_alg_t hash_alg, - uint8_t *sig_buf, - size_t *sig_buf_bytes) -{ - BIO *bio_in = NULL; /**< BIO for in_file data */ - X509 *cert = NULL; /**< Ptr to X509 certificate read data */ - EVP_PKEY *key = NULL; /**< Ptr to key read data */ - CMS_ContentInfo *cms = NULL; /**< Ptr used with openssl API */ - const EVP_MD *sign_md = NULL; /**< Ptr to digest name */ - int32_t err_value = CAL_SUCCESS; /**< Used for return value */ - /** Array to hold error string */ - char err_str[MAX_ERR_STR_BYTES]; - /* flags set to match Openssl command line options for generating - * signatures - */ - int32_t flags = CMS_DETACHED | CMS_NOCERTS | - CMS_NOSMIMECAP | CMS_BINARY; - - /* Set signature message digest alg */ - sign_md = EVP_get_digestbyname(get_digest_name(hash_alg)); - if (sign_md == NULL) { - display_error("Invalid hash digest algorithm"); - return CAL_INVALID_ARGUMENT; - } - - do - { - cert = read_certificate(cert_file); - if (!cert) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot open certificate file %s", cert_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Read key */ - key = read_private_key(key_file, - (pem_password_cb *)get_passcode_to_key_file, - key_file); - if (!key) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot open key file %s", key_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Read Data to be signed */ - if (!(bio_in = BIO_new_file(in_file, "rb"))) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot open data file %s", in_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Generate CMS Signature - can only use CMS_sign if default - * MD is used which is SHA1 */ - flags |= CMS_PARTIAL; - - cms = CMS_sign(NULL, NULL, NULL, bio_in, flags); - if (!cms) { - display_error("Failed to initialize CMS signature"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - if (!CMS_add1_signer(cms, cert, key, sign_md, flags)) { - display_error("Failed to generate CMS signature"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Finalize the signature */ - if (!CMS_final(cms, bio_in, NULL, flags)) { - display_error("Failed to finalize CMS signature"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Write CMS signature to output buffer - DER format */ - err_value = cms_to_buf(cms, bio_in, sig_buf, sig_buf_bytes, flags); - } while(0); - - /* Print any Openssl errors */ - if (err_value != CAL_SUCCESS) { - ERR_print_errors_fp(stderr); - } - - /* Close everything down */ - if (cms) CMS_ContentInfo_free(cms); - if (cert) X509_free(cert); - if (key) EVP_PKEY_free(key); - if (bio_in) BIO_free(bio_in); - - return err_value; -} - -/*-------------------------- - gen_sig_data_ecdsa ----------------------------*/ -int32_t -gen_sig_data_ecdsa(const char *in_file, - const char *key_file, - hash_alg_t hash_alg, - uint8_t *sig_buf, - size_t *sig_buf_bytes) -{ - BIO *bio_in = NULL; /**< BIO for in_file data */ - EVP_PKEY *key = NULL; /**< Private key data */ - uint32_t key_size = 0; /**< n of bytes of key param */ - const EVP_MD *sign_md = NULL; /**< Digest name */ - uint8_t *hash = NULL; /**< Hash data of in_file */ - int32_t hash_bytes = 0; /**< Length of hash buffer */ - uint8_t *sign = NULL; /**< Signature data in DER */ - uint32_t sign_bytes = 0; /**< Length of DER signature */ - uint8_t *r = NULL, *s = NULL; /**< Raw signature data R&S */ - size_t bn_bytes = 0; /**< Length of R,S big num */ - ECDSA_SIG *sign_dec = NULL; /**< Raw signature data R|S */ - int32_t err_value = CAL_SUCCESS; /**< Return value */ - char err_str[MAX_ERR_STR_BYTES]; /**< Error string */ - const BIGNUM *sig_r, *sig_s; /**< signature numbers defined as OpenSSL BIGNUM */ - - /* Set signature message digest alg */ - sign_md = EVP_get_digestbyname(get_digest_name(hash_alg)); - if (sign_md == NULL) { - display_error("Invalid hash digest algorithm"); - return CAL_INVALID_ARGUMENT; - } - - do - { - /* Read key */ - key = read_private_key(key_file, - (pem_password_cb *)get_passcode_to_key_file, - key_file); - if (!key) { - snprintf(err_str, MAX_ERR_STR_BYTES, - "Cannot open key file %s", key_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Read Data to be signed */ - if (!(bio_in = BIO_new_file(in_file, "rb"))) { - snprintf(err_str, MAX_ERR_STR_BYTES, - "Cannot open data file %s", in_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Generate hash of data from in_file */ - hash_bytes = HASH_BYTES_MAX; - hash = OPENSSL_malloc(HASH_BYTES_MAX); - - err_value = calculate_hash(in_file, hash_alg, hash, &hash_bytes); - if (err_value != CAL_SUCCESS) { - break; - } - - /* Generate ECDSA signature with DER encoding */ - sign_bytes = ECDSA_size(EVP_PKEY_get0_EC_KEY(key)); - sign = OPENSSL_malloc(sign_bytes); - - if (0 == ECDSA_sign(0 /* ignored */, hash, hash_bytes, sign, &sign_bytes, EVP_PKEY_get0_EC_KEY(key))) { - display_error("Failed to generate ECDSA signature"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - sign_dec = d2i_ECDSA_SIG(NULL, (const uint8_t **) &sign, sign_bytes); - if (NULL == sign_dec) { - display_error("Failed to decode ECDSA signature"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Copy R|S to sig_buf */ - memset(sig_buf, 0, *sig_buf_bytes); - - key_size = EVP_PKEY_bits(key) >> 3; - if (EVP_PKEY_bits(key) & 0x7) key_size += 1; /* Valid for P-521 */ - - if ((key_size * 2) > *sig_buf_bytes){ - display_error("Signature buffer too small"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - *sig_buf_bytes = key_size * 2; - - ECDSA_SIG_get0(sign_dec, &sig_r, &sig_s); - - r = get_bn(sig_r, &bn_bytes); - memcpy(sig_buf + (key_size - bn_bytes), - r, - bn_bytes); - free(r); - - s = get_bn(sig_s, &bn_bytes); - memcpy(sig_buf + key_size + (key_size - bn_bytes), - s, - bn_bytes); - free(s); - } while(0); - - /* Print any Openssl errors */ - if (err_value != CAL_SUCCESS) { - ERR_print_errors_fp(stderr); - } - - /* Close everything down */ - if (key) EVP_PKEY_free(key); - if (bio_in) BIO_free(bio_in); - - return err_value; -} - -/*-------------------------- - error ----------------------------*/ -void -display_error(const char *err) -{ - fprintf(stderr, "Error: %s\n", err); -} - -/*-------------------------- - export_signature_request ----------------------------*/ -int32_t export_signature_request(const char *in_file, - const char *cert_file) -{ - #define WRITE_LINE() \ - if (strlen(line) != fwrite(line, 1, strlen(line), sig_req)) { \ - snprintf(err_str, MAX_ERR_STR_BYTES, \ - "Unable to write to file %s", SIG_REQ_FILENAME); \ - display_error(err_str); \ - return CAL_CRYPTO_API_ERROR; \ - } - - char err_str[MAX_ERR_STR_BYTES]; /**< Used in preparing error message */ - FILE *sig_req = NULL; /**< Output signing request */ - char line[MAX_LINE_CHARS]; /**< Used in preparing output message */ - - sig_req = fopen(SIG_REQ_FILENAME, "a"); - if (NULL == sig_req) { - snprintf(err_str, MAX_ERR_STR_BYTES, - "Unable to create file %s", SIG_REQ_FILENAME); - display_error(err_str); - return CAL_CRYPTO_API_ERROR; - } - - snprintf(line, MAX_LINE_CHARS, - "[Signing request]\r\n"); - WRITE_LINE(); - snprintf(line, MAX_LINE_CHARS, - "Signing certificate = %s\r\n", cert_file); - WRITE_LINE(); - snprintf(line, MAX_LINE_CHARS, - "Data to be signed = %s\r\n\r\n", in_file); - WRITE_LINE(); - - fclose(sig_req); - - return CAL_SUCCESS; -} - -/*=========================================================================== - GLOBAL FUNCTIONS -=============================================================================*/ - -/*-------------------------- - gen_sig_data ----------------------------*/ -int32_t gen_sig_data(const char* in_file, - const char* cert_file, - hash_alg_t hash_alg, - sig_fmt_t sig_fmt, - uint8_t* sig_buf, - size_t *sig_buf_bytes, - func_mode_t mode) -{ - int32_t err = CAL_SUCCESS; /**< Used for return value */ - char *key_file; /**< Mem ptr for key filename */ - - /* Check for valid arguments */ - if ((!in_file) || (!cert_file) || (!sig_buf) || (!sig_buf_bytes)) { - return CAL_INVALID_ARGUMENT; - } - - if (MODE_HSM == mode) - { - return export_signature_request(in_file, cert_file); - } - - /* Determine private key filename from given certificate filename */ - key_file = malloc(strlen(cert_file)+1); - - err = get_key_file(cert_file, key_file); - if ( err != CAL_SUCCESS) { - free(key_file); - return CAL_FILE_NOT_FOUND; - } - - if (SIG_FMT_PKCS1 == sig_fmt) { - err = gen_sig_data_raw(in_file, key_file, - hash_alg, sig_buf, (int32_t *)sig_buf_bytes); - } - else if (SIG_FMT_CMS == sig_fmt) { - err = gen_sig_data_cms(in_file, cert_file, key_file, - hash_alg, sig_buf, sig_buf_bytes); - } - else if (SIG_FMT_ECDSA == sig_fmt) { - err = gen_sig_data_ecdsa(in_file, key_file, - hash_alg, sig_buf, sig_buf_bytes); - } - else { - free(key_file); - display_error("Invalid signature format"); - return CAL_INVALID_ARGUMENT; - } - - free(key_file); - return err; -} - -/*-------------------------- - generate_dek_key ----------------------------*/ -int32_t generate_dek_key(uint8_t * key, int32_t len) -{ - if (gen_random_bytes(key, len) != CAL_SUCCESS) { - return CAL_CRYPTO_API_ERROR; - } - - return CAL_SUCCESS; -} - -/*-------------------------- - write_plaintext_dek_key ----------------------------*/ -int32_t write_plaintext_dek_key(uint8_t * key, size_t key_bytes, - const char * cert_file, const char * enc_file) -{ - int32_t err_value = CAL_SUCCESS; /**< Return value */ - char err_str[MAX_ERR_STR_BYTES]; /**< Used in preparing error message */ - FILE *fh = NULL; /**< File handle used with file api */ -#ifdef DEBUG - int32_t i = 0; /**< Used in for loops */ -#endif - - UNUSED(cert_file); - - do { - /* Save the buffer into enc_file */ - if ((fh = fopen(enc_file, "wb")) == NULL) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Unable to create binary file %s", enc_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - if (fwrite(key, 1, key_bytes, fh) != - key_bytes) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Unable to write to binary file %s", enc_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - fclose (fh); - } while(0); - - return err_value; -} - - -/*-------------------------- - encrypt_dek_key ----------------------------*/ -int32_t encrypt_dek_key(uint8_t * key, size_t key_bytes, - const char * cert_file, const char * enc_file) -{ - X509 *cert = NULL; /**< Ptr to X509 certificate read data */ - STACK_OF(X509) *recips = NULL; /**< Ptr to X509 stack */ - CMS_ContentInfo *cms = NULL; /**< Ptr to cms structure */ - const EVP_CIPHER *cipher = NULL; /**< Ptr to EVP_CIPHER */ - int32_t err_value = CAL_SUCCESS; /**< Return value */ - char err_str[MAX_ERR_STR_BYTES]; /**< Used in preparing error message */ - BIO *bio_key = NULL; /**< Bio for the key data to encrypt */ - uint8_t * enc_buf = NULL; /**< Ptr for encoded key data */ - FILE *fh = NULL; /**< File handle used with file api */ - size_t cms_info_size = MAX_CMS_DATA; /**< Size of cms content info*/ -#ifdef DEBUG - int32_t i = 0; /**< Used in for loops */ -#endif - - do { - /* Read the certificate from cert_file */ - cert = read_certificate(cert_file); - if (!cert) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot open certificate file %s", cert_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Create recipient STACK and add recipient cert to it */ - recips = sk_X509_new_null(); - - if (!recips || !sk_X509_push(recips, cert)) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Cannot instantiate object STACK_OF(%s)", cert_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* - * sk_X509_pop_free will free up recipient STACK and its contents - * so set cert to NULL so it isn't freed up twice. - */ - cert = NULL; - - /* Instantiate correct cipher */ - if (key_bytes == (AES_KEY_LEN_128 / BYTE_SIZE_BITS)) - cipher = EVP_aes_128_cbc(); - else if (key_bytes == (AES_KEY_LEN_192 / BYTE_SIZE_BITS)) - cipher = EVP_aes_192_cbc(); - else if (key_bytes == (AES_KEY_LEN_256 / BYTE_SIZE_BITS)) - cipher = EVP_aes_256_cbc(); - if (cipher == NULL) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Invalid cipher used for encrypting key %s", enc_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Allocate memory buffer BIO for input key */ - bio_key = BIO_new_mem_buf(key, key_bytes); - if (!bio_key) { - display_error("Unable to allocate BIO memory"); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Encrypt content of the key with certificate */ - cms = CMS_encrypt(recips, bio_key, cipher, CMS_BINARY|CMS_STREAM); - if (cms == NULL) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Failed to encrypt key data"); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Finalize the CMS content info structure */ - if (!CMS_final(cms, bio_key, NULL, CMS_BINARY|CMS_STREAM)) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Failed to finalize cms data"); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Alloc mem to convert cms to binary and save it into enc_file */ - enc_buf = malloc(MAX_CMS_DATA); - if (enc_buf == NULL) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Failed to allocate memory"); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - - /* Copy cms info into enc_buf */ - err_value = cms_to_buf(cms, bio_key, enc_buf, &cms_info_size, - CMS_BINARY); - - /* Save the buffer into enc_file */ - if ((fh = fopen(enc_file, "wb")) == NULL) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Unable to create binary file %s", enc_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - if (fwrite(enc_buf, 1, cms_info_size, fh) != - cms_info_size) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, - "Unable to write to binary file %s", enc_file); - display_error(err_str); - err_value = CAL_CRYPTO_API_ERROR; - break; - } - fclose (fh); -#ifdef DEBUG - printf("Encoded key ;"); - for(i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "openssl_helper.h" -#include "version.h" -#include -#include - -/*=========================================================================== - LOCAL CONSTANTS -=============================================================================*/ - -/*=========================================================================== - LOCAL MACROS -=============================================================================*/ - -/*=========================================================================== - LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) -=============================================================================*/ - -/*=========================================================================== - OPENSSL 1.0.2 SUPPORT -=============================================================================*/ - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - -static void * -OPENSSL_zalloc(size_t num) -{ - void *ret = OPENSSL_malloc(num); - - if (ret != NULL) { - memset(ret, 0, num); - } - return ret; -} - -void -ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) { - *pr = sig->r; - } - if (ps != NULL) { - *ps = sig->s; - } -} - -int -ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) { - return 0; - } - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} - -void -EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} - -EVP_MD_CTX * -EVP_MD_CTX_new(void) -{ - return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); -} - -EC_KEY * -EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) -{ - return (pkey->pkey.ec); -} - -RSA * -EVP_PKEY_get0_RSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_RSA) { - return NULL; - } - return pkey->pkey.rsa; -} - -void -RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) { - *n = r->n; - } - if (e != NULL) { - *e = r->e; - } - if (d != NULL) { - *d = r->d; - } -} - -#endif - -/*=========================================================================== - LOCAL FUNCTION PROTOTYPES -=============================================================================*/ - -/*=========================================================================== - LOCAL FUNCTIONS -=============================================================================*/ - -/*=========================================================================== - GLOBAL FUNCTIONS -=============================================================================*/ - -/*-------------------------- - openssl_initialize ----------------------------*/ - -void -openssl_initialize(void) -{ -#if defined _WIN32 || defined __CYGWIN__ - /* Required to avoid OpenSSL runtime errors on Win32 platforms */ - /* See: https://www.openssl.org/docs/faq.html#PROG3 */ - OPENSSL_malloc_init(); -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); -#endif -} - - -/*-------------------------- - generate_hash ----------------------------*/ - -uint8_t * -generate_hash(const uint8_t *buf, size_t msg_bytes, const char *hash_alg, - size_t *hash_bytes) -{ - const EVP_MD *type; /**< Mesage digest type*/ - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); /**< Message digest context */ - uint8_t *hash_mem_ptr = NULL; /**< location of result buffer */ - unsigned int tmp; - - if (!(type = EVP_get_digestbyname(hash_alg))) - { - return NULL; - } - - if (!(hash_mem_ptr = (uint8_t *)malloc(EVP_MAX_MD_SIZE))) - { - return NULL; - } - - - EVP_DigestInit(ctx, type); - EVP_DigestUpdate(ctx, buf, msg_bytes); - EVP_DigestFinal(ctx, hash_mem_ptr, &tmp); - - *hash_bytes = tmp; - - return hash_mem_ptr; -} - -/*-------------------------- - get_bn ----------------------------*/ - -uint8_t* -get_bn(const BIGNUM *a, size_t *bytes) -{ - uint8_t *byte_array = NULL; /**< Resulting big number byte array */ - uint32_t a_num_bytes = BN_num_bytes(a); - - byte_array = malloc(a_num_bytes); - if (byte_array == NULL) - { - return NULL; - } - - BN_bn2bin(a, byte_array); - - *bytes = a_num_bytes; - return byte_array; -} - -/*-------------------------- - sign_data ----------------------------*/ - -uint8_t* -sign_data(const EVP_PKEY *skey, const BUF_MEM *bptr, hash_alg_t hash_alg, - size_t *sig_bytes) -{ - EVP_MD_CTX *ctx = EVP_MD_CTX_create(); /**< Signature context */ - uint8_t *sig_buf = NULL; /**< Location of sig. array */ - const EVP_MD *hash_type = NULL; /**< Hash digest algorithm type */ - unsigned int tmp_sig_bytes; -#ifdef DEBUG - uint32_t i; /**< Loop index */ -#endif - - if (ctx) - { - tmp_sig_bytes = EVP_PKEY_size((EVP_PKEY *)skey); - sig_buf = malloc(tmp_sig_bytes); - - /* Determine OpenSSL hash digest type */ - if (hash_alg == SHA_1) - { - hash_type = EVP_sha1(); - } - else if (hash_alg == SHA_256) - { - hash_type = EVP_sha256(); - } - else - { - EVP_MD_CTX_destroy(ctx); - return NULL; - } - - if ((sig_buf != NULL) && - ( (EVP_SignInit_ex(ctx, hash_type, NULL) != CST_SUCCESS) || - (EVP_SignUpdate(ctx, bptr->data, bptr->length) != CST_SUCCESS) || - (EVP_SignFinal(ctx, sig_buf, &tmp_sig_bytes, (EVP_PKEY *)skey) - != CST_SUCCESS) )) - { - *sig_bytes = tmp_sig_bytes; - EVP_MD_CTX_destroy(ctx); - return NULL; - } - - *sig_bytes = tmp_sig_bytes; - -#ifdef DEBUG - printf("Signature bytes = %d\n", tmp_sig_bytes); - if (sig_buf) - { - for (i = 0; i < tmp_sig_bytes; i++) - { - printf("%d) 0x%02x\n", i, sig_buf[i]); - } - } -#endif - - EVP_MD_CTX_destroy(ctx); - } - return sig_buf; -} - -/*-------------------------- - read_certificate ----------------------------*/ -X509* -read_certificate(const char* filename) -{ - BIO *bio_cert = NULL; /**< OpenSSL BIO ptr */ - X509 *cert = NULL; /**< X.509 certificate data structure */ - FILE *fp = NULL; /**< File pointer for DER encoded file */ - /** Points to expected location of ".pem" filename extension */ - const char *temp = filename + strlen(filename) - - PEM_FILE_EXTENSION_BYTES; - - bio_cert = BIO_new(BIO_s_file()); - if (bio_cert == NULL) - { - return NULL; - } - - /* PEM encoded */ - if (!strncasecmp(temp, PEM_FILE_EXTENSION, PEM_FILE_EXTENSION_BYTES)) - { - if (BIO_read_filename(bio_cert, filename) <= 0) - { - BIO_free(bio_cert); - return NULL; - } - - cert = PEM_read_bio_X509(bio_cert, NULL, 0, NULL); - } - /* DER encoded */ - else - { - /* Open the DER file and load it into a X509 object */ - fp = fopen(filename, "rb"); - if (NULL == fp) return NULL; - cert = d2i_X509_fp(fp, NULL); - fclose(fp); - } - - BIO_free(bio_cert); - return cert; -} - -/*-------------------------------- - get_der_encoded_certificate_data -----------------------------------*/ -int32_t get_der_encoded_certificate_data(const char* filename, - uint8_t ** der) -{ - /** Used for returning either size of der data or 0 to indicate an error */ - int32_t ret_val = 0; - - /* Read X509 certificate data from cert file */ - X509 *cert = read_certificate(filename); - - if (cert != NULL) - { - /* i2d_X509() allocates memory for der data, converts the X509 - * cert structure to binary der formatted data. It then - * returns the address of the memory allocated for the der data - */ - ret_val = i2d_X509(cert, der); - - /* On error return 0 */ - if (ret_val < 0) - { - ret_val = 0; - } - X509_free(cert); - } - return ret_val; -} - -/*-------------------------- - read_private_key ----------------------------*/ -EVP_PKEY* -read_private_key(const char *filename, pem_password_cb *password_cb, - const char *password) -{ - BIO *private_key = NULL; /**< OpenSSL BIO ptr */ - EVP_PKEY *pkey; /**< Private Key data structure */ - /** Points to expected location of ".pem" filename extension */ - const char *temp = filename + strlen(filename) - - PEM_FILE_EXTENSION_BYTES; - - /* Read Private key */ - private_key = BIO_new(BIO_s_file( )); - if (!private_key) - { - return NULL; - } - - /* Set BIO to read from the given filename */ - if (BIO_read_filename(private_key, filename) <= 0) - { - BIO_free(private_key); - return NULL; - } - - if (!strncasecmp(temp, PEM_FILE_EXTENSION, PEM_FILE_EXTENSION_BYTES)) - { - /* Read Private key - from PEM encoded file */ - pkey = PEM_read_bio_PrivateKey(private_key, NULL, password_cb, - (char *)password); - if (!pkey) - { - BIO_free(private_key); - return NULL; - } - } - else - { - pkey = d2i_PKCS8PrivateKey_bio (private_key, NULL, password_cb, - (char *)password ); - if (!pkey) - { - BIO_free(private_key); - return NULL; - } - } - return pkey; -} - -/*-------------------------- - print_version ----------------------------*/ - -void print_version(void) -{ - printf("Code Signing Tool release version %s\n",CST_VERSION); -} - -/*-------------------------- - seed_prng ----------------------------*/ -uint32_t seed_prng(uint32_t bytes) -{ - return RAND_load_file("/dev/random", bytes); -} - - -/*-------------------------- - gen_random_bytes ----------------------------*/ -int32_t gen_random_bytes(uint8_t *buf, size_t bytes) -{ - if (!RAND_bytes(buf, bytes)) - { - return CAL_RAND_API_ERROR; - } - - return CAL_SUCCESS; -} - -/*-------------------------- - get_digest_name ----------------------------*/ -char* -get_digest_name(hash_alg_t hash_alg) -{ - char *hash_name = NULL; /**< Ptr to return address of string macro */ - switch(hash_alg) { - case SHA_1: - hash_name = HASH_ALG_SHA1; - break; - case SHA_256: - hash_name = HASH_ALG_SHA256; - break; - case SHA_384: - hash_name = HASH_ALG_SHA384; - break; - case SHA_512: - hash_name = HASH_ALG_SHA512; - break; - default: - hash_name = HASH_ALG_INVALID; - break; - } - return hash_name; -} - -/*-------------------------- - calculate_hash ----------------------------*/ -int32_t -calculate_hash(const char *in_file, - hash_alg_t hash_alg, - uint8_t *buf, - int32_t *pbuf_bytes) -{ - const EVP_MD *sign_md; /**< Ptr to digest name */ - int32_t bio_bytes; /**< Length of bio data */ - BIO *in = NULL; /**< Ptr to BIO for reading data from in_file */ - BIO *bmd = NULL; /**< Ptr to BIO with hash bytes */ - BIO *inp; /**< Ptr to BIO for appending in with bmd */ - /** Status initialized to API error */ - int32_t err_value = CAL_CRYPTO_API_ERROR; - - sign_md = EVP_get_digestbyname(get_digest_name(hash_alg)); - if (sign_md == NULL) { - return CAL_INVALID_ARGUMENT; - } - - /* Read data to generate hash */ - do { - - /* Create necessary bios */ - in = BIO_new(BIO_s_file()); - bmd = BIO_new(BIO_f_md()); - if (in == NULL || bmd == NULL) { - break; - } - - /* Set BIO to read filename in_file */ - if (BIO_read_filename(in, in_file) <= 0) { - break; - } - - /* Set BIO md to given hash */ - if (!BIO_set_md(bmd, sign_md)) { - break; - } - - /* Appends BIO in to bmd */ - inp = BIO_push(bmd, in); - - /* Read data from file BIO */ - do - { - bio_bytes = BIO_read(inp, (uint8_t *)buf, *pbuf_bytes); - } while (bio_bytes > 0); - - /* Check for read error */ - if (bio_bytes < 0) { - break; - } - - /* Get the hash */ - bio_bytes = BIO_gets(inp, (char *)buf, *pbuf_bytes); - if (bio_bytes <= 0) { - break; - } - - /* Send the output bytes in pbuf_bytes */ - *pbuf_bytes = bio_bytes; - err_value = CAL_SUCCESS; - } while(0); - - if (in != NULL) BIO_free(in); - if (bmd != NULL) BIO_free(bmd); - - return err_value; -} - -/*-------------------------- - ver_sig_data ----------------------------*/ -int32_t ver_sig_data(const char *in_file, - const char *cert_file, - hash_alg_t hash_alg, - sig_fmt_t sig_fmt, - uint8_t *sig_buf, - size_t sig_buf_bytes) -{ - EVP_PKEY *pkey = X509_get_pubkey(read_certificate(cert_file)); - const EVP_MD *hash_type = EVP_get_digestbyname(get_digest_name(hash_alg)); - int32_t hash_bytes = HASH_BYTES_MAX; - uint8_t *hash = OPENSSL_malloc(HASH_BYTES_MAX); - ECDSA_SIG *ecdsa_sig = NULL; - uint8_t *ecdsa_der = NULL; - uint32_t ecdsa_der_size = 0; - - if (NULL == in_file) return CAL_INVALID_ARGUMENT; - if (NULL == pkey) return CAL_INVALID_ARGUMENT; - if (NULL == hash_type) return CAL_INVALID_ARGUMENT; - if (NULL == sig_buf) return CAL_INVALID_ARGUMENT; - if (0 == sig_buf_bytes) return CAL_INVALID_ARGUMENT; - if (NULL == hash) return CAL_CRYPTO_API_ERROR; - - if (CAL_SUCCESS != calculate_hash(in_file, hash_alg, hash, &hash_bytes)) - return CAL_CRYPTO_API_ERROR; - - switch (sig_fmt) - { - case SIG_FMT_PKCS1: - if (1 != RSA_verify(EVP_MD_type(hash_type), hash, hash_bytes, - sig_buf, sig_buf_bytes, EVP_PKEY_get0_RSA(pkey))) - { - return CAL_INVALID_SIGNATURE; - } - break; - - case SIG_FMT_ECDSA: - ecdsa_sig = ECDSA_SIG_new(); - if (NULL == ecdsa_sig) return CAL_CRYPTO_API_ERROR; - ECDSA_SIG_set0(ecdsa_sig, - BN_bin2bn(sig_buf, sig_buf_bytes/2, NULL), - BN_bin2bn(sig_buf + sig_buf_bytes/2, sig_buf_bytes/2, NULL)); - ecdsa_der_size = i2d_ECDSA_SIG(ecdsa_sig, &ecdsa_der); - if (0 == ecdsa_der_size) return CAL_CRYPTO_API_ERROR; - if (1 != ECDSA_verify(0 /* ignored */, hash, hash_bytes, - ecdsa_der, ecdsa_der_size, EVP_PKEY_get0_EC_KEY(pkey))) - { - return CAL_INVALID_SIGNATURE; - } - break; - - default: - return CAL_INVALID_ARGUMENT; - } - - return CAL_SUCCESS; -} - -/*-------------------------- - print_license ----------------------------*/ - -void print_license(void) -{ - printf("\n\nNXP License Information:\n"); - printf("----------------------------------\n"); - printf("Copyright (c) Freescale Semiconductor, Inc. 2011, 2012. All rights reserved.\n"); - printf("Copyright 2018-2019 NXP\n\n"); - printf("This software is under license from NXP\n"); - printf("By using this software you agree to the license terms provided\n"); - printf("at the time this release was downloaded from www.nxp.com\n"); - printf("\nOpenssl/SSLeay License Information:\n"); - printf("---------------------------------------\n"); - printf("This product includes software developed by the OpenSSL Project\n"); - printf("for use in the OpenSSL Toolkit (http://www.openssl.org/)\n\n"); - printf("This product includes cryptographic software written by\n"); - printf("Eric Young (eay@cryptsoft.com)\n"); - printf("This product includes cryptographic software written by\n"); - printf("Brian Gladman, Worcester, UK\n"); - printf("\nThe following is the full license text for OpenSSL, SSLeay\n"); - printf("and Brian Gladman:\n\n"); - printf("OpenSSL License\n"); - printf("---------------\n\n"); - printf("/* ====================================================================\n"); - printf(" * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.\n"); - printf(" *\n"); - printf(" * Redistribution and use in source and binary forms, with or without\n"); - printf(" * modification, are permitted provided that the following conditions\n"); - printf(" * are met:\n"); - printf(" *\n"); - printf(" * 1. Redistributions of source code must retain the above copyright\n"); - printf(" * notice, this list of conditions and the following disclaimer.\n"); - printf(" *\n"); - printf(" * 2. Redistributions in binary form must reproduce the above copyright\n"); - printf(" * notice, this list of conditions and the following disclaimer in\n"); - printf(" * the documentation and/or other materials provided with the\n"); - printf(" * distribution.\n"); - printf(" *\n"); - printf(" * 3. All advertising materials mentioning features or use of this\n"); - printf(" * software must display the following acknowledgment:\n"); - printf(" * \"This product includes software developed by the OpenSSL Project\n"); - printf(" * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n"); - printf(" *\n"); - printf(" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n"); - printf(" * endorse or promote products derived from this software without\n"); - printf(" * prior written permission. For written permission, please contact\n"); - printf(" * openssl-core@openssl.org.\n"); - printf(" *\n"); - printf(" * 5. Products derived from this software may not be called \"OpenSSL\"\n"); - printf(" * nor may \"OpenSSL\" appear in their names without prior written\n"); - printf(" * permission of the OpenSSL Project.\n"); - printf(" *\n"); - printf(" * 6. Redistributions of any form whatsoever must retain the following\n"); - printf(" * acknowledgment:\n"); - printf(" * \"This product includes software developed by the OpenSSL Project\n"); - printf(" * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n"); - printf(" *\n"); - printf(" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n"); - printf(" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"); - printf(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n"); - printf(" * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n"); - printf(" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"); - printf(" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n"); - printf(" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"); - printf(" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"); - printf(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n"); - printf(" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n"); - printf(" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"); - printf(" * OF THE POSSIBILITY OF SUCH DAMAGE.\n"); - printf(" * ====================================================================\n"); - printf(" *\n"); - printf(" * This product includes cryptographic software written by Eric Young\n"); - printf(" * (eay@cryptsoft.com). This product includes software written by Tim\n"); - printf(" * Hudson (tjh@cryptsoft.com).\n"); - printf(" *\n"); - printf(" */\n\n"); - printf("Original SSLeay License\n"); - printf("-----------------------\n\n"); - printf("/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)\n"); - printf(" * All rights reserved.\n"); - printf(" *\n"); - printf(" * This package is an SSL implementation written\n"); - printf(" * by Eric Young (eay@cryptsoft.com).\n"); - printf(" * The implementation was written so as to conform with Netscapes SSL.\n"); - printf(" *\n"); - printf(" * This library is free for commercial and non-commercial use as long as\n"); - printf(" * the following conditions are aheared to. The following conditions\n"); - printf(" * apply to all code found in this distribution, be it the RC4, RSA,\n"); - printf(" * lhash, DES, etc., code; not just the SSL code. The SSL documentation\n"); - printf(" * included with this distribution is covered by the same copyright terms\n"); - printf(" * except that the holder is Tim Hudson (tjh@cryptsoft.com).\n"); - printf(" *\n"); - printf(" * Copyright remains Eric Young's, and as such any Copyright notices in\n"); - printf(" * the code are not to be removed.\n"); - printf(" * If this package is used in a product, Eric Young should be given attribution\n"); - printf(" * as the author of the parts of the library used.\n"); - printf(" * This can be in the form of a textual message at program startup or\n"); - printf(" * in documentation (online or textual) provided with the package.\n"); - printf(" *\n"); - printf(" * Redistribution and use in source and binary forms, with or without\n"); - printf(" * modification, are permitted provided that the following conditions\n"); - printf(" * are met:\n"); - printf(" * 1. Redistributions of source code must retain the copyright\n"); - printf(" * notice, this list of conditions and the following disclaimer.\n"); - printf(" * 2. Redistributions in binary form must reproduce the above copyright\n"); - printf(" * notice, this list of conditions and the following disclaimer in the\n"); - printf(" * documentation and/or other materials provided with the distribution.\n"); - printf(" * 3. All advertising materials mentioning features or use of this software\n"); - printf(" * must display the following acknowledgement:\n"); - printf(" * \"This product includes cryptographic software written by\n"); - printf(" * Eric Young (eay@cryptsoft.com)\"\n"); - printf(" * The word 'cryptographic' can be left out if the rouines from the library\n"); - printf(" * being used are not cryptographic related :-).\n"); - printf(" * 4. If you include any Windows specific code (or a derivative thereof) from\n"); - printf(" * the apps directory (application code) you must include an acknowledgement:\n"); - printf(" * \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\"\n"); - printf(" *\n"); - printf(" * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\n"); - printf(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"); - printf(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"); - printf(" * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"); - printf(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"); - printf(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"); - printf(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"); - printf(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"); - printf(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"); - printf(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - printf(" * SUCH DAMAGE.\n"); - printf(" *\n"); - printf(" * The licence and distribution terms for any publically available version or\n"); - printf(" * derivative of this code cannot be changed. i.e. this code cannot simply be\n"); - printf(" * copied and put under another distribution licence\n"); - printf(" * [including the GNU Public Licence.]\n"); - printf(" */\n\n"); - printf("Original Brian Gladman License\n"); - printf("------------------------------\n\n"); - printf(" /*\n"); - printf(" ---------------------------------------------------------------------------\n"); - printf(" Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.\n"); - printf(" \n"); - printf(" LICENSE TERMS\n"); - printf(" \n"); - printf(" The redistribution and use of this software (with or without changes)\n"); - printf(" is allowed without the payment of fees or royalties provided that:\n"); - printf(" \n"); - printf(" 1. source code distributions include the above copyright notice, this\n"); - printf(" list of conditions and the following disclaimer;\n"); - printf(" \n"); - printf(" 2. binary distributions include the above copyright notice, this list\n"); - printf(" of conditions and the following disclaimer in their documentation;\n"); - printf(" \n"); - printf(" 3. the name of the copyright holder is not used to endorse products\n"); - printf(" built using this software without specific written permission.\n"); - printf(" \n"); - printf(" DISCLAIMER\n"); - printf(" \n"); - printf(" This software is provided 'as is' with no explicit or implied warranties\n"); - printf(" in respect of its properties, including, but not limited to, correctness\n"); - printf(" and/or fitness for purpose.\n"); - printf(" ---------------------------------------------------------------------------\n"); - printf(" Issue Date: 20/12/2007\n"); - printf(" */\n\n"); -} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/pkey.c imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/pkey.c --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/pkey.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/pkey.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -/*===========================================================================*/ -/** - @file pkey.c - - @brief Implements private key access API. This is part of libpkey.a - library. The functionality of these API can be customized by linking to - customer version of libpkey.a owned by customer. - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011, 2012. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============================================================================= -@endverbatim */ - -/*=========================================================================== - INCLUDE FILES -=============================================================================*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*=========================================================================== - LOCAL FUNCTION PROTOTYPES -=============================================================================*/ -/** Chomp - removes newline from character string - * - * @param[in] s input string - * - * @pre None - * - * @post s is modified removing new line characters - */ -static void -chomp(char *s); - -/*=========================================================================== - LOCAL FUNCTIONS -=============================================================================*/ -/*-------------------------- - chomp ----------------------------*/ -void -chomp(char *s) -{ - while(*s && *s != '\n' && *s != '\r') s++; - *s = 0; -} - -/*-------------------------- - get_passcode_to_key_file ----------------------------*/ -int get_passcode_to_key_file(char *buf, int size, int rwflag, void *userdata) -{ - FILE * password_fp; - char * ptr_to_last_slash; - char key_file_path[255]; - char *key_file = (char *)userdata; - - UNUSED(rwflag); - - /* Initialize the temporary path */ - memset(key_file_path,0,255); - - /* - * Get the folder where the password file is present. - * The file is located in the same folder than the keys used for signature. - * Start by searching for the last occurance of '/' in the path of - * a key installed by a CSF command and passed through *userdata. - */ - ptr_to_last_slash = strrchr(key_file, '/'); - - /* Copy from beginning to ptr_to_last_slash into key_file_path */ - if(ptr_to_last_slash != NULL) - { - strncpy(key_file_path, key_file, (ptr_to_last_slash - - key_file + 1)); - } - - /* Concatenate with key_pass.txt to form the complete path */ - strcat(key_file_path, "key_pass.txt"); - - /* - * This particular implementation assumes file key_file.txt to be present - * in keys folder with password string. - */ - password_fp = fopen(key_file_path, "r"); - if (password_fp == NULL) - { - /* Cannot open password file, it could be that keys are not encrypted - * return 0 for password size */ - return 0; - } - - fgets(buf, size, password_fp); - chomp(buf); - - return strlen(buf); -} - -/*-------------------------- - get_key_file ----------------------------*/ -int32_t get_key_file(const char* cert_file, char* key_file) -{ - /* Algorithm to locate key file from given cert file */ - /* for now just assume the key to present in the */ - /* same folder as cert file. The crt in the name will */ - /* will be replaced with key */ - char * folder; - int32_t i = strlen(cert_file); /**< Index into key filename, initialized - to filename length */ - - strcpy(key_file, cert_file); - key_file[i] = 0; - - key_file[i-5] = 'y'; - key_file[i-6] = 'e'; - key_file[i-7] = 'k'; - - /* Search for folder name "certs" in the file and replace it with "keys" */ - /* Keys are found in "keys" folder and certs are in "certs" folder */ - - folder = strstr(key_file, "crts"); - if(folder) - { - folder[0] = 'k'; - folder[1] = 'e'; - folder[2] = 'y'; - folder[3] = 's'; - } - return CAL_SUCCESS; -} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/ssl_wrapper.c imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/ssl_wrapper.c --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end/src/ssl_wrapper.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end/src/ssl_wrapper.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,296 +0,0 @@ -/*===========================================================================*/ -/** - @file ssl_wrapper.c - - @brief Implements Code Signing Tool's SSL Wrapper API for the - Freescale reference Code Signing Tool. . - -@verbatim -============================================================================= - - Freescale Semiconductor - (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018-2019 NXP - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ -#include -#include -#include -#include -#include -#include "ssl_wrapper.h" - -void handle_errors(char * str, int32_t *err_value, char *err_str) { - snprintf(err_str, MAX_ERR_STR_BYTES-1, "%s", str); - *err_value = CAL_CRYPTO_API_ERROR; -} - -int32_t encryptccm(unsigned char *plaintext, int plaintext_len, unsigned char *aad, - int aad_len, unsigned char *key, int key_len, unsigned char *iv, int iv_len, - const char * out_file, unsigned char *tag, int tag_len, int32_t *err_value, - char *err_str) { - -#ifdef REMOVE_ENCRYPTION - UNUSED(plaintext); - UNUSED(plaintext_len); - UNUSED(aad); - UNUSED(aad_len); - UNUSED(key); - UNUSED(key_len); - UNUSED(iv); - UNUSED(iv_len); - UNUSED(out_file); - UNUSED(tag); - UNUSED(tag_len); - UNUSED(err_value); - UNUSED(err_str); - - return CAL_NO_CRYPTO_API_ERROR; -#else - EVP_CIPHER_CTX *ctx; - - int len; - int ciphertext_len; - - unsigned char *ciphertext = NULL; - ciphertext = (unsigned char *)malloc(plaintext_len + EVP_MAX_BLOCK_LENGTH); - if (NULL == ciphertext) { - handle_errors("Failed to allocate memory for encrypted data", - err_value, err_str); - return *err_value; - } - - FILE *fho = NULL; - int err = 0; - do{ - /* Create and initialise the context */ - if (!(ctx = EVP_CIPHER_CTX_new())) { - handle_errors("Failed to allocate ccm context structure", - err_value, err_str); - break; - } - - /* Initialise the encryption operation. */ - switch(key_len) { - case 16: - err = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), NULL, NULL, NULL); - break; - case 24: - err = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); - break; - case 32: - err = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL); - break; - default: - handle_errors("Failed to allocate ccm context structure", - err_value, err_str); - free(ciphertext); - return *err_value; - } - - if (err != 1) { - handle_errors("Failed to initialize ccm context structure", - err_value, err_str); - break; - } - - /* - * Setting IV len to 7. Not strictly necessary as this is the default - * but shown here for the purposes of this example - */ - if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_len, NULL)) { - handle_errors("Failed to initialize IV", err_value, err_str); - break; - } - - /* Set tag length */ - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL); - - /* Initialise key and IV */ - if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) { - handle_errors("Failed to intialize key", err_value, err_str); - break; - } - - /* Provide the total plaintext length */ - if (1 != EVP_EncryptUpdate(ctx, NULL, &len, NULL, plaintext_len)) { - handle_errors("Failed to initialize length parameter", err_value, err_str); - break; - } - - /* - * Provide the message to be encrypted, and obtain the encrypted output. - * EVP_EncryptUpdate can only be called once for this - */ - if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) { - handle_errors("Failed to encrypt", err_value, err_str); - break; - } - ciphertext_len = len; - - /* Open out_file for writing */ - fho = fopen(out_file, "wb"); - if (fho == NULL) { - handle_errors("Cannot open file", err_value, err_str); - break; - } - - /* Write encrypted data to out file */ - if (fwrite(ciphertext, 1, ciphertext_len, fho) != ciphertext_len) { - handle_errors("Cannot write file", err_value, err_str); - break; - } - - /* - * Finalise the encryption. Normally ciphertext bytes may be written at - * this stage, but this does not occur in CCM mode - */ - if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { - handle_errors("Failed to finalize", err_value, err_str); - break; - } - ciphertext_len += len; - - /* Get the tag */ - if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, 16, tag)) { - handle_errors("Failed to get tag", err_value, err_str); - break; - } - - } while(0); - - /* Clean up */ - EVP_CIPHER_CTX_free(ctx); - - if (fho) { - fclose(fho); - } - - free(ciphertext); - - return *err_value; -#endif -} - -int32_t encryptcbc(unsigned char *plaintext, int plaintext_len, unsigned char *key, - int key_len, unsigned char *iv, const char * out_file, int32_t *err_value, char *err_str) -{ -#ifdef REMOVE_ENCRYPTION - return CAL_NO_CRYPTO_API_ERROR; -#else - EVP_CIPHER_CTX *ctx; - int len, ciphertext_len; - unsigned char *ciphertext = NULL; - ciphertext = (unsigned char *)malloc(plaintext_len); - if (NULL == ciphertext) { - handle_errors("Failed to allocate memory for encrypted data", - err_value, err_str); - return *err_value; - } - - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) { - handle_errors("Fail to allocate AES-CBC context", err_value, err_str); - free(ciphertext); - return *err_value; - } - - do { - /* Initialise the encryption operation */ - const EVP_CIPHER *cipher; - switch(key_len) { - case 16: - cipher = EVP_aes_128_cbc(); - break; - case 24: - cipher = EVP_aes_192_cbc(); - break; - case 32: - cipher = EVP_aes_256_cbc(); - break; - default: - handle_errors("Invalid key length for AES-CBC operation", err_value, err_str); - free(ciphertext); - return *err_value; - } - - if(1 != EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv)) { - handle_errors("Fail to initialise AES-CBC operation", err_value, err_str); - break; - } - - /* - * If the pad parameter is zero then no padding is performed, the total - * amount of data encrypted or decrypted must then be a multiple of the - * block size or an error will occur. - */ - if (1 != EVP_CIPHER_CTX_set_padding(ctx, 0)) { - handle_errors("Fail to disable padding", err_value, err_str); - break; - } - - if (0 != (plaintext_len % AES_BLOCK_BYTES)) { - handle_errors("Amount of data not multiple of AES block size (128 bits)", err_value, err_str); - break; - } - - /* Provide the message and get the encrypted data */ - if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) { - handle_errors("Fail to encrypt with AES-CBC", err_value, err_str); - break; - } - ciphertext_len = len; - - /* Finalise the encryption. Further ciphertext bytes may be written */ - if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { - handle_errors("Fail to finalise AES-CBC encryption", err_value, err_str); - break; - } - ciphertext_len += len; - - /* Write encrypted data to out file */ - FILE *out = fopen(out_file, "wb"); - if (NULL == out) { - handle_errors("Cannot open temporary out file during AES-CBC operation", err_value, err_str); - break; - } - - if (fwrite(ciphertext, 1, ciphertext_len, out) != ciphertext_len) { - handle_errors("Fail to write temporary out file during AES-CBC operation", err_value, err_str); - break; - } - - fclose(out); - - } while(0); - - EVP_CIPHER_CTX_free(ctx); - - free(ciphertext); - - return *err_value; -#endif -} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/Readme.txt imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/Readme.txt --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/Readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/Readme.txt 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1 @@ +Please refer to the Application Note AN12812 for assistance on building and using Code-Signing Tool (CST) with a Hardware Security Module (HSM) backend to perform code signing for HAB and AHAB. \ No newline at end of file diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/backend.c imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/backend.c --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/backend.c 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/backend.c 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,1476 @@ +// SPDX-License-Identifier: BSD-2-Clause +/** + * @file backend.c + * + * @brief An engine backend for Code-Signing Tool. + * + * @verbatim + * ====================================================================== + * + * Copyright 2020 NXP + * + * ======================================================================= + * @endverbatim + */ + +/* Standard includes */ +#include +#include +#include +#include +#include +#include + +/* Library Openssl includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG + +#include "openssl_helper.h" + +#define HASH_BYTES_SHA512 64 +#define HASH_BYTES_MAX HASH_BYTES_SHA512 +#define MAX_ERR_STR_BYTES 120 /**< Max. error string bytes */ +#define MAX_CMS_DATA 4096 /**< Max bytes in CMS_ContentInfo */ + +#ifdef DEBUG + #define dbg_fprintf(args...) \ + do { fprintf(stderr, args); \ + fflush(stderr); } while (0) +#else + #define dbg_fprintf(args...) +#endif + +struct cst_engine_ctx { + /* Engine configuration */ + ENGINE *engine; +}; + +typedef struct cst_engine_ctx ENGINE_CTX; + +/*=======================================================================+ + LOCAL FUNCTION PROTOTYPES + =======================================================================*/ + +/** Converts hash_alg to an equivalent NID value for OpenSSL + * + * @param[in] hash_alg Hash digest algorithm from #hash_alg_t + * + * @pre hash_alg is a valid value from #hash_alg_t + * + * @returns Openssl NID value corresponding to a valid value for + * @a hash_alg, NID_undef otherwise. + */ +static int32_t get_NID (hash_alg_t hash_alg); + +/** Generate raw PKCS#1 Signature Data + * + * Generates a raw PKCS#1 v1.5 signature for the given data file, signer + * certificate, and hash algorithm. The signature data is returned in + * a buffer provided by caller. + * + * @param[in] in_file string containing path to file with data to sign + * + * @param[in] key EVP_PKEY signing key + * + * @param[in] hash_alg hash algorithm from #hash_alg_t + * + * @param[out] sig_buf signature data buffer + * + * @param[in,out] sig_buf_bytes On input, contains size of + * @a sig_buf in bytes, On output, + * contains size of signature in bytes. + * + * @pre @a in_file, @a cert_file, @a key_file, @a sig_buf + * and @a sig_buf_bytes must not be NULL. + * + * @post On success @a sig_buf is updated to hold the resulting + * signature and + * @a sig_buf_bytes is updates to hold the length of the + * signature in bytes + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_CRYPTO_API_ERROR An Openssl related error has occurred + */ +static int32_t gen_sig_data_raw (const char *in_file, EVP_PKEY * key, + hash_alg_t hash_alg, uint8_t * sig_buf, + int32_t * sig_buf_bytes); + +/** Generate CMS Signature Data + * + * Generates a CMS signature for the given data file, + * signer certificate, and hash algorithm. The signature data is returned + * in a buffer provided by caller. Note that sign_data cannot be used + * here since that function requires an input buffer as an argument. + * For large files it becomes unreasonable to allocate a contigous + * block of memory. + * + * @param[in] in_file string containing path to file with data to sign + * + * @param[in] x509 X509 signer certificate object + * + * @param[in] hash_alg hash algorithm from #hash_alg_t + * + * @param[out] sig_buf signature data buffer + * + * @param[in,out] sig_buf_bytes On input, contains size of @ + * a sig_buf in bytes, On output, contains + * size of signature in bytes. + * + * @pre @a in_file, @a cert_file, @a key_file, @a sig_buf and + * @a sig_buf_bytes must not be NULL. + * + * @post On success @a sig_buf is updated to hold the resulting + * signature and @a sig_buf_bytes is updates to hold the length + * of the signature in bytes + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_INVALID_ARGUMENT One of the input arguments is invalid + * + * @retval #CAL_CRYPTO_API_ERROR An Openssl related error has occurred + */ +static int32_t gen_sig_data_cms (const char *in_file, X509 * x509, + EVP_PKEY * pkey, hash_alg_t hash_alg, uint8_t * sig_buf, + size_t * sig_buf_bytes); + +/** Copies CMS Content Info with encrypted or signature data to buffer + * + * @param[in] cms CMS Content Info + * + * @param[in] bio_in input bio + * + * @param[out] data_buffer address to data buffer + * + * @param[in] data_buffer_size max size, [out] return size + * + * @param[in] flags CMS Flags + * + * @returns CAL_SUCCESS upon success + * + * @returns CAL_CRYPTO_API_ERROR when openssl BIO API fail + */ +static int32_t cms_to_buf (CMS_ContentInfo * cms, BIO * bio_in, + uint8_t * data_buffer, size_t * data_buffer_size, + int32_t flags); + +/** generate_dek_key + * + * Uses openssl API to generate a random 128 bit AES key + * + * @param[out] key buffer to store the key data + * + * @param[in] len length of the key to generate + * + * @post if successful the random bytes are placed into output buffer + * + * @pre #openssl_initialize has been called previously + * + * @returns if successful function returns location CAL_SUCCESS. + */ +static int32_t generate_dek_key (uint8_t * key, int32_t len); + +/** write_plaintext_dek_key + * + * Writes the provide DEK to the give path. It will be encrypted + * under the certificate file if provided. + * + * @param[in] key input key data + * + * @param[in] key_bytes length of the input key + * + * @param[in] cert_file certificate to encrypt the DEK + * + * @param[in] enc_file destination file + * + * @post if successful the dek is written to the file + * + * @returns if successful function returns location CAL_SUCCESS. + */ +static int32_t write_plaintext_dek_key (uint8_t * key, size_t key_bytes, + const char *cert_file, const char *enc_file); + +/** encrypt_dek_key + * + * Uses openssl API to encrypt the key. + * Saves the encrypted structure to a file + * + * @param[in] key input key data + * + * @param[in] key_bytes length of the input key + * + * @param[in] cert filename of the RSA certificate, dek will + * be encrypted with + * + * @param[in] file encrypted data saved in the file + * + * @post if successful the file is created with the encrypted data + * + * @pre #openssl_initialize has been called previously + * + * @returns if successful function returns location CAL_SUCCESS. + */ +static int32_t encrypt_dek_key (uint8_t * key, size_t key_bytes, + const char *cert_file, const char *enc_file); + + +/** engine_calculate_hash + * + * Computes the digest of a file. + * + * @param[in] in_file input file + * + * @param[in] hash_alg digest algorithm + * + * @param[out] buf output digest + * + * @param[out] pbuf_bytes output digest length + * + * @pre @a in_file, @a cert_file, @a hash_alg, @a buf and @a pbuf_bytes + * must not be NULL. + * + * @post On success @a buf is updated to hold the resulting signature and + * @a pbuf_bytes is updates to hold the length of the signature in + * bytes + * + * @returns if successful function returns location CAL_SUCCESS. + */ +static int32_t engine_calculate_hash(const char *in_file, + hash_alg_t hash_alg, uint8_t *buf, int32_t *pbuf_bytes); + +/** ctx_new + * + * Allocates a new functional reference. + * + * @returns functional reference if successful NULL otherwise. + */ +static ENGINE_CTX *ctx_new(void); + +/** ctx_destroy + * + * Destroys context and release the functional reference from ctx_new + * + * @param[ctx] Pointer to engine context structure + * + * @post if successful memory space allocated for functional reference is freed. + * + * @pre #ctx_new has been called previously. + * + * @returns 1 if successful 0 otherwise. + */ +static int32_t ctx_destroy(ENGINE_CTX *ctx); + +/** ctx_init + * + * Initialize context + * + * @param[ctx] Pointer to engine context structure + * + * @post if successful memory space allocated is freed. + * + * @pre #ctx_new has been called previously. + * + * @returns 1 if successful 0 otherwise. + */ +static int32_t ctx_init(ENGINE_CTX *ctx); + +/** ctx_finish + * + * Finalize engine operations initialized with ctx_init + * + * @param[ctx] Functional reference + * + * @pre #ctx_init has been called previously. + * + * @returns 1 if successful 0 otherwise. + */ +static int32_t ctx_finish(ENGINE_CTX *ctx); + +/** ENGINE_load_certificate + * + * Read certificate with a given reference from engine. + * + * @param[in] engine input file + * + * @param[in] cert_ref certificate reference + * + * @pre @a engine, @a cert_ref must not be NULL. + * + * @returns pointer to X.509 certificate if successful, NULL otherwise. + */ +static X509* ENGINE_load_certificate (ENGINE * engine, const char *cert_ref); + +/*=======================================================================+ + LOCAL FUNCTION IMPLEMENTATIONS + =======================================================================*/ + +/*-------------------------- + ctx_new + ---------------------------*/ +static ENGINE_CTX *ctx_new() +{ + ENGINE_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(ENGINE_CTX)); + return ctx; +} + +/*-------------------------- + ctx_destroy + ---------------------------*/ +static int32_t ctx_destroy(ENGINE_CTX *ctx) +{ + if (ctx) { + ENGINE_free(ctx->engine); + OPENSSL_free(ctx); + } + return 1; +} + +/*-------------------------- + ctx_init + ---------------------------*/ +static int32_t ctx_init(ENGINE_CTX *ctx) +{ + /* OpenSSL Initialization */ +#if OPENSSL_VERSION_NUMBER>=0x10100000 + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS \ + | OPENSSL_INIT_LOAD_CONFIG, NULL); +#else + OPENSSL_config(NULL); + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_digests(); + ERR_load_crypto_strings(); +#endif + + ERR_clear_error(); + + ENGINE_load_builtin_engines(); + + ctx->engine = ENGINE_by_id("pkcs11"); + + if(ctx->engine == NULL) + return 0; + +#ifdef DEBUG + ENGINE_ctrl_cmd_string(ctx->engine, "VERBOSE", NULL, 0); +#endif + + if (!ENGINE_init(ctx->engine)) { + ENGINE_free(ctx->engine); + return 0; + } + return 1; +} + +/*-------------------------- + ctx_finish + ---------------------------*/ +static int32_t ctx_finish(ENGINE_CTX *ctx) +{ + if (ctx) { + ENGINE_finish(ctx->engine); + } + return 1; +} + +/*-------------------------- + ENGINE_load_certificate + ---------------------------*/ +X509 *ENGINE_load_certificate (ENGINE * e, const char *cert_ref) +{ + struct { + const char *s_slot_cert_id; + X509 *cert; + } params = {0}; + + params.s_slot_cert_id = cert_ref; + params.cert = NULL; + if (!ENGINE_ctrl_cmd (e, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) { + ERR_print_errors_fp (stderr); + return NULL; + } + + return params.cert; +} + +/*-------------------------- + get_NID + ---------------------------*/ +static int32_t +get_NID (hash_alg_t hash_alg) +{ + return OBJ_txt2nid (get_digest_name (hash_alg)); +} + +/*-------------------------- + gen_sig_data_ecdsa + ---------------------------*/ +static int32_t +gen_sig_data_ecdsa (const char *in_file, EVP_PKEY * key, + hash_alg_t hash_alg, uint8_t * sig_buf, + size_t * sig_buf_bytes) +{ + BIO *bio_in = NULL; /**< BIO for in_file data */ + uint32_t key_size = 0; /**< n of bytes of key param */ + const EVP_MD *sign_md = NULL; /**< Digest name */ + uint8_t *hash = NULL; /**< Hash data of in_file */ + int32_t hash_bytes = 0; /**< Length of hash buffer */ + uint8_t *sign = NULL; /**< Signature data in DER */ + uint32_t sign_bytes = 0; /**< Length of DER signature */ + uint8_t *r = NULL, *s = NULL; /**< Raw signature data R&S */ + size_t bn_bytes = 0; /**< Length of R,S big num */ + ECDSA_SIG *sign_dec = NULL; /**< Raw signature data R|S */ + int32_t err_value = CAL_SUCCESS; /**< Return value */ + char err_str[MAX_ERR_STR_BYTES]; /**< Error string */ + /**< signature numbers defined as OpenSSL BIGNUM */ + const BIGNUM *sig_r, *sig_s; + + if (!key) { + fprintf (stderr, "Invalid certificate or key\n"); + return CAL_INVALID_ARGUMENT; + } + + /* Set signature message digest alg */ + sign_md = EVP_get_digestbyname (get_digest_name (hash_alg)); + if (sign_md == NULL) { + fprintf (stderr, "Invalid hash digest algorithm\n"); + return CAL_INVALID_ARGUMENT; + } + + do { + /* Read Data to be signed */ + if (!(bio_in = BIO_new_file (in_file, "rb"))) { + snprintf (err_str, MAX_ERR_STR_BYTES, + "Cannot open data file %s", in_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Generate hash of data from in_file */ + hash_bytes = HASH_BYTES_MAX; + hash = OPENSSL_malloc (HASH_BYTES_MAX); + + err_value = calculate_hash (in_file, hash_alg, hash, &hash_bytes); + if (err_value != CAL_SUCCESS) { + break; + } + + /* Generate ECDSA signature with DER encoding */ + sign_bytes = ECDSA_size (EVP_PKEY_get0_EC_KEY (key)); + sign = OPENSSL_malloc (sign_bytes); + + if (0 == ECDSA_sign (0 /* ignored */ , hash, hash_bytes, sign, + &sign_bytes, EVP_PKEY_get0_EC_KEY (key))) { + fprintf (stderr, "Failed to generate ECDSA signature\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + sign_dec = d2i_ECDSA_SIG (NULL, (const uint8_t **) &sign, + sign_bytes); + + if (NULL == sign_dec) { + fprintf (stderr, "Failed to decode ECDSA signature\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Copy R|S to sig_buf */ + memset (sig_buf, 0, *sig_buf_bytes); + + key_size = EVP_PKEY_bits (key) >> 3; + if (EVP_PKEY_bits (key) & 0x7) + key_size += 1; /* Valid for P-521 */ + + if ((key_size * 2) > *sig_buf_bytes) { + fprintf (stderr, "Signature buffer too small\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + *sig_buf_bytes = key_size * 2; + + ECDSA_SIG_get0 (sign_dec, &sig_r, &sig_s); + + r = get_bn (sig_r, &bn_bytes); + memcpy (sig_buf + (key_size - bn_bytes), r, bn_bytes); + free (r); + + s = get_bn (sig_s, &bn_bytes); + memcpy (sig_buf + key_size + (key_size - bn_bytes), s, bn_bytes); + free (s); + } while (0); + + /* Print any Openssl errors */ + if (err_value != CAL_SUCCESS) { + ERR_print_errors_fp (stderr); + } + + /* Close everything down */ + if (bio_in) + BIO_free (bio_in); + + return err_value; +} + +/*-------------------------- + gen_sig_data_cms + ---------------------------*/ +static int32_t +gen_sig_data_cms (const char *in_file, X509 * x509, EVP_PKEY * pkey, + hash_alg_t hash_alg, uint8_t * sig_buf, + size_t * sig_buf_bytes) +{ + BIO *bio_in = NULL; /**< BIO for in_file data */ + CMS_ContentInfo *cms = NULL; /**< Ptr used with openssl API */ + const EVP_MD *sign_md = NULL; /**< Ptr to digest name */ + int32_t err_value = CAL_SUCCESS; /**< Used for return value */ + /** Array to hold error string */ + char err_str[MAX_ERR_STR_BYTES]; + /* flags set to match Openssl command line options for generating + * signatures + */ + int32_t flags = CMS_DETACHED | CMS_NOCERTS | + CMS_NOSMIMECAP | CMS_BINARY; + + if (!pkey || !x509) { + fprintf (stderr, "Invalid certificate or key\n"); + return CAL_INVALID_ARGUMENT; + } + /* Set signature message digest alg */ + sign_md = EVP_get_digestbyname (get_digest_name (hash_alg)); + + if (sign_md == NULL) { + fprintf (stderr, "Invalid hash digest algorithm\n"); + return CAL_INVALID_ARGUMENT; + } + + do { + /* Read Data to be signed */ + if (!(bio_in = BIO_new_file (in_file, "rb"))) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot open data file %s", in_file); + fprintf (stderr, "%s\n",err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Generate CMS Signature - can only use CMS_sign if default + * MD is used which is SHA1 */ + flags |= CMS_PARTIAL; + + cms = CMS_sign (NULL, NULL, NULL, bio_in, flags); + if (!cms) { + fprintf (stderr, "Failed to initialize CMS signature\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + if (!CMS_add1_signer (cms, x509, pkey, sign_md, flags)) { + fprintf (stderr, "Failed to generate CMS signature\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Finalize the signature */ + if (!CMS_final (cms, bio_in, NULL, flags)) { + fprintf (stderr, "Failed to finalize CMS signature\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Write CMS signature to output buffer - DER format */ + err_value = cms_to_buf (cms, bio_in, sig_buf, sig_buf_bytes, + flags); + } while (0); + + /* Print any Openssl errors */ + if (err_value != CAL_SUCCESS) { + ERR_print_errors_fp (stderr); + } + + /* Close everything down */ + if (cms) + CMS_ContentInfo_free (cms); + if (bio_in) + BIO_free (bio_in); + + return err_value; +} + +/*-------------------------- + gen_sig_data_raw + ---------------------------*/ +static int32_t +gen_sig_data_raw (const char *in_file, EVP_PKEY * key, + hash_alg_t hash_alg, uint8_t * sig_buf, + int32_t * sig_buf_bytes) +{ + + RSA *rsa = NULL; /**< Ptr to rsa of key data */ + uint8_t *rsa_in = NULL; /**< Mem ptr for hash data of in_file */ + uint8_t *rsa_out = NULL; /**< Mem ptr for encrypted data */ + int32_t rsa_inbytes; /**< Holds the length of rsa_in buf */ + int32_t rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ + int32_t key_bytes; /**< Size of key data */ + int32_t hash_nid; /**< hash id needed for RSA_sign() */ + /**< Holds the return error value */ + int32_t err_value = CAL_CRYPTO_API_ERROR; + + do { + rsa = EVP_PKEY_get1_RSA (key); + EVP_PKEY_free (key); + + if (!rsa) { + fprintf (stderr, + "Unable to extract RSA key for RAW PKCS#1 signature"); + break; + } + + rsa_inbytes = HASH_BYTES_MAX; + rsa_in = (unsigned char *) OPENSSL_malloc (HASH_BYTES_MAX); + key_bytes = RSA_size (rsa); + rsa_out = (unsigned char *) OPENSSL_malloc (key_bytes); + + /* Generate hash data of data from in_file */ + err_value = + engine_calculate_hash (in_file, hash_alg, rsa_in, &rsa_inbytes); + if (err_value != CAL_SUCCESS) { + break; + } + + /* Compute signature. Note: RSA_sign() adds the appropriate DER + * encoded prefix internally. + */ + hash_nid = get_NID (hash_alg); + if (!RSA_sign (hash_nid, rsa_in, rsa_inbytes, rsa_out, + (unsigned int *) &rsa_outbytes, rsa)) { + err_value = CAL_CRYPTO_API_ERROR; + fprintf (stderr, "Unable to generate signature"); + break; + } + else { + err_value = CAL_SUCCESS; + } + + /* Copy signature to sig_buf and update sig_buf_bytes */ + *sig_buf_bytes = rsa_outbytes; + memcpy (sig_buf, rsa_out, rsa_outbytes); + } while (0); + + if (err_value != CAL_SUCCESS) { + ERR_print_errors_fp (stderr); + } + + if (rsa) + RSA_free (rsa); + if (rsa_in) + OPENSSL_free (rsa_in); + if (rsa_out) + OPENSSL_free (rsa_out); + return err_value; +} + +/*-------------------------- + cms_to_buf + ---------------------------*/ +static int32_t +cms_to_buf (CMS_ContentInfo * cms, BIO * bio_in, uint8_t * data_buffer, + size_t * data_buffer_size, int32_t flags) +{ + int32_t err_value = CAL_SUCCESS; + BIO *bio_out = NULL; + BUF_MEM *buffer_memory; /**< Used with BIO functions */ + + buffer_memory = BUF_MEM_new (); + buffer_memory->length = 0; + buffer_memory->data = (char *) data_buffer; + buffer_memory->max = *data_buffer_size; + + do { + if (!(bio_out = BIO_new (BIO_s_mem ()))) { + fprintf (stderr, + "Unable to allocate CMS signature result memory\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + BIO_set_mem_buf (bio_out, buffer_memory, BIO_NOCLOSE); + + /* Convert cms to der format */ + if (!i2d_CMS_bio_stream (bio_out, cms, bio_in, flags)) { + fprintf (stderr, + "Unable to convert CMS signature to DER format\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Get the size of bio out in data_buffer_size */ + *data_buffer_size = BIO_ctrl_pending (bio_out); + } while (0); + + if (bio_out) + BIO_free (bio_out); + return err_value; +} + +/*-------------------------- + engine_calculate_hash + ---------------------------*/ +static int32_t engine_calculate_hash (const char *in_file, hash_alg_t hash_alg, + uint8_t * buf, int32_t * pbuf_bytes) +{ + const EVP_MD *sign_md; /**< Ptr to digest name */ + int32_t bio_bytes; /**< Length of bio data */ + BIO *in = NULL; /**< Ptr to BIO for reading data from in_file */ + BIO *bmd = NULL; /**< Ptr to BIO with hash bytes */ + BIO *inp; /**< Ptr to BIO for appending in with bmd */ + /** Status initialized to API error */ + int32_t err_value = CAL_CRYPTO_API_ERROR; + + sign_md = EVP_get_digestbyname (get_digest_name (hash_alg)); + if (sign_md == NULL) { + return CAL_INVALID_ARGUMENT; + } + + /* Read data to generate hash */ + do { + + /* Create necessary bios */ + in = BIO_new (BIO_s_file ()); + bmd = BIO_new (BIO_f_md ()); + if (in == NULL || bmd == NULL) { + break; + } + + /* Set BIO to read filename in_file */ + if (BIO_read_filename (in, in_file) <= 0) { + break; + } + + /* Set BIO md to given hash */ + if (!BIO_set_md (bmd, sign_md)) { + break; + } + + /* Appends BIO in to bmd */ + inp = BIO_push (bmd, in); + + /* Read data from file BIO */ + do { + bio_bytes = BIO_read (inp, (uint8_t *) buf, *pbuf_bytes); + } while (bio_bytes > 0); + + /* Check for read error */ + if (bio_bytes < 0) { + break; + } + + /* Get the hash */ + bio_bytes = BIO_gets (inp, (char *) buf, *pbuf_bytes); + if (bio_bytes <= 0) { + break; + } + + /* Send the output bytes in pbuf_bytes */ + *pbuf_bytes = bio_bytes; + err_value = CAL_SUCCESS; + } while (0); + + if (in != NULL) + BIO_free (in); + if (bmd != NULL) + BIO_free (bmd); + + return err_value; +} + +/*-------------------------- + generate_dek_key + ---------------------------*/ +static int32_t +generate_dek_key (uint8_t * key, int32_t len) +{ + if (gen_random_bytes (key, len) != CAL_SUCCESS) { + return CAL_CRYPTO_API_ERROR; + } + + return CAL_SUCCESS; +} + +/*-------------------------- + write_plaintext_dek_key + ---------------------------*/ +static int32_t +write_plaintext_dek_key (uint8_t * key, size_t key_bytes, + const char *cert_file, const char *enc_file) +{ + int32_t err_value = CAL_SUCCESS; /**< Return value */ + char err_str[MAX_ERR_STR_BYTES]; /**< Used in preparing error msg */ + FILE *fh = NULL; /**< File handle used with file api */ + + UNUSED (cert_file); + + do { + /* Save the buffer into enc_file */ + if ((fh = fopen (enc_file, "wb")) == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to create binary file %s", enc_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + if (fwrite (key, 1, key_bytes, fh) != key_bytes) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to write to binary file %s", enc_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + fclose (fh); + } while (0); + + return err_value; +} + +/*-------------------------- + encrypt_dek_key + ---------------------------*/ +static int32_t +encrypt_dek_key (uint8_t * key, size_t key_bytes, + const char *cert_file, const char *enc_file) +{ + X509 *cert = NULL; /**< Ptr to X509 certificate read data */ + STACK_OF (X509) * recips = NULL; /**< Ptr to X509 stack */ + CMS_ContentInfo *cms = NULL; /**< Ptr to cms structure */ + const EVP_CIPHER *cipher = NULL; /**< Ptr to EVP_CIPHER */ + int32_t err_value = CAL_SUCCESS; /**< Return value */ + char err_str[MAX_ERR_STR_BYTES]; /**< Used in preparing error msg */ + BIO *bio_key = NULL; /**< Bio for the key data to encrypt */ + uint8_t *enc_buf = NULL; /**< Ptr for encoded key data */ + FILE *fh = NULL; /**< File handle used with file api */ + size_t cms_info_size = MAX_CMS_DATA; /**< Size of cms content info*/ +#ifdef DEBUG + int32_t i = 0; /**< Used in for loops */ +#endif + + do { + /* Read the certificate from cert_file */ + cert = read_certificate (cert_file); + if (!cert) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot open certificate file %s", cert_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Create recipient STACK and add recipient cert to it */ + recips = sk_X509_new_null (); + + if (!recips || !sk_X509_push (recips, cert)) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot instantiate object STACK_OF(%s)", cert_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* + * sk_X509_pop_free will free up recipient STACK and its contents + * so set cert to NULL so it isn't freed up twice. + */ + cert = NULL; + + /* Instantiate correct cipher */ + if (key_bytes == (AES_KEY_LEN_128 / BYTE_SIZE_BITS)) + cipher = EVP_aes_128_cbc (); + else if (key_bytes == (AES_KEY_LEN_192 / BYTE_SIZE_BITS)) + cipher = EVP_aes_192_cbc (); + else if (key_bytes == (AES_KEY_LEN_256 / BYTE_SIZE_BITS)) + cipher = EVP_aes_256_cbc (); + if (cipher == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Invalid cipher used for encrypting key %s", enc_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Allocate memory buffer BIO for input key */ + bio_key = BIO_new_mem_buf (key, key_bytes); + if (!bio_key) { + fprintf (stderr, "Unable to allocate BIO memory\n"); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Encrypt content of the key with certificate */ + cms = CMS_encrypt (recips, bio_key, cipher, + CMS_BINARY | CMS_STREAM); + if (cms == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to encrypt key data"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Finalize the CMS content info structure */ + if (!CMS_final (cms, bio_key, NULL, CMS_BINARY | CMS_STREAM)) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to finalize cms data"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Alloc mem to convert cms to binary and save it into enc_file */ + enc_buf = malloc (MAX_CMS_DATA); + if (enc_buf == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to allocate memory"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + /* Copy cms info into enc_buf */ + err_value = cms_to_buf (cms, bio_key, enc_buf, &cms_info_size, + CMS_BINARY); + + /* Save the buffer into enc_file */ + if ((fh = fopen (enc_file, "wb")) == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to create binary file %s", enc_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + if (fwrite (enc_buf, 1, cms_info_size, fh) != cms_info_size) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to write to binary file %s", enc_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + fclose (fh); +#ifdef DEBUG + printf ("Encoded key ;"); + for (i = 0; i < key_bytes; i++) { + printf ("%02x ", enc_buf[i]); + } + printf ("\n"); +#endif + } while (0); + + if (cms) + CMS_ContentInfo_free (cms); + if (cert) + X509_free (cert); + if (recips) + sk_X509_pop_free (recips, X509_free); + if (bio_key) + BIO_free (bio_key); + return err_value; +} + +/*-------------------------- + handle_errors + ---------------------------*/ +static void +handle_errors (char *str, int32_t * err_value, char *err_str) +{ + snprintf (err_str, MAX_ERR_STR_BYTES - 1, "%s", str); + *err_value = CAL_CRYPTO_API_ERROR; +} + +/*-------------------------- + encryptccm + ---------------------------*/ +int32_t +encryptccm (unsigned char *plaintext, int plaintext_len, + unsigned char *aad, int aad_len, unsigned char *key, + int key_len, unsigned char *iv, int iv_len, + const char *out_file, unsigned char *tag, int tag_len, + int32_t * err_value, char *err_str) +{ + +#ifdef REMOVE_ENCRYPTION + UNUSED (plaintext); + UNUSED (plaintext_len); + UNUSED (aad); + UNUSED (aad_len); + UNUSED (key); + UNUSED (key_len); + UNUSED (iv); + UNUSED (iv_len); + UNUSED (out_file); + UNUSED (tag); + UNUSED (tag_len); + UNUSED (err_value); + UNUSED (err_str); + + return CAL_NO_CRYPTO_API_ERROR; +#else + EVP_CIPHER_CTX *ctx; + + int len; + int ciphertext_len; + + unsigned char ciphertext[plaintext_len + EVP_MAX_BLOCK_LENGTH]; + + FILE *fho = NULL; + int err = 0; + do { + /* Create and initialise the context */ + if (!(ctx = EVP_CIPHER_CTX_new ())) { + handle_errors ("Failed to allocate ccm context structure", + err_value, err_str); + break; + } + + /* Initialise the encryption operation. */ + switch (key_len) { + case 16: + err = + EVP_EncryptInit_ex (ctx, EVP_aes_128_ccm (), + NULL, NULL, NULL); + break; + case 24: + err = + EVP_EncryptInit_ex (ctx, EVP_aes_192_ccm (), + NULL, NULL, NULL); + break; + case 32: + err = + EVP_EncryptInit_ex (ctx, EVP_aes_256_ccm (), + NULL, NULL, NULL); + break; + default: + handle_errors ("Failed allocating ccm context structure", + err_value, err_str); + return *err_value; + } + + if (err != 1) { + handle_errors ("Failed to initialize ccm context structure", + err_value, err_str); + break; + } + + /* + * Setting IV len to 7. Not strictly necessary as this + * is the default but shown here for the purposes of this example + */ + + if (1 != + EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_CCM_SET_IVLEN, + iv_len, NULL)) { + handle_errors ("Failed to initialize IV", err_value, err_str); + break; + } + + /* Set tag length */ + EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL); + + /* Initialise key and IV */ + if (1 != EVP_EncryptInit_ex (ctx, NULL, NULL, key, iv)) { + handle_errors ("Failed to initialize key", err_value, err_str); + break; + } + + /* Provide the total plaintext length */ + if (1 != EVP_EncryptUpdate (ctx, NULL, &len, NULL, + plaintext_len)) { + handle_errors ("Failed to initialize length parameter", + err_value, err_str); + break; + } + + /* + * Provide the message to be encrypted, and obtain the encrypted + * output. EVP_EncryptUpdate can only be called once for this + */ + if (1 != EVP_EncryptUpdate (ctx, ciphertext, &len, plaintext, + plaintext_len)) { + handle_errors ("Failed to encrypt", err_value, err_str); + break; + } + ciphertext_len = len; + + /* Open out_file for writing */ + fho = fopen (out_file, "wb"); + if (fho == NULL) { + handle_errors ("Cannot open file", err_value, err_str); + break; + } + + /* Write encrypted data to out file */ + if (fwrite (ciphertext, 1, ciphertext_len, fho) + != ciphertext_len) { + handle_errors ("Cannot write file", err_value, err_str); + break; + } + + /* + * Finalise the encryption. + * Normally ciphertext bytes may be written at this stage, + * but this does not occur in CCM mode + */ + if (1 != EVP_EncryptFinal_ex (ctx, ciphertext + len, &len)) { + handle_errors ("Failed to finalize", err_value, err_str); + break; + } + ciphertext_len += len; + + /* Get the tag */ + if (1 != EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_CCM_GET_TAG, + 16, tag)) { + handle_errors ("Failed to get tag", err_value, err_str); + break; + } + + } while (0); + + /* Clean up */ + EVP_CIPHER_CTX_free (ctx); + + if (fho) { + fclose (fho); + } + + return *err_value; +#endif +} + +/*======================================================================= + GLOBAL FUNCTION IMPLEMENTATIONS + ======================================================================*/ + +/*-------------------------------- + get_der_encoded_certificate_data +----------------------------------*/ +int32_t get_der_encoded_certificate_data(const char* ref, + uint8_t ** der) +{ + /* Used for returning either size of der data or 0 to indicate an error */ + int32_t ret_val = 0; + + /* Engine configuration */ + ENGINE_CTX *ctx = NULL; + + /* X.509 certificate */ + X509 *cert = NULL; + + /* Allocate new context */ + ctx = ctx_new(); + + if(ctx == NULL){ + return 0; + } + + /* Initialize the context */ + if(!ctx_init(ctx)){ + ctx_destroy(ctx); + return 0; + } + + /* Read X509 certificate data */ + cert = ENGINE_load_certificate (ctx->engine, ref); + if (!cert) + { + ctx_finish(ctx); + ctx_destroy(ctx); + return 0; + } +#ifdef DEBUG + X509_print_fp(stdout, cert); +#endif + /* i2d_X509() allocates memory for der data, converts the X509 + * cert structure to binary der formatted data. It then + * returns the address of the memory allocated for the der data + */ + ret_val = i2d_X509(cert, der); + + /* On error return 0 */ + if (ret_val < 0) + { + ret_val = 0; + } + + /* Finish and destroy the context */ + ctx_finish(ctx); + ctx_destroy(ctx); + + if(cert) + X509_free(cert); + + return ret_val; +} + +/*-------------------------- + gen_sig_data + ---------------------------*/ +int32_t +gen_sig_data (const char *in_file, const char *cert_ref, + hash_alg_t hash_alg, sig_fmt_t sig_fmt, uint8_t * sig_buf, + size_t * sig_buf_bytes, func_mode_t mode) +{ + + /* Engine configuration */ + ENGINE_CTX *ctx = NULL; + + /* Certificate and private key */ + X509 *cert = NULL; + EVP_PKEY *key = NULL; + + /* Operation completed successfully */ + int32_t error = CAL_SUCCESS; + + /* Check for valid arguments */ + if ((!in_file) || (!cert_ref) || (!sig_buf) || (!sig_buf_bytes)) { + return CAL_INVALID_ARGUMENT; + } + + /* Allocate new context */ + ctx = ctx_new(); + + if(ctx == NULL){ + error = CAL_CRYPTO_API_ERROR; + goto out; + } + + /* Initialize the context */ + if(!ctx_init(ctx)){ + error = CAL_CRYPTO_API_ERROR; + goto out; + } + + cert = ENGINE_load_certificate (ctx->engine, cert_ref); + if (!cert) + { + error = CAL_CRYPTO_API_ERROR; + goto out; + } +#ifdef DEBUG + X509_print_fp(stdout, cert); +#endif + key = ENGINE_load_private_key(ctx->engine, cert_ref, 0, 0); + + if (key == NULL) { + error = CAL_CRYPTO_API_ERROR; + goto out; + } + + error = X509_check_private_key(cert, key); + if (!error) { + error = CAL_CRYPTO_API_ERROR; + goto out; + } + + if (sig_fmt == SIG_FMT_ECDSA) { + error = gen_sig_data_ecdsa (in_file, key, hash_alg, sig_buf, + sig_buf_bytes); + } + else if (sig_fmt == SIG_FMT_PKCS1) { + error = gen_sig_data_raw (in_file, key, hash_alg, sig_buf, + (int32_t *) sig_buf_bytes); + } + else if (sig_fmt == SIG_FMT_CMS) { + error = gen_sig_data_cms (in_file, cert, key, hash_alg, sig_buf, + sig_buf_bytes); + } + else { + fprintf (stderr, "Invalid signature format\n"); + return CAL_INVALID_ARGUMENT; + } + +out: + if(ctx) { + /* Finish and destroy the context */ + ctx_finish(ctx); + ctx_destroy(ctx); + } + if (error) + ERR_print_errors_fp(stderr); + if (cert) + X509_free (cert); + if (key) + EVP_PKEY_free (key); + + return error; +} + +/*-------------------------- + gen_auth_encrypted_data + ---------------------------*/ +int32_t +gen_auth_encrypted_data (const char *in_file, const char *out_file, + aead_alg_t aead_alg, uint8_t * aad, size_t aad_bytes, + uint8_t * nonce, size_t nonce_bytes, uint8_t * mac, + size_t mac_bytes, size_t key_bytes, + const char *cert_file, const char *key_file, + int reuse_dek) +{ + int32_t err_value = CAL_SUCCESS; /**< status of function calls */ + char err_str[MAX_ERR_STR_BYTES]; /**< Array to hold error string */ + uint8_t key[MAX_AES_KEY_LENGTH]; /**< Buffer for random key */ + FILE *fh = NULL; /**< Used with files */ + size_t file_size; /**< Size of in_file */ + unsigned char *plaintext = NULL; /**< Array to read file data */ + int32_t bytes_read; +#ifdef DEBUG + int32_t i; /**< used in for loops */ +#endif + + UNUSED (aead_alg); + + do { + /* Generate Nonce */ + err_value = gen_random_bytes ((uint8_t *) nonce, nonce_bytes); + if (err_value != CAL_SUCCESS) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to get nonce"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } +#ifdef DEBUG + printf ("nonce bytes: "); + for (i = 0; i < nonce_bytes; i++) { + printf ("%02x ", nonce[i]); + } + printf ("\n"); +#endif + if (reuse_dek) { + fh = fopen (key_file, "rb"); + if (fh == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to open dek file %s", key_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_FILE_NOT_FOUND; + break; + } + /* Read encrypted data into input_buffer */ + bytes_read = fread (key, 1, key_bytes, fh); + if (bytes_read == 0) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot read file %s", key_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_FILE_NOT_FOUND; + fclose (fh); + break; + } + fclose (fh); + } + else { + /* Generate random aes key to use it for encrypting data */ + err_value = generate_dek_key (key, key_bytes); + if (err_value) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to generate random key"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + } + +#ifdef DEBUG + printf ("random key : "); + for (i = 0; i < key_bytes; i++) { + printf ("%02x ", key[i]); + } + printf ("\n"); +#endif + if (cert_file != NULL) { + /* Encrypt key using cert file and save it in the key_file */ + err_value = encrypt_dek_key (key, key_bytes, cert_file, + key_file); + if (err_value) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to encrypt and save key"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + } else { + /* Save key in the key_file */ + err_value = write_plaintext_dek_key (key, key_bytes, cert_file, + key_file); + if (err_value) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Failed to save key"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + } + /* Get the size of in_file */ + fh = fopen (in_file, "rb"); + if (fh == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Unable to open binary file %s", in_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + fseek (fh, 0, SEEK_END); + file_size = ftell (fh); + plaintext = (unsigned char *) malloc (file_size); + + if (plaintext == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Not enough allocated memory"); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_CRYPTO_API_ERROR; + break; + } + + fclose (fh); + + fh = fopen (in_file, "rb"); + if (fh == NULL) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot open file %s", in_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_FILE_NOT_FOUND; + break; + } + + /* Read encrypted data into input_buffer */ + bytes_read = fread (plaintext, 1, file_size, fh); + /* Reached EOF? */ + if (bytes_read == 0) { + snprintf (err_str, MAX_ERR_STR_BYTES - 1, + "Cannot read file %s", out_file); + fprintf (stderr, "%s\n", err_str); + err_value = CAL_FILE_NOT_FOUND; + break; + } + + err_value = encryptccm (plaintext, file_size, aad, aad_bytes, key, + key_bytes, nonce, nonce_bytes, out_file, mac, + mac_bytes, &err_value, err_str); + if (err_value == CAL_NO_CRYPTO_API_ERROR) { + printf ("Encryption not enabled\n"); + break; + } + } while (0); + + free (plaintext); + + /* Clean up */ + return err_value; +} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/include/adapt_layer.h imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/include/adapt_layer.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/include/adapt_layer.h 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/include/adapt_layer.h 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,291 @@ +#ifndef ADAPT_LAYER_H +#define ADAPT_LAYER_H +/*===========================================================================*/ +/** + @file adapt_layer.h + + @brief CST adaptation layer interface + +@verbatim +============================================================================= + + Copyright 2020 NXP + +============================================================================= +@endverbatim */ + +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include + +/*=========================================================================== + CONSTANTS +=============================================================================*/ + +/*=========================================================================== + MACROS +=============================================================================*/ +#define UNUSED(expr) (void)(expr) + +#define CAL_SUCCESS ( 0) /* Operation completed successfully */ +#define CAL_FILE_NOT_FOUND (-1) /* Error when file does not exist */ +#define CAL_INVALID_SIG_DATA_SIZE (-2) /* Error when sig data size invalid */ +#define CAL_FAILED_FILE_CREATE (-3) /* Error unable to create file */ +#define CAL_MAC_LEN_INCORRECT (-4) /* Error MAC len is incorrect */ +#define CAL_INVALID_ARGUMENT (-5) /* Error argument passed is invalid */ +#define CAL_CRYPTO_API_ERROR (-6) /* Error with openssl API */ +#define CAL_INSUFFICIENT_BUFFER_LEN (-7) /* Buffer length is not sufficient */ +#define CAL_DATA_COMPARE_FAILED (-8) /* Data comparison operation failed */ +#define CAL_RAND_SEED_ERROR (-9) /* Failure to run rand_seed */ +#define CAL_RAND_API_ERROR (-10) /* Failure in RAND_bytes */ +#define CAL_NO_CRYPTO_API_ERROR (-11) /* Error when Encryption is disabled*/ +#define CAL_INVALID_SIGNATURE (-12) /* Error when verifying isignature */ +#define CAL_LAST_ERROR (-100) /* Max error codes for adapt layer */ + +#define FILE_BUF_SIZE (1024) /* 1K buf for file read/file write */ + +#define MAX_AES_KEY_LENGTH (32) /* Max bytes in AES key */ +#define AES_BLOCK_BYTES (16) /**< Max. AES block bytes */ +#define FLAG_BYTES (1) /**< Bytes in Flag */ +#define BYTE_SIZE_BITS (8) /**< Number of bits in a byte */ + +#define SIG_REQ_FILENAME "sig_req.txt" /**< Signing request filename */ + +/*=========================================================================== + ENUMS +=============================================================================*/ +typedef enum func_mode_e +{ + MODE_UNDEF = 0, /**< Undefined functional mode */ + MODE_NOMINAL, /**< Execution in normal mode */ + MODE_HSM, /**< Execution in HSM mode */ +} func_mode_t; + +typedef enum _SIG_FMT +{ + SIG_FMT_UNDEF = 0, /**< Undefined signature format */ + SIG_FMT_PKCS1, /**< RAW PKCS#1 signature format */ + SIG_FMT_CMS, /**< CMS (PKCS#7) signature format */ + SIG_FMT_ECDSA, /**< ECDSA signature format. R|S concatanated */ +} sig_fmt_t; + + +/** Hash Digetst Algorithm */ +typedef enum hash_alg +{ + SHA_1 = 0, /**< SHA-1 Digest Algorithm */ + SHA_256, /**< SHA-256 Digest Algorithm */ + SHA_384, /**< SHA-384 Digest Algorithm */ + SHA_512, /**< SHA-512 Digest Algorithm */ + INVALID_DIGEST /**< Invalid Digest Algorithm */ +} hash_alg_t; + +/** AES key lengths supported */ +typedef enum aes_key_bits +{ + AES_KEY_LEN_128 = 128, /**< 128 bits */ + AES_KEY_LEN_192 = 192, /**< 192 bits */ + AES_KEY_LEN_256 = 256, /**< 256 bits */ +} aes_key_bits_t; + +/** Encryption algorithms supported */ +typedef enum aead_alg +{ + AES_CCM = 0 /**< Default encryption algorithm supported */ +} aead_alg_t; + +/*=========================================================================== + STRUCTURES AND OTHER TYPEDEFS +=============================================================================*/ + +typedef struct _AEAD { + uint8_t *uch; +} AEAD_t; + +/*=========================================================================== + GLOBAL VARIABLE DECLARATIONS +=============================================================================*/ + +/*=========================================================================== + FUNCTION PROTOTYPES +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/** Converts given digest value to equivalent OpenSSL string + * + * @param[in] hash_alg one of #hash_alg_t + * + * @returns Openssl string corresponding the given hash algorithm in + * @a hash_alg, if @a hash_alg is not valid #HASH_ALG_INVALID + * is returned. + */ +char * +get_digest_name(hash_alg_t hash_alg); + +/** Generate Signature Data + * + * Generates a signature for the given data file, signer certificate, + * hash algorithm and signature format. The signature data is returned + * in a buffer provided by caller. + * + * @param[in] in_file path to file with binary data to sign + * + * @param[in] cert_file path to signer certificate file + * + * @param[in] hash_alg hash algorithm in #hash_alg_t + * + * @param[in] sig_fmt signature format in #sig_fmt_t + * + * @param[out] sig_buf buffer to return signature data + * + * @param[in,out] sig_buf_bytes input size of sig_buf allocated by caller + * output size of signature data returned by API + * + * @post Errors are printed to STDERR + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments + * + * @retval #CAL_INVALID_SIG_DATA_SIZE size insufficient to generate sig data + * + * @retval #CAL_INVALID_ARGUMENT one of the input arguments is invalid + */ +int32_t gen_sig_data(const char* in_file, + const char* cert_file, + hash_alg_t hash_alg, + sig_fmt_t sig_fmt, + uint8_t* sig_buf, + size_t *sig_buf_bytes, + func_mode_t mode); + +/** Generate authenticated encrypted data + * + * API generates authenticated encrypted data for given plain-text data file + * + * @param[in] in_file plaintext, extracted and concatenated as for signing + * + * @param[out] out_file ciphertext (file name is input) + * + * @param[in] aead_alg only AES_CCM supported for now. + * + * @param[out] aad additional authenticated data + * + * @param[in] aad_bytes size of aad (additional authenticated data) + * + * @param[out] nonce nonce bytes to return + * + * @param[in] nonce_bytes size of nonce + * + * @param[out] mac output MAC + * + * @param[in] mac_bytes size of MAC + * + * @param[in] key_bytes size of symmetric key + * + * @param[in] cert_file certificate for DEK (data enctyption key) encryption + * + * @param[out] key_file encrypted symmetric key (file name is input) + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments + * + * @retval #CAL_FAILED_FILE_CREATE the output file cannot be created + * + * @retval #CAL_MAC_LEN_INCORRECT the mac_bytes is not correct + */ +int32_t gen_auth_encrypted_data(const char* in_file, + const char* out_file, + aead_alg_t aead_alg, + uint8_t *aad, + size_t aad_bytes, + uint8_t *nonce, + size_t nonce_bytes, + uint8_t *mac, + size_t mac_bytes, + size_t key_bytes, + const char* cert_file, + const char* key_file, + int reuse_dek); + +/** Computes hash digest from a given input file + * + * This function differs from the generate_hash() function in + * openssl_helper.c in that this function will hash an arbitrary amount of + * data contained in @in_file. The generate_hash expects the data in a + * contigous memory array with the data length already known. + * + * @param[in] in_file Character string holding the input data filename. + * + * @param[in] hash_alg Hash digest algorithm from #hash_alg_t + * + * @param[in,out] buf on input, used to read input data when computing + * hash value, on output holds the resulting hash value. + * + * @param[in,out] pbuf_bytes on input, holds the size of @a buf ib bytes, + * on output pbuf_bytes is updated to hold the size of the + * resulting hash in bytes. + * + * @pre @a in_file, @a buf, and @a pbuf_bytes must not be NULL + * + * @post On success @a buf is updated to hold the hash digest result and + * @a pbuf_bytes is updated to hold the length of the hash in bytes + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_INVALID_ARGUMENTif @a hash_alg contains an unsupported + * algorithm + * + * @retval #CAL_CRYPTO_API_ERROR otherwise + */ +int32_t +calculate_hash(const char *in_file, + hash_alg_t hash_alg, + uint8_t *buf, + int32_t *pbuf_bytes); + +/** Verify Signature Data + * + * Verifies a signature for the given data file, signer certificate, + * hash algorithm and signature format. The signature data is given + * in a buffer provided by caller. + * + * @param[in] in_file path to file with binary data to sign + * + * @param[in] cert_file path to signer certificate file + * + * @param[in] hash_alg hash algorithm in #hash_alg_t + * + * @param[in] sig_fmt signature format in #sig_fmt_t + * + * @param[in] sig_buf buffer to give signature data + * + * @param[in] sig_buf_bytes input size of sig_buf allocated by caller + * + * @post Errors are printed to STDERR + * + * @retval #CAL_SUCCESS API completed its task successfully + * + * @retval #CAL_FILE_NOT_FOUND invalid path in one of the arguments + * + * @retval #CAL_INVALID_SIGNATURE invalid signature + * + * @retval #CAL_INVALID_ARGUMENT one of the input arguments is invalid + */ +int32_t +ver_sig_data(const char *in_file, + const char *cert_file, + hash_alg_t hash_alg, + sig_fmt_t sig_fmt, + uint8_t *sig_buf, + size_t sig_buf_bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* ADAPT_LAYER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/include/openssl_helper.h imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/include/openssl_helper.h --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/include/openssl_helper.h 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/include/openssl_helper.h 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,361 @@ +#ifndef __OPENSSL_HELPER_H +#define __OPENSSL_HELPER_H +/*===========================================================================*/ +/** + @file openssl_helper.h + + @brief Provide helper functions to ease openssl tasks and also defines + common macros that can used across different tools + +@verbatim +============================================================================= + + (c) Freescale Semiconductor, Inc. 2011, 2012. All rights reserved. + Copyright 2020 NXP + +============================================================================= +@endverbatim */ + +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include "adapt_layer.h" +#include +#include +#include + +/*=========================================================================== + CONSTANTS +=============================================================================*/ + +#ifndef TRUE +#define TRUE 1 /**< Success val returned by functions */ +#endif +#ifndef FALSE +#define FALSE 0 /**< Failure val returned by functions */ +#endif + +#define X509_UTCTIME_STRING_BYTES 13 /**< Expected length of validity period + * strings in X.509 certificates using + * UTCTime format + */ +#define X509_GENTIME_STRING_BYTES 15 /**< Expected length of validity period + * strings in X.509 certificates using + * Generalized Time format + */ +#define PEM_FILE_EXTENSION ".pem" /* PEM file extention */ +#define PEM_FILE_EXTENSION_BYTES 4 /* Length of pem extention */ + +/* Message digest string definitions */ +#define HASH_ALG_SHA1 "sha1" /**< String macro for sha1 */ +#define HASH_ALG_SHA256 "sha256" /**< String macro for sha256 */ +#define HASH_ALG_SHA384 "sha384" /**< String macro for sha384 */ +#define HASH_ALG_SHA512 "sha512" /**< String macro for sha512 */ +#define HASH_ALG_INVALID "null" /**< String macro for invalid hash */ + +/* Message digest length definitions */ +#define HASH_BYTES_SHA1 20 /**< Size of SHA1 output bytes */ +#define HASH_BYTES_SHA256 32 /**< Size of SHA256 output bytes */ +#define HASH_BYTES_SHA384 48 /**< Size of SHA384 output bytes */ +#define HASH_BYTES_SHA512 64 /**< Size of SHA512 output bytes */ +#define HASH_BYTES_MAX HASH_BYTES_SHA512 + +/* X509 certificate definitions */ +#define X509_USR_CERT 0x0 /**< User certificate */ +#define X509_CA_CERT 0x1 /**< CA certificate */ + +/*=========================================================================== + CONSTANTS +=============================================================================*/ + +/** Extracts a byte from a given 32 bit word value + * + * @param [in] val value to extract byte from + * + * @param [in] bit_shift Number of bits to shift @a val left before + * extracting the least significant byte + * + * @returns the least significant byte after shifting @a val to the left + * by @a bit_shift bits + */ +#define EXTRACT_BYTE(val, bit_shift) \ + (((val) >> (bit_shift)) & 0xFF) + +/*============================================================================ + ENUMS +=============================================================================*/ + +typedef enum cst_status +{ + CST_FAILURE = FALSE, + CST_SUCCESS = TRUE +} cst_status_t; + +/*============================================================================ + STRUCTURES AND OTHER TYPEDEFS +=============================================================================*/ + +/*============================================================================ + GLOBAL VARIABLE DECLARATIONS +=============================================================================*/ + +/*=========================================================================== + OPENSSL 1.0.2 SUPPORT +=============================================================================*/ + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + +#define OPENSSL_malloc_init CRYPTO_malloc_init +#define X509_get0_notBefore X509_get_notBefore +#define X509_get0_notAfter X509_get_notAfter + +void +ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); + +int +ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +EVP_MD_CTX * +EVP_MD_CTX_new(void); + +EC_KEY * +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); + +RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey); + +void +RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); + +#endif + +/*============================================================================ + FUNCTION PROTOTYPES +=============================================================================*/ + +/** openssl_initialize + * + * Initializes the openssl library. This function must be called once + * by the program using any of the openssl helper functions + * + */ +extern void +openssl_initialize(); + +/** Unix time + * + * Converts the validity time provided in X.509 certificates to Unix time + * required for WTLS certificates. + * + * @param[in] x509_time String with format: YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ + * + * @pre Input X.509 certificate has validity period. + * + * @returns 32 bit time in UNIX format if successful, 0 otherwise + */ +extern uint32_t +unix_time(const char *x509_time); + +/** Computes hash digest + * + * Calls openssl API to generate hash for the given data in buf. + * + * @param[in] buf, binary data for hashing + * + * @param[in] msg_bytes, size in bytes for binary data + * + * @param[in] hash_alg, character string containing hash algorithm, + * "sha1" or "sha256" + * + * @param[out] hash_bytes, size of digest result in bytes + * + * @pre #openssl_initialize has been called previously + * + * @pre @a buf and @a hash_alg are not NULL. + * + * @post It is the responsibilty of the caller to free the memory allocated by + * this function holding the computed hash result. + * + * @returns The location of the digest result if successful, NULL otherwise + */ +extern uint8_t * +generate_hash(const uint8_t *buf, size_t msg_bytes, const char *hash_alg, + size_t *hash_bytes); + +/** get_bn + * + * Extracts data from an openssl BIGNUM type to a byte array. Used + * for extracting certificate data such as an RSA public key modulus. + * + * @param[in] a BIG_NUM structure + * + * @param[out] bytes size of resulting byte array + * + * @pre @a a and @a bytes are not NULL + * + * @post It is the responsibilty of the caller to free the memory allocated by + * this function holding the big number result. + * + * @returns location of resulting byte array or NULL if failed to alloc mem. + */ +extern uint8_t* +get_bn(const BIGNUM *a, size_t *bytes); + + +/** sign_data + * + * Signs a data buffer with a given private key + * + * @param[in] skey signer private key + * + * @param[in] bptr location of data buffer to digitally sign + * + * @param[in] hash_alg hash digest algorithm + * + * @param[out] sig_bytes size of resulting signature buffer + * + * @pre #openssl_initialize has been called previously + * + * @post It is the responsibilty of the caller to free the memory allocated by + * this function holding the signature result. + * + * @returns if successful returns location of resulting byte array otherwise + * NULL. + */ +extern uint8_t* +sign_data(const EVP_PKEY *skey, const BUF_MEM *bptr, hash_alg_t hash_alg, + size_t *sig_bytes); + +/** write_cert_file + * + * Writes WTLS certificate data to a binary file + * + * @param[in] filename filename of WTLS certificate file + * + * @param[in] data WTLS certificate data + * + * @post if successful the contents of the WTLS certificate are written to + * the output file. + * + * @returns if successful function returns #CST_SUCCESS otherwise #CST_FAILURE + */ +extern cst_status_t +write_cert_file(const char *filename, const BIO *wtls_cert); + +/** read_certificate + * + * Read X.509 certificate data from given certificate file + * + * @param[in] filename filename of certificate file + * + * @post if successful the contents of the certificate are extracted to X509 + * object. + * + * @pre #openssl_initialize has been called previously + * + * @post caller is responsible for releasing X.509 certificate memory. + * + * @returns if successful function returns location of X509 object + * otherwise NULL. + */ +extern X509* +read_certificate(const char* filename); + +/** get_der_encoded_certificate_data + * + * Read X.509 certificate data from given certificate file and calls openssl + * to encode X509 to DER format and returns DER formatted data located at + * @derder. + * + * @param[in] filename filename, function will work with both PEM and DER + * input certificate files. + * + * @param[out] der address to write der data + * + * @post if successful the contents of the certificate are written at address + * @a der. + * + * @pre #openssl_initialize has been called previously + * + * @post caller is responsible for releasing memory location returned in @a der + * + * @returns if successful function returns number of bytes written at address + * @a der, 0 otherwise. + */ +extern int32_t get_der_encoded_certificate_data(const char* filename, + uint8_t ** der); + +/** read_private_key + * + * Uses openssl API to read private key from given certificate file + * + * @param[in] filename filename of key file + * + * @param[in] password_cb callback fn to provide password for keyfile + * see openssl's pem.h for callback'e prototype + * + * @param[in] password password for keyfile + * + * @post if successful the contents of the private key are extracted to + * EVP_PKEY object. + * + * @pre #openssl_initialize has been called previously + * + * @post caller is responsible for releasing the private key memory. + * + * @returns if successful function returns location of EVP_PKEY object + * otherwise NULL. + */ +extern EVP_PKEY* +read_private_key(const char *filename, pem_password_cb *password_cb, + const char *password); + +/** seed_prng + * + * Calls openssl API to seed prng to given bytes randomness + * + * @param[in] bytes bytes to randomize the seed + * + * @pre None + * + * @post None + */ +uint32_t seed_prng(uint32_t bytes); + +/** gen_random_bytes + * + * Generates random bytes using openssl RAND_bytes + * + * @param[out] buf buf to return the random bytes + * + * @param[in] bytes size of the buf in bytes and number of random bytes + * to generate + * + * @pre None + * + * @post None + */ +int32_t gen_random_bytes(uint8_t *buf, size_t bytes); + +/** Diplays program license information to stdout + * + * @pre None + * + * @post None + */ +extern void +print_license(void); + +/** Diplays program version information to stdout + * + * @pre None + * + * @post None + */ +extern void +print_version(void); + +#endif /* __OPENSSL_HELPER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/Makefile imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/Makefile --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/Makefile 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,61 @@ +#============================================================================== +# +# File Name: Makefile +# +# General Description: Makefile for engine backend of CST +# +#============================================================================== +# +# Copyright 2020 NXP +# +#============================================================================== + +#============================================================================== +# Compiler/Linker/Archiver Commands +#============================================================================== + +BIN := cst +LIB := libbackend.a +SRC := backend.c openssl_helper.c +DEP = -lssl -lcrypto -ldl -lpthread + +BITNESS := $(shell getconf LONG_BIT) +CFLAGS_32 := -m32 +CFLAGS_64 := -m64 +LDFLAGS_32 := -m32 +LDFLAGS_64 := -m64 + +CC := gcc +CFLAGS := $(CFLAGS_$(BITNESS)) -g -Wall -Werror -Winline -Wl,--export-all-symbols -Iinclude +LDFLAGS = $(LDFLAGS_$(BITNESS)) + +ifeq ($(OS),Windows_NT) +DEP += -lpsapi -lgdi32 + +CFLAGS += -mno-ms-bitfields +endif + +OBJ := $(SRC:.c=.o) +ROOT := ../../.. +FRONTEND := $(ROOT)/linux$(BITNESS)/lib/libfrontend.a + +.PHONY: all +all: $(BIN) + +.PHONY: clean +clean: + -rm -f $(BIN) $(LIB) $(OBJ) + +.PHONY: install +install: $(BIN) + install -d $(PREFIX)/usr/bin + install -m 0755 cst $(PREFIX)/usr/bin/ + +$(BIN): $(FRONTEND) $(LIB) + $(CC) $(LDFLAGS) -o $@ $^ $(DEP) + +$(LIB): $(OBJ) + ar rcs $@ $^ + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/openssl_helper.c imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/openssl_helper.c --- imx-code-signing-tool-3.3.0+dfsg2/code/back_end-engine/src/openssl_helper.c 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/back_end-engine/src/openssl_helper.c 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: BSD-2-Clause +/** + @file openssl_helper.c + + @brief Provide functions to backward support OpenSSL 1.0.2. + +@verbatim +============================================================================= + + Copyright 2020 NXP + +============================================================================= +@endverbatim */ + +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include +#include +#include +#include +#include + +/*=========================================================================== + FUNCTIONS +=============================================================================*/ + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + +static void * +OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) { + memset(ret, 0, num); + } + return ret; +} + +void +ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) { + *pr = sig->r; + } + if (ps != NULL) { + *ps = sig->s; + } +} + +int +ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) { + return 0; + } + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +EC_KEY * +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +{ + return (pkey->pkey.ec); +} + +RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} + +void +RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) { + *n = r->n; + } + if (e != NULL) { + *e = r->e; + } + if (d != NULL) { + *d = r->d; + } +} + +#endif + +/*=========================================================================== + GLOBAL FUNCTIONS +=============================================================================*/ + +/*-------------------------- + openssl_initialize +---------------------------*/ + +void +openssl_initialize(void) +{ +#if defined _WIN32 || defined __CYGWIN__ + /* Required to avoid OpenSSL runtime errors on Win32 platforms */ + /* See: https://www.openssl.org/docs/faq.html#PROG3 */ + OPENSSL_malloc_init(); +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#endif +} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/back_end/src/adapt_layer_openssl.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/back_end/src/adapt_layer_openssl.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/back_end/src/adapt_layer_openssl.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/back_end/src/adapt_layer_openssl.c 2021-08-12 12:53:52.000000000 +0000 @@ -12,7 +12,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018 NXP + Copyright 2018, 2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -61,6 +61,7 @@ #include "adapt_layer.h" #include "openssl_helper.h" #include "pkey.h" +#include "csf.h" #if (defined _WIN32 || defined __CYGWIN__) && defined USE_APPLINK #include #endif @@ -257,11 +258,11 @@ /*=========================================================================== GLOBAL VARIABLES =============================================================================*/ +extern int g_dummy_csf_data_generated; /*=========================================================================== LOCAL FUNCTIONS =============================================================================*/ - /*-------------------------- get_NID ---------------------------*/ @@ -286,7 +287,7 @@ uint8_t *rsa_in = NULL; /**< Mem ptr for hash data of in_file */ uint8_t *rsa_out = NULL; /**< Mem ptr for encrypted data */ int32_t rsa_inbytes; /**< Holds the length of rsa_in buf */ - int32_t rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ + unsigned int rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ int32_t key_bytes; /**< Size of key data */ int32_t hash_nid; /**< hash id needed for RSA_sign() */ /** Array to hold error string */ @@ -513,7 +514,7 @@ { BIO *bio_in = NULL; /**< BIO for in_file data */ EVP_PKEY *key = NULL; /**< Private key data */ - uint32_t key_size = 0; /**< n of bytes of key param */ + size_t key_size = 0; /**< n of bytes of key param */ const EVP_MD *sign_md = NULL; /**< Digest name */ uint8_t *hash = NULL; /**< Hash data of in_file */ int32_t hash_bytes = 0; /**< Length of hash buffer */ @@ -632,6 +633,144 @@ } /*-------------------------- + calculate_sig_buf_size +---------------------------*/ +#define SIG_BUF_FIXED_DATA_SIZE 217 + +int32_t +calculate_sig_buf_size(const char *cert_file) { + X509 *cert; + EVP_PKEY *public_key; + RSA *rsa_key; + int key_length = 0; + ASN1_INTEGER *serial_num; + int sn_length = 0; + char *issuer_name; + int issuer_name_length = 0; + + /* Calculate Signature Size for padding purposes in CSF binary: + * It has been experimentally evalutated and noted that the variables in + * signature size is related to three entries in the CMS format. This is + * only considering signatures from the keys created from the CST PKI + * scripts. + * + * The fixed size of the CMS structure was experimentally + * determined to be 217 bytes. + * + * The three entries that appear to alter the size: + * Serial Number (SN) + * CA Certificate Name + * RSA Encryption (this size is equal to key size in bytes) + * + * Given the above the current approach to calculating the signature size: + * + * + + + + */ + /* Gather Signing Key Details */ + cert = read_certificate(cert_file); + public_key = X509_get_pubkey(cert); + rsa_key = EVP_PKEY_get1_RSA(public_key); + key_length = RSA_size(rsa_key); + serial_num = X509_get_serialNumber(cert); + sn_length = serial_num->length; + issuer_name = X509_NAME_oneline(X509_get_issuer_name(cert),NULL, 0); + issuer_name_length = strlen(issuer_name); + + return (SIG_BUF_FIXED_DATA_SIZE + key_length + sn_length + issuer_name_length); +} + +/*-------------------------- + export_habv4_signature_request +---------------------------*/ +int32_t +export_habv4_signature_request(const char *in_file, + const char *cert_file, + uint8_t *sig_buf, + size_t *sig_buf_bytes) +{ + FILE *sig_req_fp = NULL; + int unique_ident[2]; + + if(g_dummy_csf_data_generated == 1) + { + FILE *in_file_fp = NULL; + FILE *cpy_data_fp = NULL; + char tmp_filename[80]; + int in_data_size = 0; + + /* Open data file */ + if(!(in_file_fp = fopen(in_file, "rb"))) + { + printf("Unable to open tmp data file\n"); + return -1; + } + + /* Determine the data file size */ + if(fseek(in_file_fp,0L,SEEK_END) == -1) + { + printf("Unable to get in_data filesize\n"); + fclose(in_file_fp); + return -1; + } + if ((in_data_size = ftell(in_file_fp)) < 0) { + printf("Unable to get in_data filesize\n"); + fclose(in_file_fp); + return -1; + } + + /* Set the fp to the beginning of the data file */ + rewind(in_file_fp); + + /* Create the output data file name */ + strcpy(tmp_filename,"data_"); + strcat(tmp_filename,in_file); + + /* Copy the data file to the output data file */ + cpy_data_fp = fopen(tmp_filename, "w"); + + while (in_data_size--) + { + char tmp; + tmp = fgetc(in_file_fp); // copying file character by character + fputc(tmp, cpy_data_fp); + } + + /* Create unique identifier */ + unique_ident[0] = rand(); + unique_ident[1] = rand(); + + /* Add entry to signing request file for new data file */ + sig_req_fp = fopen("sig_request.txt", "a"); + fseek(sig_req_fp, 0L, SEEK_END); + fprintf(sig_req_fp,"Signing Request:\n"); + fprintf(sig_req_fp,"%s\n", cert_file); + fprintf(sig_req_fp,"%s\n", tmp_filename); + fprintf(sig_req_fp,"unique tag: %08x%08x\n",unique_ident[1], unique_ident[0]); + + /* Close all files */ + fclose(in_file_fp); + fclose(cpy_data_fp); + fclose(sig_req_fp); + } else { + /* Seed rand() to generate unique data tags on the next pass */ + srand(time(0)); + + /* Ensure any data in the digest file is cleared. */ + if((sig_req_fp = fopen("sig_request.txt", "w"))) + { + fclose(sig_req_fp); + } + } + + *sig_buf_bytes = calculate_sig_buf_size(cert_file); + + memset(sig_buf, 0, *sig_buf_bytes); + memcpy(sig_buf, unique_ident, sizeof(unique_ident) ); + + return 0; +} + +/*-------------------------- export_signature_request ---------------------------*/ int32_t export_signature_request(const char *in_file, @@ -697,7 +836,12 @@ if (MODE_HSM == mode) { - return export_signature_request(in_file, cert_file); + if ( TGT_AHAB == g_target ) { + return export_signature_request(in_file, cert_file); + } else if ( TGT_HAB == g_target ) { + return export_habv4_signature_request(in_file, cert_file, + sig_buf, sig_buf_bytes); + } } /* Determine private key filename from given certificate filename */ @@ -731,6 +875,36 @@ return err; } +/*-------------------------------- + get_der_encoded_certificate_data +----------------------------------*/ +int32_t get_der_encoded_certificate_data(const char* reference, + uint8_t ** der) +{ + /** Used for returning either size of der data or 0 to indicate an error */ + int32_t ret_val = 0; + + /* Read X509 certificate data from cert file */ + X509 *cert = read_certificate(reference); + + if (cert != NULL) + { + /* i2d_X509() allocates memory for der data, converts the X509 + * cert structure to binary der formatted data. It then + * returns the address of the memory allocated for the der data + */ + ret_val = i2d_X509(cert, der); + + /* On error return 0 */ + if (ret_val < 0) + { + ret_val = 0; + } + X509_free(cert); + } + return ret_val; +} + /*-------------------------- generate_dek_key ---------------------------*/ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/back_end/src/ssl_wrapper.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/back_end/src/ssl_wrapper.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/back_end/src/ssl_wrapper.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/back_end/src/ssl_wrapper.c 2021-08-12 12:53:52.000000000 +0000 @@ -10,7 +10,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018-2019 NXP + Copyright 2018-2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -73,7 +73,7 @@ EVP_CIPHER_CTX *ctx; int len; - int ciphertext_len; + size_t ciphertext_len; unsigned char *ciphertext = NULL; ciphertext = (unsigned char *)malloc(plaintext_len + EVP_MAX_BLOCK_LENGTH); @@ -202,7 +202,8 @@ return CAL_NO_CRYPTO_API_ERROR; #else EVP_CIPHER_CTX *ctx; - int len, ciphertext_len; + int len; + size_t ciphertext_len; unsigned char *ciphertext = NULL; ciphertext = (unsigned char *)malloc(plaintext_len); if (NULL == ciphertext) { diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/binaries.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/binaries.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/binaries.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/binaries.mk 2021-08-12 12:53:52.000000000 +0000 @@ -9,7 +9,7 @@ # # Freescale Semiconductor # (c) Freescale Semiconductor, Inc. 2011-2015 All rights reserved. -# Copyright 2018-2019 NXP +# Copyright 2018-2020 NXP # # #=============================================================================== @@ -52,9 +52,6 @@ #=============================================================================== all: build -# Libraries to be released and where -LIBRARIES := $(DST)/$(OSTYPE)/lib/$(LIB_FRONTEND) - # Executables to be released and where EXECUTABLES := $(DST)/$(OSTYPE)/bin/$(EXE_SRKTOOL) EXECUTABLES += $(DST)/$(OSTYPE)/bin/$(EXE_CST) @@ -63,15 +60,11 @@ EXECUTABLES += $(DST)/keys/$(EXE_CONVLB) endif -BUILDS := $(LIBRARIES) $(EXECUTABLES) +BUILDS := $(EXECUTABLES) build: $(notdir $(BUILDS)) -rel_bin: rel_lib rel_exe - -rel_lib: $(notdir $(LIBRARIES)) - @echo "Copy libraries" - $(foreach LIB,$(LIBRARIES),$(CP) $(notdir $(LIB)) $(LIB) ;) +rel_bin: rel_exe rel_exe: $(notdir $(EXECUTABLES)) @echo "Copy executables" diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/linux32.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/linux32.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/linux32.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/linux32.mk 2021-08-12 12:53:52.000000000 +0000 @@ -9,13 +9,13 @@ # # Freescale Semiconductor # (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. -# Copyright 2018-2019 NXP +# Copyright 2018-2020 NXP # # #============================================================================== -ifneq ($(ENCRYPTION), yes) +ifeq ($(ENCRYPTION), no) CDEFINES := -DREMOVE_ENCRYPTION endif -OPENSSL_CONFIG := linux-generic32 +OPENSSL_CONFIG := linux-x86 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/linux64.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/linux64.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/linux64.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/linux64.mk 2021-08-12 12:53:52.000000000 +0000 @@ -9,12 +9,12 @@ # # Freescale Semiconductor # (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. -# Copyright 2018 NXP +# Copyright 2018, 2020 NXP # # #============================================================================== -ifneq ($(ENCRYPTION), yes) +ifeq ($(ENCRYPTION), no) CDEFINES := -DREMOVE_ENCRYPTION endif diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/mingw32.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/mingw32.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/mingw32.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/mingw32.mk 2021-08-12 12:53:52.000000000 +0000 @@ -9,7 +9,7 @@ # # Freescale Semiconductor # (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. -# Copyright 2018 NXP +# Copyright 2018, 2020 NXP # # #============================================================================== @@ -17,7 +17,7 @@ # Define -mno-ms-bitfields to get correct bit-field layout of packed structs EXTRACFLAGS += -mno-ms-bitfields -ifneq ($(ENCRYPTION), yes) +ifeq ($(ENCRYPTION), no) CDEFINES := -DREMOVE_ENCRYPTION -DUSE_APPLINK endif diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/osx.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/osx.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/build/make/osx.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/build/make/osx.mk 2021-08-12 12:53:52.000000000 +0000 @@ -7,12 +7,12 @@ # #============================================================================== # -# Copyright 2019 NXP +# Copyright 2019-2020 NXP # # #============================================================================== -ifneq ($(ENCRYPTION), yes) +ifeq ($(ENCRYPTION), no) CDEFINES := -DREMOVE_ENCRYPTION endif diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/hdr/openssl_helper.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/hdr/openssl_helper.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/hdr/openssl_helper.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/hdr/openssl_helper.h 2021-08-12 12:53:52.000000000 +0000 @@ -254,30 +254,6 @@ extern X509* read_certificate(const char* filename); -/** get_der_encoded_certificate_data - * - * Read X.509 certificate data from given certificate file and calls openssl - * to encode X509 to DER format and returns DER formatted data located at - * @derder. - * - * @param[in] filename filename, function will work with both PEM and DER - * input certificate files. - * - * @param[out] der address to write der data - * - * @post if successful the contents of the certificate are written at address - * @a der. - * - * @pre #openssl_initialize has been called previously - * - * @post caller is responsible for releasing memory location returned in @a der - * - * @returns if successful function returns number of bytes written at address - * @a der, 0 otherwise. - */ -extern int32_t get_der_encoded_certificate_data(const char* filename, - uint8_t ** der); - /** read_private_key * * Uses openssl API to read private key from given certificate file diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/hdr/version.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/hdr/version.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/hdr/version.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/hdr/version.h 2021-08-12 12:53:52.000000000 +0000 @@ -11,7 +11,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018 NXP + Copyright 2018,2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -39,6 +39,6 @@ ============================================================================= @endverbatim */ -#define CST_VERSION "3.2.0" +#define CST_VERSION "3.3.1" #endif /* __VERSION_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/src/objects.mk imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/src/objects.mk --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/src/objects.mk 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/src/objects.mk 2021-08-12 12:53:52.000000000 +0000 @@ -10,7 +10,7 @@ # # Freescale Semiconductor # (c) Freescale Semiconductor, Inc. 2011. All rights reserved. -# Copyright 2018 NXP +# Copyright 2018, 2020 NXP # # #============================================================================== @@ -29,4 +29,5 @@ OBJECTS_FRONTEND += \ openssl_helper.o \ srk_helper.o \ + misc_helper.o \ err.o diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/src/openssl_helper.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/src/openssl_helper.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/common/src/openssl_helper.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/common/src/openssl_helper.c 2021-08-12 12:53:52.000000000 +0000 @@ -349,36 +349,6 @@ return cert; } -/*-------------------------------- - get_der_encoded_certificate_data -----------------------------------*/ -int32_t get_der_encoded_certificate_data(const char* filename, - uint8_t ** der) -{ - /** Used for returning either size of der data or 0 to indicate an error */ - int32_t ret_val = 0; - - /* Read X509 certificate data from cert file */ - X509 *cert = read_certificate(filename); - - if (cert != NULL) - { - /* i2d_X509() allocates memory for der data, converts the X509 - * cert structure to binary der formatted data. It then - * returns the address of the memory allocated for the der data - */ - ret_val = i2d_X509(cert, der); - - /* On error return 0 */ - if (ret_val < 0) - { - ret_val = 0; - } - X509_free(cert); - } - return ret_val; -} - /*-------------------------- read_private_key ---------------------------*/ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/adapt_layer.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/adapt_layer.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/adapt_layer.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/adapt_layer.h 2021-08-12 12:53:52.000000000 +0000 @@ -189,6 +189,29 @@ size_t *sig_buf_bytes, func_mode_t mode); +/** get_der_encoded_certificate_data + * + * Read X.509 certificate data from given certificate reference and encode it + * to DER format and returns result in @derder. + * + * @param[in] filename filename, function will work with both PEM and DER + * input certificate files. + * + * @param[out] der address to write der data + * + * @post if successful the contents of the certificate are written at address + * @a der. + * + * @pre #openssl_initialize has been called previously + * + * @post caller is responsible for releasing memory location returned in @a der + * + * @returns if successful function returns number of bytes written at address + * @a der, 0 otherwise. + */ +int32_t get_der_encoded_certificate_data(const char* reference, + uint8_t ** der); + /** Generate authenticated encrypted data * * API generates authenticated encrypted data for given plain-text data file diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/ahab_types.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/ahab_types.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/ahab_types.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/ahab_types.h 2021-08-12 12:53:52.000000000 +0000 @@ -129,7 +129,7 @@ get_ahab_image_array(struct ahab_container_header_s *header) { return (struct ahab_container_image_s *)(uintptr_t) - ((uint32_t)(uintptr_t) header + sizeof(struct ahab_container_header_s)); + ((uintptr_t) header + sizeof(struct ahab_container_header_s)); } #define HEADER_FLAGS_SRK_SET_SHIFT 0 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/csf.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/csf.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/csf.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/csf.h 2021-08-12 12:53:52.000000000 +0000 @@ -11,7 +11,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015 All rights reserved. - Copyright 2018-2019 NXP + Copyright 2018-2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -108,6 +108,34 @@ /**< Max. nonce bytes in 16B AES blk */ #define MAX_NONCE_BYTES (13) +/** Min and Max key indexes for source/verification/target indexes */ +#define VFY_IDX_INS_KEY_SRK (0) +#define VFY_IDX_INS_KEY_MIN (2) +#define VFY_IDX_INS_KEY_MAX (4) +#define SRC_IDX_INS_KEY_MIN (0) +#define SRC_IDX_INS_KEY_MAX (3) +#define VFY_IDX_AUT_DAT_FAST_AUTH (0) +#define VFY_IDX_AUT_DAT_MIN (2) +#define VFY_IDX_AUT_DAT_MAX (5) + +/** SRK Table offsets */ +#define SRK_TABLE_TAG_OFFSET 0 +#define SRK_TABLE_VER_OFFSET 3 + +#define ERR_IF_INIT_MULT_TIMES(flag) \ + if (flag) \ + { \ + log_arg_cmd(arg->type, " argument already specified", cmd->type);\ + return ERROR_INVALID_ARGUMENT; \ + } \ + flag = true + +#define ERR_IF_UNS_ARG(flag, arg) \ + if (flag) \ + { \ + log_arg_cmd(arg, STR_ILLEGAL, cmd->type); \ + return ERROR_UNSUPPORTED_ARGUMENT; \ + } /*=========================================================================== TYPEDEFS =============================================================================*/ @@ -384,7 +412,7 @@ /* Creates signature data file for the given data */ extern int32_t create_sig_file(char *file, char *cert_file, sig_fmt_t sig_fmt, uint8_t *data, - uint32_t data_size); + size_t data_size); /* Called by parser on each command */ extern int32_t handle_command(command_t *cmd); diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/hab_cmd.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/hab_cmd.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/hab_cmd.h 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/hab_cmd.h 2021-08-12 12:53:52.000000000 +0000 @@ -273,6 +273,7 @@ #define INS_KEY_BASE_BYTES 12 +#if 0 /* * Install Key (SRK) */ @@ -294,6 +295,7 @@ (crt)) #define INS_CSFK_BYTES INS_KEY_BASE_BYTES +#endif /* * Install Key (IMGK - no hash) @@ -356,9 +358,9 @@ * Authenticate Data (CSF) */ -#define AUT_CSF(flg, pcl, eng, cfg, sig_start) \ +#define AUT_CSF(flg, pcl, eng, cfg, sig_start, csfk_idx) \ AUT_DAT(AUT_CSF_BYTES, (flg), \ - HAB_IDX_CSFK, (pcl), (eng), (cfg), \ + (csfk_idx), (pcl), (eng), (cfg), \ (sig_start)) #define AUT_CSF_BYTES AUT_DAT_BASE_BYTES diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/misc_helper.h imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/misc_helper.h --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/hdr/misc_helper.h 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/hdr/misc_helper.h 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,88 @@ +#ifndef MISC_HELPER_H +#define MISC_HELPER_H +/*===========================================================================*/ +/** + @file misc_helper.h + + @brief Provide miscellaneous helper functions + +@verbatim +============================================================================= + + Copyright 2020 NXP + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================= +@endverbatim */ + +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include "csf.h" + +/*=========================================================================== + STRUCTURES AND OTHER TYPEDEFS +=============================================================================*/ +/** Byte string + * + * Defines the byte string struct + */ +typedef struct byte_str_s +{ + uint8_t *entry; + size_t entry_bytes; +} byte_str_t; + +/*=========================================================================== + FUNCTION PROTOTYPES +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/** Read bytes from a file + * + * Reads an amount of bytes from an input file + * + * @param[in] filename Input file name to be read + * + * @param[out] byte_str Byte string struct to return the read data + * + * @param[in] offsets If defined, + * + * @pre @a filename and @a offsets must not be NULL + * + * @post none + * + * @returns the size of memory allocated point to by byte_str + */ +void +read_file(const char *filename, byte_str_t *byte_str, offsets_t *offsets); + +#ifdef __cplusplus +} +#endif + +#endif /* MISC_HELPER_H */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/acst.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/acst.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/acst.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/acst.c 2021-08-12 12:53:52.000000000 +0000 @@ -9,7 +9,7 @@ @verbatim ============================================================================= - Copyright 2018-2019 NXP + Copyright 2018-2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -45,7 +45,7 @@ #include #include "err.h" #include "srk_helper.h" -#include "csf.h" +#include "misc_helper.h" /*=========================================================================== LOCAL CONSTANTS @@ -61,15 +61,6 @@ /*=========================================================================== LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) =============================================================================*/ -/** Byte string - * - * Defines the byte string struct - */ -typedef struct byte_str_s -{ - uint8_t *entry; - size_t entry_bytes; -} byte_str_t; /*=========================================================================== LOCAL VARIABLES @@ -79,23 +70,6 @@ /*=========================================================================== LOCAL FUNCTION PROTOTYPES =============================================================================*/ -/** Read bytes from a file - * - * Reads an amount of bytes from an input file - * - * @param[in] filename Input file name to be read - * - * @param[out] byte_str Byte string struct to return the read data - * - * @param[in] offsets If defined, - * - * @pre @a filename and @a offsets must not be NULL - * - * @post none - */ -static void -read_file(const char *filename, byte_str_t *byte_str, offsets_t *offsets); - /** Retrieve hash algo * * Reads an SRK table to retrieve the hash algo information @@ -211,71 +185,6 @@ /*=========================================================================== LOCAL FUNCTIONS =============================================================================*/ - -/*-------------------------- - read_file ----------------------------*/ -void read_file(const char *filename, byte_str_t *byte_str, offsets_t *offsets) -{ - FILE *file = NULL; - uint32_t bytes_to_read, read_size; - - /* Open the source file */ - file = fopen(filename, "rb"); - if (NULL == file) - { - snprintf(err_msg, MAX_ERR_MSG_BYTES, "Cannot open %s", filename); - error(err_msg); - } - - /* Get the file size */ - fseek(file, 0, SEEK_END); - bytes_to_read = ftell(file); - rewind(file); - - /* If some offsets are specified, refine the number of bytes to be read */ - if (NULL != offsets) - { - if ((bytes_to_read < offsets->first) - || (bytes_to_read < offsets->second)) - { - snprintf(err_msg, - MAX_ERR_MSG_BYTES, - "Offsets defined outside the file %s", - filename); - error(err_msg); - } - - if (offsets->first > offsets->second) - { - error("Incorrect offsets"); - } - - bytes_to_read = offsets->second - offsets->first; - - fseek(file, offsets->first, SEEK_SET); - } - - /* Save the file data */ - byte_str->entry_bytes = bytes_to_read; - byte_str->entry = malloc(bytes_to_read); - if (NULL == byte_str->entry) - { - snprintf(err_msg, MAX_ERR_MSG_BYTES, "Cannot allocate memory for handling %s", filename); - error(err_msg); - } - memset(byte_str->entry, 0, bytes_to_read); - read_size = fread(byte_str->entry, 1, bytes_to_read, file); - - if (read_size != bytes_to_read) - { - snprintf(err_msg, MAX_ERR_MSG_BYTES, "Unexpected read termination of %s", filename); - error(err_msg); - } - - fclose(file); -} - /*-------------------------- ahab_hash_2_cst_hash ---------------------------*/ @@ -788,16 +697,17 @@ uint8_t hash_type = ahab_container_image_get_hash(image); int32_t hash_size = ahab_get_hash_size_by_sha_type(hash_type); + + if (hash_size < 0) { + error("Unsupported hash algorithm for image integrity"); + } + uint8_t *hash = malloc(hash_size); if (NULL == hash) { error("Cannot allocate memory for the hash value of the plaintext"); } - if (hash_size < 0) { - error("Unsupported hash algorithm for image integrity"); - } - /* Retrieve image data */ offsets_t offsets = { @@ -887,7 +797,7 @@ get_digest_name(ahab_hash_2_cst_hash(hash_type)), &digest_size); - if (digest_size != hash_size) { + if (digest_size != (size_t)hash_size) { error("Fail to generate hash of encrypted data of image index %d", i); } diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_aut_dat.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_aut_dat.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_aut_dat.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_aut_dat.c 2021-08-12 12:53:52.000000000 +0000 @@ -10,7 +10,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018-2019 NXP + Copyright 2018-2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -90,6 +90,8 @@ const char * out_file); int g_no_ca = 0; +int32_t g_srk_set_hab4 = SRK_SET_OEM; +int g_dummy_csf_data_generated = 0; /*=========================================================================== LOCAL FUNCTION DEFINITIONS =============================================================================*/ @@ -132,6 +134,15 @@ uint32_t i; /**< Loop index */ argument_t *arg = cmd->argument; /**< Ptr to argument_t */ + bool flag_vfy_idx = false; + bool flag_eng = false; + bool flag_eng_cfg = false; + bool flag_sig_fmt = false; + bool flag_hsh_alg = false; + bool flag_mac = false; + bool flag_fname = false; + bool flag_offset = false; + for(i=0; iargument_count; i++) { switch((arguments_t)arg->type) @@ -146,6 +157,7 @@ } break; case VerificationIndex: + ERR_IF_INIT_MULT_TIMES(flag_vfy_idx); if(vfy_index != NULL) *vfy_index = arg->value.number->num_value; else @@ -155,6 +167,7 @@ } break; case EngineName: + ERR_IF_INIT_MULT_TIMES(flag_eng); if(engine != NULL) *engine = arg->value.keyword->unsigned_value; else @@ -164,6 +177,7 @@ } break; case EngineConfiguration: + ERR_IF_INIT_MULT_TIMES(flag_eng_cfg); if(engine_cfg != NULL) { /* Engine configuration could be number or keyword */ @@ -179,6 +193,7 @@ } break; case SignatureFormat: + ERR_IF_INIT_MULT_TIMES(flag_sig_fmt); if(sig_format != NULL) *sig_format = arg->value.keyword->unsigned_value; else @@ -188,6 +203,7 @@ } break; case HashAlgorithm: + ERR_IF_INIT_MULT_TIMES(flag_hsh_alg); if(hash_alg != NULL) *hash_alg = arg->value.keyword->unsigned_value; else @@ -197,6 +213,7 @@ } break; case MacBytes: + ERR_IF_INIT_MULT_TIMES(flag_mac); if(mac_bytes != NULL) { *mac_bytes = arg->value.number->num_value; @@ -208,6 +225,7 @@ } break; case Filename: + ERR_IF_INIT_MULT_TIMES(flag_fname); if(src != NULL) *src = arg->value.keyword->string_value; else @@ -217,6 +235,7 @@ } break; case Offsets: + ERR_IF_INIT_MULT_TIMES(flag_offset); if(offsets != NULL) { offsets->first = arg->value.pair->first; @@ -327,6 +346,10 @@ int32_t engine = -1; /**< Holds engine argument value */ int32_t engine_cfg = -1; /**< Holds engine configuration arg value */ + uint32_t csfk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_CSFK : HAB_IDX_CSFK1; + + printf("Authenticate CSF\n"); + /* The Authenticate CSF command is invalid when AHAB is targeted */ if (TGT_AHAB == g_target) { @@ -334,6 +357,11 @@ return ERROR_INVALID_COMMAND; } + /* Adjust CSFK index if NOCAK */ + if ( g_no_ca == 1 ) { + csfk_idx = HAB_IDX_CSFK; + } + /* get the arguments */ ret_val = process_authenticatedata_arguments(cmd, NULL, NULL, &engine, &engine_cfg, &sig_format, NULL, NULL, NULL, NULL, NULL); @@ -391,7 +419,7 @@ uint8_t aut_csf[] = { AUT_CSF(HAB_CMD_AUT_DAT_CLR, (SIG_FMT_CMS == sig_format) ? HAB_PCL_CMS : HAB_ALG_PKCS1, - engine, engine_cfg, 0) + engine, engine_cfg, 0, csfk_idx) }; /**< Macro will output authenticate csf command bytes in aut_csf buffer */ @@ -407,7 +435,7 @@ * Dummy signature for now, will be regenerated once csf processing * is completed. Required to advance g_csf_buffer_index. */ - ret_val = create_sig_file(FILE_SIG_CSF_DATA, g_key_certs[HAB_IDX_CSFK], + ret_val = create_sig_file(FILE_SIG_CSF_DATA, g_key_certs[csfk_idx], (g_hab_version >= HAB4) ? SIG_FMT_CMS : SIG_FMT_PKCS1, g_csf_buffer, HAB_CSF_BYTES_MAX); if(ret_val != SUCCESS) @@ -427,6 +455,12 @@ } } while(0); + /* The initial call to this function is only to generated dummy data as a + place holder in the CSF output. Set the global flag to indicate the + dummy CSF data has been generated. This is used to prevent the dummy data + from being included in the digest data to be sent to an offline signer. */ + g_dummy_csf_data_generated = 1; + return ret_val; } @@ -554,6 +588,16 @@ FILE * fh = NULL; /**< File pointer to open and read block data from binary files */ + uint32_t srk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_SRK : HAB_IDX_SRK1; + uint32_t csfk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_CSFK : HAB_IDX_CSFK1; + + printf("Authenticate data\n"); + + /* Adjust CSFK index if NOCAK */ + if (g_no_ca == 1) { + csfk_idx = HAB_IDX_CSFK; + } + /* get the arguments */ if (TGT_AHAB == g_target) { @@ -622,7 +666,7 @@ if(g_hab_version >= HAB4) { /* validate the arguments */ - if(vfy_index == HAB_IDX_SRK) + if(vfy_index == srk_idx) { if (g_no_ca == 0) { @@ -632,7 +676,15 @@ break; } } - if(vfy_index == HAB_IDX_CSFK) + if(vfy_index == csfk_idx) + { + log_arg_cmd(VerificationIndex, NULL, cmd->type); + + ret_val = ERROR_INVALID_ARGUMENT; + break; + } + if((vfy_index != VFY_IDX_AUT_DAT_FAST_AUTH) && \ + (vfy_index < VFY_IDX_AUT_DAT_MIN || vfy_index > VFY_IDX_AUT_DAT_MAX)) { log_arg_cmd(VerificationIndex, NULL, cmd->type); @@ -696,7 +748,7 @@ } else { - cert_file = g_key_certs[HAB_IDX_CSFK]; + cert_file = g_key_certs[csfk_idx]; } /* Get the total size for the blocks data and allocate memory */ offset_in_data = 0; @@ -1128,7 +1180,7 @@ int32_t engine = -1; /**< Holds engine argument value */ int32_t engine_cfg = -1; /**< Holds engine config argument value */ int32_t vfy_index = -1; /**< Holds verify index argument value */ - int32_t mac_bytes = -1; /**< Holds MAC length argument value */ + ssize_t mac_bytes = -1; /**< Holds MAC length argument value */ block_t *block = NULL; /**< Holds address of block list argument */ block_t *tmpblock = NULL; /**< Holds address of block list argument */ size_t blocks_data_size=0; /**< Bytes occupied by block data in cmd */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_ins_key.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_ins_key.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_ins_key.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_ins_key.c 2021-08-12 12:53:52.000000000 +0000 @@ -10,7 +10,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018 NXP + Copyright 2018, 2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -48,7 +48,6 @@ #include #define HAB_FUTURE #include -#include #include #include #include @@ -56,6 +55,7 @@ #include #include #include +#include /*=========================================================================== MACROS =============================================================================*/ @@ -78,6 +78,9 @@ uint32_t blob_address, uint8_t *buf, int32_t *cmd_len); extern int g_no_ca; + +extern int32_t g_srk_set_hab4; + /*=========================================================================== LOCAL FUNCTION DEFINITIONS =============================================================================*/ @@ -122,11 +125,28 @@ uint32_t i; /**< Loop index */ argument_t *arg = cmd->argument; /**< Ptr to argument_t */ + bool flag_fname = false; + bool flag_src_vfy_idx = false; + bool flag_tgt_idx = false; + bool flag_hsh_alg = false; + bool flag_crt_fmt = false; + bool flag_key = false; + bool flag_key_len = false; + bool flag_blob = false; + bool flag_src = false; + bool flag_perm = false; + bool flag_sig = false; + bool flag_src_set = false; + bool flag_revoc = false; + bool flag_key_id = false; + bool flag_img_idx = false; + for(i=0; iargument_count; i++) { switch((arguments_t)arg->type) { case Filename: + ERR_IF_INIT_MULT_TIMES(flag_fname); if(cert_file != NULL) *cert_file = arg->value.keyword->string_value; else @@ -137,6 +157,7 @@ break; case SourceIndex: case VerificationIndex: + ERR_IF_INIT_MULT_TIMES(flag_src_vfy_idx); if(src_index != NULL) *src_index = arg->value.number->num_value; else @@ -146,6 +167,7 @@ } break; case TargetIndex: + ERR_IF_INIT_MULT_TIMES(flag_tgt_idx); if(tgt_index != NULL) *tgt_index = arg->value.number->num_value; else @@ -155,6 +177,7 @@ } break; case HashAlgorithm: + ERR_IF_INIT_MULT_TIMES(flag_hsh_alg); if(hash_alg != NULL) *hash_alg = arg->value.keyword->unsigned_value; else @@ -164,6 +187,7 @@ } break; case CertificateFormat: + ERR_IF_INIT_MULT_TIMES(flag_crt_fmt); if (cert_format != NULL) *cert_format = arg->value.keyword->unsigned_value; else @@ -173,6 +197,7 @@ } break; case Key: + ERR_IF_INIT_MULT_TIMES(flag_key); if(key_file != NULL) { *key_file = arg->value.keyword->string_value; @@ -184,6 +209,7 @@ } break; case KeyLength: + ERR_IF_INIT_MULT_TIMES(flag_key_len); if (key_length != NULL) { *key_length = arg->value.number->num_value; @@ -195,6 +221,7 @@ } break; case BlobAddress: + ERR_IF_INIT_MULT_TIMES(flag_blob); if (blob_address != NULL) { *blob_address = arg->value.number->num_value; @@ -206,6 +233,7 @@ } break; case Source: + ERR_IF_INIT_MULT_TIMES(flag_src); if(src != NULL) *src = arg->value.keyword->string_value; else @@ -215,6 +243,7 @@ } break; case Permissions: + ERR_IF_INIT_MULT_TIMES(flag_perm); if (perm != NULL) { *perm = arg->value.number->num_value; @@ -226,6 +255,7 @@ } break; case Signature: + ERR_IF_INIT_MULT_TIMES(flag_sig); if(sign != NULL) *sign = arg->value.keyword->string_value; else @@ -235,6 +265,7 @@ } break; case SourceSet: + ERR_IF_INIT_MULT_TIMES(flag_src_set); if (src_set != NULL) { *src_set = arg->value.keyword->unsigned_value; @@ -246,6 +277,7 @@ } break; case Revocations: + ERR_IF_INIT_MULT_TIMES(flag_revoc); if (revocations != NULL) { *revocations = arg->value.number->num_value; @@ -257,6 +289,7 @@ } break; case KeyIdentifier: + ERR_IF_INIT_MULT_TIMES(flag_key_id); if (key_identifier != NULL) { *key_identifier = arg->value.number->num_value; @@ -268,6 +301,7 @@ } break; case ImageIndexes: + ERR_IF_INIT_MULT_TIMES(flag_img_idx); if (image_indexes != NULL) { *image_indexes = arg->value.number->num_value; @@ -326,7 +360,7 @@ int32_t flag = HAB_CMD_INS_KEY_CLR; /**< Let flag be set for relative addresses */ - if(tgt_index == HAB_IDX_CSFK) + if(tgt_index == HAB_IDX_CSFK || tgt_index == HAB_IDX_CSFK1) flag |= HAB_CMD_INS_KEY_CSF; *cmd_len = INS_KEY_BASE_BYTES; @@ -425,6 +459,10 @@ int32_t cmd_len = 0; /**< Used to keep track of cmd length */ int32_t src_set = -1; /**< Holds source set argument value */ int32_t revocations = -1; /**< Holds revocation mask argument value */ + char *key_cert; + uint32_t srk_idx; + + printf("Install SRK\n"); /* get the arguments */ /* srk key cert is at index 0 */ @@ -437,9 +475,9 @@ } else { - ret_val = process_installkey_arguments(cmd, &g_key_certs[HAB_IDX_SRK], + ret_val = process_installkey_arguments(cmd, &key_cert, &src_index, NULL, &hash_alg, &cert_format, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL); + &src_set, NULL, NULL, NULL); } if(ret_val != SUCCESS) @@ -450,18 +488,42 @@ do { if (TGT_AHAB == g_target) { + byte_str_t ahab_srk_table = {NULL, 0}; + if(NULL == g_ahab_data.srk_table) { log_arg_cmd(Filename, NULL, cmd->type); ret_val = ERROR_INSUFFICIENT_ARGUMENTS; break; } - if(NULL == g_ahab_data.srk_entry) + + /* Read the srk table file into temporary buffer */ + /*** NOTE: read_file() allocates memory that must be freed ***/ + read_file(g_ahab_data.srk_table, &ahab_srk_table, NULL); + if(!ahab_srk_table.entry || ahab_srk_table.entry_bytes <= 0) { - log_arg_cmd(Source, NULL, cmd->type); - ret_val = ERROR_INSUFFICIENT_ARGUMENTS; + log_arg_cmd(Filename, NULL, cmd->type); + ret_val = ERROR_INSUFFICIENT_MEMORY; + break; + } + + /* Check for valid tag and AHAB version in Super Root Key table + * saved at g_ahab_data.srk_table + */ + if((((struct ahab_container_srk_table_s *)(ahab_srk_table.entry))->tag != SRK_TABLE_TAG) || \ + (((struct ahab_container_srk_table_s *)(ahab_srk_table.entry))->version != SRK_TABLE_VERSION)) + { + log_arg_cmd(Filename, g_ahab_data.srk_table, cmd->type); + ret_val = ERROR_INVALID_SRK_TABLE; + free(ahab_srk_table.entry); break; } + + /* read_file allocates memory, so it must be freed and reset srk_entry pointer */ + free(ahab_srk_table.entry); + ahab_srk_table.entry = NULL; + ahab_srk_table.entry_bytes = 0; + if (src_index == -1) { log_arg_cmd(SourceIndex, NULL, cmd->type); @@ -516,8 +578,25 @@ else if(g_hab_version >= HAB4) { + /* SRK set */ + if (src_set == -1) + { + src_set = SRK_SET_OEM; + } + else if ((src_set != SRK_SET_OEM) && (src_set != SRK_SET_NXP)) + { + log_arg_cmd(SourceSet, " must be equal to OEM or NXP", cmd->type); + ret_val = ERROR_INVALID_ARGUMENT; + break; + } + g_srk_set_hab4 = src_set; + + srk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_SRK : HAB_IDX_SRK1; + + g_key_certs[srk_idx] = key_cert; + /* validate the arguments */ - if(g_key_certs[HAB_IDX_SRK] == NULL) + if(g_key_certs[srk_idx] == NULL) { log_arg_cmd(Filename, NULL, cmd->type); ret_val = ERROR_INSUFFICIENT_ARGUMENTS; @@ -529,6 +608,13 @@ ret_val = ERROR_INSUFFICIENT_ARGUMENTS; break; } + else if (src_index < SRC_IDX_INS_KEY_MIN || src_index > SRC_IDX_INS_KEY_MAX) + { + log_arg_cmd(SourceIndex, NULL, cmd->type); + ret_val = ERROR_INVALID_ARGUMENT; + break; + } + /* certificate format is not an option */ if(cert_format != -1) { @@ -543,25 +629,26 @@ hash_alg = g_hash_alg; /* Read data from cert and save the data pointer into command */ - ret_val = save_file_data(cmd, g_key_certs[HAB_IDX_SRK], NULL, 0, + ret_val = save_file_data(cmd, g_key_certs[srk_idx], NULL, 0, 0, NULL, NULL, hash_alg); if(ret_val != SUCCESS) break; - /* Check for valid tag for Super Root Key table saved at - * cmd->cert_sig_data + /* Check for valid tag and HAB version in Super Root Key table + * saved at cmd->cert_sig_data */ - if(cmd->cert_sig_data[0] != HAB_TAG_CRT) + if((cmd->cert_sig_data[SRK_TABLE_TAG_OFFSET] != HAB_TAG_CRT) || \ + (cmd->cert_sig_data[SRK_TABLE_VER_OFFSET] != HAB4)) { ret_val = ERROR_INVALID_SRK_TABLE; - log_error_msg(g_key_certs[HAB_IDX_SRK]); + log_error_msg(g_key_certs[srk_idx]); break; } cmd->start_offset_cert_sig = g_csf_buffer_index + HAB4_INSTALL_KEY_CMD_CERT_OFFSET; /* generate INS_SRK command */ - ret_val = hab4_install_key(src_index, HAB_IDX_SRK, + ret_val = hab4_install_key(src_index, srk_idx, hash_alg, cert_format, NULL, 0, &g_csf_buffer[g_csf_buffer_index], &cmd_len); if(ret_val != SUCCESS) @@ -606,6 +693,11 @@ uint8_t *cert_data = NULL; /**< DER encoded certificate data */ int32_t cert_len = 0; /**< length of certificate data */ + uint32_t srk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_SRK : HAB_IDX_SRK1; + uint32_t csfk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_CSFK : HAB_IDX_CSFK1; + + printf("Install CSFK\n"); + /* The Install CSFK command is invalid when AHAB is targeted */ if (TGT_AHAB == g_target) { @@ -615,7 +707,7 @@ /* get the arguments */ /* csf key is at index 1 */ - ret_val = process_installkey_arguments(cmd, &g_key_certs[HAB_IDX_CSFK], + ret_val = process_installkey_arguments(cmd, &g_key_certs[csfk_idx], NULL, NULL, NULL, &cert_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); @@ -629,7 +721,7 @@ if(g_hab_version >= HAB4) { /* validate the arguments */ - if(g_key_certs[HAB_IDX_CSFK] == NULL) + if(g_key_certs[csfk_idx] == NULL) { log_arg_cmd(Filename, NULL, cmd->type); ret_val = ERROR_INSUFFICIENT_ARGUMENTS; @@ -647,11 +739,11 @@ /* Read data from cert and save the data pointer into command */ cert_len = get_der_encoded_certificate_data( - g_key_certs[HAB_IDX_CSFK], &cert_data); + g_key_certs[csfk_idx], &cert_data); if(cert_len == 0) { ret_val = ERROR_INVALID_PKEY_CERTIFICATE; - log_error_msg(g_key_certs[HAB_IDX_CSFK]); + log_error_msg(g_key_certs[csfk_idx]); break; } @@ -664,8 +756,8 @@ HAB4_INSTALL_KEY_CMD_CERT_OFFSET; /* generate INS_CSFK command */ - ret_val = hab4_install_key(HAB_IDX_SRK, - HAB_IDX_CSFK, HAB_ALG_ANY, cert_format, NULL, 0, + ret_val = hab4_install_key(srk_idx, + csfk_idx, HAB_ALG_ANY, cert_format, NULL, 0, &g_csf_buffer[g_csf_buffer_index], &cmd_len); if(ret_val != SUCCESS) break; @@ -707,6 +799,10 @@ uint8_t *cert_data = NULL; /**< DER encoded certificate data */ int32_t cert_len = 0; /**< length of certificate data */ + uint32_t csfk_idx = HAB_IDX_CSFK; + + printf("Install no CAK\n"); + /* The Install NOCAK command is invalid when AHAB is targeted */ if (TGT_AHAB == g_target) { @@ -717,7 +813,7 @@ g_no_ca = 1; /* get the arguments */ /* csf key is at index 1 */ - ret_val = process_installkey_arguments(cmd, &g_key_certs[HAB_IDX_CSFK], + ret_val = process_installkey_arguments(cmd, &g_key_certs[csfk_idx], NULL, NULL, NULL, &cert_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); @@ -731,7 +827,7 @@ if(g_hab_version >= HAB4) { /* validate the arguments */ - if(g_key_certs[HAB_IDX_CSFK] == NULL) + if(g_key_certs[csfk_idx] == NULL) { log_arg_cmd(Filename, NULL, cmd->type); ret_val = ERROR_INSUFFICIENT_ARGUMENTS; @@ -749,11 +845,11 @@ /* Read data from cert and save the data pointer into command */ cert_len = get_der_encoded_certificate_data( - g_key_certs[HAB_IDX_CSFK], &cert_data); + g_key_certs[csfk_idx], &cert_data); if(cert_len == 0) { ret_val = ERROR_INVALID_PKEY_CERTIFICATE; - log_error_msg(g_key_certs[HAB_IDX_CSFK]); + log_error_msg(g_key_certs[csfk_idx]); break; } @@ -810,6 +906,8 @@ uint8_t *cert_data = NULL; /**< DER encoded certificate data */ int32_t cert_len = 0; /**< length of certificate data */ + printf("Install key\n"); + /* The Install Key command is invalid when AHAB is targeted */ if (TGT_AHAB == g_target) { @@ -844,14 +942,26 @@ ret_val = ERROR_INSUFFICIENT_ARGUMENTS; break; } + else if ((vfy_index != VFY_IDX_INS_KEY_SRK) && \ + (vfy_index < VFY_IDX_INS_KEY_MIN || vfy_index > VFY_IDX_INS_KEY_MAX)) + { + log_arg_cmd(VerificationIndex, NULL, cmd->type); + ret_val = ERROR_INVALID_ARGUMENT; + break; + } + if(tgt_index == -1) { log_arg_cmd(TargetIndex, NULL, cmd->type); ret_val = ERROR_INSUFFICIENT_ARGUMENTS; break; } - if(tgt_index == HAB_IDX_SRK || tgt_index == HAB_IDX_CSFK) - { + if( + tgt_index == HAB_IDX_SRK + || tgt_index == HAB_IDX_CSFK + || tgt_index == HAB_IDX_SRK1 + || tgt_index == HAB_IDX_CSFK1 + ) { log_arg_cmd(TargetIndex, NULL, cmd->type); ret_val = ERROR_INVALID_ARGUMENT; break; @@ -862,6 +972,7 @@ ret_val = ERROR_INVALID_ARGUMENT; break; } + if(tgt_index >= HAB_KEY_PUBLIC_MAX) { log_arg_cmd(TargetIndex, STR_EXCEED_MAX, cmd->type); diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_misc.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_misc.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/csf_cmd_misc.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/csf_cmd_misc.c 2021-08-12 12:53:52.000000000 +0000 @@ -10,7 +10,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011,2012. All rights reserved. - Copyright 2018 NXP + Copyright 2018, 2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -66,20 +66,6 @@ #define BYTES_IN_WORD 4 /**< Number of bytes in a word */ -#define ERR_IF_INIT_MULT_TIMES(flag) \ - if (flag) \ - { \ - log_arg_cmd(arg->type, " argument already specified", cmd->type);\ - return ERROR_INVALID_ARGUMENT; \ - } \ - flag = true - -#define ERR_IF_UNS_ARG(flag, arg) \ - if (flag) \ - { \ - log_arg_cmd(arg, STR_ILLEGAL, cmd->type); \ - return ERROR_UNSUPPORTED_ARGUMENT; \ - } /*=========================================================================== LOCAL FUNCTION DECLARATION =============================================================================*/ @@ -118,11 +104,16 @@ uint32_t i; argument_t *arg = cmd->argument; /**< Ptr to argument_t */ + bool flag_eng = false; + bool flag_eng_cfg = false; + bool flag_hsh_alg = false; + for(i=0; iargument_count; i++) { switch((arguments_t)arg->type) { case EngineName: + ERR_IF_INIT_MULT_TIMES(flag_eng); if(engine != NULL) *engine = arg->value.keyword->unsigned_value; else @@ -132,6 +123,7 @@ } break; case EngineConfiguration: + ERR_IF_INIT_MULT_TIMES(flag_eng_cfg); if(engine_cfg != NULL) { /* Engine configuration could be number or keyword */ @@ -147,6 +139,7 @@ } break; case HashAlgorithm: + ERR_IF_INIT_MULT_TIMES(flag_hsh_alg); if(hash_alg != NULL) *hash_alg = arg->value.keyword->unsigned_value; else @@ -288,8 +281,6 @@ g_csf_buffer[CSF_HDR_HAB4_VERSION_OFFSET] = g_hab_version; } - ERR_IF_UNS_ARG(flag_mode, Mode); - if (g_engine == HAB_ENG_ANY && g_engine_config != 0) { log_arg_cmd(EngineName, STR_ENG_ANY_CFG_NOT_ZERO, cmd->type); @@ -488,12 +479,18 @@ int32_t engine = -1; /**< Holds the value of engine argument */ keyword_t *feature = NULL; /**< Holds features list argument */ int32_t num_features = 0; /**< Count of features in the argument */ + number_t *feature_num = NULL; /**< Holds numeric features list argument */ + int32_t feature_type = 0; /**< Type of features in the argument */ number_t *uid = NULL; /**< Holds UID argument */ int32_t uid_bytes = 0; /**< Length of UID in bytes */ argument_t *arg; /**< Ptr to command's argument */ int32_t cmd_len; /**< Used to keep track of cmd length */ uint32_t features = 0; /**< All features are OR'ed into this word */ + bool flag_eng = false; + bool flag_feature = false; + bool flag_uid = false; + arg = cmd->argument; for(i=0; iargument_count; i++) @@ -501,13 +498,24 @@ switch((arguments_t)arg->type) { case EngineName: + ERR_IF_INIT_MULT_TIMES(flag_eng); engine = arg->value.keyword->unsigned_value; + /* Validate if only 1 Engine is specified */ + if(arg->value_count > 1) + { + log_arg_cmd(arg->type, " must have only 1 Engine", cmd->type); + return ERROR_INVALID_ARGUMENT; + } break; case Features: + ERR_IF_INIT_MULT_TIMES(flag_feature); feature = arg->value.keyword; + feature_num = arg->value.number; num_features = arg->value_count; + feature_type = arg->value_type; break; case UID: + ERR_IF_INIT_MULT_TIMES(flag_uid); uid = arg->value.number; uid_bytes = arg->value_count; break; @@ -525,10 +533,54 @@ } /* OR'ed all feature values in features */ - while(feature != NULL) + while(feature != NULL && feature_num != NULL) { - features |= feature->unsigned_value; - feature = feature->next; + if(feature->string_value != NULL && feature_type == KEYWORD_TYPE) + { + switch(engine) + { + case HAB_ENG_SRTC: + log_arg_cmd(Features, NULL, cmd->type); + return ERROR_INVALID_ARGUMENT; + case HAB_ENG_CAAM: + if(!(strncmp(feature->string_value, "MID", 3) == 0 || + strncmp(feature->string_value, "RNG", 3) == 0 || + strncmp(feature->string_value, "MFG", 3) == 0 )) + { + log_arg_cmd(Features, " invalid for the specified engine", cmd->type); + return ERROR_INVALID_ARGUMENT; + } + break; + case HAB_ENG_SNVS: + if(!(strncmp(feature->string_value, "LPSWR", 5) == 0 || + strncmp(feature->string_value, "ZMKWRITE", 8) == 0 )) + { + log_arg_cmd(Features, " invalid for the specified engine", cmd->type); + return ERROR_INVALID_ARGUMENT; + } + break; + case HAB_ENG_OCOTP: + if(!(strncmp(feature->string_value, "FIELDRETURN", 11) == 0 || + strncmp(feature->string_value, "SRKREVOKE", 9) == 0 || + strncmp(feature->string_value, "SCS", 3) == 0 || + strncmp(feature->string_value, "JTAG", 4) == 0 )) + { + log_arg_cmd(Features, " invalid for the specified engine", cmd->type); + return ERROR_INVALID_ARGUMENT; + } + break; + default: + log_arg_cmd(EngineName, NULL, cmd->type); + return ERROR_INVALID_ARGUMENT; + } + features |= feature->unsigned_value; + feature = feature->next; + } + else if(feature_type == NUMBER_TYPE) + { + features |= feature_num->num_value; + feature_num = feature_num->next; + } } /* Set flags if this is Unlock RNG or Init RNG command */ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/cst.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/cst.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/cst.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/cst.c 2021-08-12 12:53:52.000000000 +0000 @@ -12,7 +12,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011-2015. All rights reserved. - Copyright 2018-2019 NXP + Copyright 2018-2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -80,6 +80,7 @@ extern int32_t yyparse(void); extern FILE *yyin; extern int g_no_ca; +extern int32_t g_srk_set_hab4; /*=========================================================================== INSTANTIATE GLOBAL VARIABLES =============================================================================*/ @@ -119,7 +120,7 @@ * Array of size HAB_KEY_PUBLIC_MAX for key cert file names. */ char *g_key_certs[HAB_KEY_PUBLIC_MAX] = { - NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /** @@ -129,6 +130,8 @@ {0, NULL}, {0, NULL}, {0, NULL}, + {0, NULL}, + {0, NULL}, {0, NULL} }; @@ -335,8 +338,8 @@ {"sw", (uint32_t)HAB_ENG_SW}, {"x509", (uint32_t)HAB_PCL_X509}, {"CMS", (uint32_t)SIG_FMT_CMS}, - {"srk", (uint32_t)HAB_IDX_SRK}, - {"csfk", (uint32_t)HAB_IDX_CSFK}, + //{"srk", (uint32_t)HAB_IDX_SRK}, + //{"csfk", (uint32_t)HAB_IDX_CSFK}, {"OCOTP", (uint32_t)HAB_ENG_OCOTP}, {"SNVS", (uint32_t)HAB_ENG_SNVS}, {"DTCP", (uint32_t)HAB_ENG_DTCP}, @@ -1180,12 +1183,12 @@ size_t cert_len, int32_t add_header, uint8_t **crt_hash, size_t *hash_len, int32_t hash_alg) { - uint32_t file_size; /**< File size is read into it, useful in + size_t file_size; /**< File size is read into it, useful in calulating length field of cmd header */ int32_t ret_val = SUCCESS; /**< To return and keep track of errors */ uint8_t *data = NULL; /**< Ptr to buffer for reading in file data */ int32_t header_bytes; /**< Needed for the size of header */ - int32_t data_size; /**< For total size of certificate or + size_t data_size; /**< For total size of certificate or signature */ uint8_t hdr_tag; /**< Used in HDR macro, set to either CRT or SIG */ @@ -1260,7 +1263,7 @@ memset(data, 0, data_size); if (file) { - if (fread(data+header_bytes, 1, file_size, fh) != file_size) + if (fread(data+header_bytes, 1, file_size, fh) != (size_t)file_size) { log_error_msg(file); ret_val = ERROR_READING_FILE; @@ -1343,7 +1346,7 @@ */ int32_t create_sig_file(char *file, char *cert_file, sig_fmt_t sig_fmt, uint8_t *data, - uint32_t data_size) + size_t data_size) { uint8_t sig[SIGNATURE_BUFFER_SIZE]; /**< Signature buffer on stack */ hash_alg_t hash; /**< Hash algorithm to pass into adaptation layer API */ @@ -1356,7 +1359,7 @@ * signature data and gen_sig_data returns actual size of signature * data in this argument */ - uint32_t sig_size = SIGNATURE_BUFFER_SIZE; + size_t sig_size = SIGNATURE_BUFFER_SIZE; do { /** @@ -1463,7 +1466,7 @@ if (cmd->start_offset_cert_sig > 0) { uint8_t offset_bytes[] = { - EXPAND_UINT32(cert_sig_offset) + EXPAND_UINT32((uint32_t)cert_sig_offset) }; /**< Macro puts offets into the buffer */ memcpy(&buf[cmd->start_offset_cert_sig], offset_bytes, 4); @@ -1736,6 +1739,12 @@ and replace the dummy one with it */ do { + uint32_t csfk_idx = (g_srk_set_hab4 == SRK_SET_OEM) ? HAB_IDX_CSFK : HAB_IDX_CSFK1; + + /* Adjust CSFK index if NOCAK */ + if (g_no_ca == 1) { + csfk_idx = HAB_IDX_CSFK; + } cmd = g_cmd_head; @@ -1770,7 +1779,7 @@ /* create signature for csf data into FILE_SIG_CSF_DATA */ ret_val = create_sig_file(FILE_SIG_CSF_DATA, - g_key_certs[HAB_IDX_CSFK], + g_key_certs[csfk_idx], (g_hab_version >= HAB4) ? SIG_FMT_CMS : SIG_FMT_PKCS1, g_csf_buffer, g_csf_buffer_index); diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/cst_lexer.l imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/cst_lexer.l --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/cst_lexer.l 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/cst_lexer.l 2021-08-12 12:53:52.000000000 +0000 @@ -30,7 +30,7 @@ %% [a-z][a-z0-9]* yylval.str=strdup(yytext);return WORD; -\"[a-zA-Z0-9\/\\._-]+\" { /* strip off quotes */ +\".*\" { /* strip off quotes */ yytext++; yytext[strlen(yytext) - 1] = 0; /* diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/misc_helper.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/misc_helper.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/front_end/src/misc_helper.c 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/front_end/src/misc_helper.c 2021-08-12 12:53:52.000000000 +0000 @@ -0,0 +1,153 @@ +/*===========================================================================*/ +/** + @file misc_helper.c + + @brief Provide miscellaneous helper functions + +@verbatim +============================================================================= + + Copyright 2020 NXP + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================= +@endverbatim */ + +/*=========================================================================== + INCLUDE FILES +=============================================================================*/ +#include +#include +#include +#include "misc_helper.h" +#include "err.h" + +/*=========================================================================== + LOCAL CONSTANTS +=============================================================================*/ +#define MAX_ERR_MSG_BYTES (1024) + +/*=========================================================================== + LOCAL MACROS +=============================================================================*/ + +/*=========================================================================== + LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) +=============================================================================*/ + +/*=========================================================================== + LOCAL VARIABLES +=============================================================================*/ +char err_msg[MAX_ERR_MSG_BYTES]; + +/*=========================================================================== + LOCAL FUNCTION PROTOTYPES +=============================================================================*/ +/** Read bytes from a file + * + * Reads an amount of bytes from an input file + * + * @param[in] filename Input file name to be read + * + * @param[out] byte_str Byte string struct to return the read data + * + * @param[in] offsets If defined, + * + * @pre @a filename and @a offsets must not be NULL + * + * @post none + * + * @returns the size of memory allocated point to by byte_str + */ + +/*=========================================================================== + LOCAL FUNCTIONS +=============================================================================*/ + +/*-------------------------- + read_file +---------------------------*/ +void +read_file(const char *filename, byte_str_t *byte_str, offsets_t *offsets) +{ + FILE *file = NULL; + uint32_t bytes_to_read, read_size; + + /* Open the source file */ + file = fopen(filename, "rb"); + if (NULL == file) + { + snprintf(err_msg, MAX_ERR_MSG_BYTES, "Cannot open %s", filename); + error(err_msg); + } + + /* Get the file size */ + fseek(file, 0, SEEK_END); + bytes_to_read = ftell(file); + rewind(file); + + /* If some offsets are specified, refine the number of bytes to be read */ + if (NULL != offsets) + { + if ((bytes_to_read < offsets->first) + || (bytes_to_read < offsets->second)) + { + snprintf(err_msg, + MAX_ERR_MSG_BYTES, + "Offsets defined outside the file %s", + filename); + error(err_msg); + } + + if (offsets->first > offsets->second) + { + error("Incorrect offsets"); + } + + bytes_to_read = offsets->second - offsets->first; + + fseek(file, offsets->first, SEEK_SET); + } + + /* Save the file data */ + byte_str->entry_bytes = bytes_to_read; + byte_str->entry = malloc(bytes_to_read); + if (NULL == byte_str->entry) + { + snprintf(err_msg, MAX_ERR_MSG_BYTES, "Cannot allocate memory for handling %s", filename); + error(err_msg); + } + + memset(byte_str->entry, 0, bytes_to_read); + read_size = fread(byte_str->entry, 1, bytes_to_read, file); + + if (read_size != bytes_to_read) + { + snprintf(err_msg, MAX_ERR_MSG_BYTES, "Unexpected read termination of %s", filename); + error(err_msg); + } + + fclose(file); +} diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/srktool/src/srktool.c imx-code-signing-tool-3.3.1+dfsg/code/cst/code/srktool/src/srktool.c --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/code/srktool/src/srktool.c 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/code/srktool/src/srktool.c 2021-08-12 12:53:52.000000000 +0000 @@ -11,7 +11,7 @@ Freescale Semiconductor (c) Freescale Semiconductor, Inc. 2011, 2012, 2013 All rights reserved. - Copyright 2018 NXP + Copyright 2018,2020 NXP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -80,7 +80,7 @@ #define CMDLINE_ARG_HASH_INDICATOR ('%') /**< Generate cert hash */ /** Valid short command line option letters. */ -const char* const short_options = "lvh:at:e:f:d:s:c:"; +const char* const short_options = "lvh:at:e:f:d:s:c:b"; /** Valid long command line options. */ const struct option long_options[] = @@ -95,6 +95,7 @@ {"digest", required_argument, 0, 'd'}, {"sign_digest", required_argument, 0, 's'}, {"certs", required_argument, 0, 'c'}, + {"verbose", no_argument, 0, 'b'}, {NULL, 0, NULL, 0} }; @@ -460,6 +461,9 @@ /** global index into g_table_data */ uint32_t g_index_to_table_data = SRK_TABLE_HEADER_BYTES; +/** global variable for versbose output **/ +bool g_verbose = FALSE; + /*=========================================================================== LOCAL FUNCTIONS =============================================================================*/ @@ -479,9 +483,7 @@ fuse_format_t fuse_file_format, const char *sd_alg_str) { -#ifdef DEBUG uint32_t i; /**< Loop index */ -#endif uint32_t srk_table_bytes = 0; /**< Size of SRK table */ size_t hash_bytes = 0; /**< Size of hash digest in bytes */ uint8_t *hash_data = NULL; /**< Location of hash result buffer */ @@ -556,19 +558,28 @@ hash_data); } - /* Dump for verification */ -#ifdef DEBUG + /* Dump for verification or verbose output */ + printf("Number of certificates = %d\n", num_certs); printf("SRK table binary filename = %s\n", table_filename); - printf("Hash type = %s\n", md_alg_str); - printf("Fuse binary filename = %s\n", fuses_filename); - printf("Hash keys at index "); - printf("Num_certs = %d\n", num_certs); - for (i = 0; i < num_certs; i++) + if (g_verbose) { - printf("Certificate %d = %s\n", i, certs[i].filename); - printf("Certificate %d hash = %d\n", i, certs[i].hash); + printf("Hash type = %s\n", md_alg_str); + puts("Hash keys at index "); + for (i = 0; i < num_certs; i++) + { + printf("Certificate %d = %s\n", i, certs[i].filename); + printf("Certificate %d hash = %d\n", i, certs[i].hash); + } } -#endif + printf("SRK Fuse binary filename = %s\n", fuses_filename); + puts("SRK Fuse binary dump:"); + for (i = 0; i < hash_bytes; i+=4) + { + printf("SRK HASH[%d] = 0x%02X%02X%02X%02X\n", i/4, hash_data[i+3], hash_data[i+2], hash_data[i+1], hash_data[i]); + } + + free(hash_data); + return; } @@ -620,7 +631,6 @@ error(tmp_str); } } - free(hash_data); fclose(fp_fuses); } @@ -1029,6 +1039,8 @@ printf(" -v, --version:\n"); printf(" Optional, displays the version of the tool. No "); printf("additional\n arguments are required.\n\n"); + printf(" -b, --verbose:\n"); + printf(" Optional, displays a verbose output.\n\n"); printf("Examples:\n"); printf("---------\n\n"); printf("1. To generate an SRK table and corresponding fuse pattern from "); @@ -1086,6 +1098,8 @@ printf(" -v, --version:\n"); printf(" Optional, displays the version of the tool. No "); printf("additional\n arguments are required.\n\n"); + printf(" -b, --verbose:\n"); + printf(" Optional, displays a verbose output.\n\n"); printf("Examples:\n"); printf("---------\n\n"); printf("1. To generate an SRK table and corresponding fuse pattern from "); @@ -1193,6 +1207,10 @@ exit(0); break; case 'h': + /* + * ******************DO NOT CHANGE*********************** + * NOTE: HAB version will always be 4.0 for HABv4 devices + */ if (TGT_UNDEF == target) { target = TGT_HAB; @@ -1205,6 +1223,10 @@ hab_version = check_hab_version(optarg); break; case 'a': + /* + * ******************DO NOT CHANGE********************** + * NOTE: HAB version will always be 4.2 for AHAB devices + */ if (TGT_UNDEF == target) { target = TGT_AHAB; @@ -1233,6 +1255,9 @@ case 'c': cert_filenames = optarg; break; + case 'b': + g_verbose = TRUE; + break; /* Handle invalid options */ case '?': print_usage(); diff -Nru imx-code-signing-tool-3.3.0+dfsg2/code/cst/Makefile imx-code-signing-tool-3.3.1+dfsg/code/cst/Makefile --- imx-code-signing-tool-3.3.0+dfsg2/code/cst/Makefile 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/code/cst/Makefile 2021-08-12 12:53:52.000000000 +0000 @@ -55,7 +55,7 @@ $(MKDIR) $@ # release binaries for the given configuration -rel_bin: $(DST)/$(OSTYPE)/lib $(DST)/$(OSTYPE)/bin $(DST)/keys +rel_bin: $(DST)/$(OSTYPE)/bin $(DST)/keys $(MAKE) -C $(CST_CODE_PATH)/obj.$(OSTYPE) rel_bin # build binaries for the given configuration diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/changelog imx-code-signing-tool-3.3.1+dfsg/debian/changelog --- imx-code-signing-tool-3.3.0+dfsg2/debian/changelog 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/changelog 2022-01-06 12:44:17.000000000 +0000 @@ -1,3 +1,31 @@ +imx-code-signing-tool (3.3.1+dfsg-2ubuntu1) jammy; urgency=medium + + * Build without LTO, lto-disabled-list does not + work for this package. + + -- Graham Inggs Thu, 06 Jan 2022 12:44:17 +0000 + +imx-code-signing-tool (3.3.1+dfsg-2build1) jammy; urgency=medium + + * No-change rebuild against openssl3 + + -- Simon Chopin Tue, 23 Nov 2021 16:35:34 +0100 + +imx-code-signing-tool (3.3.1+dfsg-2) unstable; urgency=medium + + * Unbreak the scripts. + Thanks to Sean Anderson (patch taken from Arch Linux). + + -- Andrej Shadura Thu, 12 Aug 2021 16:02:12 +0200 + +imx-code-signing-tool (3.3.1+dfsg-1) unstable; urgency=medium + + * New upstream release. + * Drop patches applied upstream. + * Update the copyrights. + + -- Andrej Shadura Thu, 12 Aug 2021 15:10:25 +0200 + imx-code-signing-tool (3.3.0+dfsg2-1) unstable; urgency=medium * Remove the questionably licensed and unused HSM backend diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/control imx-code-signing-tool-3.3.1+dfsg/debian/control --- imx-code-signing-tool-3.3.0+dfsg2/debian/control 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/control 2022-01-06 12:02:37.000000000 +0000 @@ -1,7 +1,8 @@ Source: imx-code-signing-tool Section: electronics Priority: optional -Maintainer: Andrej Shadura +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Andrej Shadura Build-Depends: debhelper-compat (= 13), libssl-dev, diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/copyright imx-code-signing-tool-3.3.1+dfsg/debian/copyright --- imx-code-signing-tool-3.3.0+dfsg2/debian/copyright 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/copyright 2021-08-12 14:02:12.000000000 +0000 @@ -12,7 +12,7 @@ *.exe Files: * -Copyright: 2017-2019 NXP +Copyright: 2017-2020 NXP License: BSD-3-clause Files: @@ -22,7 +22,12 @@ License: BSD-3-clause Files: - code/cst/code/back_end/hdr/ssl_wrapper.h + code/back_end-engine/src/openssl_helper.c + code/back_end-engine/src/backend.c +Copyright: 2020 NXP +License: BSD-2-clause + +Files: code/cst/code/back_end/src/adapt_layer_openssl.c code/cst/code/back_end/src/objects.mk code/cst/code/back_end/src/ssl_wrapper.c @@ -31,6 +36,7 @@ code/cst/code/common/hdr/version.h code/cst/code/common/src/objects.mk code/cst/code/common/src/openssl_helper.c + code/cst/code/front_end/hdr/misc_helper.h code/cst/code/front_end/hdr/adapt_layer.h code/cst/code/front_end/hdr/csf.h code/cst/code/front_end/hdr/hab_cmd.h @@ -43,14 +49,14 @@ code/cst/Makefile Copyright: 2007-2016 Freescale Semiconductor, Inc. - 2017-2019 NXP + 2017-2020 NXP License: BSD-3-clause Files: debian/* Copyright: - 2020 Collabora Limited - 2020 Andrej Shadura -License: BSD-3-clause + 2020, 2021 Collabora Limited + 2020, 2021 Andrej Shadura +License: BSD-2-clause or BSD-3-clause License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, @@ -67,6 +73,27 @@ . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/fill.copyright.blanks.yml imx-code-signing-tool-3.3.1+dfsg/debian/fill.copyright.blanks.yml --- imx-code-signing-tool-3.3.0+dfsg2/debian/fill.copyright.blanks.yml 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/fill.copyright.blanks.yml 2021-08-12 14:02:12.000000000 +0000 @@ -0,0 +1,4 @@ +code/back_end-engine/src/openssl_helper.c: + license: BSD-2-clause +code/back_end-engine/src/backend.c: + license: BSD-2-clause diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/patches/0001-Use-correct-types-for-sizes-to-avoid-overwriting-unr.patch imx-code-signing-tool-3.3.1+dfsg/debian/patches/0001-Use-correct-types-for-sizes-to-avoid-overwriting-unr.patch --- imx-code-signing-tool-3.3.0+dfsg2/debian/patches/0001-Use-correct-types-for-sizes-to-avoid-overwriting-unr.patch 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/patches/0001-Use-correct-types-for-sizes-to-avoid-overwriting-unr.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,159 +0,0 @@ -From: Andrej Shadura -Date: Thu, 30 Jan 2020 17:17:46 +0100 -Subject: Use correct types for sizes to avoid overwriting unrelated data - -sig_size is declared as uint32_t, but later typecast to size_t, -which is significantly wider on 64-bit architectures. - -To avoid potential issues in other places, promote sizes and lengths -to size_t/ssize_t where this makes sense - -Signed-off-by: Andrej Shadura ---- - code/cst/code/back_end/src/adapt_layer_openssl.c | 4 ++-- - code/cst/code/back_end/src/ssl_wrapper.c | 5 +++-- - code/cst/code/front_end/hdr/csf.h | 2 +- - code/cst/code/front_end/src/acst.c | 2 +- - code/cst/code/front_end/src/csf_cmd_aut_dat.c | 2 +- - code/cst/code/front_end/src/cst.c | 12 ++++++------ - 6 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/code/cst/code/back_end/src/adapt_layer_openssl.c b/code/cst/code/back_end/src/adapt_layer_openssl.c -index 3a4230e..40d215f 100644 ---- a/code/cst/code/back_end/src/adapt_layer_openssl.c -+++ b/code/cst/code/back_end/src/adapt_layer_openssl.c -@@ -286,7 +286,7 @@ gen_sig_data_raw(const char *in_file, - uint8_t *rsa_in = NULL; /**< Mem ptr for hash data of in_file */ - uint8_t *rsa_out = NULL; /**< Mem ptr for encrypted data */ - int32_t rsa_inbytes; /**< Holds the length of rsa_in buf */ -- int32_t rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ -+ unsigned int rsa_outbytes = 0; /**< Holds the length of rsa_out buf */ - int32_t key_bytes; /**< Size of key data */ - int32_t hash_nid; /**< hash id needed for RSA_sign() */ - /** Array to hold error string */ -@@ -513,7 +513,7 @@ gen_sig_data_ecdsa(const char *in_file, - { - BIO *bio_in = NULL; /**< BIO for in_file data */ - EVP_PKEY *key = NULL; /**< Private key data */ -- uint32_t key_size = 0; /**< n of bytes of key param */ -+ size_t key_size = 0; /**< n of bytes of key param */ - const EVP_MD *sign_md = NULL; /**< Digest name */ - uint8_t *hash = NULL; /**< Hash data of in_file */ - int32_t hash_bytes = 0; /**< Length of hash buffer */ -diff --git a/code/cst/code/back_end/src/ssl_wrapper.c b/code/cst/code/back_end/src/ssl_wrapper.c -index 7266f9a..eba53e8 100644 ---- a/code/cst/code/back_end/src/ssl_wrapper.c -+++ b/code/cst/code/back_end/src/ssl_wrapper.c -@@ -73,7 +73,7 @@ int32_t encryptccm(unsigned char *plaintext, int plaintext_len, unsigned char *a - EVP_CIPHER_CTX *ctx; - - int len; -- int ciphertext_len; -+ size_t ciphertext_len; - - unsigned char *ciphertext = NULL; - ciphertext = (unsigned char *)malloc(plaintext_len + EVP_MAX_BLOCK_LENGTH); -@@ -202,7 +202,8 @@ int32_t encryptcbc(unsigned char *plaintext, int plaintext_len, unsigned char *k - return CAL_NO_CRYPTO_API_ERROR; - #else - EVP_CIPHER_CTX *ctx; -- int len, ciphertext_len; -+ int len; -+ size_t ciphertext_len; - unsigned char *ciphertext = NULL; - ciphertext = (unsigned char *)malloc(plaintext_len); - if (NULL == ciphertext) { -diff --git a/code/cst/code/front_end/hdr/csf.h b/code/cst/code/front_end/hdr/csf.h -index 8773429..f45fa18 100644 ---- a/code/cst/code/front_end/hdr/csf.h -+++ b/code/cst/code/front_end/hdr/csf.h -@@ -384,7 +384,7 @@ extern int32_t append_uid_to_buffer(number_t *uid, uint8_t *buf, - /* Creates signature data file for the given data */ - extern int32_t create_sig_file(char *file, char *cert_file, - sig_fmt_t sig_fmt, uint8_t *data, -- uint32_t data_size); -+ size_t data_size); - - /* Called by parser on each command */ - extern int32_t handle_command(command_t *cmd); -diff --git a/code/cst/code/front_end/src/acst.c b/code/cst/code/front_end/src/acst.c -index ca354dd..e382673 100644 ---- a/code/cst/code/front_end/src/acst.c -+++ b/code/cst/code/front_end/src/acst.c -@@ -887,7 +887,7 @@ void encrypt_images(ahab_data_t *ahab_data, - get_digest_name(ahab_hash_2_cst_hash(hash_type)), - &digest_size); - -- if (digest_size != hash_size) { -+ if (digest_size != (size_t)hash_size) { - error("Fail to generate hash of encrypted data of image index %d", i); - } - -diff --git a/code/cst/code/front_end/src/csf_cmd_aut_dat.c b/code/cst/code/front_end/src/csf_cmd_aut_dat.c -index f63d75e..90e1ebe 100644 ---- a/code/cst/code/front_end/src/csf_cmd_aut_dat.c -+++ b/code/cst/code/front_end/src/csf_cmd_aut_dat.c -@@ -1128,7 +1128,7 @@ int32_t cmd_handler_decryptdata(command_t* cmd) - int32_t engine = -1; /**< Holds engine argument value */ - int32_t engine_cfg = -1; /**< Holds engine config argument value */ - int32_t vfy_index = -1; /**< Holds verify index argument value */ -- int32_t mac_bytes = -1; /**< Holds MAC length argument value */ -+ ssize_t mac_bytes = -1; /**< Holds MAC length argument value */ - block_t *block = NULL; /**< Holds address of block list argument */ - block_t *tmpblock = NULL; /**< Holds address of block list argument */ - size_t blocks_data_size=0; /**< Bytes occupied by block data in cmd */ -diff --git a/code/cst/code/front_end/src/cst.c b/code/cst/code/front_end/src/cst.c -index a8f3470..a35644d 100644 ---- a/code/cst/code/front_end/src/cst.c -+++ b/code/cst/code/front_end/src/cst.c -@@ -1180,12 +1180,12 @@ int32_t save_file_data(command_t *cmd, char *file, uint8_t *cert_data, - size_t cert_len, int32_t add_header, uint8_t **crt_hash, - size_t *hash_len, int32_t hash_alg) - { -- uint32_t file_size; /**< File size is read into it, useful in -+ size_t file_size; /**< File size is read into it, useful in - calulating length field of cmd header */ - int32_t ret_val = SUCCESS; /**< To return and keep track of errors */ - uint8_t *data = NULL; /**< Ptr to buffer for reading in file data */ - int32_t header_bytes; /**< Needed for the size of header */ -- int32_t data_size; /**< For total size of certificate or -+ size_t data_size; /**< For total size of certificate or - signature */ - uint8_t hdr_tag; /**< Used in HDR macro, set to either CRT or - SIG */ -@@ -1260,7 +1260,7 @@ int32_t save_file_data(command_t *cmd, char *file, uint8_t *cert_data, - memset(data, 0, data_size); - if (file) - { -- if (fread(data+header_bytes, 1, file_size, fh) != file_size) -+ if (fread(data+header_bytes, 1, file_size, fh) != (size_t)file_size) - { - log_error_msg(file); - ret_val = ERROR_READING_FILE; -@@ -1343,7 +1343,7 @@ int32_t save_file_data(command_t *cmd, char *file, uint8_t *cert_data, - */ - int32_t create_sig_file(char *file, char *cert_file, - sig_fmt_t sig_fmt, uint8_t *data, -- uint32_t data_size) -+ size_t data_size) - { - uint8_t sig[SIGNATURE_BUFFER_SIZE]; /**< Signature buffer on stack */ - hash_alg_t hash; /**< Hash algorithm to pass into adaptation layer API */ -@@ -1356,7 +1356,7 @@ int32_t create_sig_file(char *file, char *cert_file, - * signature data and gen_sig_data returns actual size of signature - * data in this argument - */ -- uint32_t sig_size = SIGNATURE_BUFFER_SIZE; -+ size_t sig_size = SIGNATURE_BUFFER_SIZE; - - do { - /** -@@ -1463,7 +1463,7 @@ static int update_offsets_in_csf(uint8_t * buf, command_t * cmd_csf, uint32_t cs - if (cmd->start_offset_cert_sig > 0) - { - uint8_t offset_bytes[] = { -- EXPAND_UINT32(cert_sig_offset) -+ EXPAND_UINT32((uint32_t)cert_sig_offset) - }; /**< Macro puts offets into the buffer */ - - memcpy(&buf[cmd->start_offset_cert_sig], offset_bytes, 4); diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/patches/0002-Check-the-hash-algorithm-before-possibly-failing-to-.patch imx-code-signing-tool-3.3.1+dfsg/debian/patches/0002-Check-the-hash-algorithm-before-possibly-failing-to-.patch --- imx-code-signing-tool-3.3.0+dfsg2/debian/patches/0002-Check-the-hash-algorithm-before-possibly-failing-to-.patch 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/patches/0002-Check-the-hash-algorithm-before-possibly-failing-to-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -From: Andrej Shadura -Date: Thu, 30 Jan 2020 17:31:36 +0100 -Subject: Check the hash algorithm before (possibly failing to) malloc - -malloc only accepts unsigned sizes, so failing to catch a negative -size as an errorcode will result in a malloc call with an enormous -value, leading to an allocation failure and a nonsensical error -message. - -Signed-off-by: Andrej Shadura ---- - code/cst/code/front_end/src/acst.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/code/cst/code/front_end/src/acst.c b/code/cst/code/front_end/src/acst.c -index e382673..3f780ab 100644 ---- a/code/cst/code/front_end/src/acst.c -+++ b/code/cst/code/front_end/src/acst.c -@@ -788,16 +788,17 @@ void encrypt_images(ahab_data_t *ahab_data, - - uint8_t hash_type = ahab_container_image_get_hash(image); - int32_t hash_size = ahab_get_hash_size_by_sha_type(hash_type); -+ -+ if (hash_size < 0) { -+ error("Unsupported hash algorithm for image integrity"); -+ } -+ - uint8_t *hash = malloc(hash_size); - - if (NULL == hash) { - error("Cannot allocate memory for the hash value of the plaintext"); - } - -- if (hash_size < 0) { -- error("Unsupported hash algorithm for image integrity"); -- } -- - /* Retrieve image data */ - - offsets_t offsets = { diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/patches/series imx-code-signing-tool-3.3.1+dfsg/debian/patches/series --- imx-code-signing-tool-3.3.0+dfsg2/debian/patches/series 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/patches/series 2021-08-12 14:02:12.000000000 +0000 @@ -1,2 +1 @@ -0001-Use-correct-types-for-sizes-to-avoid-overwriting-unr.patch -0002-Check-the-hash-algorithm-before-possibly-failing-to-.patch +unbreak-scripts.patch diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/patches/unbreak-scripts.patch imx-code-signing-tool-3.3.1+dfsg/debian/patches/unbreak-scripts.patch --- imx-code-signing-tool-3.3.0+dfsg2/debian/patches/unbreak-scripts.patch 1970-01-01 00:00:00.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/patches/unbreak-scripts.patch 2021-08-12 14:02:12.000000000 +0000 @@ -0,0 +1,217 @@ +From: Sean Anderson +Date: Fri, 12 Feb 2021 11:54:36 -0500 +Subject: Undo 3.3.1 changes which break the script for no good reason + +--- + keys/add_key.sh | 53 --------------------------------------------------- + keys/ahab_pki_tree.sh | 53 --------------------------------------------------- + keys/hab4_pki_tree.sh | 53 --------------------------------------------------- + 3 files changed, 159 deletions(-) + +diff --git a/keys/add_key.sh b/keys/add_key.sh +index 68c79c3..9417bed 100755 +--- a/keys/add_key.sh ++++ b/keys/add_key.sh +@@ -305,48 +305,6 @@ else + fi + fi + +-# Check existance of keys/, crts/ and ca/ directories of before generating keys and +-# switch current working directory to /keys directory, if needed. +-crt_dir=$(pwd) +-script_name=$(readlink "$0") +-if [ "${script_name}" = "" ] +-then +- script_name=$0 +-fi +-script_path=$(cd $(dirname "${script_name}") && pwd -P) +-keys_dir=${script_path}/../keys/ +-crts_dir=${script_path}/../crts/ +-ca_dir=${script_path}/../ca/ +- +-if [ ! -d "${keys_dir}" ] +-then +- echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." +- exit 1 +-fi +- +-if [ ! -d "${crts_dir}" ] +-then +- echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." +- exit 1 +-fi +- +-if [ ! -d "${ca_dir}" ] +-then +- echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." +- exit 1 +-fi +- +-# Switch current working directory to keys directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${keys_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${keys_dir}" +- exit 1 +- fi +-fi +- + # Generate outputs + if [ $kt = "ecc" ] + then +@@ -404,15 +362,4 @@ mv ${key_fullname}_key_tmp.pem ${key_fullname}_key.pem + + # Clean up + \rm -f *_req.pem +- +-# Switch back to initial working directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${crt_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${crt_dir}" +- exit 1 +- fi +-fi + exit 0 +diff --git a/keys/ahab_pki_tree.sh b/keys/ahab_pki_tree.sh +index f5ab36c..0b9004f 100755 +--- a/keys/ahab_pki_tree.sh ++++ b/keys/ahab_pki_tree.sh +@@ -277,48 +277,6 @@ then + read srk_ca + fi + +-# Check existance of keys/, crts/ and ca/ directories of before generating keys and +-# switch current working directory to /keys directory, if needed. +-crt_dir=$(pwd) +-script_name=$(readlink "$0") +-if [ "${script_name}" = "" ] +-then +- script_name=$0 +-fi +-script_path=$(cd $(dirname "${script_name}") && pwd -P) +-keys_dir=${script_path}/../keys/ +-crts_dir=${script_path}/../crts/ +-ca_dir=${script_path}/../ca/ +- +-if [ ! -d "${keys_dir}" ] +-then +- echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." +- exit 1 +-fi +- +-if [ ! -d "${crts_dir}" ] +-then +- echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." +- exit 1 +-fi +- +-if [ ! -d "${ca_dir}" ] +-then +- echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." +- exit 1 +-fi +- +-# Switch current working directory to keys directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${keys_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${keys_dir}" +- exit 1 +- fi +-fi +- + # Check that the file "serial" is present, if not create it: + if [ ! -f serial ] + then +@@ -613,15 +571,4 @@ do + i=$((i+1)) + done + fi +- +-# Switch back to initial working directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${crt_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${crt_dir}" +- exit 1 +- fi +-fi + exit 0 +diff --git a/keys/hab4_pki_tree.sh b/keys/hab4_pki_tree.sh +index 944cc66..ca0058c 100755 +--- a/keys/hab4_pki_tree.sh ++++ b/keys/hab4_pki_tree.sh +@@ -266,48 +266,6 @@ then + read srk_ca + fi + +-# Check existance of keys/, crts/ and ca/ directories of before generating keys and +-# switch current working directory to /keys directory, if needed. +-crt_dir=$(pwd) +-script_name=$(readlink "$0") +-if [ "${script_name}" = "" ] +-then +- script_name=$0 +-fi +-script_path=$(cd $(dirname "${script_name}") && pwd -P) +-keys_dir=${script_path}/../keys/ +-crts_dir=${script_path}/../crts/ +-ca_dir=${script_path}/../ca/ +- +-if [ ! -d "${keys_dir}" ] +-then +- echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." +- exit 1 +-fi +- +-if [ ! -d "${crts_dir}" ] +-then +- echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." +- exit 1 +-fi +- +-if [ ! -d "${ca_dir}" ] +-then +- echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." +- exit 1 +-fi +- +-# Switch current working directory to keys directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${keys_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${keys_dir}" +- exit 1 +- fi +-fi +- + # Check that the file "serial" is present, if not create it: + if [ ! -f serial ] + then +@@ -663,15 +621,4 @@ do + i=$((i+1)) + done + fi +- +-# Switch back to initial working directory, if needed. +-if [ "${crt_dir}" != "${keys_dir}" ] +-then +- cd "${crt_dir}" +- if [ $? -ge 1 ] +- then +- echo ERROR: "Cannot change directory to ${crt_dir}" +- exit 1 +- fi +-fi + exit 0 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/debian/rules imx-code-signing-tool-3.3.1+dfsg/debian/rules --- imx-code-signing-tool-3.3.0+dfsg2/debian/rules 2021-03-23 08:54:12.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/debian/rules 2022-01-06 12:02:09.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/make -f +export DEB_BUILD_MAINT_OPTIONS = optimize=-lto + %: dh $@ Binary files /tmp/tmpwn_9lsue/aUip5Dz3W2/imx-code-signing-tool-3.3.0+dfsg2/docs/CST_UG.pdf and /tmp/tmpwn_9lsue/OfqPftrade/imx-code-signing-tool-3.3.1+dfsg/docs/CST_UG.pdf differ diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/add_key.bat imx-code-signing-tool-3.3.1+dfsg/keys/add_key.bat --- imx-code-signing-tool-3.3.0+dfsg2/keys/add_key.bat 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/add_key.bat 2021-08-12 12:53:52.000000000 +0000 @@ -1,322 +1,369 @@ -@echo off - -::----------------------------------------------------------------------------- -:: -:: File: add_key.bat -:: -:: Description: This script adds a key to an existing HAB PKI tree to be used -:: with the HAB code signing feature. Both the private key and -:: corresponding certificate are generated. This script can -:: generate new SRKs, CSF keys and Images keys for HAB4 or AHAB. -:: This script is not intended for generating CA root keys. -:: -:: (c) Freescale Semiconductor, Inc. 2011. All rights reserved. -:: Copyright 2018-2019 NXP -:: -:: -::----------------------------------------------------------------------------- - -set scriptName=%0 -set numArgs=0 -for %%x in (%*) do set /A numArgs+=1 - -if %numArgs% GTR 0 ( - set interactive=n -) else ( - set interactive=y -) - -set max_param=20 -set min_param=16 - -if %interactive%==n ( - if "%1" == "-h" ( goto usage ) - if "%1" == "--help" ( goto usage ) -) else ( - goto version -) - -:: Validate command line parameters -if %numArgs% LSS %min_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) -if %numArgs% GTR %max_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) - -:: Process command line inputs -set args=0 -set "ver=" -set "key_name=" -set "kt=" -set "kl=" -set "md=" -set "duration=" -set "srk=" -set "srk_ca=" -set "signing_key=" -set "signing_crt=" - -:PROCESSINPUT -if %args% GEQ %numArgs% goto validateargs -if "%1"=="-ver" ( - set ver=%2 - goto shiftargs -) -if "%1"=="-key-name" ( - set key_name=%2 - goto shiftargs -) -if "%1"=="-kt" ( - set kt=%2 - goto shiftargs -) -if "%1"=="-kl" ( - set kl=%2 - goto shiftargs -) -if "%1"=="-md" ( - set md=%2 - goto shiftargs -) -if "%1"=="-duration" ( - set duration=%2 - goto shiftargs -) -if "%1"=="-srk" ( - set srk=%2 - goto shiftargs -) -if "%1"=="-srk-ca" ( - set srk_ca=%2 - goto shiftargs -) -if "%1"=="-signing-key" ( - set signing_key=%2 - goto shiftargs -) -if "%1"=="-signing-crt" ( - set signing_crt=%2 - goto shiftargs -) else ( - echo ERROR: Invalid parameter: %1 - goto usage -) - -:SHIFTARGS -shift -shift -set /A args+=2 -goto processinput - -:VALIDATEARGS -if defined md ( if %ver%==4 ( - echo ERROR: Message digest is fixed for HAB4 - goto usage -)) - -if %srk%==y ( if not defined srk_ca ( - echo ERROR: SRK CA option required when SRK is selected - goto usage -)) - -goto version - -:USAGE -echo. -echo Usage:" -echo Interactive Mode:" -echo %scriptName% -echo. -echo Command Line Mode:" -echo "%scriptName% -ver <4/a> -key-name -kt -kl [-md ] -duration -srk [-srk-ca ] -signing-key -signing-crt " -echo Options:" -echo -kl: -kt = ecc then Supported key lengths: p256, p384, p521 -echo : -kt = rsa then Supported key lengths: 2048, 3072, 4096 -echo -md: -ver = a then Supported message digests: sha256, sha384, sha512 -echo : -ver = 4 then md = sha256 is fixed -echo. -echo "%scriptName% -h | --help : This text" -echo. -exit /B - -:VERSION -if %interactive%==y ( - set /P ver="Which version of HAB do you want to generate the key for (4 = HAB4 / a = AHAB)?: " -) -if %ver%==4 goto VALID_ver -if %ver%==a goto VALID_ver -echo Error - HAB version selected must be either 3, 4 or a -exit /B -:VALID_ver - -if %interactive%==y ( - set /P key_name="Enter new key name (e.g. SRK5): " -) - -:: Key type -:: AHAB or HAB4 -if %interactive%==y ( - set /P kt="Enter new key type (ecc / rsa): " -) -:: Confirm that a valid key type has been entered -if %kt%==ecc goto KEY_TYPE_DONE -if %kt%==rsa goto KEY_TYPE_DONE -echo Invalid key type. Supported key types: rsa, ecc -exit /B -:KEY_TYPE_DONE - -:: Key length -if not %kt%==rsa goto KEY_LENGTH_ECC -:: RSA -if %interactive%==y ( - set /P kl="Enter new key length in bits: " -) -:: Confirm that a valid key length has been entered -if %kl%==2048 goto VALID_KEY_LENGTH -if %kl%==3072 goto VALID_KEY_LENGTH -if %kl%==4096 goto VALID_KEY_LENGTH -echo Invalid key length. Supported key lengths: 2048, 3072, 4096 -exit /B -:KEY_LENGTH_ECC -:: ECC -if %interactive%==y ( - set /P kl="Enter new key length (p256 / p384 / p521): " -) -:: Confirm that a valid key length has been entered -if %kl%==p256 set "cn=prime256v1" & goto VALID_KEY_LENGTH -if %kl%==p384 set "cn=secp384r1" & goto VALID_KEY_LENGTH -if %kl%==p521 set "cn=secp521r1" & goto VALID_KEY_LENGTH -echo Invalid key length. Supported key lengths: 256, 384, 521 -exit /B -:VALID_KEY_LENGTH - -:: Message digest -if not %ver%==a goto MD_DEFAULT -:: AHAB -if %interactive%==y ( - set /P md="Enter new message digest (sha256, sha384, sha512): " -) -:: Confirm that a valid message digest has been entered -if %md%==sha256 goto MD_DONE -if %md%==sha384 goto MD_DONE -if %md%==sha512 goto MD_DONE -echo Invalid message digest. Supported message digests: sha256, sha384, sha512 -exit /B -:: HAB4 -:MD_DEFAULT -set md=sha256 -:MD_DONE - -if %interactive%==y ( - set /P duration="Enter certificate duration (years): " -) - -:: Compute validity period -set /A val_period=%duration%*365 - -:: ---------------- Add SRK key and certificate ------------------- -if %interactive%==y ( - set /P srk="Is this an SRK key? " -) -if %srk%==n goto GEN_CSF_IMG_SGK - -:: Check if SRKs should be generated as CA certs or user certs -if %ver%==3 goto CA_DEFAULT -if %interactive%==y ( - set /P srk_ca="Do you want the SRK to have the CA flag set (y/n)?: " -) -if %srk_ca%==y goto CA_DEFAULT -set ca=usr -goto CA_DONE -:CA_DEFAULT -set ca=ca -:CA_DONE - -if %interactive%==y ( - set /P signing_key="Enter CA signing key name: " - set /P signing_crt="Enter CA signing certificate name: " -) -goto GEN_OUTPUTS - -:GEN_CSF_IMG_SGK -if %ver%==a goto GEN_SGK - -:: ---------------- Add CSF/IMG key and certificate ------------------- -set ca=usr -if %interactive%==y ( - set /P signing_key="Enter SRK signing key name: " - set /P signing_crt="Enter SRK signing certificate name: " -) -goto GEN_OUTPUTS - -:GEN_SGK -:: ---------------- Add SGK key and certificate ------------------- -set ca="usr" -set /P signing_key="Enter SRK signing key name: " -set /P signing_crt="Enter SRK signing certificate name: " -goto GEN_OUTPUTS - -:GEN_OUTPUTS -:: ---------------- Generate outputs ------------------------------ - -:: Generate key -if %kt%==rsa goto GEN_KEY_RSA -set key_fullname=%key_name%_%md%_%cn%_v3_%ca% -:: Generate Elliptic Curve parameters -openssl ecparam -out %key_fullname%_key.pem -name %cn% -genkey -:: Generate ECC key -openssl ec -in %key_fullname%_key.pem -des3 -passout file:key_pass.txt ^ - -out %key_fullname%_key.pem -goto GEN_KEY_DONE -:GEN_KEY_RSA -set key_fullname=%key_name%_%md%_%kl%_65537_v3_%ca% -:: Generate RSA key -openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out %key_fullname%_key.pem %kl% -:GEN_KEY_DONE - -:: Generate certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj /CN=%key_fullname%/ ^ - -key %key_fullname%_key.pem ^ - -out %key_fullname%_req.pem - -:: Generate certificate -openssl ca -batch -passin file:key_pass.txt ^ - -md %md% -outdir . ^ - -in %key_fullname%_req.pem ^ - -cert %signing_crt% ^ - -keyfile %signing_key% ^ - -extfile ..\\ca\\v3_%ca%.cnf ^ - -out ..\\crts\\%key_fullname%_crt.pem ^ - -days %val_period% ^ - -config ..\\ca\\openssl.cnf - -:: Convert certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in ..\\crts\\%key_fullname%_crt.pem ^ - -out ..\\crts\\%key_fullname%_crt.der - -:: Generate key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in %key_fullname%_key.pem ^ - -out %key_fullname%_key.der - -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in %key_fullname%_key.pem ^ - -out %key_fullname%_key_tmp.pem - -del /F %key_fullname%_key.pem -ren %key_fullname%_key_tmp.pem %key_fullname%_key.pem - -:CLEAN -:: Clean up -del /F *_req.pem -exit /B +@echo off + +::----------------------------------------------------------------------------- +:: +:: File: add_key.bat +:: +:: Description: This script adds a key to an existing HAB PKI tree to be used +:: with the HAB code signing feature. Both the private key and +:: corresponding certificate are generated. This script can +:: generate new SRKs, CSF keys and Images keys for HAB4 or AHAB. +:: This script is not intended for generating CA root keys. +:: +:: (c) Freescale Semiconductor, Inc. 2011. All rights reserved. +:: Copyright 2018-2019 NXP +:: +:: +::----------------------------------------------------------------------------- + +set scriptName=%0 +set scriptPath=%~dp0 +set numArgs=0 +for %%x in (%*) do set /A numArgs+=1 + +if %numArgs% GTR 0 ( + set interactive=n +) else ( + set interactive=y +) + +set max_param=20 +set min_param=16 + +if %interactive%==n ( + if "%1" == "-h" ( goto usage ) + if "%1" == "--help" ( goto usage ) +) else ( + goto version +) + +:: Validate command line parameters +if %numArgs% LSS %min_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) +if %numArgs% GTR %max_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) + +:: Process command line inputs +set args=0 +set "ver=" +set "key_name=" +set "kt=" +set "kl=" +set "md=" +set "duration=" +set "srk=" +set "srk_ca=" +set "signing_key=" +set "signing_crt=" + +:PROCESSINPUT +if %args% GEQ %numArgs% goto validateargs +if "%1"=="-ver" ( + set ver=%2 + goto shiftargs +) +if "%1"=="-key-name" ( + set key_name=%2 + goto shiftargs +) +if "%1"=="-kt" ( + set kt=%2 + goto shiftargs +) +if "%1"=="-kl" ( + set kl=%2 + goto shiftargs +) +if "%1"=="-md" ( + set md=%2 + goto shiftargs +) +if "%1"=="-duration" ( + set duration=%2 + goto shiftargs +) +if "%1"=="-srk" ( + set srk=%2 + goto shiftargs +) +if "%1"=="-srk-ca" ( + set srk_ca=%2 + goto shiftargs +) +if "%1"=="-signing-key" ( + set signing_key=%2 + goto shiftargs +) +if "%1"=="-signing-crt" ( + set signing_crt=%2 + goto shiftargs +) else ( + echo ERROR: Invalid parameter: %1 + goto usage +) + +:SHIFTARGS +shift +shift +set /A args+=2 +goto processinput + +:VALIDATEARGS +if defined md ( if %ver%==4 ( + echo ERROR: Message digest is fixed for HAB4 + goto usage +)) + +if %srk%==y ( if not defined srk_ca ( + echo ERROR: SRK CA option required when SRK is selected + goto usage +)) + +goto version + +:USAGE +echo. +echo Usage:" +echo Interactive Mode:" +echo %scriptName% +echo. +echo Command Line Mode:" +echo "%scriptName% -ver <4/a> -key-name -kt -kl [-md ] -duration -srk [-srk-ca ] -signing-key -signing-crt " +echo Options:" +echo -kl: -kt = ecc then Supported key lengths: p256, p384, p521 +echo : -kt = rsa then Supported key lengths: 2048, 3072, 4096 +echo -md: -ver = a then Supported message digests: sha256, sha384, sha512 +echo : -ver = 4 then md = sha256 is fixed +echo. +echo "%scriptName% -h | --help : This text" +echo. +exit /B + +:VERSION +if %interactive%==y ( + set /P ver="Which version of HAB do you want to generate the key for (4 = HAB4 / a = AHAB)?: " +) +if %ver%==4 goto VALID_ver +if %ver%==a goto VALID_ver +echo Error - HAB version selected must be either 3, 4 or a +exit /B +:VALID_ver + +if %interactive%==y ( + set /P key_name="Enter new key name (e.g. SRK5): " +) + +:: Key type +:: AHAB or HAB4 +if %interactive%==y ( + set /P kt="Enter new key type (ecc / rsa): " +) +:: Confirm that a valid key type has been entered +if %kt%==ecc goto KEY_TYPE_DONE +if %kt%==rsa goto KEY_TYPE_DONE +echo Invalid key type. Supported key types: rsa, ecc +exit /B +:KEY_TYPE_DONE + +:: Key length +if not %kt%==rsa goto KEY_LENGTH_ECC +:: RSA +if %interactive%==y ( + set /P kl="Enter new key length in bits: " +) +:: Confirm that a valid key length has been entered +if %kl%==2048 goto VALID_KEY_LENGTH +if %kl%==3072 goto VALID_KEY_LENGTH +if %kl%==4096 goto VALID_KEY_LENGTH +echo Invalid key length. Supported key lengths: 2048, 3072, 4096 +exit /B +:KEY_LENGTH_ECC +:: ECC +if %interactive%==y ( + set /P kl="Enter new key length (p256 / p384 / p521): " +) +:: Confirm that a valid key length has been entered +if %kl%==p256 set "cn=prime256v1" & goto VALID_KEY_LENGTH +if %kl%==p384 set "cn=secp384r1" & goto VALID_KEY_LENGTH +if %kl%==p521 set "cn=secp521r1" & goto VALID_KEY_LENGTH +echo Invalid key length. Supported key lengths: 256, 384, 521 +exit /B +:VALID_KEY_LENGTH + +:: Message digest +if not %ver%==a goto MD_DEFAULT +:: AHAB +if %interactive%==y ( + set /P md="Enter new message digest (sha256, sha384, sha512): " +) +:: Confirm that a valid message digest has been entered +if %md%==sha256 goto MD_DONE +if %md%==sha384 goto MD_DONE +if %md%==sha512 goto MD_DONE +echo Invalid message digest. Supported message digests: sha256, sha384, sha512 +exit /B +:: HAB4 +:MD_DEFAULT +set md=sha256 +:MD_DONE + +if %interactive%==y ( + set /P duration="Enter certificate duration (years): " +) + +:: Compute validity period +set /A val_period=%duration%*365 + +:: ---------------- Add SRK key and certificate ------------------- +if %interactive%==y ( + set /P srk="Is this an SRK key? " +) +if %srk%==n goto GEN_CSF_IMG_SGK + +:: Check if SRKs should be generated as CA certs or user certs +if %ver%==3 goto CA_DEFAULT +if %interactive%==y ( + set /P srk_ca="Do you want the SRK to have the CA flag set (y/n)?: " +) +if %srk_ca%==y goto CA_DEFAULT +set ca=usr +goto CA_DONE +:CA_DEFAULT +set ca=ca +:CA_DONE + +if %interactive%==y ( + set /P signing_key="Enter CA signing key name: " + set /P signing_crt="Enter CA signing certificate name: " +) +goto BEFORE_GEN_KEYS + +:GEN_CSF_IMG_SGK +if %ver%==a goto GEN_SGK + +:: ---------------- Add CSF/IMG key and certificate ------------------- +set ca=usr +if %interactive%==y ( + set /P signing_key="Enter SRK signing key name: " + set /P signing_crt="Enter SRK signing certificate name: " +) +goto BEFORE_GEN_KEYS + +:GEN_SGK +:: ---------------- Add SGK key and certificate ------------------- +set ca="usr" +set /P signing_key="Enter SRK signing key name: " +set /P signing_crt="Enter SRK signing certificate name: " +goto BEFORE_GEN_KEYS + +:BEFORE_GEN_KEYS +:: Check existance of keys/, crts/ and ca/ directories of before generating keys and +:: switch current working directory to /keys directory, if needed. +set crt_dir=%cd% +set keys_dir=%scriptPath%\\..\\keys\\ +set crts_dir=%scriptPath%\\..\\crts\\ +set ca_dir=%scriptPath%\\..\\ca\\ + +if not exist "%keys_dir%" ( + echo ERROR: Private keys directory %keys_dir% is missing. Expecting script to be located inside ^/keys directory. + exit /B +) + +if not exist "%crts_dir%" ( + echo ERROR: Public keys directory %crts_dir% is missing. Expecting ^/crts directory to be already created. + exit /B +) + +if not exist "%ca_dir%" ( + echo ERROR: Openssl configuration directory %ca_dir% is missing. Expecting ^/ca directory to hold openssl configuration files. + exit /B +) + +:: Switch current working directory to /keys directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%keys_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %keys_dir% + exit /B + ) +) + +:OPENSSL_INIT +:: The following is required otherwise OpenSSL complains +set OPENSSL_CONF=..\\ca\\openssl.cnf + +:GEN_OUTPUTS +:: ---------------- Generate outputs ------------------------------ + +:: Generate key +if %kt%==rsa goto GEN_KEY_RSA +set key_fullname=%key_name%_%md%_%cn%_v3_%ca% +:: Generate Elliptic Curve parameters +openssl ecparam -out %key_fullname%_key.pem -name %cn% -genkey +:: Generate ECC key +openssl ec -in %key_fullname%_key.pem -des3 -passout file:key_pass.txt ^ + -out %key_fullname%_key.pem +goto GEN_KEY_DONE +:GEN_KEY_RSA +set key_fullname=%key_name%_%md%_%kl%_65537_v3_%ca% +:: Generate RSA key +openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out %key_fullname%_key.pem %kl% +:GEN_KEY_DONE + +:: Generate certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj /CN=%key_fullname%/ ^ + -key %key_fullname%_key.pem ^ + -out %key_fullname%_req.pem + +:: Generate certificate +openssl ca -batch -passin file:key_pass.txt ^ + -md %md% -outdir . ^ + -in %key_fullname%_req.pem ^ + -cert %signing_crt% ^ + -keyfile %signing_key% ^ + -extfile ..\\ca\\v3_%ca%.cnf ^ + -out ..\\crts\\%key_fullname%_crt.pem ^ + -days %val_period% ^ + -config ..\\ca\\openssl.cnf + +:: Convert certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in ..\\crts\\%key_fullname%_crt.pem ^ + -out ..\\crts\\%key_fullname%_crt.der + +:: Generate key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in %key_fullname%_key.pem ^ + -out %key_fullname%_key.der + +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in %key_fullname%_key.pem ^ + -out %key_fullname%_key_tmp.pem + +del /F %key_fullname%_key.pem +ren %key_fullname%_key_tmp.pem %key_fullname%_key.pem + +:CLEAN +:: Clean up +del /F *_req.pem + +:DONE +:: Switch back to initial working directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%crt_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %crt_dir% + exit /B + ) +) +exit /B diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/add_key.sh imx-code-signing-tool-3.3.1+dfsg/keys/add_key.sh --- imx-code-signing-tool-3.3.0+dfsg2/keys/add_key.sh 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/add_key.sh 2021-08-12 12:53:52.000000000 +0000 @@ -305,6 +305,48 @@ fi fi +# Check existance of keys/, crts/ and ca/ directories of before generating keys and +# switch current working directory to /keys directory, if needed. +crt_dir=$(pwd) +script_name=$(readlink "$0") +if [ "${script_name}" = "" ] +then + script_name=$0 +fi +script_path=$(cd $(dirname "${script_name}") && pwd -P) +keys_dir=${script_path}/../keys/ +crts_dir=${script_path}/../crts/ +ca_dir=${script_path}/../ca/ + +if [ ! -d "${keys_dir}" ] +then + echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." + exit 1 +fi + +if [ ! -d "${crts_dir}" ] +then + echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." + exit 1 +fi + +if [ ! -d "${ca_dir}" ] +then + echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." + exit 1 +fi + +# Switch current working directory to keys directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${keys_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${keys_dir}" + exit 1 + fi +fi + # Generate outputs if [ $kt = "ecc" ] then @@ -362,4 +404,15 @@ # Clean up \rm -f *_req.pem + +# Switch back to initial working directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${crt_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${crt_dir}" + exit 1 + fi +fi exit 0 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/ahab_pki_tree.bat imx-code-signing-tool-3.3.1+dfsg/keys/ahab_pki_tree.bat --- imx-code-signing-tool-3.3.0+dfsg2/keys/ahab_pki_tree.bat 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/ahab_pki_tree.bat 2021-08-12 12:53:52.000000000 +0000 @@ -1,538 +1,582 @@ -@echo off - -::----------------------------------------------------------------------------- -:: -:: File: ahab_pki_tree.bat -:: -:: Description: This script generates a basic AHAB PKI tree for the NXP -:: AHAB code signing feature. What the PKI tree looks like depends -:: on whether the SRK is chosen to be a CA key or not. If the -:: SRKs are chosen to be CA keys then this script will generate the -:: following PKI tree: -:: -:: CA Key -:: | | | -:: -------- + | +--------------- -:: / | ^ -:: SRK1 SRK2 ... SRKN -:: | | | -:: | | | -:: SGK1 SGK2 SGKN -:: -:: where: N can be 1 to 4. -:: -:: Additional keys can be added to the tree separately. In this -:: configuration SRKs may only be used to sign/verify other -:: keys/certificates -:: -:: If the SRKs are chosen to be non-CA keys then this script will -:: generate the following PKI tree: -:: -:: CA Key -:: | | | -:: -------- + | +--------------- -:: / | ^ -:: SRK1 SRK2 ... SRKN -:: -:: In this configuration SRKs may only be used to sign code/data -:: and not other keys. Note that not all NXP processors -:: including AHAB support this option. -:: -:: Copyright 2018-2019 NXP -:: -::----------------------------------------------------------------------------- - -echo. -echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -echo This script is a part of the Code signing tools for NXP's -echo Advanced High Assurance Boot. It generates a basic PKI tree. The -echo PKI tree consists of one or more Super Root Keys (SRK), with each -echo SRK having one subordinate keys: -echo + a Signing key (SGK) -echo Additional keys can be added to the PKI tree but a separate -echo script is available for this. This this script assumes openssl -echo is installed on your system and is included in your search -echo path. Finally, the private keys generated are password -echo protectedwith the password provided by the file key_pass.txt. -echo The format of the file is the password repeated twice: -echo my_password -echo my_password -echo All private keys in the PKI tree are in PKCS #8 format will be -echo protected by the same password. -echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -echo. - -set scriptName=%0 -set numArgs=0 -for %%x in (%*) do set /A numArgs+=1 - -if %numArgs% GTR 0 ( - set interactive=n -) else ( - set interactive=y -) - -set max_param=16 -set min_param=12 - -if %interactive%==n ( - if "%1" == "-h" ( goto usage ) - if "%1" == "--help" ( goto usage ) -) else ( - goto process_ca_key -) - -:: Validate command line parameters -if %numArgs% LSS %min_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) -if %numArgs% GTR %max_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) - -:: Process command line inputs -set args=0 -set "existing_ca=" -set "ca_key=" -set "ca_cert=" -set "use_ecc=" -set "kl=" -set "da=" -set "duration=" -set "srk_ca=" - -:PROCESSINPUT -if %args% GEQ %numArgs% goto validateargs -if "%1"=="-existing-ca" ( - set existing_ca=%2 - goto shiftargs -) -if "%1"=="-ca-key" ( - set ca_key=%2 - goto shiftargs -) -if "%1"=="-ca-cert" ( - set ca_cert=%2 - goto shiftargs -) -if "%1"=="-use-ecc" ( - set use_ecc=%2 - goto shiftargs -) -if "%1"=="-kl" ( - set kl=%2 - goto shiftargs -) -if "%1"=="-da" ( - set da=%2 - goto shiftargs -) -if "%1"=="-duration" ( - set duration=%2 - goto shiftargs -) -if "%1"=="-srk-ca" ( - set srk_ca=%2 - goto shiftargs -) else ( - echo ERROR: Invalid parameter: %1 - goto usage -) - -:SHIFTARGS -shift -shift -set /A args+=2 -goto processinput - -:VALIDATEARGS -if %existing_ca%==y ( if not defined ca_key ( - echo ERROR: CA key is required. - goto usage -)) - -if %existing_ca%==y ( if not defined ca_cert ( - echo ERROR: CA cert is required - goto usage -)) - -goto process_ca_key - -:USAGE -echo. -echo Usage: -echo Interactive Mode: -echo %scriptName% -echo. -echo Command Line Mode: -echo "%scriptName% -existing-ca [-ca-key -ca-cert ] -use-ecc -kl -da -duration -srk-ca " -echo Options: -echo -kl: -use-ecc = y then Supported key lengths: p256, p384, p521 -echo : -use-ecc = n then Supported key lengths: 2048, 3072, 4096 -echo -da: Supported digest algorithms: sha256, sha384, sha512 -echo. -echo "%scriptName% -h | --help : This text" -echo. -exit /B - -:PROCESS_CA_KEY -if %interactive%==y ( - set /P existing_ca="Do you want to use an existing CA key (y/n)?: " -) -if %existing_ca%==n goto KEY_TYPE -if %interactive%==y ( - set /P ca_key="Enter CA key name: " - set /P ca_cert="Enter CA certificate name: " -) - -:KEY_TYPE -if %interactive%==y ( - set /P use_ecc="Do you want to use Elliptic Curve Cryptography (y/n)?: " -) -if %use_ecc%==n goto KEY_LENGTH_RSA - -:KEY_LENGTH_ECC -if %interactive%==y ( - set /P kl="Enter length for elliptic curve to be used for PKI tree (possible values p256, p384, p521): " -) -:: Confirm that a valid key length has been entered -if %kl%==p256 set "cn=prime256v1" & goto DIGEST_ALGO -if %kl%==p384 set "cn=secp384r1" & goto DIGEST_ALGO -if %kl%==p521 set "cn=secp521r1" & goto DIGEST_ALGO -echo Invalid key length. Supported key lengths: 256, 384, 521 -exit /B - -:KEY_LENGTH_RSA -if %interactive%==y ( - set /P kl="Enter key length in bits for PKI tree: " -) -:: Confirm that a valid key length has been entered -if %kl%==2048 goto DIGEST_ALGO -if %kl%==3072 goto DIGEST_ALGO -if %kl%==4096 goto DIGEST_ALGO -echo Invalid key length. Supported key lengths: 2048, 3072, 4096 -exit /B - -:DIGEST_ALGO -if %interactive%==y ( - set /P da="Enter the digest algorithm to use: " -) -:: Confirm that a valid digest algorithm has been entered -if %da%==sha256 goto KEY_DURATION -if %da%==sha384 goto KEY_DURATION -if %da%==sha512 goto KEY_DURATION -echo Invalid digest algorithm. Supported digest algorithms: sha256, sha384, sha512 -exit /B - -:KEY_DURATION -if %interactive%==y ( - set /P duration="Enter PKI tree duration (years): " -) -:: Compute validity period -set /A val_period=%duration%*365 - -:NUMBER_OF_SRKS -:: set /P num_srk="How many Super Root Keys should be generated? " -set num_srk=4 -set /A max=%num_srk%+1 -:: Check that 0 < num_srk <= 4 (Max. number of SRKs) -if %num_srk%==1 goto CA_SRK -if %num_srk%==2 goto CA_SRK -if %num_srk%==3 goto CA_SRK -if %num_srk%==4 goto CA_SRK -echo The number of SRKs generated must be between 1 and 4 -exit /B - -:CA_SRK -:: Check if SRKs should be generated as CA certs or user certs -if %interactive%==y ( - set /P srk_ca="Do you want the SRK certificates to have the CA flag set? (y/n)?: " -) - -:SERIAL -:: Check that the file "serial" is present, if not create it: -if exist "serial" goto KEY_PASS -echo 12345678 > serial -echo A default 'serial' file was created! - -:KEY_PASS -:: Check that the file "key_pass.txt" is present, if not create it with default user/pwd: -if exist "key_pass.txt" goto OPENSSL_INIT -echo test> key_pass.txt -echo test>> key_pass.txt -echo A default file 'key_pass.txt' was created with password = test! - -:OPENSSL_INIT -:: Convert file in Unix format for OpenSSL 1.0.2 -convlb key_pass.txt -:: The following is required otherwise OpenSSL complains -if exist index.txt del /F index.txt -if exist index.txt.attr del /F index.txt.attr -type nul > index.txt -echo unique_subject = no > index.txt.attr -set OPENSSL_CONF=..\\ca\\openssl.cnf - -:GEN_CA -if %existing_ca%==y goto GEN_SRK -:: Generate CA key and certificate -:: ------------------------------- -echo. -echo +++++++++++++++++++++++++++++++++++++ -echo + Generating CA key and certificate + -echo +++++++++++++++++++++++++++++++++++++ -echo. - -if %use_ecc%==n ( - set ca_key=CA1_%da%_%kl%_65537_v3_ca_key - set ca_cert=..\\crts\\CA1_%da%_%kl%_65537_v3_ca_crt - set ca_subj_req=/CN=CA1_%da%_%kl%_65537_v3_ca/ - set ca_key_type=rsa:%kl% -) else ( - openssl ecparam -out ec-%cn%.pem -name %cn% - set ca_key=CA1_%da%_%cn%_v3_ca_key - set ca_cert=..\\crts\\CA1_%da%_%cn%_v3_ca_crt - set ca_subj_req=/CN=CA1_%da%_%cn%_v3_ca/ - set ca_key_type=ec:ec-%cn%.pem -) - -openssl req -newkey %ca_key_type% -passout file:key_pass.txt ^ - -%da% ^ - -subj %ca_subj_req% ^ - -x509 -extensions v3_ca ^ - -keyout temp_ca.pem ^ - -out %ca_cert%.pem ^ - -days %val_period% - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_ca.pem ^ - -out %ca_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_ca.pem ^ - -out %ca_key%.pem - -:: Convert CA Certificate to DER format -openssl x509 -inform PEM -outform DER -in %ca_cert%.pem -out %ca_cert%.der - -:: Cleanup -del /F temp_ca.pem - -:GEN_SRK -if %srk_ca%==y goto GEN_SRK_SGK -:: Generate SRK keys and certificates (non-CA) -:: SRKs suitable for signing code/data -:: ------------------------------------------- - -:: SRK Loop index -set /A i=1 -:LOOP_SRK -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating SRK key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. -if %use_ecc%==n ( - :: Generate SRK key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out temp_srk.pem %kl% - - set srk_subj_req=/CN=SRK%i%_%da%_%kl%_65537_v3_usr/ - set srk_crt=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_usr_crt - set srk_key=SRK%i%_%da%_%kl%_65537_v3_usr_key -) else ( - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_srk.pem -name %cn% -genkey - :: Generate SRK key - openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ - -out temp_srk.pem - - set srk_subj_req=/CN=SRK%i%_%da%_%cn%_v3_usr/ - set srk_crt=..\\crts\\SRK%i%_%da%_%cn%_v3_usr_crt - set srk_key=SRK%i%_%da%_%cn%_v3_usr_key -) - -:: Generate SRK certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %srk_subj_req% ^ - -key temp_srk.pem ^ - -out temp_srk_req.pem - -:: Generate SRK certificate (this is a CA cert) -openssl ca -batch -passin file:key_pass.txt ^ - -md %da% -outdir . ^ - -in temp_srk_req.pem ^ - -cert %ca_cert%.pem ^ - -keyfile %ca_key%.pem ^ - -extfile ..\\ca\\v3_usr.cnf ^ - -out %srk_crt%.pem ^ - -days %val_period% - -:: Convert SRK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %srk_crt%.pem ^ - -out %srk_crt%.der - -:: Generate SRK key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.der - -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.pem - -:: Cleanup -del /F temp_srk.pem temp_srk_req.pem - -set /A i+=1 -if %i%==%max% exit /B -goto LOOP_SRK - -:GEN_SRK_SGK -:: Generate SRK keys and certficiates (CA) -:: Generate SGK keys and certificates (non-CA) -:: SGKs suitable for signing code/data -:: ------------------------------------------- - -:: SRK Loop index -set /A i=1 -:LOOP_SRK_SGK -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating SRK key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. - -if %use_ecc%==n ( - :: Generate SRK key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out ./temp_srk.pem %kl% - - set srk_subj_req=/CN=SRK%i%_%da%_%kl%_65537_v3_ca/ - set srk_crt=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_ca_crt - set srk_key=SRK%i%_%da%_%kl%_65537_v3_ca_key -) else ( - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_srk.pem -name %cn% -genkey - :: Generate SRK key - openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ - -out temp_srk.pem - - set srk_subj_req=/CN=SRK%i%_%da%_%cn%_v3_ca/ - set srk_crt=..\\crts\\SRK%i%_%da%_%cn%_v3_ca_crt - set srk_key=SRK%i%_%da%_%cn%_v3_ca_key -) -:: Generate SRK certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %srk_subj_req% ^ - -key temp_srk.pem ^ - -out temp_srk_req.pem - -:: Generate SRK certificate (this is a CA cert) -openssl ca -batch -passin file:key_pass.txt ^ - -md %da% -outdir . ^ - -in temp_srk_req.pem ^ - -cert %ca_cert%.pem ^ - -keyfile %ca_key%.pem ^ - -extfile ..\\ca\\v3_ca.cnf ^ - -out %srk_crt%.pem ^ - -days %val_period% - -:: Convert SRK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %srk_crt%.pem ^ - -out %srk_crt%.der - -:: Generate SRK key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.der - -openssl pkcs8 -passin file:key_pass.txt ^ - -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.pem - -:: Cleanup -del /F temp_srk.pem temp_srk_req.pem - -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating SGK key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. - -if %use_ecc%==n ( - set srk_crt_i=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_ca_crt.pem - set srk_key_i=SRK%i%_%da%_%kl%_65537_v3_ca_key.pem - :: Generate key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out ./temp_sgk.pem %kl% - - set sgk_subj_req=/CN=SGK%i%_1_%da%_%kl%_65537_v3_usr/ - set sgk_crt=..\\crts\\SGK%i%_1_%da%_%kl%_65537_v3_usr_crt - set sgk_key=SGK%i%_1_%da%_%kl%_65537_v3_usr_key -) else ( - set srk_crt_i=..\\crts\\SRK%i%_%da%_%cn%_v3_ca_crt.pem - set srk_key_i=SRK%i%_%da%_%cn%_v3_ca_key.pem - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_sgk.pem -name %cn% -genkey - :: Generate key - openssl ec -in temp_sgk.pem -des3 -passout file:key_pass.txt ^ - -out temp_sgk.pem - - set sgk_subj_req=/CN=SGK%i%_1_%da%_%cn%_v3_usr/ - set sgk_crt=..\\crts\\SGK%i%_1_%da%_%cn%_v3_usr_crt - set sgk_key=SGK%i%_1_%da%_%cn%_v3_usr_key -) - -:: Generate SGK certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %sgk_subj_req% ^ - -key temp_sgk.pem ^ - -out temp_sgk_req.pem - -:: Generate SGK certificate (this is a user cert) -openssl ca -batch -md %da% -outdir . ^ - -passin file:key_pass.txt ^ - -in temp_sgk_req.pem ^ - -cert %srk_crt_i% ^ - -keyfile %srk_key_i% ^ - -extfile ..\\ca\\v3_usr.cnf ^ - -out %sgk_crt%.pem ^ - -days %val_period% - -:: Convert SGK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %sgk_crt%.pem ^ - -out %sgk_crt%.der - -:: Generate SGK key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_sgk.pem ^ - -out %sgk_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_sgk.pem ^ - -out %sgk_key%.pem - -:: Cleanup -del /F temp_sgk.pem temp_sgk_req.pem - -set /A i+=1 -if %i%==%max% exit /B -goto LOOP_SRK_SGK +@echo off + +::----------------------------------------------------------------------------- +:: +:: File: ahab_pki_tree.bat +:: +:: Description: This script generates a basic AHAB PKI tree for the NXP +:: AHAB code signing feature. What the PKI tree looks like depends +:: on whether the SRK is chosen to be a CA key or not. If the +:: SRKs are chosen to be CA keys then this script will generate the +:: following PKI tree: +:: +:: CA Key +:: | | | +:: -------- + | +--------------- +:: / | ^ +:: SRK1 SRK2 ... SRKN +:: | | | +:: | | | +:: SGK1 SGK2 SGKN +:: +:: where: N can be 1 to 4. +:: +:: Additional keys can be added to the tree separately. In this +:: configuration SRKs may only be used to sign/verify other +:: keys/certificates +:: +:: If the SRKs are chosen to be non-CA keys then this script will +:: generate the following PKI tree: +:: +:: CA Key +:: | | | +:: -------- + | +--------------- +:: / | ^ +:: SRK1 SRK2 ... SRKN +:: +:: In this configuration SRKs may only be used to sign code/data +:: and not other keys. Note that not all NXP processors +:: including AHAB support this option. +:: +:: Copyright 2018-2019 NXP +:: +::----------------------------------------------------------------------------- + +echo. +echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +echo This script is a part of the Code signing tools for NXP's +echo Advanced High Assurance Boot. It generates a basic PKI tree. The +echo PKI tree consists of one or more Super Root Keys (SRK), with each +echo SRK having one subordinate keys: +echo + a Signing key (SGK) +echo Additional keys can be added to the PKI tree but a separate +echo script is available for this. This this script assumes openssl +echo is installed on your system and is included in your search +echo path. Finally, the private keys generated are password +echo protectedwith the password provided by the file key_pass.txt. +echo The format of the file is the password repeated twice: +echo my_password +echo my_password +echo All private keys in the PKI tree are in PKCS #8 format will be +echo protected by the same password. +echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +echo. + +set scriptName=%0 +set scriptPath=%~dp0 +set numArgs=0 +for %%x in (%*) do set /A numArgs+=1 + +if %numArgs% GTR 0 ( + set interactive=n +) else ( + set interactive=y +) + +set max_param=16 +set min_param=12 + +if %interactive%==n ( + if "%1" == "-h" ( goto usage ) + if "%1" == "--help" ( goto usage ) +) else ( + goto process_ca_key +) + +:: Validate command line parameters +if %numArgs% LSS %min_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) +if %numArgs% GTR %max_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) + +:: Process command line inputs +set args=0 +set "existing_ca=" +set "ca_key=" +set "ca_cert=" +set "use_ecc=" +set "kl=" +set "da=" +set "duration=" +set "srk_ca=" + +:PROCESSINPUT +if %args% GEQ %numArgs% goto validateargs +if "%1"=="-existing-ca" ( + set existing_ca=%2 + goto shiftargs +) +if "%1"=="-ca-key" ( + set ca_key=%2 + goto shiftargs +) +if "%1"=="-ca-cert" ( + set ca_cert=%2 + goto shiftargs +) +if "%1"=="-use-ecc" ( + set use_ecc=%2 + goto shiftargs +) +if "%1"=="-kl" ( + set kl=%2 + goto shiftargs +) +if "%1"=="-da" ( + set da=%2 + goto shiftargs +) +if "%1"=="-duration" ( + set duration=%2 + goto shiftargs +) +if "%1"=="-srk-ca" ( + set srk_ca=%2 + goto shiftargs +) else ( + echo ERROR: Invalid parameter: %1 + goto usage +) + +:SHIFTARGS +shift +shift +set /A args+=2 +goto processinput + +:VALIDATEARGS +if %existing_ca%==y ( if not defined ca_key ( + echo ERROR: CA key is required. + goto usage +)) + +if %existing_ca%==y ( if not defined ca_cert ( + echo ERROR: CA cert is required + goto usage +)) + +goto process_ca_key + +:USAGE +echo. +echo Usage: +echo Interactive Mode: +echo %scriptName% +echo. +echo Command Line Mode: +echo "%scriptName% -existing-ca [-ca-key -ca-cert ] -use-ecc -kl -da -duration -srk-ca " +echo Options: +echo -kl: -use-ecc = y then Supported key lengths: p256, p384, p521 +echo : -use-ecc = n then Supported key lengths: 2048, 3072, 4096 +echo -da: Supported digest algorithms: sha256, sha384, sha512 +echo. +echo "%scriptName% -h | --help : This text" +echo. +exit /B + +:PROCESS_CA_KEY +if %interactive%==y ( + set /P existing_ca="Do you want to use an existing CA key (y/n)?: " +) +if %existing_ca%==n goto KEY_TYPE +if %interactive%==y ( + set /P ca_key="Enter CA key name: " + set /P ca_cert="Enter CA certificate name: " +) + +:KEY_TYPE +if %interactive%==y ( + set /P use_ecc="Do you want to use Elliptic Curve Cryptography (y/n)?: " +) +if %use_ecc%==n goto KEY_LENGTH_RSA + +:KEY_LENGTH_ECC +if %interactive%==y ( + set /P kl="Enter length for elliptic curve to be used for PKI tree (possible values p256, p384, p521): " +) +:: Confirm that a valid key length has been entered +if %kl%==p256 set "cn=prime256v1" & goto DIGEST_ALGO +if %kl%==p384 set "cn=secp384r1" & goto DIGEST_ALGO +if %kl%==p521 set "cn=secp521r1" & goto DIGEST_ALGO +echo Invalid key length. Supported key lengths: 256, 384, 521 +exit /B + +:KEY_LENGTH_RSA +if %interactive%==y ( + set /P kl="Enter key length in bits for PKI tree: " +) +:: Confirm that a valid key length has been entered +if %kl%==2048 goto DIGEST_ALGO +if %kl%==3072 goto DIGEST_ALGO +if %kl%==4096 goto DIGEST_ALGO +echo Invalid key length. Supported key lengths: 2048, 3072, 4096 +exit /B + +:DIGEST_ALGO +if %interactive%==y ( + set /P da="Enter the digest algorithm to use: " +) +:: Confirm that a valid digest algorithm has been entered +if %da%==sha256 goto KEY_DURATION +if %da%==sha384 goto KEY_DURATION +if %da%==sha512 goto KEY_DURATION +echo Invalid digest algorithm. Supported digest algorithms: sha256, sha384, sha512 +exit /B + +:KEY_DURATION +if %interactive%==y ( + set /P duration="Enter PKI tree duration (years): " +) +:: Compute validity period +set /A val_period=%duration%*365 + +:NUMBER_OF_SRKS +:: set /P num_srk="How many Super Root Keys should be generated? " +set num_srk=4 +set /A max=%num_srk%+1 +:: Check that 0 < num_srk <= 4 (Max. number of SRKs) +if %num_srk%==1 goto CA_SRK +if %num_srk%==2 goto CA_SRK +if %num_srk%==3 goto CA_SRK +if %num_srk%==4 goto CA_SRK +echo The number of SRKs generated must be between 1 and 4 +exit /B + +:CA_SRK +:: Check if SRKs should be generated as CA certs or user certs +if %interactive%==y ( + set /P srk_ca="Do you want the SRK certificates to have the CA flag set? (y/n)?: " +) + +:BEFORE_GEN_KEYS +:: Check existance of keys/, crts/ and ca/ directories of before generating keys and +:: switch current working directory to /keys directory, if needed. +set crt_dir=%cd% +set keys_dir=%scriptPath%\\..\\keys\\ +set crts_dir=%scriptPath%\\..\\crts\\ +set ca_dir=%scriptPath%\\..\\ca\\ + +if not exist "%keys_dir%" ( + echo ERROR: Private keys directory %keys_dir% is missing. Expecting script to be located inside ^/keys directory. + exit /B +) + +if not exist "%crts_dir%" ( + echo ERROR: Public keys directory %crts_dir% is missing. Expecting ^/crts directory to be already created. + exit /B +) + +if not exist "%ca_dir%" ( + echo ERROR: Openssl configuration directory %ca_dir% is missing. Expecting ^/ca directory to hold openssl configuration files. + exit /B +) + +:: Switch current working directory to /keys directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%keys_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %keys_dir% + exit /B + ) +) + +:SERIAL +:: Check that the file "serial" is present, if not create it: +if exist "serial" goto KEY_PASS +echo 12345678 > serial +echo A default 'serial' file was created! + +:KEY_PASS +:: Check that the file "key_pass.txt" is present, if not create it with default user/pwd: +if exist "key_pass.txt" goto OPENSSL_INIT +echo test> key_pass.txt +echo test>> key_pass.txt +echo A default file 'key_pass.txt' was created with password = test! + +:OPENSSL_INIT +:: Convert file in Unix format for OpenSSL 1.0.2 +convlb key_pass.txt +:: The following is required otherwise OpenSSL complains +if exist index.txt del /F index.txt +if exist index.txt.attr del /F index.txt.attr +type nul > index.txt +echo unique_subject = no > index.txt.attr +set OPENSSL_CONF=..\\ca\\openssl.cnf + +:GEN_CA +if %existing_ca%==y goto GEN_SRK +:: Generate CA key and certificate +:: ------------------------------- +echo. +echo +++++++++++++++++++++++++++++++++++++ +echo + Generating CA key and certificate + +echo +++++++++++++++++++++++++++++++++++++ +echo. + +if %use_ecc%==n ( + set ca_key=CA1_%da%_%kl%_65537_v3_ca_key + set ca_cert=..\\crts\\CA1_%da%_%kl%_65537_v3_ca_crt + set ca_subj_req=/CN=CA1_%da%_%kl%_65537_v3_ca/ + set ca_key_type=rsa:%kl% +) else ( + openssl ecparam -out ec-%cn%.pem -name %cn% + set ca_key=CA1_%da%_%cn%_v3_ca_key + set ca_cert=..\\crts\\CA1_%da%_%cn%_v3_ca_crt + set ca_subj_req=/CN=CA1_%da%_%cn%_v3_ca/ + set ca_key_type=ec:ec-%cn%.pem +) + +openssl req -newkey %ca_key_type% -passout file:key_pass.txt ^ + -%da% ^ + -subj %ca_subj_req% ^ + -x509 -extensions v3_ca ^ + -keyout temp_ca.pem ^ + -out %ca_cert%.pem ^ + -days %val_period% + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_ca.pem ^ + -out %ca_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_ca.pem ^ + -out %ca_key%.pem + +:: Convert CA Certificate to DER format +openssl x509 -inform PEM -outform DER -in %ca_cert%.pem -out %ca_cert%.der + +:: Cleanup +del /F temp_ca.pem + +:GEN_SRK +if %srk_ca%==y goto GEN_SRK_SGK +:: Generate SRK keys and certificates (non-CA) +:: SRKs suitable for signing code/data +:: ------------------------------------------- + +:: SRK Loop index +set /A i=1 +:LOOP_SRK +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating SRK key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. +if %use_ecc%==n ( + :: Generate SRK key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out temp_srk.pem %kl% + + set srk_subj_req=/CN=SRK%i%_%da%_%kl%_65537_v3_usr/ + set srk_crt=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_usr_crt + set srk_key=SRK%i%_%da%_%kl%_65537_v3_usr_key +) else ( + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_srk.pem -name %cn% -genkey + :: Generate SRK key + openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ + -out temp_srk.pem + + set srk_subj_req=/CN=SRK%i%_%da%_%cn%_v3_usr/ + set srk_crt=..\\crts\\SRK%i%_%da%_%cn%_v3_usr_crt + set srk_key=SRK%i%_%da%_%cn%_v3_usr_key +) + +:: Generate SRK certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %srk_subj_req% ^ + -key temp_srk.pem ^ + -out temp_srk_req.pem + +:: Generate SRK certificate (this is a CA cert) +openssl ca -batch -passin file:key_pass.txt ^ + -md %da% -outdir . ^ + -in temp_srk_req.pem ^ + -cert %ca_cert%.pem ^ + -keyfile %ca_key%.pem ^ + -extfile ..\\ca\\v3_usr.cnf ^ + -out %srk_crt%.pem ^ + -days %val_period% + +:: Convert SRK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %srk_crt%.pem ^ + -out %srk_crt%.der + +:: Generate SRK key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.der + +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.pem + +:: Cleanup +del /F temp_srk.pem temp_srk_req.pem + +set /A i+=1 +if %i%==%max% exit /B +goto LOOP_SRK + +:GEN_SRK_SGK +:: Generate SRK keys and certficiates (CA) +:: Generate SGK keys and certificates (non-CA) +:: SGKs suitable for signing code/data +:: ------------------------------------------- + +:: SRK Loop index +set /A i=1 +:LOOP_SRK_SGK +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating SRK key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. + +if %use_ecc%==n ( + :: Generate SRK key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out ./temp_srk.pem %kl% + + set srk_subj_req=/CN=SRK%i%_%da%_%kl%_65537_v3_ca/ + set srk_crt=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_ca_crt + set srk_key=SRK%i%_%da%_%kl%_65537_v3_ca_key +) else ( + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_srk.pem -name %cn% -genkey + :: Generate SRK key + openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ + -out temp_srk.pem + + set srk_subj_req=/CN=SRK%i%_%da%_%cn%_v3_ca/ + set srk_crt=..\\crts\\SRK%i%_%da%_%cn%_v3_ca_crt + set srk_key=SRK%i%_%da%_%cn%_v3_ca_key +) +:: Generate SRK certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %srk_subj_req% ^ + -key temp_srk.pem ^ + -out temp_srk_req.pem + +:: Generate SRK certificate (this is a CA cert) +openssl ca -batch -passin file:key_pass.txt ^ + -md %da% -outdir . ^ + -in temp_srk_req.pem ^ + -cert %ca_cert%.pem ^ + -keyfile %ca_key%.pem ^ + -extfile ..\\ca\\v3_ca.cnf ^ + -out %srk_crt%.pem ^ + -days %val_period% + +:: Convert SRK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %srk_crt%.pem ^ + -out %srk_crt%.der + +:: Generate SRK key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.der + +openssl pkcs8 -passin file:key_pass.txt ^ + -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.pem + +:: Cleanup +del /F temp_srk.pem temp_srk_req.pem + +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating SGK key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. + +if %use_ecc%==n ( + set srk_crt_i=..\\crts\\SRK%i%_%da%_%kl%_65537_v3_ca_crt.pem + set srk_key_i=SRK%i%_%da%_%kl%_65537_v3_ca_key.pem + :: Generate key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out ./temp_sgk.pem %kl% + + set sgk_subj_req=/CN=SGK%i%_1_%da%_%kl%_65537_v3_usr/ + set sgk_crt=..\\crts\\SGK%i%_1_%da%_%kl%_65537_v3_usr_crt + set sgk_key=SGK%i%_1_%da%_%kl%_65537_v3_usr_key +) else ( + set srk_crt_i=..\\crts\\SRK%i%_%da%_%cn%_v3_ca_crt.pem + set srk_key_i=SRK%i%_%da%_%cn%_v3_ca_key.pem + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_sgk.pem -name %cn% -genkey + :: Generate key + openssl ec -in temp_sgk.pem -des3 -passout file:key_pass.txt ^ + -out temp_sgk.pem + + set sgk_subj_req=/CN=SGK%i%_1_%da%_%cn%_v3_usr/ + set sgk_crt=..\\crts\\SGK%i%_1_%da%_%cn%_v3_usr_crt + set sgk_key=SGK%i%_1_%da%_%cn%_v3_usr_key +) + +:: Generate SGK certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %sgk_subj_req% ^ + -key temp_sgk.pem ^ + -out temp_sgk_req.pem + +:: Generate SGK certificate (this is a user cert) +openssl ca -batch -md %da% -outdir . ^ + -passin file:key_pass.txt ^ + -in temp_sgk_req.pem ^ + -cert %srk_crt_i% ^ + -keyfile %srk_key_i% ^ + -extfile ..\\ca\\v3_usr.cnf ^ + -out %sgk_crt%.pem ^ + -days %val_period% + +:: Convert SGK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %sgk_crt%.pem ^ + -out %sgk_crt%.der + +:: Generate SGK key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_sgk.pem ^ + -out %sgk_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_sgk.pem ^ + -out %sgk_key%.pem + +:: Cleanup +del /F temp_sgk.pem temp_sgk_req.pem + +set /A i+=1 +if %i%==%max% goto DONE +goto LOOP_SRK_SGK + +:DONE +:: Switch back to initial working directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%crt_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %crt_dir% + exit /B + ) +) +exit /B diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/ahab_pki_tree.sh imx-code-signing-tool-3.3.1+dfsg/keys/ahab_pki_tree.sh --- imx-code-signing-tool-3.3.0+dfsg2/keys/ahab_pki_tree.sh 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/ahab_pki_tree.sh 2021-08-12 12:53:52.000000000 +0000 @@ -277,6 +277,48 @@ read srk_ca fi +# Check existance of keys/, crts/ and ca/ directories of before generating keys and +# switch current working directory to /keys directory, if needed. +crt_dir=$(pwd) +script_name=$(readlink "$0") +if [ "${script_name}" = "" ] +then + script_name=$0 +fi +script_path=$(cd $(dirname "${script_name}") && pwd -P) +keys_dir=${script_path}/../keys/ +crts_dir=${script_path}/../crts/ +ca_dir=${script_path}/../ca/ + +if [ ! -d "${keys_dir}" ] +then + echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." + exit 1 +fi + +if [ ! -d "${crts_dir}" ] +then + echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." + exit 1 +fi + +if [ ! -d "${ca_dir}" ] +then + echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." + exit 1 +fi + +# Switch current working directory to keys directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${keys_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${keys_dir}" + exit 1 + fi +fi + # Check that the file "serial" is present, if not create it: if [ ! -f serial ] then @@ -571,4 +613,15 @@ i=$((i+1)) done fi + +# Switch back to initial working directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${crt_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${crt_dir}" + exit 1 + fi +fi exit 0 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/hab4_pki_tree.bat imx-code-signing-tool-3.3.1+dfsg/keys/hab4_pki_tree.bat --- imx-code-signing-tool-3.3.0+dfsg2/keys/hab4_pki_tree.bat 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/hab4_pki_tree.bat 2021-08-12 12:53:52.000000000 +0000 @@ -1,621 +1,662 @@ -@echo off - -:: ----------------------------------------------------------------------------- -:: -:: File: hab4_pki_tree.bat -:: -:: Description: This script generates a basic HAB4 PKI tree for the Freescale -:: HAB code signing feature. What the PKI tree looks like depends -:: on whether the SRK is chosen to be a CA key or not. If the -:: SRKs are chosen to be CA keys then this script will generate the -:: following PKI tree: -:: -:: CA Key -:: | | | -:: -------- + | +--------------- -:: / | \ -:: SRK1 SRK2 ... SRKN -:: / \ / \ / \ -:: / \ / \ / \ -:: CSF1_1 IMG1_1 CSF2_1 IMG2_1 ... CSFN_1 IMGN_1 -:: -:: where: N can be 1 to 4. -:: -:: Additional keys can be added to the tree separately. In this -:: configuration SRKs may only be used to sign/verify other -:: keys/certificates -:: -:: If the SRKs are chosen to be non-CA keys then this script will -:: generate the following PKI tree: -:: -:: CA Key -:: | | | -:: -------- + | +--------------- -:: / | \ -:: SRK1 SRK2 ... SRKN -:: -:: In this configuration SRKs may only be used to sign code/data -:: and not other keys. Note that not all Freescale processors -:: including HAB support this option. -:: -:: (c) Freescale Semiconductor, Inc. 2011. All rights reserved. -:: Copyright 2018 NXP -:: -:: -:: ---------------------------------------------------------------------------- - -echo. -echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -echo This script is a part of the Code signing tools for Freescale's -echo High Assurance Boot. It generates a basic PKI tree. The PKI -echo tree consists of one or more Super Root Keys (SRK), with each -echo SRK having two subordinate keys: -echo + a Command Sequence File (CSF) key -echo + Image key. -echo Additional keys can be added to the PKI tree but a separate -echo script is available for this. This this script assumes openssl -echo is installed on your system and is included in your search -echo path. Finally, the private keys generated are password -echo protectedwith the password provided by the file key_pass.txt. -echo The format of the file is the password repeated twice: -echo my_password -echo my_password -echo All private keys in the PKI tree will be protected by the same -echo password. -echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -echo. - -set scriptName=%0 -set numArgs=0 -for %%x in (%*) do set /A numArgs+=1 - -if %numArgs% GTR 0 ( - set interactive=n -) else ( - set interactive=y -) - -set max_param=16 -set min_param=12 - -if %interactive%==n ( - if "%1" == "-h" ( goto usage ) - if "%1" == "--help" ( goto usage ) -) else ( - goto process_existing_ca -) - -:: Validate command line parameters -if %numArgs% LSS %min_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) -if %numArgs% GTR %max_param% ( - echo ERROR: Correct parameters required in non-interactive mode - goto usage -) - -:: Process command line inputs -set args=0 -set "existing_ca=" -set "ca_key=" -set "ca_cert=" -set "use_ecc=" -set "kl=" -set "duration=" -set "num_srk=" -set "srk_ca=" - -:PROCESSINPUT -if %args% GEQ %numArgs% goto validateargs -if "%1"=="-existing-ca" ( - set existing_ca=%2 - goto shiftargs -) -if "%1"=="-ca-key" ( - set ca_key=%2 - goto shiftargs -) -if "%1"=="-ca-cert" ( - set ca_cert=%2 - goto shiftargs -) -if "%1"=="-use-ecc" ( - set use_ecc=%2 - goto shiftargs -) -if "%1"=="-kl" ( - set kl=%2 - goto shiftargs -) -if "%1"=="-duration" ( - set duration=%2 - goto shiftargs -) -if "%1"=="-num-srk" ( - set num_srk=%2 - goto shiftargs -) -if "%1"=="-srk-ca" ( - set srk_ca=%2 - goto shiftargs -) else ( - echo ERROR: Invalid parameter: %1 - goto usage -) - -:SHIFTARGS -shift -shift -set /A args+=2 -goto processinput - -:VALIDATEARGS -if %existing_ca%==y ( if not defined ca_key ( - echo ERROR: CA key is required. - goto usage -)) - -if %existing_ca%==y ( if not defined ca_cert ( - echo ERROR: CA cert is required - goto usage -)) - -goto process_existing_ca - -:USAGE -echo Usage: -echo Interactive Mode: -echo %scriptName% -echo. -echo Command Line Mode: -echo "%scriptName% -existing-ca [-ca-key -ca-cert ] -use-ecc -kl -duration -num-srk <1-4> -srk-ca " -echo Options: -echo -kl: -use-ecc = y then Supported key lengths: p256, p384, p521 -echo : -use-ecc = n then Supported key lengths: 1024, 2048, 3072, 4096 -echo. -echo "%scriptName% -h | --help : This text" -echo. -exit /B - -:PROCESS_EXISTING_CA -if %interactive%==y ( - set /P existing_ca="Do you want to use an existing CA key (y/n)?: " -) - -if %existing_ca%==n goto KEY_LENGTH - -if %interactive%==y ( - set /P ca_key="Enter CA key name: " - set /P ca_cert="Enter CA certificate name: " -) - -:KEY_LENGTH - -if %interactive%==y ( - set /P use_ecc="Do you want to use Elliptic Curve Cryptography (y/n)?: " -) - -if %use_ecc%==n goto RSA_CERTS - -if %interactive%==y ( - echo Enter length for elliptic curve to be used for PKI tree: - set /P kl="Possible values p256, p384, p521: " -) - -:: Confirm that a valid key length has been entered -if %kl%==p256 ( - set cn="prime256v1" - goto VALID_KEY_LENGTH -) -if %kl%==p384 ( - set cn="secp384r1" - goto VALID_KEY_LENGTH -) -if %kl%==p521 ( - set cn="secp521r1" - goto VALID_KEY_LENGTH -) -echo Invalid key length. Supported key lengths: 256, 384, 521 -exit /B - -:RSA_CERTS - -if %interactive%==y ( - set /P kl="Enter key length in bits for PKI tree: " -) -:: Confirm that a valid key length has been entered -if %kl%==1024 goto VALID_KEY_LENGTH -if %kl%==2048 goto VALID_KEY_LENGTH -if %kl%==3072 goto VALID_KEY_LENGTH -if %kl%==4096 goto VALID_KEY_LENGTH -echo Invalid key length. Supported key lengths: 1024, 2048, 3072, 4096 -exit /B -:VALID_KEY_LENGTH - -if %interactive%==y ( - set /P duration="Enter PKI tree duration (years): " -) - -if %interactive%==y ( - :: Compute validity period - set /A val_period=%duration%*365 -) - -if %interactive%==y ( - set /P num_srk="How many Super Root Keys should be generated? " -) - -:: Check that 0 < num_srk < 4 (Max. number of SRKs) -if %num_srk%==1 goto VALID_NUM_KEYS -if %num_srk%==2 goto VALID_NUM_KEYS -if %num_srk%==3 goto VALID_NUM_KEYS -if %num_srk%==4 goto VALID_NUM_KEYS -echo The number of SRKs generated must be between 1 and 4 -exit /B -:VALID_NUM_KEYS - -if %interactive%==y ( - :: Check if SRKs should be generated as CA certs or user certs - set /P srk_ca="Do you want the SRK certificates to have the CA flag set? (y/n)?: " -) - -:SERIAL -:: Check that the file "serial" is present, if not create it: -if exist "serial" goto KEY_PASS -echo 12345678 > serial -echo A default 'serial' file was created! - -:KEY_PASS -:: Check that the file "key_pass.txt" is present, if not create it with default user/pwd: -if exist "key_pass.txt" goto OPENSSL_INIT -echo test> key_pass.txt -echo test>> key_pass.txt -echo A default file 'key_pass.txt' was created with password = test! - -:OPENSSL_INIT -:: Convert file in Unix format for OpenSSL 1.0.2 -convlb key_pass.txt -:: The following is required otherwise OpenSSL complains -if exist index.txt del /F index.txt -if exist index.txt.attr del /F index.txt.attr -type nul > index.txt -echo unique_subject = no > index.txt.attr -set OPENSSL_CONF=..\\ca\\openssl.cnf - -if %existing_ca%==y goto GEN_SRK -:: Generate CA key and certificate -:: ------------------------------- - -echo. -echo +++++++++++++++++++++++++++++++++++++ -echo + Generating CA key and certificate + -echo +++++++++++++++++++++++++++++++++++++ -echo. -if %use_ecc%==y GOTO g1_ecc - - set ca_key=CA1_sha256_%kl%_65537_v3_ca_key - set ca_cert=..\\crts\\CA1_sha256_%kl%_65537_v3_ca_crt - set ca_subj_req=/CN=CA1_sha256_%kl%_65537_v3_ca/ - set ca_key_type=rsa:%kl% - -goto g1_done -:g1_ecc - set eck=ec-%cn%.pem - openssl ecparam -out %eck% -name %cn% - set ca_key=CA1_sha256_%cn%_v3_ca_key - set ca_cert=..\\crts\\CA1_sha256_%cn%_v3_ca_crt - set ca_subj_req=/CN=CA1_sha256_%cn%_v3_ca/ - set ca_key_type=ec:%eck% - -:g1_done - -:: Note: '^' is to continue the command on the next line -openssl req -newkey %ca_key_type% -passout file:key_pass.txt ^ - -subj %ca_subj_req% ^ - -x509 -extensions v3_ca ^ - -keyout temp_ca.pem ^ - -out %ca_cert%.pem ^ - -days %val_period% - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_ca.pem ^ - -out %ca_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_ca.pem ^ - -out %ca_key%.pem - -:: Convert CA Certificate to DER format -openssl x509 -inform PEM -outform DER -in %ca_cert%.pem -out %ca_cert%.der - -:: Cleanup -del /F temp_ca.pem - -:GEN_SRK -if %srk_ca%==y goto GEN_SRK_CSF_IMG -:: Generate SRK keys and certificates (non-CA) -:: SRKs suitable for signing code/data -:: ------------------------------------------- -set /a i=1 -set /a max=num_srk+1 - -:GEN_SRK_LOOP -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating SRK key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. -if %use_ecc%==y GOTO g2_ecc - - :: Generate SRK key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out temp_srk.pem %kl% - - set srk_subj_req=/CN=SRK%i%_sha256_%kl%_65537_v3_usr/ - set srk_crt=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_usr_crt - set srk_key=SRK%i%_sha256_%kl%_65537_v3_usr_key -goto g2_done -:g2_ecc - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_srk.pem -name %cn% -genkey - - :: Generate SRK key - openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ - -out temp_srk.pem - - set srk_subj_req=/CN=SRK%i%_sha256_%cn%_v3_usr/ - set srk_crt=..\\crts\\SRK%i%_sha256_%cn%_v3_usr_crt - set srk_key=SRK%i%_sha256_%cn%_v3_usr_key - -:g2_done - - -:: Generate SRK certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %srk_subj_req% ^ - -key temp_srk.pem ^ - -out temp_srk_req.pem - -:: Generate SRK certificate (this is a CA cert) -openssl ca -batch -passin file:key_pass.txt ^ - -md sha256 -outdir . ^ - -in temp_srk_req.pem ^ - -cert %ca_cert%.pem ^ - -keyfile %ca_key%.pem ^ - -extfile ..\\ca\\v3_usr.cnf ^ - -out %srk_crt%.pem ^ - -days %val_period% - -::Convert SRK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %srk_crt%.pem ^ - -out %srk_crt%.der - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.pem - -:: Cleanup -del /F temp_srk.pem temp_srk_req.pem - -set /a i += 1 -if %i%==%max% goto DONE -goto GEN_SRK_LOOP - -:: Generate HAB keys and certificate -:: --------------------------------- -:GEN_SRK_CSF_IMG -set /a i=1 -set /a max=num_srk+1 - -:GEN_SRK_CSF_IMG_LOOP -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating SRK key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. -if %use_ecc%==y GOTO g3_ecc - - :: Generate SRK key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out temp_srk.pem %kl% - - set srk_subj_req=/CN=SRK%i%_sha256_%kl%_65537_v3_ca/ - set srk_crt=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_ca_crt - set srk_key=SRK%i%_sha256_%kl%_65537_v3_ca_key - -goto g3_done -:g3_ecc - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_srk.pem -name %cn% -genkey - - :: Generate SRK key - openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ - -out temp_srk.pem - - set srk_subj_req=/CN=SRK%i%_sha256_%cn%_v3_ca/ - set srk_crt=..\\crts\\SRK%i%_sha256_%cn%_v3_ca_crt - set srk_key=SRK%i%_sha256_%cn%_v3_ca_key -:g3_done - -:: Generate SRK certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %srk_subj_req% ^ - -key temp_srk.pem ^ - -out temp_srk_req.pem - -:: Generate SRK certificate (this is a CA cert) -openssl ca -batch -passin file:key_pass.txt ^ - -md sha256 -outdir . ^ - -in temp_srk_req.pem ^ - -cert %ca_cert%.pem ^ - -keyfile %ca_key%.pem ^ - -extfile ..\\ca\\v3_ca.cnf ^ - -out %srk_crt%.pem ^ - -days %val_period% - -::Convert SRK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %srk_crt%.pem ^ - -out %srk_crt%.der - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_srk.pem ^ - -out %srk_key%.pem - -:: Cleanup -del /F temp_srk.pem temp_srk_req.pem - -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating CSF key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. -if %use_ecc%==y goto g4_ecc - set srk_crt_i=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_ca_crt.pem - set srk_key_i=SRK%i%_sha256_%kl%_65537_v3_ca_key.pem - :: Generate key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out temp_csf.pem %kl% - - set csf_subj_req=/CN=CSF%i%_1_sha256_%kl%_65537_v3_usr/ - set csf_crt=..\\crts\\CSF%i%_1_sha256_%kl%_65537_v3_usr_crt - set csf_key=CSF%i%_1_sha256_%kl%_65537_v3_usr_key - -goto g4_done -:g4_ecc - set srk_crt_i=..\\crts\\SRK%i%_sha256_%cn%_v3_ca_crt.pem - set srk_key_i=SRK%i%_sha256_%cn%_v3_ca_key.pem - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_csf.pem -name %cn% -genkey - - :: Generate key - openssl ec -in temp_csf.pem -des3 -passout file:key_pass.txt ^ - -out temp_csf.pem - - set csf_subj_req=/CN=CSF%i%_1_sha256_%cn%_v3_usr/ - set csf_crt=..\\crts\\CSF%i%_1_sha256_%cn%_v3_usr_crt - set csf_key=CSF%i%_1_sha256_%cn%_v3_usr_key -:g4_done - - -:: Generate CSF certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %csf_subj_req% ^ - -key temp_csf.pem ^ - -out temp_csf_req.pem - -:: Generate CSF certificate (this is a user cert) -openssl ca -batch -md sha256 -outdir . ^ - -passin file:key_pass.txt ^ - -in temp_csf_req.pem ^ - -cert %srk_crt_i% ^ - -keyfile %srk_key_i% ^ - -extfile ..\\ca\\v3_usr.cnf ^ - -out %csf_crt%.pem ^ - -days %val_period% - -::Convert CSF Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %csf_crt%.pem ^ - -out %csf_crt%.der - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_csf.pem ^ - -out %csf_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_csf.pem ^ - -out %csf_key%.pem - - -:: Cleanup -del /F temp_csf.pem temp_csf_req.pem - -echo. -echo ++++++++++++++++++++++++++++++++++++++++ -echo + Generating IMG key and certificate %i% + -echo ++++++++++++++++++++++++++++++++++++++++ -echo. - -if %use_ecc%==y goto g5_ecc - :: Generate key - openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ - -out temp_img.pem %kl% - - set img_subj_req=/CN=IMG%i%_1_sha256_%kl%_65537_v3_usr/ - set img_crt=..\\crts\\IMG%i%_1_sha256_%kl%_65537_v3_usr_crt - set img_key=IMG%i%_1_sha256_%kl%_65537_v3_usr_key -goto g5_done -:g5_ecc - :: Generate Elliptic Curve parameters: - openssl ecparam -out temp_img.pem -name %cn% -genkey - - :: Generate key - openssl ec -in temp_img.pem -des3 -passout file:key_pass.txt ^ - -out temp_img.pem - - set img_subj_req=/CN=IMG%i%_1_sha256_%cn%_v3_usr/ - set img_crt=..\\crts\\IMG%i%_1_sha256_%cn%_v3_usr_crt - set img_key=IMG%i%_1_sha256_%cn%_v3_usr_key -:g5_done - -:: Generate IMG certificate signing request -openssl req -new -batch -passin file:key_pass.txt ^ - -subj %img_subj_req% ^ - -key temp_img.pem ^ - -out temp_img_req.pem - -openssl ca -batch -md sha256 -outdir . ^ - -passin file:key_pass.txt ^ - -in temp_img_req.pem ^ - -cert %srk_crt_i% ^ - -keyfile %srk_key_i% ^ - -extfile ..\\ca\\v3_usr.cnf ^ - -out %img_crt%.pem ^ - -days %val_period% - -:: Convert SRK Certificate to DER format -openssl x509 -inform PEM -outform DER ^ - -in %img_crt%.pem ^ - -out %img_crt%.der - -:: Generate CA key in PKCS #8 format - both PEM and DER -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform DER -v2 des3 ^ - -in temp_img.pem ^ - -out %img_key%.der - -openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ - -topk8 -inform PEM -outform PEM -v2 des3 ^ - -in temp_img.pem ^ - -out %img_key%.pem - -:: Cleanup -del /F temp_img.pem temp_img_req.pem - -set /a i += 1 -if %i%==%max% goto DONE -goto GEN_SRK_CSF_IMG_LOOP -:DONE +@echo off + +:: ----------------------------------------------------------------------------- +:: +:: File: hab4_pki_tree.bat +:: +:: Description: This script generates a basic HAB4 PKI tree for the Freescale +:: HAB code signing feature. What the PKI tree looks like depends +:: on whether the SRK is chosen to be a CA key or not. If the +:: SRKs are chosen to be CA keys then this script will generate the +:: following PKI tree: +:: +:: CA Key +:: | | | +:: -------- + | +--------------- +:: / | \ +:: SRK1 SRK2 ... SRKN +:: / \ / \ / \ +:: / \ / \ / \ +:: CSF1_1 IMG1_1 CSF2_1 IMG2_1 ... CSFN_1 IMGN_1 +:: +:: where: N can be 1 to 4. +:: +:: Additional keys can be added to the tree separately. In this +:: configuration SRKs may only be used to sign/verify other +:: keys/certificates +:: +:: If the SRKs are chosen to be non-CA keys then this script will +:: generate the following PKI tree: +:: +:: CA Key +:: | | | +:: -------- + | +--------------- +:: / | \ +:: SRK1 SRK2 ... SRKN +:: +:: In this configuration SRKs may only be used to sign code/data +:: and not other keys. Note that not all Freescale processors +:: including HAB support this option. +:: +:: (c) Freescale Semiconductor, Inc. 2011. All rights reserved. +:: Copyright 2018 NXP +:: +:: +:: ---------------------------------------------------------------------------- + +echo. +echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +echo This script is a part of the Code signing tools for Freescale's +echo High Assurance Boot. It generates a basic PKI tree. The PKI +echo tree consists of one or more Super Root Keys (SRK), with each +echo SRK having two subordinate keys: +echo + a Command Sequence File (CSF) key +echo + Image key. +echo Additional keys can be added to the PKI tree but a separate +echo script is available for this. This this script assumes openssl +echo is installed on your system and is included in your search +echo path. Finally, the private keys generated are password +echo protectedwith the password provided by the file key_pass.txt. +echo The format of the file is the password repeated twice: +echo my_password +echo my_password +echo All private keys in the PKI tree will be protected by the same +echo password. +echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +echo. + +set scriptName=%0 +set scriptPath=%~dp0 +set numArgs=0 +for %%x in (%*) do set /A numArgs+=1 + +if %numArgs% GTR 0 ( + set interactive=n +) else ( + set interactive=y +) + +set max_param=16 +set min_param=12 + +if %interactive%==n ( + if "%1" == "-h" ( goto usage ) + if "%1" == "--help" ( goto usage ) +) else ( + goto process_existing_ca +) + +:: Validate command line parameters +if %numArgs% LSS %min_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) +if %numArgs% GTR %max_param% ( + echo ERROR: Correct parameters required in non-interactive mode + goto usage +) + +:: Process command line inputs +set args=0 +set "existing_ca=" +set "ca_key=" +set "ca_cert=" +set "use_ecc=" +set "kl=" +set "duration=" +set "num_srk=" +set "srk_ca=" + +:PROCESSINPUT +if %args% GEQ %numArgs% goto validateargs +if "%1"=="-existing-ca" ( + set existing_ca=%2 + goto shiftargs +) +if "%1"=="-ca-key" ( + set ca_key=%2 + goto shiftargs +) +if "%1"=="-ca-cert" ( + set ca_cert=%2 + goto shiftargs +) +if "%1"=="-use-ecc" ( + set use_ecc=%2 + goto shiftargs +) +if "%1"=="-kl" ( + set kl=%2 + goto shiftargs +) +if "%1"=="-duration" ( + set duration=%2 + goto shiftargs +) +if "%1"=="-num-srk" ( + set num_srk=%2 + goto shiftargs +) +if "%1"=="-srk-ca" ( + set srk_ca=%2 + goto shiftargs +) else ( + echo ERROR: Invalid parameter: %1 + goto usage +) + +:SHIFTARGS +shift +shift +set /A args+=2 +goto processinput + +:VALIDATEARGS +if %existing_ca%==y ( if not defined ca_key ( + echo ERROR: CA key is required. + goto usage +)) + +if %existing_ca%==y ( if not defined ca_cert ( + echo ERROR: CA cert is required + goto usage +)) + +goto process_existing_ca + +:USAGE +echo Usage: +echo Interactive Mode: +echo %scriptName% +echo. +echo Command Line Mode: +echo "%scriptName% -existing-ca [-ca-key -ca-cert ] -use-ecc -kl -duration -num-srk <1-4> -srk-ca " +echo Options: +echo -kl: -use-ecc = y then Supported key lengths: p256, p384, p521 +echo : -use-ecc = n then Supported key lengths: 1024, 2048, 3072, 4096 +echo. +echo "%scriptName% -h | --help : This text" +echo. +exit /B + +:PROCESS_EXISTING_CA +if %interactive%==y ( + set /P existing_ca="Do you want to use an existing CA key (y/n)?: " +) + +if %existing_ca%==n goto KEY_LENGTH + +if %interactive%==y ( + set /P ca_key="Enter CA key name: " + set /P ca_cert="Enter CA certificate name: " +) + +:KEY_LENGTH + +if %interactive%==y ( + set /P use_ecc="Do you want to use Elliptic Curve Cryptography (y/n)?: " +) + +if %use_ecc%==n goto RSA_CERTS + +if %interactive%==y ( + echo Enter length for elliptic curve to be used for PKI tree: + set /P kl="Possible values p256, p384, p521: " +) + +:: Confirm that a valid key length has been entered +if %kl%==p256 ( + set cn="prime256v1" + goto VALID_KEY_LENGTH +) +if %kl%==p384 ( + set cn="secp384r1" + goto VALID_KEY_LENGTH +) +if %kl%==p521 ( + set cn="secp521r1" + goto VALID_KEY_LENGTH +) +echo Invalid key length. Supported key lengths: 256, 384, 521 +exit /B + +:RSA_CERTS + +if %interactive%==y ( + set /P kl="Enter key length in bits for PKI tree: " +) +:: Confirm that a valid key length has been entered +if %kl%==1024 goto VALID_KEY_LENGTH +if %kl%==2048 goto VALID_KEY_LENGTH +if %kl%==3072 goto VALID_KEY_LENGTH +if %kl%==4096 goto VALID_KEY_LENGTH +echo Invalid key length. Supported key lengths: 1024, 2048, 3072, 4096 +exit /B +:VALID_KEY_LENGTH + +if %interactive%==y ( + set /P duration="Enter PKI tree duration (years): " +) + +:: Compute validity period +set /A val_period=%duration%*365 + +if %interactive%==y ( + set /P num_srk="How many Super Root Keys should be generated? " +) + +:: Check that 0 < num_srk < 4 (Max. number of SRKs) +if %num_srk%==1 goto VALID_NUM_KEYS +if %num_srk%==2 goto VALID_NUM_KEYS +if %num_srk%==3 goto VALID_NUM_KEYS +if %num_srk%==4 goto VALID_NUM_KEYS +echo The number of SRKs generated must be between 1 and 4 +exit /B +:VALID_NUM_KEYS + +if %interactive%==y ( + :: Check if SRKs should be generated as CA certs or user certs + set /P srk_ca="Do you want the SRK certificates to have the CA flag set? (y/n)?: " +) + +:BEFORE_GEN_KEYS +:: Check existance of keys/, crts/ and ca/ directories of before generating keys and +:: switch current working directory to /keys directory, if needed. +set crt_dir=%cd% +set keys_dir=%scriptPath%\\..\\keys\\ +set crts_dir=%scriptPath%\\..\\crts\\ +set ca_dir=%scriptPath%\\..\\ca\\ + +if not exist "%keys_dir%" ( + echo ERROR: Private keys directory %keys_dir% is missing. Expecting script to be located inside ^/keys directory. + exit /B +) + +if not exist "%crts_dir%" ( + echo ERROR: Public keys directory %crts_dir% is missing. Expecting ^/crts directory to be already created. + exit /B +) + +if not exist "%ca_dir%" ( + echo ERROR: Openssl configuration directory %ca_dir% is missing. Expecting ^/ca directory to hold openssl configuration files. + exit /B +) + +:: Switch current working directory to /keys directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%keys_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %keys_dir% + exit /B + ) +) + +:SERIAL +:: Check that the file "serial" is present, if not create it: +if exist "serial" goto KEY_PASS +echo 12345678 > serial +echo A default 'serial' file was created! + +:KEY_PASS +:: Check that the file "key_pass.txt" is present, if not create it with default user/pwd: +if exist "key_pass.txt" goto OPENSSL_INIT +echo test> key_pass.txt +echo test>> key_pass.txt +echo A default file 'key_pass.txt' was created with password = test! + +:OPENSSL_INIT +:: Convert file in Unix format for OpenSSL 1.0.2 +convlb key_pass.txt +:: The following is required otherwise OpenSSL complains +if exist index.txt del /F index.txt +if exist index.txt.attr del /F index.txt.attr +type nul > index.txt +echo unique_subject = no > index.txt.attr +set OPENSSL_CONF=..\\ca\\openssl.cnf + +if %existing_ca%==y goto GEN_SRK +:: Generate CA key and certificate +:: ------------------------------- + +echo. +echo +++++++++++++++++++++++++++++++++++++ +echo + Generating CA key and certificate + +echo +++++++++++++++++++++++++++++++++++++ +echo. +if %use_ecc%==y GOTO g1_ecc + + set ca_key=CA1_sha256_%kl%_65537_v3_ca_key + set ca_cert=..\\crts\\CA1_sha256_%kl%_65537_v3_ca_crt + set ca_subj_req=/CN=CA1_sha256_%kl%_65537_v3_ca/ + set ca_key_type=rsa:%kl% + +goto g1_done +:g1_ecc + set eck=ec-%cn%.pem + openssl ecparam -out %eck% -name %cn% + set ca_key=CA1_sha256_%cn%_v3_ca_key + set ca_cert=..\\crts\\CA1_sha256_%cn%_v3_ca_crt + set ca_subj_req=/CN=CA1_sha256_%cn%_v3_ca/ + set ca_key_type=ec:%eck% + +:g1_done + +:: Note: '^' is to continue the command on the next line +openssl req -newkey %ca_key_type% -passout file:key_pass.txt ^ + -subj %ca_subj_req% ^ + -x509 -extensions v3_ca ^ + -keyout temp_ca.pem ^ + -out %ca_cert%.pem ^ + -days %val_period% + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_ca.pem ^ + -out %ca_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_ca.pem ^ + -out %ca_key%.pem + +:: Convert CA Certificate to DER format +openssl x509 -inform PEM -outform DER -in %ca_cert%.pem -out %ca_cert%.der + +:: Cleanup +del /F temp_ca.pem + +:GEN_SRK +if %srk_ca%==y goto GEN_SRK_CSF_IMG +:: Generate SRK keys and certificates (non-CA) +:: SRKs suitable for signing code/data +:: ------------------------------------------- +set /a i=1 +set /a max=num_srk+1 + +:GEN_SRK_LOOP +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating SRK key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. +if %use_ecc%==y GOTO g2_ecc + + :: Generate SRK key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out temp_srk.pem %kl% + + set srk_subj_req=/CN=SRK%i%_sha256_%kl%_65537_v3_usr/ + set srk_crt=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_usr_crt + set srk_key=SRK%i%_sha256_%kl%_65537_v3_usr_key +goto g2_done +:g2_ecc + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_srk.pem -name %cn% -genkey + + :: Generate SRK key + openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ + -out temp_srk.pem + + set srk_subj_req=/CN=SRK%i%_sha256_%cn%_v3_usr/ + set srk_crt=..\\crts\\SRK%i%_sha256_%cn%_v3_usr_crt + set srk_key=SRK%i%_sha256_%cn%_v3_usr_key + +:g2_done + + +:: Generate SRK certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %srk_subj_req% ^ + -key temp_srk.pem ^ + -out temp_srk_req.pem + +:: Generate SRK certificate (this is a CA cert) +openssl ca -batch -passin file:key_pass.txt ^ + -md sha256 -outdir . ^ + -in temp_srk_req.pem ^ + -cert %ca_cert%.pem ^ + -keyfile %ca_key%.pem ^ + -extfile ..\\ca\\v3_usr.cnf ^ + -out %srk_crt%.pem ^ + -days %val_period% + +::Convert SRK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %srk_crt%.pem ^ + -out %srk_crt%.der + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.pem + +:: Cleanup +del /F temp_srk.pem temp_srk_req.pem + +set /a i += 1 +if %i%==%max% goto DONE +goto GEN_SRK_LOOP + +:: Generate HAB keys and certificate +:: --------------------------------- +:GEN_SRK_CSF_IMG +set /a i=1 +set /a max=num_srk+1 + +:GEN_SRK_CSF_IMG_LOOP +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating SRK key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. +if %use_ecc%==y GOTO g3_ecc + + :: Generate SRK key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out temp_srk.pem %kl% + + set srk_subj_req=/CN=SRK%i%_sha256_%kl%_65537_v3_ca/ + set srk_crt=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_ca_crt + set srk_key=SRK%i%_sha256_%kl%_65537_v3_ca_key + +goto g3_done +:g3_ecc + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_srk.pem -name %cn% -genkey + + :: Generate SRK key + openssl ec -in temp_srk.pem -des3 -passout file:key_pass.txt ^ + -out temp_srk.pem + + set srk_subj_req=/CN=SRK%i%_sha256_%cn%_v3_ca/ + set srk_crt=..\\crts\\SRK%i%_sha256_%cn%_v3_ca_crt + set srk_key=SRK%i%_sha256_%cn%_v3_ca_key +:g3_done + +:: Generate SRK certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %srk_subj_req% ^ + -key temp_srk.pem ^ + -out temp_srk_req.pem + +:: Generate SRK certificate (this is a CA cert) +openssl ca -batch -passin file:key_pass.txt ^ + -md sha256 -outdir . ^ + -in temp_srk_req.pem ^ + -cert %ca_cert%.pem ^ + -keyfile %ca_key%.pem ^ + -extfile ..\\ca\\v3_ca.cnf ^ + -out %srk_crt%.pem ^ + -days %val_period% + +::Convert SRK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %srk_crt%.pem ^ + -out %srk_crt%.der + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_srk.pem ^ + -out %srk_key%.pem + +:: Cleanup +del /F temp_srk.pem temp_srk_req.pem + +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating CSF key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. +if %use_ecc%==y goto g4_ecc + set srk_crt_i=..\\crts\\SRK%i%_sha256_%kl%_65537_v3_ca_crt.pem + set srk_key_i=SRK%i%_sha256_%kl%_65537_v3_ca_key.pem + :: Generate key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out temp_csf.pem %kl% + + set csf_subj_req=/CN=CSF%i%_1_sha256_%kl%_65537_v3_usr/ + set csf_crt=..\\crts\\CSF%i%_1_sha256_%kl%_65537_v3_usr_crt + set csf_key=CSF%i%_1_sha256_%kl%_65537_v3_usr_key + +goto g4_done +:g4_ecc + set srk_crt_i=..\\crts\\SRK%i%_sha256_%cn%_v3_ca_crt.pem + set srk_key_i=SRK%i%_sha256_%cn%_v3_ca_key.pem + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_csf.pem -name %cn% -genkey + + :: Generate key + openssl ec -in temp_csf.pem -des3 -passout file:key_pass.txt ^ + -out temp_csf.pem + + set csf_subj_req=/CN=CSF%i%_1_sha256_%cn%_v3_usr/ + set csf_crt=..\\crts\\CSF%i%_1_sha256_%cn%_v3_usr_crt + set csf_key=CSF%i%_1_sha256_%cn%_v3_usr_key +:g4_done + + +:: Generate CSF certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %csf_subj_req% ^ + -key temp_csf.pem ^ + -out temp_csf_req.pem + +:: Generate CSF certificate (this is a user cert) +openssl ca -batch -md sha256 -outdir . ^ + -passin file:key_pass.txt ^ + -in temp_csf_req.pem ^ + -cert %srk_crt_i% ^ + -keyfile %srk_key_i% ^ + -extfile ..\\ca\\v3_usr.cnf ^ + -out %csf_crt%.pem ^ + -days %val_period% + +::Convert CSF Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %csf_crt%.pem ^ + -out %csf_crt%.der + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_csf.pem ^ + -out %csf_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_csf.pem ^ + -out %csf_key%.pem + + +:: Cleanup +del /F temp_csf.pem temp_csf_req.pem + +echo. +echo ++++++++++++++++++++++++++++++++++++++++ +echo + Generating IMG key and certificate %i% + +echo ++++++++++++++++++++++++++++++++++++++++ +echo. + +if %use_ecc%==y goto g5_ecc + :: Generate key + openssl genrsa -des3 -passout file:key_pass.txt -f4 ^ + -out temp_img.pem %kl% + + set img_subj_req=/CN=IMG%i%_1_sha256_%kl%_65537_v3_usr/ + set img_crt=..\\crts\\IMG%i%_1_sha256_%kl%_65537_v3_usr_crt + set img_key=IMG%i%_1_sha256_%kl%_65537_v3_usr_key +goto g5_done +:g5_ecc + :: Generate Elliptic Curve parameters: + openssl ecparam -out temp_img.pem -name %cn% -genkey + + :: Generate key + openssl ec -in temp_img.pem -des3 -passout file:key_pass.txt ^ + -out temp_img.pem + + set img_subj_req=/CN=IMG%i%_1_sha256_%cn%_v3_usr/ + set img_crt=..\\crts\\IMG%i%_1_sha256_%cn%_v3_usr_crt + set img_key=IMG%i%_1_sha256_%cn%_v3_usr_key +:g5_done + +:: Generate IMG certificate signing request +openssl req -new -batch -passin file:key_pass.txt ^ + -subj %img_subj_req% ^ + -key temp_img.pem ^ + -out temp_img_req.pem + +openssl ca -batch -md sha256 -outdir . ^ + -passin file:key_pass.txt ^ + -in temp_img_req.pem ^ + -cert %srk_crt_i% ^ + -keyfile %srk_key_i% ^ + -extfile ..\\ca\\v3_usr.cnf ^ + -out %img_crt%.pem ^ + -days %val_period% + +:: Convert SRK Certificate to DER format +openssl x509 -inform PEM -outform DER ^ + -in %img_crt%.pem ^ + -out %img_crt%.der + +:: Generate CA key in PKCS #8 format - both PEM and DER +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform DER -v2 des3 ^ + -in temp_img.pem ^ + -out %img_key%.der + +openssl pkcs8 -passin file:key_pass.txt -passout file:key_pass.txt ^ + -topk8 -inform PEM -outform PEM -v2 des3 ^ + -in temp_img.pem ^ + -out %img_key%.pem + +:: Cleanup +del /F temp_img.pem temp_img_req.pem + +set /a i += 1 +if %i%==%max% goto DONE +goto GEN_SRK_CSF_IMG_LOOP + +:DONE +:: Switch back to initial working directory, if needed. +if not "%crt_dir%" == "%keys_dir%" ( + cd "%crt_dir%" + if %errorlevel% NEQ 0 ( + echo ERROR: Cannot change directory to %crt_dir% + exit /B + ) +) +exit /B diff -Nru imx-code-signing-tool-3.3.0+dfsg2/keys/hab4_pki_tree.sh imx-code-signing-tool-3.3.1+dfsg/keys/hab4_pki_tree.sh --- imx-code-signing-tool-3.3.0+dfsg2/keys/hab4_pki_tree.sh 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/keys/hab4_pki_tree.sh 2021-08-12 12:53:52.000000000 +0000 @@ -266,6 +266,48 @@ read srk_ca fi +# Check existance of keys/, crts/ and ca/ directories of before generating keys and +# switch current working directory to /keys directory, if needed. +crt_dir=$(pwd) +script_name=$(readlink "$0") +if [ "${script_name}" = "" ] +then + script_name=$0 +fi +script_path=$(cd $(dirname "${script_name}") && pwd -P) +keys_dir=${script_path}/../keys/ +crts_dir=${script_path}/../crts/ +ca_dir=${script_path}/../ca/ + +if [ ! -d "${keys_dir}" ] +then + echo ERROR: "Private keys directory ${keys_dir} is missing. Expecting script to be located inside /keys directory." + exit 1 +fi + +if [ ! -d "${crts_dir}" ] +then + echo ERROR: "Public keys directory ${crts_dir} is missing. Expecting /crts directory to be already created." + exit 1 +fi + +if [ ! -d "${ca_dir}" ] +then + echo ERROR: "Openssl configuration directory ${ca_dir} is missing. Expecting /ca directory to hold openssl configuration files." + exit 1 +fi + +# Switch current working directory to keys directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${keys_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${keys_dir}" + exit 1 + fi +fi + # Check that the file "serial" is present, if not create it: if [ ! -f serial ] then @@ -282,7 +324,7 @@ fi # The following is required otherwise OpenSSL complains -if [-f index.txt ] +if [ -f index.txt ] then rm index.txt fi @@ -621,4 +663,15 @@ i=$((i+1)) done fi + +# Switch back to initial working directory, if needed. +if [ "${crt_dir}" != "${keys_dir}" ] +then + cd "${crt_dir}" + if [ $? -ge 1 ] + then + echo ERROR: "Cannot change directory to ${crt_dir}" + exit 1 + fi +fi exit 0 diff -Nru imx-code-signing-tool-3.3.0+dfsg2/Release_Notes.txt imx-code-signing-tool-3.3.1+dfsg/Release_Notes.txt --- imx-code-signing-tool-3.3.0+dfsg2/Release_Notes.txt 2021-03-23 08:41:52.000000000 +0000 +++ imx-code-signing-tool-3.3.1+dfsg/Release_Notes.txt 2021-08-12 12:53:52.000000000 +0000 @@ -1,10 +1,9 @@ - CST 3.3.0 Release Notes + CST 3.3.1 Release Notes +PROJECT(S): CST +DATE: July, 2020 -PROJECT(S): CST -DATE: April, 2019 - - COPYRIGHT 2017-2019 NXP +COPYRIGHT 2017-2020 NXP 1 READ ME FIRST This is the NXP Code Signing Tool (CST) for the High @@ -16,7 +15,7 @@ for the code signing for SoC supporting HAB version 4 and AHAB. 1.1 REQUIREMENTS - This release supports Linux, MacOS, and Windows hosts + This release supports Linux, MacOS, and Windows hosts. For Linux, the CST is known to work on Ubuntu 14.04 and later. For Windows, the CST is known to work on Windows 7 and later. For MacOS, the CST is known to work on Mojave and later. @@ -29,239 +28,282 @@ Problems with this release may be reported to your local NXP representative or at community.nxp.com. +2 KNOWN ISSUES -2 NEW FEATURES & Fixes - The following is included in this release: - -2.1 Encrypted Boot support - This version of CST allows the user to relink the executable - to include support for generating encrypted boot images. - - To relink on Ubuntu 14.04 machines, please first install binutils 2.26: - sudo apt-get install binutils-2.26 - export PATH=/usr/lib/binutils-2.26/bin:${PATH} - - To relink on 32 bit Linux machines: - This requires the GCC compiler and the OpenSSL header files and - library. For example on Ubuntu machines: - sudo apt-get install gcc libssl-dev - - cd /code/back_end/src - gcc -o cst -I ../hdr -L ../../../linux32/lib *.c \ - -lfrontend -lcrypto - cp cst ../../../linux32 - - To relink on 64 bit Linux machines: - This requires the GCC compiler and the OpenSSL header files and - library. For example on Ubuntu machines: - sudo apt-get install gcc libssl-dev - - cd /code/cst/ - - The Makefile includes the possibilty to recompile OpenSSL. This is mainly - interesting when cross-compiling CST (e.g. for Win32 builds). - make OSTYPE=mingw32 OPENSSL_PATH= openssl - - To rebuild the CST binaries: - make OSTYPE=linux64 rel_bin - with OpenSSL dependencies: - make OSTYPE=mingw32 OPENSSL_PATH= rel_bin - - Existing OS types (OSTYPE) are: linux32 | linux64 | mingw32. - - The generated binaries can be found in /code/cst/release - - This was added in CST 3.2.0 - -2.14 MacOS Support - This version of the CST package includes support for macOS. - - The executables are provided in the 'osx' directory. - The Makefile included with the source code includes the build support - for macOS. - - To build on macOS: - Please change your working directory. - cd /code/cst/ - - The Makefile includes a build target for OpenSSL. The OpenSSL project should - be downloaded and built with this build target. - make OSTYPE=mingw32 OPENSSL_PATH= openssl - - To rebuild the CST binaries: - make OSTYPE=osx rel_bin - with OpenSSL dependencies: - make OSTYPE=osx OPENSSL_PATH= rel_bin - - The generated binaries can be found in: - /code/cst/release/osx/bin - - This was added in CST 3.3.0 - -2.15 Encryption Support Enabled - This version of the CST is released with encryption support enabled by default. - - This was added in CST 3.3.0 - -2.16 PKI Generation Script Updated - The version of the CST package includes updated PKI generation scripts - supporting command line input of parameters. Previously the scripts - interactively queried the user for input options. - - This was added in CST 3.3.0 - -2.17 Dockerfile Added to Source Code - This version of the CST package include a 'Dockerfile' in the source - code directory to provide the environment for building the source. - - This was added in CST 3.3.0 - -2.18 AHAB Signature Block Parser - This version of the CST package includes a new AHAB Signature Block Parser - utility. The parser evaluates an image and dumps details about the AHAB - signatures. - - The parser is found at: - /code/ahab_signature_block_parser +4. Historical Release Notes + Please note that there was an issue in 3.0.1 that prevented this + feature from working. - This was added in CST 3.3.0 -3 KNOWN ISSUES + Release 3.3.0: + ** New Features ** + 1. MacOS Support + This version of the CST package includes support for macOS. + + The executables are provided in the 'osx' directory. + The Makefile included with the source code includes the build support + for macOS. + + To build on macOS: + Please change your working directory. + cd /code/cst/ + + The Makefile includes a build target for OpenSSL. The OpenSSL project should + be downloaded and built with this build target. + make OSTYPE=mingw32 OPENSSL_PATH= openssl + + To rebuild the CST binaries: + make OSTYPE=osx rel_bin + with OpenSSL dependencies: + make OSTYPE=osx OPENSSL_PATH= rel_bin + + The generated binaries can be found in: + /code/cst/release/osx/bin + + 2. Encryption Support Enabled in Release Binaries + This version of the CST is released with encryption support + enabled by default. + + 3. PKI Generation Script Updated + The version of the CST package includes updated PKI generation scripts + supporting command line input of parameters. Previously the scripts + interactively queried the user for input options. + + 4. Dockerfile Added to Source Code + This version of the CST package include a 'Dockerfile' in the source + code directory to provide the environment for building the source. + + 5. AHAB Signature Block Parser + This version of the CST package includes a new AHAB Signature Block Parser + utility. The parser evaluates an image and dumps details about the AHAB + signatures. + + The parser is found at: + /code/ahab_signature_block_parser + + ** Bug Fixes ** + -NONE- + + + Release 3.2.0: + ** New Features ** + 1. HAB3 support + This version of the CST package removes support for HAB3. + + 2. Encrypted boot support for AHAB + + 3. CST source code + This version of the CST package includes the CST source code. To + rebuild on Ubuntu 16.04 machines, please first install the packages: + gcc + make + git + byacc + flex + mingw-w64 + g++-multilib + libssl-dev + libssl-dev:i386 + + Please change your working directory. + cd /code/cst/ + + The Makefile includes the possibilty to recompile OpenSSL. This is mainly + interesting when cross-compiling CST (e.g. for Win32 builds). + make OSTYPE=mingw32 OPENSSL_PATH= openssl + + To rebuild the CST binaries: + make OSTYPE=linux64 rel_bin + with OpenSSL dependencies: + make OSTYPE=mingw32 OPENSSL_PATH= rel_bin + + Existing OS types (OSTYPE) are: linux32 | linux64 | mingw32. + + The generated binaries can be found in /code/cst/release + ** Bug Fixes ** + + -NONE- + + + Release 3.1.0: + ** New Features ** + 1. ECDSA support for HAB4 + This version of CST adds support for ECDSA for HAB4. + ECDSA support was added in HAB 4.5 + + 2. OpenSSL 1.1.0 + This version of CST adds support for OpenSSL 1.1.0. + Even if OpenSSL 1.0.2 is known to work with CST, OpenSSL 1.1.0 + or later is recommended. + + 3. Add-ons + This version of the CST package includes additional tools. + Please refer to the CST User Guide for more information. + - HSM Back-End support + - HABv4 log parser tool + - HABv4 CSF parser tool + - HABv4 SRKTool scripts + + ** Bug Fixes ** + -NONE- + + + Release 3.0.0: + ** New Features ** + 1. AHAB support + This version of CST adds support for AHAB. + + ** Bug Fixes ** + -NONE- + + + Release 2.3.3: + ** New Features ** + 1. Windows support + This version of CST adds support for Microsoft Windows. + + 2. Removed several commands + This version of CST removed support for the following commands: + Write Data + Clear Mask + Set Mask + Check All Clear + Check All Set + Check Any Clear + Check Any Set + Set MID + + ** Bug Fixes ** + -NONE- + + + Release 2.3.2 + ** New Features ** + 1. Changed CST input file handling + Previous versions of CST got the CSF input file on standard + input. This has changed. Now the input filename is supplied as a + command line argument. + + Example: + cst --output csf.bin --input input.csf + + This was added in CST 2.3.2 + + 2. Added unlock command for Manufacturing Protection + The new unlock command will cause HAB to keep the manufacturing + protection key in internal CAAM memory after boot. + + ** Bug Fixes ** + 1. Fixed INIT RNG Unlock Command + + +Release 2.3.1: + ** New Features ** + 1. Encrypted Boot support + This version of CST allows the user to relink the executable + to include support for generating encrypted boot images. + + To relink on Ubuntu 14.04 machines, please first install binutils 2.26: + sudo apt-get install binutils-2.26 + export PATH=/usr/lib/binutils-2.26/bin:${PATH} + + To relink on 32 bit Linux machines: + This requires the GCC compiler and the OpenSSL header files and + library. For example on Ubuntu machines: + sudo apt-get install gcc libssl-dev + + cd /code/back_end/src + gcc -o cst -I ../hdr -L ../../../linux32/lib *.c \ + -lfrontend -lcrypto + cp cst ../../../linux32 + + To relink on 64 bit Linux machines: + This requires the GCC compiler and the OpenSSL header files and + library. For example on Ubuntu machines: + sudo apt-get install gcc libssl-dev + + cd .tgz +Package: cst-3.3.1.tgz Outgoing License: BSD-3-Clause License Files: ./LICENSE.bsd3 ./LICENSE.openssl (OpenSSL License and SSLeay License)