| /* |
| * 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(u8_t *input, u8_t length, |
| u8_t *output) |
| { |
| int i, j; |
| u8_t bit; |
| u16_t crc; |
| u16_t double_carry; |
| u8_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; |
| } |
| } |
| } |
| |
| *(u16_t *)output = crc << 8 | crc >> 8; |
| } |
| |
| static inline int burst_write_i2c(struct device *dev, u16_t dev_addr, |
| u16_t start_addr, u8_t *buf, |
| u8_t num_bytes) |
| { |
| const struct i2c_driver_api *api = dev->driver_api; |
| u8_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, u16_t dev_addr, |
| u16_t start_addr, u8_t *buf, |
| u8_t num_bytes) |
| { |
| const struct i2c_driver_api *api = dev->driver_api; |
| u8_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, u16_t dev_addr, |
| u16_t reg_addr, u8_t *value) |
| { |
| return burst_read_i2c(dev, dev_addr, reg_addr, value, 1); |
| } |
| |
| static inline int write_reg_i2c(struct device *dev, u16_t dev_addr, |
| u16_t reg_addr, u8_t value) |
| { |
| return burst_write_i2c(dev, dev_addr, reg_addr, &value, 1); |
| } |
| |
| struct ataes132a_device_config { |
| const char *i2c_port; |
| u16_t i2c_addr; |
| u8_t i2c_speed; |
| }; |
| |
| struct ataes132a_device_data { |
| struct device *i2c; |
| u8_t command_buffer[64]; |
| struct k_sem device_sem; |
| }; |
| |
| struct ataes132a_driver_state { |
| bool in_use; |
| u8_t key_id; |
| u8_t key_config; |
| u8_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 */ |
| u8_t encryption_key_id; |
| /** MAC Count value */ |
| u8_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, |
| u8_t key_id, |
| struct ataes132a_mac_mode *mac_mode, |
| struct ataes132a_mac_packet *mac_packet, |
| struct cipher_aead_pkt *aead_op, |
| u8_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, |
| u8_t key_id, |
| struct ataes132a_mac_mode *mac_mode, |
| struct cipher_aead_pkt *aead_op, |
| u8_t *nonce_buf, |
| u8_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, |
| u8_t key_id, |
| struct cipher_pkt *pkt); |
| |
| #endif /* _ATAES132A_PRIV_ */ |