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