STM32L443xx HAL User Manual
stm32l4xx_hal_pka.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_pka.c
00004   * @author  MCD Application Team
00005   * @brief   PKA HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of public key accelerator(PKA):
00008   *           + Initialization and de-initialization functions
00009   *           + Start an operation
00010   *           + Retrieve the operation result
00011   *
00012   ******************************************************************************
00013   * @attention
00014   *
00015   * Copyright (c) 2017 STMicroelectronics.
00016   * All rights reserved.
00017   *
00018   * This software is licensed under terms that can be found in the LICENSE file
00019   * in the root directory of this software component.
00020   * If no LICENSE file comes with this software, it is provided AS-IS.
00021   *
00022   ******************************************************************************
00023   @verbatim
00024   ==============================================================================
00025                         ##### How to use this driver #####
00026   ==============================================================================
00027     [..]
00028     The PKA HAL driver can be used as follows:
00029 
00030     (#) Declare a PKA_HandleTypeDef handle structure, for example: PKA_HandleTypeDef  hpka;
00031 
00032     (#) Initialize the PKA low level resources by implementing the HAL_PKA_MspInit() API:
00033         (##) Enable the PKA interface clock
00034         (##) NVIC configuration if you need to use interrupt process
00035             (+++) Configure the PKA interrupt priority
00036             (+++) Enable the NVIC PKA IRQ Channel
00037 
00038     (#) Initialize the PKA registers by calling the HAL_PKA_Init() API which trig
00039         HAL_PKA_MspInit().
00040 
00041     (#) Fill entirely the input structure corresponding to your operation:
00042         For instance: PKA_ModExpInTypeDef for HAL_PKA_ModExp().
00043 
00044     (#) Execute the operation (in polling or interrupt) and check the returned value.
00045 
00046     (#) Retrieve the result of the operation (For instance, HAL_PKA_ModExp_GetResult for
00047         HAL_PKA_ModExp operation). The function to gather the result is different for each
00048         kind of operation. The correspondence can be found in the following section.
00049 
00050     (#) Call the function HAL_PKA_DeInit() to restore the default configuration which trig
00051         HAL_PKA_MspDeInit().
00052 
00053     *** High level operation ***
00054     =================================
00055     [..]
00056       (+) Input structure requires buffers as uint8_t array.
00057 
00058       (+) Output structure requires buffers as uint8_t array.
00059 
00060       (+) Modular exponentiation using:
00061       (++) HAL_PKA_ModExp().
00062       (++) HAL_PKA_ModExp_IT().
00063       (++) HAL_PKA_ModExpFastMode().
00064       (++) HAL_PKA_ModExpFastMode_IT().
00065       (++) HAL_PKA_ModExp_GetResult() to retrieve the result of the operation.
00066 
00067       (+) RSA Chinese Remainder Theorem (CRT) using:
00068       (++) HAL_PKA_RSACRTExp().
00069       (++) HAL_PKA_RSACRTExp_IT().
00070       (++) HAL_PKA_RSACRTExp_GetResult() to retrieve the result of the operation.
00071 
00072       (+) ECC Point Check using:
00073       (++) HAL_PKA_PointCheck().
00074       (++) HAL_PKA_PointCheck_IT().
00075       (++) HAL_PKA_PointCheck_IsOnCurve() to retrieve the result of the operation.
00076 
00077       (+) ECDSA Sign
00078       (++) HAL_PKA_ECDSASign().
00079       (++) HAL_PKA_ECDSASign_IT().
00080       (++) HAL_PKA_ECDSASign_GetResult() to retrieve the result of the operation.
00081 
00082       (+) ECDSA Verify
00083       (++) HAL_PKA_ECDSAVerif().
00084       (++) HAL_PKA_ECDSAVerif_IT().
00085       (++) HAL_PKA_ECDSAVerif_IsValidSignature() to retrieve the result of the operation.
00086 
00087       (+) ECC Scalar Multiplication using:
00088       (++) HAL_PKA_ECCMul().
00089       (++) HAL_PKA_ECCMul_IT().
00090       (++) HAL_PKA_ECCMulFastMode().
00091       (++) HAL_PKA_ECCMulFastMode_IT().
00092       (++) HAL_PKA_ECCMul_GetResult() to retrieve the result of the operation.
00093 
00094 
00095     *** Low level operation ***
00096     =================================
00097     [..]
00098       (+) Input structure requires buffers as uint32_t array.
00099 
00100       (+) Output structure requires buffers as uint32_t array.
00101 
00102       (+) Arithmetic addition using:
00103       (++) HAL_PKA_Add().
00104       (++) HAL_PKA_Add_IT().
00105       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00106             The resulting size can be the input parameter or the input parameter size + 1 (overflow).
00107 
00108       (+) Arithmetic subtraction using:
00109       (++) HAL_PKA_Sub().
00110       (++) HAL_PKA_Sub_IT().
00111       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00112 
00113       (+) Arithmetic multiplication using:
00114       (++) HAL_PKA_Mul().
00115       (++) HAL_PKA_Mul_IT().
00116       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00117 
00118       (+) Comparison using:
00119       (++) HAL_PKA_Cmp().
00120       (++) HAL_PKA_Cmp_IT().
00121       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00122 
00123       (+) Modular addition using:
00124       (++) HAL_PKA_ModAdd().
00125       (++) HAL_PKA_ModAdd_IT().
00126       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00127 
00128       (+) Modular subtraction using:
00129       (++) HAL_PKA_ModSub().
00130       (++) HAL_PKA_ModSub_IT().
00131       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00132 
00133       (+) Modular inversion using:
00134       (++) HAL_PKA_ModInv().
00135       (++) HAL_PKA_ModInv_IT().
00136       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00137 
00138       (+) Modular reduction using:
00139       (++) HAL_PKA_ModRed().
00140       (++) HAL_PKA_ModRed_IT().
00141       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00142 
00143       (+) Montgomery multiplication using:
00144       (++) HAL_PKA_MontgomeryMul().
00145       (++) HAL_PKA_MontgomeryMul_IT().
00146       (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation.
00147 
00148     *** Montgomery parameter ***
00149     =================================
00150       (+) For some operation, the computation of the Montgomery parameter is a prerequisite.
00151       (+) Input structure requires buffers as uint8_t array.
00152       (+) Output structure requires buffers as uint32_t array.(Only used inside PKA).
00153       (+) You can compute the Montgomery parameter using:
00154       (++) HAL_PKA_MontgomeryParam().
00155       (++) HAL_PKA_MontgomeryParam_IT().
00156       (++) HAL_PKA_MontgomeryParam_GetResult() to retrieve the result of the operation.
00157 
00158     *** Polling mode operation ***
00159     ===================================
00160     [..]
00161       (+) When an operation is started in polling mode, the function returns when:
00162       (++) A timeout is encounter.
00163       (++) The operation is completed.
00164 
00165     *** Interrupt mode operation ***
00166     ===================================
00167     [..]
00168       (+) Add HAL_PKA_IRQHandler to the IRQHandler of PKA.
00169       (+) Enable the IRQ using HAL_NVIC_EnableIRQ().
00170       (+) When an operation is started in interrupt mode, the function returns immediately.
00171       (+) When the operation is completed, the callback HAL_PKA_OperationCpltCallback is called.
00172       (+) When an error is encountered, the callback HAL_PKA_ErrorCallback is called.
00173       (+) To stop any operation in interrupt mode, use HAL_PKA_Abort().
00174 
00175     *** Utilities ***
00176     ===================================
00177     [..]
00178       (+) To clear the PKA RAM, use HAL_PKA_RAMReset().
00179       (+) To get current state, use HAL_PKA_GetState().
00180       (+) To get current error, use HAL_PKA_GetError().
00181 
00182     *** Callback registration ***
00183     =============================================
00184     [..]
00185 
00186      The compilation flag USE_HAL_PKA_REGISTER_CALLBACKS, when set to 1,
00187      allows the user to configure dynamically the driver callbacks.
00188      Use Functions HAL_PKA_RegisterCallback()
00189      to register an interrupt callback.
00190     [..]
00191 
00192      Function HAL_PKA_RegisterCallback() allows to register following callbacks:
00193        (+) OperationCpltCallback : callback for End of operation.
00194        (+) ErrorCallback         : callback for error detection.
00195        (+) MspInitCallback       : callback for Msp Init.
00196        (+) MspDeInitCallback     : callback for Msp DeInit.
00197      This function takes as parameters the HAL peripheral handle, the Callback ID
00198      and a pointer to the user callback function.
00199     [..]
00200 
00201      Use function HAL_PKA_UnRegisterCallback to reset a callback to the default
00202      weak function.
00203     [..]
00204 
00205      HAL_PKA_UnRegisterCallback takes as parameters the HAL peripheral handle,
00206      and the Callback ID.
00207      This function allows to reset following callbacks:
00208        (+) OperationCpltCallback : callback for End of operation.
00209        (+) ErrorCallback         : callback for error detection.
00210        (+) MspInitCallback       : callback for Msp Init.
00211        (+) MspDeInitCallback     : callback for Msp DeInit.
00212      [..]
00213 
00214      By default, after the HAL_PKA_Init() and when the state is HAL_PKA_STATE_RESET
00215      all callbacks are set to the corresponding weak functions:
00216      examples HAL_PKA_OperationCpltCallback(), HAL_PKA_ErrorCallback().
00217      Exception done for MspInit and MspDeInit functions that are
00218      reset to the legacy weak functions in the HAL_PKA_Init()/ HAL_PKA_DeInit() only when
00219      these callbacks are null (not registered beforehand).
00220     [..]
00221 
00222      If MspInit or MspDeInit are not null, the HAL_PKA_Init()/ HAL_PKA_DeInit()
00223      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00224      [..]
00225 
00226      Callbacks can be registered/unregistered in HAL_PKA_STATE_READY state only.
00227      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00228      in HAL_PKA_STATE_READY or HAL_PKA_STATE_RESET state,
00229      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00230     [..]
00231 
00232      Then, the user first registers the MspInit/MspDeInit user callbacks
00233      using HAL_PKA_RegisterCallback() before calling HAL_PKA_DeInit()
00234      or HAL_PKA_Init() function.
00235      [..]
00236 
00237      When the compilation flag USE_HAL_PKA_REGISTER_CALLBACKS is set to 0 or
00238      not defined, the callback registration feature is not available and all callbacks
00239      are set to the corresponding weak functions.
00240 
00241   @endverbatim
00242   ******************************************************************************
00243   */
00244 
00245 /* Includes ------------------------------------------------------------------*/
00246 #include "stm32l4xx_hal.h"
00247 
00248 /** @addtogroup STM32L4xx_HAL_Driver
00249   * @{
00250   */
00251 
00252 #if defined(PKA) && defined(HAL_PKA_MODULE_ENABLED)
00253 
00254 /** @defgroup PKA PKA
00255   * @brief    PKA HAL module driver.
00256   * @{
00257   */
00258 
00259 /* Private typedef -----------------------------------------------------------*/
00260 /* Private define ------------------------------------------------------------*/
00261 /** @defgroup PKA_Private_Define PKA Private Define
00262   * @{
00263   */
00264 #define PKA_RAM_SIZE 894U
00265 #define PKA_RAM_ERASE_TIMEOUT 1000U
00266 
00267 /* Private macro -------------------------------------------------------------*/
00268 #define __PKA_RAM_PARAM_END(TAB,INDEX)                do{                                   \
00269                                                                     TAB[INDEX] = 0UL;       \
00270                                                                   } while(0)
00271 /**
00272   * @}
00273   */
00274 
00275 /* Private variables ---------------------------------------------------------*/
00276 /* Private function prototypes -----------------------------------------------*/
00277 /** @defgroup PKA_Private_Functions PKA Private Functions
00278   * @{
00279   */
00280 uint32_t PKA_GetMode(PKA_HandleTypeDef *hpka);
00281 HAL_StatusTypeDef PKA_PollEndOfOperation(PKA_HandleTypeDef *hpka, uint32_t Timeout, uint32_t Tickstart);
00282 uint32_t PKA_CheckError(PKA_HandleTypeDef *hpka, uint32_t mode);
00283 uint32_t PKA_GetBitSize_u8(uint32_t byteNumber);
00284 uint32_t PKA_GetOptBitSize_u8(uint32_t byteNumber, uint8_t msb);
00285 uint32_t PKA_GetBitSize_u32(uint32_t wordNumber);
00286 uint32_t PKA_GetArraySize_u8(uint32_t bitSize);
00287 void PKA_Memcpy_u32_to_u8(uint8_t dst[], __IO const uint32_t src[], size_t n);
00288 void PKA_Memcpy_u8_to_u32(__IO uint32_t dst[], const uint8_t src[], size_t n);
00289 void PKA_Memcpy_u32_to_u32(__IO uint32_t dst[], __IO const uint32_t src[], size_t n);
00290 HAL_StatusTypeDef PKA_Process(PKA_HandleTypeDef *hpka, uint32_t mode, uint32_t Timeout);
00291 HAL_StatusTypeDef PKA_Process_IT(PKA_HandleTypeDef *hpka, uint32_t mode);
00292 void PKA_ModExp_Set(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in);
00293 void PKA_ModExpFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in);
00294 void PKA_ECDSASign_Set(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in);
00295 void PKA_ECDSAVerif_Set(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in);
00296 void PKA_RSACRTExp_Set(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in);
00297 void PKA_PointCheck_Set(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in);
00298 void PKA_ECCMul_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in);
00299 void PKA_ECCMulFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulFastModeInTypeDef *in);
00300 void PKA_ModRed_Set(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in);
00301 void PKA_ModInv_Set(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in);
00302 void PKA_MontgomeryParam_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint8_t *pOp1);
00303 void PKA_ARI_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint32_t *pOp1, const uint32_t *pOp2,
00304                  const uint8_t *pOp3);
00305 /**
00306   * @}
00307   */
00308 
00309 /* Exported functions --------------------------------------------------------*/
00310 
00311 /** @defgroup PKA_Exported_Functions PKA Exported Functions
00312   * @{
00313   */
00314 
00315 /** @defgroup PKA_Exported_Functions_Group1 Initialization and de-initialization functions
00316   * @brief    Initialization and de-initialization functions
00317   *
00318 @verbatim
00319  ===============================================================================
00320              ##### Initialization and de-initialization functions  #####
00321  ===============================================================================
00322     [..]  This subsection provides a set of functions allowing to initialize and
00323           deinitialize the PKAx peripheral:
00324 
00325       (+) User must implement HAL_PKA_MspInit() function in which he configures
00326           all related peripherals resources (CLOCK, IT and NVIC ).
00327 
00328       (+) Call the function HAL_PKA_Init() to configure the device.
00329 
00330       (+) Call the function HAL_PKA_DeInit() to restore the default configuration
00331           of the selected PKAx peripheral.
00332 
00333 @endverbatim
00334   * @{
00335   */
00336 
00337 /**
00338   * @brief  Initialize the PKA according to the specified
00339   *         parameters in the PKA_InitTypeDef and initialize the associated handle.
00340   * @param  hpka PKA handle
00341   * @retval HAL status
00342   */
00343 HAL_StatusTypeDef HAL_PKA_Init(PKA_HandleTypeDef *hpka)
00344 {
00345   HAL_StatusTypeDef err = HAL_OK;
00346   uint32_t tickstart;
00347 
00348   /* Check the PKA handle allocation */
00349   if (hpka != NULL)
00350   {
00351     /* Check the parameters */
00352     assert_param(IS_PKA_ALL_INSTANCE(hpka->Instance));
00353 
00354     if (hpka->State == HAL_PKA_STATE_RESET)
00355     {
00356 
00357 #if (USE_HAL_PKA_REGISTER_CALLBACKS == 1)
00358       /* Init the PKA Callback settings */
00359       hpka->OperationCpltCallback = HAL_PKA_OperationCpltCallback; /* Legacy weak OperationCpltCallback */
00360       hpka->ErrorCallback         = HAL_PKA_ErrorCallback;         /* Legacy weak ErrorCallback         */
00361 
00362       if (hpka->MspInitCallback == NULL)
00363       {
00364         hpka->MspInitCallback = HAL_PKA_MspInit; /* Legacy weak MspInit  */
00365       }
00366 
00367       /* Init the low level hardware */
00368       hpka->MspInitCallback(hpka);
00369 #else
00370       /* Init the low level hardware */
00371       HAL_PKA_MspInit(hpka);
00372 #endif /* USE_HAL_PKA_REGISTER_CALLBACKS */
00373     }
00374 
00375     /* Set the state to busy */
00376     hpka->State = HAL_PKA_STATE_BUSY;
00377 
00378     /* Get current tick */
00379     tickstart = HAL_GetTick();
00380 
00381     /* Reset the control register and enable the PKA (wait the end of PKA RAM erase) */
00382     while ((hpka->Instance->CR & PKA_CR_EN) != PKA_CR_EN)
00383     {
00384       hpka->Instance->CR = PKA_CR_EN;
00385 
00386       /* Check the Timeout */
00387       if ((HAL_GetTick() - tickstart) > PKA_RAM_ERASE_TIMEOUT)
00388       {
00389         /* Set timeout status */
00390         err = HAL_TIMEOUT;
00391         break;
00392       }
00393     }
00394 
00395     if (err == HAL_OK)
00396     {
00397       /* Reset any pending flag */
00398       SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC);
00399 
00400       /* Initialize the error code */
00401       hpka->ErrorCode = HAL_PKA_ERROR_NONE;
00402 
00403       /* Set the state to ready */
00404       hpka->State = HAL_PKA_STATE_READY;
00405     }
00406     else
00407     {
00408       /* Set the error code to timeout error */
00409       hpka->ErrorCode = HAL_PKA_ERROR_TIMEOUT;
00410 
00411       /* Set the state to error */
00412       hpka->State = HAL_PKA_STATE_ERROR;
00413     }
00414   }
00415   else
00416   {
00417     err = HAL_ERROR;
00418   }
00419 
00420   return err;
00421 }
00422 
00423 /**
00424   * @brief  DeInitialize the PKA peripheral.
00425   * @param  hpka PKA handle
00426   * @retval HAL status
00427   */
00428 HAL_StatusTypeDef HAL_PKA_DeInit(PKA_HandleTypeDef *hpka)
00429 {
00430   HAL_StatusTypeDef err = HAL_OK;
00431 
00432   /* Check the PKA handle allocation */
00433   if (hpka != NULL)
00434   {
00435     /* Check the parameters */
00436     assert_param(IS_PKA_ALL_INSTANCE(hpka->Instance));
00437 
00438     /* Set the state to busy */
00439     hpka->State = HAL_PKA_STATE_BUSY;
00440 
00441     /* Reset the control register */
00442     /* This abort any operation in progress (PKA RAM content is not guaranteed in this case) */
00443     hpka->Instance->CR = 0;
00444 
00445     /* Reset any pending flag */
00446     SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC);
00447 
00448 #if (USE_HAL_PKA_REGISTER_CALLBACKS == 1)
00449     if (hpka->MspDeInitCallback == NULL)
00450     {
00451       hpka->MspDeInitCallback = HAL_PKA_MspDeInit; /* Legacy weak MspDeInit  */
00452     }
00453 
00454     /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00455     hpka->MspDeInitCallback(hpka);
00456 #else
00457     /* DeInit the low level hardware: CLOCK, NVIC */
00458     HAL_PKA_MspDeInit(hpka);
00459 #endif /* USE_HAL_PKA_REGISTER_CALLBACKS */
00460 
00461     /* Reset the error code */
00462     hpka->ErrorCode = HAL_PKA_ERROR_NONE;
00463 
00464     /* Reset the state */
00465     hpka->State = HAL_PKA_STATE_RESET;
00466   }
00467   else
00468   {
00469     err = HAL_ERROR;
00470   }
00471 
00472   return err;
00473 }
00474 
00475 /**
00476   * @brief  Initialize the PKA MSP.
00477   * @param  hpka PKA handle
00478   * @retval None
00479   */
00480 __weak void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka)
00481 {
00482   /* Prevent unused argument(s) compilation warning */
00483   UNUSED(hpka);
00484 
00485   /* NOTE : This function should not be modified, when the callback is needed,
00486             the HAL_PKA_MspInit can be implemented in the user file
00487    */
00488 }
00489 
00490 /**
00491   * @brief  DeInitialize the PKA MSP.
00492   * @param  hpka PKA handle
00493   * @retval None
00494   */
00495 __weak void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka)
00496 {
00497   /* Prevent unused argument(s) compilation warning */
00498   UNUSED(hpka);
00499 
00500   /* NOTE : This function should not be modified, when the callback is needed,
00501             the HAL_PKA_MspDeInit can be implemented in the user file
00502    */
00503 }
00504 
00505 #if (USE_HAL_PKA_REGISTER_CALLBACKS == 1)
00506 /**
00507   * @brief  Register a User PKA Callback
00508   *         To be used instead of the weak predefined callback
00509   * @param  hpka Pointer to a PKA_HandleTypeDef structure that contains
00510   *                the configuration information for the specified PKA.
00511   * @param  CallbackID ID of the callback to be registered
00512   *         This parameter can be one of the following values:
00513   *          @arg @ref HAL_PKA_OPERATION_COMPLETE_CB_ID End of operation callback ID
00514   *          @arg @ref HAL_PKA_ERROR_CB_ID Error callback ID
00515   *          @arg @ref HAL_PKA_MSPINIT_CB_ID MspInit callback ID
00516   *          @arg @ref HAL_PKA_MSPDEINIT_CB_ID MspDeInit callback ID
00517   * @param  pCallback pointer to the Callback function
00518   * @retval HAL status
00519   */
00520 HAL_StatusTypeDef HAL_PKA_RegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID,
00521                                            pPKA_CallbackTypeDef pCallback)
00522 {
00523   HAL_StatusTypeDef status = HAL_OK;
00524 
00525   if (pCallback == NULL)
00526   {
00527     /* Update the error code */
00528     hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00529 
00530     return HAL_ERROR;
00531   }
00532 
00533   if (HAL_PKA_STATE_READY == hpka->State)
00534   {
00535     switch (CallbackID)
00536     {
00537       case HAL_PKA_OPERATION_COMPLETE_CB_ID :
00538         hpka->OperationCpltCallback = pCallback;
00539         break;
00540 
00541       case HAL_PKA_ERROR_CB_ID :
00542         hpka->ErrorCallback = pCallback;
00543         break;
00544 
00545       case HAL_PKA_MSPINIT_CB_ID :
00546         hpka->MspInitCallback = pCallback;
00547         break;
00548 
00549       case HAL_PKA_MSPDEINIT_CB_ID :
00550         hpka->MspDeInitCallback = pCallback;
00551         break;
00552 
00553       default :
00554         /* Update the error code */
00555         hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00556 
00557         /* Return error status */
00558         status = HAL_ERROR;
00559         break;
00560     }
00561   }
00562   else if (HAL_PKA_STATE_RESET == hpka->State)
00563   {
00564     switch (CallbackID)
00565     {
00566       case HAL_PKA_MSPINIT_CB_ID :
00567         hpka->MspInitCallback = pCallback;
00568         break;
00569 
00570       case HAL_PKA_MSPDEINIT_CB_ID :
00571         hpka->MspDeInitCallback = pCallback;
00572         break;
00573 
00574       default :
00575         /* Update the error code */
00576         hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00577 
00578         /* Return error status */
00579         status = HAL_ERROR;
00580         break;
00581     }
00582   }
00583   else
00584   {
00585     /* Update the error code */
00586     hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00587 
00588     /* Return error status */
00589     status =  HAL_ERROR;
00590   }
00591 
00592   return status;
00593 }
00594 
00595 /**
00596   * @brief  Unregister a PKA Callback
00597   *         PKA callback is redirected to the weak predefined callback
00598   * @param  hpka Pointer to a PKA_HandleTypeDef structure that contains
00599   *                the configuration information for the specified PKA.
00600   * @param  CallbackID ID of the callback to be unregistered
00601   *         This parameter can be one of the following values:
00602   *          @arg @ref HAL_PKA_OPERATION_COMPLETE_CB_ID End of operation callback ID
00603   *          @arg @ref HAL_PKA_ERROR_CB_ID Error callback ID
00604   *          @arg @ref HAL_PKA_MSPINIT_CB_ID MspInit callback ID
00605   *          @arg @ref HAL_PKA_MSPDEINIT_CB_ID MspDeInit callback ID
00606   * @retval HAL status
00607   */
00608 HAL_StatusTypeDef HAL_PKA_UnRegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID)
00609 {
00610   HAL_StatusTypeDef status = HAL_OK;
00611 
00612   if (HAL_PKA_STATE_READY == hpka->State)
00613   {
00614     switch (CallbackID)
00615     {
00616       case HAL_PKA_OPERATION_COMPLETE_CB_ID :
00617         hpka->OperationCpltCallback = HAL_PKA_OperationCpltCallback; /* Legacy weak OperationCpltCallback */
00618         break;
00619 
00620       case HAL_PKA_ERROR_CB_ID :
00621         hpka->ErrorCallback = HAL_PKA_ErrorCallback;                 /* Legacy weak ErrorCallback        */
00622         break;
00623 
00624       case HAL_PKA_MSPINIT_CB_ID :
00625         hpka->MspInitCallback = HAL_PKA_MspInit;                     /* Legacy weak MspInit              */
00626         break;
00627 
00628       case HAL_PKA_MSPDEINIT_CB_ID :
00629         hpka->MspDeInitCallback = HAL_PKA_MspDeInit;                 /* Legacy weak MspDeInit            */
00630         break;
00631 
00632       default :
00633         /* Update the error code */
00634         hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00635 
00636         /* Return error status */
00637         status =  HAL_ERROR;
00638         break;
00639     }
00640   }
00641   else if (HAL_PKA_STATE_RESET == hpka->State)
00642   {
00643     switch (CallbackID)
00644     {
00645       case HAL_PKA_MSPINIT_CB_ID :
00646         hpka->MspInitCallback = HAL_PKA_MspInit;                   /* Legacy weak MspInit              */
00647         break;
00648 
00649       case HAL_PKA_MSPDEINIT_CB_ID :
00650         hpka->MspDeInitCallback = HAL_PKA_MspDeInit;               /* Legacy weak MspDeInit            */
00651         break;
00652 
00653       default :
00654         /* Update the error code */
00655         hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00656 
00657         /* Return error status */
00658         status =  HAL_ERROR;
00659         break;
00660     }
00661   }
00662   else
00663   {
00664     /* Update the error code */
00665     hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK;
00666 
00667     /* Return error status */
00668     status =  HAL_ERROR;
00669   }
00670 
00671   return status;
00672 }
00673 
00674 #endif /* USE_HAL_PKA_REGISTER_CALLBACKS */
00675 
00676 /**
00677   * @}
00678   */
00679 
00680 /** @defgroup PKA_Exported_Functions_Group2 IO operation functions
00681   * @brief    IO operation functions
00682   *
00683 @verbatim
00684  ===============================================================================
00685                       ##### IO operation functions #####
00686  ===============================================================================
00687     [..]
00688     This subsection provides a set of functions allowing to manage the PKA operations.
00689 
00690     (#) There are two modes of operation:
00691 
00692        (++) Blocking mode : The operation is performed in the polling mode.
00693             These functions return when data operation is completed.
00694        (++) No-Blocking mode : The operation is performed using Interrupts.
00695             These functions return immediately.
00696             The end of the operation is indicated by HAL_PKA_ErrorCallback in case of error.
00697             The end of the operation is indicated by HAL_PKA_OperationCpltCallback in case of success.
00698             To stop any operation in interrupt mode, use HAL_PKA_Abort().
00699 
00700     (#) Blocking mode functions are :
00701 
00702         (++) HAL_PKA_ModExp()
00703         (++) HAL_PKA_ModExpFastMode()
00704         (++) HAL_PKA_ModExp_GetResult();
00705 
00706         (++) HAL_PKA_ECDSASign()
00707         (++) HAL_PKA_ECDSASign_GetResult();
00708 
00709         (++) HAL_PKA_ECDSAVerif()
00710         (++) HAL_PKA_ECDSAVerif_IsValidSignature();
00711 
00712         (++) HAL_PKA_RSACRTExp()
00713         (++) HAL_PKA_RSACRTExp_GetResult();
00714 
00715         (++) HAL_PKA_PointCheck()
00716         (++) HAL_PKA_PointCheck_IsOnCurve();
00717 
00718         (++) HAL_PKA_ECCMul()
00719         (++) HAL_PKA_ECCMulFastMode()
00720         (++) HAL_PKA_ECCMul_GetResult();
00721 
00722 
00723         (++) HAL_PKA_Add()
00724         (++) HAL_PKA_Sub()
00725         (++) HAL_PKA_Cmp()
00726         (++) HAL_PKA_Mul()
00727         (++) HAL_PKA_ModAdd()
00728         (++) HAL_PKA_ModSub()
00729         (++) HAL_PKA_ModInv()
00730         (++) HAL_PKA_ModRed()
00731         (++) HAL_PKA_MontgomeryMul()
00732         (++) HAL_PKA_Arithmetic_GetResult(P);
00733 
00734         (++) HAL_PKA_MontgomeryParam()
00735         (++) HAL_PKA_MontgomeryParam_GetResult();
00736 
00737     (#) No-Blocking mode functions with Interrupt are :
00738 
00739         (++) HAL_PKA_ModExp_IT();
00740         (++) HAL_PKA_ModExpFastMode_IT();
00741         (++) HAL_PKA_ModExp_GetResult();
00742 
00743         (++) HAL_PKA_ECDSASign_IT();
00744         (++) HAL_PKA_ECDSASign_GetResult();
00745 
00746         (++) HAL_PKA_ECDSAVerif_IT();
00747         (++) HAL_PKA_ECDSAVerif_IsValidSignature();
00748 
00749         (++) HAL_PKA_RSACRTExp_IT();
00750         (++) HAL_PKA_RSACRTExp_GetResult();
00751 
00752         (++) HAL_PKA_PointCheck_IT();
00753         (++) HAL_PKA_PointCheck_IsOnCurve();
00754 
00755         (++) HAL_PKA_ECCMul_IT();
00756         (++) HAL_PKA_ECCMulFastMode_IT();
00757         (++) HAL_PKA_ECCMul_GetResult();
00758 
00759         (++) HAL_PKA_Add_IT();
00760         (++) HAL_PKA_Sub_IT();
00761         (++) HAL_PKA_Cmp_IT();
00762         (++) HAL_PKA_Mul_IT();
00763         (++) HAL_PKA_ModAdd_IT();
00764         (++) HAL_PKA_ModSub_IT();
00765         (++) HAL_PKA_ModInv_IT();
00766         (++) HAL_PKA_ModRed_IT();
00767         (++) HAL_PKA_MontgomeryMul_IT();
00768         (++) HAL_PKA_Arithmetic_GetResult();
00769 
00770         (++) HAL_PKA_MontgomeryParam_IT();
00771         (++) HAL_PKA_MontgomeryParam_GetResult();
00772 
00773         (++) HAL_PKA_Abort();
00774 
00775 @endverbatim
00776   * @{
00777   */
00778 
00779 /**
00780   * @brief  Modular exponentiation in blocking mode.
00781   * @param  hpka PKA handle
00782   * @param  in Input information
00783   * @param  Timeout Timeout duration
00784   * @retval HAL status
00785   */
00786 HAL_StatusTypeDef HAL_PKA_ModExp(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in, uint32_t Timeout)
00787 {
00788   /* Set input parameter in PKA RAM */
00789   PKA_ModExp_Set(hpka, in);
00790 
00791   /* Start the operation */
00792   return PKA_Process(hpka, PKA_MODE_MODULAR_EXP, Timeout);
00793 }
00794 
00795 /**
00796   * @brief  Modular exponentiation in non-blocking mode with Interrupt.
00797   * @param  hpka PKA handle
00798   * @param  in Input information
00799   * @retval HAL status
00800   */
00801 HAL_StatusTypeDef HAL_PKA_ModExp_IT(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in)
00802 {
00803   /* Set input parameter in PKA RAM */
00804   PKA_ModExp_Set(hpka, in);
00805 
00806   /* Start the operation */
00807   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_EXP);
00808 }
00809 
00810 /**
00811   * @brief  Modular exponentiation in blocking mode.
00812   * @param  hpka PKA handle
00813   * @param  in Input information
00814   * @param  Timeout Timeout duration
00815   * @retval HAL status
00816   */
00817 HAL_StatusTypeDef HAL_PKA_ModExpFastMode(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in, uint32_t Timeout)
00818 {
00819   /* Set input parameter in PKA RAM */
00820   PKA_ModExpFastMode_Set(hpka, in);
00821 
00822   /* Start the operation */
00823   return PKA_Process(hpka, PKA_MODE_MODULAR_EXP_FAST_MODE, Timeout);
00824 }
00825 
00826 /**
00827   * @brief  Modular exponentiation in non-blocking mode with Interrupt.
00828   * @param  hpka PKA handle
00829   * @param  in Input information
00830   * @retval HAL status
00831   */
00832 HAL_StatusTypeDef HAL_PKA_ModExpFastMode_IT(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in)
00833 {
00834   /* Set input parameter in PKA RAM */
00835   PKA_ModExpFastMode_Set(hpka, in);
00836 
00837   /* Start the operation */
00838   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_EXP_FAST_MODE);
00839 }
00840 
00841 
00842 /**
00843   * @brief  Retrieve operation result.
00844   * @param  hpka PKA handle
00845   * @param  pRes Output buffer
00846   * @retval HAL status
00847   */
00848 void HAL_PKA_ModExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes)
00849 {
00850   uint32_t size;
00851 
00852   /* Indicate to the user the final size */
00853   size = (hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] + 7UL) / 8UL;
00854 
00855   /* Move the result to appropriate location (indicated in out parameter) */
00856   PKA_Memcpy_u32_to_u8(pRes, &hpka->Instance->RAM[PKA_MODULAR_EXP_OUT_SM_ALGO_ACC1], size);
00857 }
00858 
00859 /**
00860   * @brief  Sign a message using elliptic curves over prime fields in blocking mode.
00861   * @param  hpka PKA handle
00862   * @param  in Input information
00863   * @param  Timeout Timeout duration
00864   * @retval HAL status
00865   */
00866 HAL_StatusTypeDef HAL_PKA_ECDSASign(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in, uint32_t Timeout)
00867 {
00868   /* Set input parameter in PKA RAM */
00869   PKA_ECDSASign_Set(hpka, in);
00870 
00871   /* Start the operation */
00872   return PKA_Process(hpka, PKA_MODE_ECDSA_SIGNATURE, Timeout);
00873 }
00874 
00875 /**
00876   * @brief  Sign a message using elliptic curves over prime fields in non-blocking mode with Interrupt.
00877   * @param  hpka PKA handle
00878   * @param  in Input information
00879   * @retval HAL status
00880   */
00881 HAL_StatusTypeDef HAL_PKA_ECDSASign_IT(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in)
00882 {
00883   /* Set input parameter in PKA RAM */
00884   PKA_ECDSASign_Set(hpka, in);
00885 
00886   /* Start the operation */
00887   return PKA_Process_IT(hpka, PKA_MODE_ECDSA_SIGNATURE);
00888 }
00889 
00890 /**
00891   * @brief  Retrieve operation result.
00892   * @param  hpka PKA handle
00893   * @param  out Output information
00894   * @param  outExt Additional Output information (facultative)
00895   */
00896 void HAL_PKA_ECDSASign_GetResult(PKA_HandleTypeDef *hpka, PKA_ECDSASignOutTypeDef *out,
00897                                  PKA_ECDSASignOutExtParamTypeDef *outExt)
00898 {
00899   uint32_t size;
00900 
00901   size = (hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_MOD_NB_BITS] + 7UL) / 8UL;
00902 
00903   if (out != NULL)
00904   {
00905     PKA_Memcpy_u32_to_u8(out->RSign, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_SIGNATURE_R], size);
00906     PKA_Memcpy_u32_to_u8(out->SSign, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_SIGNATURE_S], size);
00907   }
00908 
00909   /* If user requires the additional information */
00910   if (outExt != NULL)
00911   {
00912     /* Move the result to appropriate location (indicated in outExt parameter) */
00913     PKA_Memcpy_u32_to_u8(outExt->ptX, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_FINAL_POINT_X], size);
00914     PKA_Memcpy_u32_to_u8(outExt->ptY, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_FINAL_POINT_Y], size);
00915   }
00916 }
00917 
00918 /**
00919   * @brief  Verify the validity of a signature using elliptic curves over prime fields in blocking mode.
00920   * @param  hpka PKA handle
00921   * @param  in Input information
00922   * @param  Timeout Timeout duration
00923   * @retval HAL status
00924   */
00925 HAL_StatusTypeDef HAL_PKA_ECDSAVerif(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in, uint32_t Timeout)
00926 {
00927   /* Set input parameter in PKA RAM */
00928   PKA_ECDSAVerif_Set(hpka, in);
00929 
00930   /* Start the operation */
00931   return PKA_Process(hpka, PKA_MODE_ECDSA_VERIFICATION, Timeout);
00932 }
00933 
00934 /**
00935   * @brief  Verify the validity of a signature using elliptic curves
00936   *         over prime fields in non-blocking mode with Interrupt.
00937   * @param  hpka PKA handle
00938   * @param  in Input information
00939   * @retval HAL status
00940   */
00941 HAL_StatusTypeDef HAL_PKA_ECDSAVerif_IT(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in)
00942 {
00943   /* Set input parameter in PKA RAM */
00944   PKA_ECDSAVerif_Set(hpka, in);
00945 
00946   /* Start the operation */
00947   return PKA_Process_IT(hpka, PKA_MODE_ECDSA_VERIFICATION);
00948 }
00949 
00950 /**
00951   * @brief  Return the result of the ECDSA verification operation.
00952   * @param  hpka PKA handle
00953   * @retval 1 if signature is verified, 0 in other case
00954   */
00955 uint32_t HAL_PKA_ECDSAVerif_IsValidSignature(PKA_HandleTypeDef const *const hpka)
00956 {
00957   /* Invert the state of the PKA RAM bit containing the result of the operation */
00958   return (hpka->Instance->RAM[PKA_ECDSA_VERIF_OUT_RESULT] == 0UL) ? 1UL : 0UL;
00959 }
00960 
00961 /**
00962   * @brief  RSA CRT exponentiation in blocking mode.
00963   * @param  hpka PKA handle
00964   * @param  in Input information
00965   * @param  Timeout Timeout duration
00966   * @retval HAL status
00967   */
00968 HAL_StatusTypeDef HAL_PKA_RSACRTExp(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in, uint32_t Timeout)
00969 {
00970   /* Set input parameter in PKA RAM */
00971   PKA_RSACRTExp_Set(hpka, in);
00972 
00973   /* Start the operation */
00974   return PKA_Process(hpka, PKA_MODE_RSA_CRT_EXP, Timeout);
00975 }
00976 
00977 /**
00978   * @brief  RSA CRT exponentiation in non-blocking mode with Interrupt.
00979   * @param  hpka PKA handle
00980   * @param  in Input information
00981   * @retval HAL status
00982   */
00983 HAL_StatusTypeDef HAL_PKA_RSACRTExp_IT(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in)
00984 {
00985   /* Set input parameter in PKA RAM */
00986   PKA_RSACRTExp_Set(hpka, in);
00987 
00988   /* Start the operation */
00989   return PKA_Process_IT(hpka, PKA_MODE_RSA_CRT_EXP);
00990 }
00991 
00992 /**
00993   * @brief  Retrieve operation result.
00994   * @param  hpka PKA handle
00995   * @param  pRes Pointer to memory location to receive the result of the operation
00996   * @retval HAL status
00997   */
00998 void HAL_PKA_RSACRTExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes)
00999 {
01000   uint32_t size;
01001 
01002   /* Move the result to appropriate location (indicated in out parameter) */
01003   size = (hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_MOD_NB_BITS] + 7UL) / 8UL;
01004 
01005   PKA_Memcpy_u32_to_u8(pRes, &hpka->Instance->RAM[PKA_RSA_CRT_EXP_OUT_RESULT], size);
01006 }
01007 
01008 /**
01009   * @brief  Point on elliptic curve check in blocking mode.
01010   * @param  hpka PKA handle
01011   * @param  in Input information
01012   * @param  Timeout Timeout duration
01013   * @retval HAL status
01014   */
01015 HAL_StatusTypeDef HAL_PKA_PointCheck(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in, uint32_t Timeout)
01016 {
01017   /* Set input parameter in PKA RAM */
01018   PKA_PointCheck_Set(hpka, in);
01019 
01020   /* Start the operation */
01021   return PKA_Process(hpka, PKA_MODE_POINT_CHECK, Timeout);
01022 }
01023 
01024 /**
01025   * @brief  Point on elliptic curve check in non-blocking mode with Interrupt.
01026   * @param  hpka PKA handle
01027   * @param  in Input information
01028   * @retval HAL status
01029   */
01030 HAL_StatusTypeDef HAL_PKA_PointCheck_IT(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in)
01031 {
01032   /* Set input parameter in PKA RAM */
01033   PKA_PointCheck_Set(hpka, in);
01034 
01035   /* Start the operation */
01036   return PKA_Process_IT(hpka, PKA_MODE_POINT_CHECK);
01037 }
01038 
01039 /**
01040   * @brief  Return the result of the point check operation.
01041   * @param  hpka PKA handle
01042   * @retval 1 if point is on curve, 0 in other case
01043   */
01044 uint32_t HAL_PKA_PointCheck_IsOnCurve(PKA_HandleTypeDef const *const hpka)
01045 {
01046 #define PKA_POINT_IS_ON_CURVE 0UL
01047   /* Invert the value of the PKA RAM containing the result of the operation */
01048   return (hpka->Instance->RAM[PKA_POINT_CHECK_OUT_ERROR] == PKA_POINT_IS_ON_CURVE) ? 1UL : 0UL;
01049 }
01050 
01051 /**
01052   * @brief  ECC scalar multiplication in blocking mode.
01053   * @param  hpka PKA handle
01054   * @param  in Input information
01055   * @param  Timeout Timeout duration
01056   * @retval HAL status
01057   */
01058 HAL_StatusTypeDef HAL_PKA_ECCMul(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in, uint32_t Timeout)
01059 {
01060   /* Set input parameter in PKA RAM */
01061   PKA_ECCMul_Set(hpka, in);
01062 
01063   /* Start the operation */
01064   return PKA_Process(hpka, PKA_MODE_ECC_MUL, Timeout);
01065 }
01066 
01067 /**
01068   * @brief  ECC scalar multiplication in non-blocking mode with Interrupt.
01069   * @param  hpka PKA handle
01070   * @param  in Input information
01071   * @retval HAL status
01072   */
01073 HAL_StatusTypeDef HAL_PKA_ECCMul_IT(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in)
01074 {
01075   /* Set input parameter in PKA RAM */
01076   PKA_ECCMul_Set(hpka, in);
01077 
01078   /* Start the operation */
01079   return PKA_Process_IT(hpka, PKA_MODE_ECC_MUL);
01080 }
01081 /**
01082   * @brief  ECC scalar multiplication in blocking mode.
01083   * @param  hpka PKA handle
01084   * @param  in Input information
01085   * @param  Timeout Timeout duration
01086   * @retval HAL status
01087   */
01088 HAL_StatusTypeDef HAL_PKA_ECCMulFastMode(PKA_HandleTypeDef *hpka, PKA_ECCMulFastModeInTypeDef *in, uint32_t Timeout)
01089 {
01090   /* Set input parameter in PKA RAM */
01091   PKA_ECCMulFastMode_Set(hpka, in);
01092 
01093   /* Start the operation */
01094   return PKA_Process(hpka, PKA_MODE_ECC_MUL_FAST_MODE, Timeout);
01095 }
01096 
01097 /**
01098   * @brief  ECC scalar multiplication in non-blocking mode with Interrupt.
01099   * @param  hpka PKA handle
01100   * @param  in Input information
01101   * @retval HAL status
01102   */
01103 HAL_StatusTypeDef HAL_PKA_ECCMulFastMode_IT(PKA_HandleTypeDef *hpka, PKA_ECCMulFastModeInTypeDef *in)
01104 {
01105   /* Set input parameter in PKA RAM */
01106   PKA_ECCMulFastMode_Set(hpka, in);
01107 
01108   /* Start the operation */
01109   return PKA_Process_IT(hpka, PKA_MODE_ECC_MUL_FAST_MODE);
01110 }
01111 /**
01112   * @brief  Retrieve operation result.
01113   * @param  hpka PKA handle
01114   * @param  out Output information
01115   * @retval HAL status
01116   */
01117 void HAL_PKA_ECCMul_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCMulOutTypeDef *out)
01118 {
01119   uint32_t size;
01120 
01121   /* Retrieve the size of the array from the PKA RAM */
01122   size = (hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS] + 7UL) / 8UL;
01123 
01124   /* If a destination buffer is provided */
01125   if (out != NULL)
01126   {
01127     /* Move the result to appropriate location (indicated in out parameter) */
01128     PKA_Memcpy_u32_to_u8(out->ptX, &hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_RESULT_X], size);
01129     PKA_Memcpy_u32_to_u8(out->ptY, &hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_RESULT_Y], size);
01130   }
01131 }
01132 
01133 /**
01134   * @brief  Arithmetic addition in blocking mode.
01135   * @param  hpka PKA handle
01136   * @param  in Input information
01137   * @param  Timeout Timeout duration
01138   * @retval HAL status
01139   */
01140 HAL_StatusTypeDef HAL_PKA_Add(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in, uint32_t Timeout)
01141 {
01142   /* Set input parameter in PKA RAM */
01143   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01144 
01145   /* Start the operation */
01146   return PKA_Process(hpka, PKA_MODE_ARITHMETIC_ADD, Timeout);
01147 }
01148 
01149 /**
01150   * @brief  Arithmetic addition in non-blocking mode with Interrupt.
01151   * @param  hpka PKA handle
01152   * @param  in Input information
01153   * @retval HAL status
01154   */
01155 HAL_StatusTypeDef HAL_PKA_Add_IT(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in)
01156 {
01157   /* Set input parameter in PKA RAM */
01158   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01159 
01160   /* Start the operation */
01161   return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_ADD);
01162 }
01163 
01164 /**
01165   * @brief  Arithmetic subtraction in blocking mode.
01166   * @param  hpka PKA handle
01167   * @param  in Input information
01168   * @param  Timeout Timeout duration
01169   * @retval HAL status
01170   */
01171 HAL_StatusTypeDef HAL_PKA_Sub(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in, uint32_t Timeout)
01172 {
01173   /* Set input parameter in PKA RAM */
01174   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01175 
01176   /* Start the operation */
01177   return PKA_Process(hpka, PKA_MODE_ARITHMETIC_SUB, Timeout);
01178 }
01179 
01180 /**
01181   * @brief  Arithmetic subtraction in non-blocking mode with Interrupt.
01182   * @param  hpka PKA handle
01183   * @param  in Input information
01184   * @retval HAL status
01185   */
01186 HAL_StatusTypeDef HAL_PKA_Sub_IT(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in)
01187 {
01188   /* Set input parameter in PKA RAM */
01189   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01190 
01191   /* Start the operation */
01192   return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_SUB);
01193 }
01194 
01195 /**
01196   * @brief  Arithmetic multiplication in blocking mode.
01197   * @param  hpka PKA handle
01198   * @param  in Input information
01199   * @param  Timeout Timeout duration
01200   * @retval HAL status
01201   */
01202 HAL_StatusTypeDef HAL_PKA_Mul(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in, uint32_t Timeout)
01203 {
01204   /* Set input parameter in PKA RAM */
01205   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01206 
01207   /* Start the operation */
01208   return PKA_Process(hpka, PKA_MODE_ARITHMETIC_MUL, Timeout);
01209 }
01210 
01211 /**
01212   * @brief  Arithmetic multiplication in non-blocking mode with Interrupt.
01213   * @param  hpka PKA handle
01214   * @param  in Input information
01215   * @retval HAL status
01216   */
01217 HAL_StatusTypeDef HAL_PKA_Mul_IT(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in)
01218 {
01219   /* Set input parameter in PKA RAM */
01220   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01221 
01222   /* Start the operation */
01223   return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_MUL);
01224 }
01225 
01226 /**
01227   * @brief  Comparison in blocking mode.
01228   * @param  hpka PKA handle
01229   * @param  in Input information
01230   * @param  Timeout Timeout duration
01231   * @retval HAL status
01232   */
01233 HAL_StatusTypeDef HAL_PKA_Cmp(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in, uint32_t Timeout)
01234 {
01235   /* Set input parameter in PKA RAM */
01236   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01237 
01238   /* Start the operation */
01239   return PKA_Process(hpka, PKA_MODE_COMPARISON, Timeout);
01240 }
01241 
01242 /**
01243   * @brief  Comparison in non-blocking mode with Interrupt.
01244   * @param  hpka PKA handle
01245   * @param  in Input information
01246   * @retval HAL status
01247   */
01248 HAL_StatusTypeDef HAL_PKA_Cmp_IT(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in)
01249 {
01250   /* Set input parameter in PKA RAM */
01251   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL);
01252 
01253   /* Start the operation */
01254   return PKA_Process_IT(hpka, PKA_MODE_COMPARISON);
01255 }
01256 
01257 /**
01258   * @brief  Modular addition in blocking mode.
01259   * @param  hpka PKA handle
01260   * @param  in Input information
01261   * @param  Timeout Timeout duration
01262   * @retval HAL status
01263   */
01264 HAL_StatusTypeDef HAL_PKA_ModAdd(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in, uint32_t Timeout)
01265 {
01266   /* Set input parameter in PKA RAM */
01267   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01268 
01269   /* Start the operation */
01270   return PKA_Process(hpka, PKA_MODE_MODULAR_ADD, Timeout);
01271 }
01272 
01273 /**
01274   * @brief  Modular addition in non-blocking mode with Interrupt.
01275   * @param  hpka PKA handle
01276   * @param  in Input information
01277   * @retval HAL status
01278   */
01279 HAL_StatusTypeDef HAL_PKA_ModAdd_IT(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in)
01280 {
01281   /* Set input parameter in PKA RAM */
01282   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01283 
01284   /* Start the operation */
01285   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_ADD);
01286 }
01287 
01288 /**
01289   * @brief  Modular inversion in blocking mode.
01290   * @param  hpka PKA handle
01291   * @param  in Input information
01292   * @param  Timeout Timeout duration
01293   * @retval HAL status
01294   */
01295 HAL_StatusTypeDef HAL_PKA_ModInv(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in, uint32_t Timeout)
01296 {
01297   /* Set input parameter in PKA RAM */
01298   PKA_ModInv_Set(hpka, in);
01299 
01300   /* Start the operation */
01301   return PKA_Process(hpka, PKA_MODE_MODULAR_INV, Timeout);
01302 }
01303 
01304 /**
01305   * @brief  Modular inversion in non-blocking mode with Interrupt.
01306   * @param  hpka PKA handle
01307   * @param  in Input information
01308   * @retval HAL status
01309   */
01310 HAL_StatusTypeDef HAL_PKA_ModInv_IT(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in)
01311 {
01312   /* Set input parameter in PKA RAM */
01313   PKA_ModInv_Set(hpka, in);
01314 
01315   /* Start the operation */
01316   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_INV);
01317 }
01318 
01319 /**
01320   * @brief  Modular subtraction in blocking mode.
01321   * @param  hpka PKA handle
01322   * @param  in Input information
01323   * @param  Timeout Timeout duration
01324   * @retval HAL status
01325   */
01326 HAL_StatusTypeDef HAL_PKA_ModSub(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in, uint32_t Timeout)
01327 {
01328   /* Set input parameter in PKA RAM */
01329   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01330 
01331   /* Start the operation */
01332   return PKA_Process(hpka, PKA_MODE_MODULAR_SUB, Timeout);
01333 }
01334 
01335 /**
01336   * @brief  Modular subtraction in non-blocking mode with Interrupt.
01337   * @param  hpka PKA handle
01338   * @param  in Input information
01339   * @retval HAL status
01340   */
01341 HAL_StatusTypeDef HAL_PKA_ModSub_IT(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in)
01342 {
01343   /* Set input parameter in PKA RAM */
01344   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01345 
01346   /* Start the operation */
01347   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_SUB);
01348 }
01349 
01350 /**
01351   * @brief  Modular reduction in blocking mode.
01352   * @param  hpka PKA handle
01353   * @param  in Input information
01354   * @param  Timeout Timeout duration
01355   * @retval HAL status
01356   */
01357 HAL_StatusTypeDef HAL_PKA_ModRed(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in, uint32_t Timeout)
01358 {
01359   /* Set input parameter in PKA RAM */
01360   PKA_ModRed_Set(hpka, in);
01361 
01362   /* Start the operation */
01363   return PKA_Process(hpka, PKA_MODE_MODULAR_RED, Timeout);
01364 }
01365 
01366 /**
01367   * @brief  Modular reduction in non-blocking mode with Interrupt.
01368   * @param  hpka PKA handle
01369   * @param  in Input information
01370   * @retval HAL status
01371   */
01372 HAL_StatusTypeDef HAL_PKA_ModRed_IT(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in)
01373 {
01374   /* Set input parameter in PKA RAM */
01375   PKA_ModRed_Set(hpka, in);
01376 
01377   /* Start the operation */
01378   return PKA_Process_IT(hpka, PKA_MODE_MODULAR_RED);
01379 }
01380 
01381 /**
01382   * @brief  Montgomery multiplication in blocking mode.
01383   * @param  hpka PKA handle
01384   * @param  in Input information
01385   * @param  Timeout Timeout duration
01386   * @retval HAL status
01387   */
01388 HAL_StatusTypeDef HAL_PKA_MontgomeryMul(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in, uint32_t Timeout)
01389 {
01390   /* Set input parameter in PKA RAM */
01391   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01392 
01393   /* Start the operation */
01394   return PKA_Process(hpka, PKA_MODE_MONTGOMERY_MUL, Timeout);
01395 }
01396 
01397 /**
01398   * @brief  Montgomery multiplication in non-blocking mode with Interrupt.
01399   * @param  hpka PKA handle
01400   * @param  in Input information
01401   * @retval HAL status
01402   */
01403 HAL_StatusTypeDef HAL_PKA_MontgomeryMul_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in)
01404 {
01405   /* Set input parameter in PKA RAM */
01406   PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3);
01407 
01408   /* Start the operation */
01409   return PKA_Process_IT(hpka, PKA_MODE_MONTGOMERY_MUL);
01410 }
01411 
01412 /**
01413   * @brief  Retrieve operation result.
01414   * @param  hpka PKA handle
01415   * @param  pRes Pointer to memory location to receive the result of the operation
01416   */
01417 void HAL_PKA_Arithmetic_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes)
01418 {
01419   uint32_t mode = (hpka->Instance->CR & PKA_CR_MODE_Msk) >> PKA_CR_MODE_Pos;
01420   uint32_t size = 0;
01421 
01422   /* Move the result to appropriate location (indicated in pRes parameter) */
01423   switch (mode)
01424   {
01425     case PKA_MODE_ARITHMETIC_SUB:
01426     case PKA_MODE_MODULAR_ADD:
01427     case PKA_MODE_MODULAR_RED:
01428     case PKA_MODE_MODULAR_INV:
01429     case PKA_MODE_MODULAR_SUB:
01430     case PKA_MODE_MONTGOMERY_MUL:
01431       size = hpka->Instance->RAM[1] / 32UL;
01432       break;
01433     case PKA_MODE_ARITHMETIC_ADD:
01434       size = hpka->Instance->RAM[1] / 32UL;
01435 
01436       /* Manage the overflow of the addition */
01437       if (hpka->Instance->RAM[500U + size] != 0UL)
01438       {
01439         size += 1UL;
01440       }
01441 
01442       break;
01443     case PKA_MODE_COMPARISON:
01444       size = 1;
01445       break;
01446     case PKA_MODE_ARITHMETIC_MUL:
01447       size = hpka->Instance->RAM[1] / 32UL * 2UL;
01448       break;
01449     default:
01450       break;
01451   }
01452 
01453   if (pRes != NULL)
01454   {
01455     switch (mode)
01456     {
01457       case PKA_MODE_ARITHMETIC_SUB:
01458       case PKA_MODE_MODULAR_ADD:
01459       case PKA_MODE_MODULAR_RED:
01460       case PKA_MODE_MODULAR_INV:
01461       case PKA_MODE_MODULAR_SUB:
01462       case PKA_MODE_MONTGOMERY_MUL:
01463       case PKA_MODE_ARITHMETIC_ADD:
01464       case PKA_MODE_COMPARISON:
01465       case PKA_MODE_ARITHMETIC_MUL:
01466         PKA_Memcpy_u32_to_u32(pRes, &hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_OUT_RESULT], size);
01467         break;
01468       default:
01469         break;
01470     }
01471   }
01472 }
01473 
01474 /**
01475   * @brief  Montgomery parameter computation in blocking mode.
01476   * @param  hpka PKA handle
01477   * @param  in Input information
01478   * @param  Timeout Timeout duration
01479   * @retval HAL status
01480   */
01481 HAL_StatusTypeDef HAL_PKA_MontgomeryParam(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in, uint32_t Timeout)
01482 {
01483   /* Set input parameter in PKA RAM */
01484   PKA_MontgomeryParam_Set(hpka, in->size, in->pOp1);
01485 
01486   /* Start the operation */
01487   return PKA_Process(hpka, PKA_MODE_MONTGOMERY_PARAM, Timeout);
01488 }
01489 
01490 /**
01491   * @brief  Montgomery parameter computation in non-blocking mode with Interrupt.
01492   * @param  hpka PKA handle
01493   * @param  in Input information
01494   * @retval HAL status
01495   */
01496 HAL_StatusTypeDef HAL_PKA_MontgomeryParam_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in)
01497 {
01498   /* Set input parameter in PKA RAM */
01499   PKA_MontgomeryParam_Set(hpka, in->size, in->pOp1);
01500 
01501   /* Start the operation */
01502   return PKA_Process_IT(hpka, PKA_MODE_MONTGOMERY_PARAM);
01503 }
01504 
01505 
01506 /**
01507   * @brief  Retrieve operation result.
01508   * @param  hpka PKA handle
01509   * @param  pRes pointer to buffer where the result will be copied
01510   * @retval HAL status
01511   */
01512 void HAL_PKA_MontgomeryParam_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes)
01513 {
01514   uint32_t size;
01515 
01516   /* Retrieve the size of the buffer from the PKA RAM */
01517   size = (hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MOD_NB_BITS] + 31UL) / 32UL;
01518 
01519   /* Move the result to appropriate location (indicated in out parameter) */
01520   PKA_Memcpy_u32_to_u32(pRes, &hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_OUT_PARAMETER], size);
01521 }
01522 
01523 /**
01524   * @brief  Abort any ongoing operation.
01525   * @param  hpka PKA handle
01526   * @retval HAL status
01527   */
01528 HAL_StatusTypeDef HAL_PKA_Abort(PKA_HandleTypeDef *hpka)
01529 {
01530   HAL_StatusTypeDef err = HAL_OK;
01531 
01532   /* Clear EN bit */
01533   /* This abort any operation in progress (PKA RAM content is not guaranteed in this case) */
01534   CLEAR_BIT(hpka->Instance->CR, PKA_CR_EN);
01535   SET_BIT(hpka->Instance->CR, PKA_CR_EN);
01536 
01537   /* Reset any pending flag */
01538   SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC);
01539 
01540   /* Reset the error code */
01541   hpka->ErrorCode = HAL_PKA_ERROR_NONE;
01542 
01543   /* Reset the state */
01544   hpka->State = HAL_PKA_STATE_READY;
01545 
01546   return err;
01547 }
01548 
01549 /**
01550   * @brief  Reset the PKA RAM.
01551   * @param  hpka PKA handle
01552   * @retval None
01553   */
01554 void HAL_PKA_RAMReset(PKA_HandleTypeDef *hpka)
01555 {
01556   uint32_t index;
01557 
01558   /* For each element in the PKA RAM */
01559   for (index = 0; index < PKA_RAM_SIZE; index++)
01560   {
01561     /* Clear the content */
01562     hpka->Instance->RAM[index] = 0UL;
01563   }
01564 }
01565 
01566 /**
01567   * @brief  This function handles PKA event interrupt request.
01568   * @param  hpka PKA handle
01569   * @retval None
01570   */
01571 void HAL_PKA_IRQHandler(PKA_HandleTypeDef *hpka)
01572 {
01573   uint32_t mode = PKA_GetMode(hpka);
01574   FlagStatus addErrFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_ADDRERR);
01575   FlagStatus ramErrFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_RAMERR);
01576   FlagStatus procEndFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_PROCEND);
01577 
01578   /* Address error interrupt occurred */
01579   if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_ADDRERR) == SET) && (addErrFlag == SET))
01580   {
01581     hpka->ErrorCode |= HAL_PKA_ERROR_ADDRERR;
01582 
01583     /* Clear ADDRERR flag */
01584     __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_ADDRERR);
01585   }
01586 
01587   /* RAM access error interrupt occurred */
01588   if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_RAMERR) == SET) && (ramErrFlag == SET))
01589   {
01590     hpka->ErrorCode |= HAL_PKA_ERROR_RAMERR;
01591 
01592     /* Clear RAMERR flag */
01593     __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_RAMERR);
01594   }
01595 
01596   /* Check the operation success in case of ECDSA signature */
01597   if (mode == PKA_MODE_ECDSA_SIGNATURE)
01598   {
01599     /* If error output result is different from 0, ecdsa sign operation need to be repeated */
01600     if (hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_ERROR] != 0UL)
01601     {
01602       hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION;
01603     }
01604   }
01605   /* Trigger the error callback if an error is present */
01606   if (hpka->ErrorCode != HAL_PKA_ERROR_NONE)
01607   {
01608 #if (USE_HAL_PKA_REGISTER_CALLBACKS == 1)
01609     hpka->ErrorCallback(hpka);
01610 #else
01611     HAL_PKA_ErrorCallback(hpka);
01612 #endif /* USE_HAL_PKA_REGISTER_CALLBACKS */
01613   }
01614 
01615   /* End Of Operation interrupt occurred */
01616   if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_PROCEND) == SET) && (procEndFlag == SET))
01617   {
01618     /* Clear PROCEND flag */
01619     __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_PROCEND);
01620 
01621     /* Set the state to ready */
01622     hpka->State = HAL_PKA_STATE_READY;
01623 
01624 #if (USE_HAL_PKA_REGISTER_CALLBACKS == 1)
01625     hpka->OperationCpltCallback(hpka);
01626 #else
01627     HAL_PKA_OperationCpltCallback(hpka);
01628 #endif /* USE_HAL_PKA_REGISTER_CALLBACKS */
01629   }
01630 }
01631 
01632 /**
01633   * @brief  Process completed callback.
01634   * @param  hpka PKA handle
01635   * @retval None
01636   */
01637 __weak void HAL_PKA_OperationCpltCallback(PKA_HandleTypeDef *hpka)
01638 {
01639   /* Prevent unused argument(s) compilation warning */
01640   UNUSED(hpka);
01641 
01642   /* NOTE : This function should not be modified, when the callback is needed,
01643             the HAL_PKA_OperationCpltCallback could be implemented in the user file
01644    */
01645 }
01646 
01647 /**
01648   * @brief  Error callback.
01649   * @param  hpka PKA handle
01650   * @retval None
01651   */
01652 __weak void HAL_PKA_ErrorCallback(PKA_HandleTypeDef *hpka)
01653 {
01654   /* Prevent unused argument(s) compilation warning */
01655   UNUSED(hpka);
01656 
01657   /* NOTE : This function should not be modified, when the callback is needed,
01658             the HAL_PKA_ErrorCallback could be implemented in the user file
01659    */
01660 }
01661 
01662 /**
01663   * @}
01664   */
01665 
01666 /** @defgroup PKA_Exported_Functions_Group3 Peripheral State and Error functions
01667   * @brief    Peripheral State and Error functions
01668   *
01669   @verbatim
01670  ===============================================================================
01671             ##### Peripheral State and Error functions #####
01672  ===============================================================================
01673     [..]
01674     This subsection permit to get in run-time the status of the peripheral.
01675 
01676 @endverbatim
01677   * @{
01678   */
01679 
01680 /**
01681   * @brief  Return the PKA handle state.
01682   * @param  hpka PKA handle
01683   * @retval HAL status
01684   */
01685 HAL_PKA_StateTypeDef HAL_PKA_GetState(PKA_HandleTypeDef *hpka)
01686 {
01687   /* Return PKA handle state */
01688   return hpka->State;
01689 }
01690 
01691 /**
01692   * @brief  Return the PKA error code.
01693   * @param  hpka PKA handle
01694   * @retval PKA error code
01695   */
01696 uint32_t HAL_PKA_GetError(PKA_HandleTypeDef *hpka)
01697 {
01698   /* Return PKA handle error code */
01699   return hpka->ErrorCode;
01700 }
01701 
01702 /**
01703   * @}
01704   */
01705 
01706 /**
01707   * @}
01708   */
01709 
01710 /** @addtogroup PKA_Private_Functions
01711   * @{
01712   */
01713 
01714 /**
01715   * @brief  Get PKA operating mode.
01716   * @param  hpka PKA handle
01717   * @retval Return the current mode
01718   */
01719 uint32_t PKA_GetMode(PKA_HandleTypeDef *hpka)
01720 {
01721   /* return the shifted PKA_CR_MODE value */
01722   return (uint32_t)(READ_BIT(hpka->Instance->CR, PKA_CR_MODE) >> PKA_CR_MODE_Pos);
01723 }
01724 
01725 /**
01726   * @brief  Wait for operation completion or timeout.
01727   * @param  hpka PKA handle
01728   * @param  Timeout Timeout duration in millisecond.
01729   * @param  Tickstart Tick start value
01730   * @retval HAL status
01731   */
01732 HAL_StatusTypeDef PKA_PollEndOfOperation(PKA_HandleTypeDef *hpka, uint32_t Timeout, uint32_t Tickstart)
01733 {
01734   /* Wait for the end of operation or timeout */
01735   while ((hpka->Instance->SR & PKA_SR_PROCENDF) == 0UL)
01736   {
01737     /* Check if timeout is disabled (set to infinite wait) */
01738     if (Timeout != HAL_MAX_DELAY)
01739     {
01740       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0UL))
01741       {
01742         return HAL_TIMEOUT;
01743       }
01744     }
01745   }
01746   return HAL_OK;
01747 }
01748 
01749 /**
01750   * @brief  Return a hal error code based on PKA error flags.
01751   * @param  hpka PKA handle
01752   * @param  mode PKA operating mode
01753   * @retval error code
01754   */
01755 uint32_t PKA_CheckError(PKA_HandleTypeDef *hpka, uint32_t mode)
01756 {
01757   uint32_t err = HAL_PKA_ERROR_NONE;
01758 
01759   /* Check RAMERR error */
01760   if (__HAL_PKA_GET_FLAG(hpka, PKA_FLAG_RAMERR) == SET)
01761   {
01762     err |= HAL_PKA_ERROR_RAMERR;
01763   }
01764 
01765   /* Check ADDRERR error */
01766   if (__HAL_PKA_GET_FLAG(hpka, PKA_FLAG_ADDRERR) == SET)
01767   {
01768     err |= HAL_PKA_ERROR_ADDRERR;
01769   }
01770 
01771   /* Check the operation success in case of ECDSA signature */
01772   if (mode == PKA_MODE_ECDSA_SIGNATURE)
01773   {
01774 #define EDCSA_SIGN_NOERROR 0UL
01775     /* If error output result is different from no error, ecsa sign operation need to be repeated */
01776     if (hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_ERROR] != EDCSA_SIGN_NOERROR)
01777     {
01778       err |= HAL_PKA_ERROR_OPERATION;
01779     }
01780   }
01781 
01782   return err;
01783 }
01784 
01785 /**
01786   * @brief  Get number of bits inside an array of u8.
01787   * @param  byteNumber Number of u8 inside the array
01788   */
01789 uint32_t PKA_GetBitSize_u8(uint32_t byteNumber)
01790 {
01791   /* Convert from number of uint8_t in an array to the associated number of bits in this array */
01792   return byteNumber * 8UL;
01793 }
01794 
01795 /**
01796   * @brief  Get optimal number of bits inside an array of u8.
01797   * @param  byteNumber Number of u8 inside the array
01798   * @param  msb Most significant uint8_t of the array
01799   */
01800 uint32_t PKA_GetOptBitSize_u8(uint32_t byteNumber, uint8_t msb)
01801 {
01802   uint32_t position;
01803 
01804   position = 32UL - __CLZ(msb);
01805 
01806   return (((byteNumber - 1UL) * 8UL) + position);
01807 }
01808 
01809 /**
01810   * @brief  Get number of bits inside an array of u32.
01811   * @param  wordNumber Number of u32 inside the array
01812   */
01813 uint32_t PKA_GetBitSize_u32(uint32_t wordNumber)
01814 {
01815   /* Convert from number of uint32_t in an array to the associated number of bits in this array */
01816   return wordNumber * 32UL;
01817 }
01818 
01819 /**
01820   * @brief  Get number of uint8_t element in an array of bitSize bits.
01821   * @param  bitSize Number of bits in an array
01822   */
01823 uint32_t PKA_GetArraySize_u8(uint32_t bitSize)
01824 {
01825   /* Manage the non aligned on uint8_t bitsize: */
01826   /*   512 bits requires 64 uint8_t             */
01827   /*   521 bits requires 66 uint8_t             */
01828   return ((bitSize + 7UL) / 8UL);
01829 }
01830 
01831 /**
01832   * @brief  Copy uint32_t array to uint8_t array to fit PKA number representation.
01833   * @param  dst Pointer to destination
01834   * @param  src Pointer to source
01835   * @param  n Number of uint8_t to copy
01836   * @retval dst
01837   */
01838 void PKA_Memcpy_u32_to_u8(uint8_t dst[], __IO const uint32_t src[], size_t n)
01839 {
01840   if (dst != NULL)
01841   {
01842     if (src != NULL)
01843     {
01844       uint32_t index_uint32_t = 0UL; /* This index is used outside of the loop */
01845 
01846       for (; index_uint32_t < (n / 4UL); index_uint32_t++)
01847       {
01848         /* Avoid casting from uint8_t* to uint32_t* by copying 4 uint8_t in a row */
01849         /* Apply __REV equivalent */
01850         uint32_t index_uint8_t = n - 4UL - (index_uint32_t * 4UL);
01851         dst[index_uint8_t + 3UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU));
01852         dst[index_uint8_t + 2UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL);
01853         dst[index_uint8_t + 1UL] = (uint8_t)((src[index_uint32_t] & 0x00FF0000U) >> 16UL);
01854         dst[index_uint8_t + 0UL] = (uint8_t)((src[index_uint32_t] & 0xFF000000U) >> 24UL);
01855       }
01856 
01857       /* Manage the buffers not aligned on uint32_t */
01858       if ((n % 4UL) == 1UL)
01859       {
01860         dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU));
01861       }
01862       else if ((n % 4UL) == 2UL)
01863       {
01864         dst[1UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU));
01865         dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL);
01866       }
01867       else if ((n % 4UL) == 3UL)
01868       {
01869         dst[2UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU));
01870         dst[1UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL);
01871         dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x00FF0000U) >> 16UL);
01872       }
01873       else
01874       {
01875         /* The last element is already handle in the loop */
01876       }
01877     }
01878   }
01879 }
01880 
01881 /**
01882   * @brief  Copy uint8_t array to uint32_t array to fit PKA number representation.
01883   * @param  dst Pointer to destination
01884   * @param  src Pointer to source
01885   * @param  n Number of uint8_t to copy (must be multiple of 4)
01886   * @retval dst
01887   */
01888 void PKA_Memcpy_u8_to_u32(__IO uint32_t dst[], const uint8_t src[], size_t n)
01889 {
01890   if (dst != NULL)
01891   {
01892     if (src != NULL)
01893     {
01894       uint32_t index = 0UL; /* This index is used outside of the loop */
01895 
01896       for (; index < (n / 4UL); index++)
01897       {
01898         /* Apply the equivalent of __REV from uint8_t to uint32_t */
01899         dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \
01900                      | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL) \
01901                      | ((uint32_t)src[(n - (index * 4UL) - 3UL)] << 16UL) \
01902                      | ((uint32_t)src[(n - (index * 4UL) - 4UL)] << 24UL);
01903       }
01904 
01905       /* Manage the buffers not aligned on uint32_t */
01906       if ((n % 4UL) == 1UL)
01907       {
01908         dst[index] = (uint32_t)src[(n - (index * 4UL) - 1UL)];
01909       }
01910       else if ((n % 4UL) == 2UL)
01911       {
01912         dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \
01913                      | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL);
01914       }
01915       else if ((n % 4UL) == 3UL)
01916       {
01917         dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \
01918                      | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL) \
01919                      | ((uint32_t)src[(n - (index * 4UL) - 3UL)] << 16UL);
01920       }
01921       else
01922       {
01923         /* The last element is already handle in the loop */
01924       }
01925     }
01926   }
01927 }
01928 
01929 /**
01930   * @brief  Copy uint32_t array to uint32_t array.
01931   * @param  dst Pointer to destination
01932   * @param  src Pointer to source
01933   * @param  n Number of u32 to be handled
01934   * @retval dst
01935   */
01936 void PKA_Memcpy_u32_to_u32(__IO uint32_t dst[], __IO const uint32_t src[], size_t n)
01937 {
01938   /* If a destination buffer is provided */
01939   if (dst != NULL)
01940   {
01941     /* If a source buffer is provided */
01942     if (src != NULL)
01943     {
01944       /* For each element in the array */
01945       for (uint32_t index = 0UL; index < n; index++)
01946       {
01947         /* Copy the content */
01948         dst[index] = src[index];
01949       }
01950     }
01951   }
01952 }
01953 
01954 /**
01955   * @brief  Generic function to start a PKA operation in blocking mode.
01956   * @param  hpka PKA handle
01957   * @param  mode PKA operation
01958   * @param  Timeout Timeout duration
01959   * @retval HAL status
01960   */
01961 HAL_StatusTypeDef PKA_Process(PKA_HandleTypeDef *hpka, uint32_t mode, uint32_t Timeout)
01962 {
01963   HAL_StatusTypeDef err = HAL_OK;
01964   uint32_t tickstart;
01965 
01966   if (hpka->State == HAL_PKA_STATE_READY)
01967   {
01968     /* Set the state to busy */
01969     hpka->State = HAL_PKA_STATE_BUSY;
01970 
01971     /* Clear any pending error */
01972     hpka->ErrorCode = HAL_PKA_ERROR_NONE;
01973 
01974     /* Init tickstart for timeout management*/
01975     tickstart = HAL_GetTick();
01976 
01977     /* Set the mode and deactivate the interrupts */
01978     MODIFY_REG(hpka->Instance->CR, PKA_CR_MODE | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE,
01979                mode << PKA_CR_MODE_Pos);
01980 
01981     /* Start the computation */
01982     hpka->Instance->CR |= PKA_CR_START;
01983 
01984     /* Wait for the end of operation or timeout */
01985     if (PKA_PollEndOfOperation(hpka, Timeout, tickstart) != HAL_OK)
01986     {
01987       /* Abort any ongoing operation */
01988       CLEAR_BIT(hpka->Instance->CR, PKA_CR_EN);
01989 
01990       hpka->ErrorCode |= HAL_PKA_ERROR_TIMEOUT;
01991 
01992       /* Make ready for the next operation */
01993       SET_BIT(hpka->Instance->CR, PKA_CR_EN);
01994     }
01995 
01996     /* Check error */
01997     hpka->ErrorCode |= PKA_CheckError(hpka, mode);
01998 
01999     /* Clear all flags */
02000     hpka->Instance->CLRFR |= (PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC);
02001 
02002     /* Set the state to ready */
02003     hpka->State = HAL_PKA_STATE_READY;
02004 
02005     /* Manage the result based on encountered errors */
02006     if (hpka->ErrorCode != HAL_PKA_ERROR_NONE)
02007     {
02008       err = HAL_ERROR;
02009     }
02010   }
02011   else
02012   {
02013     err = HAL_ERROR;
02014   }
02015   return err;
02016 }
02017 
02018 /**
02019   * @brief  Generic function to start a PKA operation in non-blocking mode with Interrupt.
02020   * @param  hpka PKA handle
02021   * @param  mode PKA operation
02022   * @retval HAL status
02023   */
02024 HAL_StatusTypeDef PKA_Process_IT(PKA_HandleTypeDef *hpka, uint32_t mode)
02025 {
02026   HAL_StatusTypeDef err = HAL_OK;
02027 
02028   if (hpka->State == HAL_PKA_STATE_READY)
02029   {
02030     /* Set the state to busy */
02031     hpka->State = HAL_PKA_STATE_BUSY;
02032 
02033     /* Clear any pending error */
02034     hpka->ErrorCode = HAL_PKA_ERROR_NONE;
02035 
02036     /* Set the mode and activate interrupts */
02037     MODIFY_REG(hpka->Instance->CR, PKA_CR_MODE | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE,
02038                (mode << PKA_CR_MODE_Pos) | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE);
02039 
02040     /* Start the computation */
02041     hpka->Instance->CR |= PKA_CR_START;
02042   }
02043   else
02044   {
02045     err = HAL_ERROR;
02046   }
02047   return err;
02048 }
02049 
02050 /**
02051   * @brief  Set input parameters.
02052   * @param  hpka PKA handle
02053   * @param  in Input information
02054   */
02055 void PKA_ModExp_Set(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in)
02056 {
02057   /* Get the number of bit per operand */
02058   hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = PKA_GetBitSize_u8(in->OpSize);
02059 
02060   /* Get the number of bit of the exponent */
02061   hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = PKA_GetBitSize_u8(in->expSize);
02062 
02063   /* Move the input parameters pOp1 to PKA RAM */
02064   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT_BASE], in->pOp1, in->OpSize);
02065   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT_BASE + ((in->OpSize + 3UL) / 4UL));
02066 
02067   /* Move the exponent to PKA RAM */
02068   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT], in->pExp, in->expSize);
02069   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT + ((in->expSize + 3UL) / 4UL));
02070 
02071   /* Move the modulus to PKA RAM */
02072   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MODULUS], in->pMod, in->OpSize);
02073   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MODULUS + ((in->OpSize + 3UL) / 4UL));
02074 }
02075 
02076 /**
02077   * @brief  Set input parameters.
02078   * @param  hpka PKA handle
02079   * @param  in Input information
02080   */
02081 void PKA_ModExpFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in)
02082 {
02083   /* Get the number of bit per operand */
02084   hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = PKA_GetBitSize_u8(in->OpSize);
02085 
02086   /* Get the number of bit of the exponent */
02087   hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = PKA_GetBitSize_u8(in->expSize);
02088 
02089   /* Move the input parameters pOp1 to PKA RAM */
02090   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT_BASE], in->pOp1, in->OpSize);
02091   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT_BASE + (in->OpSize / 4UL));
02092 
02093   /* Move the exponent to PKA RAM */
02094   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT], in->pExp, in->expSize);
02095   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT + (in->expSize / 4UL));
02096 
02097   /* Move the modulus to PKA RAM */
02098   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MODULUS], in->pMod, in->OpSize);
02099   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MODULUS + (in->OpSize / 4UL));
02100 
02101   /* Move the Montgomery parameter to PKA RAM */
02102   PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MONTGOMERY_PARAM], in->pMontgomeryParam,
02103                         in->OpSize / 4UL);
02104   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MONTGOMERY_PARAM + (in->OpSize / 4UL));
02105 }
02106 
02107 
02108 /**
02109   * @brief  Set input parameters.
02110   * @param  hpka PKA handle
02111   * @param  in Input information
02112   */
02113 void PKA_ECDSASign_Set(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in)
02114 {
02115   /* Get the prime order n length */
02116   hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_ORDER_NB_BITS] = PKA_GetOptBitSize_u8(in->primeOrderSize, *(in->primeOrder));
02117 
02118   /* Get the modulus p length */
02119   hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus));
02120 
02121   /* Get the coefficient a sign */
02122   hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_A_COEFF_SIGN] = in->coefSign;
02123 
02124   /* Move the input parameters coefficient |a| to PKA RAM */
02125   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_A_COEFF], in->coef, in->modulusSize);
02126   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL));
02127 
02128   /* Move the input parameters modulus value p to PKA RAM */
02129   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_MOD_GF], in->modulus, in->modulusSize);
02130   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL));
02131 
02132   /* Move the input parameters integer k to PKA RAM */
02133   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_K], in->integer, in->primeOrderSize);
02134   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_K + ((in->primeOrderSize + 3UL) / 4UL));
02135 
02136   /* Move the input parameters base point G coordinate x to PKA RAM */
02137   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_INITIAL_POINT_X], in->basePointX, in->modulusSize);
02138   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02139 
02140   /* Move the input parameters base point G coordinate y to PKA RAM */
02141   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y], in->basePointY, in->modulusSize);
02142   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02143 
02144   /* Move the input parameters hash of message z to PKA RAM */
02145   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_HASH_E], in->hash, in->primeOrderSize);
02146   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_HASH_E + ((in->primeOrderSize + 3UL) / 4UL));
02147 
02148   /* Move the input parameters private key d to PKA RAM */
02149   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D], in->privateKey, in->primeOrderSize);
02150   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D + ((in->primeOrderSize + 3UL) / 4UL));
02151 
02152   /* Move the input parameters prime order n to PKA RAM */
02153   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_ORDER_N], in->primeOrder, in->primeOrderSize);
02154   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_ORDER_N + ((in->primeOrderSize + 3UL) / 4UL));
02155 }
02156 
02157 /**
02158   * @brief  Set input parameters.
02159   * @param  hpka PKA handle
02160   * @param  in Input information
02161   */
02162 void PKA_ECDSAVerif_Set(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in)
02163 {
02164   /* Get the prime order n length */
02165   hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_ORDER_NB_BITS] = PKA_GetOptBitSize_u8(in->primeOrderSize, *(in->primeOrder));
02166 
02167   /* Get the modulus p length */
02168   hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus));
02169 
02170   /* Get the coefficient a sign */
02171   hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_A_COEFF_SIGN] = in->coefSign;
02172 
02173   /* Move the input parameters coefficient |a| to PKA RAM */
02174   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_A_COEFF], in->coef, in->modulusSize);
02175   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL));
02176 
02177   /* Move the input parameters modulus value p to PKA RAM */
02178   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_MOD_GF], in->modulus, in->modulusSize);
02179   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL));
02180 
02181   /* Move the input parameters base point G coordinate x to PKA RAM */
02182   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_INITIAL_POINT_X], in->basePointX, in->modulusSize);
02183   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02184 
02185   /* Move the input parameters base point G coordinate y to PKA RAM */
02186   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y], in->basePointY, in->modulusSize);
02187   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02188 
02189   /* Move the input parameters public-key curve point Q coordinate xQ to PKA RAM */
02190   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X], in->pPubKeyCurvePtX,
02191                        in->modulusSize);
02192   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02193 
02194   /* Move the input parameters public-key curve point Q coordinate xQ to PKA RAM */
02195   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y], in->pPubKeyCurvePtY,
02196                        in->modulusSize);
02197   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02198 
02199   /* Move the input parameters signature part r to PKA RAM */
02200   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_SIGNATURE_R], in->RSign, in->primeOrderSize);
02201   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_SIGNATURE_R + ((in->primeOrderSize + 3UL) / 4UL));
02202 
02203   /* Move the input parameters signature part s to PKA RAM */
02204   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_SIGNATURE_S], in->SSign, in->primeOrderSize);
02205   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_SIGNATURE_S + ((in->primeOrderSize + 3UL) / 4UL));
02206 
02207   /* Move the input parameters hash of message z to PKA RAM */
02208   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_HASH_E], in->hash, in->primeOrderSize);
02209   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_HASH_E + ((in->primeOrderSize + 3UL) / 4UL));
02210 
02211   /* Move the input parameters curve prime order n to PKA RAM */
02212   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_ORDER_N], in->primeOrder, in->primeOrderSize);
02213   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_ORDER_N + ((in->primeOrderSize + 3UL) / 4UL));
02214 }
02215 
02216 /**
02217   * @brief  Set input parameters.
02218   * @param  hpka PKA handle
02219   * @param  in Input information
02220   */
02221 void PKA_RSACRTExp_Set(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in)
02222 {
02223   /* Get the operand length M */
02224   hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_MOD_NB_BITS] = PKA_GetBitSize_u8(in->size);
02225 
02226   /* Move the input parameters operand dP to PKA RAM */
02227   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_DP_CRT], in->pOpDp, in->size / 2UL);
02228   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_DP_CRT + (in->size / 8UL));
02229 
02230   /* Move the input parameters operand dQ to PKA RAM */
02231   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_DQ_CRT], in->pOpDq, in->size / 2UL);
02232   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_DQ_CRT + (in->size / 8UL));
02233 
02234   /* Move the input parameters operand qinv to PKA RAM */
02235   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_QINV_CRT], in->pOpQinv, in->size / 2UL);
02236   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_QINV_CRT + (in->size / 8UL));
02237 
02238   /* Move the input parameters prime p to PKA RAM */
02239   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_PRIME_P], in->pPrimeP, in->size / 2UL);
02240   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_PRIME_P + (in->size / 8UL));
02241 
02242   /* Move the input parameters prime q to PKA RAM */
02243   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_PRIME_Q], in->pPrimeQ, in->size / 2UL);
02244   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_PRIME_Q + (in->size / 8UL));
02245 
02246   /* Move the input parameters operand A to PKA RAM */
02247   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_EXPONENT_BASE], in->popA, in->size);
02248   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_EXPONENT_BASE + (in->size / 4UL));
02249 }
02250 
02251 /**
02252   * @brief  Set input parameters.
02253   * @param  hpka PKA handle
02254   * @param  in Input information
02255   */
02256 void PKA_PointCheck_Set(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in)
02257 {
02258   /* Get the modulus length */
02259   hpka->Instance->RAM[PKA_POINT_CHECK_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus));
02260 
02261   /* Get the coefficient a sign */
02262   hpka->Instance->RAM[PKA_POINT_CHECK_IN_A_COEFF_SIGN] = in->coefSign;
02263 
02264   /* Move the input parameters coefficient |a| to PKA RAM */
02265   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_A_COEFF], in->coefA, in->modulusSize);
02266   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL));
02267 
02268   /* Move the input parameters coefficient b to PKA RAM */
02269   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_B_COEFF], in->coefB, in->modulusSize);
02270   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_B_COEFF + ((in->modulusSize + 3UL) / 4UL));
02271 
02272   /* Move the input parameters modulus value p to PKA RAM */
02273   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_MOD_GF], in->modulus, in->modulusSize);
02274   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL));
02275 
02276   /* Move the input parameters Point P coordinate x to PKA RAM */
02277   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_X], in->pointX, in->modulusSize);
02278   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02279 
02280   /* Move the input parameters Point P coordinate y to PKA RAM */
02281   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_Y], in->pointY, in->modulusSize);
02282   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02283 }
02284 
02285 /**
02286   * @brief  Set input parameters.
02287   * @param  hpka PKA handle
02288   * @param  in Input information
02289   */
02290 void PKA_ECCMul_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in)
02291 {
02292   /* Get the scalar multiplier k length */
02293   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS] = PKA_GetOptBitSize_u8(in->scalarMulSize, *(in->scalarMul));
02294 
02295   /* Get the modulus length */
02296   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus));
02297 
02298   /* Get the coefficient a sign */
02299   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN] = in->coefSign;
02300 
02301   /* Move the input parameters coefficient |a| to PKA RAM */
02302   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF], in->coefA, in->modulusSize);
02303   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL));
02304 
02305 
02306   /* Move the input parameters modulus value p to PKA RAM */
02307   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_MOD_GF], in->modulus, in->modulusSize);
02308   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL));
02309 
02310   /* Move the input parameters scalar multiplier k to PKA RAM */
02311   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_K], in->scalarMul, in->scalarMulSize);
02312   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_K + ((in->scalarMulSize + 3UL) / 4UL));
02313 
02314   /* Move the input parameters Point P coordinate x to PKA RAM */
02315   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X], in->pointX, in->modulusSize);
02316   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02317 
02318   /* Move the input parameters Point P coordinate y to PKA RAM */
02319   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y], in->pointY, in->modulusSize);
02320   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02321 
02322 }
02323 
02324 
02325 /**
02326   * @brief  Set input parameters.
02327   * @param  hpka PKA handle
02328   * @param  in Input information
02329   */
02330 void PKA_ECCMulFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulFastModeInTypeDef *in)
02331 {
02332   /* Get the scalar multiplier k length */
02333   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS] = PKA_GetOptBitSize_u8(in->scalarMulSize, *(in->scalarMul));
02334 
02335   /* Get the modulus length */
02336   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus));
02337 
02338   /* Get the coefficient a sign */
02339   hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN] = in->coefSign;
02340 
02341   /* Move the input parameters coefficient |a| to PKA RAM */
02342   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF], in->coefA, in->modulusSize);
02343   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL));
02344 
02345   /* Move the input parameters modulus value p to PKA RAM */
02346   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_MOD_GF], in->modulus, in->modulusSize);
02347   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL));
02348 
02349   /* Move the input parameters scalar multiplier k to PKA RAM */
02350   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_K], in->scalarMul, in->scalarMulSize);
02351   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_K + ((in->scalarMulSize + 3UL) / 4UL));
02352 
02353   /* Move the input parameters Point P coordinate x to PKA RAM */
02354   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_X], in->pointX, in->modulusSize);
02355   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL));
02356 
02357   /* Move the input parameters Point P coordinate y to PKA RAM */
02358   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_Y], in->pointY, in->modulusSize);
02359   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL));
02360 
02361   /* Move the Montgomery parameter to PKA RAM */
02362   PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_MONTGOMERY_PARAM], in->pMontgomeryParam,
02363                         (in->modulusSize + 3UL) / 4UL);
02364   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_MONTGOMERY_PARAM + ((in->modulusSize + 3UL) / 4UL));
02365 }
02366 /**
02367   * @brief  Set input parameters.
02368   * @param  hpka PKA handle
02369   * @param  in Input information
02370   */
02371 void PKA_ModInv_Set(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in)
02372 {
02373   /* Get the number of bit per operand */
02374   hpka->Instance->RAM[PKA_MODULAR_INV_NB_BITS] = PKA_GetBitSize_u32(in->size);
02375 
02376   /* Move the input parameters operand A to PKA RAM */
02377   PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_INV_IN_OP1], in->pOp1, in->size);
02378   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_INV_IN_OP1 + in->size);
02379 
02380   /* Move the input parameters modulus value n to PKA RAM */
02381   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_INV_IN_OP2_MOD], in->pMod, in->size * 4UL);
02382   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_INV_IN_OP2_MOD + in->size);
02383 }
02384 
02385 /**
02386   * @brief  Set input parameters.
02387   * @param  hpka PKA handle
02388   * @param  in Input information
02389   */
02390 void PKA_ModRed_Set(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in)
02391 {
02392   /* Get the number of bit per operand */
02393   hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_OP_LENGTH] = PKA_GetBitSize_u32(in->OpSize);
02394 
02395   /* Get the number of bit per modulus */
02396   hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_MOD_LENGTH] = PKA_GetBitSize_u8(in->modSize);
02397 
02398   /* Move the input parameters operand A to PKA RAM */
02399   PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_OPERAND], in->pOp1, in->OpSize);
02400   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_REDUC_IN_OPERAND + in->OpSize);
02401 
02402   /* Move the input parameters modulus value n to PKA RAM */
02403   PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_MODULUS], in->pMod, in->modSize);
02404   __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_REDUC_IN_MODULUS + (in->modSize / 4UL));
02405 }
02406 
02407 /**
02408   * @brief  Set input parameters.
02409   * @param  hpka PKA handle
02410   * @param  size Size of the operand
02411   * @param  pOp1 Generic pointer to input data
02412   */
02413 void PKA_MontgomeryParam_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint8_t *pOp1)
02414 {
02415   uint32_t bytetoskip = 0UL;
02416   uint32_t newSize;
02417 
02418   if (pOp1 != NULL)
02419   {
02420     /* Count the number of zero bytes */
02421     while ((bytetoskip < size) && (pOp1[bytetoskip] == 0UL))
02422     {
02423       bytetoskip++;
02424     }
02425 
02426     /* Get new size after skipping zero bytes */
02427     newSize = size - bytetoskip;
02428 
02429     /* Get the number of bit per operand */
02430     hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(newSize, pOp1[bytetoskip]);
02431 
02432     /* Move the input parameters pOp1 to PKA RAM */
02433     PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MODULUS], pOp1, size);
02434     __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MONTGOMERY_PARAM_IN_MODULUS + ((size + 3UL) / 4UL));
02435   }
02436 }
02437 
02438 /**
02439   * @brief  Generic function to set input parameters.
02440   * @param  hpka PKA handle
02441   * @param  size Size of the operand
02442   * @param  pOp1 Generic pointer to input data
02443   * @param  pOp2 Generic pointer to input data
02444   * @param  pOp3 Generic pointer to input data
02445   */
02446 void PKA_ARI_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint32_t *pOp1, const uint32_t *pOp2,
02447                  const uint8_t *pOp3)
02448 {
02449   /* Get the number of bit per operand */
02450   hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_NB_BITS] = PKA_GetBitSize_u32(size);
02451 
02452   if (pOp1 != NULL)
02453   {
02454     /* Move the input parameters pOp1 to PKA RAM */
02455     PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP1], pOp1, size);
02456     __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP1 + size);
02457   }
02458 
02459   if (pOp2 != NULL)
02460   {
02461     /* Move the input parameters pOp2 to PKA RAM */
02462     PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP2], pOp2, size);
02463     __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP2 + size);
02464   }
02465 
02466   if (pOp3 != NULL)
02467   {
02468     /* Move the input parameters pOp3 to PKA RAM */
02469     PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP3], pOp3, size * 4UL);
02470     __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP3 + size);
02471   }
02472 }
02473 
02474 /**
02475   * @}
02476   */
02477 
02478 /**
02479   * @}
02480   */
02481 
02482 #endif /* defined(PKA) && defined(HAL_PKA_MODULE_ENABLED) */
02483 
02484 /**
02485   * @}
02486   */