1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include "string.h"
7 #include "stdio.h"
8 #include "stdlib.h"
9 
10 #include "cc_pal_types.h"
11 #include "mbedtls/ctr_drbg.h"
12 
13 #include "run_integration_helper.h"
14 #include "run_integration_test.h"
15 #include "run_integration_pal_log.h"
16 #include "run_integration_flash.h"
17 
18 /**
19  * Assigns into ppBuffAligned the next aligned 32bit address relative to pBuff.
20  *
21  * @param pBuff
22  * @param ppBuffAligned
23  */
runIt_buffAlign32(uint8_t * pBuff,uint32_t ** ppBuffAligned,uint32_t wantedBuffSize,const char * name)24 void runIt_buffAlign32(uint8_t* pBuff, uint32_t **ppBuffAligned, uint32_t wantedBuffSize, const char * name)
25 {
26     uint32_t address = (uint32_t)pBuff;
27     uint32_t remainder = (sizeof(uint32_t) - (address % sizeof(uint32_t))) % sizeof(uint32_t);
28     *ppBuffAligned = (uint32_t*)(address + remainder);
29 
30     CC_UNUSED_PARAM(wantedBuffSize);
31     CC_UNUSED_PARAM(name);
32 
33 #if defined(RUNIT_DEBUG_ALLOC)
34     RUNIT_PRINT_DBG("%-30.30s pBuff[%"PRIxPTR"] ppBuffAligned[%"PRIxPTR"] wantedBuffSize[%04"PRIu32"]\n", name, (uintptr_t)pBuff, (uintptr_t)*ppBuffAligned, wantedBuffSize);
35 #endif
36 }
37 
runIt_unhexify(unsigned char * obuf,const char * ibuf)38 int runIt_unhexify(unsigned char *obuf, const char *ibuf)
39 {
40     #define assert(a) do{} while(0)
41     unsigned char c, c2;
42     int len = strlen(ibuf) / 2;
43     assert(strlen( ibuf ) % 2 == 0); /* must be even number of bytes */
44 
45     while (*ibuf != 0)
46     {
47         c = *ibuf++;
48         if (c >= '0' && c <= '9')
49             c -= '0';
50         else if (c >= 'a' && c <= 'f')
51             c -= 'a' - 10;
52         else if (c >= 'A' && c <= 'F')
53             c -= 'A' - 10;
54         else
55             assert(0);
56 
57         c2 = *ibuf++;
58         if (c2 >= '0' && c2 <= '9')
59             c2 -= '0';
60         else if (c2 >= 'a' && c2 <= 'f')
61             c2 -= 'a' - 10;
62         else if (c2 >= 'A' && c2 <= 'F')
63             c2 -= 'A' - 10;
64         else
65             assert(0);
66 
67         *obuf++ = (c << 4) | c2;
68     }
69 
70     return len;
71 }
72 
runIt_hexify(unsigned char * obuf,const unsigned char * ibuf,int len)73 void runIt_hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
74 {
75     unsigned char l, h;
76 
77     while (len != 0)
78     {
79         h = *ibuf / 16;
80         l = *ibuf % 16;
81 
82         if (h < 10)
83             *obuf++ = '0' + h;
84         else
85             *obuf++ = 'a' + h - 10;
86 
87         if (l < 10)
88             *obuf++ = '0' + l;
89         else
90             *obuf++ = 'a' + l - 10;
91 
92         ++ibuf;
93         len--;
94     }
95 }
96 
97 /**
98  * This function just returns data from rand().
99  * Although predictable and often similar on multiple
100  * runs, this does not result in identical random on
101  * each run. So do not use this if the results of a
102  * test depend on the random data that is generated.
103  *
104  * rng_state shall be NULL.
105  */
runIt_rndStdRand(void * rng_state,unsigned char * output,size_t len)106 static int runIt_rndStdRand(void *rng_state, unsigned char *output, size_t len)
107 {
108 #if !defined(__OpenBSD__)
109     size_t i;
110 
111     if (rng_state != NULL)
112         rng_state = NULL;
113 
114     for (i = 0; i < len; ++i)
115         output[i] = rand();
116 #else
117     if( rng_state != NULL )
118     rng_state = NULL;
119 
120     arc4random_buf( output, len );
121 #endif /* !OpenBSD */
122 
123     return (0);
124 }
125 
126 /**
127  * This function returns random based on a buffer it receives.
128  *
129  * rng_state shall be a pointer to a rnd_buf_info structure.
130  *
131  * The number of bytes released from the buffer on each call to
132  * the random function is specified by per_call. (Can be between
133  * 1 and 4)
134  *
135  * After the buffer is empty it will return rand();
136  */
runIt_rndBufferRand(void * rng_state,unsigned char * output,size_t len)137 int runIt_rndBufferRand(void *rng_state, unsigned char *output, size_t len)
138 {
139     rnd_buf_info *info = (rnd_buf_info *) rng_state;
140     size_t use_len;
141 
142     if (rng_state == NULL)
143         return (runIt_rndStdRand( NULL, output, len));
144 
145     use_len = len;
146     if (len > info->length)
147         use_len = info->length;
148 
149     if (use_len)
150     {
151         memcpy(output, info->buf, use_len);
152         info->buf += use_len;
153         info->length -= use_len;
154     }
155 
156     if (len - use_len > 0)
157         return (runIt_rndStdRand( NULL, output + use_len, len - use_len));
158 
159     return (0);
160 }
161 
runIt_free(RunItPtr * ptrElement)162 int runIt_free(RunItPtr *ptrElement)
163 {
164     int rc = 0;
165     RUNIT_ASSERT(ptrElement != NULL);
166 
167     mbedtls_free(ptrElement->buf);
168 
169 bail:
170     return rc;
171 }
172 
runIt_malloc(RunItPtr * ptrElement,size_t length)173 int runIt_malloc(RunItPtr *ptrElement, size_t length)
174 {
175     int rc = 0;
176     RUNIT_ASSERT(ptrElement != NULL);
177 
178     memset(ptrElement, 0, sizeof(*ptrElement));
179 
180     ptrElement->buf = mbedtls_calloc(1, length + RUNIT_ALIGN32_SLACK + sizeof(uint32_t));
181     runIt_buffAlign32(ptrElement->buf, &(ptrElement->ba), length, "temp");
182     ptrElement->length = length;
183 
184 bail:
185     return rc;
186 }
187 
188 /**
189  * @brief                   Function needed by some of CC API.
190  *                          Converts between CC API signature to internal flash read function
191  *                          This specific function implementation reads the flash content in newly allocated memory.
192  *
193  * @param flashAddress      [input]
194  * @param memDst            [output]
195  * @param sizeToRead        [input]
196  * @param context           [input] not used
197  *
198  * @return                  CC_OK on success
199  */
runIt_flashReadWrap(void * flashAddress,uint8_t * memDst,uint32_t sizeToRead,void * context)200 uint32_t runIt_flashReadWrap(void* flashAddress, /*! Flash address to read from */
201                              uint8_t *memDst, /*! memory destination to read the data to */
202                              uint32_t sizeToRead, /*! size to read from Flash (in bytes) */
203                              void* context)
204 {
205     CC_UNUSED_PARAM(context);
206 
207     if (runIt_flashRead((uint32_t)flashAddress, memDst, sizeToRead) != RUNIT_ERROR__OK)
208         return 1;
209 
210     return 0;
211 }
212 
213 
runIt_buildRandomBuffer(uint8_t * pBuf,size_t bufSize)214 int runIt_buildRandomBuffer(uint8_t *pBuf, size_t bufSize)
215 {
216     uint32_t chunkSize = 0;
217     uint32_t doneSize = 0;
218 
219     while (doneSize < bufSize)
220     {
221         chunkSize = (bufSize - doneSize > MBEDTLS_CTR_DRBG_MAX_REQUEST) ? MBEDTLS_CTR_DRBG_MAX_REQUEST : (bufSize - doneSize);
222         if (gpRndContext->rndGenerateVectFunc(gpRndContext->rndState, pBuf + doneSize, chunkSize) == 0)
223         {
224             doneSize += chunkSize;
225         }
226         else
227         {
228             return RUNIT_ERROR__FAIL;
229         }
230     }
231 
232     return RUNIT_ERROR__OK;
233 }
234