1 /***************************************************************************//**
2 * \file cy_cryptolite_rsa.c
3 * \version 2.50
4 *
5 * \brief
6 * This file provides provides constant and parameters
7 * for the API of the RSA in the Cryptolite driver.
8 *
9 ********************************************************************************
10 * Copyright 2020-2021 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 #include "cy_device.h"
26
27 #if defined (CY_IP_MXCRYPTOLITE)
28
29 #include "cy_cryptolite_vu.h"
30 #include "cy_cryptolite_rsa.h"
31 #include "cy_cryptolite_utils.h"
32
33 #if defined(__cplusplus)
34 extern "C" {
35 #endif
36
37 #if (CRYPTOLITE_VU_PRESENT == 1)
38 #if defined(CY_CRYPTOLITE_CFG_RSA_C)
39
40 #define CY_CRYPTOLITE_SHA1_PADDING_SIZE (15u)
41 #define CY_CRYPTOLITE_SHA256_512_PADDING_SIZE (19u)
42 /* Defines for the SHA algorithm */
43 /** Hash size for the SHA1 mode (in bytes) */
44 #define CY_CRYPTOLITE_SHA1_DIGEST_SIZE (20u)
45 /** Hash size for the SHA224 mode (in bytes) */
46 #define CY_CRYPTOLITE_SHA224_DIGEST_SIZE (28u)
47 /** Hash size for the SHA256 mode (in bytes) */
48 #define CY_CRYPTOLITE_SHA256_DIGEST_SIZE (32u)
49 /** Hash size for the SHA384 mode (in bytes) */
50 #define CY_CRYPTOLITE_SHA384_DIGEST_SIZE (48u)
51 /** Hash size for the SHA512 mode (in bytes) */
52 #define CY_CRYPTOLITE_SHA512_DIGEST_SIZE (64u)
53 /** Hash size for the SHA512_224 mode (in bytes) */
54 #define CY_CRYPTOLITE_SHA512_224_DIGEST_SIZE (28u)
55 /** Hash size for the SHA512_256 mode (in bytes) */
56 #define CY_CRYPTOLITE_SHA512_256_DIGEST_SIZE (32u)
57 /** The maximal Hash size for the SHA modes (in bytes). */
58 #define CY_CRYPTOLITE_SHA_MAX_DIGEST_SIZE (CY_CRYPTOLITE_SHA512_DIGEST_SIZE)
59
Cy_Cryptolite_Rsa_Mont_Inv_Transform(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_a,uint8_t * p_barrett_u,uint8_t * p_mont_r_inv,uint8_t * p_mod,uint8_t * p_t1_2n1,uint8_t * p_t2_2n1,uint32_t bit_size)60 static void Cy_Cryptolite_Rsa_Mont_Inv_Transform (
61 CRYPTOLITE_Type *base,
62 cy_stc_cryptolite_context_rsa_t *cfContext,
63 uint8_t* p_a, // bit_size
64 uint8_t* p_barrett_u, // bit_size+1
65 uint8_t* p_mont_r_inv, // bit_size+1
66 uint8_t* p_mod, // bit_size
67 uint8_t* p_t1_2n1, // 2*bit_size+1
68 uint8_t* p_t2_2n1, // 2*bit_size+1
69 uint32_t bit_size )
70 {
71 uint32_t bitsize_p1 = VU_BITS_TO_WORDS(bit_size+1U);
72 uint32_t bitsize = VU_BITS_TO_WORDS(bit_size);
73 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0U];
74 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1U];
75
76 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_mont_r_inv, bitsize);
77 (void)Cy_Cryptolite_Vu_lsr_hw (base, vu_struct1, p_a, bitsize, p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size), bit_size);
78 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_barrett_u, bitsize_p1);
79 (void)Cy_Cryptolite_Vu_lsr_hw (base, vu_struct1, p_a, bitsize, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), bit_size);
80 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_mod, bitsize);
81 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct1, p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_t2_2n1, VU_BITS_TO_WORDS(bit_size+2U));
82 // Reduction.
83 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct0, p_t2_2n1, bitsize_p1, p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_mod, bitsize);
84 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct1, p_a, bitsize, p_t2_2n1, bitsize_p1, p_mod, bitsize);
85
86 return;
87 }
88
Cy_Cryptolite_Rsa_Mont_Transform(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_a,uint8_t * p_barrett_u,uint8_t * p_mod,uint8_t * p_t1_2n1,uint8_t * p_t2_2n1,uint32_t bit_size)89 static void Cy_Cryptolite_Rsa_Mont_Transform (
90 CRYPTOLITE_Type *base,
91 cy_stc_cryptolite_context_rsa_t *cfContext,
92 uint8_t* p_a, // bit_size
93 uint8_t* p_barrett_u, // bit_size+1
94 uint8_t* p_mod, // bit_size
95 uint8_t* p_t1_2n1, // 2*bit_size+1
96 uint8_t* p_t2_2n1, // 2*bit_size+1
97 uint32_t bit_size )
98 {
99 uint32_t bitsize_p1 = VU_BITS_TO_WORDS(bit_size+1U);
100 uint32_t bitsize = VU_BITS_TO_WORDS(bit_size);
101 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0U];
102 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1U];
103
104 (void)Cy_Cryptolite_Vu_lsl ( p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, bit_size);
105
106 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_barrett_u, bitsize_p1);
107 (void)Cy_Cryptolite_Vu_lsr_hw (base, vu_struct1, p_a, bitsize, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), bit_size);
108 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_mod, bitsize);
109 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct1, p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_t2_2n1, VU_BITS_TO_WORDS(bit_size+2U));
110 // Reduction.
111 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct0, p_t2_2n1, bitsize_p1, p_t1_2n1, VU_BITS_TO_WORDS(bit_size+2U), p_mod, bitsize);
112 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct1, p_a, bitsize, p_t2_2n1, bitsize_p1, p_mod, bitsize);
113
114 return;
115 }
116
Cy_Cryptolite_Rsa_Mont_Mul(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_z,uint8_t * p_a,uint8_t * p_b,uint8_t * p_mont_mod_der,uint8_t * p_mod,uint8_t * p_t1_2n1,uint8_t * p_t2_2n1,uint32_t bit_size)117 static void Cy_Cryptolite_Rsa_Mont_Mul (
118 CRYPTOLITE_Type *base,
119 cy_stc_cryptolite_context_rsa_t *cfContext,
120 uint8_t* p_z, // bit_size
121 uint8_t* p_a, // bit_size
122 uint8_t* p_b, // bit_size
123 uint8_t* p_mont_mod_der, // bit_size
124 uint8_t* p_mod, // bit_size
125 uint8_t* p_t1_2n1, // 2*bit_size + 1
126 uint8_t* p_t2_2n1, // 2*bit_size + 1
127 uint32_t bit_size )
128 {
129 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0U];
130 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1U];
131
132 uint32_t bitsize_p1 = VU_BITS_TO_WORDS(bit_size+1U);
133 uint32_t bitsize = VU_BITS_TO_WORDS(bit_size);
134
135 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_a, bitsize, p_b, bitsize);
136 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct1, p_z, bitsize, p_t1_2n1, bitsize, p_mont_mod_der, bitsize);
137 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_z, bitsize, p_mod, bitsize);
138
139 (void)Cy_Cryptolite_Vu_add_hw (base, vu_struct1, p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size+1U), p_t2_2n1, VU_BITS_TO_WORDS(2U*bit_size), p_t1_2n1, VU_BITS_TO_WORDS(2U*bit_size));
140 // Reduction.
141 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct0, p_z, bitsize, &(p_t1_2n1[VU_BITS_TO_BYTES(bit_size)]), bitsize_p1, p_mod, bitsize);
142
143 return;
144 }
145
146 static uint32_t Cy_Cryptolite_Vu_Get_Msb_Bit(cy_stc_cryptolite_context_rsa_t *cfContext, uint8_t* p_z, uint32_t exp_bit_size);
147 /*******************************************************************************
148 * Function Name: Cy_Cryptolite_Vu_Get_Msb_Bit
149 ****************************************************************************//**
150 *
151 * Function to calculate the position of the most significant bit set.
152 *
153 * \param cfContext
154 * The pointer to the rsa context.
155 *
156 * \param p_z
157 * The pointer to the data.
158 *
159 * \param exp_bit_size
160 * The size of the data .
161 *
162 * \return
163 * The position of the most significant bit set.
164 *
165 *******************************************************************************/
Cy_Cryptolite_Vu_Get_Msb_Bit(cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_z,uint32_t exp_bit_size)166 static uint32_t Cy_Cryptolite_Vu_Get_Msb_Bit(cy_stc_cryptolite_context_rsa_t *cfContext, uint8_t* p_z, uint32_t exp_bit_size)
167 {
168
169 uint32_t i=0u;
170 uint32_t total_bit_processed = 0u;
171 uint32_t exp_byte_align_size = 0u;
172 uint32_t exp_word_align_size = 0u;
173 uint32_t bit_offset = 0u;
174
175 exp_byte_align_size = CY_CRYPTOLITE_BYTE_SIZE_OF_BITS(exp_bit_size);
176 exp_word_align_size = VU_BITS_TO_WORDS(exp_bit_size);
177 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3','Intentional pointer type conversion');
178 uint32_t * exp_ptr = (uint32_t *)cfContext->p_buffer;
179
180 Cy_Cryptolite_Vu_clr ((uint8_t*) exp_ptr, VU_BYTES_TO_WORDS(CY_CRYPTOLITE_RSA_BUFFER_SIZE));
181 Cy_Cryptolite_Setnumber((uint8_t *)exp_ptr, p_z, exp_byte_align_size);
182 exp_ptr += exp_word_align_size;
183
184 for(i=0u; i<exp_word_align_size; i++)
185 {
186 exp_ptr--;
187
188 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.3','signed 32-bit int" to different or narrower essential type "unsigned 32-bit int');
189 if((bit_offset = __CLZ(*exp_ptr)) != 32u)
190 {
191 total_bit_processed += bit_offset;
192
193 return (exp_word_align_size * 32u) - total_bit_processed;
194 }
195
196 total_bit_processed += 32u;
197 }
198
199 return 0u;
200 }
201
Cy_Cryptolite_Rsa_Exp(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_z,const uint8_t * p_a,uint8_t * p_exp,uint8_t * p_barrett_u,uint8_t * p_mont_r_inv,uint8_t * p_mont_mod_der,uint8_t * p_mod,uint8_t * p_buffer,uint32_t bit_size,uint32_t exp_bit_size)202 static void Cy_Cryptolite_Rsa_Exp (
203 CRYPTOLITE_Type *base,
204 cy_stc_cryptolite_context_rsa_t *cfContext,
205 uint8_t* p_z, // bit_size
206 const uint8_t* p_a, // bit_size
207 uint8_t* p_exp, // exp_bit_size
208 uint8_t* p_barrett_u, // bit_size + 1
209 uint8_t* p_mont_r_inv, // bit_size + 1 to allow for the addition
210 uint8_t* p_mont_mod_der, // bit_size
211 uint8_t* p_mod, // bit_size
212 uint8_t* p_buffer, // (2*bit_size + 1) + (2*bit_size + 1) + bit_size
213 uint32_t bit_size, // support 1024, 2048, 3072, 4096
214 uint32_t exp_bit_size ) // most significant bit assumed to be '1'
215 {
216 int i;
217 uint8_t* p;
218 uint8_t* p_local_z = p_z;
219 uint8_t* p_t1_2n1 = &p_buffer[0U];
220 uint8_t* p_t2_2n1 = &p_buffer[4U*VU_BITS_TO_WORDS(2U*bit_size+1U)];
221 uint8_t* p_t3_n = &p_buffer[4U*VU_BITS_TO_WORDS(2U*bit_size+1U) + 4U*VU_BITS_TO_WORDS(2U*bit_size+1U)];
222 uint8_t* p_msg = &p_buffer[4U*VU_BITS_TO_WORDS(2U*bit_size+1U) + 4U*VU_BITS_TO_WORDS(2U*bit_size+1U) + 4U*VU_BITS_TO_WORDS(bit_size)];
223
224 uint32_t bitsize = VU_BITS_TO_WORDS(bit_size);
225 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0U];
226 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1U];
227
228 exp_bit_size = Cy_Cryptolite_Vu_Get_Msb_Bit(cfContext, p_exp, exp_bit_size);
229
230 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, p_msg, bitsize, (uint8_t*)p_a, bitsize);
231
232 Cy_Cryptolite_Rsa_Mont_Transform (base, cfContext, p_msg, p_barrett_u, p_mod, p_t1_2n1, p_t2_2n1, bit_size);
233
234 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, p_z, bitsize, p_msg, bitsize);
235
236
237 if (exp_bit_size != 1U) {
238 for (i = ((int)exp_bit_size-2); i >= 0; i--) {
239 Cy_Cryptolite_Rsa_Mont_Mul (base, cfContext, p_t3_n, p_z, p_z, p_mont_mod_der, p_mod, p_t1_2n1, p_t2_2n1, bit_size);
240
241 if ((bool)Cy_Cryptolite_Vu_get_bit (p_exp, (uint32_t)i)){
242 Cy_Cryptolite_Rsa_Mont_Mul (base, cfContext, p_z, p_t3_n, p_msg, p_mont_mod_der, p_mod, p_t1_2n1, p_t2_2n1, bit_size);
243 }else {
244 p = p_t3_n; p_t3_n = p_z; p_z = p; // swap
245 }
246 }
247
248 if (p_local_z != p_z) {
249 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct1, p_local_z, bitsize, p_z, bitsize);
250 }
251 }
252
253 Cy_Cryptolite_Rsa_Mont_Inv_Transform (base, cfContext, p_local_z, p_barrett_u, p_mont_r_inv, p_mod, p_t1_2n1, p_t2_2n1, bit_size);
254 }
255
Cy_Cryptolite_Rsa_Coeff(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,uint8_t * p_barrett_u,uint8_t * p_mont_r_inv,uint8_t * p_mont_mod_der,uint8_t * p_mod,uint8_t * p_buffer,uint32_t bit_size)256 static void Cy_Cryptolite_Rsa_Coeff (
257 CRYPTOLITE_Type *base,
258 cy_stc_cryptolite_context_rsa_t *cfContext,
259 uint8_t* p_barrett_u, // bit_size + 1
260 uint8_t* p_mont_r_inv, // bit_size + 1 to allow for the addition
261 uint8_t* p_mont_mod_der, // bit_size
262 uint8_t* p_mod, // bit_size
263 uint8_t* p_buffer, // (bit_size + 1) + (bit_size + 1)
264 uint32_t bit_size )
265 {
266 int i;
267 uint8_t* p;
268 uint32_t sign;
269 bool even;
270 uint32_t bitsize_p1 = VU_BITS_TO_WORDS(bit_size+1U);
271 uint32_t bitsize = VU_BITS_TO_WORDS(bit_size);
272 uint8_t* p_t1_n1 = &p_buffer[0U];
273 uint8_t* p_t2_n1 = &p_buffer[4U*bitsize_p1];
274 uint8_t* p_dividend = p_t1_n1;
275
276 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0U];
277 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1U];
278
279 Cy_Cryptolite_Vu_clr (p_dividend, bitsize_p1 );
280 Cy_Cryptolite_Vu_set_bit (p_dividend, bit_size);
281 Cy_Cryptolite_Vu_clr (p_barrett_u, bitsize_p1);
282
283 Cy_Cryptolite_Vu_clr (p_mont_r_inv, bitsize_p1);
284 Cy_Cryptolite_Vu_set_bit (p_mont_r_inv, 0U);
285 Cy_Cryptolite_Vu_clr (p_mont_mod_der, bitsize);
286
287 // Barrett "barrett_u[bit_size]",
288
289 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct0, p_dividend, bitsize_p1, p_dividend, bitsize_p1, p_mod, bitsize);
290
291 Cy_Cryptolite_Vu_set_bit (p_barrett_u, bit_size);
292
293 Cy_Cryptolite_Vu_wait_hw (base);
294 Cy_Cryptolite_Vu_clr_bit (p_dividend, bit_size); // drop top bit
295 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct1, p_dividend, bitsize_p1, p_dividend, bitsize_p1);
296
297 for (i = ((int)bit_size-1); i >= 0; i--)
298 {
299 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct0, p_t2_n1, bitsize_p1, p_dividend, bitsize_p1, p_mod, bitsize);
300 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct1, p_mont_mod_der, bitsize, p_mont_mod_der, bitsize);
301
302 even = Cy_Cryptolite_Vu_test_even (p_mont_r_inv);
303
304 if (even)
305 {
306 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct0, p_mont_r_inv, bitsize, p_mont_r_inv, bitsize);
307 }
308 else
309 {
310 (void)Cy_Cryptolite_Vu_add_hw (base, vu_struct0, p_mont_r_inv, bitsize_p1, p_mont_r_inv, bitsize, p_mod, bitsize); // needs extra bit
311 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct1, p_mont_r_inv, bitsize_p1, p_mont_r_inv, bitsize_p1);
312 Cy_Cryptolite_Vu_set_bit (p_mont_mod_der, bit_size-1U);
313 }
314
315 sign = Cy_Cryptolite_Vu_get_bit (p_t2_n1, bit_size); // sign = (dividend < mod)
316
317 if (!(bool)sign) {
318 Cy_Cryptolite_Vu_set_bit (p_barrett_u, (uint32_t)i);
319 p = p_t2_n1; p_t2_n1 = p_dividend; p_dividend = p; // swap
320 }
321
322 Cy_Cryptolite_Vu_clr_bit (p_dividend, bit_size); // drop top bit
323 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct0, p_dividend, bitsize_p1, p_dividend, bitsize_p1);
324 }
325 }
326
327 /*******************************************************************************
328 * Function Name: Cy_Cryptolite_Rsa_Init
329 ****************************************************************************//*
330 *
331 * Initialize the RSA context.
332 *
333 * \param base
334 * The pointer to the CRYPTOLITE instance.
335 *
336 * \param cfContext
337 * The pointer to the CRYPTOLITE context.
338 *
339 * \param rsaBuffers
340 * The pointer to the RSA buffers.
341 *
342 * \return
343 * \ref cy_en_cryptolite_status_t
344 *
345 *******************************************************************************/
Cy_Cryptolite_Rsa_Init(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,cy_stc_cryptolite_rsa_buffer_t * rsaBuffers)346 cy_en_cryptolite_status_t Cy_Cryptolite_Rsa_Init(CRYPTOLITE_Type *base,
347 cy_stc_cryptolite_context_rsa_t *cfContext,
348 cy_stc_cryptolite_rsa_buffer_t *rsaBuffers)
349 {
350 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_SUCCESS;
351 uint32_t address_offset=0u;
352
353 if (base == NULL || cfContext == NULL || rsaBuffers == NULL)
354 {
355 return CY_CRYPTOLITE_BAD_PARAMS;
356 }
357
358 /*Aligning the buffer address by 4 bytes*/
359 if(((uint32_t)rsaBuffers & 0x03U) != 0u)
360 {
361 address_offset = 4u - ((uint32_t)rsaBuffers & 0x03U);
362 }
363
364 cfContext->p_buffer = (uint8_t*)((cy_stc_cryptolite_rsa_buffer_t *)((uint32_t)rsaBuffers + address_offset))->p_buffer;
365 return status;
366 }
367
368 /*******************************************************************************
369 * Function Name: Cy_Cryptolite_Rsa_Free
370 ****************************************************************************//*
371 *
372 * Cleanup the RSA context.
373 *
374 * \param base
375 * The pointer to the CRYPTOLITE instance.
376 *
377 * \param cfContext
378 * The pointer to the CRYPTOLITE context.
379 *
380 * \return
381 * \ref cy_en_cryptolite_status_t
382 *
383 *******************************************************************************/
Cy_Cryptolite_Rsa_Free(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext)384 cy_en_cryptolite_status_t Cy_Cryptolite_Rsa_Free(CRYPTOLITE_Type *base,
385 cy_stc_cryptolite_context_rsa_t *cfContext)
386 {
387 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_SUCCESS;
388 (void)base;
389
390 if (base == NULL || cfContext == NULL)
391 {
392 return CY_CRYPTOLITE_BAD_PARAMS;
393 }
394
395 Cy_Cryptolite_Vu_clr((uint8_t*)cfContext->vu_desptr, (sizeof(cy_stc_cryptolite_descr_t) *2U)/4U);
396
397 if(cfContext->p_buffer != NULL)
398 {
399 Cy_Cryptolite_Vu_clr(cfContext->p_buffer, CY_CRYPTOLITE_RSA_BUFFER_SIZE/4u);
400 cfContext->p_buffer = NULL;
401 }
402
403 return status;
404 }
405
406 /*******************************************************************************
407 * Function Name: Cy_Cryptolite_Core_Rsa_Proc
408 ****************************************************************************//*
409 *
410 * RSA process algorithm based on the Montgomery algorithm
411 * using Barrett reduction
412 *
413 * https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29
414 *
415 * Key, message, processedMessage buffers must be 4 byte aligned and end with 4 byte boundary.
416 *
417 * \param base
418 * The pointer to the CRYPTOLITE instance.
419 *
420 * \param cfContext
421 * The pointer to the CRYPTOLITE context.
422 *
423 * \param key
424 * The pointer to the \ref cy_stc_cryptolite_rsa_pub_key_t structure that stores
425 * public key.
426 *
427 * \param message
428 * The pointer to the message to be processed.
429 *
430 * \param messageSize
431 * The length of the message to be processed.
432 *
433 * \param processedMessage
434 * The pointer to processed message.
435 *
436 * \return
437 * \ref cy_en_cryptolite_status_t
438 *
439 *******************************************************************************/
Cy_Cryptolite_Rsa_Proc(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,cy_stc_cryptolite_rsa_pub_key_t * key,uint8_t const * message,uint32_t messageSize,uint8_t * processedMessage)440 cy_en_cryptolite_status_t Cy_Cryptolite_Rsa_Proc(CRYPTOLITE_Type *base,
441 cy_stc_cryptolite_context_rsa_t *cfContext,
442 cy_stc_cryptolite_rsa_pub_key_t *key,
443 uint8_t const *message,
444 uint32_t messageSize,
445 uint8_t *processedMessage)
446 {
447 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_SUCCESS;
448 (void)messageSize;
449
450 uint8_t *barretCoefPtrRemap;
451 uint8_t *inverseModuloPtrRemap;
452 uint8_t *rBarPtrRemap;
453 uint8_t *moduloPtrRemap;
454 uint8_t *pubExpPtrRemap;
455 uint8_t *messagePtrRemap;
456
457 barretCoefPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->barretCoefPtr);
458 inverseModuloPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->inverseModuloPtr);
459 rBarPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->rBarPtr);
460 moduloPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->moduloPtr);
461 pubExpPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->pubExpPtr);
462 messagePtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(message);
463
464 if(key->preCalculatedCoeff == false)
465 {
466 Cy_Cryptolite_Rsa_Coeff(base, cfContext, barretCoefPtrRemap, inverseModuloPtrRemap, rBarPtrRemap, moduloPtrRemap, cfContext->p_buffer, key->moduloLength);
467 key->preCalculatedCoeff = true;
468 }
469
470 Cy_Cryptolite_Rsa_Exp(base, cfContext, processedMessage, messagePtrRemap, pubExpPtrRemap, barretCoefPtrRemap, inverseModuloPtrRemap, rBarPtrRemap, moduloPtrRemap, cfContext->p_buffer, key->moduloLength, key->pubExpLength);
471
472 return status;
473 }
474
475 /*******************************************************************************
476 * Function Name: Cy_Cryptolite_Rsa_Coef
477 ****************************************************************************//*
478 *
479 * Calculation constant coefficients to speed-up Montgomery algorithm.
480 * These coefficients are:
481 * coefficient for Barrett reduction,
482 * binary inverse of the modulo,
483 * result of (2^moduloLength mod modulo)
484 *
485 * \param base
486 * The pointer to the CRYPTOLITE instance.
487 *
488 * \param cfContext
489 * The pointer to the CRYPTOLITE context.
490 *
491 * \param key
492 * The pointer to the \ref cy_stc_cryptolite_rsa_pub_key_t structure that stores a
493 * public key.
494 *
495 * \return
496 * \ref cy_en_cryptolite_status_t
497 *
498 *******************************************************************************/
Cy_Cryptolite_Rsa_Coef(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,cy_stc_cryptolite_rsa_pub_key_t * key)499 cy_en_cryptolite_status_t Cy_Cryptolite_Rsa_Coef(CRYPTOLITE_Type *base,
500 cy_stc_cryptolite_context_rsa_t *cfContext,
501 cy_stc_cryptolite_rsa_pub_key_t *key)
502 {
503 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_SUCCESS;
504
505 uint8_t *barretCoefPtrRemap;
506 uint8_t *inverseModuloPtrRemap;
507 uint8_t *rBarPtrRemap;
508 uint8_t *moduloPtrRemap;
509
510 if((NULL == key->barretCoefPtr) || (NULL == key->inverseModuloPtr) || (NULL == key->rBarPtr) || (NULL == key->moduloPtr) || (NULL == cfContext))
511 {
512 return CY_CRYPTOLITE_BAD_PARAMS;
513 }
514
515
516 barretCoefPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->barretCoefPtr);
517 inverseModuloPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->inverseModuloPtr);
518 rBarPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->rBarPtr);
519 moduloPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(key->moduloPtr);
520
521 Cy_Cryptolite_Rsa_Coeff(base, cfContext, barretCoefPtrRemap, inverseModuloPtrRemap, rBarPtrRemap, moduloPtrRemap, cfContext->p_buffer, key->moduloLength);
522
523 key->preCalculatedCoeff = true;
524
525 return status;
526 }
527
528 /*******************************************************************************
529 * Function Name: Cy_Cryptolite_Rsa_Verify
530 ****************************************************************************//*
531 *
532 * RSA verification with checks for content, paddings and signature format.
533 * SHA digest of the message and decrypted message should be calculated before.
534 * Supports only PKCS1-v1_5 format, inside of this format supported padding
535 * using only SHA, cases with MD2 and MD5 are not supported.
536 * PKCS1-v1_5 described here, page 31:
537 * http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
538 *
539 * The digest and decryptedSignature buffers must be 4 byte aligned
540 *
541 * Returns the verification result \ref cy_en_cryptolite_sig_verify_result_t.
542 *
543 * \param base
544 * The pointer to the CRYPTOLITE instance.
545 *
546 * \param cfContext
547 * The pointer to the CRYPTOLITE context.
548 *
549 * \param verResult
550 * The pointer to the verification result \ref cy_en_cryptolite_sig_verify_result_t.
551 *
552 * \param digestType
553 * SHA mode used for hash calculation \ref cy_en_cryptolite_sha_mode_t.
554 *
555 * \param digest
556 * The pointer to the hash of the message or the message whose signature is to be verified.
557 *
558 * \param digestLength
559 * The length of the message whose signature is to be verified and is applicable for CY_CRYPTOLITE_MODE_SHA_NONE mode.
560 *
561 * \param decryptedSignature
562 * The pointer to the decrypted signature to be verified.
563 *
564 * \param decryptedSignatureLength
565 * The length of the decrypted signature to be verified (in bytes)
566 *
567 * \return
568 * \ref cy_en_cryptolite_status_t
569 *
570 *******************************************************************************/
571 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_ENABLED
Cy_Cryptolite_Rsa_Verify(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_rsa_t * cfContext,cy_en_cryptolite_sig_verify_result_t * verResult,cy_en_cryptolite_sha_mode_t digestType,uint8_t const * digest,uint32_t digestLength,uint8_t const * decryptedSignature,uint32_t decryptedSignatureLength)572 cy_en_cryptolite_status_t Cy_Cryptolite_Rsa_Verify(CRYPTOLITE_Type *base,
573 cy_stc_cryptolite_context_rsa_t *cfContext,
574 cy_en_cryptolite_sig_verify_result_t *verResult,
575 cy_en_cryptolite_sha_mode_t digestType,
576 uint8_t const *digest,
577 uint32_t digestLength,
578 uint8_t const *decryptedSignature,
579 uint32_t decryptedSignatureLength)
580 {
581 cy_en_cryptolite_status_t tmpResult = CY_CRYPTOLITE_SUCCESS;
582 (void)base;
583 (void)cfContext;
584
585 uint8_t *digestRemap;
586 uint8_t *decryptedSignatureRemap;
587
588 digestRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(digest);
589 decryptedSignatureRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(decryptedSignature);
590
591 /* Encodings for hash functions */
592
593 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA1
594 static const uint8_t sha1EncStr[CY_CRYPTOLITE_SHA1_PADDING_SIZE] =
595 {
596 0x30u, 0x21u, 0x30u, 0x09u, 0x06u, 0x05u, 0x2Bu, 0x0Eu,
597 0x03u, 0x02u, 0x1Au, 0x05u, 0x00u, 0x04u, 0x14u
598 };
599 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA1 == 1) */
600
601 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA256
602 static const uint8_t sha224EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
603 {
604 0x30u, 0x2Du, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
605 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x04u, 0x05u,
606 0x00u, 0x04u, 0x1Cu
607 };
608
609 static const uint8_t sha256EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
610 {
611 0x30u, 0x31u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
612 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x01u, 0x05u,
613 0x00u, 0x04u, 0x20u
614 };
615 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA256 == 1) */
616
617 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA512
618 static const uint8_t sha384EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
619 {
620 0x30u, 0x41u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
621 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x02u, 0x05u,
622 0x00u, 0x04u, 0x30u
623 };
624
625 static const uint8_t sha512EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
626 {
627 0x30u, 0x51u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
628 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x03u, 0x05u,
629 0x00u, 0x04u, 0x40u
630 };
631
632 static const uint8_t sha512_224EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
633 {
634 0x30u, 0x2Du, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
635 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x05u, 0x05u,
636 0x00u, 0x04u, 0x1Cu
637 };
638
639 static const uint8_t sha512_256EncStr[CY_CRYPTOLITE_SHA256_512_PADDING_SIZE] =
640 {
641 0x30u, 0x31u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
642 0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x06u, 0x05u,
643 0x00u, 0x04u, 0x20u
644 };
645 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA512 == 1) */
646
647 uint8_t const *encodingArr = NULL;
648 uint32_t encodingArrSize = 0u;
649 uint32_t locDigestSize = 0u;
650 uint32_t i;
651 uint32_t psLength;
652 uint32_t cmpRes = 0u;
653
654
655 switch (digestType)
656 {
657
658 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA1
659 case CY_CRYPTOLITE_MODE_SHA1:
660 encodingArr = sha1EncStr;
661 encodingArrSize = sizeof(sha1EncStr);
662 locDigestSize = CY_CRYPTOLITE_SHA1_DIGEST_SIZE;
663 break;
664 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA1 == 1) */
665
666 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA256
667 case CY_CRYPTOLITE_MODE_SHA224:
668 encodingArr = sha224EncStr;
669 encodingArrSize = sizeof(sha224EncStr);
670 locDigestSize = CY_CRYPTOLITE_SHA224_DIGEST_SIZE;
671 break;
672
673 case CY_CRYPTOLITE_MODE_SHA256:
674 encodingArr = sha256EncStr;
675 encodingArrSize = sizeof(sha256EncStr);
676 locDigestSize = CY_CRYPTOLITE_SHA256_DIGEST_SIZE;
677 break;
678 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA256 == 1) */
679
680 #ifdef CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA512
681 case CY_CRYPTOLITE_MODE_SHA384:
682 encodingArr = sha384EncStr;
683 encodingArrSize = sizeof(sha384EncStr);
684 locDigestSize = CY_CRYPTOLITE_SHA384_DIGEST_SIZE;
685 break;
686
687 case CY_CRYPTOLITE_MODE_SHA512:
688 encodingArr = sha512EncStr;
689 encodingArrSize = sizeof(sha512EncStr);
690 locDigestSize = CY_CRYPTOLITE_SHA512_DIGEST_SIZE;
691 break;
692
693 case CY_CRYPTOLITE_MODE_SHA512_224:
694 encodingArr = sha512_224EncStr;
695 encodingArrSize = sizeof(sha512_224EncStr);
696 locDigestSize = CY_CRYPTOLITE_SHA512_224_DIGEST_SIZE;
697 break;
698
699 case CY_CRYPTOLITE_MODE_SHA512_256:
700 encodingArr = sha512_256EncStr;
701 encodingArrSize = sizeof(sha512_256EncStr);
702 locDigestSize = CY_CRYPTOLITE_SHA512_256_DIGEST_SIZE;
703 break;
704 #endif /* #if (CY_CRYPTOLITE_CFG_RSA_VERIFY_SHA512 == 1) */
705 case CY_CRYPTOLITE_MODE_SHA_NONE:
706 encodingArr = NULL;
707 encodingArrSize = 0U;
708 locDigestSize = digestLength;
709 break;
710 default:
711 /* Unknown Digest Type */
712 break;
713 }
714
715 /* Fail by default */
716 *verResult = CY_CRYPTOLITE_SIG_INVALID;
717
718 if (CY_CRYPTOLITE_MODE_SHA_NONE != digestType)
719 {
720 /* Check size of decrypted message */
721 if (decryptedSignatureLength < (encodingArrSize + locDigestSize + 11u))
722 {
723 cmpRes = 1u; /* further checking is not needed */
724 }
725 }
726
727 psLength = decryptedSignatureLength - locDigestSize - encodingArrSize - 3u;
728
729 /* Check whether the begin of message is 0x00, 0x01 and after PS string (before T string) is 0x00 byte.*/
730 if ( (0u != cmpRes) ||
731 (0x00u != *(decryptedSignatureRemap)) ||
732 (0x01u != *(decryptedSignatureRemap + 1u)) ||
733 (0x00u != *(decryptedSignatureRemap + psLength + 2u)) )
734 {
735 cmpRes = 1u; /* Further checking is not needed */
736 }
737
738 /* Check FFs */
739 if (0u == cmpRes )
740 {
741 for (i = 0u; i < psLength; i++)
742 {
743 if (0xFFu != *(decryptedSignatureRemap + 2u + i))
744 {
745 cmpRes = 1u; /* Further checking is not needed */
746 break;
747 }
748 }
749 }
750
751 if (CY_CRYPTOLITE_MODE_SHA_NONE != digestType)
752 {
753 /* Check the padding (T string) */
754 if (0u == cmpRes)
755 {
756 cmpRes = Cy_Cryptolite_Vu_memcmp(encodingArr,
757 (decryptedSignatureRemap + psLength + 3u),
758 (uint16_t)encodingArrSize);
759 }
760 }
761
762 /* Check the digest */
763 if (0u == cmpRes)
764 {
765 cmpRes = Cy_Cryptolite_Vu_memcmp(digestRemap,
766 (decryptedSignatureRemap + (decryptedSignatureLength - locDigestSize)),
767 (uint16_t)locDigestSize);
768 }
769
770 if (0u == cmpRes )
771 {
772 *verResult = CY_CRYPTOLITE_SIG_VALID;
773 }
774
775 return (tmpResult);
776 }
777 #endif /* CY_CRYPTOLITE_CFG_RSA_VERIFY_ENABLED */
778
779 #endif /*#if defined(CY_CRYPTOLITE_CFG_RSA_C)*/
780 #endif /*#if (CPUSS_CRYPTOLITE_VU == 1)*/
781
782 #if defined(__cplusplus)
783 }
784 #endif
785
786 #endif /* CY_IP_MXCRYPTOLITE */
787