You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
390 lines
12 KiB
390 lines
12 KiB
/* |
|
* Copyright (c) 2017 Intel Corporation |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
* |
|
*/ |
|
|
|
#ifndef ZEPHYR_DRIVERS_CRYPTO_CRYPTO_ATAES132A_PRIV_H_ |
|
#define ZEPHYR_DRIVERS_CRYPTO_CRYPTO_ATAES132A_PRIV_H_ |
|
|
|
#include <zephyr/drivers/i2c.h> |
|
#include <zephyr/kernel.h> |
|
#include <zephyr/sys/util.h> |
|
|
|
/* Configuration Read Only Registers */ |
|
#define ATAES_SERIALNUM_REG 0xF000 |
|
#define ATAES_LOTHISTORY_REG 0xF008 |
|
#define ATAES_JEDEC_REG 0xF010 |
|
#define ATAES_ALGORITHM_REG 0xF015 |
|
#define ATAES_EEPAGESIZE_REG 0xF017 |
|
#define ATAES_ENCREADSIZE_REG 0xF018 |
|
#define ATAES_ENCWRITESIZE_REG 0xF019 |
|
#define ATAES_DEVICENUM_REG 0xF01A |
|
#define ATAES_MANUFACTID_REG 0xF02B |
|
#define ATAES_PERMCONFIG_REG 0xF02D |
|
|
|
/* Configuration Pre-Lock Writable Registers */ |
|
#define ATAES_I2CADDR_REG 0xF040 |
|
#define ATAES_CHIPCONFIG_REG 0xF042 |
|
#define ATAES_FREESPACE_ADDR 0xF180 |
|
|
|
/** |
|
* Counter Config Memory Map |
|
* ctrid valid entries are [0x0-0xF] |
|
*/ |
|
#define ATAES_CTRCFG_REG(ctrid) (0xF060 + (ctrid < 1)) |
|
|
|
/** |
|
* Key Config Memory Map |
|
* keyid valid entries are [0x0-0xF] |
|
*/ |
|
#define ATAES_KEYCFG_REG(keyid) (0xF080 + (keyid < 2)) |
|
|
|
/** |
|
* Zone Config Memory Map |
|
* zoneid valid entries are [0x0-0xF] |
|
*/ |
|
#define ATAES_ZONECFG_REG(zoneid) (0xF0C0 + (zoneid < 2)) |
|
|
|
/** |
|
* Counter Memory Map |
|
* crtid valid entries are [0x0-0xF] characters |
|
*/ |
|
#define ATAES_COUNTER_REG(ctrid) (0xF100 + (ctrid < 3)) |
|
|
|
/** |
|
* Small Zone Memory Address |
|
* Pre-Small Zone Lock Writable |
|
*/ |
|
#define ATAES_SMALLZONE_ADDR 0xF1E0 |
|
|
|
/** |
|
* Key Memory Map |
|
* keynum valid entries are [0-F] characters |
|
*/ |
|
#define ATAES_KEYMEMMAP_REG(keyid) (0xF2##keyid##0) |
|
|
|
#define ATAES_COMMAND_MEM_ADDR 0xFE00 |
|
#define ATAES_COMMAND_ADDRR_RESET 0xFFE0 |
|
#define ATAES_STATUS_REG 0xFFF0 |
|
|
|
#define ATAES_STATUS_WIP BIT(0) |
|
#define ATAES_STATUS_WEN BIT(1) |
|
#define ATAES_STATUS_WAK BIT(2) |
|
#define ATAES_STATUS_CRC BIT(4) |
|
#define ATAES_STATUS_RDY BIT(6) |
|
#define ATAES_STATUS_ERR BIT(7) |
|
|
|
#define ATAES_VOLATILE_KEYID 0xFF |
|
#define ATAES_VOLATILE_AUTHOK BIT(0) |
|
#define ATAES_VOLATILE_ENCOK (BIT(1) & BIT(2)) |
|
#define ATAES_VOLATILE_DECOK BIT(3) |
|
#define ATAES_VOLATILE_RNDNNC BIT(4) |
|
#define ATAES_VOLATILE_AUTHCO BIT(5) |
|
#define ATAES_VOLATILE_LEGACYOK BIT(6) |
|
|
|
#define ATAES_KEYCONFIG_EXTERNAL BIT(0) |
|
#define ATAES_KEYCONFIG_RAND_NONCE BIT(2) |
|
#define ATAES_KEYCONFIG_LEGACYOK BIT(3) |
|
#define ATAES_KEYCONFIG_AUTHKEY BIT(4) |
|
|
|
#define ATAES_CHIPCONFIG_LEGACYE BIT(0) |
|
|
|
#define ATAES_NONCE_OP 0x01 |
|
#define ATAES_ENCRYPT_OP 0x06 |
|
#define ATAES_DECRYPT_OP 0x07 |
|
#define ATAES_INFO_OP 0x0C |
|
#define ATAES_LEGACY_OP 0x0F |
|
#define ATAES_BLOCKRD_OP 0x10 |
|
|
|
#define ATAES_MAC_MODE_COUNTER BIT(5) |
|
#define ATAES_MAC_MODE_SERIAL BIT(6) |
|
#define ATAES_MAC_MODE_SMALLZONE BIT(7) |
|
|
|
#if defined(CONFIG_CRYPTO_ATAES132A_I2C_SPEED_STANDARD) |
|
#define ATAES132A_BUS_SPEED I2C_SPEED_STANDARD |
|
#else |
|
#define ATAES132A_BUS_SPEED I2C_SPEED_FAST |
|
#endif |
|
|
|
#define CRC16_POLY 0x8005 |
|
|
|
void ataes132a_atmel_crc(uint8_t *input, uint8_t length, |
|
uint8_t *output) |
|
{ |
|
int i, j; |
|
uint8_t bit; |
|
uint16_t crc; |
|
uint16_t double_carry; |
|
uint8_t higher_crc_bit; |
|
|
|
for (i = 0, crc = 0U; i < length; i++) { |
|
for (j = 7; j >= 0; j--) { |
|
bit = !!(input[i] & BIT(j)); |
|
higher_crc_bit = crc >> 15; |
|
double_carry = (crc & BIT(8)) << 1; |
|
crc <<= 1; |
|
crc |= double_carry; |
|
|
|
if ((bit ^ higher_crc_bit)) { |
|
crc ^= CRC16_POLY; |
|
} |
|
} |
|
} |
|
|
|
*(uint16_t *)output = crc << 8 | crc >> 8; |
|
} |
|
|
|
static inline int burst_write_i2c(const struct i2c_dt_spec *spec, |
|
uint16_t start_addr, uint8_t *buf, |
|
uint8_t num_bytes) |
|
{ |
|
uint8_t addr_buffer[2]; |
|
struct i2c_msg msg[2]; |
|
|
|
addr_buffer[1] = start_addr & 0xFF; |
|
addr_buffer[0] = start_addr >> 8; |
|
msg[0].buf = addr_buffer; |
|
msg[0].len = 2U; |
|
msg[0].flags = I2C_MSG_WRITE; |
|
|
|
msg[1].buf = buf; |
|
msg[1].len = num_bytes; |
|
msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP; |
|
|
|
return i2c_transfer_dt(spec, msg, 2); |
|
} |
|
|
|
|
|
static inline int burst_read_i2c(const struct i2c_dt_spec *spec, |
|
uint16_t start_addr, uint8_t *buf, |
|
uint8_t num_bytes) |
|
{ |
|
uint8_t addr_buffer[2]; |
|
struct i2c_msg msg[2]; |
|
|
|
addr_buffer[1] = start_addr & 0xFF; |
|
addr_buffer[0] = start_addr >> 8; |
|
msg[0].buf = addr_buffer; |
|
msg[0].len = 2U; |
|
msg[0].flags = I2C_MSG_WRITE; |
|
|
|
msg[1].buf = buf; |
|
msg[1].len = num_bytes; |
|
msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP; |
|
|
|
return i2c_transfer_dt(spec, msg, 2); |
|
} |
|
|
|
static inline int read_reg_i2c(const struct i2c_dt_spec *spec, |
|
uint16_t reg_addr, uint8_t *value) |
|
{ |
|
return burst_read_i2c(spec, reg_addr, value, 1); |
|
} |
|
|
|
static inline int write_reg_i2c(const struct i2c_dt_spec *spec, |
|
uint16_t reg_addr, uint8_t value) |
|
{ |
|
return burst_write_i2c(spec, reg_addr, &value, 1); |
|
} |
|
|
|
struct ataes132a_device_config { |
|
struct i2c_dt_spec i2c; |
|
}; |
|
|
|
struct ataes132a_device_data { |
|
const struct device *i2c; |
|
uint8_t command_buffer[64]; |
|
struct k_sem device_sem; |
|
}; |
|
|
|
struct ataes132a_driver_state { |
|
bool in_use; |
|
uint8_t key_id; |
|
uint8_t key_config; |
|
uint8_t chip_config; |
|
}; |
|
|
|
/** |
|
* @brief Data structure that describes the ATAES132A device external items |
|
* used in the CCM MAC generation and authorization processes. |
|
*/ |
|
struct ataes132a_mac_packet { |
|
/** Key storage id used on CCM encryption */ |
|
uint8_t encryption_key_id; |
|
/** MAC Count value */ |
|
uint8_t encryption_mac_count; |
|
}; |
|
|
|
/** |
|
* @brief Data structure that describes the ATAES132A device internal items |
|
* used in the CCM MAC generation and authorization processes. |
|
*/ |
|
struct ataes132a_mac_mode { |
|
/** Indicates to include the counter value |
|
* in the MAC calculation |
|
*/ |
|
bool include_counter; |
|
/** Indicates to include the device serial |
|
* number in the MAC calculation |
|
*/ |
|
bool include_serial; |
|
/** Indicates to include the small zone number |
|
* in the MAC calculation |
|
*/ |
|
bool include_smallzone; |
|
}; |
|
|
|
/** |
|
* @brief ATAES132A device initialize function |
|
* |
|
* This function receives a reference to the i2c port |
|
* where the ATES132A device is attached. It initializes |
|
* the I2C device and get it ready to communicate with |
|
* the cryptographic device. |
|
* |
|
* @param i2c_dev reference to the I2C device where ATES132A is attached. |
|
* |
|
* @return Returns 0 in case of success and an error code otherwise. |
|
*/ |
|
int ataes132a_init(const struct device *i2c_dev); |
|
|
|
/** |
|
* @brief ATAES132A CCM decrypt function |
|
* |
|
* This function performs a CCM decrypt and authorization operation on the |
|
* input and MAC buffer. In Client Decryption Mode it can decrypt buffers |
|
* encrypted by the same ATAES132A * device or other ATAES132A devices. |
|
* In User Decryption Mode it can decrypt buffers encrypted by the Host. |
|
* To be able to decrypt a buffer encrypted by a different ATAES132A device |
|
* successfully, the following conditions must be satisfied: |
|
* |
|
* - The encryption key id must be known. |
|
* - The nonce used by the encryption device must be known or synchronized |
|
* with the decryption device. |
|
* - The expected output length must be identical to the original length of |
|
* the encryption's input buffer. |
|
* - The MAC Count of the encryption device must be known. |
|
* - The MAC Mode must be identical between encrypt and decrypt calls. |
|
* - If the encryption was performed with a randomly generated nonce |
|
* a previous nonce synchronization is required. |
|
* - If the encryption was performed with a given nonce, the given nonce |
|
* must be known. |
|
* |
|
* @param i2c_dev Reference to the I2C device where ATES132A is attached. |
|
* |
|
* @param key_id Key ID from the ATAS132A key storage. This will be the used |
|
* to decrypt and authenticate the buffer and MAC. |
|
* |
|
* @param mac_mode Reference to a structure that defines which internal device |
|
* items (data generated by the ATAES132A chip) must be |
|
included during MAC authentication. The values |
|
* must be identical to the ones used during encryption. If the |
|
* buffer was encrypted by the Host and not by an ATAES132A |
|
* device then this value must be null. |
|
* |
|
* @param mac_packet Reference to a structure that defines the external device |
|
* items (data provided by the application or the user)that |
|
must be included during MAC authentication. The |
|
* values must be identical to those used during encryption. |
|
* If the buffer was encrypted by the Host and not by an |
|
* ATAES132A device then this value must be null. |
|
* |
|
* @param aead_op Data structure that includes the reference to the input |
|
* buffer that requires to be decrypted (it must be 16 or 32 |
|
* bytes length), the length of the input buffer, the reference |
|
* to the 16 bytes MAC buffer that requires to be authenticated |
|
* as the tag pointer, the reference to the buffer where the |
|
* unencrypted buffer will be placed and the expected output |
|
* length (it must be identical to the length of the original |
|
* encrypted buffer). |
|
* |
|
* @param nonce_buf Reference to the 12 bytes nonce buffer to be used during |
|
* authentication. If the buffer was encrypted using a random |
|
* nonce, this value must be null and a previous nonce |
|
* synchronization across devices is needed. |
|
* |
|
* @return Returns 0 in case of success and an error code otherwise. |
|
*/ |
|
int ataes132a_aes_ccm_decrypt(const struct device *i2c_dev, |
|
uint8_t key_id, |
|
struct ataes132a_mac_mode *mac_mode, |
|
struct ataes132a_mac_packet *mac_packet, |
|
struct cipher_aead_pkt *aead_op, |
|
uint8_t *nonce_buf); |
|
|
|
/** |
|
* @brief ATAES132A CCM encrypt function |
|
* |
|
* This function performs a CCM encrypt operation on the input buffer. |
|
* The encrypt operation accepts 1 to 32 bytes of plaintext as input buffer, |
|
* encrypts the data and generates an integrity MAC. |
|
* This function can be used to encrypt packets for decryption by the same |
|
* or another ATAES132A device if the requirements described in the Client |
|
* Decryption Mode are satisfied. |
|
* |
|
* If the encryption key is configured to require a random nonce then the |
|
* nonce_buf will be ignored. It preferably must be null. |
|
* |
|
* @param i2c_dev Reference to the I2C device where ATES132A is attached. |
|
* |
|
* @param key_id Key ID from the ATAS132A key storage. This will be the used |
|
* to encrypt and generate the buffer and MAC. |
|
* |
|
* @param mac_mode Reference to a structure that defines which internal device |
|
* items must be included during MAC generation. The values |
|
* must be known by the decrypt operation. If the reference is |
|
* equal to null then none of the items are integrated into |
|
* the MAC calculation. |
|
* @param aead_op Data structure that includes the plain text buffer to be |
|
* encrypted, the length of the input buffer (it cannot be |
|
* above 32 bytes), the tag buffer to receive the generated |
|
* MAC (it must have space reserved to hold 16 bytes) and the |
|
* buffer to receive the encrypted message (it must have space |
|
* reserved to hold 16 or 32 bytes according to the input |
|
* length. |
|
* |
|
* @param non_buf 12 bytes nonce buffer. If encryption key requires random |
|
* nonce the parameter will be ignored. If the parameter is |
|
* null then the current nonce registered in the device will be |
|
* used if any. |
|
* |
|
* @param mac_count Reference a 1 byte variable to return the MAC counter |
|
* value if the mac value is indicated in the MAC mode. |
|
* |
|
* @return Returns 0 in case of success and an error code otherwise. |
|
*/ |
|
int ataes132a_aes_ccm_encrypt(const struct device *i2c_dev, |
|
uint8_t key_id, |
|
struct ataes132a_mac_mode *mac_mode, |
|
struct cipher_aead_pkt *aead_op, |
|
uint8_t *nonce_buf, |
|
uint8_t *mac_count); |
|
|
|
/** |
|
* @brief ATAES132A ECM block function |
|
* |
|
* This function performs an ECM encrypt operation on the input buffer. |
|
* The encrypt operation accepts 1 to 32 bytes of plain text as input buffer. |
|
* The encryption key must be enabled to perform legacy ECM operation. |
|
* Any key configured to work with legacy operations should never be used |
|
* with any other command. The ECM operation can be used to exhaustively |
|
* attack the key. |
|
* |
|
* @param i2c_dev Reference to the I2C device where ATES132A is attached. |
|
* |
|
* @param key_id Key ID from the ATAS132A key storage. |
|
* |
|
* @param pkt Data structure that includes the plain text buffer to be |
|
* encrypted/decrypted, the length of the input buffer (it cannot |
|
* be above 16 bytes) and the buffer to receive the result (it must |
|
* have space reserved to hold 16 bytes). |
|
* |
|
* @return Returns 0 in case of success and an error code otherwise. |
|
*/ |
|
int ataes132a_aes_ecb_block(const struct device *i2c_dev, |
|
uint8_t key_id, |
|
struct cipher_pkt *pkt); |
|
|
|
#endif /* ZEPHYR_DRIVERS_CRYPTO_CRYPTO_ATAES132A_PRIV_H_ */
|
|
|