Skip to content

Atmel hardware reference implementation #1

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

Closed
wants to merge 3 commits into from
Closed
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
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "psa-crypto"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we call this mbedtls-psa instead to match the repo name? Or are you calling it psa-crypto because you anticipate depending on the psa-crypto repo instead of mbedtls-psa later to get the header file?

Copy link
Author

Choose a reason for hiding this comment

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

exactly, all we need is the headers so it will be less of a pain to update this when we'll be able to fetch the headers from the psa-crypto repo.

path = psa-crypto
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be under features/atecc608a instead of at the root?

Copy link
Author

Choose a reason for hiding this comment

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

I tried this, it's problematic due to the mbed build system (maybe a bug in mbed?).
I tried a bunch of different ways but the wrong mbedtls/config.h file was getting included even though the mbed_lib.json had MBEDTLS_CONFIG_FILE defined properly to point to the correct file. Just for sport I even tried passing it via the linker but again this was not successful.

It's possible to add the submodule to the root of features if that's better...

url = [email protected]:ARMmbed/mbedtls-psa.git
branch = feature-psa
10 changes: 10 additions & 0 deletions .mbedignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
psa-crypto/configs/*
Copy link
Contributor

Choose a reason for hiding this comment

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

Where should the .mbedignore go? Is there a place we could put it in features? I want users to still be able to use their own custom .mbedignore file without having to edit our own.

Copy link
Author

Choose a reason for hiding this comment

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

As with the submodule this was not successful and had to be at the root.

psa-crypto/doxygen/*
psa-crypto/include/mbedtls/*
psa-crypto/library/*
psa-crypto/programs/*
psa-crypto/scripts/*
psa-crypto/tests/*
psa-crypto/visualc/*
psa-crypto/yotta/*

97 changes: 97 additions & 0 deletions features/atecc608a/ATCAConfig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* ATECC608A driver
* Copyright (c) 2018 ARM Limited
*
* 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.
*/

#include "ATCAConfig.h"

ATCAError SlotConfig::EnableGenKey()
{
if (!IsPrivKey())
return ATCA_ERR_SLOT_NOT_PRIV_KEY;
_register = (_register & ~SLOT_CONFIG_WRITE_CONFIG_MASK) | SLOT_CONFIG_GEN_KEY_ENABLE_FLAG;
return ATCA_SUCCESS;
}

void SlotConfig::SetAsPrivKey()
{
/* Declare ECC Private key */
_register |= SLOT_CONFIG_IS_SECRET_MASK;
/* Disable reads */
_register &= ~SLOT_CONFIG_ENCRYPT_READ_MASK;
}

void SlotConfig::EnableExtMsgSig()
{
/* Disable ECDH operations and internal signatures */
_register &= ~SLOT_CONFIG_READ_KEY_MASK;
/* Enable signing of arbitrary external messages */
_register |= SLOT_CONFIG_INT_SIG_FLAG;
_register |= SLOT_CONFIG_EXT_SIG_FLAG;
}

bool SlotConfig::GenKeyEnabled()
{
return ( (_register & SLOT_CONFIG_WRITE_CONFIG_MASK) == SLOT_CONFIG_GEN_KEY_ENABLE_FLAG);
}

bool SlotConfig::IsPrivKey()
{
return (_register & SLOT_CONFIG_IS_SECRET_MASK) == SLOT_CONFIG_IS_SECRET_MASK &&
(_register & SLOT_CONFIG_ENCRYPT_READ_MASK) == 0;
}


ATCAError KeyConfig::SetECCKeyType()
{
_register &= ~KEY_CONFIG_KEY_TYPE_MASK;
_register |= KEY_CONFIG_P256_ECC_KEY;
return ATCA_SUCCESS;
}

ATCAError KeyConfig::SetNonECCKeyType()
{
_register &= ~KEY_CONFIG_KEY_TYPE_MASK;
_register |= KEY_CONFIG_NON_ECC_KEY;
return ATCA_SUCCESS;
}

ATCAError KeyConfig::EnablePubKeyGen()
{
if (!IsPrivate())
return ATCA_ERR_SLOT_NOT_PRIV_KEY;
_register |= KEY_CONFIG_EN_PUB_KEY_MASK;
return ATCA_SUCCESS;
}

void KeyConfig::SetPrivate()
{
_register |= KEY_CONFIG_PRIVATE_KEY_MASK;
}

bool KeyConfig::IsECCKey()
{
return ( (_register & KEY_CONFIG_P256_ECC_KEY) == KEY_CONFIG_P256_ECC_KEY);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use Mbed OS C coding style and not Mbed TLS coding style.

https://os.mbed.com/docs/latest/reference/style.html

Copy link
Author

Choose a reason for hiding this comment

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

There are different styles throughout the code here, but I think it's best to wait until we do some refactoring in the driver code.

}

bool KeyConfig::PubKeyGenEnabled()
{
return ( (_register & KEY_CONFIG_EN_PUB_KEY_MASK) == KEY_CONFIG_EN_PUB_KEY_MASK);
}

bool KeyConfig::IsPrivate()
{
return ( (_register & KEY_CONFIG_PRIVATE_KEY_MASK) == KEY_CONFIG_PRIVATE_KEY_MASK);
}

102 changes: 102 additions & 0 deletions features/atecc608a/ATCAConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* ATECC608A driver
* Copyright (c) 2018 ARM Limited
*
* 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.
*/

#ifndef ATCACONFIG_H
#define ATCACONFIG_H

#include <stdint.h>
#include "ATCAError.h"

/* Field masks */
#define SLOT_CONFIG_WRITE_CONFIG_MASK 0xF000
#define SLOT_CONFIG_IS_SECRET_MASK 0x0080
#define SLOT_CONFIG_ENCRYPT_READ_MASK 0x0040
#define SLOT_CONFIG_READ_KEY_MASK 0x000F

#define KEY_CONFIG_KEY_TYPE_MASK 0x001C
#define KEY_CONFIG_PRIVATE_KEY_MASK 0x0001
#define KEY_CONFIG_EN_PUB_KEY_MASK 0x0002

/* Configuration flags */
#define SLOT_CONFIG_GEN_KEY_ENABLE_FLAG 0x2000
#define SLOT_CONFIG_INT_SIG_FLAG 0x0002
#define SLOT_CONFIG_EXT_SIG_FLAG 0x0001

#define KEY_CONFIG_P256_ECC_KEY 0x0010
#define KEY_CONFIG_NON_ECC_KEY 0x001C

/** class for validating and preparing slot config for a data zone.
*/
class SlotConfig
{
private:
uint16_t _register;
public:
SlotConfig(uint16_t slot_config)
: _register(slot_config)
{}
SlotConfig()
{
Reset();
}

void Reset(){ _register = 0; }
ATCAError EnableGenKey();
void SetAsPrivKey();
void EnableExtMsgSig();

bool GenKeyEnabled();
bool IsPrivKey();
uint16_t Get()
{
return _register;
}
};


/** class for validating and preparing key config for a data zone.
*/
class KeyConfig
{
private:
uint16_t _register;

public:
KeyConfig(uint16_t key_config)
: _register(key_config)
{}

KeyConfig()
{
Reset();
}

void Reset(){ _register = 0; }
ATCAError SetECCKeyType();
ATCAError SetNonECCKeyType();
ATCAError EnablePubKeyGen();
void SetPrivate();

bool IsECCKey();
bool PubKeyGenEnabled();
bool IsPrivate();
uint16_t Get()
{
return _register;
}
};

#endif /* ATCACONFIG_H */
125 changes: 125 additions & 0 deletions features/atecc608a/ATCAConstants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* ATECC608A driver
* Copyright (c) 2018 ARM Limited
*
* 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.
*/

#ifndef ATCAECCCONSTANTS_H
#define ATCAECCCONSTANTS_H

/** Datasheet defined constants */
#define ATCA_ECC_508A_I2C_ADDR 0xC0
#define ATCA_ECC_508A_REVISION {0x00, 0x00, 0x50, 0x00}
#define ATCA_ECC_WORD_SZ 4
#define ATCA_ECC_STATUS_RESP_LEN 4
#define ATCA_ECC_RESP_STATUS_IDX 1
#define ATCA_ECC_NUM_PRIV_KEY_SLOTS 8
#define ATCA_ECC_ECC_PK_LEN 64
#define ATCA_ECC_CONFIG_ZONE_SZ 128
#define ATCA_KEY_ID_0 0
#define ATCA_ECC_HASH_256_LEN 32
#define ATCA_ECC_SIG_LEN 64
#define ATCA_ECC_CRC_POLYNOMIAL 0x8005
#define ATCA_ECC_NUM_DEVICE_DATA_BLOCKS 4

/** Device functions */
#define ATCA_ECC_FUNC_RST_IO_ADDR 0x00
#define ATCA_ECC_FUNC_SLEEP 0x01
#define ATCA_ECC_FUNC_IDLE 0x02
#define ATCA_ECC_FUNC_COMMAND 0x03


/** EEPROM Zones */
enum ATCAZone
{
ATCA_ECC_ZONE_CONFIG = 0x0

/* Data and OTP zones are not defined here as this driver does not make
* use of them. */
};

/** Command opcodes */
enum ATCAOpCode
{
ATCA_ECC_CMD_OPCODE_READ = 0x02,
ATCA_ECC_CMD_OPCODE_WRITE = 0x12,
ATCA_ECC_CMD_OPCODE_LOCK = 0x17,
ATCA_ECC_CMD_OPCODE_GENKEY = 0x40,
ATCA_ECC_CMD_OPCODE_NONCE = 0x16,
ATCA_ECC_CMD_OPCODE_SIGN = 0x41,
ATCA_ECC_CMD_OPCODE_VERIFY = 0x45,
};

/** Key ID/Slot no. Type */
typedef uint32_t ATCAKeyID;
#define ATCA_ECC_KEY_ID_0 0
#define ATCA_ECC_KEY_ID_INVALID 0xFFFFFFFF

/** Command and response length */
#define ATCA_ECC_CMD_OFFSET 2 /* Command offset in Tx buffer */
#define ATCA_ECC_RESP_OFFSET 1 /* Response offset in Rx buffer */
#define ATCA_ECC_CRC_INPUT_OFFSET 1 /* CRC input data offset in Tx buffer */
#define ATCA_ECC_MAX_CMD_LEN 132 /* Bytes device allocates for constructing command */
#define ATCA_ECC_MAX_RESP_LEN 67 /* Bytes device allocates for constructing responce */
#define ATCA_ECC_FUNCTION_LEN 1 /* Device function (Write address) */
#define ATCA_ECC_CMD_IO_WRAPER_LEN 3 /* Count + CRC */
#define ATCA_ECC_CMD_READ_LEN 4
#define ATCA_ECC_RESP_READ_LEN 7
#define ATCA_ECC_CMD_WRITE_LEN 8
#define ATCA_ECC_RESP_WRITE_LEN 4
#define ATCA_ECC_CMD_WRITE_LEN 8
#define ATCA_ECC_RESP_WRITE_LEN 4
#define ATCA_ECC_CMD_LOCK_LEN 4
#define ATCA_ECC_STATUS_LEN 4
#define ATCA_ECC_CMD_GENKEY_LEN 4
#define ATCA_ECC_RESP_GENKEY_LEN 67
#define ATCA_ECC_CMD_NONCE_LEN 36
#define ATCA_ECC_CMD_SIGN_LEN 4
#define ATCA_ECC_RESP_SIGN_LEN 67
#define ATCA_ECC_CMD_VERIFY_LEN 132

/** EEPROM addresses */
#define ATCA_ECC_CFG_ADDR_REVISION 4
#define ATCA_ECC_CFG_ADDR_SLOT_CFG 20
#define ATCA_ECC_CFG_ADDR_KEY_CFG 96
#define ATCA_ECC_CFG_ADDR_LCK_CFG 87

/** Flags */
#define ATCA_ECC_FLG_READ_SZ_32 0x80

/** Devices Delays */
#define ATCA_ECC_DELAY_TPU_US 100
#define ATCA_ECC_DELAY_TWLO_US 60
#define ATCA_ECC_DELAY_TWHI_US 1500
#define ATCA_ECC_DELAY_WAKE_TOKEN_RETRY_US 100

/** Command execution times */
#define ATCA_ECC_EXEC_TIME_READ_TYP_US 100
#define ATCA_ECC_EXEC_TIME_READ_MAX_US 1000
#define ATCA_ECC_EXEC_TIME_WRITE_TYP_US 7000
#define ATCA_ECC_EXEC_TIME_WRITE_MAX_US 26000
#define ATCA_ECC_EXEC_TIME_LOCK_TYP_US 8000
#define ATCA_ECC_EXEC_TIME_LOCK_MAX_US 32000
#define ATCA_ECC_EXEC_TIME_GENKEY_TYP_US 11000
#define ATCA_ECC_EXEC_TIME_GENKEY_MAX_US 115000
#define ATCA_ECC_EXEC_TIME_NONCE_TYP_US 100
#define ATCA_ECC_EXEC_TIME_NONCE_MAX_US 7000
#define ATCA_ECC_EXEC_TIME_SIGN_TYP_US 42000
#define ATCA_ECC_EXEC_TIME_SIGN_MAX_US 50000
#define ATCA_ECC_EXEC_TIME_VERIFY_TYP_US 38000
#define ATCA_ECC_EXEC_TIME_VERIFY_MAX_US 58000

/** Driver defined constants */
#define ATCA_ECC_I2C_FREQUENCY 10000

#endif /* ATCAECCCONSTANTS_H */
Loading