REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
dcp.cpp File Reference

Hardware-accelerated CRC32, SHA1 and SHA256 (cryptographic) hashing for Teensy 4. More...

#include <Arduino.h>
#include "utils/dcp.h"
Include dependency graph for dcp.cpp:

Go to the source code of this file.

Classes

struct  utils::_dcp_hash_ctx_t
 
union  utils::_dcp_hash_block
 
struct  utils::_dcp_handle
 
struct  utils::_dcp_hash_ctx_internal
 
struct  utils::_dcp_work_packet
 
struct  utils::DCP_Type
 DCP - Register Layout Typedef. More...
 

Namespaces

namespace  utils
 

Macros

#define __IO   volatile
 
#define __I   volatile
 
#define DCP_CH0SEMA_VALUE_MASK   (0xFF0000U)
 
#define DCP_CH0STAT_ERROR_CODE_MASK   (0xFF0000U)
 
#define DCP_HASH_BLOCK_SIZE   128
 
#define DCP_STAT_OTP_KEY_READY_MASK   (0x10000000U)
 
#define DCP_KEY_INDEX_MASK   (0x30U)
 
#define DCP_KEY_INDEX_SHIFT   (4U)
 
#define DCP_KEY_INDEX(x)
 
#define DCP   ((DCP_Type *)0x402FC000)
 

Typedefs

typedef enum utils::_dcp_ch_enable utils::_dcp_ch_enable_t
 
typedef enum utils::_dcp_channel utils::dcp_channel_t
 
typedef enum utils::_dcp_key_slot utils::dcp_key_slot_t
 
typedef enum utils::_dcp_swap utils::dcp_swap_t
 
typedef enum utils::_dcp_hash_algo_t utils::dcp_hash_algo_t
 
typedef struct utils::_dcp_hash_ctx_t utils::dcp_hash_ctx_t
 
typedef union utils::_dcp_hash_block utils::dcp_hash_block_t
 
typedef enum utils::_dcp_hash_algo_state utils::dcp_hash_algo_state_t
 
typedef struct utils::_dcp_handle utils::dcp_handle_t
 
typedef struct utils::_dcp_hash_ctx_internal utils::dcp_hash_ctx_internal_t
 
typedef struct utils::_dcp_work_packet utils::dcp_work_packet_t
 

Enumerations

enum  utils::_generic_status {
  utils::kStatus_Success = 0 , utils::kStatus_Fail = 1 , utils::kStatus_ReadOnly = 2 , utils::kStatus_OutOfRange = 3 ,
  utils::kStatus_InvalidArgument = 4 , utils::kStatus_Timeout = 5 , utils::kStatus_DCP_Again = 6
}
 
enum  utils::_dcp_ch_enable {
  utils::kDCP_chDisable = 0U , utils::kDCP_ch0Enable = 1U , utils::kDCP_ch1Enable = 2U , utils::kDCP_ch2Enable = 4U ,
  utils::kDCP_ch3Enable = 8U , utils::kDCP_chEnableAll = 15U
}
 
enum  utils::_dcp_channel { utils::kDCP_Channel0 = (1u << 16) , utils::kDCP_Channel1 = (1u << 17) , utils::kDCP_Channel2 = (1u << 18) , utils::kDCP_Channel3 = (1u << 19) }
 
enum  utils::_dcp_key_slot {
  utils::kDCP_KeySlot0 = 0U , utils::kDCP_KeySlot1 = 1U , utils::kDCP_KeySlot2 = 2U , utils::kDCP_KeySlot3 = 3U ,
  utils::kDCP_OtpKey = 4U , utils::kDCP_OtpUniqueKey = 5U , utils::kDCP_PayloadKey = 6U
}
 
enum  utils::_dcp_swap {
  utils::kDCP_NoSwap = 0x0U , utils::kDCP_KeyByteSwap = 0x40000U , utils::kDCP_KeyWordSwap = 0x80000U , utils::kDCP_InputByteSwap = 0x100000U ,
  utils::kDCP_InputWordSwap = 0x200000U , utils::kDCP_OutputByteSwap = 0x400000U , utils::kDCP_OutputWordSwap = 0x800000U
}
 
enum  utils::_dcp_hash_algo_t { utils::kDCP_Sha1 , utils::kDCP_Sha256 , utils::kDCP_Crc32 }
 
enum  utils::_dcp_hash_digest_len { utils::kDCP_OutLenSha1 = 20u , utils::kDCP_OutLenSha256 = 32u , utils::kDCP_OutLenCrc32 = 4u }
 
enum  utils::_dcp_work_packet_bit_definitions {
  utils::kDCP_CONTROL0_DECR_SEMAPHOR = 1u << 1 , utils::kDCP_CONTROL0_ENABLE_HASH = 1u << 6 , utils::kDCP_CONTROL0_HASH_INIT = 1u << 12 , utils::kDCP_CONTROL0_HASH_TERM = 1u << 13 ,
  utils::kDCP_CONTROL1_HASH_SELECT_SHA256 = 2u << 16 , utils::kDCP_CONTROL1_HASH_SELECT_SHA1 = 0u << 16 , utils::kDCP_CONTROL1_HASH_SELECT_CRC32 = 1u << 16
}
 
enum  utils::_dcp_hash_algo_state { utils::kDCP_StateHashInit = 1u , utils::kDCP_StateHashUpdate }
 

Functions

static FLASHMEM void utils::dcp_reverse_and_copy (uint8_t *src, uint8_t *dest, size_t src_len)
 
static FLASHMEM uint32_t utils::dcp_get_channel_status (dcp_channel_t channel)
 
static FLASHMEM void utils::dcp_clear_status ()
 
static FLASHMEM void utils::dcp_clear_channel_status (uint32_t mask)
 
uint32_t utils::DCP_WaitForChannelComplete (dcp_handle_t *handle)
 
static FLASHMEM uint32_t utils::dcp_schedule_work (dcp_handle_t *handle, dcp_work_packet_t *dcpPacket)
 
static FLASHMEM uint32_t utils::dcp_hash_update_non_blocking (dcp_hash_ctx_internal_t *ctxInternal, dcp_work_packet_t *dcpPacket, const uint8_t *msg, size_t size)
 
void utils::dcp_hash_update (dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *msg, size_t size)
 
FLASHMEM void utils::dcp_hash_process_message_data (dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *message, size_t messageSize)
 
FLASHMEM void utils::DCP_HASH_Init (dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo)
 
FLASHMEM void utils::DCP_HASH_Update (dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
 
FLASHMEM void utils::DCP_HASH_Finish (dcp_hash_ctx_t *ctx, uint8_t *output)
 
FLASHMEM void utils::dcp_init ()
 
FLASHMEM void utils::prhash (unsigned char *h, int n)
 
FLASHMEM void utils::demo_sha256 ()
 
FLASHMEM void utils::demo_crc32 ()
 
FLASHMEM void utils::hash (const uint8_t *msg, size_t msg_len, uint8_t *out_hash, dcp_hash_algo_t algo)
 
FLASHMEM void utils::hash_sha256 (const uint8_t *msg, size_t msg_len, uint8_t *out_hash)
 Computes the SHA256 sum of an arbitrary message (large memory segment).
 
FLASHMEM void utils::hash_sha1 (const uint8_t *msg, size_t msg_len, uint8_t *out_hash)
 

Detailed Description

Hardware-accelerated CRC32, SHA1 and SHA256 (cryptographic) hashing for Teensy 4.

DCP stands for Data Co-Processor and provides hardware acceleration for cryptographic algorithms. Used for creating checksums of data. Performance is like 70MByte/sec with input data coming from flash, so it is pretty neat.

Finding the correct library to do the job costed me some trial-and-error:

  1. First I tried out the CryptoAccel.h which is part of framework-arduinoteensy and available at https://github.com/PaulStoffregen/CryptoAccel. There is hardly any documentation. It can create CRC-32 variants in POSIX and ADCCP/PKZIP/Ethernet/802.3, however I could not reproduce a single of these checksums. CRC-32 is to ill-defined. Also considered https://www.etlcpp.com/hash.html but doesn't change CRC-32s nature.
  2. Then I tried FastCRC which is also part of framework-arduinoteensy. It is written in assembly and silently creates wrong MD5sums for Teensy4 and also the md5sums. cf. https://forum.pjrc.com/index.php?threads/cryptoaccel-library-use-with-t4-1-for-encryption-decryption.71091/post-312784
  3. Then I tried https://github.com/okdshin/PicoSHA2 which however just crashes on the Teensy. I guess this is because of the intensive heap usage of the std::vector buffers.
  4. Then I tried this dcp header which I found at https://github.com/manitou48/teensy4/blob/master/dcptst.ino According to https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=197722&viewfull=1#post197722 The code basically stems straight from the NXP SDK. This is the first code which produced a correct checksum/hash for me.
Note
The NXP SDK is BSD-3 licensed, see https://github.com/nxp-mcuxpresso/mcux-sdk This code ultimately originates from https://github.com/nxp-mcuxpresso/mcux-sdk/blob/main/drivers/dcp/fsl_dcp.c

Usage: Look out for utils::hash_sha256() at the end of this file.

Definition in file dcp.cpp.

Macro Definition Documentation

◆ __I

#define __I   volatile

Definition at line 49 of file dcp.cpp.

◆ __IO

#define __IO   volatile

Definition at line 48 of file dcp.cpp.

◆ DCP

◆ DCP_CH0SEMA_VALUE_MASK

#define DCP_CH0SEMA_VALUE_MASK   (0xFF0000U)

Definition at line 50 of file dcp.cpp.

Referenced by utils::dcp_get_channel_status().

◆ DCP_CH0STAT_ERROR_CODE_MASK

#define DCP_CH0STAT_ERROR_CODE_MASK   (0xFF0000U)

Definition at line 51 of file dcp.cpp.

Referenced by utils::dcp_get_channel_status().

◆ DCP_HASH_BLOCK_SIZE

#define DCP_HASH_BLOCK_SIZE   128

Definition at line 52 of file dcp.cpp.

Referenced by utils::dcp_hash_process_message_data(), and utils::DCP_HASH_Update().

◆ DCP_KEY_INDEX

#define DCP_KEY_INDEX ( x)
Value:
uint32_t
Definition flasher.cpp:195
#define DCP_KEY_INDEX_SHIFT
Definition dcp.cpp:55
#define DCP_KEY_INDEX_MASK
Definition dcp.cpp:54

Definition at line 56 of file dcp.cpp.

◆ DCP_KEY_INDEX_MASK

#define DCP_KEY_INDEX_MASK   (0x30U)

Definition at line 54 of file dcp.cpp.

◆ DCP_KEY_INDEX_SHIFT

#define DCP_KEY_INDEX_SHIFT   (4U)

Definition at line 55 of file dcp.cpp.

◆ DCP_STAT_OTP_KEY_READY_MASK

#define DCP_STAT_OTP_KEY_READY_MASK   (0x10000000U)

Definition at line 53 of file dcp.cpp.