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 #include "cc_pal_mem.h"
16 #include "cc_common_math.h"
17 #include "cc_rsa_local.h"
18 #include "cc_rsa_error.h"
19 #include "cc_rnd_error.h"
20 
21 /************************ Defines ******************************/
22 
23 /************************ Enums ******************************/
24 
25 /************************ Typedefs ***************************/
26 
27 /************************ Public Functions *******************/
28 
29 
30 #if !defined(_INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT)
31 
32 /************************ Global Data ******************************/
33 /* DER(BER) encoded data for allowed HASH algorithms
34  * typedef struct HashDerCode_t {
35  *             uint32_t algIdSizeBytes;
36  *             CCHashOperationMode_t hashMode;
37  *             uint8_t algId[HASH_DER_CODE_MAX_SIZE_BYTES];
38  * } HashDerCode_t;
39  *
40  * Note: algId is the DER encoding of the T value corresponding to the
41  *       ASN.1 structure DigestInfo as specified in RFC8017 sect 9.2,
42  *       without the hash H part that has to be concatenated at the end
43  */
44 /* Note: order of algorithms in array must be according to HASH mode ID */
45 static const HashDerCode_t gHashDerCodes[] = {
46         {15, CC_HASH_SHA1_mode,  {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14}},                     /*SHA1*/
47         {19, CC_HASH_SHA224_mode,{0x30,0x2D,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1C}}, /*SHA224*/
48         {19, CC_HASH_SHA256_mode,{0x30,0x31,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}}, /*SHA256*/
49         {19, CC_HASH_SHA384_mode,{0x30,0x41,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}}, /*SHA384*/
50         {19, CC_HASH_SHA512_mode,{0x30,0x51,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}}, /*SHA512*/
51         {18, CC_HASH_MD5_mode,   {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10}},      /*MD5*/
52 };
53 
54 /*************************** Private functions **********************/
55 
56 /**
57  * The function gets DER code of choosen Hash algoritm.
58  *
59  * @author reuvenl (9/11/2014)
60  *
61  * @param hashMode - Hash mode enumeration.
62  * @param pAlgId - The pointer to Hash algoritm DER code;
63  * @param pAlgIdSize - The size of the Hash algoritm DER code;
64  *
65  * @return CCError_t
66  */
GetHashAlgDerCode(CCHashOperationMode_t hashMode,const uint8_t ** pAlgId,uint32_t * pAlgIdSize)67 static CCError_t GetHashAlgDerCode(
68                                     CCHashOperationMode_t hashMode,
69                                     const uint8_t **pAlgId,
70                                     uint32_t *pAlgIdSize)
71 {
72         if (hashMode >= sizeof(gHashDerCodes) / sizeof(HashDerCode_t))
73                 return CC_RSA_GET_DER_HASH_MODE_ILLEGAL;
74         /* output requirred Hash algorithm DER code */
75         *pAlgId = gHashDerCodes[hashMode].algId;
76         *pAlgIdSize = (gHashDerCodes[hashMode]).algIdSizeBytes;
77         return CC_OK;
78 }
79 
80 /*****************************************************************************/
81 /**
82  * The function generates vector of non zero octets.
83  *
84  * @author reuvenl (9/14/2014)
85  *
86  * @param rndContext_ptr  - Pointer to the RND context buffer.
87  * @param pVect - The pointer to output buffer.
88  * @param size  - The size of vector in bytes.
89  *
90  * @return CCError_t
91  */
RsaGenRndNonZeroVect(CCRndContext_t * rndContext_ptr,uint8_t * pVect,uint32_t size)92 CCError_t  RsaGenRndNonZeroVect(CCRndContext_t *rndContext_ptr, uint8_t *pVect, uint32_t size)
93 {
94         #define TMP_SIZE 16
95         CCError_t err = CC_OK;
96         uint32_t i, j, newRnd;
97         uint8_t tmp[TMP_SIZE];
98         uint8_t zero[TMP_SIZE] = { 0 };
99 
100 
101         void   *rndState_ptr;
102         CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
103 
104         /* check parameters */
105         if (rndContext_ptr == NULL)
106                 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
107 
108         rndState_ptr = rndContext_ptr->rndState;
109         RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
110 
111         if (RndGenerateVectFunc == NULL)
112                 return CC_RND_GEN_VECTOR_FUNC_ERROR;
113 
114         /* generate random vector */
115         err = RndGenerateVectFunc(rndState_ptr, (unsigned char *)pVect, (size_t)size);
116         if (err != CC_OK) {
117                 return err;
118         }
119 
120         /* generate auxiliary random buff and change zero octets */
121         j = 0; newRnd = 1;
122         for (i=0; i<size; i++) {
123                 while (1) {
124                         if (newRnd) {
125                                 j = 0; newRnd = 0;
126                                 err = RndGenerateVectFunc(rndState_ptr, (unsigned char *)tmp, sizeof(tmp));
127                                 // Handle case of RND function which returns zeros
128                                 if (CC_PalMemCmp(tmp, zero, TMP_SIZE) == 0) {
129                                     return CC_RND_GEN_VECTOR_FUNC_ERROR;
130                                 }
131                                 if (err != CC_OK) {
132                                         return err;
133                                 }
134                         }
135 
136                         /* change byte*/
137                         if (pVect[i] == 0 ) {
138                                 if (tmp[j] == 0) {
139                                         j++;
140                                         if (j == sizeof(tmp)) {
141                                             newRnd = 1;
142                                         }
143                                         continue;
144                                 }
145                                 pVect[i] = tmp[j];
146                                 j++;
147                                 break;
148                         } else
149                                 break;
150                 }
151                 if (j == sizeof(tmp)) {
152                         newRnd = 1;
153                 }
154         }
155         return err;
156 }
157 
158 /*********************************************************************************/
159 /**
160  * @brief The function implements PKCS#1 v1.5 (9.2) EMSA Encoding
161  *        algorithm used in Sign/Verify operations.
162  *
163  * @author reuvenl (9/14/2014)
164  *
165  * @param K - The size of encoded message in octets.
166  * @param hashMode - hash mode ID (enum).
167  * @param pM - The Pointer to the Message M. In case of Sign it is a hash (H).
168  * @param MSize - Denotes the Message size: for Sig/Ver = hashSize,
169  *                for Enc/Dec <= K-hashAlgIdSize-PSS_MIN_LEN-3.
170  * @param pOut - The pointer to a buffer which is at least K octets long.
171  * @param bIsRawMode - boolean to indicate if the function is used in Raw mode,
172  *                     which means that the T structure is already
173  *                     provided as an input (no need to perform hashing)
174  * @param DataIn_ptr - Buffer containing the T structure to be signed (possibly
175  *                     the DER encoding of ASN.1 DigestInfo structure as
176  *                     specified in RFC8017 sect. 9.2 notes)
177  * @param DataInSize - Size in bytes of the raw input T provided in DataIn_ptr
178  *
179  * @return CCError_t
180  */
RsaEmsaPkcs1v15Encode(uint32_t K,CCHashOperationMode_t hashMode,uint8_t * pM,uint32_t MSize,uint8_t * pOut,bool bIsRawMode,const uint8_t * DataIn_ptr,size_t DataInSize)181 CCError_t RsaEmsaPkcs1v15Encode(
182         uint32_t              K,
183         CCHashOperationMode_t hashMode,
184         uint8_t               *pM, /*mess.digest*/
185         uint32_t              MSize,
186         uint8_t               *pOut,
187         bool                  bIsRawMode,
188         const uint8_t         *DataIn_ptr,
189         size_t                DataInSize)
190 {
191         /* The return error identifier */
192         CCError_t Error = CC_OK;
193 
194         /* Padding String Size  */
195         int32_t  PSSize;
196         /* The pointer to Hash Alg. ID (DER code) and its size */
197         const uint8_t *pHashAlgId = NULL;
198         uint32_t hashAlgIdSize = 0;
199 
200         /* FUNCTION LOGIC */
201 #ifdef DEBUG
202         /* Init to garbage */
203         CC_PalMemSet(pOut, 0xCC, K);
204 #endif
205         /*---------------------------------------------------*/
206         /*  Encryption block formating for EMSA-PKCS1-v1_5:  */
207         /*          00 || 01 || PS || 00 || T            */
208         /*         MSB                      LSB          */
209         /* Note:  BT=02, PS=FF...FF, T=DER||Hash(M)          */
210         /*---------------------------------------------------*/
211         if (!bIsRawMode) {
212             /* Get Hash alg. parametrs including DER code */
213             Error = GetHashAlgDerCode(hashMode, &pHashAlgId, &hashAlgIdSize);
214             if (Error) {
215                 return Error;
216             }
217             /* check sizes */
218             if (3+MSize+PS_MIN_LEN+hashAlgIdSize > K) {
219                 return CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE;
220             }
221             PSSize = K-MSize-hashAlgIdSize-3; /*therefore, PSSize >= PS_MIN_LEN*/
222         } else {
223             /* check sizes */
224             if (K < DataInSize+11)  {
225                 return CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE;
226             }
227             PSSize = K-DataInSize-3;
228         }
229 
230         /* Fill the formatted output buffer */
231         pOut[0]=0x00;    /* set the 00 */
232         pOut[1]=0x01;    /* set Block Type 01 */
233         CC_PalMemSet(&pOut[2], 0xFF, PSSize);
234         /* set 00-byte after PS */
235         pOut[2+PSSize] = 0x00;
236         if (!bIsRawMode) {
237             /* copy the Hash Algorithm ID (DER code) */
238             CC_PalMemCopy(&pOut[3+PSSize], pHashAlgId, hashAlgIdSize);
239             /* copy the message/digest data */
240             CC_PalMemCopy(&pOut[K-MSize], pM, MSize);
241         } else {
242             CC_PalMemCopy(&pOut[3+PSSize], DataIn_ptr, DataInSize);
243         }
244 
245         return CC_OK;
246 }
247 
248 #endif /*defined(_INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
249 
250 /******************************************************************************************/
251 
252 /* just to have a declaarion so the 'C' file passes compilation */
CRTS_RSA_VER15_UTIL_foo(void)253 void CRTS_RSA_VER15_UTIL_foo(void) {}
254 
255 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
256 
257