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