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 <string.h>
8 #include "cc_pal_types.h"
9 #include "cc_pal_mem.h"
10 #include "cc_hash_defs.h"
11 #include "cc_rnd_common.h"
12 #include "cc_ec_edw_api.h"
13 #include "mbedtls_cc_ec_mont_edw_error.h"
14
15 #include "ec_edw.h"
16 #include "ec_edw_local.h"
17
18 /******************************************************************************/
19 /** Ed25519 Sign/Verify two types APIs: 1. For signature concatenated with *
20 * message; 2. For detached signature and message with separate in/out */
21 /******************************************************************************/
22 /******************************************************************************/
23 /**
24 * The function creates EC Edwards signature on the message.
25 *
26 * Note: Used detached form of signature, separated from the message.
27 * Implemented algorithm of Bernstein D. etc. sign ed25519.
28 *
29 * @return CC_OK on success,
30 * @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
31 */
CC_EcEdwSign(uint8_t * pSign,size_t * pSignSize,const uint8_t * pMsg,size_t msgSize,const uint8_t * pSignSecrKey,size_t secrKeySize,CCEcEdwTempBuff_t * pTempBuff)32 CEXPORT_C CCError_t CC_EcEdwSign (
33 uint8_t *pSign, /*!< [out] Pointer to the detached signature. */
34 size_t *pSignSize, /*!< [in/out] Pointer to the total size of the signature ;
35 In - the buffer size, which (must be at least 2*EC order size);
36 Out - the actual size of output data. */
37 const uint8_t *pMsg, /*!< [in] Pointer to the message. */
38 size_t msgSize, /*!< [in] Message size in bytes: must be less, than
39 (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
40 const uint8_t *pSignSecrKey, /*!< [in] Pointer to the signer secret key (seed || pulKey) */
41 size_t secrKeySize, /*!< [in] Size of signer secret key in bytes: (must be 2*EC order size). */
42 CCEcEdwTempBuff_t *pTempBuff) /*!< [in] pointer to the temp buffer. */
43 {
44 CCError_t err = CC_OK;
45 uint32_t ecEdwKeySizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
46 uint32_t ecEdwSignSizeBytes = 2*ecEdwKeySizeBytes;
47 /* the pointer to EC domain */
48 const CCEcEdwDomain_t *pEcDomain;
49
50 /* check input pointers */
51 if (pSign == NULL || pSignSize == NULL ||
52 ((pMsg == NULL)^(msgSize == 0)) ||
53 pSignSecrKey == NULL ||
54 pTempBuff == NULL) {
55 return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
56 }
57
58 /* max size of message according to HASH update requirements */
59 if(msgSize >= CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES) {
60 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
61 }
62 /* conditions for secret key size and buff. size for signature output */
63 if (secrKeySize != 2*ecEdwKeySizeBytes ||
64 *pSignSize < ecEdwSignSizeBytes) {
65 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
66 }
67
68 /* get domain */
69 pEcDomain = EcEdwGetDomain25519();
70
71 /***********************************************/
72 /** calculate signature on the massage **/
73 /***********************************************/
74
75 err = EcEdwSign(pSign, pMsg, msgSize,
76 pSignSecrKey, pEcDomain, pTempBuff);
77 if (err) {
78 goto End;
79 } else {
80 *pSignSize = 2*ecEdwKeySizeBytes;
81 }
82
83 End:
84
85 return err;
86 }
87
88 /******************************************************************************/
89 /**
90 * The function verifies the EC Edwards ed25519 signature on the message.
91 *
92 * Note: The input signature is in detached form, i.e. separated from the
93 * message.
94 *
95 * Verification is performed using EC Edwards ed25519 signature algorithm.
96 *
97 * @return CC_OK on success,
98 * @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
99 */
CC_EcEdwVerify(const uint8_t * pSign,size_t signSize,const uint8_t * pSignPublKey,size_t publKeySize,uint8_t * pMsg,size_t msgSize,CCEcEdwTempBuff_t * pTempBuff)100 CEXPORT_C CCError_t CC_EcEdwVerify(
101 const uint8_t *pSign, /*!< [in] Pointer to detached signature, i.e. the
102 signature is separated from the message. */
103 size_t signSize, /*!< [in] Size of the signature in bytes, it must be
104 equal to two EC Order size in bytes. */
105 const uint8_t *pSignPublKey, /*!< [in] Pointer to signer public key. */
106 size_t publKeySize, /*!< [in] Size of the signer public key in bytes; must be
107 equal to EC modulus size. */
108 uint8_t *pMsg, /*!< [in] Pointer to the message. */
109 size_t msgSize, /*!< [in] Pointer to the message size in bytes. Must be less than
110 (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
111 CCEcEdwTempBuff_t *pTempBuff) /*!< [in] the pointer to temp buffer. */
112
113 {
114 CCError_t err = CC_OK;
115 uint32_t ecEdwSizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
116 uint32_t ecEdwSignSizeBytes = 2*ecEdwSizeBytes;
117 const CCEcEdwDomain_t *pEcDomain; /*the pointer to Edw. EC domain*/
118
119 /* set pointers to temp buffers */
120 if (pSign == NULL || pSignPublKey == NULL ||
121 ((pMsg == NULL)^(msgSize == 0)) || pTempBuff == NULL) {
122 return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
123 }
124
125 if(signSize != ecEdwSignSizeBytes ) {
126 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
127 }
128
129 if(msgSize > CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES) {
130 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
131 }
132 if (publKeySize != ecEdwSizeBytes) {
133 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
134 }
135
136 /* get domain */
137 pEcDomain = EcEdwGetDomain25519();
138
139 /* perform scalar mult. and adding of two points */
140 err = EcEdwSignVerify (pSign, pMsg, msgSize,
141 pSignPublKey, pEcDomain, pTempBuff);
142
143 return err;
144 }
145
146
147 /*******************************************************************/
148 /** Edwards Key Pair generation from seeds API */
149 /*******************************************************************/
150 /**
151 @brief The function randomly generates Ec ed25519 private and public keys
152 using given seed.
153
154 The generation is performed using EC Edwards ed25519 algorithm.
155
156 @return CC_OK on success,
157 @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
158 */
CC_EcEdwSeedKeyPair(const uint8_t * pSeed,size_t seedSize,uint8_t * pSecrKey,size_t * pSecrKeySize,uint8_t * pPublKey,size_t * pPublKeySize,CCEcEdwTempBuff_t * pTempBuff)159 CEXPORT_C CCError_t CC_EcEdwSeedKeyPair (
160 const uint8_t *pSeed, /*!< [in] Pointer to the given seed. */
161 size_t seedSize, /*!< [in] Size of the seed in bytes, must be equal the EC order size
162 in bytes. */
163 uint8_t *pSecrKey, /*!< [out] Pointer to the secret key, including the seed, concatenated
164 with the public key. */
165 size_t *pSecrKeySize, /*!< [in/out] Pointer to the size of the secret key buffer in bytes
166 (must be at least 2*EC order size). */
167 uint8_t *pPublKey, /*!< [out] Pointer to the public key. */
168 size_t *pPublKeySize, /*!< [in/out] Pointer to the size of the public key in bytes.
169 In - the size of buffer must be at least EC modulus size;
170 Out - the actual size. */
171 CCEcEdwTempBuff_t *pTempBuff)
172 {
173 CCError_t err = CC_OK;
174 uint32_t ecEdwSizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
175 uint32_t ecEdwSecrKeySizeBytes = 2*ecEdwSizeBytes;
176 const CCEcEdwDomain_t *pEcDomain; /*the pointer to Edw. EC domain*/
177
178
179 if (pSeed == NULL || pSecrKey == NULL || pSecrKeySize == NULL ||
180 pPublKey == NULL || pPublKeySize == NULL ) {
181 return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
182 }
183
184 if(pTempBuff == NULL)
185 return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
186
187 if(*pSecrKeySize < ecEdwSecrKeySizeBytes) {
188 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
189 }
190 if (*pPublKeySize < ecEdwSizeBytes) {
191 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
192 }
193
194 if (seedSize != ecEdwSizeBytes) {
195 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
196 }
197
198 /* get domain */
199 pEcDomain = EcEdwGetDomain25519();
200
201 /* calculate publ/priv keys and clean temp buffer */
202 err = EcEdwSeedKeyPair(pPublKey, pSecrKey,
203 pSeed, pEcDomain, (uint32_t*)pTempBuff);
204 if (err)
205 goto End;
206
207 *pSecrKeySize = ecEdwSecrKeySizeBytes;
208 *pPublKeySize = ecEdwSizeBytes;
209
210 End:
211 return err;
212 }
213
214
215 /*******************************************************************/
216 /** Edwards Key Pair (random) generation API */
217 /*******************************************************************/
218 /**
219 @brief The function randomly generates the EC Edwards ed25519 private and
220 public keys.
221
222 The generation performed using EC Edwards ed25519 algorithm.
223
224 @return CC_OK on success,
225 @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
226 */
CC_EcEdwKeyPair(uint8_t * pSecrKey,size_t * pSecrKeySize,uint8_t * pPublKey,size_t * pPublKeySize,CCRndContext_t * pRndContext,CCEcEdwTempBuff_t * pTempBuff)227 CEXPORT_C CCError_t CC_EcEdwKeyPair (
228 uint8_t *pSecrKey, /*!< [out] Pointer to the secret key (including seed and public key). */
229 size_t *pSecrKeySize, /*!< [in/out] Pointer to the size of the secret key in bytes,
230 (must be at least 2*EC order size). */
231 uint8_t *pPublKey, /*!< [out] Pointer to the public key. */
232 size_t *pPublKeySize, /*!< [in/out] - Pointer to the size of the public key in bytes.
233 In - the size of buffer must be at least EC modulus size;
234 Out - the actual size. */
235 CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
236 CCEcEdwTempBuff_t *pTempBuff)
237 {
238 CCError_t err = CC_OK;
239 uint32_t ecEdwSizeBytes;
240 uint8_t *pSeed = (uint8_t*)pTempBuff;
241 const CCEcEdwDomain_t *pEcDomain; /*the pointer to Edw. EC domain*/
242 CCRndState_t *pRndState;
243 CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
244
245
246 /* FUNCTION LOGIC */
247
248 /* check parameters */
249 if (pSecrKey == NULL || pSecrKeySize == NULL ||
250 pPublKey == NULL || pPublKeySize == NULL ||
251 pTempBuff == NULL) {
252 return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
253 }
254 if (pRndContext == NULL)
255 return CC_EC_EDW_RND_CONTEXT_PTR_INVALID_ERROR;
256
257 /* get domain */
258 pEcDomain = EcEdwGetDomain25519();
259
260 ecEdwSizeBytes = CC_32BIT_WORD_SIZE * pEcDomain->ecModSizeInWords;
261
262 if(*pSecrKeySize < 2*ecEdwSizeBytes) {
263 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
264 }
265 if (*pPublKeySize < ecEdwSizeBytes) {
266 return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
267 }
268
269 pRndState = (CCRndState_t *)(pRndContext->rndState);
270 RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
271
272 if (RndGenerateVectFunc == NULL)
273 return CC_EC_EDW_RND_GEN_VECTOR_FUNC_ERROR;
274
275
276 /* generate random seed */
277 err = RndGenerateVectFunc((void *)pRndState, (unsigned char *)pSeed, (size_t)ecEdwSizeBytes);
278 if (err) {
279 goto End;
280 }
281
282
283 /* generate key pair */
284 err = EcEdwSeedKeyPair(pPublKey, pSecrKey,
285 pSeed, pEcDomain,
286 (uint32_t*)pTempBuff + CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS);
287 if(err)
288 goto End;
289
290 *pSecrKeySize = 2*ecEdwSizeBytes;
291 *pPublKeySize = ecEdwSizeBytes;
292
293 End:
294 CC_PalMemSetZero(pTempBuff, ecEdwSizeBytes);
295 return err;
296 }
297
298