1 /*
2 * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #ifdef CC_IOT
7 #include "mbedtls/build_info.h"
8 #endif
9
10 #if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
11
12 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_RSA_DH
13
14 /************* Include Files ****************/
15
16 #include "cc_pal_mem.h"
17 #include "cc_common.h"
18 #include "cc_common_math.h"
19 #include "cc_rsa_error.h"
20 #include "cc_rsa_local.h"
21 #include "rsa.h"
22 #include "rsa_public.h"
23 #include "rsa_private.h"
24 #include "cc_fips_defs.h"
25
26 /************************ Defines ******************************/
27
28 /************************ Enums ******************************/
29
30 /************************ Typedefs ******************************/
31
32 /************************ Global Data ******************************/
33
34 /************************ Public Functions ******************************/
35
36
37 /**********************************************************************************/
38 /**
39 @brief
40 CC_RsaPrimEncrypt implements the RSAEP algorithm as defined in PKCS#1 v2.1 6.1.1
41
42 @param[in] UserPubKey_ptr - Pointer to the public key data structure.
43 @param[in] PrimeData_ptr - A pointer to a structure containing temp buffers.
44 @param[in] Data_ptr - Pointer to the input data to be encrypted.
45 @param[in] DataSize - The size, in bytes, of the input data.
46 \Note: DataSize <= modulus size is supported, but recommended
47 that size is equal to modulus size. If smaller, the data will be
48 zero-padded on left side up to the modulus size and therefore,
49 after further decrypt operation its result will contain
50 padding zeros also.
51 @param[out] Output_ptr - Pointer to the encrypted data. The size of output data
52 is always equal to size modulus size. The output buffer
53 must be at least of modulus size in bytes.
54
55 @return CCError_t - CC_OK,
56 CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
57 CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR,
58 CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID,
59 CC_RSA_DATA_POINTER_INVALID_ERROR,
60 CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
61 CC_RSA_INVALID_MESSAGE_BUFFER_SIZE,
62 CC_RSA_INVALID_MESSAGE_DATA_SIZE,
63 CC_RSA_INVALID_MESSAGE_VAL
64 */
CC_RsaPrimEncrypt(CCRsaUserPubKey_t * UserPubKey_ptr,CCRsaPrimeData_t * PrimeData_ptr,uint8_t * Data_ptr,size_t DataSize,uint8_t * Output_ptr)65 CEXPORT_C CCError_t CC_RsaPrimEncrypt(CCRsaUserPubKey_t *UserPubKey_ptr,
66 CCRsaPrimeData_t *PrimeData_ptr,
67 uint8_t *Data_ptr,
68 size_t DataSize,
69 uint8_t *Output_ptr)
70 {
71 /* FUNCTION LOCAL DECLERATIONS */
72
73 /* the counter compare result */
74 CCCommonCmpCounter_t CounterCmpResult;
75
76 /* the public key database pointer */
77 CCRsaPubKey_t *PubKey_ptr;
78
79 /* the modulus size in bytes */
80 uint32_t nSizeInBytes;
81
82 /* The return error identifier */
83 CCError_t Error = CC_OK;
84
85 /* FUNCTION LOGIC */
86
87
88 /* ............... checking the parameters pointers validity .......... */
89 /* -------------------------------------------------------------------- */
90
91 CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
92 /* checking the key database handle pointer */
93 if (UserPubKey_ptr == NULL)
94 return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
95
96 /* if the users TAG is illegal return an error - the context is invalid */
97 if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG)
98 return CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
99
100 /* checking the Prime Data pointer */
101 if (PrimeData_ptr == NULL)
102 return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
103
104 /* if the users Data pointer is illegal return an error */
105 if (Data_ptr == NULL)
106 return CC_RSA_DATA_POINTER_INVALID_ERROR;
107
108 /* if the users output pointer is illegal return an error */
109 if (Output_ptr == NULL)
110 return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
111
112 /* if the data size is larger then the internal buffer return error */
113 if (DataSize > sizeof(PrimeData_ptr->DataIn))
114 return CC_RSA_INVALID_MESSAGE_BUFFER_SIZE;
115
116 /* setting the pointer to the key database */
117 PubKey_ptr = (CCRsaPubKey_t*)UserPubKey_ptr->PublicKeyDbBuff;
118
119 /* setting the modulus size in bytes */
120 nSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->nSizeInBits);
121
122
123 /* ................ copying the input data to the buffer .............. */
124 /* -------------------------------------------------------------------- */
125
126 /* clear the input data */
127 CC_PalMemSet(PrimeData_ptr->DataIn, 0, sizeof(PrimeData_ptr->DataIn));
128
129 /* copy the input data to the aligned buffer on the data handler */
130 Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrimeData_ptr->DataIn, 4*((nSizeInBytes+3)/4),
131 Data_ptr, DataSize);
132 if (Error != CC_OK) {
133 Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE;
134 goto End;
135 }
136
137 /* ...... checking the the message value it must be less then the modulus ...... */
138 CounterCmpResult = CC_CommonCmpLsWordsUnsignedCounters(
139 PrimeData_ptr->DataIn, (uint16_t)(nSizeInBytes+3)/4,
140 PubKey_ptr->n, (uint16_t)(nSizeInBytes+3)/4);
141
142 if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
143 Error = CC_RSA_INVALID_MESSAGE_VAL;
144 goto End;
145 }
146
147 /* executing the encryption */
148 Error = RsaExecPubKeyExp(PubKey_ptr, PrimeData_ptr);
149
150 if (Error != CC_OK) {
151 Error = CC_RSA_INTERNAL_ERROR;
152 goto End;
153 }
154
155 /* copy the output data from the aligned buffer to the users data on big endian format */
156 Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Output_ptr, 4*((nSizeInBytes+3)/4),
157 PrimeData_ptr->DataOut, nSizeInBytes );
158 if (Error != CC_OK) {
159 Error = CC_RSA_INVALID_MESSAGE_VAL;
160 goto End;
161 }
162
163 End:
164 if (Error != CC_OK) {
165 CC_PalMemSetZero(Output_ptr, nSizeInBytes);
166 }
167 /* clear the data buffer */
168 CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t) );
169
170 return Error;
171
172
173 }/* END OF CC_RsaPrimEncrypt */
174
175
176 /**********************************************************************************/
177 /**
178 @brief
179 CC_RsaPrimDecrypt implements the RSADP algorithm as defined in PKCS#1 v2.1 6.1.2
180
181 @param[in] PrivKey_ptr - Pointer to the private key data
182 structure. \note The RSA key parameters and hence the algorithm (CRT
183 or not) are determined by this structure. Using CC_BuildPrivKey or
184 CC_BuildPrivKeyCRT determines which algorithm will be used.
185
186 @param[in] PrimeData_ptr - A pointer to a structure containing internal
187 buffers required for the RSA operation.
188 @param[in] Data_ptr - Pointer to the data to be decrypted.
189 @param[in] DataSize - The size, in bytes, of the input data. To decrypt
190 previously encrypted data its size must be equal to
191 modulus size.
192 \Note: DataSize <= modulus size is supported, but
193 it is recommended that the size is equal to modulus size.
194 If smaller, the data will be zero-padded on left side
195 up to the modulus size and therefore, after further decrypt
196 operation its result will contain padding zeros also.
197 @param[out] Output_ptr - Pointer to the decrypted data. The size of output data
198 is always equal to size modulus size. The output buffer
199 must be at least of modulus size in bytes.
200
201 @return CCError_t - CC_OK,
202 CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
203 CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID,
204 CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR,
205 CC_RSA_DATA_POINTER_INVALID_ERROR,
206 CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
207 CC_RSA_INVALID_MESSAGE_DATA_SIZE,
208 CC_RSA_INVALID_MESSAGE_VAL
209 */
210
CC_RsaPrimDecrypt(CCRsaUserPrivKey_t * UserPrivKey_ptr,CCRsaPrimeData_t * PrimeData_ptr,uint8_t * Data_ptr,size_t DataSize,uint8_t * Output_ptr)211 CEXPORT_C CCError_t CC_RsaPrimDecrypt(
212 CCRsaUserPrivKey_t *UserPrivKey_ptr,
213 CCRsaPrimeData_t *PrimeData_ptr,
214 uint8_t *Data_ptr,
215 size_t DataSize,
216 uint8_t *Output_ptr)
217 {
218 /* FUNCTION LOCAL DECLERATIONS */
219
220 /* the counter compare result */
221 CCCommonCmpCounter_t CounterCmpResult;
222
223 /* the private key database pointer */
224 CCRsaPrivKey_t *PrivKey_ptr;
225
226 /* the modulus size in bytes */
227 uint32_t nSizeInBytes;
228
229 /* The return error identifier */
230 CCError_t Error = CC_OK;
231
232 /* FUNCTION LOGIC */
233
234
235 /* ............... checking the parameters pointers validity .......... */
236 /* -------------------------------------------------------------------- */
237 CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
238
239 /* ...... checking the key database handle pointer .................... */
240 if (UserPrivKey_ptr == NULL)
241 return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
242
243 /* ...... checking the Prime Data pointer .................... */
244 if (PrimeData_ptr == NULL)
245 return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
246
247 /* if the users TAG is illegal return an error - the context is invalid */
248 if (UserPrivKey_ptr->valid_tag != CC_RSA_PRIV_KEY_VALIDATION_TAG)
249 return CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR;
250
251 /* if the users Data pointer is NULL return an error */
252 if (Data_ptr == NULL)
253 return CC_RSA_DATA_POINTER_INVALID_ERROR;
254
255 /* if the users Output pointer is NULL return an error */
256 if (Output_ptr == NULL)
257 return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
258
259
260 /* setting the pointer to the key database */
261 PrivKey_ptr = (CCRsaPrivKey_t*)UserPrivKey_ptr->PrivateKeyDbBuff;
262
263 /* setting the modulus size in bytes */
264 nSizeInBytes = CALC_FULL_BYTES(PrivKey_ptr->nSizeInBits);
265
266 /* if the data size is 0 or great than modulus size - return an error */
267 if (DataSize == 0 || DataSize > nSizeInBytes)
268 return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
269
270 /* ................ copying the input data to the buffer .............. */
271 /* -------------------------------------------------------------------- */
272
273 /* clear the input data */
274 CC_PalMemSetZero( PrimeData_ptr->DataIn, sizeof(PrimeData_ptr->DataIn));
275
276 /* copy the input data to the aligned buffer on the data handler in little endian format */
277 Error = CC_CommonConvertMsbLsbBytesToLswMswWords(
278 PrimeData_ptr->DataIn, 4*((nSizeInBytes+3)/4), Data_ptr, DataSize);
279 if (Error != CC_OK) {
280 Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE;
281 goto End;
282 }
283
284 /* .. checking the message value it must be less then the modulus .. */
285 /* ----------------------------------------------------------------- */
286 CounterCmpResult = CC_CommonCmpLsWordsUnsignedCounters(
287 PrimeData_ptr->DataIn, (uint16_t)(nSizeInBytes+3)/4,
288 PrivKey_ptr->n, (uint16_t)(nSizeInBytes+3)/4);
289
290 if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
291 Error = CC_RSA_INVALID_MESSAGE_VAL;
292 goto End;
293 }
294
295 /* ..................... executing the encryption ...................... */
296 /* --------------------------------------------------------------------- */
297
298 Error = RsaExecPrivKeyExp(PrivKey_ptr, PrimeData_ptr);
299
300 if (Error != CC_OK) {
301 Error = CC_RSA_INTERNAL_ERROR;
302 goto End;
303 }
304
305 /* copy the output data from the aligned words-buffer to the users data in MS-LS bytes order */
306 Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Output_ptr, 4*((nSizeInBytes+3)/4),
307 PrimeData_ptr->DataOut, nSizeInBytes);
308 if (Error != CC_OK) {
309 Error = CC_RSA_INVALID_MESSAGE_VAL;
310 goto End;
311 }
312
313 End:
314 if (Error != CC_OK) {
315 CC_PalMemSetZero(Output_ptr, nSizeInBytes);
316 }
317
318 /* clear the temp data buffer */
319 CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
320
321 return Error;
322
323
324 }/* END OF CC_RsaPrimDecrypt */
325
326 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
327
328