1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _CC_RSA_LOCAL_H
8 #define _CC_RSA_LOCAL_H
9 
10 #include "cc_error.h"
11 #include "cc_rsa_types.h"
12 #include "cc_rnd_common.h"
13 
14 
15 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 
21 /************************ Defines ******************************/
22 
23 /* the RSA public key user validity TAG */
24 #define CC_RSA_PUB_KEY_VALIDATION_TAG 0x13579BDF
25 
26 /* the RSA private key user validity TAG */
27 #define CC_RSA_PRIV_KEY_VALIDATION_TAG 0x2468ACE0
28 
29 /* the RSA sign Context user validity TAG */
30 #define CC_RSA_SIGN_CONTEXT_VALIDATION_TAG   0x98765432
31 #define CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG 0x45678901
32 
33 
34 typedef struct {
35     uint16_t hashResultSize;
36     CCHashOperationMode_t hashMode;
37 }RsaHash_t;
38 
39 extern const RsaHash_t RsaHashInfo_t[CC_RSA_HASH_NumOfModes];
40 extern const uint8_t RsaSupportedHashModes_t[CC_RSA_HASH_NumOfModes];
41 #ifdef USE_MBEDTLS_CRYPTOCELL
42 extern const mbedtls_md_type_t RsaHash_CC_mbedtls_Info[CC_HASH_NumOfModes];
43 #endif
44 
45 /***************
46 
47   ASN1 types - for BER Parser - used for PKCS#1 Ver 1.5
48 
49 ***************/
50 
51 #define ASN1_BOOLEAN        1
52 #define ASN1_INTEGER        2
53 #define ASN1_BIT_STRING     3
54 #define ASN1_OCTET_STRING   4
55 #define ASN1_NULL       5
56 #define ASN1_OBJECT_IDENTIFIER  6
57 #define ASN1_SEQUENCE       16 /* 0x10 */
58 #define ASN1_SET        17 /* 0x11 */
59 #define ASN1_PRINTABLE_STRING   19 /* 0x13 */
60 #define ASN1_TELETEX_STRING 20 /* 0x14 */
61 #define ASN1_IA5STRING      22 /* 0x16 */
62 #define ASN1_UTC_TIME           23 /* 0x17 */
63 
64 /**********************
65  structures definition
66  **********************/
67 #define TEST_MSB_BIT 0x80
68 
69 /* Hash algorithm ID (DER code) structure type */
70 #define HASH_DER_CODE_MAX_SIZE_BYTES 24
71 typedef struct HashDerCode_t {
72     uint32_t algIdSizeBytes;
73     CCHashOperationMode_t hashMode;
74     uint8_t algId[HASH_DER_CODE_MAX_SIZE_BYTES];
75 }HashDerCode_t;
76 
77 /* For security goal the padding string PS in EME-PKCS1-v1_5 encodding method
78    must be at least eight octets long */
79 #define PS_MIN_LEN 8
80 
81 
82 /************************ macros ********************************/
83 
84 /************************ Typedefs  ****************************/
85 
86 
87 /************************ Structs  ******************************/
88 typedef struct CCRsaOaepData_t{
89     uint8_t  MaskDB[CC_RSA_OAEP_ENCODE_MAX_MASKDB_SIZE];
90     uint8_t  SeedMask[CC_RSA_OAEP_ENCODE_MAX_SEEDMASK_SIZE];
91 #ifdef USE_MBEDTLS_CRYPTOCELL
92     mbedtls_md_context_t hash_ctx;
93 #else
94     CCHashUserContext_t HashUsercontext;
95 #endif
96     CCHashResultBuf_t         HashResultBuff;
97 }CC_PAL_COMPILER_TYPE_MAY_ALIAS CCRsaOaepData_t;
98 
99 /************************ Public Variables **********************/
100 
101 
102 /************************ Public Functions **********************/
103 
104 /*********************************************************************************/
105 /**
106  * @brief The function implements PKCS#1 v1.5 (9.2) EMSA Encoding
107  *        algorithm used in Sign/Verify operations.
108  *
109  * @author reuvenl (9/14/2014)
110  *
111  * @param K - The size of encoded message in octets.
112  * @param hashMode - hash mode ID (enum).
113  * @param pM - The Pointer to the Message M. In case of Sign it is a hash (H).
114  * @param MSize - Denotes the Message size: for Sig/Ver = hashSize,
115  *                for Enc/Dec <= K-hashAlgIdSize-PSS_MIN_LEN-3.
116  * @param pOut - The pointer to a buffer which is at least K octets long.
117  * @param bIsRawMode - boolean to indicate if the function is used in Raw mode,
118  *                     which means that structure T to be signed is passed as
119  *                     input already (no need to perform hashing)
120  * @param DataIn_ptr - Buffer containing the T structure to be signed (possibly
121  *                     the DER encoding of ASN.1 DigestInfo structure as
122  *                     specified in RFC8017 sect. 9.2 notes)
123  * @param DataInSize - Size in bytes of the structure T to be signed
124  *                     which is passed as input for raw signing mode
125  *
126  * @return CCError_t
127  */
128 CCError_t RsaEmsaPkcs1v15Encode(
129         uint32_t              K,
130         CCHashOperationMode_t hashMode,
131         uint8_t               *pM, /*mess.digest*/
132         uint32_t              MSize,
133         uint8_t               *pOut,
134         bool                  bIsRawMode,
135         const uint8_t         *DataIn_ptr,
136         size_t                DataInSize);
137 
138 
139 
140 /**********************************************************************************************************/
141 
142 CCError_t RsaOaepMGF1( uint16_t hLen, /*size in Bytes*/
143                 uint8_t * Z_ptr,
144                 uint16_t ZSize,/*size in Bytes*/
145                 uint32_t L,
146                 uint8_t  *Mask_ptr,
147                 CCPkcs1HashFunc_t hashFunc,
148                 uint8_t  *T_Buf,    /*T_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/
149                 uint8_t  *T_TMP_Buf);/*T_TMP_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/
150 
151 /**********************************************************************************************************/
152 /**
153    @brief
154    RsaPssOaepEncode implements the the Encoding operation according to the PKCS#1 as defined
155    in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
156 */
157 CCError_t RsaPssOaepEncode(CCRndContext_t *rndContext_ptr, /* random functions context */
158                              CCPkcs1HashFunc_t hashFunc,     /* PKCS1 hash mode enum */
159                              CCPkcs1Mgf_t MGF,               /* MGF function type enum */
160                              uint8_t *M_ptr,                     /* a pointer to the message to be encoded */
161                              uint16_t MSize,                     /* the message size in bytes */
162                              uint8_t *P_ptr,                     /* a pointer to the label; can be empty string */
163                              size_t PSize,                     /* the size of the label in bytes */
164                              uint16_t emLen, /* The value is set before the call */
165                              CCRsaPrimeData_t  *PrimeData_ptr,/* temp buffer */
166                              uint8_t  *EMInput_ptr,              /* encoded message output */
167                              CCPkcs1Version_t PKCS1_ver);
168 
169 /**********************************************************************************************************/
170 /**
171    @brief
172    RsaPssOaepDecode implements the the De operation according to the PKCS#1 as defined
173    in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
174 */
175 CCError_t RsaPssOaepDecode(CCPkcs1HashFunc_t hashFunc,
176                              CCPkcs1Mgf_t MGF,
177                              uint8_t  *EM_ptr,
178                              uint16_t EMSize,
179                              uint8_t *P_ptr,
180                              size_t  PSize,
181                              CCRsaPrimeData_t  *PrimeData_ptr, /*Only for stack memory save*/
182                              uint8_t *M_ptr,
183                              size_t  *MSize_ptr);
184 
185 /**********************************************************************************************************/
186 /**
187  * @brief
188  * This function does implements the functionality of PKCS1 Ver 2.1 Sign
189  *  operation after the Hash operation
190  *
191  * Before using that function a Hash must be completed on the Data.
192  * The function is called after the call to Hash_Finish
193  *
194  * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
195  * @param[in] Context_ptr - Pointer to a valid context as
196  *                           given from CC_RsaSign
197  *
198  * @param[out] Output_ptr - A buffer allocated for the output which is at least the size of the MOdulus N
199  *
200  *
201  * @return CCError_t - On success CC_OK is returned, on failure a
202  *                        value MODULE_* as defined in ...
203  */
204 CCError_t RsaPssSign21(CCRndContext_t *rndContext_ptr,
205                                 RSAPrivContext_t *Context_ptr,
206                                 uint8_t     *Output_ptr);
207 
208 
209 /**********************************************************************************************************/
210 /**
211     Function Name: RsaPssVerify21
212     Date:   06-12-2004
213     Author: Ohad Shperling
214 
215 
216     \brief RsaPssVerify21 implements EMSA-PSS-Verify algorithm
217    as defined in PKCS#1 v2.1 Sec 9.1.2
218 
219    @param[in] Context_ptr - Pointer to a valid context as
220                             given from the VerifyFinish function.
221 
222    The field HASH_Result inside the Context_ptr is initialized with the Hashed digested message.
223    The field HASH_Result_Size inside the Context_ptr is initialized with the Hash digested message size
224 
225    @return CCError_t - CC_OK,or error
226 */
227 CCError_t RsaPssVerify21(RSAPubContext_t *Context_ptr);
228 
229 /**********************************************************************************************************/
230 /**
231  * @brief The CC_RsaGenerateVectorInRangeX931 function generates a random vector in range:
232  *            MinVect < RandVect < MaxVect, where:
233  *            MinVect = sqwRoot(2) * 2^(RndSizeInBits-1),  MaxVect = 2^RndSizeInBits.
234  *
235  *            Note: 1. MSBit of RandVect must be set to 1.
236  *                  2. Words order of output vector is set from LS word to MS
237  *                 word.
238  *
239  *        This function is used in PKI RSA for random generation according to ANS X9.31 standard.
240  *        If PKI_RSA is not supported, the function does nothing.
241  *
242  *        Functions algorithm::
243  *
244  *        1.  Calls the CC_RndGenerateVector() function for generating random vector
245  *            RndVect of size RndSizeInWords, rounded up to bytes. Set index i
246  *            to high word i = SizeInWords-1.
247  *        2.  Check and adust candidate for msWord inside the random vector
248  *            starting from msWord himselv, if msWord > high word of MinVect,
249  *            goto step 3, else try next word i--; if no words to try, then goto
250  *            step 1.
251  *        3.  Set the found msWord to high position in array and generate new
252  *            random words instead all checked and rejected words.
253  *
254  * @rndContext_ptr[in/out]  - Pointer to the RND context buffer.
255  * @rndSizeWords[in]  - The size of random vectore that is required.
256  * @rnd_ptr[out]      - The output buffer of size not less, than rndSizeWords.
257  *
258  * @return CCError_t - On success CC_OK is returned, on failure a
259  *                       value MODULE_* as defined in ...
260  */
261 CCError_t CC_RsaGenerateVectorInRangeX931(CCRndContext_t *rndContext_ptr,
262                                                uint32_t   rndSizeWords,
263                                                uint32_t  *rnd_ptr);
264 
265 /*****************************************************************************/
266 /**
267  * The function generates vector of non zero octets.
268  *
269  * @author reuvenl (9/14/2014)
270  *
271  * @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
272  * @param pVect - The pointer to output buffer.
273  * @param size  - The size of vector in bytes.
274  *
275  * @return CCError_t
276  */
277 CCError_t  RsaGenRndNonZeroVect(CCRndContext_t *rndContext_ptr, uint8_t *pVect, uint32_t size);
278 
279 
280 /**********************************************************************************************************/
281 /*!
282 @brief RSA_SignInit initializes the Signing multi-call algorithm as defined in PKCS#1 2.1 standard, including v1.5.
283 
284 NOTE:
285 -# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1.
286 -# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info.
287 
288 This function does not do cryptographic processing. Rather, it
289 prepares a context that is used by the Update and Finish functions.
290 
291 @return CC_OK on success.
292 @return error on failure
293 */
294 CIMPORT_C CCError_t CC_RsaSignInit(
295                             CCRsaPrivUserContext_t *UserContext_ptr,     /*!< [in/out] A pointer to a Context. The value returned here must be passed to the Update and Finish functions. */
296                             CCRsaUserPrivKey_t *UserPrivKey_ptr,         /*!< [in]  A pointer to the private key data structure.
297                                                                                        \note The representation (pair or quintuple) and hence the algorithm (CRT or not) is determined by the Private Key data structure.
298                                                                                        Using of the CC_BuildPrivKey or CC_BuildPrivKeyCRT determines which algorithm is used. */
299                             CCRsaHashOpMode_t rsaHashMode,             /*!< [in]  The enumerator value, defining the hash function to be used: SHA-1,SHA224/256/384/512, MD5 (MD5 allowed only in v1.5).
300                                                                                         The hash functions recommended by PKCS#1 v2.1 are: 256/384/512. Also allowed "After" HASH modes for said functions. */
301                             CCPkcs1Mgf_t MGF,                           /*!< [in]  The mask generation function. PKCS#1 v2.1 defines MGF1, so the only value allowed here is CC_PKCS1_MGF1. */
302                             size_t SaltLen,                 /*!< [in]  The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only, typically lengths is 0 or hLen). FIPS 186-4 requires,
303                                                                                        that SaltLen <= hlen. If SaltLen > KeySize - hLen - 2, the function returns an error. */
304                             CCPkcs1Version_t PKCS1_ver          /*!< [in]  Ver 1.5 or 2.1, according to the functionality required. */
305 );
306 
307 /**********************************************************************************************************/
308 /*!
309 @brief CC_RsaSignUpdate processes the data to be signed in a given context.
310 
311 @note CC_RsaSignUpdate can be called multiple times with data
312 
313 @return CC_OK on success.
314 @return Error on failure
315 */
316 CIMPORT_C CCError_t CC_RsaSignUpdate(
317                                 CCRsaPrivUserContext_t *UserContext_ptr,     /*!< [in] A pointer to a valid context, as returned by CC_RsaSignInit. */
318                                 uint8_t     *DataIn_ptr,                        /*!< [in] A pointer to the data to sign. */
319                                 size_t      DataInSize                         /*!< [in] The size, in bytes, of the data to sign. */
320 );
321 
322 /**********************************************************************************************************/
323 /*!
324 @brief CC_RsaSignFinish calculates the signature on the data passed to one or more calls to CC_RsaSignUpdate,
325 and releases the context.
326 
327 @return CC_OK on success.
328 @return Error on failure:\n
329             CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,\n
330             CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR,\n
331             CC_RSA_INVALID_OUTPUT_POINTER_ERROR,\n
332             CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE,\n
333             CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,\n
334             CC_RSA_PKCS1_VER_ARG_ERROR
335 */
336 
337 CIMPORT_C CCError_t CC_RsaSignFinish(
338             CCRndContext_t *rndContext_ptr,          /*!< [in/out] Pointer to the RND context buffer. */
339             CCRsaPrivUserContext_t *UserContext_ptr, /*!< [in/out] A pointer to the Context initialized by the SignInit function and used by the SignUpdate function. */
340             uint8_t *Output_ptr,                     /*!< [out] A pointer to the signature.
341                                                           The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */
342             size_t *OutputSize_ptr,                  /*!< [in/out] A pointer to the Signature Size value -
343                                                           the input value is the signature buffer size allocated, the output value is the signature size used.
344                                                           The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */
345             bool bIsRawMode,                         /*!< [in] This flag is true for those cases where we need to sign only (without encoding T) */
346             const uint8_t *DataIn_ptr,               /*!< [in] Pointer to the raw data to be signed in raw mode. Relevant only when bIsRawMode is true */
347             size_t DataInSize                        /*!< [in] Size in bytes of the raw input data pointed by DataIn_ptr */
348 );
349 
350 /**********************************************************************************************************/
351 /*!
352 @brief  RSA_VerifyInit initializes the Verify multi-call algorithm as defined in PKCS#1 v1.5 and 2.1
353 
354 note:
355 -# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1.
356 -# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info.
357 
358 @return CC_OK on success.
359 @return Error on failure
360 */
361 CIMPORT_C CCError_t CC_RsaVerifyInit(
362                             CCRsaPubUserContext_t *UserContext_ptr,      /*!< [in]  A pointer to the public Context structure of the User. */
363                             CCRsaUserPubKey_t *UserPubKey_ptr,           /*!< [in]  A pointer to the public key data structure. */
364                             CCRsaHashOpMode_t rsaHashMode,             /*!< [in]  The hash function to be used. Currently available HASH functions: SHA1/SHA-256/384/512/MD5 (MD5 - allowed only for PKCS#1 v1.5).
365                                                                                         Also allowed "After HASH" modes for said functions. */
366                             CCPkcs1Mgf_t MGF,                           /*!< [in]  The mask generation function, relevant only for PKCS#1 v2.1. The currently allowed value for v2.1 is CC_PKCS1_MGF1. */
367                             size_t  SaltLen,                               /*!< [in]  The Length of the Salt buffer. Relevant for PKCS#1 Ver 2.1 only. Typical lengths are 0 and hashLen (20 for SHA1).
368                                                                                         The maximum length allowed is NSize - hLen - 2.
369                                                                                         If the salt length is not available in this process, the user can use the define: CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN.
370                                                                                         Security Note: This mode is not FIPS approved and it is recommended not to use this flag and provide the Salt length
371                                                                                         on each verification. */
372                             CCPkcs1Version_t PKCS1_ver                    /*!< [in]  Ver 1.5 or 2.1, according to the functionality required. */
373 );
374 
375 /**********************************************************************************************************/
376 /*!
377 @brief RSA_VerifyUpdate processes the data to be verified in a given context, according to PKCS1 v1.5 and 2.1
378 @brief RSA_VerifyUpdate can be called multiple times with data
379 
380 @return CC_OK on success.
381 @return Error on failure
382 */
383 
384 CIMPORT_C CCError_t CC_RsaVerifyUpdate(
385                                 CCRsaPubUserContext_t *UserContext_ptr,      /*!< [in]  A pointer to the public Context structure of the User. */
386                                 uint8_t     *DataIn_ptr,                        /*!< [in]  A pointer to the data whose signature is to be verified. */
387                                 size_t       DataInSize                         /*!< [in]  The size, in bytes, of the data whose signature is to be verified. */
388 );
389 
390 /**********************************************************************************************************/
391 /*!
392 @brief RSA_VerifyFinish implements the Finish Phase of the Verify algorithm as defined in PKCS#1 v2.1 or PKCS#1 v1.5
393 
394 @return CC_OK on success.
395 @return Error on failure
396 */
397 
398 CIMPORT_C CCError_t CC_RsaVerifyFinish(
399             CCRsaPubUserContext_t *UserContext_ptr,  /*!< [in]  A pointer to the public Context structure of the User. */
400             uint8_t *Sig_ptr,                        /*!< [in]  A pointer to the signature to be verified.
401                                                                 The length of the signature is PubKey_ptr->N.len bytes (that is, the size of the modulus, in bytes). */
402             bool bIsRawMode,                         /*!< [in]  Boolean indicating whether the input is a an already encoded T structure (possibly as specified by RFC8017 sect 9.2)
403                                                                 In that case, no hashing is performed */
404             const uint8_t *DataIn_ptr,               /*!< [in]  Pointer containing the already encoded T structure to be verified as input in raw mode */
405             size_t DataInSize                        /*!< [in]  Size in bytes of the structure T passed as raw input */
406 );
407 
408 #ifdef __cplusplus
409 }
410 #endif
411 
412 #endif
413 
414