max32690_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file max32690_crypto_pkc.c
3  * @brief MAX32690 public-key hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "mxc_device.h"
36 #include "mxc_sys.h"
37 #include "ctb.h"
38 #include "core/crypto.h"
41 #include "ecc/ec.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (MAX32690_CRYPTO_PKC_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Set operand value
50  * @param[in] offset MAA memory offset
51  * @param[in] value Value of the operand
52  * @param[in] length Length of the operand, in bits
53  **/
54 
55 void maaSetValue(uint_t offset, uint32_t value, uint_t length)
56 {
57  uint_t i;
58  uint32_t *p;
59 
60  //Point to the specified MAA memory segment
61  p = (uint32_t *) (MXC_BASE_CTB + offset);
62 
63  //Retrieve the length of the operand, in 64-bit words
64  length = (length + 63) / 64;
65 
66  //Set the value of the operand
67  p[0] = value;
68 
69  //Clear MAA memory
70  for(i = 1; i < (length * 2); i++)
71  {
72  p[i] = 0;
73  }
74 }
75 
76 
77 /**
78  * @brief Import multiple-precision integer
79  * @param[in] offset MAA memory offset
80  * @param[in] a Pointer to the multiple-precision integer
81  * @param[in] length Length of the operand, in bits
82  **/
83 
84 void maaImportMpi(uint_t offset, const Mpi *a, uint_t length)
85 {
86  uint_t i;
87  uint32_t *p;
88 
89  //Point to the specified MAA memory segment
90  p = (uint32_t *) (MXC_BASE_CTB + offset);
91 
92  //Retrieve the length of the operand, in 64-bit words
93  length = (length + 63) / 64;
94 
95  //Copy the multiple-precision integer to the MAA memory
96  for(i = 0; i < a->size && i < (length * 2); i++)
97  {
98  p[i] = a->data[i];
99  }
100 
101  //Pad the operand with zeroes
102  while(i < (length * 2))
103  {
104  p[i++] = 0;
105  }
106 }
107 
108 
109 /**
110  * @brief Export multiple-precision integer
111  * @param[in] offset MAA memory offset
112  * @param[out] r Pointer to the multiple-precision integer
113  * @param[in] length Length of the operand, in bits
114  * @return Error code
115  **/
116 
118 {
119  error_t error;
120  uint_t i;
121  uint32_t *p;
122 
123  //Point to the specified MAA memory segment
124  p = (uint32_t *) (MXC_BASE_CTB + offset);
125 
126  //Retrieve the length of the operand, in 32-bit words
127  length = (length + 31) / 32;
128 
129  //Ajust the size of the multiple precision integer
130  error = mpiGrow(r, length);
131 
132  //Check status code
133  if(!error)
134  {
135  //Copy the multiple-precision integer from the PKA RAM
136  for(i = 0; i < length; i++)
137  {
138  r->data[i] = p[i];
139  }
140 
141  //Pad the resulting value with zeroes
142  for(; i < r->size; i++)
143  {
144  r->data[i] = 0;
145  }
146 
147  //Set the sign
148  r->sign = 1;
149  }
150 
151  //Return status code
152  return error;
153 }
154 
155 
156 #if (MPI_SUPPORT == ENABLED)
157 
158 /**
159  * @brief Modular exponentiation (fast calculation)
160  * @param[out] r Resulting integer R = A ^ E mod P
161  * @param[in] a Pointer to a multiple precision integer
162  * @param[in] e Exponent
163  * @param[in] p Modulus
164  * @return Error code
165  **/
166 
167 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
168 {
169  error_t error;
170  uint_t modLen;
171 
172  //Retrieve the length of the modulus, in bits
173  modLen = mpiGetBitLength(p);
174 
175  //The accelerator supports operand lengths up to 2048 bits
176  if(modLen <= 2048)
177  {
178  //Acquire exclusive access to the CTB module
180 
181  //Reset the engine by setting CTB_CTRL.rst
182  MXC_CTB->ctrl = MXC_F_CTB_CTRL_RST;
183 
184  //Software must poll the CTB_CTRL.rst bit until it is set to 1 by
185  //hardware, indicating the cryptographic accelerator is ready for use
186  while((MXC_CTB->ctrl & MXC_F_CTB_CTRL_RDY) == 0)
187  {
188  }
189 
190  //Legacy support for the access behavior of the done flags
191  MXC_CTB->ctrl |= MXC_F_CTB_CTRL_FLAG_MODE;
192 
193  //Specify the size of the modular operation
194  MXC_CTB->maa_maws = modLen;
195 
196  //Copy the operand
198  //For exponentiation operations, b memory must contain the value of 1
200  //The exponent is always stored in memory instance 4
202  //The modulus is always stored in memory instance 5
204 
205  //Set up a modular exponentiation operation (speed-optimized calculation)
206  MXC_CTB->maa_ctrl = CTB_MAA_CTRL_TMA(6) | CTB_MAA_CTRL_RMA(4) |
209 
210  //Start MAA operation
211  MXC_CTB->maa_ctrl |= CTB_MAA_CTRL_START_Msk;
212 
213  //Wait for the MAA operation to complete
214  while((MXC_CTB->ctrl & TB_CTRL_MAA_DONE_Msk) == 0)
215  {
216  }
217 
218  //Copy the result
219  error = maaExportMpi(CTB_MAA_MEM_INSTANCE_2, r, modLen);
220 
221  //Release exclusive access to the CTB module
223  }
224  else
225  {
226  //Perform modular exponentiation (r = a ^ e mod p)
227  error = mpiExpMod(r, a, e, p);
228  }
229 
230  //Return status code
231  return error;
232 }
233 
234 
235 /**
236  * @brief Modular exponentiation (regular calculation)
237  * @param[out] r Resulting integer R = A ^ E mod P
238  * @param[in] a Pointer to a multiple precision integer
239  * @param[in] e Exponent
240  * @param[in] p Modulus
241  * @return Error code
242  **/
243 
244 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
245 {
246  error_t error;
247  uint_t modLen;
248 
249  //Retrieve the length of the modulus, in bits
250  modLen = mpiGetBitLength(p);
251 
252  //The accelerator supports operand lengths up to 2048 bits
253  if(modLen <= 2048)
254  {
255  //Acquire exclusive access to the CTB module
257 
258  //Reset the engine by setting CTB_CTRL.rst
259  MXC_CTB->ctrl = MXC_F_CTB_CTRL_RST;
260 
261  //Software must poll the CTB_CTRL.rst bit until it is set to 1 by
262  //hardware, indicating the cryptographic accelerator is ready for use
263  while((MXC_CTB->ctrl & MXC_F_CTB_CTRL_RDY) == 0)
264  {
265  }
266 
267  //Legacy support for the access behavior of the done flags
268  MXC_CTB->ctrl |= MXC_F_CTB_CTRL_FLAG_MODE;
269 
270  //Specify the size of the modular operation
271  MXC_CTB->maa_maws = modLen;
272 
273  //Copy the operand
275  //For exponentiation operations, b memory must contain the value of 1
277  //The exponent is always stored in memory instance 4
279  //The modulus is always stored in memory instance 5
281 
282  //Set up a modular exponentiation operation
283  MXC_CTB->maa_ctrl = CTB_MAA_CTRL_TMA(6) | CTB_MAA_CTRL_RMA(4) |
286 
287  //Start MAA operation
288  MXC_CTB->maa_ctrl |= CTB_MAA_CTRL_START_Msk;
289 
290  //Wait for the MAA operation to complete
291  while((MXC_CTB->ctrl & TB_CTRL_MAA_DONE_Msk) == 0)
292  {
293  }
294 
295  //Copy the result
296  error = maaExportMpi(CTB_MAA_MEM_INSTANCE_2, r, modLen);
297 
298  //Release exclusive access to the CTB module
300  }
301  else
302  {
303  //Perform modular exponentiation (r = a ^ e mod p)
304  error = mpiExpMod(r, a, e, p);
305  }
306 
307  //Return status code
308  return error;
309 }
310 
311 #endif
312 #if (EC_SUPPORT == ENABLED)
313 
314 /**
315  * @brief Modular multiplication
316  * @param[in] params EC domain parameters
317  * @param[out] r Resulting integer R = (A * B) mod p
318  * @param[in] a An integer such as 0 <= A < p
319  * @param[in] b An integer such as 0 <= B < p
320  * @return Error code
321  **/
322 
323 error_t ecMulMod(const EcDomainParameters *params, Mpi *r, const Mpi *a,
324  const Mpi *b)
325 {
326  error_t error;
327  uint_t modLen;
328 
329  //Retrieve the length of the modulus, in bits
330  modLen = mpiGetBitLength(&params->p);
331 
332  //Acquire exclusive access to the CTB module
334 
335  //Reset the engine by setting CTB_CTRL.rst
336  MXC_CTB->ctrl = MXC_F_CTB_CTRL_RST;
337 
338  //Software must poll the CTB_CTRL.rst bit until it is set to 1 by hardware,
339  //indicating the cryptographic accelerator is ready for use
340  while((MXC_CTB->ctrl & MXC_F_CTB_CTRL_RDY) == 0)
341  {
342  }
343 
344  //Legacy support for the access behavior of the done flags
345  MXC_CTB->ctrl |= MXC_F_CTB_CTRL_FLAG_MODE;
346 
347  //Specify the size of the modular operation
348  MXC_CTB->maa_maws = modLen;
349 
350  //Copy the first operand
352  //Copy the second operand
354  //The modulus is always stored in memory instance 5
355  maaImportMpi(CTB_MAA_MEM_INSTANCE_5, &params->p, modLen);
356 
357  //Set up a modular multiplication operation
358  MXC_CTB->maa_ctrl = CTB_MAA_CTRL_TMA(6) | CTB_MAA_CTRL_RMA(4) |
361 
362  //Start MAA operation
363  MXC_CTB->maa_ctrl |= CTB_MAA_CTRL_START_Msk;
364 
365  //Wait for the MAA operation to complete
366  while((MXC_CTB->ctrl & TB_CTRL_MAA_DONE_Msk) == 0)
367  {
368  }
369 
370  //Copy the result
371  error = maaExportMpi(CTB_MAA_MEM_INSTANCE_2, r, modLen);
372 
373  //Release exclusive access to the CTB module
375 
376  //Return status code
377  return error;
378 }
379 
380 
381 /**
382  * @brief Fast modular squaring
383  * @param[in] params EC domain parameters
384  * @param[out] r Resulting integer R = (A ^ 2) mod p
385  * @param[in] a An integer such as 0 <= A < p
386  * @return Error code
387  **/
388 
389 error_t ecSqrMod(const EcDomainParameters *params, Mpi *r, const Mpi *a)
390 {
391  error_t error;
392  uint_t modLen;
393 
394  //Retrieve the length of the modulus, in bits
395  modLen = mpiGetBitLength(&params->p);
396 
397  //Acquire exclusive access to the CTB module
399 
400  //Reset the engine by setting CTB_CTRL.rst
401  MXC_CTB->ctrl = MXC_F_CTB_CTRL_RST;
402 
403  //Software must poll the CTB_CTRL.rst bit until it is set to 1 by hardware,
404  //indicating the cryptographic accelerator is ready for use
405  while((MXC_CTB->ctrl & MXC_F_CTB_CTRL_RDY) == 0)
406  {
407  }
408 
409  //Legacy support for the access behavior of the done flags
410  MXC_CTB->ctrl |= MXC_F_CTB_CTRL_FLAG_MODE;
411 
412  //Specify the size of the modular operation
413  MXC_CTB->maa_maws = modLen;
414 
415  //Copy the operand
417  //The modulus is always stored in memory instance 5
418  maaImportMpi(CTB_MAA_MEM_INSTANCE_5, &params->p, modLen);
419 
420  //Set up a modular square operation
421  MXC_CTB->maa_ctrl = CTB_MAA_CTRL_TMA(6) | CTB_MAA_CTRL_RMA(4) |
424 
425  //Start MAA operation
426  MXC_CTB->maa_ctrl |= CTB_MAA_CTRL_START_Msk;
427 
428  //Wait for the MAA operation to complete
429  while((MXC_CTB->ctrl & TB_CTRL_MAA_DONE_Msk) == 0)
430  {
431  }
432 
433  //Copy the result
434  error = maaExportMpi(CTB_MAA_MEM_INSTANCE_2, r, modLen);
435 
436  //Release exclusive access to the CTB module
438 
439  //Return status code
440  return error;
441 }
442 
443 #endif
444 #endif
#define CTB_MAA_CTRL_AMA(n)
uint8_t b
Definition: nbns_common.h:104
void maaSetValue(uint_t offset, uint32_t value, uint_t length)
Set operand value.
Mpi p
Prime.
Definition: ec.h:79
MAX32690 hardware cryptographic accelerator.
uint8_t a
Definition: ndp.h:411
error_t maaExportMpi(uint_t offset, Mpi *r, uint_t length)
Export multiple-precision integer.
Arbitrary precision integer.
Definition: mpi.h:80
uint8_t p
Definition: ndp.h:300
#define CTB_MAA_CTRL_CALC_MOD_EXP_Val
error_t ecMulMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b)
Modular multiplication.
#define CTB_MAA_CTRL_OPT_Msk
EC domain parameters.
Definition: ec.h:76
void maaImportMpi(uint_t offset, const Mpi *a, uint_t length)
Import multiple-precision integer.
#define CTB_MAA_CTRL_START_Msk
uint8_t r
Definition: ndp.h:346
#define CTB_MAA_MEM_INSTANCE_1
error_t
Error codes.
Definition: error.h:43
#define CTB_MAA_CTRL_RMA(n)
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
MAX32690 public-key hardware accelerator.
General definitions for cryptographic algorithms.
#define CTB_MAA_MEM_INSTANCE_5
uint8_t length
Definition: tcp.h:368
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
#define CTB_MAA_MEM_INSTANCE_2
#define CTB_MAA_MEM_INSTANCE_0
#define CTB_MAA_MEM_INSTANCE_4
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define CTB_MAA_CTRL_TMA(n)
#define CTB_MAA_CTRL_CALC_MOD_MUL_Val
#define CTB_MAA_CTRL_CALC_MOD_SQR_Val
uint8_t value[]
Definition: tcp.h:369
OsMutex max32690CryptoMutex
#define TB_CTRL_MAA_DONE_Msk
#define CTB_MAA_CTRL_BMA(n)
unsigned int uint_t
Definition: compiler_port.h:50
ECC (Elliptic Curve Cryptography)
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:94
#define CTB_MAA_CTRL_CALC(n)
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
Debugging facilities.
error_t ecSqrMod(const EcDomainParameters *params, Mpi *r, const Mpi *a)
Fast modular squaring.
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)