1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include "cc_pal_mem.h"
7 #include "cc_pal_mutex.h"
8 #include "cc_pal_abort.h"
9 #include "cc_common_math.h"
10 #include "cc_ecpki_types.h"
11 #include "cc_ecpki_error.h"
12 #include "cc_ecpki_local.h"
13 #include "pka_hw_defs.h"
14 #include "cc_ecpki_types.h"
15 #include "pki.h"
16 #include "pka.h"
17 #include "pka_error.h"
18 #include "ec_wrst.h"
19 #include "pka_ec_wrst.h"
20 #include "ec_wrst_error.h"
21 #include "pki_modular_arithmetic.h"
22 #include "pki_dbg.h"
23 #include "cc_common.h"
24 #include "pka_point_compress_regs_def.h"
25
26 /*********** EcWrstInitPubKey function **********************/
27 /**
28 * @brief Performs uncompression (extracts Y-coordinate) checks
29 * and inits the public key (ANS X9.62-2005).
30 *
31 * @author reuvenl (22/09/2014)
32 *
33 * @return - On success CC_OK is returned, on failure an error code.
34 *
35 */
EcWrstInitPubKey(CCEcpkiPublKey_t * pPublKey,uint8_t pointCtl)36 CCError_t EcWrstInitPubKey(CCEcpkiPublKey_t *pPublKey, /*!< [in/out] Pointer to the public key structure. */
37 uint8_t pointCtl) /*!< [in] EC point control byte = (compression mode | Y-MSbit). */
38 {
39 CCError_t err = CC_OK;
40 uint32_t modSizeInBits, modSizeInWords;
41 CCEcpkiDomain_t *pDomain;
42 uint32_t w;
43 bool rootExist;
44 uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
45
46 /* EC domain parameters */
47 pDomain = &pPublKey->domain;
48
49 modSizeInBits = pDomain->modSizeInBits;
50 modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
51
52 if (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)
53 return CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
54
55 /* lock mutex and init PKA */
56 err = PkaInitAndMutexLock(modSizeInBits, &pkaReqRegs);
57 if (err != CC_OK) {
58 return err;
59 }
60
61 /* set modulus P and Barrett tag NP into PKA registers 0,1 */
62 PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, 1, pDomain->ecP, modSizeInWords);
63
64 PkaCopyDataIntoPkaReg(PKA_REG_NP/*dstReg*/, 1, pDomain->llfBuff/*NP*/,
65 CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
66
67 /* set public key coordinates into PKA registers */
68 PkaCopyDataIntoPkaReg(PKA_REG_X/*dstReg*/, 1, pPublKey->x, modSizeInWords);
69
70 /* set EC params */
71 PkaCopyDataIntoPkaReg(PKA_REG_EC_A/*dstReg*/, 1, pDomain->ecA, modSizeInWords);
72 PkaCopyDataIntoPkaReg(PKA_REG_EC_B/*dstReg*/, 1, pDomain->ecB, modSizeInWords);
73
74 /* calculate y^2 for from x */
75 PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T/*Res*/, PKA_REG_X/*OpA*/, PKA_REG_X/*OpB*/);
76 PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, PKA_REG_T/*Res*/, PKA_REG_T/*OpA*/, PKA_REG_EC_A/*OpB*/);
77 PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T/*Res*/, PKA_REG_X/*OpA*/, PKA_REG_T/*OpB*/);
78 PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y2/*=PKA_REG_EC_A*/, PKA_REG_T/*OpA*/, PKA_REG_EC_B/*OpB*/);
79
80 if((pointCtl & 6) != 2) {
81 /* Partly check uncompressed key (is it on curve ?) */
82 /* calculate y^2 directly */
83 PkaCopyDataIntoPkaReg(PKA_REG_Y/*dstReg*/, 1, pPublKey->y, modSizeInWords);
84 PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T, PKA_REG_Y, PKA_REG_Y);
85 PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y2, PKA_REG_T, w/*stat*/);
86 if(w != 1) {
87 err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
88 goto End;
89 }
90 }
91 else {
92 /* Uncompress the Y coordinate if needed */
93 /* derive modular square root (in/out registers according to *
94 * included definitions file */
95 /*implicit parameterss: PKA_REG_Y(PKA_REG_Y1)=3(out), PKA_REG_Y2(PKA_REG_EC_A)=4(in), *
96 * PKA_REG_N=0(in) */
97 rootExist = PkiIsModSquareRootExists();
98
99 /* check is the root exists */
100 if(rootExist != true){
101 err = PKA_MOD_SQUARE_ROOT_NOT_EXIST_ERROR;
102 goto End;
103 }
104
105 /* check Y LS-bit and set Y = -Y if need */
106 PKA_READ_WORD_FROM_REG(w, 0, PKA_REG_Y);
107 if((w & 1) != (pointCtl & 1)) {
108 PKA_SUB(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y, PKA_REG_N, PKA_REG_Y);
109 }
110
111 /* copy Y-coordinate */
112 PkaCopyDataFromPkaReg(pPublKey->y/*dst*/, modSizeInWords, PKA_REG_Y/*src reg*/);
113 }
114
115 End:
116 PkaFinishAndMutexUnlock(pkaReqRegs);
117 return err;
118
119 }
120
121
122 /*********** EcWrstFullCheckPublKey function **********************/
123 /**
124 * @brief Checks that the public key is valid point belonging to EC group.
125 *
126 * Assuming: partly check (sizes, point is on curve) of the public key
127 * was done previously.
128 *
129 * @return - On success CC_OK is returned, on failure an error code.
130 *
131 */
EcWrstFullCheckPublKey(CCEcpkiPublKey_t * pPublKey,uint32_t * pTempBuff)132 CCError_t EcWrstFullCheckPublKey( CCEcpkiPublKey_t *pPublKey, /*!< [in] Pointer to the public key structure. */
133 uint32_t *pTempBuff) /*!< [in] Pointer to itemp buffer of size not less 2*modulusSize. */
134 {
135 CCError_t err = CC_OK;
136 uint32_t ordSizeInWords, modSizeInWords, sizeBits;
137 uint32_t *outPointX, *outPointY;
138 uint32_t *pTmpForFunc;
139
140 modSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.modSizeInBits);
141 ordSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.ordSizeInBits);
142
143 /* scalar mult. resut coordinates */
144 outPointX = pTempBuff;
145 outPointY = outPointX + modSizeInWords;
146 pTmpForFunc = outPointY + modSizeInWords;
147
148
149 /* scalar mult publ.key point by EC generator order ecR */
150 err = PkaEcWrstScalarMult(
151 &pPublKey->domain,
152 pPublKey->domain.ecR, /*in*/
153 ordSizeInWords, /*in - publ key X*/
154 pPublKey->x, /*in - publ key Y*/
155 pPublKey->y, /*in*/
156 outPointX, /*out*/
157 outPointY, /*out*/
158 pTmpForFunc);
159 if(err) {
160 err = CC_ECPKI_INTERNAL_ERROR;
161 goto End;
162 }
163
164 /* check that out point is on infinity, i.e. X=0 && Y=0 */
165 sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(outPointY, modSizeInWords);
166 if(sizeBits > 0){
167 err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
168 goto End;
169 }
170 /* check condition for X */
171 sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(outPointX, modSizeInWords);
172 if(sizeBits > 0){
173 err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
174 goto End;
175 }
176
177 End:
178 return err;
179 }
180
181
182 /*********** EcWrstDhDeriveSharedSecret function **********************/
183 /**
184 * @brief Derives shared secrete value from provided keys. called also SVDP_DH
185 *
186 * @return - On success CC_OK is returned, on failure an error code.
187 *
188 */
EcWrstDhDeriveSharedSecret(CCEcpkiPublKey_t * pPublKey,CCEcpkiPrivKey_t * pPrivKey,uint8_t * pSharedSecretValue,CCEcdhTempData_t * pTempBuff)189 CCError_t EcWrstDhDeriveSharedSecret(CCEcpkiPublKey_t *pPublKey, /*!< [in] Pointer to the public key structure. */
190 CCEcpkiPrivKey_t *pPrivKey, /*!< [in] Pointer to the private key structure. */
191 uint8_t *pSharedSecretValue, /*!< [out] Pointer to buffer for Shared Secret Value of size
192 not less than modulusSize in words. */
193 CCEcdhTempData_t *pTempBuff) /*!< [in] Pointer to temp buffer. */
194 {
195 CCError_t err;
196 uint32_t ordSizeInWords, modSizeInWords, modSizeInBytes;
197 uint32_t *outPointX, *outPointY;
198 uint32_t *pTmpForFunc;
199
200 modSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.modSizeInBits);
201 ordSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.ordSizeInBits);
202 modSizeInBytes = CALC_FULL_BYTES(pPublKey->domain.modSizeInBits);
203
204 /* scalar mult. resut coordinates */
205 outPointX = (uint32_t*)pTempBuff;
206 outPointY = outPointX + modSizeInWords;
207 pTmpForFunc = outPointY + modSizeInWords;
208
209 /* scalar mult publ.key point by EC generator order ecR */
210 err = PkaEcWrstScalarMult(
211 &pPublKey->domain,
212 pPrivKey->PrivKey, /*in*/
213 ordSizeInWords, /*in - publ key X*/
214 pPublKey->x, /*in - publ key Y*/
215 pPublKey->y, /*in*/
216 outPointX, /*out*/
217 outPointY, /*out*/
218 pTmpForFunc); /*in*/
219 if(err)
220 goto End;
221
222 /* Note: Because output of scalar mult result point in affine *
223 * form,there no need to check, that coordinates X,Y <= mod-1. */
224 /* Check that out point is not on infinity, i.e. X,Y != 0 */
225 if(CC_CommonGetWordsCounterEffectiveSizeInBits(outPointY, modSizeInWords) == 0 ||
226 CC_CommonGetWordsCounterEffectiveSizeInBits(outPointX, modSizeInWords) == 0){
227 err = ECWRST_DH_SHARED_VALUE_IS_ON_INFINITY_ERROR;
228 goto End;
229 } else {
230 /* copy X-coordinate of SecrP to output */
231 CC_CommonReverseMemcpy(pSharedSecretValue, (uint8_t*)outPointX, modSizeInBytes);
232 }
233
234 End:
235 CC_PalMemSetZero ( pTempBuff, sizeof(CCEcdhTempData_t) );
236 return err;
237
238 }
239
240
241
242