Skip to content

Commit

Permalink
[nrf noup] Attest+COSE: Draft to test upstream change
Browse files Browse the repository at this point in the history
  • Loading branch information
hellesvik-nordic committed Dec 6, 2024
1 parent cc9a53f commit 55d44ca
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 14 deletions.
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,7 @@ 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()``: Calculates the signature over a value.
- ``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
17 changes: 14 additions & 3 deletions lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ t_cose_crypto_pub_key_verify(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)
{
Expand Down Expand Up @@ -196,13 +196,24 @@ 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.
*/

#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 */
#else
psa_result = psa_sign_hash(signing_key_psa,
psa_alg_id,
hash_to_sign.ptr,
hash_to_sign.len,
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
11 changes: 5 additions & 6 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,7 +214,7 @@ 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);

Expand Down
61 changes: 60 additions & 1 deletion lib/ext/t_cose/src/t_cose_sign1_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
#error COSE algorithm identifier definitions are in error
#endif

/**
* This is the size of the first part of the CBOR encoded TBS
* bytes. It is around 30 bytes. See create_tbs_hash().
*/
#define T_COSE_SIZE_OF_TBS \
1 + /* For opening the array */ \
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_SIZE_PROTECTED_PARAMETERS + /* entire protected params */ \
1 + /* Empty bstr for absent external_aad */ \
220 /* The max CBOR length encoding for start of payload */


#ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN
/**
Expand Down Expand Up @@ -323,14 +335,27 @@ 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;
#ifndef T_COSE_SIGN_MESSAGE
/* pointer and length of the completed tbs hash */
struct q_useful_buf_c tbs_hash;
#else
/* pointer and length of the completed tbs message */
struct q_useful_buf_c tbs_message;
QCBOREncodeContext cbor_Sig_structure_ctx;
/* Pointer and length of the completed signature */
QCBORError qcbor_result;
Q_USEFUL_BUF_MAKE_STACK_UB( buffer_for_tbs_message, T_COSE_SIZE_OF_TBS);
#endif
/* 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);
#ifndef T_COSE_SIGN_MESSAGE
/* Buffer for the tbs hash. */
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 @@ -359,6 +384,7 @@ t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *me,
&signature.len);
} else {

#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
Expand All @@ -374,6 +400,7 @@ t_cose_sign1_encode_signature(struct t_cose_sign1_sign_ctx *me,
if(return_value) {
goto Done;
}
#endif

/* Compute the signature using public key crypto. The key and
* algorithm ID are passed in to know how and what to sign
Expand All @@ -388,9 +415,41 @@ 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 */
#ifdef T_COSE_SIGN_MESSAGE
QCBOREncode_Init(&cbor_Sig_structure_ctx, buffer_for_tbs_message);
QCBOREncode_OpenArray(&cbor_Sig_structure_ctx);

/* context */
QCBOREncode_AddSZString(&cbor_Sig_structure_ctx, COSE_SIG_CONTEXT_STRING_SIGNATURE1);
/* body_protected */
QCBOREncode_AddBytes(&cbor_Sig_structure_ctx, me->protected_parameters);

/* sign_protected is not used for COSE_Sign1 */

/* external_aad. There is none so an empty bstr */
QCBOREncode_AddBytes(&cbor_Sig_structure_ctx, NULL_Q_USEFUL_BUF_C);

/* payload */
QCBOREncode_AddBytes(&cbor_Sig_structure_ctx, signed_payload);

/* Close off the array */
QCBOREncode_CloseArray(&cbor_Sig_structure_ctx);

qcbor_result = QCBOREncode_Finish(&cbor_Sig_structure_ctx, &tbs_message);
if(qcbor_result) {
/* Mainly means that the protected_parameters were too big
* (which should never happen) */
return_value = T_COSE_ERR_SIG_STRUCT;
goto Done;
}

tbs = &tbs_message;
#else
tbs = &tbs_hash;
#endif
return_value = t_cose_crypto_pub_key_sign(me->cose_algorithm_id,
me->signing_key,
tbs_hash,
*tbs,
buffer_for_signature,
&signature);
} else {
Expand Down
17 changes: 15 additions & 2 deletions lib/ext/t_cose/test/t_cose_make_test_messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,14 +475,18 @@ t_cose_sign1_test_message_output_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);
#ifndef T_COSE_SIGN_MESSAGE
/* Buffer for the tbs hash. */
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 All @@ -501,6 +505,8 @@ t_cose_sign1_test_message_output_signature(struct t_cose_sign1_sign_ctx *me,
goto Done;
}

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
Expand All @@ -516,6 +522,7 @@ t_cose_sign1_test_message_output_signature(struct t_cose_sign1_sign_ctx *me,
if(return_value != T_COSE_SUCCESS) {
goto Done;
}
#endif

/* Compute the signature using public key crypto. The key selector
* and algorithm ID are passed in to know how and what to sign
Expand All @@ -529,11 +536,17 @@ t_cose_sign1_test_message_output_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,
*tbs,
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
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,7 +241,6 @@ attest_token_encode_start(struct attest_token_encode_ctx *me,
me->opt_flags = opt_flags;
me->key_select = key_select;


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

0 comments on commit 55d44ca

Please sign in to comment.