/* * Copyright 2017-2020 NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef FSL_CAU3_H_ #define FSL_CAU3_H_ #include "fsl_common.h" /******************************************************************************* * Definitions *******************************************************************************/ /*! * @addtogroup cau3_driver * @{ */ /*! @name Driver version */ /*! @{ */ /*! @brief CAU3 driver version. Version 2.0.5. * * Current version: 2.0.5 * * Change log: * - Version 2.0.0 * - Initial version * - Version 2.0.1 * - Replace static cau3_make_mems_private() with public CAU3_MakeMemsPrivate(). * - Remove the cau3_make_mems_private() from CAU3_Init to allow loading multiple images. * - Version 2.0.2 * - Add FSL_CAU3_USE_HW_SEMA compile time macro. When enabled, all CAU3 API functions * lock hw semaphore on function entry and release the hw semaphore on function return. * - Version 2.0.3 * - Fix MISRA C-2012 issue. * - Version 2.0.4 * - Fix MISRA C-2012 issue. * - Version 2.0.5 * - Fix MISRA-C 2012 issue. */ #define FSL_CAU3_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*! @} */ /*! @brief Hardware semaphore usage by driver functions. * This macro can be enabled for mutual exclusive calls to CAU3 APIs * from multiple CPUs. Note this does not lock against calls from multiple threads on one CPU. */ /* #define FSL_CAU3_USE_HW_SEMA 1 */ #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0) /* Using SEMA42 hardware semaphore for multiprocessor locking. * Currently supporting only SEMA42 hardware semaphore. */ #if defined(FSL_FEATURE_SOC_SEMA42_COUNT) && (FSL_FEATURE_SOC_SEMA42_COUNT > 0) #include "fsl_sema42.h" #define FSL_CAU3_SEMA42_BASE SEMA420 #define FSL_CAU3_SEMA42_GATE (1) #define FSL_CAU3_SEMA42_CLOCK_NAME kCLOCK_Sema420 #else #error FSL_CAU3_USE_HW_SEMA requires SEMA42 semaphore. #endif #endif /*! @brief CAU3 key slot selection. Current CryptoCore firmware supports 4 key slots inside CryptoCore's Private DMEM. * */ typedef enum _cau3_key_slot { kCAU3_KeySlot0 = 0x0U, /*!< CAU3 key slot 0. */ kCAU3_KeySlotNone = 0x0U, /*!< No key. */ kCAU3_KeySlot1 = 0x1U, /*!< CAU3 key slot 1. */ kCAU3_KeySlot2 = 0x2U, /*!< CAU3 key slot 2.*/ kCAU3_KeySlot3 = 0x3U, /*!< CAU3 key slot 3. */ } cau3_key_slot_t; /*! @brief CAU3 task done selection. */ typedef enum _cau3_task_done { kCAU3_TaskDoneNull = 0x00000000U, /*!< */ kCAU3_TaskDonePoll = 0x00000000U, /*!< Poll CAU3 status flag. */ kCAU3_TaskDoneIrq = 0x00010000U, /*!< Start operation and return. CAU3 asserts interrupt request when done. */ kCAU3_TaskDoneEvent = 0x00020000U, /*!< Call Wait-for-event opcode until CAU3 completes processing. */ kCAU3_TaskDoneDmaRequest = 0x00040000, /*!< Start operation and return. CAU3 asserts DMA request when done. */ } cau3_task_done_t; /*! @brief Specify CAU3's key resource and signalling to be used for an operation. */ typedef struct _cau3_handle { cau3_task_done_t taskDone; /*!< Specify CAU3 task done signalling to Host CPU. */ cau3_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify CAU3 key slot. */ } cau3_handle_t; /*! @} */ /******************************************************************************* * AES Definitions *******************************************************************************/ /*! * @addtogroup cau3_driver_aes * @{ */ /*! AES block size in bytes */ #define CAU3_AES_BLOCK_SIZE 16 /*! *@} */ /* end of cau3_driver_aes */ /******************************************************************************* * HASH Definitions ******************************************************************************/ /*! * @addtogroup cau3_driver_hash * @{ */ /*! @brief Supported cryptographic block cipher functions for HASH creation */ typedef enum _cau3_hash_algo_t { kCAU3_Sha1, /*!< SHA_1 */ kCAU3_Sha256, /*!< SHA_256 */ } cau3_hash_algo_t; /*! @brief CAU3 HASH Context size. */ #define CAU3_SHA_BLOCK_SIZE 128U /*!< internal buffer block size */ #define CAU3_HASH_BLOCK_SIZE CAU3_SHA_BLOCK_SIZE /*!< CAU3 hash block size */ /*! @brief CAU3 HASH Context size. */ #define CAU3_HASH_CTX_SIZE 58 /*! @brief Storage type used to save hash context. */ typedef struct _cau3_hash_ctx_t { uint32_t x[CAU3_HASH_CTX_SIZE]; } cau3_hash_ctx_t; /*! *@} */ /* end of cau3_driver_hash */ /******************************************************************************* * PKHA Definitions ******************************************************************************/ /*! * @addtogroup cau3_driver_pkha * @{ */ /*! PKHA ECC point structure */ typedef struct _cau3_pkha_ecc_point_t { uint8_t *X; /*!< X coordinate (affine) */ uint8_t *Y; /*!< Y coordinate (affine) */ } cau3_pkha_ecc_point_t; /*! @brief Use of timing equalized version of a PKHA function. */ typedef enum _cau3_pkha_timing_t { kCAU3_PKHA_NoTimingEqualized = 0U, /*!< Normal version of a PKHA operation */ kCAU3_PKHA_TimingEqualized = 1U /*!< Timing-equalized version of a PKHA operation */ } cau3_pkha_timing_t; /*! @brief Integer vs binary polynomial arithmetic selection. */ typedef enum _cau3_pkha_f2m_t { kCAU3_PKHA_IntegerArith = 0U, /*!< Use integer arithmetic */ kCAU3_PKHA_F2mArith = 1U /*!< Use binary polynomial arithmetic */ } cau3_pkha_f2m_t; /*! @brief Montgomery or normal PKHA input format. */ typedef enum _cau3_pkha_montgomery_form_t { kCAU3_PKHA_NormalValue = 0U, /*!< PKHA number is normal integer */ kCAU3_PKHA_MontgomeryFormat = 1U /*!< PKHA number is in montgomery format */ } cau3_pkha_montgomery_form_t; /*! *@} */ /* cau3_driver_pkha */ /******************************************************************************* * API ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @addtogroup cau3_driver * @{ */ /*! * @brief Enables clock for CAU3 and loads image to memory * * Enable CAU3 clock and loads image to CryptoCore. * * @param base CAU3 base address */ void CAU3_Init(CAU3_Type *base); /*! * @brief Execute a CAU3 null task to signal error termination * * Execute a null task to signal error termination. * The CryptoCore task executes one instruction - a "stop with error". * * @param base CAU3 base address * @param taskDone indicates completion signal * * @return status check from task completion */ status_t CAU3_ForceError(CAU3_Type *base, cau3_task_done_t taskDone); /*! * @brief Load special hardware "key context" into the CAU3's data memory * * Load the special hardware key context into the private DMEM. This only * includes the complete 256-bit key which is then specified with a size of * [8,16,24,32] bytes (for DES or AES-[128,256]). It also loads the * default IV value specified in NIST/RFC2294 IV=0xa6a6a6a6a6a6a6a6. This operation typically * loads keySlot 0, which, by convention, is used for the system key encryption * key. * * See the GENERAL COMMENTS for more information on the keyContext structure. * * NOTE: This function also performs an AES key expansion if a keySize > 8 * is specified. * * @param base CAU3 base address * @param keySize is the logical key size in bytes [8,16,24,32] * @param keySlot is the destination key slot number [0-3] * @param taskDone indicates completion signal. * * @return status check from task completion */ status_t CAU3_LoadSpecialKeyContext(CAU3_Type *base, size_t keySize, cau3_key_slot_t keySlot, cau3_task_done_t taskDone); /*! * @brief Invalidate a 64-byte "key context" in the CAU3's private data memory * * Clears the key context in the private DMEM. There is support for four "key * slots" with slot 0 typically used for the system key encryption key. * * @param base CAU3 base address * @param keySlot is the key slot number [0-3] to invalidate * @param taskDone indicates completion signal * * @return status check from task completion */ status_t CAU3_ClearKeyContext(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone); /*! * @brief Load an initialization vector into a key context * * Loads a 16-byte initialization vector (iv) into the specified key slot. * There is support for a maximum of 4 key slots. * The function is used internally for loading AEAD_CHACHA20_POY1305 nonce. * It can be also used for Alternative Initial Values for A[0] in RFC 3394. * * @param base CAU3 base address * @param iv The initialization vector, ALIGNED ON A 0-MOD-4 ADDRESS. * @param keySlot is the destination key context * @param taskDone indicates completion signal * * @return status check from task completion */ status_t CAU3_LoadKeyInitVector(CAU3_Type *base, const uint8_t *iv, cau3_key_slot_t keySlot, cau3_task_done_t taskDone); /*! * @brief Make the CAU3's local memories private * * Modify the CAU3's internal configuration so the local memories are private * and only accessible to the CAU3. This operation is typically performed after * the CAU_InitializeInstMemory(), * CAU_InitializeDataMemory(), and * CAU_InitializeReadOnlyDataMemory() functions have been performed. * * This configuration remains in effect until the next hardware reset. * * @param base CAU3 base address * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ] * * @retval status check from task completion: CAU_[OK, ERROR] */ status_t CAU3_MakeMemsPrivate(CAU3_Type *base, cau3_task_done_t taskDone); /*! *@} */ /* end of cau3_driver */ /******************************************************************************* * AES API ******************************************************************************/ /*! * @addtogroup cau3_driver_aes * @{ */ /*! * @brief Load AES key into CAU3 key slot. * * Load the key context into the private DMEM. This function also performs an AES key expansion. * For CAU3 AES encryption/decryption/cmac, users only need to call one of @ref CAU3_AES_SetKey and @ref * CAU3_LoadSpecialKeyContext. * * CAU3_AES_SetKey * @param base CAU3 peripheral base address. * @param handle Handle used for the request. * @param key 0-mod-4 aligned pointer to AES key. * @param keySize AES key size in bytes. Shall equal 16 or 32. * @return status from set key operation */ status_t CAU3_AES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize); /*! * @brief Encrypts AES on one 128-bit block. * * Encrypts AES. * The source plaintext and destination ciphertext can overlap in system memory. * * @param base CAU3 peripheral base address * @param handle Handle used for this request. * @param plaintext Input plain text to encrypt * @param[out] ciphertext Output cipher text * @return Status from encrypt operation */ status_t CAU3_AES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t plaintext[16], uint8_t ciphertext[16]); /*! * @brief Decrypts AES on one 128-bit block. * * Decrypts AES. * The source ciphertext and destination plaintext can overlap in system memory. * * @param base CAU3 peripheral base address * @param handle Handle used for this request. * @param ciphertext Input plain text to encrypt * @param[out] plaintext Output cipher text * @return Status from decrypt operation */ status_t CAU3_AES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t ciphertext[16], uint8_t plaintext[16]); /*! * @brief Perform an AES-128 cipher-based authentication code (CMAC) * * Performs an AES-128 cipher-based authentication code (CMAC) on a * message. RFC 4493. * * @param base CAU3 peripheral base address * @param handle Handle used for this request. * @param message is source uint8_t array of data bytes, any alignment * @param size Number of bytes in the message. * @param mac is the output 16 bytes MAC, must be a 0-mod-4 aligned address * @return status check from task completion */ status_t CAU3_AES_Cmac(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *message, size_t size, uint8_t *mac); /*! * @brief Perform an AES key expansion for specified key slot * * Performs an AES key expansion (aka schedule) on the specified key slot. It * uses the keySize information in the context to determine whether the key * expansion applies to a 128- or 256-bit AES key. * This function is primarily intended to be called after * key blob has been unwrapped by @ref CAU3_KeyBlobUnwrap to destination key slot, so that the unwrapped key * can be used for AES encryption. * * @param base CAU3 base address * @param keySlot is the key context * @param taskDone indicates completion signal * @return status check from task completion */ status_t CAU3_AES_KeyExpansion(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone); /*! *@} */ /* end of cau3_driver_aes */ /******************************************************************************* * DES API ******************************************************************************/ /*! * @addtogroup cau3_driver_des * @{ */ /*! * @brief Perform a 3DES key parity check * * Performs a 3DES key parity check on three 8-byte keys. * The function is blocking. * * @param base CAU3 peripheral base address * @param keySlot defines the key context to be used in the parity check * * @return status check from task completion */ status_t CAU3_TDES_CheckParity(CAU3_Type *base, cau3_key_slot_t keySlot); /*! * @brief Load DES key into CAU3 key slot. * * Load the key context into the private DMEM. * * @param base CAU3 peripheral base address. * @param handle Handle used for the request. * @param key 0-mod-4 aligned pointer to 3DES key. * @param keySize 3DES key size in bytes. Shall equal 24. * @return status from set key operation */ status_t CAU3_TDES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize); /*! * @brief Perform a 3DES encryption * * Performs a 3DES "electronic code book" encryption on one 8-byte data block. * The source plaintext and destination ciphertext can overlap in system memory. * Supports both blocking and non-blocking task completion. * * @param base CAU3 peripheral base address. * @param handle Handle used for this request. * @param plaintext is source uint8_t array of data bytes, any alignment * @param ciphertext is destination uint8_t array of data byte, any alignment * * @return status check from task completion */ status_t CAU3_TDES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext); /*! * @brief Perform a 3DES decryption * * Performs a 3DES "electronic code book" decryption on one 8-byte data block. * The source ciphertext and destination plaintext can overlap in sysMemory. * Supports both blocking and non-blocking task completion. * * @param base CAU3 peripheral base address. * @param handle Handle used for this request. * @param ciphertext is destination uint8_t array of data byte, any alignment * @param plaintext is source uint8_t array of data bytes, any alignment * @return status check from task completion */ status_t CAU3_TDES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext); /*! *@} */ /* end of cau3_driver_des */ /******************************************************************************* * HASH API ******************************************************************************/ /*! * @addtogroup cau3_driver_hash * @{ */ /*! * @brief Initialize HASH context * * This function initializes the HASH. * * For blocking CAU3 HASH API, the HASH context contains all information required for context switch, * such as running hash. * * @param base CAU3 peripheral base address * @param[out] ctx Output hash context * @param algo Underlaying algorithm to use for hash computation. * @return Status of initialization */ status_t CAU3_HASH_Init(CAU3_Type *base, cau3_hash_ctx_t *ctx, cau3_hash_algo_t algo); /*! * @brief Add data to current HASH * * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be * hashed. The functions blocks. If it returns kStatus_Success, the running hash or mac * has been updated (CAU3 has processed the input data), so the memory at input pointer * can be released back to system. The context is updated with the running hash or mac * and with all necessary information to support possible context switch. * * @param base CAU3 peripheral base address * @param[in,out] ctx HASH context * @param input Input data * @param inputSize Size of input data in bytes * @return Status of the hash update operation */ status_t CAU3_HASH_Update(CAU3_Type *base, cau3_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize); /*! * @brief Finalize hashing * * Outputs the final hash (computed by CAU3_HASH_Update()) and erases the context. * * @param base CAU3 peripheral base address * @param[in,out] ctx Input hash context * @param[out] output Output hash data * @param[out] outputSize Output parameter storing the size of the output hash in bytes * @return Status of the hash finish operation */ status_t CAU3_HASH_Finish(CAU3_Type *base, cau3_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize); /*! * @brief Create HASH on given data * * Perform the full SHA in one function call. The function is blocking. * * @param base CAU3 peripheral base address * @param algo Underlaying algorithm to use for hash computation. * @param input Input data * @param inputSize Size of input data in bytes * @param[out] output Output hash data * @param[out] outputSize Output parameter storing the size of the output hash in bytes * @return Status of the one call hash operation. */ status_t CAU3_HASH(CAU3_Type *base, cau3_hash_algo_t algo, const uint8_t *input, size_t inputSize, uint8_t *output, size_t *outputSize); /*! *@} */ /* end of cau3_driver_hash */ /******************************************************************************* * AEAD API ******************************************************************************/ /*! * @addtogroup cau3_driver_chacha_poly * @{ */ /*! * @brief Load 256-bit key into CAU3 key context (in key slot). * * Load the key context into the private DMEM for CHACHA20_POLY1305 AEAD. * * @param base CAU3 peripheral base address. * @param handle Handle used for the request. * @param key 0-mod-4 aligned pointer to CHACHA20_POLY1305 256-bit key. * @param keySize Size of the key in bytes. Shall be 32. * @return status from set key operation */ status_t CAU3_CHACHA20_POLY1305_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize); /*! * @brief Perform ChaCha-Poly encryption/authentication * * Perform ChaCha encryption over a message of "n" bytes, and authentication * over the encrypted data plus an additional authenticated data, * returning encrypted data + a message digest. * * @param base CAU3 peripheral base address * @param handle Handle used for this request. The keySlot member specifies key context with key and IV. * @param plaintext The uint8_t source message to be encrypted, any alignment * @param[out] ciphertext is a pointer to the output encrypted message, any aligment * @param size The length of the plaintext and ciphertext in bytes * @param aad A pointer to the additional authenticated data, any alignment * @param aadLen Length of additional authenticated data in bytes * @param nonce 0-mod-4 aligned pointer to CHACHA20_POLY1305 96-bit nonce. * @param[out] tag A pointer to the 128-bit message digest output, any alignment * * @return status check from task completion */ status_t CAU3_CHACHA20_POLY1305_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size, const uint8_t *aad, size_t aadLen, const uint8_t *nonce, uint8_t *tag); /*! * @brief Perform ChaCha-Poly decryption/authentication check * * Perform ChaCha decryption over a message of "n" bytes, and checks * authentication over the encrypted data plus an additional authenticated data, * returning decrypted data. IF the tag authentication fails, the task terminates with error and * the output is forced to zero. * * @param base CAU3 peripheral base address * @param handle Handle used for this request. The keySlot member specifies key context with key and IV. * @param ciphertext The uint8_t source msg to be decrypted, any alignment * @param[out] plaintext A pointer to the output decrypted message, any alignment * @param size Length of the plaintext and ciphertext in bytes * @param aad A pointer to the additional authenticated data, any alignment * @param aadLen Length of additional authenticated data in bytes * @param nonce 0-mod-4 aligned pointer to CHACHA20_POLY1305 96-bit nonce. * @param tag A pointer to the 128-bit msg digest input to be checked, any alignment * * @return status check from task completion * */ status_t CAU3_CHACHA20_POLY1305_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size, const uint8_t *aad, size_t aadLen, const uint8_t *nonce, const uint8_t *tag); /*! *@} */ /* end of cau3_driver_chacha_poly */ /******************************************************************************* * BLOB API ******************************************************************************/ /*! * @addtogroup cau3_driver_blob * @{ */ /*! * @brief Perform an RFC3394 key blob unwrap * * Perform an RFC3394 unwrap of an AES encrypted key blob. The unwrapped * key blob is loaded into the specified key slot [1-3]. The initial * special hardware KEK contained in key slot 0 is typically used for the * unwrapping operation. The destination context number must be different than * the keySlot used for unwrapping. * Implements the algorithm at RFC 3394 to AES key unwrap. The * current implementation allows to unwrap up to 512 bits, * with the restriction of nblocks=2 or =4 or n=8(means it * unwraps only 128bits, 256bits or two 256 bits keys (512)). It * is allowed input key of 128 and 256bits only (passed using * the keyslot). The function also assumes the * @ref CAU3_LoadSpecialKeyContext was called before. * It returns error and clear the destination context in case * parameters are not inside aceptable values. * In case n>4 && n!=8 it clears both destination contexts (the * dstContext and the adjacent/next context) * In case of n=8, the first unwraped key will be stored in the * dstContext slot, and the second key will be saved in the next * context (E.g: if dstContext=1, then first key goes to slot 1 * and second key to slot 2. If dstContext=3 then first key goes * to slot 3 and second key goes to slot 1). * Examples of n usage. * E.g.: n = 2 means a unwraped key of 128 bits (2 * 64) * E.g.: n = 4 means a unwraped key of 256 bits (4 * 64) * E.g.: n = 8 means two unwraped keys of 256 bits (8 * 64) * * The function is blocking, it uses the polling task done signaling. * * @param base CAU3 peripheral base address * @param keySlot is the key used to unwrap the key blob [0-3] * @param keyBlob 0-mod-4 aligned pointer is the RFC3394 wrapped key blob. * @param numberOfBlocks is the unwrapped keyBlob length as multiple of 64-bit blocks * @param dstContext is the destination key context for unwrapped blob [0-3] * @retval status check from task completion */ status_t CAU3_KeyBlobUnwrap(CAU3_Type *base, cau3_key_slot_t keySlot, const uint8_t *keyBlob, uint32_t numberOfBlocks, cau3_key_slot_t dstContext); /*! *@} */ /* end of cau3_driver_blob */ /******************************************************************************* * PKHA API ******************************************************************************/ /*! * @addtogroup cau3_driver_pkha * @{ */ int CAU3_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB); /*! * @brief Converts from integer to Montgomery format. * * This function computes R2 mod N and optionally converts A or B into Montgomery format of A or B. * * @param base CAU3 peripheral base address * @param N modulus * @param sizeN size of N in bytes * @param[in,out] A The first input in non-Montgomery format. Output Montgomery format of the first input. * @param[in,out] sizeA pointer to size variable. On input it holds size of input A in bytes. On output it holds size of * Montgomery format of A in bytes. * @param[in,out] B Second input in non-Montgomery format. Output Montgomery format of the second input. * @param[in,out] sizeB pointer to size variable. On input it holds size of input B in bytes. On output it holds size of * Montgomery format of B in bytes. * @param[out] R2 Output Montgomery factor R2 mod N. * @param[out] sizeR2 pointer to size variable. On output it holds size of Montgomery factor R2 mod N in bytes. * @param equalTime Run the function time equalized or no timing equalization. * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_NormalToMontgomery(CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *A, size_t *sizeA, uint8_t *B, size_t *sizeB, uint8_t *R2, size_t *sizeR2, cau3_pkha_timing_t equalTime, cau3_pkha_f2m_t arithType); /*! * @brief Converts from Montgomery format to int. * * This function converts Montgomery format of A or B into int A or B. * * @param base CAU3 peripheral base address * @param N modulus. * @param sizeN size of N modulus in bytes. * @param[in,out] A Input first number in Montgomery format. Output is non-Montgomery format. * @param[in,out] sizeA pointer to size variable. On input it holds size of the input A in bytes. On output it holds * size of non-Montgomery A in bytes. * @param[in,out] B Input first number in Montgomery format. Output is non-Montgomery format. * @param[in,out] sizeB pointer to size variable. On input it holds size of the input B in bytes. On output it holds * size of non-Montgomery B in bytes. * @param equalTime Run the function time equalized or no timing equalization. * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_MontgomeryToNormal(CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *A, size_t *sizeA, uint8_t *B, size_t *sizeB, cau3_pkha_timing_t equalTime, cau3_pkha_f2m_t arithType); /*! * @brief Performs modular addition - (A + B) mod N. * * This function performs modular addition of (A + B) mod N, with either * integer or binary polynomial (F2m) inputs. In the F2m form, this function is * equivalent to a bitwise XOR and it is functionally the same as subtraction. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param B second addend (integer or binary polynomial) * @param sizeB Size of B in bytes * @param N modulus. * @param sizeN Size of N in bytes. * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_ModAdd(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *B, size_t sizeB, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType); /*! * @brief Performs modular subtraction - (A - B) mod N. * * This function performs modular subtraction of (A - B) mod N with * integer inputs. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param B second addend (integer or binary polynomial) * @param sizeB Size of B in bytes * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @return Operation status. */ status_t CAU3_PKHA_ModSub1(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *B, size_t sizeB, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize); /*! * @brief Performs modular subtraction - (B - A) mod N. * * This function performs modular subtraction of (B - A) mod N, * with integer inputs. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param B second addend (integer or binary polynomial) * @param sizeB Size of B in bytes * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @return Operation status. */ status_t CAU3_PKHA_ModSub2(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *B, size_t sizeB, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize); /*! * @brief Performs modular multiplication - (A x B) mod N. * * This function performs modular multiplication with either integer or * binary polynomial (F2m) inputs. It can optionally specify whether inputs * and/or outputs will be in Montgomery form or not. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param B second addend (integer or binary polynomial) * @param sizeB Size of B in bytes * @param N modulus. * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @param montIn Format of inputs * @param montOut Format of output * @param equalTime Run the function time equalized or no timing equalization. This argument is ignored for F2m modular * multiplication. * @return Operation status. */ status_t CAU3_PKHA_ModMul(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *B, size_t sizeB, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType, cau3_pkha_montgomery_form_t montIn, cau3_pkha_montgomery_form_t montOut, cau3_pkha_timing_t equalTime); /*! * @brief Performs modular exponentiation - (A^E) mod N. * * This function performs modular exponentiation with either integer or * binary polynomial (F2m) inputs. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param N modulus * @param sizeN Size of N in bytes * @param E exponent * @param sizeE Size of E in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param montIn Format of A input (normal or Montgomery) * @param arithType Type of arithmetic to perform (integer or F2m) * @param equalTime Run the function time equalized or no timing equalization. * @return Operation status. */ status_t CAU3_PKHA_ModExp(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *N, size_t sizeN, const uint8_t *E, size_t sizeE, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType, cau3_pkha_montgomery_form_t montIn, cau3_pkha_timing_t equalTime); /*! * @brief Performs Modular Square Root. * * This function performs modular square root with integer inputs. * The modular square root function computes output result B, such that ( B x B ) mod N = input A. * If no such B result exists, the result will be set to 0 and the PKHA "prime" flag * will be set. Input values A and B are limited to a maximum size of 128 bytes. Note that * two such square root values may exist. This algorithm will find either one of them, if any * exist. The second possible square root (B') can be found by calculating B' = N - B. * * @param base CAU3 peripheral base address * @param A input value, for which a square root is to be calculated * @param sizeA Size of A in bytes * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @return Operation status. */ status_t CAU3_PKHA_ModSqrt(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize); /*! * @brief Performs modular reduction - (A) mod N. * * This function performs modular reduction with either integer or * binary polynomial (F2m) inputs. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_ModRed(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType); /*! * @brief Performs modular inversion - (A^-1) mod N. * * This function performs modular inversion with either integer or * binary polynomial (F2m) inputs. * * @param base CAU3 peripheral base address * @param A first addend (integer or binary polynomial) * @param sizeA Size of A in bytes * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_ModInv(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType); /*! * @brief Computes integer Montgomery factor R^2 mod N. * * This function computes a constant to assist in converting operands * into the Montgomery residue system representation. * * @param base CAU3 peripheral base address * @param N modulus * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_ModR2( CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType); /*! * @brief Performs Integer RERP mod P. * * This function is used to compute a constant to assist in converting operands into the * Montgomery residue system representation specifically for Chinese Remainder Theorem * while performing RSA with a CRT implementation where a modulus E=P x Q, and P and * Q are prime numbers. Although labeled RERP mod P, this routine (function) can also * compute RERQ mod Q. * * @param base CAU3 peripheral base address * @param P modulus P or Q of CRT, an odd integer * @param sizeP Size of P in bytes * @param sizeE Number of bytes of E = P x Q (this size must be given, though content of E itself is not used). * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @return Operation status. */ status_t CAU3_PKHA_ModRR( CAU3_Type *base, const uint8_t *P, size_t sizeP, size_t sizeE, uint8_t *result, size_t *resultSize); /*! * @brief Calculates the greatest common divisor - GCD (A, N). * * This function calculates the greatest common divisor of two inputs with * either integer or binary polynomial (F2m) inputs. * * @param base CAU3 peripheral base address * @param A first value (must be smaller than or equal to N) * @param sizeA Size of A in bytes * @param N second value (must be non-zero) * @param sizeN Size of N in bytes * @param[out] result Output array to store result of operation * @param[out] resultSize Output size of operation in bytes * @param arithType Type of arithmetic to perform (integer or F2m) * @return Operation status. */ status_t CAU3_PKHA_ModGcd(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType); /*! * @brief Executes Miller-Rabin primality test. * * This function calculates whether or not a candidate prime number is likely * to be a prime. * * @param base CAU3 peripheral base address * @param A initial random seed * @param sizeA Size of A in bytes * @param B number of trial runs * @param sizeB Size of B in bytes * @param N candidate prime integer * @param sizeN Size of N in bytes * @param[out] res True if the value is likely prime or false otherwise * @return Operation status. */ status_t CAU3_PKHA_PrimalityTest(CAU3_Type *base, const uint8_t *A, size_t sizeA, const uint8_t *B, size_t sizeB, const uint8_t *N, size_t sizeN, bool *res); /*! * @brief Adds elliptic curve points - A + B. * * This function performs ECC point addition over a prime field (Fp) or binary field (F2m) using * affine coordinates. * * @param base CAU3 peripheral base address * @param A Left-hand point * @param B Right-hand point * @param N Prime modulus of the field * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from * CAU3_PKHA_ModR2() function). * @param aCurveParam A parameter from curve equation * @param bCurveParam B parameter from curve equation (constant) * @param size Size in bytes of curve points and parameters * @param arithType Type of arithmetic to perform (integer or F2m) * @param[out] result Result point * @return Operation status. */ status_t CAU3_PKHA_ECC_PointAdd(CAU3_Type *base, const cau3_pkha_ecc_point_t *A, const cau3_pkha_ecc_point_t *B, const uint8_t *N, const uint8_t *R2modN, const uint8_t *aCurveParam, const uint8_t *bCurveParam, size_t size, cau3_pkha_f2m_t arithType, cau3_pkha_ecc_point_t *result); /*! * @brief Doubles elliptic curve points - B + B. * * This function performs ECC point doubling over a prime field (Fp) or binary field (F2m) using * affine coordinates. * * @param base CAU3 peripheral base address * @param B Point to double * @param N Prime modulus of the field * @param aCurveParam A parameter from curve equation * @param bCurveParam B parameter from curve equation (constant) * @param size Size in bytes of curve points and parameters * @param arithType Type of arithmetic to perform (integer or F2m) * @param[out] result Result point * @return Operation status. */ status_t CAU3_PKHA_ECC_PointDouble(CAU3_Type *base, const cau3_pkha_ecc_point_t *B, const uint8_t *N, const uint8_t *aCurveParam, const uint8_t *bCurveParam, size_t size, cau3_pkha_f2m_t arithType, cau3_pkha_ecc_point_t *result); /*! * @brief Multiplies an elliptic curve point by a scalar - E x (A0, A1). * * This function performs ECC point multiplication to multiply an ECC point by * a scalar integer multiplier over a prime field (Fp) or a binary field (F2m). * * @param base CAU3 peripheral base address * @param A Point as multiplicand * @param E Scalar multiple * @param sizeE The size of E, in bytes * @param N Modulus, a prime number for the Fp field or Irreducible polynomial for F2m field. * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from * CAU3_PKHA_ModR2() function). * @param aCurveParam A parameter from curve equation * @param bCurveParam B parameter from curve equation (C parameter for operation over F2m). * @param size Size in bytes of curve points and parameters * @param equalTime Run the function time equalized or no timing equalization. * @param arithType Type of arithmetic to perform (integer or F2m) * @param[out] result Result point * @return Operation status. */ status_t CAU3_PKHA_ECC_PointMul(CAU3_Type *base, const cau3_pkha_ecc_point_t *A, const uint8_t *E, size_t sizeE, const uint8_t *N, const uint8_t *R2modN, const uint8_t *aCurveParam, const uint8_t *bCurveParam, size_t size, cau3_pkha_timing_t equalTime, cau3_pkha_f2m_t arithType, cau3_pkha_ecc_point_t *result); /*! * @brief Computes scalar multiplication of a point on an elliptic curve in Montgomery form. * * This function computes the scalar multiplication of a point on an elliptic curve in * Montgomery form. The input and output are just the x coordinates of the points. * The points on a curve are defined by the equation E: B*y^2 = x^3 + A*x^2 + x mod p * This function computes a point multiplication on a Montgomery curve, using * Montgomery values, by means of a Montgomery ladder. At the end of the ladder, P2 = P3 + P1, * where P1 is the input and P3 is the result. * * @param base CAU3 peripheral base address * @param E Scalar multiplier, any integer * @param sizeE The size of E, in bytes * @param inputCoordinate Point as multiplicand, an input point's affine x coordinate * @param A24 elliptic curve a24 parameter, that is, (A+2)/4 * @param N Modulus, a prime number. * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from * @ref CAU3_PKHA_ModR2() function). * @param size Size in bytes of curve points and parameters * @param equalTime Run the function time equalized or no timing equalization. * @param[out] outputCoordinate Resulting poin's x affine coordinate. * @return Operation status. */ status_t CAU3_PKHA_ECM_PointMul(CAU3_Type *base, const uint8_t *E, size_t sizeE, const uint8_t *inputCoordinate, const uint8_t *A24, const uint8_t *N, const uint8_t *R2modN, size_t size, cau3_pkha_timing_t equalTime, uint8_t *outputCoordinate); /*! * @brief Multiplies an Edwards-form elliptic curve point by a scalar - E x (A0, A1). * * This function performs scalar multiplication of an Edwards-form elliptic curve point * in affine coordinates. * The points on a curve are defined by the equation E: a*X^2 + d^2 = 1 + D^2*X^2*Y^2 mod N * * @param base CAU3 peripheral base address * @param A Point as multiplicand * @param E Scalar multiple * @param sizeE The size of E, in bytes * @param N Modulus, a prime number for the Fp field. * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from * @ref CAU3_PKHA_ModR2() function). * @param aCurveParam A parameter from curve equation * @param dCurveParam D parameter from curve equation. * @param size Size in bytes of curve points and parameters * @param equalTime Run the function time equalized or no timing equalization. * @param[out] result Result point * @return Operation status. */ status_t CAU3_PKHA_ECT_PointMul(CAU3_Type *base, const cau3_pkha_ecc_point_t *A, const uint8_t *E, size_t sizeE, const uint8_t *N, const uint8_t *R2modN, const uint8_t *aCurveParam, const uint8_t *dCurveParam, size_t size, cau3_pkha_timing_t equalTime, cau3_pkha_ecc_point_t *result); /*! * @brief Adds an Edwards-form elliptic curve points - A + B. * * This function performs Edwards-form elliptic curve point addition over a prime field (Fp) using affine coordinates. * The points on a curve are defined by the equation E: a*X^2 + Y^2 = 1 + d^2*X^2*Y^2 mod N * * @param base CAU3 peripheral base address * @param A Left-hand point * @param B Right-hand point * @param N Prime modulus of the field * @param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from * @ref CAU3_PKHA_ModR2() function). * @param aCurveParam A parameter from curve equation * @param dCurveParam D parameter from curve equation * @param size Size in bytes of curve points and parameters * @param[out] result Result point * @return Operation status. */ status_t CAU3_PKHA_ECT_PointAdd(CAU3_Type *base, const cau3_pkha_ecc_point_t *A, const cau3_pkha_ecc_point_t *B, const uint8_t *N, const uint8_t *R2modN, const uint8_t *aCurveParam, const uint8_t *dCurveParam, size_t size, cau3_pkha_ecc_point_t *result); /*! *@} */ /* end of cau3_driver_pkha */ #if defined(__cplusplus) } #endif #endif /* FSL_CAU3_H_ */