mimxrt1160_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file mimxrt1160_crypto_pkc.c
3  * @brief i.MX RT1160 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 "fsl_device_registers.h"
36 #include "fsl_caam.h"
37 #include "core/crypto.h"
40 #include "ecc/ec.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (MIMXRT1160_CRYPTO_PKC_SUPPORT == ENABLED)
45 
46 //Global variables
49 
50 
51 /**
52  * @brief Modular multiplication
53  * @param[out] r Resulting integer R = A * B mod P
54  * @param[in] a The first operand A
55  * @param[in] b The second operand B
56  * @param[in] p The modulus P
57  * @return Error code
58  **/
59 
60 error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
61 {
62  error_t error;
63  status_t status;
64  size_t aLen;
65  size_t bLen;
66  size_t modLen;
67  size_t resultLen;
68  caam_handle_t caamHandle;
69  Mpi ta;
70  Mpi tb;
71 
72  //Initialize multiple precision integers
73  mpiInit(&ta);
74  mpiInit(&tb);
75 
76  //Retrieve the length of the modulus, in bytes
77  modLen = mpiGetByteLength(p);
78 
79  //The accelerator supports operand lengths up to 4096 bits
80  if(modLen <= 512)
81  {
82  //Reduce the first operand
83  error = mpiMod(&ta, a, p);
84 
85  //Check status code
86  if(!error)
87  {
88  //Reduce the second operand
89  error = mpiMod(&tb, b, p);
90  }
91 
92  //Check status code
93  if(!error)
94  {
95  //Retrieve the length of the first operand, in bytes
96  aLen = mpiGetByteLength(&ta);
97  //Retrieve the length of the second operand, in bytes
98  bLen = mpiGetByteLength(&tb);
99 
100  //Set CAAM job ring
101  caamHandle.jobRing = kCAAM_JobRing0;
102 
103  //Acquire exclusive access to the CAAM module
105 
106  //Copy first operand
107  mpiWriteRaw(&ta, pkhaArgs.a, aLen);
108  //Copy second operand
109  mpiWriteRaw(&tb, pkhaArgs.b, bLen);
110  //Copy modulus
111  mpiWriteRaw(p, pkhaArgs.p, modLen);
112 
113  //Perform modular multiplication
114  status = CAAM_PKHA_ModMul(CAAM, &caamHandle, pkhaArgs.a, aLen,
115  pkhaArgs.b, bLen, pkhaArgs.p, modLen, pkhaArgs.r, &resultLen,
116  kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue,
117  kCAAM_PKHA_NormalValue, kCAAM_PKHA_TimingEqualized);
118 
119  //Check status code
120  if(status == kStatus_Success)
121  {
122  //Copy resulting integer
123  error = mpiReadRaw(r, pkhaArgs.r, resultLen);
124  }
125  else
126  {
127  //Report an error
128  error = ERROR_FAILURE;
129  }
130 
131  //Release exclusive access to the CAAM module
133  }
134  }
135  else
136  {
137  //Report an error
138  error = ERROR_FAILURE;
139  }
140 
141  //Release multiple precision integers
142  mpiFree(&ta);
143  mpiFree(&tb);
144 
145  //Return status code
146  return error;
147 }
148 
149 
150 /**
151  * @brief Modular exponentiation
152  * @param[out] r Resulting integer R = A ^ E mod P
153  * @param[in] a Pointer to a multiple precision integer
154  * @param[in] e Exponent
155  * @param[in] p Modulus
156  * @return Error code
157  **/
158 
159 error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
160 {
161  error_t error;
162  status_t status;
163  size_t scalarLen;
164  size_t expLen;
165  size_t modLen;
166  size_t resultLen;
167  caam_handle_t caamHandle;
168 
169  //Retrieve the length of the exponent, in bytes
170  expLen = mpiGetByteLength(e);
171  //Retrieve the length of the modulus, in bytes
172  modLen = mpiGetByteLength(p);
173 
174  //The accelerator supports operand lengths up to 4096 bits
175  if(modLen > 0 && modLen <= 512 && expLen > 0 && expLen <= 512)
176  {
177  //Reduce the integer first
178  error = mpiMod(r, a, p);
179 
180  //Check status code
181  if(!error)
182  {
183  //Retrieve the length of the integer, in bytes
184  scalarLen = mpiGetByteLength(r);
185 
186  //Set CAAM job ring
187  caamHandle.jobRing = kCAAM_JobRing0;
188 
189  //Acquire exclusive access to the CAAM module
191 
192  //Copy scalar
193  mpiWriteRaw(r, pkhaArgs.a, scalarLen);
194  //Copy exponent
195  mpiWriteRaw(e, pkhaArgs.e, expLen);
196  //Copy modulus
197  mpiWriteRaw(p, pkhaArgs.p, modLen);
198 
199  //Perform modular exponentiation
200  status = CAAM_PKHA_ModExp(CAAM, &caamHandle, pkhaArgs.a, scalarLen,
201  pkhaArgs.p, modLen, pkhaArgs.e, expLen, pkhaArgs.r, &resultLen,
202  kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue,
203  kCAAM_PKHA_TimingEqualized);
204 
205  //Check status code
206  if(status == kStatus_Success)
207  {
208  //Copy resulting integer
209  error = mpiReadRaw(r, pkhaArgs.r, resultLen);
210  }
211  else
212  {
213  //Report an error
214  error = ERROR_FAILURE;
215  }
216 
217  //Release exclusive access to the CAAM module
219  }
220  }
221  else
222  {
223  //Report an error
224  error = ERROR_FAILURE;
225  }
226 
227  //Return status code
228  return error;
229 }
230 
231 
232 /**
233  * @brief Scalar multiplication
234  * @param[in] params EC domain parameters
235  * @param[out] r Resulting point R = d.S
236  * @param[in] d An integer d such as 0 <= d < p
237  * @param[in] s EC point
238  * @return Error code
239  **/
240 
241 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
242  const EcPoint *s)
243 {
244  error_t error;
245  status_t status;
246  size_t modLen;
247  size_t scalarLen;
248  caam_handle_t caamHandle;
249  caam_pkha_ecc_point_t input;
250  caam_pkha_ecc_point_t output;
251 
252  //Retrieve the length of the modulus, in bytes
253  modLen = mpiGetByteLength(&params->p);
254  //Retrieve the length of the scalar, in bytes
255  scalarLen = mpiGetByteLength(d);
256 
257  //Check the length of the operands
258  if(modLen <= 66 && scalarLen <= 66)
259  {
260  //Set CAAM job ring
261  caamHandle.jobRing = kCAAM_JobRing0;
262 
263  //Acquire exclusive access to the CAAM module
265 
266  //Copy domain parameters
267  mpiWriteRaw(&params->p, pkhaEccArgs.p, modLen);
268  mpiWriteRaw(&params->a, pkhaEccArgs.a, modLen);
269  mpiWriteRaw(&params->b, pkhaEccArgs.b, modLen);
270 
271  //Copy scalar
272  mpiWriteRaw(d, pkhaEccArgs.d, scalarLen);
273 
274  //Copy input point
275  mpiWriteRaw(&s->x, pkhaEccArgs.gx, modLen);
276  mpiWriteRaw(&s->y, pkhaEccArgs.gy, modLen);
277  input.X = pkhaEccArgs.gx;
278  input.Y = pkhaEccArgs.gy;
279 
280  //Specify the buffer where to store the output point
281  output.X = pkhaEccArgs.qx;
282  output.Y = pkhaEccArgs.qy;
283 
284  //Perform scalar multiplication
285  status = CAAM_PKHA_ECC_PointMul(CAAM, &caamHandle, &input, pkhaEccArgs.d,
286  scalarLen, pkhaEccArgs.p, NULL, pkhaEccArgs.a, pkhaEccArgs.b,
287  modLen, kCAAM_PKHA_TimingEqualized, kCAAM_PKHA_IntegerArith, &output);
288 
289  //Check status code
290  if(status == kStatus_Success)
291  {
292  //Copy the x-coordinate of the result
293  error = mpiReadRaw(&r->x, pkhaEccArgs.qx, modLen);
294 
295  //Check status code
296  if(!error)
297  {
298  //Copy the y-coordinate of the result
299  error = mpiReadRaw(&r->y, pkhaEccArgs.qy, modLen);
300  }
301 
302  //Check status code
303  if(!error)
304  {
305  //Set the z-coordinate of the result
306  error = mpiSetValue(&r->z, 1);
307  }
308  }
309  else
310  {
311  //Report an error
312  error = ERROR_FAILURE;
313  }
314 
315  //Release exclusive access to the CAAM module
317  }
318  else
319  {
320  //Report an error
321  error = ERROR_FAILURE;
322  }
323 
324  //Return status code
325  return error;
326 }
327 
328 #endif
uint8_t b
Definition: nbns_common.h:104
Mpi p
Prime.
Definition: ec.h:79
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:80
PKHA ECC primitive arguments.
uint8_t p
Definition: ndp.h:300
uint8_t r[512]
i.MX RT1160 hardware cryptographic accelerator (CAAM)
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
uint8_t a[512]
EC domain parameters.
Definition: ec.h:76
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
Mpi a
Curve parameter a.
Definition: ec.h:80
uint8_t r
Definition: ndp.h:346
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
uint8_t p[512]
error_t
Error codes.
Definition: error.h:43
uint8_t e[512]
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
General definitions for cryptographic algorithms.
EC point.
Definition: ec.h:64
PKHA primitive arguments.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
uint8_t b[512]
uint8_t s
Definition: igmp_common.h:234
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
OsMutex mimxrt1160CryptoMutex
PkhaEccArgs pkhaEccArgs
Mpi b
Curve parameter b.
Definition: ec.h:81
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
i.MX RT1160 public-key hardware accelerator
ECC (Elliptic Curve Cryptography)
Debugging facilities.
PkhaArgs pkhaArgs
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64