1 /*
2  * Copyright (c) 2001-2020, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_ECC
8 
9 /************* Include Files ****************/
10 
11 #include "cc_pal_mem.h"
12 #include "cc_ecpki_error.h"
13 #include "cc_ecpki_local.h"
14 #include "cc_common.h"
15 #include "cc_rsa_types.h"
16 #include "cc_fips_defs.h"
17 #include "ec_wrst.h"
18 #ifdef USE_MBEDTLS_CRYPTOCELL
19 #include "cc_general_defs.h"
20 #include "mbedtls/md.h"
21 #endif
22 
23 /************************ Defines *****************************************/
24 #if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
25         #error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS or CC_HASH_USER_CTX_SIZE_IN_WORDS  defined not correctly.
26 #endif
27 
28 /************************ Enums *******************************************/
29 /************************ Typedefs ****************************************/
30 /************************ Global Data *************************************/
31 extern const CCEcpkiHash_t ecpki_hash_info[CC_ECPKI_HASH_NumOfModes];
32 extern const uint8_t ecpki_supported_hash_modes[CC_ECPKI_HASH_NumOfModes];
33 /************* Private function prototype *********************************/
34 
35 /************************ Public Functions ********************************/
36 
37 /**************************************************************************
38  *                EcdsaVerifyInit  function
39  **************************************************************************/
40 /**
41    @brief  Prepares a context that is used by the Update and Finish functions
42            but does not perform elliptic curve cryptographic processing
43 
44                     The function:
45                         - Receives and decrypts user data (working context).
46                         - Checks input parameters of  ECDSA Vrifying primitive.
47                         - Calls hash init function.
48                         - Initializes variables and structures for calling next functions.
49                         - Encrypts and releases working context.
50 
51                         NOTE: Using of HASH functions with HASH size great, than EC modulus size,
52                         is not recommended!
53 
54    @param[in,out] pVerifyUserContext - A pointer to the user buffer for verifying database.
55    @param[in] pSignerPublKey - A pointer to a Signer public key structure.
56    @param[in] hashMode - The enumerator variable defines the hash function to be used.
57 
58    @return <b>CCError_t</b>: <br>
59                          CC_OK<br>
60                          CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
61                          CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR <br>
62                          CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR <br>
63                          CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR <br>
64                          CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
65 **/
EcdsaVerifyInit(CCEcdsaVerifyUserContext_t * pVerifyUserContext,CCEcpkiUserPublKey_t * pSignerPublKey,CCEcpkiHashOpMode_t hashMode)66 CEXPORT_C CCError_t EcdsaVerifyInit(
67                                            CCEcdsaVerifyUserContext_t  *pVerifyUserContext, /*in/out*/
68                                            CCEcpkiUserPublKey_t        *pSignerPublKey,     /*in*/
69                                            CCEcpkiHashOpMode_t         hashMode               /*in*/ )
70 {
71         /* FUNCTION DECLERATIONS */
72 
73         /* The return error identifier */
74         CCError_t err = CC_OK;
75         /* defining a pointer to the active context allcated by the CCM */
76         EcdsaVerifyContext_t *pWorkingContext;
77 #ifdef USE_MBEDTLS_CRYPTOCELL
78         const mbedtls_md_info_t *md_info=NULL;
79 #endif
80 
81         /* FUNCTION LOGIC */
82 
83         pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
84 
85         /* ............... checking the parameters validity ................... */
86         /* -------------------------------------------------------------------- */
87 
88         /* if the users context ID pointer is NULL return an error */
89         if (pVerifyUserContext == NULL){
90                 return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
91         }
92 
93         /*if the private key object is NULL return an error*/
94         if (pSignerPublKey == NULL){
95                 err = CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR;
96                 goto End;
97         }
98 
99         /* check if the hash operation mode is legal */
100         if (hashMode >= CC_ECPKI_HASH_NumOfModes){
101                 err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
102                 goto End;
103         }
104 
105         if (pSignerPublKey->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG){
106                 err = CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR;
107                 goto End;
108         }
109 
110         /* reset the Context handler for improper previous values initialized */
111         CC_PalMemSet(pWorkingContext, 0, sizeof(EcdsaVerifyContext_t));
112 
113         /* ................. loading the context .................................. */
114         /* ------------------------------------------------------------------------ */
115 
116         /*Initializing the Hash operation mode in the ECDSA Context */
117 
118 
119         if (ecpki_supported_hash_modes[hashMode] == CC_FALSE) {
120                 err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
121                 goto End;
122         }
123 
124         pWorkingContext->hashMode = hashMode;
125         pWorkingContext->hashResultSizeWords = ecpki_hash_info[pWorkingContext->hashMode].hashResultSize;
126 
127         if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
128 #ifdef USE_MBEDTLS_CRYPTOCELL
129                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[ecpki_hash_info[pWorkingContext->hashMode].hashMode] );
130                 if (NULL == md_info) {
131                         err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
132                         goto End;
133                 }
134                 mbedtls_md_init(&(pWorkingContext->hash_ctx));
135                 err = mbedtls_md_setup(&(pWorkingContext->hash_ctx), md_info, 0); // 0 = HASH, not HMAC
136                 if (err != 0) {
137                         goto End;
138                 }
139                 err = mbedtls_md_starts(&(pWorkingContext->hash_ctx));
140 #else
141                 err = CC_HashInit(&(pWorkingContext->hashUserCtxBuff), ecpki_hash_info[pWorkingContext->hashMode].hashMode);
142 #endif
143                 if (err != CC_OK)
144                         goto End;
145         }
146 
147         /* copy the ECPKI Public key to the context*/
148         CC_PalMemCopy(&pWorkingContext->ECDSA_SignerPublKey, pSignerPublKey, sizeof(CCEcpkiUserPublKey_t));
149 
150         /* set the ECDSA validation tag */
151         pVerifyUserContext->valid_tag = CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG;
152 
153         End:
154         /*  clear the users context in case of error */
155         if (err != CC_OK) {
156 #ifdef USE_MBEDTLS_CRYPTOCELL
157                 if(md_info!=NULL){
158                         mbedtls_md_free(&(pWorkingContext->hash_ctx));
159                 }
160 #endif
161                 CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
162         }
163 
164         return err;
165 
166 }/* EcdsaVerifyInit */
167 
168 
169 /**************************************************************************
170  *                EcdsaVerifyUpdate function
171  **************************************************************************/
172 /**
173    @brief  Performs a hash  operation on data allocated by the user
174            before finally verifying its signature.
175 
176            In case user divides signing data by block, he must call the Update function
177            continuously a number of times until processing of the entire data block is complete.
178 
179        NOTE: Using of HASH functions with HASH size greater, than EC modulus size,
180              is not recommended.
181 
182    @param [in,out] pVerifyUserContext - The pointer to the user buffer for verifying database.
183    @param [in] pMessageDataIn - The message data for calculating Hash.
184    @param [in]dataInSize - The size of the message data block, in bytes. The data size,
185                    passed on each call of the function, besides the last call, must be
186                    a multiple of the HASH block size according to used HASH mode.
187 
188    @return <b>CCError_t</b>: <br>
189                          CC_OK<br>
190                          CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
191                          CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
192                          CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR <br>
193                          CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR <br>
194                          CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
195  **/
EcdsaVerifyUpdate(CCEcdsaVerifyUserContext_t * pVerifyUserContext,uint8_t * pMessageDataIn,size_t dataInSize)196 CEXPORT_C CCError_t EcdsaVerifyUpdate(
197                                              CCEcdsaVerifyUserContext_t *pVerifyUserContext, /*in/out*/
198                                              uint8_t                        *pMessageDataIn,     /* in */
199                                              size_t                         dataInSize          /* in */ )
200 {
201         /* FUNCTION DECLARATIONS */
202 
203         /* The return error identifier */
204         CCError_t err = CC_OK;
205         /* defining a pointer to the active context allcated by the CCM */
206         EcdsaVerifyContext_t *pWorkingContext;
207 
208         /* FUNCTION LOGIC */
209 
210         /* sign working context */
211         pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
212 
213         /* ............... checking the parameters validity ................... */
214         /* -------------------------------------------------------------------- */
215 
216         /* if the users context pointer is NULL return an error */
217         if (pVerifyUserContext == NULL){
218                 return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
219         }
220 
221         /* if the users context TAG is illegal return an error - the context is invalid */
222         if (pVerifyUserContext->valid_tag != CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG){
223                 err = CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR;
224                 goto End;
225         }
226 
227         /* if the users MessageDataIn pointer is illegal return an error */
228         if (pMessageDataIn == NULL && dataInSize){
229                 err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR;
230                 goto End;
231         }
232 
233         /* check that the data size < 2^29 (to prevent an overflow on the
234            transition to bits ) */
235         if (dataInSize >= (1UL << 29)){
236                 err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
237                 goto End;
238         }
239 
240 
241         /* HASH update operations */
242         if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
243                 /*Operate the Hash update function for relevant version */
244 #ifdef USE_MBEDTLS_CRYPTOCELL
245                 err = mbedtls_md_update(&(pWorkingContext->hash_ctx), pMessageDataIn, dataInSize);
246 #else
247                 err = CC_HashUpdate( &(pWorkingContext->hashUserCtxBuff), pMessageDataIn, dataInSize );
248 #endif
249                 if (err != CC_OK) {
250                         goto End;
251                 }
252         } else {
253                 if (dataInSize != ecpki_hash_info[pWorkingContext->hashMode].hashResultSize*CC_32BIT_WORD_SIZE) {
254                         /* DataInSize must fit exactly to the size of Hash output that we support */
255                         err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
256                         goto End;
257                 }
258                 /* Copy the DataIn_ptr to the HASH_Result */
259                 CC_PalMemCopy((uint8_t *)pWorkingContext->hashResult,pMessageDataIn,dataInSize);
260         }
261 
262         End:
263         /*  clear the users context in case of error */
264         if (err != CC_OK) {
265 #ifdef USE_MBEDTLS_CRYPTOCELL
266                 mbedtls_md_free(&(pWorkingContext->hash_ctx));
267 #endif
268                 CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
269         }
270 
271         return err;
272 
273 }/* EcdsaVerifyUpdate */
274 
275 
276 
277 /**************************************************************************
278  *                EcdsaVerifyFinish function
279  **************************************************************************/
280 /**
281    @brief  Performs initialization of variables and structures,
282            calls the hash function for the last block of data (if necessary),
283            than calls EcWrstDsaVerify function for verifying signature
284            according to EC DSA algorithm.
285 
286        NOTE: Using of HASH functions with HASH size greater, than EC modulus size,
287              is not recommended!
288              Algorithm according ANS X9.62 standard
289 
290    @param[in] pVerifyUserContext - A pointer to the user buffer for verifying the database.
291    @param[in] pSignatureIn       - A pointer to a buffer for the signature to be compared
292    @param[in] SignatureSizeBytes    - The size of a user passed signature (must be 2*orderSizeInBytes).
293 
294    @return <b>CCError_t</b>: <br>
295               CC_OK <br>
296                           CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
297                           CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
298                           CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR <br>
299                           CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
300                           CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR <br>
301                           CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR <br>
302 **/
EcdsaVerifyFinish(CCEcdsaVerifyUserContext_t * pVerifyUserContext,uint8_t * pSignatureIn,size_t SignatureSizeBytes)303 CEXPORT_C CCError_t EcdsaVerifyFinish(
304                                              CCEcdsaVerifyUserContext_t *pVerifyUserContext,  /*in*/
305                                              uint8_t                        *pSignatureIn,        /*in*/
306                                              size_t                         SignatureSizeBytes  /*in*/)
307 {
308         /* FUNCTION DECLARATIONS */
309 
310         /* The return error identifier */
311         CCError_t err = CC_OK;
312 
313         /* pointer to the active context  */
314         EcdsaVerifyContext_t *pWorkingContext;
315         /* pointer to public key structure in ccmWorkingContext  */
316         CCEcpkiPublKey_t  *PublKey_ptr;
317         /*  EC domain ID and pointer to the current domain */
318         /*  pointer to the current domain */
319         CCEcpkiDomain_t   *pDomain;
320 
321         uint32_t  *pMessRepres, *pSignatureC, *pSignatureD;
322         uint32_t   hashSizeWords;
323         uint32_t   orderSizeInBytes, orderSizeInWords;
324 
325         /* FUNCTION LOGIC */
326 
327         /* the pointer to the internal Verify context */
328         pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
329 
330         /* ............... checking the parameters validity ................... */
331         /* -------------------------------------------------------------------- */
332 
333         /* if the users context pointer is NULL return an error */
334         if (pVerifyUserContext == NULL){
335                 return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
336         }
337 
338         /* if the users context TAG is illegal return an error - the context is invalid */
339         if (pVerifyUserContext->valid_tag != CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG){
340                 err = CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR;
341                 goto End;
342         }
343 
344         /* if the users Signature pointer is illegal then return an error */
345         if (pSignatureIn == NULL){
346                 err = CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR;
347                 goto End;
348         }
349 
350 
351         /* ............. checking the validity of context ........ */
352         /* ------------------------------------------------------- */
353 
354         /* check Hash mode */
355         if (pWorkingContext->hashMode >= CC_ECPKI_HASH_NumOfModes){
356                 err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
357                 goto End;
358         }
359 
360         PublKey_ptr = (CCEcpkiPublKey_t *)&pWorkingContext->ECDSA_SignerPublKey.PublKeyDbBuff;
361 
362         /* Initializing domain parameters */
363         pDomain = &PublKey_ptr->domain;
364         orderSizeInBytes  =  CALC_FULL_BYTES(pDomain->ordSizeInBits);
365         orderSizeInWords  =  CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits);
366 
367         /* if the user signature size is not equal to 2*ModSizeInBytes, then return an error */
368         if (SignatureSizeBytes != 2*orderSizeInBytes){
369                 err = CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR;
370                 goto End;
371         }
372 
373         /*Operating the HASH Finish function only in case that Hash operation is needed*/
374         if (pWorkingContext->hashMode <= CC_ECPKI_HASH_SHA512_mode) {
375 #ifdef USE_MBEDTLS_CRYPTOCELL
376                 err = mbedtls_md_finish(&(pWorkingContext->hash_ctx), (unsigned char *)pWorkingContext->hashResult);
377 #else
378                 err = CC_HashFinish(&(pWorkingContext->hashUserCtxBuff), pWorkingContext->hashResult);
379 #endif
380                 if (err != CC_OK)
381                         goto End;
382         }
383 
384         /*  Initialization of  EcWrstDsaVerify arguments */
385         hashSizeWords        = pWorkingContext->hashResultSizeWords;
386         /* Temp buffers */
387         pSignatureC       = ((EcWrstDsaVerifyDb_t*)(pWorkingContext->ccEcdsaVerIntBuff))->tempBuff;
388         pSignatureD       = pSignatureC + orderSizeInWords; /* Max lengths of C in whole words */
389         pMessRepres = pSignatureD + orderSizeInWords;
390 
391         // Check shortened cleaning
392         /* Clean memory  */
393         CC_PalMemSetZero(pSignatureC, 2*4*orderSizeInWords); //-> pSignatureC[orderSizeInWords-1] = 0;
394         //-> pSignatureD[orderSizeInWords-1] = 0;
395         CC_PalMemSetZero(pMessRepres, 4*orderSizeInWords);   //-> pMessRepres[orderSizeInWords-1] = 0;
396 
397         /* Derive message representative = leftmost OrderSizeInBits bits of HASH_Result */
398         if (pDomain->ordSizeInBits >= 32*hashSizeWords) {
399                 CC_CommonReverseMemcpy((uint8_t*)pMessRepres,
400                                           (uint8_t*)(pWorkingContext->hashResult), 4*hashSizeWords);
401         } else {
402                 EcWrstDsaTruncateMsg(pMessRepres,
403                                       (uint8_t*)(pWorkingContext->hashResult), pDomain->ordSizeInBits);
404 
405         }
406 
407         /* Convert signature data to words array with little entian order of  *
408         *  words                                  */
409         pSignatureC[orderSizeInWords-1] = 0;
410         CC_CommonReverseMemcpy((uint8_t*)pSignatureC, pSignatureIn, orderSizeInBytes);
411         pSignatureD[orderSizeInWords-1] = 0;
412         CC_CommonReverseMemcpy((uint8_t*)pSignatureD, pSignatureIn + orderSizeInBytes, orderSizeInBytes);
413 
414         /*------------------------------*/
415         /* Verifying operation      */
416         /*------------------------------*/
417         err =  EcWrstDsaVerify(PublKey_ptr, pMessRepres, orderSizeInWords, pSignatureC, pSignatureD);
418         if (err != CC_OK) {
419                 err = CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR;
420         }
421 
422         End:
423 #ifdef USE_MBEDTLS_CRYPTOCELL
424         mbedtls_md_free(&(pWorkingContext->hash_ctx));
425 #endif
426 
427         /* clear the users context  */
428         CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
429 
430         return err;
431 
432 
433 }/* End EcdsaVerifyFinish */
434 
435 
436 /**************************************************************************
437  *                CC_EcdsaVerify integrated function
438  **************************************************************************/
439 /**
440    @brief  Performs all ECDSA verifying operations simultaneously.
441 
442            This function simply calls the Init, Update and Finish functions continuously.
443 
444        NOTE: Using of HASH functions with HASH size great, than EC modulus size,
445              is not recommended!
446              Algorithm according ANS X9.62 standard
447 
448 
449    @param[in]  pVerifyUserContext - A pointer to the user buffer for verifying database.
450    @param[in]  pUserPublKey       - A pointer to a user public key structure.
451    @param[in]  hashMode              - The enumerator variable defines the hash function to be used.
452    @param[in]  pMessageDataIn     - Message data for calculating hash.
453    @param[in]  messageSizeInBytes    - Size of block of message data in bytes.
454    @param[in]  pSignatureIn       - A pointer to a buffer for output of signature.
455    @param[in]  SignatureSizeBytes    - Size of signature, in bytes (must be 2*orderSizeInBytes).
456 
457    @return <b>CCError_t</b>: <br>
458                         CC_OK <br>
459                         CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
460                         CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
461                         CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR <br>
462                         CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR <br>
463                         CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR <br>
464                         CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
465                         CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR <br>
466                         CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR <br>
467                         CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR <br>
468                         CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR <br>
469                         CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR <br>
470 **/
CC_EcdsaVerify(CCEcdsaVerifyUserContext_t * pVerifyUserContext,CCEcpkiUserPublKey_t * pUserPublKey,CCEcpkiHashOpMode_t hashMode,uint8_t * pSignatureIn,size_t SignatureSizeBytes,uint8_t * pMessageDataIn,size_t messageSizeInBytes)471 CEXPORT_C CCError_t CC_EcdsaVerify (
472                                         CCEcdsaVerifyUserContext_t *pVerifyUserContext,  /*in/out*/
473                                         CCEcpkiUserPublKey_t       *pUserPublKey,        /*in*/
474                                         CCEcpkiHashOpMode_t        hashMode,            /*in*/
475                                         uint8_t                        *pSignatureIn,        /*in*/
476                                         size_t                         SignatureSizeBytes,  /*in*/
477                                         uint8_t                        *pMessageDataIn,      /*in*/
478                                         size_t                         messageSizeInBytes  /*in*/)
479 {
480         /* FUNCTION DECLERATIONS */
481 
482         CCError_t err = CC_OK;
483 
484         /* FUNCTION LOGIC */
485         CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
486 
487 
488         err = EcdsaVerifyInit(pVerifyUserContext, pUserPublKey, hashMode);
489 
490         if (err!=CC_OK)
491                 return err;
492 
493         err = EcdsaVerifyUpdate(pVerifyUserContext, pMessageDataIn, messageSizeInBytes);
494         if (err!=CC_OK)
495                 return err;
496 
497         err = EcdsaVerifyFinish(pVerifyUserContext, pSignatureIn,
498                                       SignatureSizeBytes);
499         return err;
500 
501 }/* END OF CC_EcdsaVerify */
502 
503