• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "security_auth_enhance.h"
33 #include <securec.h>
34 #include "securectype.h"
35 #include "tc_client_sub_driver.h"
36 #include "tc_ns_client.h"
37 #include "tc_ns_log.h"
38 #include "teek_client_constants.h"
39 #include "teek_client_type.h"
40 #include "tzdriver_compat.h"
41 
42 #if !defined(UINT64_MAX)
43     #define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFFULL)
44 #endif
45 
46 #ifdef SECURITY_AUTH_ENHANCE
47 #define GLOBAL_CMD_ID_SSA               0x2DCB /* SSA cmdId 11723 */
48 #define GLOBAL_CMD_ID_MT                0x2DCC /* MT cmdId 11724 */
49 #define GLOBAL_CMD_ID_MT_UPDATE         0x2DCD /* MT_IPDATE cmdId 11725 */
50 #define TEEC_PENDING2_AGENT             0xFFFF2001
51 
IsTokenEmpty(const uint8_t * token,uint32_t tokenLen)52 static bool IsTokenEmpty(const uint8_t *token, uint32_t tokenLen)
53 {
54     uint32_t i;
55 
56     if (token == NULL) {
57         tloge("bad parameters, token is null\n");
58         return true;
59     }
60     for (i = 0; i < tokenLen; i++) {
61         if (*(token + i)) {
62             return false;
63         }
64     }
65     return true;
66 }
67 
ScramblingTimestamp(const void * in,void * out,uint32_t dataLen,const void * key,uint32_t keyLen)68 static TeecResult ScramblingTimestamp(const void *in, void *out,
69     uint32_t dataLen, const void *key, uint32_t keyLen)
70 {
71     uint32_t i;
72     bool checkValue = false;
73 
74     if (in == NULL || out == NULL || key == NULL) {
75         tloge("bad parameters, input_data is null\n");
76         return TEEC_ERROR_BAD_PARAMETERS;
77     }
78     checkValue = (dataLen == 0 || dataLen > SECUREC_MEM_MAX_LEN ||
79             keyLen > SECUREC_MEM_MAX_LEN || keyLen == 0);
80     if (checkValue) {
81         tloge("bad parameters, dataLen is %u, scrambling_len is %u\n",
82               dataLen, keyLen);
83         return TEEC_ERROR_BAD_PARAMETERS;
84     }
85     for (i = 0; i < dataLen; i++) {
86         *((uint8_t *)out + i) =
87             *((uint8_t *)in + i) ^ *((uint8_t *)key + i % keyLen);
88     }
89 
90     return TEEC_SUCCESS;
91 }
92 
ChangeTimeStamp(uint8_t flag,uint64_t * timeStamp)93 static int32_t ChangeTimeStamp(uint8_t flag, uint64_t *timeStamp)
94 {
95     if (flag == INC) {
96         if (*timeStamp < UINT64_MAX) {
97             (*timeStamp)++;
98         } else {
99             tloge("val overflow\n");
100             return -EFAULT;
101         }
102     } else if (flag == DEC) {
103         if (*timeStamp > 0) {
104             (*timeStamp)--;
105         } else {
106             tloge("val down overflow\n");
107             return -EFAULT;
108         }
109     } else {
110         tloge("flag error , 0x%x\n", flag);
111         return -EFAULT;
112     }
113     return EOK;
114 }
115 
DescramblingTimestamp(uint8_t * inTokenBuf,const struct SessionSecureInfo * secureInfo,uint8_t flag)116 static int32_t DescramblingTimestamp(uint8_t *inTokenBuf,
117     const struct SessionSecureInfo *secureInfo, uint8_t flag)
118 {
119     uint64_t timeStamp = 0;
120     int32_t ret;
121 
122     if (inTokenBuf == NULL || secureInfo == NULL) {
123         tloge("invalid params!\n");
124         return -EINVAL;
125     }
126     if (ScramblingTimestamp(&inTokenBuf[TIMESTAMP_BUFFER_INDEX],
127         &timeStamp, TIMESTAMP_LEN_DEFAULT, secureInfo->scrambling, SCRAMBLING_KEY_LEN)) {
128         tloge("DescramblingTimestamp failed\n");
129         return -EFAULT;
130     }
131     ret = ChangeTimeStamp(flag, &timeStamp);
132     if (ret != EOK) {
133         return ret;
134     }
135 
136     tlogd("timestamp is %llu\n", timeStamp);
137     if (ScramblingTimestamp(&timeStamp, &inTokenBuf[TIMESTAMP_BUFFER_INDEX],
138         TIMESTAMP_LEN_DEFAULT, secureInfo->scrambling, SCRAMBLING_KEY_LEN)) {
139         tloge("DescramblingTimestamp failed\n");
140         return -EFAULT;
141     }
142     return EOK;
143 }
144 
UpdateTimestamp(const TcNsSmcCmd * cmd)145 TeecResult UpdateTimestamp(const TcNsSmcCmd *cmd)
146 {
147     TcNsSession *session = NULL;
148     struct SessionSecureInfo *secureInfo = NULL;
149     uint8_t *tokenBuffer = NULL;
150     bool filterFlag = false;
151     bool needCheckFlag = false;
152 
153     if (cmd == NULL) {
154         tloge("cmd is NULL, error!");
155         return TEEC_ERROR_BAD_PARAMETERS;
156     }
157     /* if cmd is agent, not check uuid. and sometime uuid canot access it */
158     filterFlag = (cmd->agentId != 0) ||
159             (cmd->retVal == TEEC_PENDING2_AGENT);
160     if (filterFlag) {
161         return TEEC_SUCCESS;
162     }
163 
164     needCheckFlag = (cmd->globalCmd == false) && (cmd->agentId == 0) &&
165         (cmd->retVal != TEEC_PENDING2_AGENT);
166     if (needCheckFlag) {
167         tokenBuffer = (void *)LOS_PaddrToKVaddr((paddr_t)(cmd->tokenPhys));
168         if (tokenBuffer == NULL ||
169             IsTokenEmpty(tokenBuffer, TOKEN_BUFFER_LEN)) {
170             tloge("token is NULL or token is empyt, error!\n");
171             return TEEC_ERROR_GENERIC;
172         }
173 
174         session = TcFindSession2(cmd->devFileId, cmd);
175         if (session == NULL) {
176             tlogd("tc_find_session_key find session FAILURE\n");
177             return TEEC_ERROR_GENERIC;
178         }
179         secureInfo = &session->secureInfo;
180         if (DescramblingTimestamp(tokenBuffer, secureInfo, INC) != EOK) {
181             PutSessionStruct(session);
182             tloge("update tokenBuffer error\n");
183             return TEEC_ERROR_GENERIC;
184         }
185         PutSessionStruct(session);
186         tokenBuffer[SYNC_INDEX] = UN_SYNCED;
187     } else {
188         tlogd("global cmd or agent, do not update timestamp\n");
189     }
190     return TEEC_SUCCESS;
191 }
192 
SyncTimestamp(const TcNsSmcCmd * cmd,uint8_t * token,uint32_t tokenLen,bool global)193 TeecResult SyncTimestamp(const TcNsSmcCmd *cmd, uint8_t *token,
194     uint32_t tokenLen, bool global)
195 {
196     TcNsSession *session = NULL;
197     bool checkVal = false;
198 
199     checkVal = (cmd == NULL || token == NULL || tokenLen <= SYNC_INDEX);
200     if (checkVal) {
201         tloge("parameters is NULL, error!\n");
202         return TEEC_ERROR_BAD_PARAMETERS;
203     }
204     if (cmd->cmdId == GLOBAL_CMD_ID_OPEN_SESSION && global) {
205         tlogd("OpenSession would not need sync timestamp\n");
206         return TEEC_SUCCESS;
207     }
208 
209     if (token[SYNC_INDEX] == UN_SYNCED) {
210         tlogd("flag is UN_SYNC, to sync timestamp!\n");
211 
212         session = TcFindSession2(cmd->devFileId, cmd);
213         if (session == NULL) {
214             tloge("SyncTimestamp find session FAILURE\n");
215             return TEEC_ERROR_GENERIC;
216         }
217         if (DescramblingTimestamp(token, &session->secureInfo, DEC) != EOK) {
218             PutSessionStruct(session);
219             tloge("sync tokenBuffer error\n");
220             return TEEC_ERROR_GENERIC;
221         }
222         PutSessionStruct(session);
223         return TEEC_SUCCESS;
224     } else if (token[SYNC_INDEX] == IS_SYNCED) {
225         return TEEC_SUCCESS;
226     } else {
227         tloge("sync flag error! 0x%x\n", token[SYNC_INDEX]);
228     }
229     return TEEC_ERROR_GENERIC;
230 }
231 
232 /* scrambling operation and pid */
ScramblingOperation(TcNsSmcCmd * cmd,uint32_t scrambler)233 static void ScramblingOperation(TcNsSmcCmd *cmd, uint32_t scrambler)
234 {
235     if (cmd == NULL) {
236         return;
237     }
238     if (cmd->operationPhys != 0 || cmd->operationHphys != 0) {
239         cmd->operationPhys = cmd->operationPhys ^ scrambler;
240         cmd->operationHphys = cmd->operationHphys ^ scrambler;
241     }
242     cmd->pid = cmd->pid ^ scrambler;
243 }
244 
AgentMsg(uint32_t cmdId)245 static bool AgentMsg(uint32_t cmdId)
246 {
247     bool agent = cmdId == GLOBAL_CMD_ID_SSA ||
248         cmdId == GLOBAL_CMD_ID_MT ||
249         cmdId == GLOBAL_CMD_ID_MT_UPDATE;
250 
251     return agent;
252 }
253 
254 /* calculate cmd checksum and scrambling operation */
UpdateChksum(TcNsSmcCmd * cmd)255 TeecResult UpdateChksum(TcNsSmcCmd *cmd)
256 {
257     TcNsSession *session = NULL;
258     struct SessionSecureInfo *secureInfo = NULL;
259     uint32_t ScramblerOper;
260     bool checkValue = false;
261 
262     if (cmd == NULL) {
263         tloge("cmd is NULL, error\n");
264         return TEEC_ERROR_BAD_PARAMETERS;
265     }
266     /*
267      * if cmd is agent, do not check uuid.
268      * and sometimes uuid cannot access it
269      */
270     checkValue = (cmd->agentId != 0 || cmd->retVal == TEEC_PENDING2_AGENT);
271     if (checkValue == true) {
272         return TEEC_SUCCESS;
273     }
274 
275     if (AgentMsg(cmd->cmdId)) {
276         tlogd("SSA cmd, no need to UpdateChksum\n");
277         return TEEC_SUCCESS;
278     }
279     /* cmd is invoke command */
280     checkValue = (cmd->globalCmd == false) && (cmd->agentId == 0) &&
281         (cmd->retVal != TEEC_PENDING2_AGENT);
282 
283     if (checkValue) {
284         session = TcFindSession2(cmd->devFileId, cmd);
285         if (session != NULL) {
286             secureInfo = &session->secureInfo;
287             ScramblerOper =
288                 secureInfo->scrambling[SCRAMBLING_OPERATION];
289             ScramblingOperation(cmd, ScramblerOper);
290             PutSessionStruct(session);
291         }
292     }
293     return TEEC_SUCCESS;
294 }
295 
VerifyChksum(const TcNsSmcCmd * cmd)296 TeecResult VerifyChksum(const TcNsSmcCmd *cmd)
297 {
298     TcNsSession *session = NULL;
299     bool checkFlag = false;
300 
301     if (cmd == NULL) {
302         tloge("cmd is NULL, error\n");
303         return TEEC_ERROR_BAD_PARAMETERS;
304     }
305     if (AgentMsg(cmd->cmdId)) {
306         tlogd("SSA cmd, no need to UpdateChksum\n");
307         return TEEC_SUCCESS;
308     }
309 
310     /* cmd is invoke command */
311     checkFlag = cmd->globalCmd == false &&
312             cmd->cmdId != GLOBAL_CMD_ID_CLOSE_SESSION &&
313             cmd->cmdId != GLOBAL_CMD_ID_KILL_TASK &&
314             cmd->agentId == 0;
315     if (checkFlag) {
316         session = TcFindSession2(cmd->devFileId, cmd);
317         if (session) {
318             PutSessionStruct(session);
319         }
320     }
321     return TEEC_SUCCESS;
322 }
323 #endif
324