Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf noup] For Attestation, use message instead of hash #180

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/config_base.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ set(SYMMETRIC_INITIAL_ATTESTATION OFF CACHE BOOL "Use symmetr
set(ATTEST_INCLUDE_TEST_CODE OFF CACHE BOOL "Include minimal development tests in the initial attestation regression test suite")
set(ATTEST_KEY_BITS 256 CACHE STRING "The size of the initial attestation key in bits")
set(PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE 0x250 CACHE STRING "The maximum possible size of a token")
set(ATTEST_SIGN_MESSAGE OFF CACHE BOOL "Sign message instead of hash")

set(TFM_PARTITION_PLATFORM OFF CACHE BOOL "Enable Platform partition")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ device. System integrators might need to re-implement the following functions
if they want to use initial attestation service with a different cryptographic
library than Crypto service:

- ``t_cose_crypto_pub_key_sign()``: Calculates the signature over a hash value.
- ``t_cose_crypto_pub_key_sign_hash()``: Calculates the signature over a hash value.
- ``t_cose_crypto_pub_key_sign_message()``: Calculates the signature over a message.
- ``t_cose_crypto_get_ec_pub_key()``: Get the public key to create the key
identifier.
- ``t_cose_crypto_hash_start()``: Start a multipart hash operation.
Expand Down
35 changes: 25 additions & 10 deletions lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
return return_value;
}


/*
* See documentation in t_cose_crypto.h
*/
enum t_cose_err_t
t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
struct t_cose_key signing_key,
struct q_useful_buf_c hash_to_sign,
struct q_useful_buf_c to_sign,
struct q_useful_buf signature_buffer,
struct q_useful_buf_c *signature)
struct q_useful_buf_c *signature,
int32_t option_flags)
{
enum t_cose_err_t return_value;
psa_status_t psa_result;
Expand Down Expand Up @@ -196,13 +196,28 @@ t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
/* It is assumed that this call is checking the signature_buffer
* length and won't write off the end of it.
*/
psa_result = psa_sign_hash(signing_key_psa,
psa_alg_id,
hash_to_sign.ptr,
hash_to_sign.len,
signature_buffer.ptr, /* Sig buf */
signature_buffer.len, /* Sig buf size */
&signature_len); /* Sig length */

if(!(option_flags & T_COSE_OPT_SIGN_MESSAGE)) {
#ifndef T_COSE_SIGN_MESSAGE
psa_result = psa_sign_hash(signing_key_psa,
psa_alg_id,
to_sign.ptr,
to_sign.len,
signature_buffer.ptr, /* Sig buf */
signature_buffer.len, /* Sig buf size */
&signature_len); /* Sig length */
#endif
} else {
#ifdef T_COSE_SIGN_MESSAGE
psa_result = psa_sign_message(signing_key_psa,
psa_alg_id,
to_sign.ptr,
to_sign.len,
signature_buffer.ptr, /* Sig buf */
signature_buffer.len, /* Sig buf size */
&signature_len); /* Sig length */
#endif
}

return_value = psa_status_to_t_cose_error_signing(psa_result);

Expand Down
8 changes: 8 additions & 0 deletions lib/ext/t_cose/inc/t_cose_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,14 @@ struct t_cose_parameters {
*/
#define T_COSE_OPT_DECODE_ONLY 0x00000008

/**
* By default, the cose t_cose_sign1_sign will calculate the hash
* of the payload and sign the hash.
* Set T_COSE_OPT_SIGN_MESSAGE to instead sign the message(payload)
* directly instead.
*/
#define T_COSE_OPT_SIGN_MESSAGE 0x00000010


#ifdef __cplusplus
}
Expand Down
15 changes: 8 additions & 7 deletions lib/ext/t_cose/src/t_cose_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ t_cose_crypto_sig_size(int32_t cose_algorithm_id,
struct t_cose_key signing_key,
size_t *sig_size);


/**
* \brief Perform public key signing. Part of the t_cose crypto
* adaptation layer.
* \brief Perform public key signing of a payload. Can sign either
* a message or message hash. Part of the t_cose crypto adaptation
* layer.
*
* \param[in] cose_algorithm_id The algorithm to sign with. The IDs are
* defined in [COSE (RFC 8152)]
Expand All @@ -169,8 +169,7 @@ t_cose_crypto_sig_size(int32_t cose_algorithm_id,
* locally (\c \#define) if the needed
* one hasn't been registered.
* \param[in] signing_key Indicates or contains key to sign with.
* \param[in] hash_to_sign The bytes to sign. Typically, a hash of
* a payload.
* \param[in] to_sign The bytes to sign.
* \param[in] signature_buffer Pointer and length of buffer into which
* the resulting signature is put.
* \param[in] signature Pointer and length of the signature
Expand Down Expand Up @@ -215,9 +214,11 @@ t_cose_crypto_sig_size(int32_t cose_algorithm_id,
enum t_cose_err_t
t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
struct t_cose_key signing_key,
struct q_useful_buf_c hash_to_sign,
struct q_useful_buf_c to_sign,
struct q_useful_buf signature_buffer,
struct q_useful_buf_c *signature);
struct q_useful_buf_c *signature,
int32_t option_flags);



/**
Expand Down
40 changes: 28 additions & 12 deletions lib/ext/t_cose/src/t_cose_sign1_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,18 @@ t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *me,
*/
enum t_cose_err_t return_value;
QCBORError cbor_err;
/* Pointer to useful_buf used for the signature*/
struct q_useful_buf_c *tbs;
/* pointer and length of the completed tbs hash */
struct q_useful_buf_c tbs_hash;
/* Pointer and length of the completed signature */
struct q_useful_buf_c signature;
/* Buffer for the actual signature */
Q_USEFUL_BUF_MAKE_STACK_UB( buffer_for_signature, T_COSE_MAX_SIG_SIZE);
/* Buffer for the tbs hash. */
#ifndef T_COSE_SIGN_MESSAGE
Q_USEFUL_BUF_MAKE_STACK_UB( buffer_for_tbs_hash, T_COSE_CRYPTO_MAX_HASH_SIZE);
#endif
struct q_useful_buf_c signed_payload;

QCBOREncode_CloseBstrWrap(cbor_encode_ctx, &signed_payload);
Expand Down Expand Up @@ -358,21 +362,27 @@ t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *me,
me->signing_key,
&signature.len);
} else {
/* Sign hash
*/

if(!(me->option_flags & T_COSE_OPT_SIGN_MESSAGE)) {
#ifndef T_COSE_SIGN_MESSAGE
/* Create the hash of the to-be-signed bytes. Inputs to the
* hash are the protected parameters, the payload that is
* getting signed, the cose signature alg from which the hash
* alg is determined. The cose_algorithm_id was checked in
* t_cose_sign1_init() so it doesn't need to be checked here.
*/
return_value = create_tbs_hash(me->cose_algorithm_id,
me->protected_parameters,
T_COSE_TBS_PAYLOAD_IS_BSTR_WRAPPED,
signed_payload,
buffer_for_tbs_hash,
&tbs_hash);
if(return_value) {
goto Done;
return_value = create_tbs_hash(me->cose_algorithm_id,
me->protected_parameters,
T_COSE_TBS_PAYLOAD_IS_BSTR_WRAPPED,
signed_payload,
buffer_for_tbs_hash,
&tbs_hash);
if(return_value) {
goto Done;
}
#endif
}

/* Compute the signature using public key crypto. The key and
Expand All @@ -388,11 +398,17 @@ t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *me,
*/
if(!(me->option_flags & T_COSE_OPT_SHORT_CIRCUIT_SIG)) {
/* Normal, non-short-circuit signing */
if(!(me->option_flags & T_COSE_OPT_SIGN_MESSAGE)) {
tbs = &tbs_hash;
} else {
tbs = &(me->protected_parameters);
}
return_value = t_cose_crypto_pub_key_sign(me->cose_algorithm_id,
me->signing_key,
tbs_hash,
buffer_for_signature,
&signature);
me->signing_key,
*tbs,
buffer_for_signature,
&signature,
me->option_flags);
} else {
#ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN
/* Short-circuit signing */
Expand Down
3 changes: 2 additions & 1 deletion lib/ext/t_cose/test/t_cose_make_test_messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,8 @@ t_cose_sign1_test_message_output_signature(struct t_cose_sign1_sign_ctx *me,
me->signing_key,
tbs_hash,
buffer_for_signature,
&signature);
&signature,
me->option_flags);
} else {
#ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN
return_value = short_circuit_sign(me->cose_algorithm_id,
Expand Down
1 change: 1 addition & 0 deletions lib/ext/t_cose/tfm_t_cose.cmake
Copy link
Contributor

@tomi-font tomi-font Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we making changes to lib/ext/t_cose as a noup while it exists upstream?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I will make a PR upstream instead, and then fix this PR accordingly.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ target_compile_definitions(tfm_t_cose_defs
$<$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>:T_COSE_DISABLE_SIGN1>
$<$<NOT:$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>>:T_COSE_DISABLE_MAC0>
$<$<NOT:$<BOOL:${ATTEST_INCLUDE_TEST_CODE}>>:T_COSE_DISABLE_SHORT_CIRCUIT_SIGN>
$<$<BOOL:${ATTEST_SIGN_MESSAGE}>:T_COSE_SIGN_MESSAGE>
)

############################### t_cose common ##################################
Expand Down
8 changes: 8 additions & 0 deletions secure_fw/partitions/initial_attestation/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ config ATTEST_KEY_BITS
help
The size of the initial attestation key in bits

config ATTEST_SIGN_MESSAGE
bool "Sign message instead of hash"
default n
help
By default attestation calculates a hash of the payload and signs that.
Use this to instead sign the payload/message directly.


config PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE
hex "The maximum possible size of a token"
default 0x250
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ attest_token_encode_start(struct attest_token_encode_ctx *me,
me->opt_flags = opt_flags;
me->key_select = key_select;

#ifdef ATTEST_SIGN_MESSAGE
t_cose_options |= T_COSE_OPT_SIGN_MESSAGE;
#endif

if (opt_flags & TOKEN_OPT_SHORT_CIRCUIT_SIGN) {
t_cose_options |= T_COSE_OPT_SHORT_CIRCUIT_SIG;
Expand Down