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