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 "cc_pal_mem.h"
8 #include "cc_rnd_common.h"
9 #include "cc_ecpki_types.h"
10 #include "cc_ecpki_error.h"
11 #include "cc_ecpki_local.h"
12 #include "pki.h"
13 #include "ec_wrst.h"
14 #include "cc_general_defs.h"
15 #include "cc_fips_defs.h"
16 #include "cc_rnd_local.h"
17 
18 
19 /***************  CC_EcpkiKeyPairGenerateBase function  **************/
20 /**
21  @brief Generates a pair of private and public keys using configurable base point
22  in little endian ordinary form according to [ANS X9.31].
23 
24     The function performs the following:
25       1. Checks the validity of all of the function inputs. If one of the received
26          parameters is not valid, it returns an error.
27       2. Cleans buffers and generates random private key.
28       3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
29       4. Outputs the user public and private key structures in little endian form.
30       5. Cleans temporary buffers.
31       6. Exits.
32 
33  @param [in/out] pRndContext - Pointer to RND context.
34  @param [in] pDomain  - The pointer to current EC domain.
35  @param [in] ecX_ptr - The X cordinate of the base point. little endian.
36  @param [in] ecY_ptr - The Y cordinate of the base point. little endian.
37  @param [out] pUserPrivKey - The pointer to the private key structure.
38  @param [out] pUserPublKey - The pointer to the public key structure.
39  @param [in] pTempBuf - Temporary buffers of size, defined by CCEcpkiKgTempData_t.
40  @param [in] pFipsCtx - Pointer to temporary buffer used in case FIPS certification if required
41 
42  @return <b>CCError_t</b>: <br>
43                        CC_OK<br>
44                         CC_ECPKI_RND_CONTEXT_PTR_ERROR
45                         CC_ECPKI_DOMAIN_PTR_ERROR<br>
46                         CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR<br>
47                         CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR<br>
48                         CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR<br>
49 */
CC_EcpkiKeyPairGenerateBase(CCRndContext_t * pRndContext,const CCEcpkiDomain_t * pDomain,const uint32_t * ecX_ptr,const uint32_t * ecY_ptr,CCEcpkiUserPrivKey_t * pUserPrivKey,CCEcpkiUserPublKey_t * pUserPublKey,CCEcpkiKgTempData_t * pTempBuff,CCEcpkiKgFipsContext_t * pFipsCtx)50 CEXPORT_C CCError_t CC_EcpkiKeyPairGenerateBase(
51                                            CCRndContext_t              *pRndContext,         /*in/out*/
52                                            const CCEcpkiDomain_t       *pDomain,             /*in*/
53                                            const uint32_t              *ecX_ptr,             /*in*/
54                                            const uint32_t              *ecY_ptr,             /*in*/
55                                            CCEcpkiUserPrivKey_t        *pUserPrivKey,        /*out*/
56                                            CCEcpkiUserPublKey_t        *pUserPublKey,        /*out*/
57                                            CCEcpkiKgTempData_t         *pTempBuff,           /*in*/
58                                            CCEcpkiKgFipsContext_t      *pFipsCtx)            /*in*/
59 {
60         CCError_t err = CC_OK;
61         CCEcpkiPrivKey_t *pPrivKey;
62         uint32_t  orderSizeInWords;
63 
64         CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
65 
66 
67         /* ......... checking the validity of arguments .......... */
68         /* ------------------------------------------------------- */
69 
70         if (pRndContext == NULL)
71                 return CC_ECPKI_RND_CONTEXT_PTR_ERROR;
72 
73         if (pDomain == NULL)
74                 return CC_ECPKI_DOMAIN_PTR_ERROR;
75 
76         if (ecX_ptr == NULL || ecY_ptr == NULL)
77             return CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR;
78 
79         if (pUserPrivKey == NULL)
80                 return CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR;
81 
82         if (pUserPublKey == NULL)
83                 return CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR;
84 
85         if (pTempBuff == NULL)
86                 return CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR;
87 
88         /* .........  clear all input structures  ............*/
89 
90         CC_PalMemSetZero( pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t) );
91         CC_PalMemSetZero( pUserPublKey, sizeof(CCEcpkiUserPublKey_t) );
92 
93         /* the pointer to the key database */
94         pPrivKey = (CCEcpkiPrivKey_t *)&pUserPrivKey->PrivKeyDbBuff;
95 
96         orderSizeInWords = (pDomain->ordSizeInBits+CC_BITS_IN_32BIT_WORD-1)/CC_BITS_IN_32BIT_WORD;
97         /*  set EC order as max. vect. */
98         CC_PalMemCopy(pTempBuff, pDomain->ecR, sizeof(uint32_t)*orderSizeInWords);
99 
100         /* generate random private key vector in range: 1 < privKey < EcOrder *
101          * Note: we exclude privKey = 1, allowed by FIPS 186-4, because the   *
102         *  negligible low probability of its random generation                */
103         pPrivKey->PrivKey[orderSizeInWords - 1] = 0;
104         err = CC_RndGenerateVectorInRange(pRndContext, (uint32_t)pDomain->ordSizeInBits,
105                                             (uint8_t*)pTempBuff/*MaxVect*/, (uint8_t*)pPrivKey->PrivKey/*RndVect*/);
106         if (err) {
107                 goto End;
108         }
109 
110         err = EcWrstGenKeyPairBase(pDomain, ecX_ptr, ecY_ptr, pUserPrivKey, pUserPublKey, pTempBuff);
111         if (err) {
112                 goto End;
113         }
114 
115         err = FIPS_ECC_VALIDATE(pRndContext, pUserPrivKey, pUserPublKey, pFipsCtx);
116 
117         End:
118         if (err) {
119                 CC_PalMemSetZero(pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t));
120                 CC_PalMemSetZero(pUserPublKey, sizeof(CCEcpkiUserPublKey_t));
121         }
122         if (pFipsCtx != NULL) {
123                 CC_PalMemSetZero(pFipsCtx, sizeof(CCEcpkiKgFipsContext_t));
124         }
125 
126         CC_PalMemSetZero(pTempBuff, sizeof(CCEcpkiKgTempData_t));
127         return err;
128 }/* END OF CC_EcpkiKeyPairGenerateBase */
129 
130 /***************  CC_EcpkiKeyPairGenerate function  **************/
131 /**
132  @brief Generates a pair of private and public keys in little endian ordinary form according to [ANS X9.31].
133 
134     The function performs the following:
135       1. Checks the validity of all of the function inputs. If one of the received
136          parameters is not valid, it returns an error.
137       2. Cleans buffers and generates random private key.
138       3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
139       4. Outputs the user public and private key structures in little endian form.
140       5. Cleans temporary buffers.
141       6. Exits.
142 
143  @param [in/out] pRndContext - The pointer to random context (state).
144  @param [in] pDomain  - The pointer to current EC domain.
145  @param [out] pUserPrivKey - The pointer to the private key structure.
146  @param [out] pUserPublKey - The pointer to the public key structure.
147  @param [in] pTempBuf - Temporary buffers of size, defined by CCEcpkiKgTempData_t.
148  @param [in] pFipsCtx - Pointer to temporary buffer used in case FIPS certification if required
149 
150  @return <b>CCError_t</b>: <br>
151                        CC_OK<br>
152                         CC_ECPKI_RND_CONTEXT_PTR_ERROR
153                         CC_ECPKI_DOMAIN_PTR_ERROR<br>
154                         CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR<br>
155                         CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR<br>
156                         CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR<br>
157 */
CC_EcpkiKeyPairGenerate(CCRndContext_t * pRndContext,const CCEcpkiDomain_t * pDomain,CCEcpkiUserPrivKey_t * pUserPrivKey,CCEcpkiUserPublKey_t * pUserPublKey,CCEcpkiKgTempData_t * pTempBuff,CCEcpkiKgFipsContext_t * pFipsCtx)158 CEXPORT_C CCError_t CC_EcpkiKeyPairGenerate(
159                                            CCRndContext_t         *pRndContext,  /*in/out*/
160                                            const CCEcpkiDomain_t  *pDomain,      /*in*/
161                                            CCEcpkiUserPrivKey_t   *pUserPrivKey, /*out*/
162                                            CCEcpkiUserPublKey_t   *pUserPublKey, /*out*/
163                                            CCEcpkiKgTempData_t   *pTempBuff,    /*in*/
164                                            CCEcpkiKgFipsContext_t *pFipsCtx)    /*in*/
165 {
166 
167     if (NULL == pDomain) {
168         return CC_ECPKI_DOMAIN_PTR_ERROR;
169     }
170 
171     return CC_EcpkiKeyPairGenerateBase(pRndContext, pDomain, pDomain->ecGx, pDomain->ecGy,
172                                        pUserPrivKey, pUserPublKey, pTempBuff, pFipsCtx);
173 }
174 
175 /**********************************************************************/
176 
177 
178 
179