//======================================================================
//
// cryptech.h
// ----------
// Memory map and access functions for Cryptech cores.
//
//
// Authors: Joachim Strombergson, Paul Selkirk
// Copyright (c) 2015, NORDUnet A/S All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of the NORDUnet nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
// Segments.
#define CORE_SIZE 0x100
#define SEGMENT_SIZE 0x20 * CORE_SIZE
#define SEGMENT_OFFSET_GLOBALS 0 * SEGMENT_SIZE
#define SEGMENT_OFFSET_HASHES 1 * SEGMENT_SIZE
#define SEGMENT_OFFSET_RNGS 2 * SEGMENT_SIZE
#define SEGMENT_OFFSET_CIPHERS 3 * SEGMENT_SIZE
#define SEGMENT_OFFSET_MATH 4 * SEGMENT_SIZE
//------------------------------------------------------------------
// Addresses and codes common to all cores
//------------------------------------------------------------------
#define ADDR_NAME0 0x00
#define ADDR_NAME1 0x01
#define ADDR_VERSION 0x02
#define ADDR_CTRL 0x08
#define CTRL_INIT_BIT 1
#define CTRL_NEXT_BIT 2
#define ADDR_STATUS 0x09
#define STATUS_READY_BIT 1
#define STATUS_VALID_BIT 2
// a handy macro from cryptlib
#ifndef bitsToBytes
#define bitsToBytes(x) (x / 8)
#endif
//------------------------------------------------------------------
// Board segment.
// Board-level registers and communication channel registers
//------------------------------------------------------------------
#define BOARD_ADDR_BASE SEGMENT_OFFSET_GLOBALS + (0 * CORE_SIZE)
#define BOARD_ADDR_NAME0 BOARD_ADDR_BASE + ADDR_NAME0
#define BOARD_ADDR_NAME1 BOARD_ADDR_BASE + ADDR_NAME1
#define BOARD_ADDR_VERSION BOARD_ADDR_BASE + ADDR_VERSION
#define BOARD_ADDR_DUMMY BOARD_ADDR_BASE + 0xFF
#define COMM_ADDR_BASE SEGMENT_OFFSET_GLOBALS + (1 * CORE_SIZE)
#define COMM_ADDR_NAME0 COMM_ADDR_BASE + ADDR_NAME0
#define COMM_ADDR_NAME1 COMM_ADDR_BASE + ADDR_NAME1
#define COMM_ADDR_VERSION COMM_ADDR_BASE + ADDR_VERSION
#define NOVENA_BOARD_NAME0 "PVT1"
#define NOVENA_BOARD_NAME1 " "
#define NOVENA_BOARD_VERSION "0.10"
#define EIM_INTERFACE_NAME0 "eim "
#define EIM_INTERFACE_NAME1 " "
#define EIM_INTERFACE_VERSION "0.10"
#define I2C_INTERFACE_NAME0 "i2c "
#define I2C_INTERFACE_NAME1 " "
#define I2C_INTERFACE_VERSION "0.10"
//------------------------------------------------------------------
// Hashes segment.
//------------------------------------------------------------------
// addresses and codes common to all hash cores
#define CTRL_INIT_CMD 1
#define CTRL_NEXT_CMD 2
#define ADDR_BLOCK 0x10
#define ADDR_DIGEST 0x20 // except SHA512
// addresses and codes for the specific hash cores.
#define SHA1_ADDR_BASE SEGMENT_OFFSET_HASHES + (0 * CORE_SIZE)
#define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0
#define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1
#define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION
#define SHA1_ADDR_CTRL SHA1_ADDR_BASE + ADDR_CTRL
#define SHA1_ADDR_STATUS SHA1_ADDR_BASE + ADDR_STATUS
#define SHA1_ADDR_BLOCK SHA1_ADDR_BASE + ADDR_BLOCK
#define SHA1_ADDR_DIGEST SHA1_ADDR_BASE + ADDR_DIGEST
#define SHA1_BLOCK_LEN bitsToBytes(512)
#define SHA1_LENGTH_LEN bitsToBytes(64)
#define SHA1_DIGEST_LEN bitsToBytes(160)
#define SHA256_ADDR_BASE SEGMENT_OFFSET_HASHES + (1 * CORE_SIZE)
#define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0
#define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1
#define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION
#define SHA256_ADDR_CTRL SHA256_ADDR_BASE + ADDR_CTRL
#define SHA256_ADDR_STATUS SHA256_ADDR_BASE + ADDR_STATUS
#define SHA256_ADDR_BLOCK SHA256_ADDR_BASE + ADDR_BLOCK
#define SHA256_ADDR_DIGEST SHA256_ADDR_BASE + ADDR_DIGEST
#define SHA256_BLOCK_LEN bitsToBytes(512)
#define SHA256_LENGTH_LEN bitsToBytes(64)
#define SHA256_DIGEST_LEN bitsToBytes(256)
#define SHA512_ADDR_BASE SEGMENT_OFFSET_HASHES + (2 * CORE_SIZE)
#define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0
#define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1
#define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION
#define SHA512_ADDR_CTRL SHA512_ADDR_BASE + ADDR_CTRL
#define SHA512_ADDR_STATUS SHA512_ADDR_BASE + ADDR_STATUS
#define SHA512_ADDR_BLOCK SHA512_ADDR_BASE + ADDR_BLOCK
#define SHA512_ADDR_DIGEST SHA512_ADDR_BASE + 0x40
#define SHA512_BLOCK_LEN bitsToBytes(1024)
#define SHA512_LENGTH_LEN bitsToBytes(128)
#define SHA512_224_DIGEST_LEN bitsToBytes(224)
#define SHA512_256_DIGEST_LEN bitsToBytes(256)
#define SHA384_DIGEST_LEN bitsToBytes(384)
#define SHA512_DIGEST_LEN bitsToBytes(512)
#define MODE_SHA_512_224 0 << 2
#define MODE_SHA_512_256 1 << 2
#define MODE_SHA_384 2 << 2
#define MODE_SHA_512 3 << 2
#define SHA1_NAME0 "sha1"
#define SHA1_NAME1 " "
#define SHA1_VERSION "0.50"
#define SHA256_NAME0 "sha2"
#define SHA256_NAME1 "-256"
#define SHA256_VERSION "0.80"
#define SHA512_NAME0 "sha2"
#define SHA512_NAME1 "-512"
#define SHA512_VERSION "0.80"
//-----------------------------------------------------------------
// TRNG segment.
//-----------------------------------------------------------------
// addresses and codes for the TRNG cores */
#define TRNG_ADDR_BASE SEGMENT_OFFSET_RNGS + (0x00 * CORE_SIZE)
#define TRNG_ADDR_NAME0 TRNG_ADDR_BASE + ADDR_NAME0
#define TRNG_ADDR_NAME1 TRNG_ADDR_BASE + ADDR_NAME1
#define TRNG_ADDR_VERSION TRNG_ADDR_BASE + ADDR_VERSION
#define TRNG_ADDR_CTRL TRNG_ADDR_BASE + 0x10
#define TRNG_CTRL_DISCARD 1
#define TRNG_CTRL_TEST_MODE 2
#define TRNG_ADDR_STATUS TRNG_ADDR_BASE + 0x11
// no status bits defined (yet)
#define TRNG_ADDR_DELAY TRNG_ADDR_BASE + 0x13
#define ENTROPY1_ADDR_BASE SEGMENT_OFFSET_RNGS + (0x05 * CORE_SIZE)
#define ENTROPY1_ADDR_NAME0 ENTROPY1_ADDR_BASE + ADDR_NAME0
#define ENTROPY1_ADDR_NAME1 ENTROPY1_ADDR_BASE + ADDR_NAME1
#define ENTROPY1_ADDR_VERSION ENTROPY1_ADDR_BASE + ADDR_VERSION
#define ENTROPY1_ADDR_CTRL ENTROPY1_ADDR_BASE + 0x10
#define ENTROPY1_CTRL_ENABLE 1
#define ENTROPY1_ADDR_STATUS ENTROPY1_ADDR_BASE + 0x11
#define ENTROPY1_STATUS_VALID 1
#define ENTROPY1_ADDR_ENTROPY ENTROPY1_ADDR_BASE + 0x20
#define ENTROPY1_ADDR_DELTA ENTROPY1_ADDR_BASE + 0x30
#define ENTROPY2_ADDR_BASE SEGMENT_OFFSET_RNGS + (0x06 * CORE_SIZE)
#define ENTROPY2_ADDR_NAME0 ENTROPY2_ADDR_BASE + ADDR_NAME0
#define ENTROPY2_ADDR_NAME1 ENTROPY2_ADDR_BASE + ADDR_NAME1
#define ENTROPY2_ADDR_VERSION ENTROPY2_ADDR_BASE + ADDR_VERSION
#define ENTROPY2_ADDR_CTRL ENTROPY2_ADDR_BASE + 0x10
#define ENTROPY2_CTRL_ENABLE 1
#define ENTROPY2_ADDR_STATUS ENTROPY2_ADDR_BASE + 0x11
#define ENTROPY2_STATUS_VALID 1
#define ENTROPY2_ADDR_OPA ENTROPY2_ADDR_BASE + 0x18
#define ENTROPY2_ADDR_OPB ENTROPY2_ADDR_BASE + 0x19
#define ENTROPY2_ADDR_ENTROPY ENTROPY2_ADDR_BASE + 0x20
#define ENTROPY2_ADDR_RAW ENTROPY2_ADDR_BASE + 0x21
#define ENTROPY2_ADDR_ROSC ENTROPY2_ADDR_BASE + 0x22
#define MIXER_ADDR_BASE SEGMENT_OFFSET_RNGS + (0x0a * CORE_SIZE)
#define MIXER_ADDR_NAME0 MIXER_ADDR_BASE + ADDR_NAME0
#define MIXER_ADDR_NAME1 MIXER_ADDR_BASE + ADDR_NAME1
#define MIXER_ADDR_VERSION MIXER_ADDR_BASE + ADDR_VERSION
#define MIXER_ADDR_CTRL MIXER_ADDR_BASE + 0x10
#define MIXER_CTRL_ENABLE 1
#define MIXER_CTRL_RESTART 2
#define MIXER_ADDR_STATUS MIXER_ADDR_BASE + 0x11
// no status bits defined (yet)
#define MIXER_ADDR_TIMEOUT MIXER_ADDR_BASE + 0x20
#define CSPRNG_ADDR_BASE SEGMENT_OFFSET_RNGS + (0x0b * CORE_SIZE)
#define CSPRNG_ADDR_NAME0 CSPRNG_ADDR_BASE + ADDR_NAME0
#define CSPRNG_ADDR_NAME1 CSPRNG_ADDR_BASE + ADDR_NAME1
#define CSPRNG_ADDR_VERSION CSPRNG_ADDR_BASE + ADDR_VERSION
#define CSPRNG_ADDR_CTRL CSPRNG_ADDR_BASE + 0x10
#define CSPRNG_CTRL_ENABLE 1
#define CSPRNG_CTRL_SEED 2
#define CSPRNG_ADDR_STATUS CSPRNG_ADDR_BASE + 0x11
#define CSPRNG_STATUS_VALID 1
#define CSPRNG_ADDR_RANDOM CSPRNG_ADDR_BASE + 0x20
#define CSPRNG_ADDR_NROUNDS CSPRNG_ADDR_BASE + 0x40
#define CSPRNG_ADDR_NBLOCKS_LO CSPRNG_ADDR_BASE + 0x41
#define CSPRNG_ADDR_NBLOCKS_HI CSPRNG_ADDR_BASE + 0x42
#define TRNG_NAME0 "trng"
#define TRNG_NAME1 " "
#define TRNG_VERSION "0.50"
#define AVALANCHE_ENTROPY_NAME0 "extn"
#define AVALANCHE_ENTROPY_NAME1 "oise"
#define AVALANCHE_ENTROPY_VERSION "0.10"
#define ROSC_ENTROPY_NAME0 "rosc"
#define ROSC_ENTROPY_NAME1 " ent"
#define ROSC_ENTROPY_VERSION "0.10"
#define CSPRNG_NAME0 "cspr"
#define CSPRNG_NAME1 "ng "
#define CSPRNG_VERSION "0.50"
// -----------------------------------------------------------------
// CIPHERS segment.
// -----------------------------------------------------------------
// aes core.
#define AES_ADDR_BASE SEGMENT_OFFSET_CIPHERS + (0 * CORE_SIZE)
#define AES_ADDR_NAME0 AES_ADDR_BASE + ADDR_NAME0
#define AES_ADDR_NAME1 AES_ADDR_BASE + ADDR_NAME1
#define AES_ADDR_VERSION AES_ADDR_BASE + ADDR_VERSION
#define AES_ADDR_CTRL AES_ADDR_BASE + ADDR_CTRL
#define AES_CTRL_INIT_BIT CTRL_INIT_BIT
#define AES_CTRL_NEXT_BIT CTRL_INIT_BIT
#define AES_ADDR_STATUS AES_ADDR_BASE + ADDR_STATUS
#define AES_STATUS_READY_BIT STATUS_READY_BIT
#define AES_STATUS_VALID_BIT STATUS_VALID_BIT
#define AES_ADDR_CONFIG AES_ADDR_BASE + 0x0a
#define AES_CONFIG_ENCDEC_BIT 1
#define AES_CONFIG_KEYLEN_BIT 2
#define AES_ADDR_KEY0 0x10
#define AES_ADDR_KEY1 0x11
#define AES_ADDR_KEY2 0x12
#define AES_ADDR_KEY3 0x13
#define AES_ADDR_KEY4 0x14
#define AES_ADDR_KEY5 0x15
#define AES_ADDR_KEY6 0x16
#define AES_ADDR_KEY7 0x17
#define AES_ADDR_BLOCK0 0x20
#define AES_ADDR_BLOCK1 0x21
#define AES_ADDR_BLOCK2 0x22
#define AES_ADDR_BLOCK3 0x23
#define AES_ADDR_RESULT0 0x30
#define AES_ADDR_RESULT1 0x31
#define AES_ADDR_RESULT2 0x32
#define AES_ADDR_RESULT3 0x33
#define AES_CORE_NAME0 "aes "
#define AES_CORE_NAME1 " "
#define AES_CORE_VERSION "0.80"
// -----------------------------------------------------------------
// MATH segment.
// -----------------------------------------------------------------
// Modexp core.
#define GENERAL_PREFIX 0x000
#define MODULUS_PREFIX 0x100
#define EXPONENT_PREFIX 0x200
#define MESSAGE_PREFIX 0x300
#define RESULT_PREFIX 0x400
#define MODEXP_ADDR_BASE SEGMENT_OFFSET_MATH + (0x00 * CORE_SIZE)
#define MODEXP_ADDR_NAME0 MODEXP_ADDR_BASE + ADDR_NAME0
#define MODEXP_ADDR_NAME1 MODEXP_ADDR_BASE + ADDR_NAME1
#define MODEXP_ADDR_VERSION MODEXP_ADDR_BASE + ADDR_VERSION
#define MODEXP_ADDR_CTRL MODEXP_ADDR_BASE + ADDR_CTRL
#define MODEXP_CTRL_INIT_BIT 1
#define MODEXP_CTRL_NEXT_BIT 2
#define MODEXP_ADDR_STATUS MODEXP_ADDR_BASE + ADDR_STATUS
#define MODEXP_ADDR_DELAY MODEXP_ADDR_BASE + 0x13
#define MODEXP_STATUS_READY 1
#define MODEXP_MODULUS_LENGTH MODEXP_ADDR_BASE + 0x20
#define MODEXP_EXPONENT_LENGTH MODEXP_ADDR_BASE + 0x21
#define MODEXP_NAME0 "mode"
#define MODEXP_NAME1 "xp "
#define MODEXP_VERSION "0.50"
//------------------------------------------------------------------
// Test case public functions
//------------------------------------------------------------------
void tc_set_debug(int onoff);
int tc_write(off_t offset, const uint8_t *buf, size_t len);
int tc_read(off_t offset, uint8_t *buf, size_t len);
int tc_expected(off_t offset, const uint8_t *expected, size_t len);
int tc_init(off_t offset);
int tc_next(off_t offset);
int tc_wait(off_t offset, uint8_t status, int *count);
int tc_wait_ready(off_t offset);
int tc_wait_valid(off_t offset);
//------------------------------------------------------------------
// I2C configuration
// Only used in I2C, but not harmful to define for EIM
//------------------------------------------------------------------
#define I2C_dev "/dev/i2c-2"
#define I2C_addr 0x0f
#define I2C_SLAVE 0x0703
//======================================================================
// EOF cryptech.h
//======================================================================