1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /************* Include Files ****************/
8 #include "mbedtls_cc_ecies.h"
9 
10 #include "cc_pal_mem.h"
11 #include "cc_pal_log.h"
12 #include "cc_pal_types.h"
13 
14 #include "cc_ecpki_build.h"
15 #include "cc_ecpki_error.h"
16 #include "cc_ecpki_domain.h"
17 #include "cc_rnd_common.h"
18 #include "cc_ecpki_kg.h"
19 #include "ecp_common.h"
20 #include "ec_wrst.h"
21 #include "cc_kdf.h"
22 #include "mbedtls_cc_hkdf.h"
23 #include "mbedtls_common.h"
24 
25 #include "mbedtls/platform.h"
26 
27 /************************ Defines *************************************/
28 
29 /************************ Enums ***************************************/
30 
31 /************************ Typedefs ************************************/
32 
33 /************************ Global Data *********************************/
34 
35 /************* Private function prototype *****************************/
ecies_convert_mbed_to_cc_hkdf_hash_mode(mbedtls_hkdf_hashmode_t mode)36 static CCKdfHashOpMode_t ecies_convert_mbed_to_cc_hkdf_hash_mode(mbedtls_hkdf_hashmode_t mode)
37 {
38     switch (mode)
39     {
40         case CC_HKDF_HASH_SHA1_mode:
41             return CC_KDF_HASH_SHA1_mode;
42         case CC_HKDF_HASH_SHA224_mode:
43             return CC_KDF_HASH_SHA224_mode;
44         case CC_HKDF_HASH_SHA256_mode:
45             return CC_KDF_HASH_SHA256_mode;
46         case CC_HKDF_HASH_SHA384_mode:
47             return CC_KDF_HASH_SHA384_mode;
48         case CC_HKDF_HASH_SHA512_mode:
49             return CC_KDF_HASH_SHA512_mode;
50         default:
51             return CC_KDF_HASH_OpModeLast;
52     }
53 }
54 
ecies_convert_mbed_to_cc_public_key(const mbedtls_ecp_group * pGrp,const CCEcpkiDomain_t * pDomain,mbedtls_ecp_point * pPubKey,CCEcpkiUserPublKey_t * pUserPublKey,CCEciesTempData_t * tempBuff)55 static int ecies_convert_mbed_to_cc_public_key(const mbedtls_ecp_group *pGrp, /*in*/
56                                                const CCEcpkiDomain_t *pDomain,
57                                                mbedtls_ecp_point *pPubKey, /*in*/
58                                                CCEcpkiUserPublKey_t *pUserPublKey, /*out*/
59                                                CCEciesTempData_t *tempBuff /*in*/)
60 
61 {
62     int error = 0;
63     size_t keylen = 0;
64     uint8_t *pBuf = NULL;
65     CCEcpkiBuildTempData_t *pTempBuildBuff = NULL;
66     size_t bufSize = 0;
67 
68     if (tempBuff == NULL)
69     {
70         CC_PAL_LOG_ERR("Error - tempBuff is NULL\n");
71         error = CC_ECIES_INVALID_PTR;
72         goto EXIT_ON_ERROR;
73     }
74 
75     pTempBuildBuff = &tempBuff->tmp.buildTempbuff;
76     pBuf = (uint8_t*)&tempBuff->ConvPublKey;
77     bufSize = sizeof(tempBuff->ConvPublKey);
78 
79     /* write mpi to buf */
80     if ((error = mbedtls_ecp_point_write_binary(pGrp,
81                                                 pPubKey,
82                                                 MBEDTLS_ECP_PF_UNCOMPRESSED,
83                                                 &keylen,
84                                                 pBuf,
85                                                 bufSize)) != 0)
86     {
87         CC_PAL_LOG_ERR("Error - failed to write mpi\n");
88         goto EXIT_ON_ERROR;
89     }
90 
91     if ((error = CC_EcpkiPublKeyBuildAndCheck(pDomain,
92                                               pBuf,
93                                               keylen,
94                                               ECpublKeyFullCheck,
95                                               pUserPublKey,
96                                               pTempBuildBuff)) != CC_OK)
97     {
98         CC_PAL_LOG_ERR("Error - failed CC_EcpkiPublKeyBuildAndCheck\n");
99         goto EXIT_ON_ERROR;
100     }
101 
102 EXIT_ON_ERROR:
103     return error;
104 
105 }
106 
ecies_convert_mbed_to_cc_private_key(const CCEcpkiDomain_t * pDomain,mbedtls_mpi * pPrivKey,CCEcpkiUserPrivKey_t * pUserPrivKey,CCEciesTempData_t * tempBuff)107 static int ecies_convert_mbed_to_cc_private_key(const CCEcpkiDomain_t *pDomain,
108                                                 mbedtls_mpi *pPrivKey, /*in*/
109                                                 CCEcpkiUserPrivKey_t *pUserPrivKey /*out*/,
110                                                 CCEciesTempData_t *tempBuff)
111 {
112     int error = 0;
113     size_t n = 0;
114     CCEcpkiBuildTempData_t *pTempBuildBuff = NULL;
115     if (tempBuff == NULL)
116     {
117         CC_PAL_LOG_ERR("Error - tempBuff is NULL\n");
118         error = CC_ECIES_INVALID_PTR;
119         goto EXIT_ON_ERROR;
120     }
121 
122     pTempBuildBuff = &tempBuff->tmp.buildTempbuff;
123     n = mbedtls_mpi_size( pPrivKey );
124 
125     if (n > sizeof(*pTempBuildBuff))
126     {
127         CC_PAL_LOG_ERR("Error - n[%u] latger pTempBuildBuff struct[%u]\n", n, sizeof(*pTempBuildBuff));
128         error = CC_ECIES_INVALID_TEMP_DATA_SIZE_ERROR;
129         goto EXIT_ON_ERROR;
130     }
131     /* write mpi to buf */
132     if ((error = mbedtls_mpi_write_binary(pPrivKey, (uint8_t*)pTempBuildBuff, n)) != 0)
133     {
134         CC_PAL_LOG_ERR("Error - failed to write mpi\n");
135         goto EXIT_ON_ERROR;
136     }
137 
138     if ((error = CC_EcpkiPrivKeyBuild(pDomain, (uint8_t*)pTempBuildBuff, n, pUserPrivKey)) != CC_OK)
139     {
140         CC_PAL_LOG_ERR("Error - failed to CC_EcpkiPrivKeyBuild n[%u]\n", n);
141         goto EXIT_ON_ERROR;
142     }
143 
144 EXIT_ON_ERROR:
145     return error;
146 
147 }
148 
ecies_free_keys(CCEcpkiUserPrivKey_t * a,CCEcpkiUserPublKey_t * b)149 static void ecies_free_keys(CCEcpkiUserPrivKey_t *a, CCEcpkiUserPublKey_t *b)
150 {
151     if (a != NULL)
152     {
153         CC_PalMemSetZero(a, sizeof(*a));
154         mbedtls_free(a);
155     }
156 
157     if (b != NULL)
158     {
159         CC_PalMemSetZero(b, sizeof(*b));
160         mbedtls_free(b);
161     }
162 }
163 
164 /************************ Public Functions ****************************/
mbedtls_ecies_kem_encrypt_full(mbedtls_ecp_group * pGrp,mbedtls_ecp_point * pRecipUzPublKey,CCKdfDerivFuncMode_t kdfDerivMode,mbedtls_hkdf_hashmode_t kdfHashMode,uint32_t isSingleHashMode,mbedtls_ecp_point * pExtEphUzPublicKey,mbedtls_mpi * pExtEphUzPrivateKey,uint8_t * pSecrKey,size_t secrKeySize,uint8_t * pCipherData,size_t * pCipherDataSize,void * pBuff,size_t buffLen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)165 CCError_t mbedtls_ecies_kem_encrypt_full(mbedtls_ecp_group *pGrp,
166                                          mbedtls_ecp_point *pRecipUzPublKey,
167                                          CCKdfDerivFuncMode_t kdfDerivMode,
168                                          mbedtls_hkdf_hashmode_t kdfHashMode,
169                                          uint32_t isSingleHashMode,
170                                          mbedtls_ecp_point *pExtEphUzPublicKey,
171                                          mbedtls_mpi *pExtEphUzPrivateKey,
172                                          uint8_t *pSecrKey,
173                                          size_t secrKeySize,
174                                          uint8_t *pCipherData,
175                                          size_t *pCipherDataSize,
176                                          void *pBuff,
177                                          size_t buffLen,
178                                          int (*f_rng)(void *, unsigned char *, size_t),
179                                          void *p_rng)
180 {
181 
182     /* LOCAL DECLARATIONS */
183     CCError_t error = CC_OK;
184 
185     /*  pointer to EC domain  */
186     const CCEcpkiDomain_t *pDomain;
187     CCEcpkiDomainID_t domain_id;
188 
189     uint32_t modSizeInBytes, kdfDataSize;
190     uint8_t *pKdfData;
191 
192 
193     /* pointers to ephemeral key pair, which should be used */
194     CCEcpkiUserPublKey_t *pCcReciptUzPublKey = NULL;
195     CCEcpkiUserPrivKey_t *pEphUzPrivKey = NULL;
196     CCEcpkiUserPublKey_t *pEphUzPublKey = NULL;
197     CCEcpkiPublKey_t *pRecipPublKey = NULL;
198     CCEcpkiPrivKey_t *pEphPrivKey = NULL;
199 
200     CCEciesTempData_t *pTempBuff = NULL;
201     CCRndContext_t *pRndContext = NULL;
202 
203     /* Initialize Error */
204     error = CC_OK;
205 
206     /* .........    checking the validity of input parameters  .......... */
207     /* Note: pRndContext and pFipsCtx will be checked in called functions */
208     /* ------------------------------------------------------------------- */
209 
210     /* check the validity of the user static private key */
211     if (pRecipUzPublKey == NULL)
212         return CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR;
213 
214     /* check KDF and HASH modes */
215     if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode && kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
216         return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
217 
218     /* check HASH mode */
219     if (kdfHashMode >= CC_HKDF_HASH_NumOfModes)
220         return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
221 
222     /* check the pointer to the buffer for secret key output */
223     if (pSecrKey == NULL)
224         return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
225 
226     /* check the size of secret key to be generated */
227     if (secrKeySize == 0)
228         return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
229 
230     /* checking the buffer for cipher text output */
231     if (pCipherData == NULL)
232         return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
233 
234     if (pCipherDataSize == NULL)
235         return CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR;
236 
237     if ((pExtEphUzPublicKey != NULL) ^ (pExtEphUzPrivateKey != NULL))
238         return CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR;
239 
240     /* checking the temp buffer pointer  */
241     if (pBuff == NULL)
242         return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
243 
244     if (buffLen < sizeof(CCEciesTempData_t))
245         return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
246 
247 
248     /* ..  initializtions  and other checking   .... */
249     /* --------------------------------------------- */
250 
251     /* convert grp_id to domain ID */
252     if ((error = ecp_grp_id_to_domain_id(pGrp->id, &domain_id)) != 0)
253     {
254         CC_PAL_LOG_ERR("Error - failed to ecp_grp_id_to_domain_id grpId[%u]. error[0x%08x]\n", pGrp->id, error);
255         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
256         goto End;
257     }
258 
259     /* check EC Domain ID */
260     if (domain_id >= CC_ECPKI_DomainID_OffMode)
261     {
262         CC_PAL_LOG_ERR("Error - domain_id[%u] larger than CC_ECPKI_DomainID_OffMode[%u]\n", domain_id, CC_ECPKI_DomainID_OffMode);
263         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
264         goto End;
265     }
266 
267     /* get domain from id */
268     pDomain = CC_EcpkiGetEcDomain(domain_id);
269     if (pDomain == NULL)
270     {
271         CC_PAL_LOG_ERR("Error - failed to get pDomain by id[%u]\n", domain_id);
272         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
273         goto End;
274     }
275 
276     /* convert mbedtls keys to cc structs */
277     pTempBuff = (CCEciesTempData_t *)pBuff;
278 
279     pCcReciptUzPublKey = mbedtls_calloc(1, sizeof(*pCcReciptUzPublKey));
280     if (pCcReciptUzPublKey == NULL)
281     {
282         CC_PAL_LOG_ERR("Error - pCcReciptUzPublKey failed to allocate\n");
283         error = CC_ECIES_INVALID_PTR;
284         goto End;
285     }
286 
287     if ((error = ecies_convert_mbed_to_cc_public_key(pGrp, pDomain, pRecipUzPublKey, pCcReciptUzPublKey, pTempBuff)) != 0)
288     {
289         CC_PAL_LOG_ERR("Error - failed to ecp_convert_mbed_to_cc_public_key receipt public key. error[0x%08x]\n", error);
290         goto End;
291     }
292 
293      /* derive and check domainID from recipient Public Key */
294     pRecipPublKey = (CCEcpkiPublKey_t*) &pCcReciptUzPublKey->PublKeyDbBuff;
295 
296     /* modulus size */
297     modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
298 
299     /* check cipher output buffer size */
300     if (*pCipherDataSize < 2 * modSizeInBytes + 1)
301     {
302         CC_PAL_LOG_ERR("Error - size mismatch dataSize[%u] keyDataSize[%u]\n", *pCipherDataSize, 2 * modSizeInBytes + 1);
303         error = CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR;
304         goto End;
305     }
306 
307     if (pExtEphUzPublicKey == NULL && pExtEphUzPrivateKey == NULL)
308     {
309         pRndContext = mbedtls_calloc(1, sizeof(CCRndContext_t));
310         if (pRndContext == NULL)
311         {
312             CC_PAL_LOG_ERR("Error - failed to allocate CCRndContext_t\n");
313             error = CC_ECIES_INVALID_PTR;
314             goto End;
315         }
316 
317         if (f_rng == NULL)
318         {
319             CC_PAL_LOG_ERR("Error - f_rng is NULL\n");
320             error = CC_ECIES_INVALID_PTR;
321             goto End;
322         }
323 
324         pRndContext->rndGenerateVectFunc = (CCRndGenerateVectWorkFunc_t)f_rng;
325         pRndContext->rndState = p_rng;
326 
327         /* use internal genrated ephemeral Key Pair */
328         error = CC_EcpkiKeyPairGenerate(pRndContext, /*in/out*/
329                                         pDomain,
330                                         &pTempBuff->PrivKey,
331                                         &pTempBuff->PublKey,
332                                         &pTempBuff->tmp.KgTempBuff,
333                                         NULL);
334 
335         CC_PalMemSetZero(pRndContext, sizeof(*pRndContext));
336         mbedtls_free(pRndContext);
337 
338         if (error != CC_OK)
339             goto End;
340 
341         pEphUzPrivKey = &pTempBuff->PrivKey;    // r
342         pEphUzPublKey = &pTempBuff->PublKey;    // g~ = r*G
343     }
344     else
345     {
346         pEphUzPrivKey = &pTempBuff->PrivKey;
347         pEphUzPublKey = &pTempBuff->PublKey;
348 
349         /* use external ephemeral Key Pair */
350         if ((error = ecies_convert_mbed_to_cc_private_key(pDomain, pExtEphUzPrivateKey, pEphUzPrivKey, pTempBuff)) != 0)
351         {
352             CC_PAL_LOG_ERR("Error - failed to ecies_convert_mbed_to_cc_private_key. error[0x%08x]\n", error);
353             ecies_free_keys(pEphUzPrivKey, pEphUzPublKey);
354             goto End;
355         }
356 
357         if ((error = ecies_convert_mbed_to_cc_public_key(pGrp, pDomain, pExtEphUzPublicKey, pEphUzPublKey, pTempBuff)) != 0)
358         {
359             CC_PAL_LOG_ERR("Error - failed to ecies_convert_mbed_to_cc_public_key. error[0x%08x]\n", error);
360             ecies_free_keys(pEphUzPrivKey, pEphUzPublKey);
361             goto End;
362         }
363     }
364 
365     /* convert ephemeral public key to standard form */
366     error = CC_EcpkiPubKeyExport(pEphUzPublKey, /*in*/
367                                  CC_EC_PointUncompressed, /*in*/
368                                  (uint8_t*) &pTempBuff->zz, /*out*/
369                                  pCipherDataSize); /*in/out*//* Number of Bytes that were copied to zz*/
370     if (error != CC_OK)
371     {
372         CC_PAL_LOG_ERR("Error - failed to CC_EcpkiPubKeyExport. error[0x%08x]\n", error);
373         goto End;
374     }
375 
376     /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value */
377     /* --------------------------------------------------------------- */        // h~ = r*h
378     pEphPrivKey = (CCEcpkiPrivKey_t*) &pEphUzPrivKey->PrivKeyDbBuff;
379     error = EcWrstDhDeriveSharedSecret(pRecipPublKey, /*in*/
380                                        (CCEcpkiPrivKey_t *) (pEphPrivKey->PrivKey), /*in*/
381                                        &((uint8_t*) &pTempBuff->zz)[*pCipherDataSize], /*out*//* Next available space in zz where the (SV X coordinate of multiplication) will be stored*/
382                                        &pTempBuff->tmp.DhTempBuff); /*in*/
383     if (error != CC_OK)
384     {
385         CC_PAL_LOG_ERR("Error - failed to EcWrstDhDeriveSharedSecret. error[0x%08x]\n", error);
386         goto End;
387     }
388 
389     /* derive the Keying Data from the Secret Value by calling the KDF function    */
390     /* --------------------------------------------------------------------------- */
391 
392     /* set pointer  and size of input data for KDF function */
393     if (isSingleHashMode == CC_TRUE)
394     { /* z = X */
395         pKdfData = &((uint8_t*) &pTempBuff->zz)[*pCipherDataSize];
396         kdfDataSize = modSizeInBytes;
397     }
398     else
399     { /*z = C0 || X*/
400         pKdfData = (uint8_t*) &pTempBuff->zz;
401         kdfDataSize = *pCipherDataSize + modSizeInBytes;
402     }
403 
404     /*derive the Keying Data */
405     error = CC_KdfKeyDerivFunc(pKdfData/*ZZSecret*/,
406                                kdfDataSize/*ZZSecretSize*/,
407                                NULL/*&otherInfo*/,
408                                ecies_convert_mbed_to_cc_hkdf_hash_mode(kdfHashMode),
409                                kdfDerivMode,
410                                pSecrKey,
411                                secrKeySize);
412     if (error != CC_OK)
413     {
414         CC_PAL_LOG_ERR("Error - failed to CC_KdfKeyDerivFunc. error[0x%08x]\n", error);
415         goto End;
416     }
417 
418     /* Output of the Cipher Data (C0) = Ephemeral Public Key */
419     CC_PalMemCopy(pCipherData, pTempBuff->zz, *pCipherDataSize);
420 
421 End:
422 
423     if (error != CC_OK)
424     {
425         *pCipherDataSize = 0;
426     }
427 
428     ecies_free_keys(NULL, pCcReciptUzPublKey);
429 
430     /* clean temp buffers */
431     CC_PalMemSetZero(pBuff, buffLen);
432 
433     return error;
434 
435 }/* END OF CC_EciesKemEncrypt */
436 
mbedtls_ecies_kem_decrypt(mbedtls_ecp_group * pGrp,mbedtls_mpi * pRecipUzPrivKey,CCKdfDerivFuncMode_t kdfDerivMode,mbedtls_hkdf_hashmode_t kdfHashMode,uint32_t isSingleHashMode,uint8_t * pCipherData,size_t cipherDataSize,uint8_t * pSecrKey,size_t secrKeySize,void * pBuff,size_t buffLen)437 CCError_t mbedtls_ecies_kem_decrypt(mbedtls_ecp_group *pGrp,
438                                     mbedtls_mpi *pRecipUzPrivKey,
439                                     CCKdfDerivFuncMode_t kdfDerivMode,
440                                     mbedtls_hkdf_hashmode_t kdfHashMode,
441                                     uint32_t isSingleHashMode,
442                                     uint8_t *pCipherData,
443                                     size_t cipherDataSize,
444                                     uint8_t *pSecrKey,
445                                     size_t secrKeySize,
446                                     void *pBuff,
447                                     size_t buffLen)
448 {
449 
450     /* LOCAL DECLARATIONS */
451 
452     CCError_t error = CC_OK;
453 
454     /*  pointer to EC domain  */
455     const CCEcpkiDomain_t *pDomain;
456     CCEcpkiDomainID_t domain_id;
457 
458     uint32_t modSizeInBytes, kdfDataSize;
459     uint8_t *pKdfData;
460 
461     CCEcpkiPrivKey_t *pRecipPrivKey = NULL;
462     CCEcpkiUserPrivKey_t *pRecipUserPrivKey;
463 
464     CCEciesTempData_t *pTempBuff = NULL;
465 
466     /* ................. checking the validity of input parameters  .......... */
467     /* ----------------------------------------------------------------------- */
468 
469     /* check the validity of the recipient's private key */
470     if (pRecipUzPrivKey == NULL)
471         return CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR;
472 
473     /*check KDF and HASH modes */
474     if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode && kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
475         return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
476 
477     if (kdfHashMode >= CC_HKDF_HASH_NumOfModes) {
478         return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
479     }
480 
481     /* check the pointer to the buffer for secret key output */
482     if (pSecrKey == NULL)
483         return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
484 
485     /* checking the size of secret key to be generated */
486     if (secrKeySize == 0)
487         return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
488 
489     /* check the buffer for cipher text output */
490     if (pCipherData == NULL)
491         return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
492 
493     /* checking the temp buffer pointer  */
494     if (pBuff == NULL)
495         return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
496 
497     /* check the buffer is bug enough */
498     if (buffLen < MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES)
499     {
500         CC_PAL_LOG_ERR("Error - buffLen[%u] < MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES[%u]\n", buffLen, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
501         return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
502     }
503 
504     /* ..  initializations  and other checking   .... */
505     /* ---------------------------------------------- */
506 
507     /* convert grp_id to domain ID */
508     if ((error = ecp_grp_id_to_domain_id(pGrp->id, &domain_id)) != 0)
509     {
510         CC_PAL_LOG_ERR("Error - failed to ecp_grp_id_to_domain_id grpId[%u]. error[0x%08x]\n", pGrp->id, error);
511         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
512         goto End;
513     }
514 
515     /* check EC Domain ID */
516     if (domain_id >= CC_ECPKI_DomainID_OffMode)
517     {
518         CC_PAL_LOG_ERR("Error - domain_id[%u] larger than CC_ECPKI_DomainID_OffMode[%u]\n", domain_id, CC_ECPKI_DomainID_OffMode);
519         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
520         goto End;
521     }
522 
523     /* get domain from id */
524     pDomain = CC_EcpkiGetEcDomain(domain_id);
525     if (pDomain == NULL)
526     {
527         CC_PAL_LOG_ERR("Error - failed to get pDomain by id[%u]\n", domain_id);
528         error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
529         goto End;
530     }
531 
532     /* convert mbedtls keys to cc structs */
533     pTempBuff = (CCEciesTempData_t *)pBuff;
534     pRecipUserPrivKey = &pTempBuff->PrivKey;
535 
536     if ((error = ecies_convert_mbed_to_cc_private_key(pDomain, pRecipUzPrivKey, pRecipUserPrivKey, pTempBuff)) != 0)
537     {
538         CC_PAL_LOG_ERR("Error - failed to ecp_convert_mbed_to_cc_public_key reciept public key. error[0x%08x]\n", error);
539         goto End;
540     }
541 
542     /* derive domainID from recipient Private Key */
543     pRecipPrivKey = (CCEcpkiPrivKey_t*) &(pRecipUserPrivKey->PrivKeyDbBuff);
544 
545     /* modulus size */
546     modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
547 
548     /* partially check the cipher data C0 (ephemeral public key)
549      and initialize appropriate CC Key structure */
550     error = CC_EcpkiPublKeyBuildAndCheck(pDomain, /*in*/
551                                          pCipherData, /*in - ephem. publ.key data*/
552                                          cipherDataSize, /*in*/
553                                          ECpublKeyPartlyCheck, /*in*/
554                                          &pTempBuff->PublKey, /*out*/
555                                          &pTempBuff->tmp.buildTempbuff); /*in*/
556     if (error != CC_OK)
557         goto End;
558 
559     /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value SV */
560     /* ----------------------------------------------------------------- */
561     error = EcWrstDhDeriveSharedSecret((CCEcpkiPublKey_t*) &pTempBuff->PublKey.PublKeyDbBuff, /*in*/
562                                        (CCEcpkiPrivKey_t *) pRecipPrivKey->PrivKey, /*in*/
563                                        &((uint8_t*) &pTempBuff->zz)[cipherDataSize], /*out*/
564                                        &pTempBuff->tmp.DhTempBuff); /*in*/
565 
566     if (error != CC_OK)
567         goto End;
568 
569     /* set pointer  and size of input data for KDF function */
570     if (isSingleHashMode == CC_TRUE)
571     { /* zz = SV */
572         pKdfData = &((uint8_t*) &pTempBuff->zz)[cipherDataSize];
573         kdfDataSize = modSizeInBytes;
574     }
575     else
576     { /* zz = C0 || SV */
577         pKdfData = (uint8_t*) &pTempBuff->zz;
578         kdfDataSize = cipherDataSize + modSizeInBytes;
579         /* set cipherData  C0 in the temp buffer zz */
580         CC_PalMemCopy((uint8_t* )&pTempBuff->zz, pCipherData, cipherDataSize);
581     }
582 
583     /* derive the Keying Data from the ZZ Value by calling the KDF function */
584     /* -----------------------------------------------------------------  - */
585     error = CC_KdfKeyDerivFunc(pKdfData/*ZZSecret*/,
586                                kdfDataSize/*ZZSecretSize*/,
587                                NULL/*&otherInfo*/,
588                                ecies_convert_mbed_to_cc_hkdf_hash_mode(kdfHashMode),
589                                kdfDerivMode,
590                                pSecrKey,
591                                secrKeySize);
592 End:
593     /* clean temp buffers */
594     CC_PalMemSetZero(pBuff, buffLen);
595 
596     return error;
597 
598 }
599