Skip to content

PSA Initial Attestation service #9668

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

Merged
merged 56 commits into from
Mar 1, 2019
Merged

Conversation

moranpeker
Copy link
Contributor

@moranpeker moranpeker commented Feb 11, 2019

Description

Attestation service can create a token on request, which contains a fix set of
device specific data.

Contains the implementation of ‘psa_initial_attest_get_token_size’ , ‘psa_initial_attest_get_token’ and ‘psa_attestation_inject_key’.

PSA Initial Attestation Service based on TF-M Attestation Service that taken from TF-M master.
TF-M latest attestation version is: c43181daf54f69f53de58593a50dd6a9c233eecd

Signing of token
‘psa_attestation_inject_key’ API - Device must contain an attestation key pair. The token is signed with the private part of attestation key pair. The public key is used to verify the token authenticity.

Inject attestation key by importing a given private key or generate a key pair.
Attestation key stored as a persistent key with a specific key-id.

Claims in the initial attestation token
The initial attestation token is formed of claims.
List of claims are included in the token:
https://confluence.arm.com/display/IoTBU/Claims+in+PSA+IAT+report
In the current implementation no bootloader exists in single & dual V7 .
In the current implementation temporary mandatory claims (ONLY) are given by a hard coded temp bootloader status data (attestation_bootloader_data.c).

Code structure
The PSA interface for the Initial Attestation Service is located in
components\TARGET_PSA\services\attestation.
The only headers to be included by applications that want to use functions from
the PSA API are psa_initial_attestation_api.h and psa_attest_inject_key.h (under components\TARGET_PSA\inc\psa folder).

Service source files

  • CBOR library: qcbor: This library is used to create a proper CBOR token. It is a fork of this external QCBOR library.

  • For now, TFM source files are part of this PR and located in components\TARGET_PSA\services\attestation\tfm_impl + header files ‘psa_initial_attestation_api.h’ and ‘attestation.h’.
    An importer needs to be created to import TFM source files.

Code checked over K64F and PSOC6.
Pass compliance tests over K64F and PSOC6.

This PR includes and depends on the security lifecycle bug fix ( PR = #9745 )

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[X] Functionality change
[ ] Docs update
[ ] Test update
[X] Breaking change

Reviewers

Release Notes

  • A brief description of changes introduced.
    Add PSA Initial Attestation Service implementation.
  • An analysis of effects: components affected, potential consequences for users and reasons for the addition or change.
    this code is a new feature and doesn't effect existing code.
  • Migration guidance: actions for updating the current code. Please include code snippets to illustrate before and after the addition or change.
    This breaks backwards compatibility with Nucleo F411RE entropy injection.

@ciarmcom ciarmcom requested a review from a team February 11, 2019 22:00
@ciarmcom
Copy link
Member

@moranpeker, thank you for your changes.
@ARMmbed/mbed-os-maintainers please review.

@@ -23,3 +23,4 @@ targets
components/802.15.4_RF
components/wifi
tools
components/TARGET_PSA/services/attestation/COMPONENT_PSA_SRV_IMPL/tfm_impl
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 for the commit comment about this.

Copy link
Contributor

Choose a reason for hiding this comment

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

One note: please revert file permissions changes 100644 → 100755 ?

@cmonr cmonr requested a review from a team February 12, 2019 00:10
@cmonr
Copy link
Contributor

cmonr commented Feb 12, 2019

Checked over K64F and PSOC6.

Should PSOC6 also have its/their targets.json entries updated?

cmonr
cmonr previously requested changes Feb 12, 2019
Copy link
Contributor

@cmonr cmonr left a comment

Choose a reason for hiding this comment

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

A nit whilse others get a better chance to review.
Please revert the permissions of target.json and .astyle.yml (755 -> 644)

@cmonr
Copy link
Contributor

cmonr commented Feb 12, 2019

Also, there are still some astyle issues: https://travis-ci.org/ARMmbed/mbed-os/jobs/491854379

*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

please change license for all to Apache.

  • Copyright (c) 2006-2013 ARM Limited
  • SPDX-License-Identifier: Apache-2.0
  • Licensed under the Apache License, Version 2.0 (the "License");
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
  • http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an "AS IS" BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */

Copy link
Contributor

Choose a reason for hiding this comment

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

2018-2019

Copy link
Contributor

Choose a reason for hiding this comment

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

Please leave all TF-M sources license as is. only our wrappers should be under Apache.
TF-M license is handled by legal currently

return err;
}

*token_size = out_vec[0].len;
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need this line?
or this takes care of it psa_outvec out_vec[1] = { { token, *token_size } };

Copy link
Contributor

@alekshex alekshex left a comment

Choose a reason for hiding this comment

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

first pass

* \brief Indicates whether shared data area was already initialized.
*
*/
static uint32_t shared_data_init_done;
Copy link
Contributor

Choose a reason for hiding this comment

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

please assign initial uninitialized value

psa_outvec out_vec[1] = { { token_size, sizeof(*token_size) } };

err = initial_attest_get_token_size(in_vec, 1, out_vec, 1);
if (err != PSA_ATTEST_ERR_SUCCESS)
Copy link
Contributor

Choose a reason for hiding this comment

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

no need, err returned anyway, unless you want additional handling

offset = (uintptr_t)BOOT_TFM_SHARED_DATA_BASE + (uintptr_t)SHARED_DATA_HEADER_SIZE;

/* Add header to output buffer as well */
if (len < SHARED_DATA_HEADER_SIZE)
Copy link
Contributor

Choose a reason for hiding this comment

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

what if len > header size?
is the idea that len must be equal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

len its the buffer lenght. it must be bigger/equal to all boot status data.
this check in line 78:
if (len < ptr_tlv_header->tlv_tot_len + tlv_entry->tlv_len)

if (len < SHARED_DATA_HEADER_SIZE)
{
return PSA_ATTEST_ERR_INIT_FAILED;
} else
Copy link
Contributor

Choose a reason for hiding this comment

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

why do you need else if you have return before?

#include "tfm_plat_crypto_keys.h"
#include <string.h>

static psa_hash_operation_t hash_handle;
Copy link
Contributor

Choose a reason for hiding this comment

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

please init to NULL initially

crypto_ret = psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle);
if (crypto_ret != PSA_SUCCESS)
{
return TFM_PLAT_ERR_SYSTEM_ERR;
Copy link
Contributor

Choose a reason for hiding this comment

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

no crypto deinit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed all calling to psa_crypto_init - we assume init called before crypto operations, if not an error will be return.

#include "attestation.h"
#include "crypto.h"

extern int32_t g_caller_id;
Copy link
Contributor

Choose a reason for hiding this comment

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

must be initialized

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no need in extern

/* Hash of attestation public key */
static enum tfm_plat_err_t attest_public_key_sha256(uint32_t *size, uint8_t *buf)
{
const psa_key_id_t key_id = 17;
Copy link
Contributor

Choose a reason for hiding this comment

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

...


crypto_ret = psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle);
if (crypto_ret != PSA_SUCCESS) {
return TFM_PLAT_ERR_SYSTEM_ERR;
Copy link
Contributor

Choose a reason for hiding this comment

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

..


status = psa_create_key(lifetime, key_id, &handle);
if (status != PSA_SUCCESS) {
return (status);
Copy link
Contributor

Choose a reason for hiding this comment

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

deinit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same.

{
if (data_to_hash.ptr != NULL) {
psa_hash_update(&hash_handle, data_to_hash.ptr, data_to_hash.len);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

why else needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function caled by get attestation token and get attestation token size.
for the second purpose - data_to_hash(the payload) its null and no hash needed

public_key_data, public_key_data_size
};
out_vec[1] = (psa_outvec) {
public_key_data_length, sizeof(*public_key_data_length)
Copy link
Contributor

Choose a reason for hiding this comment

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

why sizeof?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why not ?

Copy link
Contributor

Choose a reason for hiding this comment

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

is the idea here to have sizeof member pointed to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

psa_outvec out_vec[1] = { { token, *token_size } };

handle = psa_connect(PSA_ATTEST_GET_TOKEN_ID, MINOR_VER);
if (handle <= 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

0 is also illegal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right

Copy link
Contributor

@0xc0170 0xc0170 left a comment

Choose a reason for hiding this comment

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

[ ] Functionality change

Please set PR type

If functionality change, I believe this one yes, will require release notes addition , see https://os.mbed.com/docs/mbed-os/v5.11/contributing/workflow.html#functionality-change

@@ -23,3 +23,4 @@ targets
components/802.15.4_RF
components/wifi
tools
components/TARGET_PSA/services/attestation/COMPONENT_PSA_SRV_IMPL/tfm_impl
Copy link
Contributor

Choose a reason for hiding this comment

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

One note: please revert file permissions changes 100644 → 100755 ?

@@ -0,0 +1,148 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

2019 now?

psa_key_handle_t handle = 0;
psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle);
psa_destroy_key(handle);
// mbedtls_psa_cr/ypto_free();
Copy link
Contributor

Choose a reason for hiding this comment

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

don't leave dead code behind

/* These APIs are still evolving and are meant as a prototype for review.*/
/* The APIs will change depending on feedback and will be firmed up */
/* to a stable set of APIs once all the feedback has been considered. */
/***************************************************************************/
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this ready fro the release or kept here only during this review?

@@ -1456,7 +1456,8 @@
"KPSDK_CODE",
"MCU_K64F",
"Freescale_EMAC",
"PSA"
"PSA",
Copy link
Contributor

Choose a reason for hiding this comment

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

Same for this file, file permissions are being changed

@@ -0,0 +1,230 @@
// ---------------------------------- Includes ---------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

missing license header

@0xc0170
Copy link
Contributor

0xc0170 commented Feb 20, 2019

@moranpeker Please let us know what has been update (PR status)

@moranpeker
Copy link
Contributor Author

Hi @0xc0170 , the PR is rebased over master and ready for review.
@avolinski will review it too.

Can you please change the label to 'need: review" ? ( I can't change it )

Copy link
Contributor

@alekshex alekshex left a comment

Choose a reason for hiding this comment

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

please see comments

{
#if (defined(COMPONENT_PSA_SRV_IPC) || defined(MBEDTLS_ENTROPY_NV_SEED))
uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = {0};
/* inject some a seed for test*/
Copy link
Contributor

Choose a reason for hiding this comment

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

/* inject some seed for test*/

seed[i] = i;
}

/* don't really care if this succeed this is just to make crypto init pass*/
Copy link
Contributor

Choose a reason for hiding this comment

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

/* don't really care if this succeeds this is just to make crypto init pass*/

extern const uint32_t crypto_srv_external_sids[4];
extern const uint32_t platform_external_sids[1];

spm_partition_t g_partitions[4] = {
spm_partition_t g_partitions[5] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

why not in define?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

psa_setup is generated file by calling 'tools/psa/generate_tfm_partition_code.py' script

Copy link
Contributor

Choose a reason for hiding this comment

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

That script could just omit the size, if only to avoid such comments.

extern const uint32_t crypto_srv_external_sids[4];
extern const uint32_t platform_external_sids[1];

spm_partition_t g_partitions[5] = {
spm_partition_t g_partitions[6] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

def

Copy link
Contributor Author

Choose a reason for hiding this comment

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

psa_setup is generated file by calling 'tools/psa/generate_tfm_partition_code.py' script

extern const uint32_t crypto_srv_external_sids[4];
extern const uint32_t platform_external_sids[1];

spm_partition_t g_partitions[4] = {
spm_partition_t g_partitions[5] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

def

Copy link
Contributor Author

Choose a reason for hiding this comment

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

psa_setup is generated file by calling 'tools/psa/generate_tfm_partition_code.py' script

*size,
(size_t *) size);
if (crypto_ret != PSA_SUCCESS) {
free(public_key);
Copy link
Contributor

Choose a reason for hiding this comment

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

too many same kind of operations: free, close
please consider goto with appropriate error code

* \param[in] p_src Pointer to the ID
* \param[in] size Length of the ID
*/
static inline void copy_id(uint8_t *p_dst, uint8_t *p_src, size_t size)
Copy link
Contributor

Choose a reason for hiding this comment

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

code duplication, copy_key can be used here also.
just name it copy_src_to_dst

And if the ptr is uint8*, why aren't you using memcpy??


#include "attestation_bootloader_data.h"

/* Temporary Boodloader data - conatians temp mandatory claims */
Copy link
Contributor

Choose a reason for hiding this comment

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

contains

return PSA_ATTEST_ERR_INVALID_INPUT;
}
return PSA_ATTEST_ERR_SUCCESS;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

legal eof?


status = psa_create_key(lifetime, key_id, &handle);
if (status != PSA_SUCCESS) {
return (status);
Copy link
Contributor

Choose a reason for hiding this comment

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

no crypto deinit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same

Moran Peker added 2 commits February 28, 2019 15:54
-initialized  psa_hash_operation_t to zeros
-fix TF-M attestation code - increase t_cose_crypto_hash bytes to
handle max psa_hash_operation_t size
*
* Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
Copy link
Contributor

Choose a reason for hiding this comment

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

just checking, this attestation is already in Readme covered as non apache file and license file present in the attestation folder?

Copy link
Contributor

Choose a reason for hiding this comment

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

Answer: yes, I've just checked

@0xc0170
Copy link
Contributor

0xc0170 commented Feb 28, 2019

@moranpeker Can you review build failures? Latest commits are fixing these or still to do?

@moranpeker
Copy link
Contributor Author

@moranpeker Can you review build failures? Latest commits are fixing these or still to do?

last CI run failed because I asked from @NirSonnenschein to stop the running for new commits I pushed.

@mikisch81 mikisch81 mentioned this pull request Feb 28, 2019
@mbed-ci
Copy link

mbed-ci commented Feb 28, 2019

Test run: FAILED

Summary: 1 of 9 test jobs failed
Build number : 6
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-IAR8

@mikisch81
Copy link
Contributor

@cmonr was the last CI run aborted? If so can it restart?

@cmonr
Copy link
Contributor

cmonr commented Feb 28, 2019

@mikisch81 It's because a new commit was added to the PR, thus changing the HEAD's sha.
Will restart.

last CI run failed because I asked from @NirSonnenschein to stop the running for new commits I pushed.

@cmonr
Copy link
Contributor

cmonr commented Feb 28, 2019

CI started

@mbed-ci
Copy link

mbed-ci commented Feb 28, 2019

Test run: SUCCESS

Summary: 13 of 13 test jobs passed
Build number : 7
Build artifacts

@cmonr cmonr merged commit befed11 into ARMmbed:master Mar 1, 2019
@cmonr cmonr removed the needs: CI label Mar 1, 2019
@cmonr
Copy link
Contributor

cmonr commented Mar 1, 2019

@moranpeker @orenc17 I want to confirm something.

https://travis-ci.org/ARMmbed/mbed-os/jobs/500094537

Does this PR modify what is generated in this test?

@cmonr
Copy link
Contributor

cmonr commented Mar 1, 2019

CC @ARMmbed/mbed-os-maintainers

@mikisch81
Copy link
Contributor

@NirSonnenschein @cmonr @0xc0170
There was apperently a race between this PR and another PR which re-generated code.
Therefore for each PR the psa_autogen job passed, but after they were merged the next PRs failed.
We need to call python tools/psa/generate_mbed_spm_partition_code.py on master in order to regenerate again.

@mikisch81
Copy link
Contributor

I can do it when I will be near a PC, but if anyone can do it earlier it's to the best

@mikisch81
Copy link
Contributor

Also python tools/psa/generate_tfm_partition_code.py needs to be called.

@0xc0170
Copy link
Contributor

0xc0170 commented Mar 1, 2019

Thanks @mikisch81 !

@mikisch81
Copy link
Contributor

#9899 will fix the Travis issue

@adbridge
Copy link
Contributor

adbridge commented Mar 8, 2019

@moranpeker According to @teetak01 " this breaks backwards compatibility with Nucleo F411RE entropy injection.". Can you please add this to the release notes section and change the type to breaking change rather than functionality change.

@moranpeker
Copy link
Contributor Author

@moranpeker According to @teetak01 " this breaks backwards compatibility with Nucleo F411RE entropy injection.". Can you please add this to the release notes section and change the type to breaking change rather than functionality change.

Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.