12ee81decSopenharmony_ci/*
22ee81decSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
32ee81decSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42ee81decSopenharmony_ci * you may not use this file except in compliance with the License.
52ee81decSopenharmony_ci * You may obtain a copy of the License at
62ee81decSopenharmony_ci *
72ee81decSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
82ee81decSopenharmony_ci *
92ee81decSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102ee81decSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112ee81decSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122ee81decSopenharmony_ci * See the License for the specific language governing permissions and
132ee81decSopenharmony_ci * limitations under the License.
142ee81decSopenharmony_ci */
152ee81decSopenharmony_ci
162ee81decSopenharmony_ci#include "dslm_inner_process.h"
172ee81decSopenharmony_ci
182ee81decSopenharmony_ci#include <stddef.h>
192ee81decSopenharmony_ci#include <stdint.h>
202ee81decSopenharmony_ci
212ee81decSopenharmony_ci#include "device_security_defines.h"
222ee81decSopenharmony_ci#include "utils_datetime.h"
232ee81decSopenharmony_ci#include "utils_log.h"
242ee81decSopenharmony_ci#include "utils_state_machine.h"
252ee81decSopenharmony_ci#include "dslm_core_defines.h"
262ee81decSopenharmony_ci#include "dslm_credential.h"
272ee81decSopenharmony_ci#include "dslm_crypto.h"
282ee81decSopenharmony_ci#include "dslm_messenger_wrapper.h"
292ee81decSopenharmony_ci#include "dslm_msg_utils.h"
302ee81decSopenharmony_ci#include "dslm_cred.h"
312ee81decSopenharmony_ci
322ee81decSopenharmony_ci#ifdef __cplusplus
332ee81decSopenharmony_ciextern "C" {
342ee81decSopenharmony_ci#endif
352ee81decSopenharmony_ci
362ee81decSopenharmony_ci#define NONCE_ALIVE_TIME 60000
372ee81decSopenharmony_ci
382ee81decSopenharmony_ciint32_t CheckAndGenerateChallenge(DslmDeviceInfo *device)
392ee81decSopenharmony_ci{
402ee81decSopenharmony_ci    if (device == NULL) {
412ee81decSopenharmony_ci        return ERR_INVALID_PARA;
422ee81decSopenharmony_ci    }
432ee81decSopenharmony_ci
442ee81decSopenharmony_ci    uint64_t curr = GetMillisecondSinceBoot();
452ee81decSopenharmony_ci    if ((curr <= device->nonceTimeStamp) || (curr - device->nonceTimeStamp > NONCE_ALIVE_TIME) || device->nonce == 0) {
462ee81decSopenharmony_ci        SECURITY_LOG_INFO("update nonce for device %{public}x", device->machine.machineId);
472ee81decSopenharmony_ci        RandomValue rand = {0};
482ee81decSopenharmony_ci        GenerateRandom(&rand, RANDOM_MAX_LEN);
492ee81decSopenharmony_ci        device->nonce = *(uint64_t *)&rand.value[0];
502ee81decSopenharmony_ci        device->nonceTimeStamp = curr;
512ee81decSopenharmony_ci    }
522ee81decSopenharmony_ci
532ee81decSopenharmony_ci    return SUCCESS;
542ee81decSopenharmony_ci}
552ee81decSopenharmony_ci
562ee81decSopenharmony_ciint32_t SendDeviceInfoRequest(DslmDeviceInfo *device)
572ee81decSopenharmony_ci{
582ee81decSopenharmony_ci    if (device == NULL) {
592ee81decSopenharmony_ci        return ERR_INVALID_PARA;
602ee81decSopenharmony_ci    }
612ee81decSopenharmony_ci
622ee81decSopenharmony_ci    MessageBuff *buff = NULL;
632ee81decSopenharmony_ci    int32_t ret = BuildDeviceSecInfoRequest(device->nonce, &buff);
642ee81decSopenharmony_ci    if (ret != SUCCESS) {
652ee81decSopenharmony_ci        return ERR_INVALID_PARA;
662ee81decSopenharmony_ci    }
672ee81decSopenharmony_ci    device->transNum++;
682ee81decSopenharmony_ci#ifndef L0_MINI
692ee81decSopenharmony_ci    // mini devices are not support yet
702ee81decSopenharmony_ci    SendMsgToDevice(device->transNum, &device->identity, buff->buff, buff->length);
712ee81decSopenharmony_ci#endif
722ee81decSopenharmony_ci    SECURITY_LOG_DEBUG("buff is %s", (char *)buff->buff);
732ee81decSopenharmony_ci    SECURITY_LOG_INFO("challenge is %{public}x***, transNum is %{public}u",
742ee81decSopenharmony_ci        (uint32_t)device->nonce, (uint32_t)device->transNum);
752ee81decSopenharmony_ci    FreeMessageBuff(buff);
762ee81decSopenharmony_ci    return SUCCESS;
772ee81decSopenharmony_ci}
782ee81decSopenharmony_ci
792ee81decSopenharmony_ciint32_t VerifyDeviceInfoResponse(DslmDeviceInfo *device, const MessageBuff *buff)
802ee81decSopenharmony_ci{
812ee81decSopenharmony_ci    if (device == NULL || buff == NULL) {
822ee81decSopenharmony_ci        return ERR_INVALID_PARA;
832ee81decSopenharmony_ci    }
842ee81decSopenharmony_ci
852ee81decSopenharmony_ci    DslmCredBuff *cred = NULL;
862ee81decSopenharmony_ci    uint64_t nonce = 0;
872ee81decSopenharmony_ci    uint32_t version = 0;
882ee81decSopenharmony_ci    int32_t ret;
892ee81decSopenharmony_ci
902ee81decSopenharmony_ci    do {
912ee81decSopenharmony_ci        // Parse the msg
922ee81decSopenharmony_ci        ret = ParseDeviceSecInfoResponse(buff, &nonce, &version, &cred);
932ee81decSopenharmony_ci        if (ret != SUCCESS) {
942ee81decSopenharmony_ci            SECURITY_LOG_ERROR("ParseDeviceSecInfoResponse failed, ret is %{public}d", ret);
952ee81decSopenharmony_ci            break;
962ee81decSopenharmony_ci        }
972ee81decSopenharmony_ci        device->version = version;
982ee81decSopenharmony_ci        if (nonce != device->nonce || nonce == 0) {
992ee81decSopenharmony_ci            ret = ERR_CHALLENGE_ERR;
1002ee81decSopenharmony_ci            SECURITY_LOG_ERROR("nonce not equal");
1012ee81decSopenharmony_ci            DestroyDslmCred(cred);
1022ee81decSopenharmony_ci            break;
1032ee81decSopenharmony_ci        }
1042ee81decSopenharmony_ci#ifdef L2_STANDARD
1052ee81decSopenharmony_ci        uint64_t curr = GetMillisecondSinceBoot();
1062ee81decSopenharmony_ci        if ((curr <= device->nonceTimeStamp) || (curr - device->nonceTimeStamp > NONCE_ALIVE_TIME)) {
1072ee81decSopenharmony_ci            ret = ERR_CHALLENGE_ERR;
1082ee81decSopenharmony_ci            SECURITY_LOG_ERROR("nonce expired");
1092ee81decSopenharmony_ci            DestroyDslmCred(cred);
1102ee81decSopenharmony_ci            break;
1112ee81decSopenharmony_ci        }
1122ee81decSopenharmony_ci#endif // L2_STANDARD
1132ee81decSopenharmony_ci        // process
1142ee81decSopenharmony_ci        ret = DefaultVerifyDslmCred(&device->identity, device->nonce, cred, &device->credInfo);
1152ee81decSopenharmony_ci        DestroyDslmCred(cred);
1162ee81decSopenharmony_ci    } while (0);
1172ee81decSopenharmony_ci
1182ee81decSopenharmony_ci    SECURITY_LOG_INFO("challenge is %{public}x***, ret is %{public}d", (uint32_t)nonce, ret);
1192ee81decSopenharmony_ci    return ret;
1202ee81decSopenharmony_ci}
1212ee81decSopenharmony_ci
1222ee81decSopenharmony_ci#ifdef __cplusplus
1232ee81decSopenharmony_ci}
1242ee81decSopenharmony_ci#endif
125