1 /*
2  * Copyright 2019-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #include <stdint.h>
8 
9 #include "fsl_sscp_mu.h"
10 #include "fsl_sss_sscp.h"
11 #include "fsl_sss_mgmt.h"
12 
13 #define MU_Deinit   (void)
14 #define ELE_SUCCESS ((uint8_t)0x3C)
15 #define ELE_FAIL    ((uint8_t)0xC3)
16 
MU_Init(void)17 void MU_Init(void)
18 {
19     ELEMU_mu_init(ELEMUA);
20 }
21 
MU_ReceiveMsg(ELEMU_Type * base,uint32_t msg[ELEMU_RR_COUNT],size_t wordNum)22 sscp_status_t MU_ReceiveMsg(ELEMU_Type *base, uint32_t msg[ELEMU_RR_COUNT], size_t wordNum)
23 {
24     sscp_status_t ret = kStatus_SSCP_Fail;
25     /* NBOOT MISRA Ex. 1 - Rule 11.3 - Casting between pointers of different types is not allowed */
26     if (ELEMU_mu_get_response((ELEMU_Type *)(uintptr_t)base, msg, wordNum) != kStatus_Success)
27     {
28     }
29 #if (defined(FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER) && FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER)
30     else if (ELEMU_mu_release_ownership((ELEMU_Type *)base) != kStatus_Success)
31     {
32     }
33 #endif /* FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER */
34     else
35     {
36         ret = kStatus_SSCP_Success;
37     }
38     return ret;
39 }
40 
MU_SendMsg(ELEMU_Type * base,uint32_t msg[ELEMU_TR_COUNT],size_t wordNum)41 sscp_status_t MU_SendMsg(ELEMU_Type *base, uint32_t msg[ELEMU_TR_COUNT], size_t wordNum)
42 {
43     sscp_status_t ret = kStatus_SSCP_Fail;
44 #if (defined(FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER) && FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER)
45     /* NBOOT MISRA Ex. 1 - Rule 11.3 - Casting between pointers of different types is not allowed */
46     if (ELEMU_mu_get_ownership((ELEMU_Type *)base) != kStatus_Success)
47     {
48         ret = kStatus_SSCP_ResourceBusy;
49     }
50     else
51 #endif /* FSL_FEATURE_ELEMU_HAS_SEMA4_STATUS_REGISTER */
52         if (ELEMU_mu_send_message((ELEMU_Type *)(uintptr_t)base, msg, wordNum) != kStatus_Success)
53         {
54         }
55         else
56         {
57             ret = kStatus_SSCP_Success;
58         }
59     return ret;
60 }
61 
sscp_mu_init(sscp_context_t * context,ELEMU_Type * base)62 sscp_status_t sscp_mu_init(sscp_context_t *context, ELEMU_Type *base)
63 {
64     sscp_mu_context_t *muContext = (sscp_mu_context_t *)(uintptr_t)context;
65 
66     muContext->base = base;
67     MU_Init();
68 
69     /* assign MU implementation of ::sscp_invoke_command() */
70     muContext->invoke = sscp_mu_invoke_command;
71     return kStatus_SSCP_Success;
72 }
73 
sscp_mu_deinit(sscp_context_t * context)74 void sscp_mu_deinit(sscp_context_t *context)
75 {
76     /*sscp_mu_context_t *muContext = (sscp_mu_context_t *)(uintptr_t)context;
77 
78     MU_Deinit(muContext->base);*/
79 }
80 
81 sscp_status_t prepareMessage(sscp_operation_t *op, uint32_t msg[ELEMU_TR_COUNT], uint32_t *wrId);
82 
83 /* NBOOT HIS metric Ex. 1 - HIS_CCM - Cyclomatic complexity */
prepareMessage(sscp_operation_t * op,uint32_t msg[ELEMU_TR_COUNT],uint32_t * wrId)84 sscp_status_t prepareMessage(sscp_operation_t *op, uint32_t msg[ELEMU_TR_COUNT], uint32_t *wrId)
85 {
86     bool done            = false;
87     uint32_t wrIdx       = MU_MSG_HEADER_SIZE;
88     sscp_status_t ret    = kStatus_SSCP_Fail;
89     sscp_status_t tmpRet = kStatus_SSCP_Success;
90     uint32_t i;
91     for (i = 0u; (!done) && (i < SSCP_OPERATION_PARAM_COUNT); i++)
92     {
93         switch (SSCP_OP_GET_PARAM(i, op->paramTypes))
94         {
95             case kSSCP_ParamType_ContextReference:
96                 switch (op->params[i].context.type)
97                 {
98                     case kSSCP_ParamContextType_SSS_Session:
99                         msg[wrIdx++] = (uint32_t)((sss_sscp_session_t *)(op->params[i].context.ptr))->ctx;
100                         break;
101                     case kSSCP_ParamContextType_SSS_Symmetric:
102                         msg[wrIdx++] = (uint32_t)((sss_sscp_symmetric_t *)(op->params[i].context.ptr))->ctx;
103                         break;
104                     case kSSCP_ParamContextType_SSS_Aead:
105                         msg[wrIdx++] = (uint32_t)((sss_sscp_aead_t *)(op->params[i].context.ptr))->ctx;
106                         break;
107                     case kSSCP_ParamContextType_SSS_Digest:
108                         msg[wrIdx++] = (uint32_t)((sss_sscp_digest_t *)op->params[i].context.ptr)->ctx;
109                         break;
110                     case kSSCP_ParamContextType_SSS_Asymmetric:
111                         msg[wrIdx++] = (uint32_t)((sss_sscp_asymmetric_t *)op->params[i].context.ptr)->ctx;
112                         break;
113                     case kSSCP_ParamContextType_SSS_Object:
114                         msg[wrIdx++] = (uint32_t)((sss_sscp_object_t *)op->params[i].context.ptr)->ctx;
115                         break;
116                     case kSSCP_ParamContextType_SSS_KeyStore:
117                         msg[wrIdx++] = (uint32_t)((sss_sscp_key_store_t *)op->params[i].context.ptr)->ctx;
118                         break;
119                     case kSSCP_ParamContextType_SSS_DeriveKey:
120                         msg[wrIdx++] = (uint32_t)((sss_sscp_derive_key_t *)op->params[i].context.ptr)->ctx;
121                         break;
122                     case kSSCP_ParamContextType_SSS_Mgmt:
123                         msg[wrIdx++] = (uint32_t)((sss_mgmt_t *)op->params[i].context.ptr)->ctx;
124                         break;
125                     case kSSCP_ParamContextType_SSS_Rng:
126                         msg[wrIdx++] = (uint32_t)((sss_sscp_rng_t *)op->params[i].context.ptr)->rngTypeSpecifier;
127                         break;
128                     case kSSCP_ParamContextType_SSS_Mac:
129                         msg[wrIdx++] = (uint32_t)((sss_sscp_mac_t *)op->params[i].context.ptr)->ctx;
130                         break;
131                     case kSSCP_ParamContextType_SSS_Tunnel:
132                         msg[wrIdx++] = (uint32_t)((sss_sscp_tunnel_t *)op->params[i].context.ptr)->ctx;
133                         break;
134                     default:
135                         tmpRet = kStatus_SSCP_Fail;
136                         break;
137                 }
138                 break;
139 
140             case kSSCP_ParamType_Aggregate:
141                 break;
142             case kSSCP_ParamType_MemrefInput:
143             case kSSCP_ParamType_MemrefInOut:
144                 msg[wrIdx++] = (uint32_t)(op->params[i].memref.buffer);
145                 msg[wrIdx++] = op->params[i].memref.size;
146                 break;
147             case kSSCP_ParamType_MemrefOutputNoSize:
148             case kSSCP_ParamType_MemrefInputNoSize:
149                 msg[wrIdx++] = (uint32_t)(op->params[i].memref.buffer);
150                 break;
151             case kSSCP_ParamType_MemrefOutput:
152                 msg[wrIdx++] = (uint32_t)(op->params[i].memref.buffer);
153                 msg[wrIdx++] = (uint32_t)(op->params[i].memref.size);
154                 break;
155             case kSSCP_ParamType_ValueInputTuple:
156                 msg[wrIdx++] = op->params[i].value.a;
157                 msg[wrIdx++] = op->params[i].value.b;
158                 break;
159             case kSSCP_ParamType_ValueInputSingle:
160                 msg[wrIdx++] = op->params[i].value.a;
161                 break;
162             case kSSCP_ParamType_None:
163                 done = true; /* break the for loop */
164                 ret  = kStatus_SSCP_Success;
165                 break;
166             default:
167                 tmpRet = kStatus_SSCP_Fail;
168                 break;
169         }
170         if (tmpRet == kStatus_SSCP_Fail)
171         {
172             ret = kStatus_SSCP_Fail;
173             break;
174         }
175         /* Buffer overoload, end with error. */
176         if (wrIdx > ELEMU_TR_COUNT - 1u)
177         {
178             ret = kStatus_SSCP_Fail;
179             break;
180         }
181     }
182     if (i == SSCP_OPERATION_PARAM_COUNT)
183     {
184         ret = kStatus_SSCP_Success;
185     }
186     *wrId = wrIdx;
187     return ret;
188 }
189 
190 /* NBOOT HIS metric Ex. 1 - HIS_CCM - Cyclomatic complexity */
sscp_mu_invoke_command(sscp_context_t * context,sscp_command_t commandId,sscp_operation_t * op,uint32_t * ret)191 sscp_status_t sscp_mu_invoke_command(sscp_context_t *context,
192                                      sscp_command_t commandId,
193                                      sscp_operation_t *op,
194                                      uint32_t *ret)
195 {
196     /* NBOOT MISRA Ex. 1 - Rule 11.3 - Casting between pointers of different types is not allowed */
197     sscp_mu_context_t *muContext = (sscp_mu_context_t *)(uintptr_t)context;
198     /* parse the operation to create message */
199     uint32_t msg[ELEMU_TR_COUNT] = {0};
200     uint32_t wrIdx               = 0;
201     sscp_status_t ret2           = kStatus_SSCP_Fail;
202     sscp_status_t tmpRet         = kStatus_SSCP_Success;
203     *ret                         = kStatus_SSS_Fail;
204     mu_hdr_t muMsgHeader;
205 
206     do
207     {
208         if (prepareMessage(op, msg, &wrIdx) != kStatus_SSCP_Success)
209         {
210             ret2 = kStatus_SSCP_Fail;
211             break;
212         }
213         muMsgHeader.check_bits = STATIC_CHECK_BITS;
214         muMsgHeader.tag_sts    = MESSAGING_TAG_COMMAND;
215         muMsgHeader.command    = commandId;
216         muMsgHeader.size       = (uint8_t)(wrIdx - MU_MSG_HEADER_SIZE);
217         /* NBOOT MISRA Ex. 1 - Rule 11.3 - Casting between pointers of different types is not allowed */
218         msg[0] = (uint32_t)(*((uint32_t *)(uintptr_t)(&muMsgHeader)));
219         if (MU_SendMsg(muContext->base, msg, wrIdx) != kStatus_SSCP_Success)
220         {
221             ret2 = kStatus_SSCP_Fail;
222             break;
223         }
224 
225         /* poll for response */
226         if (MU_ReceiveMsg(muContext->base, msg, ELEMU_RR_COUNT) != kStatus_SSCP_Success)
227         {
228             ret2 = kStatus_SSCP_Fail;
229             break;
230         }
231         /* NBOOT MISRA Ex. 1 - Rule 11.3 - Casting between pointers of different types is not allowed */
232         mu_hdr_t *muReplyHeader = (mu_hdr_t *)(uintptr_t)&msg[0];
233         if (muReplyHeader->size != op->resultCount)
234         {
235             ret2 = kStatus_SSCP_Fail;
236             break;
237         }
238         if (muReplyHeader->command != commandId)
239         {
240             ret2 = kStatus_SSCP_Fail;
241             break;
242         }
243         for (uint32_t i = 1u; i <= op->resultCount; i++)
244         {
245             uint32_t k = i - 1u;
246             switch (SSCP_OP_GET_PARAM(k, op->resultTypes))
247             {
248                 case kSSCP_ParamType_ContextReference:
249                     switch (op->result[k].context.type)
250                     {
251                         case kSSCP_ParamContextType_SSS_Session:
252                             ((sss_sscp_session_t *)(op->result[k].context.ptr))->ctx = msg[i];
253                             break;
254                         case kSSCP_ParamContextType_SSS_Symmetric:
255                             ((sss_sscp_symmetric_t *)(op->result[k].context.ptr))->ctx = msg[i];
256                             break;
257                         case kSSCP_ParamContextType_SSS_Aead:
258                             ((sss_sscp_aead_t *)(op->result[k].context.ptr))->ctx = msg[i];
259                             break;
260                         case kSSCP_ParamContextType_SSS_Digest:
261                             ((sss_sscp_digest_t *)op->result[k].context.ptr)->ctx = msg[i];
262                             break;
263                         case kSSCP_ParamContextType_SSS_Asymmetric:
264                             ((sss_sscp_asymmetric_t *)op->result[k].context.ptr)->ctx = msg[i];
265                             break;
266                         case kSSCP_ParamContextType_SSS_Object:
267                             ((sss_sscp_object_t *)op->result[k].context.ptr)->ctx = msg[i];
268                             break;
269                         /*case kSSCP_ParamContextType_SSS_KeyStoreCtx:
270                             ((sss_sscp_key_store_t *)op->result[k].context.ptr)->keyStoreCtx = msg[i];
271                             break;*/
272                         case kSSCP_ParamContextType_SSS_KeyStore:
273                             ((sss_sscp_key_store_t *)op->result[k].context.ptr)->ctx = msg[i];
274                             break;
275                         case kSSCP_ParamContextType_SSS_DeriveKey:
276                             ((sss_sscp_derive_key_t *)op->result[k].context.ptr)->ctx = msg[i];
277                             break;
278                         case kSSCP_ParamContextType_SSS_Mgmt:
279                             ((sss_mgmt_t *)op->result[k].context.ptr)->ctx = msg[i];
280                             break;
281                         case kSSCP_ParamContextType_SSS_Mac:
282                             ((sss_sscp_mac_t *)op->result[k].context.ptr)->ctx = msg[i];
283                             break;
284                         case kSSCP_ParamContextType_SSS_Tunnel:
285                             ((sss_sscp_tunnel_t *)op->result[k].context.ptr)->ctx = msg[i];
286                             break;
287                         default:
288                             tmpRet = kStatus_SSCP_Fail;
289                             break;
290                     }
291                     break;
292                 case kSSCP_ParamType_ValueOutputSingle:
293                     *((uint32_t *)(op->result[k].value.a)) = msg[i];
294                     break;
295                 case kSSCP_ParamType_None:
296                     break;
297                 default:
298                     tmpRet = kStatus_SSCP_Fail;
299                     break;
300             }
301         }
302         if (tmpRet == kStatus_SSCP_Fail)
303         {
304             ret2 = kStatus_SSCP_Fail;
305             break;
306         }
307         if (muReplyHeader->tag_sts == ELE_SUCCESS)
308         {
309             *ret = kStatus_SSS_Success;
310             ret2 = kStatus_SSCP_Success;
311         }
312         else
313         {
314             ret2 = kStatus_SSCP_Fail;
315         }
316     } while (false);
317 
318     return ret2;
319 }
320