395 lines
12 KiB
C
395 lines
12 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
*/
|
|
|
|
#ifndef _ATAES132A_PRIV_
|
|
#define _ATAES132A_PRIV_
|
|
|
|
#include <i2c.h>
|
|
#include <kernel.h>
|
|
#include <misc/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
|
|
|
|
/* Configuarion 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_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 = 0; 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(struct device *dev, uint16_t dev_addr,
|
|
uint16_t start_addr, uint8_t *buf,
|
|
uint8_t num_bytes)
|
|
{
|
|
const struct i2c_driver_api *api = dev->driver_api;
|
|
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 = 2;
|
|
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 api->transfer(dev, msg, 2, dev_addr);
|
|
}
|
|
|
|
|
|
static inline int burst_read_i2c(struct device *dev, uint16_t dev_addr,
|
|
uint16_t start_addr, uint8_t *buf,
|
|
uint8_t num_bytes)
|
|
{
|
|
const struct i2c_driver_api *api = dev->driver_api;
|
|
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 = 2;
|
|
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 api->transfer(dev, msg, 2, dev_addr);
|
|
}
|
|
|
|
static inline int read_reg_i2c(struct device *dev, uint16_t dev_addr,
|
|
uint16_t reg_addr, uint8_t *value)
|
|
{
|
|
return burst_read_i2c(dev, dev_addr, reg_addr, value, 1);
|
|
}
|
|
|
|
static inline int write_reg_i2c(struct device *dev, uint16_t dev_addr,
|
|
uint16_t reg_addr, uint8_t value)
|
|
{
|
|
return burst_write_i2c(dev, dev_addr, reg_addr, &value, 1);
|
|
}
|
|
|
|
struct ataes132a_device_config {
|
|
const char *i2c_port;
|
|
uint16_t i2c_addr;
|
|
uint8_t i2c_speed;
|
|
};
|
|
|
|
struct ataes132a_device_data {
|
|
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(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(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(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(struct device *i2c_dev,
|
|
uint8_t key_id,
|
|
struct cipher_pkt *pkt);
|
|
|
|
#endif /* _ATAES132A_PRIV_ */
|