mcxn947_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file mcxn947_crypto_pkc.c
3  * @brief NXP MCX N947 public-key hardware accelerator (PKA)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include <mcuxClToolchain.h>
36 #include <mcuxClEls.h>
37 #include <mcuxClEcc.h>
38 #include <mcuxClRsa.h>
39 #include <internal/mcuxClRsa_Internal_Functions.h>
40 #include "core/crypto.h"
43 #include "pkc/rsa.h"
44 #include "ecc/ec.h"
45 #include "ecc/ec_misc.h"
46 #include "ecc/ecdsa.h"
47 #include "ecc/x25519.h"
48 #include "ecc/x448.h"
49 #include "ecc/ed25519.h"
50 #include "debug.h"
51 
52 //Check crypto library configuration
53 #if (MCXN947_CRYPTO_PKC_SUPPORT == ENABLED)
54 
55 //Global variables
61 
62 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp192r1)
63 static const uint8_t SECP192R1_PRECG[] =
64 {
65  0x51, 0xA5, 0x81, 0xD9, 0x18, 0x4A, 0xC7, 0x37, 0x47, 0x30, 0xD4, 0xF4, 0x80, 0xD1, 0x09, 0x0B,
66  0xB1, 0x99, 0x63, 0xD8, 0xC0, 0xA1, 0xE3, 0x40,
67  0x5B, 0xD8, 0x1E, 0xE2, 0xE0, 0xBB, 0x9F, 0x6E, 0x7C, 0xDF, 0xCE, 0xA0, 0x2F, 0x68, 0x3F, 0x16,
68  0xEC, 0xC5, 0x67, 0x31, 0xE6, 0x99, 0x12, 0xA5
69 };
70 
71 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp224r1)
72 static const uint8_t SECP224R1_PRECG[] =
73 {
74  0x04, 0x99, 0xAA, 0x8A, 0x5F, 0x8E, 0xBE, 0xEF, 0xEC, 0x27, 0xA4, 0xE1, 0x3A, 0x0B, 0x91, 0xFB,
75  0x29, 0x91, 0xFA, 0xB0, 0xA0, 0x06, 0x41, 0x96, 0x6C, 0xAB, 0x26, 0xE3,
76  0x69, 0x16, 0xF6, 0xD4, 0x33, 0x8C, 0x5B, 0x81, 0xD7, 0x7A, 0xAE, 0x82, 0xF7, 0x06, 0x84, 0xD9,
77  0x29, 0x61, 0x0D, 0x54, 0x50, 0x75, 0x10, 0x40, 0x77, 0x66, 0xAF, 0x5D
78 };
79 
80 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp256k1)
81 static const uint8_t SECP256K1_PRECG[] =
82 {
83  0x8F, 0x68, 0xB9, 0xD2, 0xF6, 0x3B, 0x5F, 0x33, 0x92, 0x39, 0xC1, 0xAD, 0x98, 0x1F, 0x16, 0x2E,
84  0xE8, 0x8C, 0x56, 0x78, 0x72, 0x3E, 0xA3, 0x35, 0x1B, 0x7B, 0x44, 0x4C, 0x9E, 0xC4, 0xC0, 0xDA,
85  0x66, 0x2A, 0x9F, 0x2D, 0xBA, 0x06, 0x39, 0x86, 0xDE, 0x1D, 0x90, 0xC2, 0xB6, 0xBE, 0x21, 0x5D,
86  0xBB, 0xEA, 0x2C, 0xFE, 0x95, 0x51, 0x0B, 0xFD, 0xF2, 0x3C, 0xBF, 0x79, 0x50, 0x1F, 0xFF, 0x82
87 };
88 
89 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp256r1)
90 static const uint8_t SECP256R1_PRECG[] =
91 {
92  0x44, 0x7D, 0x73, 0x9B, 0xEE, 0xDB, 0x5E, 0x67, 0xFB, 0x98, 0x2F, 0xD5, 0x88, 0xC6, 0x76, 0x6E,
93  0xFC, 0x35, 0xFF, 0x7D, 0xC2, 0x97, 0xEA, 0xC3, 0x57, 0xC8, 0x4F, 0xC9, 0xD7, 0x89, 0xBD, 0x85,
94  0x2D, 0x48, 0x25, 0xAB, 0x83, 0x41, 0x31, 0xEE, 0xE1, 0x2E, 0x9D, 0x95, 0x3A, 0x4A, 0xAF, 0xF7,
95  0x3D, 0x34, 0x9B, 0x95, 0xA7, 0xFA, 0xE5, 0x00, 0x0C, 0x7E, 0x33, 0xC9, 0x72, 0xE2, 0x5B, 0x32
96 };
97 
98 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp384r1)
99 static const uint8_t SECP384R1_PRECG[] =
100 {
101  0xC1, 0x9E, 0x0B, 0x4C, 0x80, 0x01, 0x19, 0xC4, 0x40, 0xF7, 0xF9, 0xE7, 0x06, 0x42, 0x12, 0x79,
102  0xB4, 0x2A, 0x31, 0xAF, 0x8A, 0x3E, 0x29, 0x7D, 0xDB, 0x29, 0x87, 0x89, 0x4D, 0x10, 0xDD, 0xEA,
103  0xBA, 0x06, 0x54, 0x58, 0xA4, 0xF5, 0x2D, 0x78, 0xA6, 0x28, 0xB0, 0x9A, 0xAA, 0x03, 0xBD, 0x53,
104  0x16, 0xF3, 0xFD, 0xBF, 0x03, 0x56, 0xB3, 0x01, 0xE5, 0xA0, 0x19, 0x1D, 0x1F, 0x5B, 0x77, 0xF6,
105  0x57, 0x7A, 0x30, 0xEA, 0xE3, 0x56, 0x7A, 0xF9, 0xC1, 0xC7, 0xCA, 0xD1, 0x35, 0xF6, 0xEB, 0xF2,
106  0xAF, 0x68, 0xAA, 0x6D, 0xE6, 0x39, 0xD8, 0x58, 0x82, 0x2D, 0x0F, 0xC5, 0xE6, 0xC8, 0x8C, 0x41
107 };
108 
109 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (secp521r1)
110 static const uint8_t SECP521R1_PRECG[] =
111 {
112  0x00, 0x8E, 0x81, 0x8D, 0x28, 0xF3, 0x81, 0xD8, 0xB2, 0x05, 0xED, 0xFF, 0x69, 0x61, 0x3B, 0x96,
113  0x2E, 0x0C, 0x77, 0xD2, 0x23, 0xEF, 0x25, 0xCC, 0x1C, 0x99, 0xD9, 0xA6, 0x2E, 0x4F, 0x25, 0x72,
114  0xC1, 0x61, 0x7A, 0xD0, 0xF5, 0xE9, 0xA8, 0x6B, 0x71, 0x04, 0xE8, 0x97, 0x00, 0xD4, 0xDA, 0x71,
115  0x3C, 0xB4, 0x08, 0xF3, 0xDE, 0x44, 0x65, 0xF8, 0x6A, 0xC4, 0xEE, 0x31, 0xE7, 0x1A, 0x28, 0x64,
116  0x92, 0xAD,
117  0x01, 0x3E, 0xFD, 0xBC, 0x85, 0x6E, 0x8F, 0x68, 0xBF, 0x44, 0xD4, 0xE1, 0x9F, 0xC7, 0xC3, 0x26,
118  0xFE, 0x48, 0xA1, 0x6F, 0x78, 0x55, 0xC8, 0x08, 0x66, 0x23, 0x71, 0x96, 0xBF, 0x8F, 0x72, 0xEA,
119  0x0D, 0xCB, 0x42, 0x22, 0x85, 0xDC, 0x03, 0x70, 0x68, 0x9F, 0xBE, 0x72, 0x6F, 0x8C, 0xE0, 0x45,
120  0xA4, 0x03, 0x8B, 0x64, 0x0F, 0x2B, 0x67, 0x17, 0x76, 0x0F, 0x72, 0x12, 0x31, 0xCF, 0x8C, 0xDF,
121  0x1F, 0x60
122 };
123 
124 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (brainpoolP256r1)
125 static const uint8_t BRAINPOOLP256R1_PRECG[] =
126 {
127  0x4A, 0x14, 0xC0, 0x30, 0x3B, 0x85, 0x6C, 0x94, 0xB4, 0x43, 0x85, 0x11, 0x7F, 0x87, 0xED, 0x9D,
128  0x12, 0x00, 0xCA, 0x9B, 0x11, 0x00, 0x65, 0x90, 0xEB, 0x6B, 0x65, 0x1C, 0xF5, 0x84, 0x72, 0xC9,
129  0x7B, 0x81, 0xE4, 0x70, 0xDA, 0xE2, 0xD5, 0xEF, 0xE6, 0x38, 0x73, 0x49, 0x8B, 0x47, 0xCC, 0x5E,
130  0xD5, 0x44, 0xA0, 0x68, 0xCD, 0x73, 0x21, 0x17, 0x52, 0x9C, 0x5C, 0xD6, 0x28, 0xF8, 0x52, 0xD1
131 };
132 
133 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (brainpoolP384r1)
134 static const uint8_t BRAINPOOLP384R1_PRECG[] =
135 {
136  0x23, 0x69, 0xDB, 0xB6, 0x39, 0x7C, 0x99, 0xF1, 0x89, 0x74, 0xB5, 0x68, 0x8E, 0x81, 0xAF, 0x98,
137  0xDF, 0x4D, 0xDA, 0xCC, 0xBB, 0x1F, 0xDC, 0x04, 0xE1, 0x8A, 0x5D, 0x2D, 0x02, 0xC7, 0xF7, 0x27,
138  0x02, 0xA3, 0x53, 0xBC, 0x53, 0x45, 0xA9, 0x46, 0x6B, 0xF5, 0x50, 0xB0, 0x4D, 0x99, 0x4B, 0x04,
139  0x6F, 0x47, 0xB1, 0x1D, 0xAA, 0x3B, 0x12, 0x4F, 0x93, 0xB0, 0x87, 0x75, 0x92, 0x5F, 0xF0, 0xA8,
140  0x12, 0x73, 0x68, 0xF1, 0x07, 0x42, 0xFA, 0x8F, 0xCD, 0x41, 0xCA, 0xE9, 0x33, 0x34, 0xCE, 0x66,
141  0x43, 0xF1, 0x43, 0xE6, 0x50, 0x0C, 0xB2, 0xC1, 0x0E, 0xE1, 0x88, 0xBB, 0x14, 0x50, 0x4C, 0x85
142 };
143 
144 //Pre-computed value of (2 ^ (byteLenN * 4)) * G (brainpoolP512r1)
145 static const uint8_t BRAINPOOLP512R1_PRECG[] =
146 {
147  0x7B, 0x59, 0x13, 0xF7, 0x66, 0xC4, 0xED, 0x95, 0xD5, 0x26, 0x2C, 0xE1, 0xB8, 0xF1, 0xB2, 0xAF,
148  0xC0, 0x56, 0xFD, 0x65, 0x8F, 0x28, 0x48, 0x70, 0x79, 0xA8, 0x3D, 0x9B, 0x94, 0x5E, 0x84, 0x60,
149  0x1B, 0xAE, 0x0F, 0x47, 0xAC, 0xA3, 0xB9, 0x4E, 0x97, 0x50, 0x2F, 0x33, 0x73, 0x0A, 0x37, 0x21,
150  0x9D, 0x18, 0x9C, 0x54, 0x08, 0xAC, 0x7D, 0xA5, 0xCA, 0x44, 0x81, 0x27, 0xEF, 0x66, 0xEF, 0xB5,
151  0x3B, 0x4D, 0x8E, 0x45, 0x4F, 0xFC, 0x59, 0x3A, 0x37, 0x27, 0xEA, 0x1E, 0xEA, 0x20, 0xB7, 0x08,
152  0xC2, 0x1F, 0xCA, 0x91, 0x61, 0x30, 0x6A, 0xF0, 0xE4, 0x66, 0x56, 0xA7, 0x5F, 0xC4, 0x50, 0xA8,
153  0xFB, 0x4E, 0xDB, 0x0D, 0xBC, 0x57, 0x88, 0x77, 0x24, 0xEC, 0x6F, 0x84, 0x4E, 0xB4, 0x96, 0xC3,
154  0x3E, 0x94, 0x70, 0xF8, 0xDA, 0x00, 0x92, 0xC9, 0xD6, 0x10, 0x45, 0x3C, 0xC2, 0xF4, 0x58, 0x72
155 };
156 
157 
158 #if (MPI_SUPPORT == ENABLED)
159 
160 /**
161  * @brief Modular exponentiation (regular calculation)
162  * @param[out] r Resulting integer R = A ^ E mod P
163  * @param[in] a Pointer to a multiple precision integer
164  * @param[in] e Exponent
165  * @param[in] p Modulus
166  * @return Error code
167  **/
168 
169 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
170 {
171  error_t error;
172  uint_t aLen;
173  uint_t eLen;
174  uint_t pLen;
175  mcuxClRsa_KeyEntry_t ee;
176  mcuxClRsa_KeyEntry_t pp;
177  mcuxClRsa_Key privateKey;
178 
179  //Initialize status code
180  error = NO_ERROR;
181 
182  //Get the length of the operands, in bytes
183  aLen = mpiGetByteLength(a);
184  eLen = mpiGetByteLength(e);
185  pLen = mpiGetByteLength(p);
186 
187  //Check the length of the operands
188  if(aLen <= pLen && eLen <= 512 && pLen <= 512)
189  {
190  //Acquire exclusive access to the ELS module
192 
193  //Copy the input integer
194  mpiWriteRaw(a, elsRsaArgs.c, pLen);
195  //Copy the public exponent
196  mpiWriteRaw(e, elsRsaArgs.e, eLen);
197  //Copy the modulus
198  mpiWriteRaw(p, elsRsaArgs.n, pLen);
199 
200  //Set the public exponent
201  ee.pKeyEntryData = elsRsaArgs.e;
202  ee.keyEntryLength = eLen;
203 
204  //Set the modulus
205  pp.pKeyEntryData = elsRsaArgs.n;
206  pp.keyEntryLength = pLen;
207 
208  //Set the RSA private key
209  privateKey.keytype = MCUXCLRSA_KEY_PRIVATEPLAIN;
210  privateKey.pMod1 = &pp;
211  privateKey.pMod2 = NULL;
212  privateKey.pQInv = NULL;
213  privateKey.pExp1 = &ee;
214  privateKey.pExp2 = NULL;
215  privateKey.pExp3 = NULL;
216 
217  //Apply RSAVP1 primitive
218  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClRsa_sign(
219  &elsSession, &privateKey, elsRsaArgs.c, pLen,
220  (mcuxClRsa_SignVerifyMode_t *) &mcuxClRsa_Mode_Sign_NoEncode,
221  0, 0, elsRsaArgs.m));
222 
223  //Check the protection token and the return value
224  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClRsa_sign) ||
225  status != MCUXCLRSA_STATUS_SIGN_OK)
226  {
227  error = ERROR_FAILURE;
228  }
229 
230  //End of function call
231  MCUX_CSSL_FP_FUNCTION_CALL_END();
232 
233  //Check status code
234  if(!error)
235  {
236  //Copy the output
237  error = mpiReadRaw(r, elsRsaArgs.m, pLen);
238  }
239 
240  //Release exclusive access to the ELS module
242  }
243  else
244  {
245  //Perform modular exponentiation (r = a ^ e mod p)
246  error = mpiExpMod(r, a, e, p);
247  }
248 
249  //Return status code
250  return error;
251 }
252 
253 #endif
254 #if (RSA_SUPPORT == ENABLED)
255 
256 /**
257  * @brief RSA encryption primitive
258  *
259  * The RSA encryption primitive produces a ciphertext representative from
260  * a message representative under the control of a public key
261  *
262  * @param[in] key RSA public key
263  * @param[in] m Message representative
264  * @param[out] c Ciphertext representative
265  * @return Error code
266  **/
267 
268 error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
269 {
270  error_t error;
271  size_t nLen;
272  size_t eLen;
273  mcuxClRsa_KeyEntry_t n;
274  mcuxClRsa_KeyEntry_t e;
275  mcuxClRsa_Key publicKey;
276 
277  //The message representative m shall be between 0 and n - 1
278  if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
279  return ERROR_OUT_OF_RANGE;
280 
281  //Initialize status code
282  error = NO_ERROR;
283 
284  //Get the length of the modulus, in bytes
285  nLen = mpiGetByteLength(&key->n);
286  //Get the length of the public exponent, in bytes
287  eLen = mpiGetByteLength(&key->e);
288 
289  //Check the length of the operands
290  if(nLen <= 512 && eLen <= 512)
291  {
292  //Acquire exclusive access to the ELS module
294 
295  //Copy the modulus
296  mpiWriteRaw(&key->n, elsRsaArgs.n, nLen);
297  //Copy the public exponent
298  mpiWriteRaw(&key->e, elsRsaArgs.e, eLen);
299 
300  //Set the modulus
301  n.pKeyEntryData = elsRsaArgs.n;
302  n.keyEntryLength = nLen;
303 
304  //Set the public exponent
305  e.pKeyEntryData = elsRsaArgs.e;
306  e.keyEntryLength = eLen;
307 
308  //Set the RSA public key
309  publicKey.keytype = MCUXCLRSA_KEY_PUBLIC;
310  publicKey.pMod1 = &n;
311  publicKey.pMod2 = NULL;
312  publicKey.pQInv = NULL;
313  publicKey.pExp1 = &e;
314  publicKey.pExp2 = NULL;
315  publicKey.pExp3 = NULL;
316 
317  //Copy the message representative
318  mpiWriteRaw(m, elsRsaArgs.m, nLen);
319 
320  //Apply RSASP1 primitive
321  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClRsa_verify(
322  &elsSession, &publicKey, NULL, 0, elsRsaArgs.m,
323  (mcuxClRsa_SignVerifyMode_t *) &mcuxClRsa_Mode_Verify_NoVerify,
324  0, 0, elsRsaArgs.c));
325 
326  //Check the protection token and the return value
327  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClRsa_verify) ||
328  status != MCUXCLRSA_STATUS_VERIFYPRIMITIVE_OK)
329  {
330  error = ERROR_FAILURE;
331  }
332 
333  //End of function call
334  MCUX_CSSL_FP_FUNCTION_CALL_END();
335 
336  //Check status code
337  if(!error)
338  {
339  //Copy the ciphertext representative
340  error = mpiReadRaw(c, elsRsaArgs.c, nLen);
341  }
342 
343  //Release exclusive access to the ELS module
345  }
346  else
347  {
348  //Report an error
349  error = ERROR_INVALID_LENGTH;
350  }
351 
352  //Return status code
353  return error;
354 }
355 
356 
357 /**
358  * @brief RSA decryption primitive
359  *
360  * The RSA decryption primitive recovers the message representative from
361  * the ciphertext representative under the control of a private key
362  *
363  * @param[in] key RSA private key
364  * @param[in] c Ciphertext representative
365  * @param[out] m Message representative
366  * @return Error code
367  **/
368 
369 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
370 {
371  error_t error;
372  size_t nLen;
373  size_t dLen;
374  mcuxClRsa_KeyEntry_t n;
375  mcuxClRsa_KeyEntry_t d;
376  mcuxClRsa_KeyEntry_t p;
377  mcuxClRsa_KeyEntry_t q;
378  mcuxClRsa_KeyEntry_t dp;
379  mcuxClRsa_KeyEntry_t dq;
380  mcuxClRsa_KeyEntry_t qinv;
381  mcuxClRsa_Key privateKey;
382 
383  //The ciphertext representative c shall be between 0 and n - 1
384  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
385  return ERROR_OUT_OF_RANGE;
386 
387  //Initialize status code
388  error = NO_ERROR;
389 
390  //Get the length of the modulus, in bytes
391  nLen = mpiGetByteLength(&key->n);
392  //Get the length of the private exponent, in bytes
393  dLen = mpiGetByteLength(&key->d);
394 
395  //Check the length of the operands
396  if(nLen <= 512 && dLen <= 512)
397  {
398  //Acquire exclusive access to the ELS module
400 
401  //Use the Chinese remainder algorithm?
402  if(mpiGetLength(&key->p) > 0 && mpiGetLength(&key->q) > 0 &&
403  mpiGetLength(&key->dp) > 0 && mpiGetLength(&key->dq) > 0 &&
404  mpiGetLength(&key->qinv) > 0)
405  {
406  //Copy the first factor
407  mpiWriteRaw(&key->p, elsRsaArgs.p, nLen / 2);
408  //Copy the second factor
409  mpiWriteRaw(&key->q, elsRsaArgs.q, nLen / 2);
410  //Copy the first factor's CRT exponent
411  mpiWriteRaw(&key->dp, elsRsaArgs.dp, nLen / 2);
412  //Copy the second factor's CRT exponent
413  mpiWriteRaw(&key->dq, elsRsaArgs.dq, nLen / 2);
414  //Copy the CRT coefficient
415  mpiWriteRaw(&key->qinv, elsRsaArgs.qinv, nLen / 2);
416 
417  //Set the first factor
418  p.pKeyEntryData = elsRsaArgs.p;
419  p.keyEntryLength = nLen / 2;
420 
421  //Set the second factor
422  q.pKeyEntryData = elsRsaArgs.q;
423  q.keyEntryLength = nLen / 2;
424 
425  //Set the first factor's CRT exponent
426  dp.pKeyEntryData = elsRsaArgs.dp;
427  dp.keyEntryLength = nLen / 2;
428 
429  //Set the second factor's CRT exponent
430  dq.pKeyEntryData = elsRsaArgs.dq;
431  dq.keyEntryLength = nLen / 2;
432 
433  //Set the CRT coefficient
434  qinv.pKeyEntryData = elsRsaArgs.qinv;
435  qinv.keyEntryLength = nLen / 2;
436 
437  //Set the RSA private key
438  privateKey.keytype = MCUXCLRSA_KEY_PRIVATECRT;
439  privateKey.pMod1 = &p;
440  privateKey.pMod2 = &q;
441  privateKey.pQInv = &qinv;
442  privateKey.pExp1 = &dp;
443  privateKey.pExp2 = &dq;
444  privateKey.pExp3 = NULL;
445  }
446  else
447  {
448  //Copy the modulus
449  mpiWriteRaw(&key->n, elsRsaArgs.n, nLen);
450  //Copy the private exponent
451  mpiWriteRaw(&key->d, elsRsaArgs.d, dLen);
452 
453  //Set the modulus
454  n.pKeyEntryData = elsRsaArgs.n;
455  n.keyEntryLength = nLen;
456 
457  //Set the private exponent
458  d.pKeyEntryData = elsRsaArgs.d;
459  d.keyEntryLength = dLen;
460 
461  //Set the RSA private key
462  privateKey.keytype = MCUXCLRSA_KEY_PRIVATEPLAIN;
463  privateKey.pMod1 = &n;
464  privateKey.pMod2 = NULL;
465  privateKey.pQInv = NULL;
466  privateKey.pExp1 = &d;
467  privateKey.pExp2 = NULL;
468  privateKey.pExp3 = NULL;
469  }
470 
471  //Copy the ciphertext representative
472  mpiWriteRaw(c, elsRsaArgs.c, nLen);
473 
474  //Apply RSAVP1 primitive
475  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClRsa_sign(
476  &elsSession, &privateKey, elsRsaArgs.c, nLen,
477  (mcuxClRsa_SignVerifyMode_t *) &mcuxClRsa_Mode_Sign_NoEncode,
478  0, 0, elsRsaArgs.m));
479 
480  //Check the protection token and the return value
481  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClRsa_sign) ||
482  status != MCUXCLRSA_STATUS_SIGN_OK)
483  {
484  error = ERROR_FAILURE;
485  }
486 
487  //End of function call
488  MCUX_CSSL_FP_FUNCTION_CALL_END();
489 
490  //Check status code
491  if(!error)
492  {
493  //Copy the message representative
494  error = mpiReadRaw(m, elsRsaArgs.m, nLen);
495  }
496 
497  //Release exclusive access to the ELS module
499  }
500  else
501  {
502  //Report an error
503  error = ERROR_INVALID_LENGTH;
504  }
505 
506  //Return status code
507  return error;
508 }
509 
510 #endif
511 #if (EC_SUPPORT == ENABLED)
512 
513 /**
514  * @brief Scalar multiplication (fast calculation)
515  * @param[in] curve Elliptic curve parameters
516  * @param[out] r Resulting point R = d.S
517  * @param[in] d An integer d such as 0 <= d < p
518  * @param[in] s EC point
519  * @return Error code
520  **/
521 
522 error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
523  const EcPoint3 *s)
524 {
525  //Compute R = d.S
526  return ecMulRegular(curve, r, d, s);
527 }
528 
529 
530 /**
531  * @brief Scalar multiplication (regular calculation)
532  * @param[in] curve Elliptic curve parameters
533  * @param[out] r Resulting point R = d.S
534  * @param[in] d An integer d such as 0 <= d < q
535  * @param[in] s EC point
536  * @return Error code
537  **/
538 
539 error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
540  const EcPoint3 *s)
541 {
542  error_t error;
543  size_t modLen;
544  size_t orderLen;
545  mcuxClEcc_PointMult_Param_t pointMultParam;
546 
547  //Initialize status code
548  error = NO_ERROR;
549 
550  //Get the length of the modulus, in bytes
551  modLen = (curve->fieldSize + 7) / 8;
552  //Get the length of the order, in bytes
553  orderLen = (curve->orderSize + 7) / 8;
554 
555  //Check the length of the operands
556  if(modLen <= 66 && orderLen <= 66)
557  {
558  //Acquire exclusive access to the ELS module
560 
561  //Copy domain parameters
562  ecScalarExport(curve->p, (modLen + 3) / 4, elsEccArgs.p, modLen,
564 
565  ecScalarExport(curve->a, (modLen + 3) / 4, elsEccArgs.a, modLen,
567 
568  ecScalarExport(curve->b, (modLen + 3) / 4, elsEccArgs.b, modLen,
570 
571  ecScalarExport(curve->g.x, (modLen + 3) / 4, elsEccArgs.g, modLen,
573 
574  ecScalarExport(curve->g.y, (modLen + 3) / 4, elsEccArgs.g + modLen,
576 
577  ecScalarExport(curve->q, (modLen + 3) / 4, elsEccArgs.q, orderLen,
579 
580  //Copy scalar
581  ecScalarExport(d, (orderLen + 3) / 4, elsEccArgs.d, orderLen,
583 
584  //Copy input point
585  ecScalarExport(s->x, (modLen + 3) / 4, elsEccArgs.input, modLen,
587 
588  ecScalarExport(s->y, (modLen + 3) / 4, elsEccArgs.input + modLen,
590 
591  //Set point multiplication parameters
592  pointMultParam.curveParam.pA = elsEccArgs.a;
593  pointMultParam.curveParam.pB = elsEccArgs.b;
594  pointMultParam.curveParam.pP = elsEccArgs.p;
595  pointMultParam.curveParam.pG = elsEccArgs.g;
596  pointMultParam.curveParam.pN = elsEccArgs.q;
597  pointMultParam.curveParam.misc = (orderLen << 8) | modLen;
598  pointMultParam.pScalar = elsEccArgs.d;
599  pointMultParam.pPoint = elsEccArgs.input;
600  pointMultParam.pResult = elsEccArgs.output;
601  pointMultParam.optLen = 0;
602 
603  //Perform scalar multiplication
604  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClEcc_PointMult(
605  &elsSession, &pointMultParam));
606 
607  //Check the protection token and the return value
608  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_PointMult) ||
609  status != MCUXCLECC_STATUS_OK)
610  {
611  error = ERROR_FAILURE;
612  }
613 
614  //End of function call
615  MCUX_CSSL_FP_FUNCTION_CALL_END();
616 
617  //Check status code
618  if(!error)
619  {
620  //Copy the x-coordinate of the result
623 
624  //Check status code
625  if(!error)
626  {
627  //Copy the y-coordinate of the result
629  modLen, modLen, EC_SCALAR_FORMAT_BIG_ENDIAN);
630  }
631 
632  //Check status code
633  if(!error)
634  {
635  //Set the z-coordinate of the result
637  }
638  }
639 
640  //Release exclusive access to the ELS module
642  }
643  else
644  {
645  //Report an error
646  error = ERROR_INVALID_LENGTH;
647  }
648 
649  //Return status code
650  return error;
651 }
652 
653 
654 /**
655  * @brief Twin multiplication
656  * @param[in] curve Elliptic curve parameters
657  * @param[out] r Resulting point R = d0.S + d1.T
658  * @param[in] d0 An integer d such as 0 <= d0 < p
659  * @param[in] s EC point
660  * @param[in] d1 An integer d such as 0 <= d1 < p
661  * @param[in] t EC point
662  * @return Error code
663  **/
664 
665 error_t ecTwinMul(const EcCurve *curve, EcPoint3 *r, const uint32_t *d0,
666  const EcPoint3 *s, const uint32_t *d1, const EcPoint3 *t)
667 {
668  error_t error;
669  EcPoint3 u;
670 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
671  EcState *state;
672 #else
673  EcState state[1];
674 #endif
675 
676 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
677  //Allocate working state
678  state = cryptoAllocMem(sizeof(EcState));
679  //Failed to allocate memory?
680  if(state == NULL)
681  return ERROR_OUT_OF_MEMORY;
682 #endif
683 
684  //Initialize working state
685  osMemset(state, 0, sizeof(EcState));
686  //Save elliptic curve parameters
687  state->curve = curve;
688 
689  //Compute d0.S
690  error = ecMulFast(curve, r, d0, s);
691 
692  //Check status code
693  if(!error)
694  {
695  //Compute d1.T
696  error = ecMulFast(curve, &u, d1, t);
697  }
698 
699  //Check status code
700  if(!error)
701  {
702  //Compute d0.S + d1.T
703  ecFullAdd(state, r, r, &u);
704  }
705 
706  //Return status code
707  return error;
708 }
709 
710 #endif
711 #if (ECDSA_SUPPORT == ENABLED)
712 
713 /**
714  * @brief ECDSA signature generation
715  * @param[in] prngAlgo PRNG algorithm
716  * @param[in] prngContext Pointer to the PRNG context
717  * @param[in] privateKey Signer's EC private key
718  * @param[in] digest Digest of the message to be signed
719  * @param[in] digestLen Length in octets of the digest
720  * @param[out] signature (R, S) integer pair
721  * @return Error code
722  **/
723 
724 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
725  const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen,
726  EcdsaSignature *signature)
727 {
728  error_t error;
729  size_t modLen;
730  size_t orderLen;
731  const EcCurve *curve;
732  mcuxClEcc_Sign_Param_t signParam;
733 
734  //Check parameters
735  if(privateKey == NULL || digest == NULL || signature == NULL)
737 
738  //Invalid elliptic curve?
739  if(privateKey->curve == NULL)
741 
742  //Initialize status code
743  error = NO_ERROR;
744 
745  //Get elliptic curve parameters
746  curve = privateKey->curve;
747 
748  //Get the length of the modulus, in bytes
749  modLen = (curve->fieldSize + 7) / 8;
750  //Get the length of the order, in bytes
751  orderLen = (curve->orderSize + 7) / 8;
752 
753  //Check the length of the operands
754  if(modLen <= 66 && orderLen <= 66)
755  {
756  //Acquire exclusive access to the ELS module
758 
759  //Copy domain parameters
760  ecScalarExport(curve->p, (modLen + 3) / 4, elsEcdsaArgs.p, modLen,
762 
763  ecScalarExport(curve->a, (modLen + 3) / 4, elsEcdsaArgs.a, modLen,
765 
766  ecScalarExport(curve->b, (modLen + 3) / 4, elsEcdsaArgs.b, modLen,
768 
769  ecScalarExport(curve->g.x, (modLen + 3) / 4, elsEcdsaArgs.g, modLen,
771 
772  ecScalarExport(curve->g.y, (modLen + 3) / 4, elsEcdsaArgs.g + modLen,
774 
775  ecScalarExport(curve->q, (modLen + 3) / 4, elsEcdsaArgs.q, orderLen,
777 
778  //Copy private key
779  ecScalarExport(privateKey->d, (orderLen + 3) / 4, elsEcdsaArgs.privateKey,
780  orderLen, EC_SCALAR_FORMAT_BIG_ENDIAN);
781 
782  //Set point multiplication parameters
783  signParam.curveParam.pA = elsEcdsaArgs.a;
784  signParam.curveParam.pB = elsEcdsaArgs.b;
785  signParam.curveParam.pP = elsEcdsaArgs.p;
786  signParam.curveParam.pG = elsEcdsaArgs.g;
787  signParam.curveParam.pN = elsEcdsaArgs.q;
788  signParam.curveParam.misc = (orderLen << 8) | modLen;
789  signParam.pHash = digest;
790  signParam.pPrivateKey = elsEcdsaArgs.privateKey;
791  signParam.pSignature = elsEcdsaArgs.signature;
792  signParam.optLen = mcuxClEcc_Sign_Param_optLen_Pack(digestLen);
793  signParam.pMode = &mcuxClEcc_ECDSA_ProtocolDescriptor;
794 
795  //Generate ECDSA signature
796  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClEcc_Sign(
797  &elsSession, &signParam));
798 
799  //Check the protection token and the return value
800  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_Sign) ||
801  status != MCUXCLECC_STATUS_OK)
802  {
803  error = ERROR_FAILURE;
804  }
805 
806  //End of function call
807  MCUX_CSSL_FP_FUNCTION_CALL_END();
808 
809  //Check status code
810  if(!error)
811  {
812  //Save elliptic curve parameters
813  signature->curve = curve;
814 
815  //Copy integer R
816  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE,
818 
819  //Check status code
820  if(!error)
821  {
822  //Copy integer S
823  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE,
824  elsEcdsaArgs.signature + orderLen, orderLen,
826  }
827  }
828 
829  //Release exclusive access to the ELS module
831  }
832  else
833  {
834  //Report an error
835  error = ERROR_INVALID_LENGTH;
836  }
837 
838  //Return status code
839  return error;
840 }
841 
842 
843 /**
844  * @brief ECDSA signature verification
845  * @param[in] publicKey Signer's EC public key
846  * @param[in] digest Digest of the message whose signature is to be verified
847  * @param[in] digestLen Length in octets of the digest
848  * @param[in] signature (R, S) integer pair
849  * @return Error code
850  **/
851 
853  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
854 {
855  error_t error;
856  size_t modLen;
857  size_t orderLen;
858  const uint8_t *precG;
859  const EcCurve *curve;
860  mcuxClEcc_Verify_Param_t verifyParam;
861 
862  //Check parameters
863  if(publicKey == NULL || digest == NULL || signature == NULL)
865 
866  //Invalid elliptic curve?
867  if(publicKey->curve == NULL)
869 
870  //Initialize status code
871  error = NO_ERROR;
872 
873  //Get elliptic curve parameters
874  curve = publicKey->curve;
875 
876  //Check elliptic curve parameters
877  if(osStrcmp(curve->name, "secp192r1") == 0)
878  {
879  precG = SECP192R1_PRECG;
880  }
881  else if(osStrcmp(curve->name, "secp224r1") == 0)
882  {
883  precG = SECP224R1_PRECG;
884  }
885  else if(osStrcmp(curve->name, "secp256k1") == 0)
886  {
887  precG = SECP256K1_PRECG;
888  }
889  else if(osStrcmp(curve->name, "secp256r1") == 0)
890  {
891  precG = SECP256R1_PRECG;
892  }
893  else if(osStrcmp(curve->name, "secp384r1") == 0)
894  {
895  precG = SECP384R1_PRECG;
896  }
897  else if(osStrcmp(curve->name, "secp521r1") == 0)
898  {
899  precG = SECP521R1_PRECG;
900  }
901  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
902  {
903  precG = BRAINPOOLP256R1_PRECG;
904  }
905  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
906  {
907  precG = BRAINPOOLP384R1_PRECG;
908  }
909  else if(osStrcmp(curve->name, "brainpoolP512r1") == 0)
910  {
911  precG = BRAINPOOLP512R1_PRECG;
912  }
913  else
914  {
915  return ERROR_FAILURE;
916  }
917 
918  //Get the length of the modulus, in bytes
919  modLen = (curve->fieldSize + 7) / 8;
920  //Get the length of the order, in bytes
921  orderLen = (curve->orderSize + 7) / 8;
922 
923  //Check the length of the operands
924  if(modLen <= 66 && orderLen <= 66)
925  {
926  //Acquire exclusive access to the ELS module
928 
929  //Copy domain parameters
930  ecScalarExport(curve->p, (modLen + 3) / 4, elsEcdsaArgs.p, modLen,
932 
933  ecScalarExport(curve->a, (modLen + 3) / 4, elsEcdsaArgs.a, modLen,
935 
936  ecScalarExport(curve->b, (modLen + 3) / 4, elsEcdsaArgs.b, modLen,
938 
939  ecScalarExport(curve->g.x, (modLen + 3) / 4, elsEcdsaArgs.g, modLen,
941 
942  ecScalarExport(curve->g.y, (modLen + 3) / 4, elsEcdsaArgs.g + modLen,
944 
945  ecScalarExport(curve->q, (modLen + 3) / 4, elsEcdsaArgs.q, orderLen,
947 
948  //Copy public key
949  ecScalarExport(publicKey->q.x, (modLen + 3) / 4, elsEcdsaArgs.publicKey,
951 
952  ecScalarExport(publicKey->q.y, (modLen + 3) / 4, elsEcdsaArgs.publicKey +
953  modLen, modLen, EC_SCALAR_FORMAT_BIG_ENDIAN);
954 
955  //Copy signature
956  ecScalarExport(signature->r, (modLen + 3) / 4, elsEcdsaArgs.signature,
957  orderLen, EC_SCALAR_FORMAT_BIG_ENDIAN);
958 
959  ecScalarExport(signature->s, (modLen + 3) / 4, elsEcdsaArgs.signature +
960  orderLen, orderLen, EC_SCALAR_FORMAT_BIG_ENDIAN);
961 
962  //Set point multiplication parameters
963  verifyParam.curveParam.pA = elsEcdsaArgs.a;
964  verifyParam.curveParam.pB = elsEcdsaArgs.b;
965  verifyParam.curveParam.pP = elsEcdsaArgs.p;
966  verifyParam.curveParam.pG = elsEcdsaArgs.g;
967  verifyParam.curveParam.pN = elsEcdsaArgs.q;
968  verifyParam.curveParam.misc = (orderLen << 8) | modLen;
969  verifyParam.pPrecG = precG;
970  verifyParam.pHash = digest;
971  verifyParam.pSignature = elsEcdsaArgs.signature;
972  verifyParam.pPublicKey = elsEcdsaArgs.publicKey;
973  verifyParam.pOutputR = elsEcdsaArgs.r;
974  verifyParam.optLen = mcuxClEcc_Sign_Param_optLen_Pack(digestLen);
975 
976  //Verify ECDSA signature
977  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClEcc_Verify(
978  &elsSession, &verifyParam));
979 
980  //Check the protection token and the return value
981  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_Verify))
982  {
983  error = ERROR_FAILURE;
984  }
985  else if(status == MCUXCLECC_STATUS_OK)
986  {
987  error = NO_ERROR;
988  }
989  else if(status == MCUXCLECC_STATUS_INVALID_SIGNATURE)
990  {
991  error = ERROR_INVALID_SIGNATURE;
992  }
993  else
994  {
995  error = ERROR_FAILURE;
996  }
997 
998  //End of function call
999  MCUX_CSSL_FP_FUNCTION_CALL_END();
1000 
1001  //Release exclusive access to the ELS module
1003  }
1004  else
1005  {
1006  //Report an error
1007  error = ERROR_INVALID_LENGTH;
1008  }
1009 
1010  //Return status code
1011  return error;
1012 }
1013 
1014 #endif
1015 #if (X25519_SUPPORT == ENABLED)
1016 
1017 /**
1018  * @brief X25519 function (scalar multiplication on Curve25519)
1019  * @param[out] r Output u-coordinate
1020  * @param[in] k Input scalar
1021  * @param[in] u Input u-coordinate
1022  * @return Error code
1023  **/
1024 
1025 error_t x25519(uint8_t *r, const uint8_t *k, const uint8_t *u)
1026 {
1027  error_t error;
1028  uint32_t n;
1029 
1030  //Point to the private and public key descriptors
1031  mcuxClKey_Handle_t privKeyHandle = (mcuxClKey_Handle_t) elsMontDhArgs.privKeyDesc;
1032  mcuxClKey_Handle_t pubKeyHandle = (mcuxClKey_Handle_t) elsMontDhArgs.pubKeyDesc;
1033 
1034  //Initialize status code
1035  error = NO_ERROR;
1036 
1037  //Acquire exclusive access to the ELS module
1039 
1040  //Load input scalar
1041  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1042  privKeyHandle, mcuxClKey_Type_Ecc_MontDH_Curve25519_PrivateKey, k,
1043  MCUXCLECC_MONTDH_CURVE25519_SIZE_PRIVATEKEY));
1044 
1045  //Check the protection token and the return value
1046  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1047  status != MCUXCLKEY_STATUS_OK)
1048  {
1049  error = ERROR_FAILURE;
1050  }
1051 
1052  //End of function call
1053  MCUX_CSSL_FP_FUNCTION_CALL_END();
1054 
1055  //Check status code
1056  if(!error)
1057  {
1058  //Load input u-coordinate
1059  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1060  pubKeyHandle, mcuxClKey_Type_Ecc_MontDH_Curve25519_PublicKey, u,
1061  MCUXCLECC_MONTDH_CURVE25519_SIZE_PUBLICKEY));
1062 
1063  //Check the protection token and the return value
1064  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1065  status != MCUXCLKEY_STATUS_OK)
1066  {
1067  error = ERROR_FAILURE;
1068  }
1069 
1070  //End of function call
1071  MCUX_CSSL_FP_FUNCTION_CALL_END();
1072  }
1073 
1074  //Check status code
1075  if(!error)
1076  {
1077  //Perform scalar multiplication
1078  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClEcc_MontDH_KeyAgreement(
1079  &elsSession, privKeyHandle, pubKeyHandle, elsMontDhArgs.sharedSecret, &n));
1080 
1081  //Check the protection token and the return value
1082  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_MontDH_KeyAgreement) ||
1083  status != MCUXCLECC_STATUS_OK)
1084  {
1085  error = ERROR_FAILURE;
1086  }
1087 
1088  //End of function call
1089  MCUX_CSSL_FP_FUNCTION_CALL_END();
1090  }
1091 
1092  //Check status code
1093  if(!error)
1094  {
1095  //Copy output u-coordinate
1097  }
1098 
1099  //Release exclusive access to the ELS module
1101 
1102  //Return status code
1103  return error;
1104 }
1105 
1106 #endif
1107 #if (X448_SUPPORT == ENABLED)
1108 
1109 /**
1110  * @brief X448 function (scalar multiplication on Curve448)
1111  * @param[out] r Output u-coordinate
1112  * @param[in] k Input scalar
1113  * @param[in] u Input u-coordinate
1114  * @return Error code
1115  **/
1116 
1117 error_t x448(uint8_t *r, const uint8_t *k, const uint8_t *u)
1118 {
1119  error_t error;
1120  uint32_t n;
1121 
1122  //Point to the private and public key descriptors
1123  mcuxClKey_Handle_t privKeyHandle = (mcuxClKey_Handle_t) elsMontDhArgs.privKeyDesc;
1124  mcuxClKey_Handle_t pubKeyHandle = (mcuxClKey_Handle_t) elsMontDhArgs.pubKeyDesc;
1125 
1126  //Initialize status code
1127  error = NO_ERROR;
1128 
1129  //Acquire exclusive access to the ELS module
1131 
1132  //Load input scalar
1133  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1134  privKeyHandle, mcuxClKey_Type_Ecc_MontDH_Curve448_PrivateKey, k,
1135  MCUXCLECC_MONTDH_CURVE448_SIZE_PRIVATEKEY));
1136 
1137  //Check the protection token and the return value
1138  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1139  status != MCUXCLKEY_STATUS_OK)
1140  {
1141  error = ERROR_FAILURE;
1142  }
1143 
1144  //End of function call
1145  MCUX_CSSL_FP_FUNCTION_CALL_END();
1146 
1147  //Check status code
1148  if(!error)
1149  {
1150  //Load input u-coordinate
1151  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1152  pubKeyHandle, mcuxClKey_Type_Ecc_MontDH_Curve448_PublicKey, u,
1153  MCUXCLECC_MONTDH_CURVE448_SIZE_PUBLICKEY));
1154 
1155  //Check the protection token and the return value
1156  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1157  status != MCUXCLKEY_STATUS_OK)
1158  {
1159  error = ERROR_FAILURE;
1160  }
1161 
1162  //End of function call
1163  MCUX_CSSL_FP_FUNCTION_CALL_END();
1164  }
1165 
1166  //Check status code
1167  if(!error)
1168  {
1169  //Perform scalar multiplication
1170  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClEcc_MontDH_KeyAgreement(
1171  &elsSession, privKeyHandle, pubKeyHandle, elsMontDhArgs.sharedSecret, &n));
1172 
1173  //Check the protection token and the return value
1174  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_MontDH_KeyAgreement) ||
1175  status != MCUXCLECC_STATUS_OK)
1176  {
1177  error = ERROR_FAILURE;
1178  }
1179 
1180  //End of function call
1181  MCUX_CSSL_FP_FUNCTION_CALL_END();
1182  }
1183 
1184  //Check status code
1185  if(!error)
1186  {
1187  //Copy output u-coordinate
1189  }
1190 
1191  //Release exclusive access to the ELS module
1193 
1194  //Return status code
1195  return error;
1196 }
1197 
1198 #endif
1199 #if (ED25519_SUPPORT == ENABLED)
1200 
1201 /**
1202  * @brief EdDSA signature generation
1203  * @param[in] privateKey Signer's EdDSA private key (32 bytes)
1204  * @param[in] publicKey Signer's EdDSA public key (32 bytes)
1205  * @param[in] message Pointer to the message to be signed
1206  * @param[in] messageLen Length of the message, in bytes
1207  * @param[in] context Constant string specified by the protocol using it
1208  * @param[in] contextLen Length of the context, in bytes
1209  * @param[in] flag Prehash flag for Ed25519ph scheme
1210  * @param[out] signature EdDSA signature (64 bytes)
1211  * @return Error code
1212  **/
1213 
1214 error_t ed25519GenerateSignature(const uint8_t *privateKey,
1215  const uint8_t *publicKey, const void *message, size_t messageLen,
1216  const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
1217 {
1218  error_t error;
1219  uint32_t n;
1220  const mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *protocolDesc;
1221 
1222  //Point to the private and public key descriptors
1223  mcuxClKey_Handle_t privKeyHandle = (mcuxClKey_Handle_t) elsEddsaArgs.privKeyDesc;
1224  mcuxClKey_Handle_t pubKeyHandle = (mcuxClKey_Handle_t) elsEddsaArgs.pubKeyDesc;
1225 
1226  //Ed25519ph scheme is not supported
1227  if(flag != 0)
1228  return ERROR_INVALID_PARAMETER;
1229 
1230  //Initialize status code
1231  error = NO_ERROR;
1232 
1233  //Acquire exclusive access to the ELS module
1235 
1236  //Initialize private key
1237  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1238  privKeyHandle, mcuxClKey_Type_EdDSA_Ed25519_Priv, elsEddsaArgs.privKeyData,
1239  MCUXCLECC_EDDSA_ED25519_SIZE_PRIVATEKEYDATA));
1240 
1241  //Check the protection token and the return value
1242  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1243  status != MCUXCLKEY_STATUS_OK)
1244  {
1245  error = ERROR_FAILURE;
1246  }
1247 
1248  //End of function call
1249  MCUX_CSSL_FP_FUNCTION_CALL_END();
1250 
1251  //Check status code
1252  if(!error)
1253  {
1254  //Initialize public key
1255  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1256  pubKeyHandle, mcuxClKey_Type_EdDSA_Ed25519_Pub, elsEddsaArgs.pubKeyData,
1257  MCUXCLECC_EDDSA_ED25519_SIZE_PUBLICKEY));
1258 
1259  //Check the protection token and the return value
1260  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1261  status != MCUXCLKEY_STATUS_OK)
1262  {
1263  error = ERROR_FAILURE;
1264  }
1265 
1266  //End of function call
1267  MCUX_CSSL_FP_FUNCTION_CALL_END();
1268  }
1269 
1270  //Check status code
1271  if(!error)
1272  {
1273  //Load private key
1274  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1275  mcuxClEcc_EdDSA_InitPrivKeyInputMode(&elsSession,
1276  (mcuxClEcc_EdDSA_GenerateKeyPairDescriptor_t *) &elsEddsaArgs.keyPairDesc,
1277  privateKey));
1278 
1279  //Check the protection token and the return value
1280  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_InitPrivKeyInputMode) ||
1281  status != MCUXCLECC_STATUS_OK)
1282  {
1283  error = ERROR_FAILURE;
1284  }
1285 
1286  //End of function call
1287  MCUX_CSSL_FP_FUNCTION_CALL_END();
1288  }
1289 
1290  //Check status code
1291  if(!error)
1292  {
1293  //Derive the public key from the private key
1294  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1295  mcuxClEcc_EdDSA_GenerateKeyPair(&elsSession,
1296  (mcuxClEcc_EdDSA_GenerateKeyPairDescriptor_t *) &elsEddsaArgs.keyPairDesc,
1297  privKeyHandle, pubKeyHandle));
1298 
1299  //Check the protection token and the return value
1300  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_GenerateKeyPair) ||
1301  status != MCUXCLECC_STATUS_OK)
1302  {
1303  error = ERROR_FAILURE;
1304  }
1305 
1306  //End of function call
1307  MCUX_CSSL_FP_FUNCTION_CALL_END();
1308  }
1309 
1310  //Check status code
1311  if(!error)
1312  {
1313  //Ed25519ctx scheme?
1314  if(context != NULL)
1315  {
1316  //Point to the protocol descriptor
1317  protocolDesc = (mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *) elsEddsaArgs.protocolDesc;
1318 
1319  //Generate Ed25519ctx protocol descriptor
1320  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1321  mcuxClEcc_EdDSA_GenerateProtocolDescriptor(&elsSession,
1322  &mcuxClEcc_EdDSA_DomainParams_Ed25519,
1323  (mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *) protocolDesc,
1324  MCUXCLECC_EDDSA_PHFLAG_ZERO, context, contextLen));
1325 
1326  //Check the protection token and the return value
1327  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_GenerateProtocolDescriptor) ||
1328  status != MCUXCLECC_STATUS_OK)
1329  {
1330  error = ERROR_FAILURE;
1331  }
1332 
1333  //End of function call
1334  MCUX_CSSL_FP_FUNCTION_CALL_END();
1335  }
1336  else
1337  {
1338  //Point to the protocol descriptor
1339  protocolDesc = &mcuxClEcc_EdDsa_Ed25519ProtocolDescriptor;
1340  }
1341  }
1342 
1343  //Check status code
1344  if(!error)
1345  {
1346  //Generate Ed25519 signature
1347  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1348  mcuxClEcc_EdDSA_GenerateSignature(&elsSession, privKeyHandle,
1349  protocolDesc, message, messageLen, elsEddsaArgs.signature, &n));
1350 
1351  //Check the protection token and the return value
1352  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_GenerateSignature) ||
1353  status != MCUXCLECC_STATUS_OK)
1354  {
1355  error = ERROR_FAILURE;
1356  }
1357 
1358  //End of function call
1359  MCUX_CSSL_FP_FUNCTION_CALL_END();
1360  }
1361 
1362  //Check status code
1363  if(!error)
1364  {
1365  //Copy signature
1366  osMemcpy(signature, elsEddsaArgs.signature, n);
1367  }
1368 
1369  //Release exclusive access to the ELS module
1371 
1372  //Return status code
1373  return error;
1374 }
1375 
1376 
1377 /**
1378  * @brief EdDSA signature verification
1379  * @param[in] publicKey Signer's EdDSA public key (32 bytes)
1380  * @param[in] message Message whose signature is to be verified
1381  * @param[in] messageLen Length of the message, in bytes
1382  * @param[in] context Constant string specified by the protocol using it
1383  * @param[in] contextLen Length of the context, in bytes
1384  * @param[in] flag Prehash flag for Ed25519ph scheme
1385  * @param[in] signature EdDSA signature (64 bytes)
1386  * @return Error code
1387  **/
1388 
1389 error_t ed25519VerifySignature(const uint8_t *publicKey, const void *message,
1390  size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag,
1391  const uint8_t *signature)
1392 {
1393  error_t error;
1394  const mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *protocolDesc;
1395 
1396  //Point to the public key descriptor
1397  mcuxClKey_Handle_t pubKeyHandle = (mcuxClKey_Handle_t) elsEddsaArgs.pubKeyDesc;
1398 
1399  //Ed25519ph scheme is not supported
1400  if(flag != 0)
1401  return ERROR_INVALID_PARAMETER;
1402 
1403  //Initialize status code
1404  error = NO_ERROR;
1405 
1406  //Acquire exclusive access to the ELS module
1408 
1409  //Load public key
1410  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token, mcuxClKey_init(&elsSession,
1411  pubKeyHandle, mcuxClKey_Type_EdDSA_Ed25519_Pub, publicKey,
1412  MCUXCLECC_EDDSA_ED25519_SIZE_PUBLICKEY));
1413 
1414  //Check the protection token and the return value
1415  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) ||
1416  status != MCUXCLKEY_STATUS_OK)
1417  {
1418  error = ERROR_FAILURE;
1419  }
1420 
1421  //End of function call
1422  MCUX_CSSL_FP_FUNCTION_CALL_END();
1423 
1424  //Check status code
1425  if(!error)
1426  {
1427  //Ed25519ctx scheme?
1428  if(context != NULL)
1429  {
1430  //Point to the protocol descriptor
1431  protocolDesc = (mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *) elsEddsaArgs.protocolDesc;
1432 
1433  //Generate Ed25519ctx protocol descriptor
1434  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1435  mcuxClEcc_EdDSA_GenerateProtocolDescriptor(&elsSession,
1436  &mcuxClEcc_EdDSA_DomainParams_Ed25519,
1437  (mcuxClEcc_EdDSA_SignatureProtocolDescriptor_t *) protocolDesc,
1438  MCUXCLECC_EDDSA_PHFLAG_ZERO, context, contextLen));
1439 
1440  //Check the protection token and the return value
1441  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_GenerateProtocolDescriptor) ||
1442  status != MCUXCLECC_STATUS_OK)
1443  {
1444  error = ERROR_FAILURE;
1445  }
1446 
1447  //End of function call
1448  MCUX_CSSL_FP_FUNCTION_CALL_END();
1449  }
1450  else
1451  {
1452  //Point to the protocol descriptor
1453  protocolDesc = &mcuxClEcc_EdDsa_Ed25519ProtocolDescriptor;
1454  }
1455  }
1456 
1457  //Check status code
1458  if(!error)
1459  {
1460  //Copy signature
1462 
1463  //Verify Ed25519 signature
1464  MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(status, token,
1465  mcuxClEcc_EdDSA_VerifySignature(&elsSession, pubKeyHandle,
1466  protocolDesc, message, messageLen, elsEddsaArgs.signature,
1468 
1469  //Check the protection token and the return value
1470  if(token != MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEcc_EdDSA_VerifySignature))
1471  {
1472  error = ERROR_FAILURE;
1473  }
1474  else if(status == MCUXCLECC_STATUS_OK)
1475  {
1476  error = NO_ERROR;
1477  }
1478  else if(status == MCUXCLECC_STATUS_INVALID_SIGNATURE)
1479  {
1480  error = ERROR_INVALID_SIGNATURE;
1481  }
1482  else
1483  {
1484  error = ERROR_FAILURE;
1485  }
1486 
1487  //End of function call
1488  MCUX_CSSL_FP_FUNCTION_CALL_END();
1489  }
1490 
1491  //Release exclusive access to the ELS module
1493 
1494  //Return status code
1495  return error;
1496 }
1497 
1498 #endif
1499 #endif
error_t ed25519GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
uint8_t dp[512]
error_t ecScalarImport(uint32_t *r, uint_t n, const uint8_t *input, size_t length, EcScalarFormat format)
Octet string to integer conversion.
Definition: ec_misc.c:54
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
ECDSA signature.
Definition: ecdsa.h:63
ELS ECC primitive arguments.
Ed25519 elliptic curve (constant-time implementation)
uint8_t signature[132]
@ ERROR_OUT_OF_RANGE
Definition: error.h:138
NXP MCX N947 hardware cryptographic accelerator.
Mpi p
First factor.
Definition: rsa.h:72
uint8_t a
Definition: ndp.h:411
uint32_t pubKeyDesc[MCUXCLKEY_DESCRIPTOR_SIZE_IN_WORDS]
error_t ecScalarExport(const uint32_t *a, uint_t n, uint8_t *output, size_t length, EcScalarFormat format)
Integer to octet string conversion.
Definition: ec_misc.c:150
Arbitrary precision integer.
Definition: mpi.h:102
uint8_t publicKey[132]
#define PrngAlgo
Definition: crypto.h:1008
uint8_t dq[512]
ALIGNED ElsEcdsaArgs elsEcdsaArgs
ECDSA (Elliptic Curve Digital Signature Algorithm)
uint8_t p
Definition: ndp.h:300
ALIGNED ElsMontDhArgs elsMontDhArgs
const EcCurve * curve
Elliptic curve parameters.
Definition: ecdsa.h:64
uint8_t message[]
Definition: chap.h:154
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:433
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t privKeyData[MCUXCLECC_EDDSA_ED25519_SIZE_PRIVATEKEYDATA]
void ecFullAdd(EcState *state, EcPoint3 *r, const EcPoint3 *s, const EcPoint3 *t)
Point addition.
Definition: ec.c:1136
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
uint8_t p[66]
Mpi n
Modulus.
Definition: rsa.h:69
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#define osStrcmp(s1, s2)
Definition: os_port.h:174
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
Mpi e
Public exponent.
Definition: rsa.h:59
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
uint8_t d[66]
Mpi d
Private exponent.
Definition: rsa.h:71
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
Mpi n
Modulus.
Definition: rsa.h:58
X448 function implementation.
uint8_t r
Definition: ndp.h:346
uint8_t n[512]
OsMutex mcxn947CryptoMutex
@ ERROR_INVALID_ELLIPTIC_CURVE
Definition: error.h:134
uint32_t privKeyDesc[MCUXCLKEY_DESCRIPTOR_SIZE_IN_WORDS]
error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (regular calculation)
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
error_t
Error codes.
Definition: error.h:43
NXP MCX N947 public-key hardware accelerator (PKA)
uint8_t pubKeyData[MCUXCLECC_EDDSA_ED25519_SIZE_PUBLICKEY]
uint8_t a[66]
ELS MontDH primitive arguments.
ALIGNED ElsEccArgs elsEccArgs
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
uint8_t d[512]
void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
Set integer value.
Definition: ec_misc.c:505
Mpi q
Second factor.
Definition: rsa.h:73
Helper routines for ECC.
ELS ECDSA primitive arguments.
RSA public key.
Definition: rsa.h:57
ELS EdDSA primitive arguments.
uint8_t output[132]
uint32_t r[EC_MAX_ORDER_SIZE]
Integer R.
Definition: ecdsa.h:65
uint8_t g[132]
mcuxClSession_Descriptor_t elsSession
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
uint32_t privKeyDesc[MCUXCLKEY_DESCRIPTOR_SIZE_IN_WORDS]
EC private key.
Definition: ec.h:432
uint8_t u
Definition: lldp_ext_med.h:213
ALIGNED ElsRsaArgs elsRsaArgs
uint32_t pubKeyDesc[MCUXCLKEY_DESCRIPTOR_SIZE_IN_WORDS]
uint8_t c[512]
X25519 function implementation.
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
uint8_t m[512]
EC public key.
Definition: ec.h:421
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:189
const EcCurve * curve
Definition: ec.h:446
ALIGNED ElsEddsaArgs elsEddsaArgs
error_t x25519(uint8_t *r, const uint8_t *k, const uint8_t *u)
X25519 function (scalar multiplication on Curve25519)
uint32_t d[EC_MAX_ORDER_SIZE]
Private key.
Definition: ec.h:434
uint8_t p[512]
Working state (point addition/subtraction/doubling)
Definition: ec.h:445
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
uint8_t e[512]
@ EC_SCALAR_FORMAT_BIG_ENDIAN
Definition: ec_misc.h:51
uint8_t qinv[512]
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
EC point (projective coordinates)
Definition: ec.h:409
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
error_t ecdsaVerifySignature(const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
error_t x448(uint8_t *r, const uint8_t *k, const uint8_t *u)
X448 function (scalar multiplication on Curve448)
error_t ecTwinMul(const EcCurve *curve, EcPoint3 *r, const uint32_t *d0, const EcPoint3 *s, const uint32_t *d1, const EcPoint3 *t)
Twin multiplication.
uint32_t keyPairDesc[MCUXCLECC_EDDSA_GENERATEKEYPAIR_DESCRIPTOR_SIZE_IN_WORDS]
uint8_t input[132]
EcPoint q
Public key.
Definition: ec.h:423
uint32_t s[EC_MAX_ORDER_SIZE]
Integer S.
Definition: ecdsa.h:66
#define cryptoAllocMem(size)
Definition: crypto.h:856
uint8_t s
Definition: igmp_common.h:234
uint8_t sharedSecret[MCUXCLECC_MONTDH_CURVE448_SIZE_SHAREDSECRET]
RSA primitive arguments.
uint8_t g[132]
#define EcCurve
Definition: ec.h:346
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:359
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
uint8_t q[66]
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:430
unsigned int uint_t
Definition: compiler_port.h:57
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
#define osMemset(p, value, length)
Definition: os_port.h:138
uint8_t q[512]
error_t ed25519VerifySignature(const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, const uint8_t *signature)
EdDSA signature verification.
ECC (Elliptic Curve Cryptography)
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
uint8_t signature[MCUXCLECC_EDDSA_ED25519_SIZE_SIGNATURE]
uint8_t privateKey[66]
uint32_t protocolDesc[MCUXCLECC_EDDSA_ED25519_SIGNATURE_PROTOCOL_DESCRIPTOR_SIZE_IN_WORD(256)]
uint8_t b[66]
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
#define EC_MAX_MODULUS_SIZE
Definition: ec.h:284
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
Debugging facilities.
error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (fast calculation)
uint8_t token[]
Definition: coap_common.h:181
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216