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