11b8d9b87Sopenharmony_ci/*
21b8d9b87Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
31b8d9b87Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41b8d9b87Sopenharmony_ci * you may not use this file except in compliance with the License.
51b8d9b87Sopenharmony_ci * You may obtain a copy of the License at
61b8d9b87Sopenharmony_ci *
71b8d9b87Sopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
81b8d9b87Sopenharmony_ci *
91b8d9b87Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101b8d9b87Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111b8d9b87Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121b8d9b87Sopenharmony_ci * See the License for the specific language governing permissions and
131b8d9b87Sopenharmony_ci * limitations under the License.
141b8d9b87Sopenharmony_ci */
151b8d9b87Sopenharmony_ci
161b8d9b87Sopenharmony_ci#include "crypto_signature.h"
171b8d9b87Sopenharmony_ci#include <string.h>
181b8d9b87Sopenharmony_ci#include <stdlib.h>
191b8d9b87Sopenharmony_ci#include "signature.h"
201b8d9b87Sopenharmony_ci#include "memory.h"
211b8d9b87Sopenharmony_ci#include "crypto_common.h"
221b8d9b87Sopenharmony_ci#include "blob.h"
231b8d9b87Sopenharmony_ci#include "object_base.h"
241b8d9b87Sopenharmony_ci#include "result.h"
251b8d9b87Sopenharmony_ci#include "native_common.h"
261b8d9b87Sopenharmony_ci
271b8d9b87Sopenharmony_cistruct OH_CryptoVerify {
281b8d9b87Sopenharmony_ci    HcfObjectBase base;
291b8d9b87Sopenharmony_ci
301b8d9b87Sopenharmony_ci    HcfResult (*init)(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey);
311b8d9b87Sopenharmony_ci
321b8d9b87Sopenharmony_ci    HcfResult (*update)(HcfVerify *self, HcfBlob *data);
331b8d9b87Sopenharmony_ci
341b8d9b87Sopenharmony_ci    bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData);
351b8d9b87Sopenharmony_ci
361b8d9b87Sopenharmony_ci    HcfResult (*recover)(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData);
371b8d9b87Sopenharmony_ci
381b8d9b87Sopenharmony_ci    const char *(*getAlgoName)(HcfVerify *self);
391b8d9b87Sopenharmony_ci
401b8d9b87Sopenharmony_ci    HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen);
411b8d9b87Sopenharmony_ci
421b8d9b87Sopenharmony_ci    HcfResult (*getVerifySpecString)(HcfVerify *self, SignSpecItem item, char **returnString);
431b8d9b87Sopenharmony_ci
441b8d9b87Sopenharmony_ci    HcfResult (*getVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t *returnInt);
451b8d9b87Sopenharmony_ci
461b8d9b87Sopenharmony_ci    HcfResult (*setVerifySpecUint8Array)(HcfVerify *self, SignSpecItem item, HcfBlob blob);
471b8d9b87Sopenharmony_ci};
481b8d9b87Sopenharmony_ci
491b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_Create(const char *algoName, OH_CryptoVerify **verify)
501b8d9b87Sopenharmony_ci{
511b8d9b87Sopenharmony_ci    if (verify == NULL) {
521b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
531b8d9b87Sopenharmony_ci    }
541b8d9b87Sopenharmony_ci    HcfResult ret = HcfVerifyCreate(algoName, (HcfVerify **)verify);
551b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
561b8d9b87Sopenharmony_ci}
571b8d9b87Sopenharmony_ci
581b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_Init(OH_CryptoVerify *ctx, OH_CryptoPubKey *pubKey)
591b8d9b87Sopenharmony_ci{
601b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (ctx->init == NULL) || (pubKey == NULL)) {
611b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
621b8d9b87Sopenharmony_ci    }
631b8d9b87Sopenharmony_ci    HcfResult ret = ctx->init((HcfVerify *)ctx, NULL, (HcfPubKey *)pubKey);
641b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
651b8d9b87Sopenharmony_ci}
661b8d9b87Sopenharmony_ci
671b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_Update(OH_CryptoVerify *ctx, Crypto_DataBlob *in)
681b8d9b87Sopenharmony_ci{
691b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (ctx->update == NULL) || (in == NULL)) {
701b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
711b8d9b87Sopenharmony_ci    }
721b8d9b87Sopenharmony_ci    HcfResult ret = ctx->update((HcfVerify *)ctx, (HcfBlob *)in);
731b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
741b8d9b87Sopenharmony_ci}
751b8d9b87Sopenharmony_ci
761b8d9b87Sopenharmony_cibool OH_CryptoVerify_Final(OH_CryptoVerify *ctx, Crypto_DataBlob *in, Crypto_DataBlob *signData)
771b8d9b87Sopenharmony_ci{
781b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (ctx->verify == NULL) || (signData == NULL)) {
791b8d9b87Sopenharmony_ci        return false;
801b8d9b87Sopenharmony_ci    }
811b8d9b87Sopenharmony_ci    bool ret = ctx->verify((HcfVerify *)ctx, (HcfBlob *)in, (HcfBlob *)signData);
821b8d9b87Sopenharmony_ci    if (ret != true) {
831b8d9b87Sopenharmony_ci        return false;
841b8d9b87Sopenharmony_ci    }
851b8d9b87Sopenharmony_ci
861b8d9b87Sopenharmony_ci    return ret;
871b8d9b87Sopenharmony_ci}
881b8d9b87Sopenharmony_ci
891b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_Recover(OH_CryptoVerify *ctx, Crypto_DataBlob *signData,
901b8d9b87Sopenharmony_ci    Crypto_DataBlob *rawSignData)
911b8d9b87Sopenharmony_ci{
921b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (ctx->recover == NULL) || (signData == NULL) || (rawSignData == NULL)) {
931b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
941b8d9b87Sopenharmony_ci    }
951b8d9b87Sopenharmony_ci    HcfResult ret = ctx->recover((HcfVerify *)ctx, (HcfBlob *)signData, (HcfBlob *)rawSignData);
961b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
971b8d9b87Sopenharmony_ci}
981b8d9b87Sopenharmony_ci
991b8d9b87Sopenharmony_ciconst char *OH_CryptoVerify_GetAlgoName(OH_CryptoVerify *ctx)
1001b8d9b87Sopenharmony_ci{
1011b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
1021b8d9b87Sopenharmony_ci        return NULL;
1031b8d9b87Sopenharmony_ci    }
1041b8d9b87Sopenharmony_ci    return ctx->getAlgoName((HcfVerify *)ctx);
1051b8d9b87Sopenharmony_ci}
1061b8d9b87Sopenharmony_ci
1071b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_SetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
1081b8d9b87Sopenharmony_ci    Crypto_DataBlob *value)
1091b8d9b87Sopenharmony_ci{
1101b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (value == NULL)) {
1111b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
1121b8d9b87Sopenharmony_ci    }
1131b8d9b87Sopenharmony_ci    HcfResult ret = HCF_INVALID_PARAMS;
1141b8d9b87Sopenharmony_ci    switch (type) {
1151b8d9b87Sopenharmony_ci        case CRYPTO_PSS_SALT_LEN_INT:
1161b8d9b87Sopenharmony_ci        case CRYPTO_PSS_TRAILER_FIELD_INT:
1171b8d9b87Sopenharmony_ci            if ((value->data == NULL) || (value->len != sizeof(int32_t)) || (ctx->setVerifySpecInt == NULL)) {
1181b8d9b87Sopenharmony_ci                ret = HCF_INVALID_PARAMS;
1191b8d9b87Sopenharmony_ci                break;
1201b8d9b87Sopenharmony_ci            }
1211b8d9b87Sopenharmony_ci            ret = ctx->setVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, *((int32_t *)value->data));
1221b8d9b87Sopenharmony_ci            break;
1231b8d9b87Sopenharmony_ci        case CRYPTO_SM2_USER_ID_DATABLOB:
1241b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MGF1_NAME_STR:
1251b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MGF_NAME_STR:
1261b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MD_NAME_STR:
1271b8d9b87Sopenharmony_ci            if (ctx->setVerifySpecUint8Array == NULL) {
1281b8d9b87Sopenharmony_ci                ret = HCF_INVALID_PARAMS;
1291b8d9b87Sopenharmony_ci                break;
1301b8d9b87Sopenharmony_ci            }
1311b8d9b87Sopenharmony_ci            ret = ctx->setVerifySpecUint8Array((HcfVerify *)ctx, (SignSpecItem)type, *((HcfBlob *)value));
1321b8d9b87Sopenharmony_ci            break;
1331b8d9b87Sopenharmony_ci        default:
1341b8d9b87Sopenharmony_ci            return CRYPTO_INVALID_PARAMS;
1351b8d9b87Sopenharmony_ci    }
1361b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
1371b8d9b87Sopenharmony_ci}
1381b8d9b87Sopenharmony_ci
1391b8d9b87Sopenharmony_ciOH_Crypto_ErrCode OH_CryptoVerify_GetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
1401b8d9b87Sopenharmony_ci    Crypto_DataBlob *value)
1411b8d9b87Sopenharmony_ci{
1421b8d9b87Sopenharmony_ci    if ((ctx == NULL) || (value == NULL)) {
1431b8d9b87Sopenharmony_ci        return CRYPTO_INVALID_PARAMS;
1441b8d9b87Sopenharmony_ci    }
1451b8d9b87Sopenharmony_ci    int32_t *returnInt = NULL;
1461b8d9b87Sopenharmony_ci    char *returnStr = NULL;
1471b8d9b87Sopenharmony_ci    HcfResult ret = HCF_INVALID_PARAMS;
1481b8d9b87Sopenharmony_ci    switch (type) {
1491b8d9b87Sopenharmony_ci        case CRYPTO_PSS_SALT_LEN_INT:
1501b8d9b87Sopenharmony_ci        case CRYPTO_PSS_TRAILER_FIELD_INT:
1511b8d9b87Sopenharmony_ci        case CRYPTO_SM2_USER_ID_DATABLOB:
1521b8d9b87Sopenharmony_ci            if (ctx->getVerifySpecInt == NULL) {
1531b8d9b87Sopenharmony_ci                ret = HCF_INVALID_PARAMS;
1541b8d9b87Sopenharmony_ci                break;
1551b8d9b87Sopenharmony_ci            }
1561b8d9b87Sopenharmony_ci            returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
1571b8d9b87Sopenharmony_ci            if (returnInt == NULL) {
1581b8d9b87Sopenharmony_ci                return CRYPTO_MEMORY_ERROR;
1591b8d9b87Sopenharmony_ci            }
1601b8d9b87Sopenharmony_ci            ret = ctx->getVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, returnInt);
1611b8d9b87Sopenharmony_ci            if (ret != HCF_SUCCESS) {
1621b8d9b87Sopenharmony_ci                HcfFree(returnInt);
1631b8d9b87Sopenharmony_ci                break;
1641b8d9b87Sopenharmony_ci            }
1651b8d9b87Sopenharmony_ci            value->data = (uint8_t *)returnInt;
1661b8d9b87Sopenharmony_ci            value->len = sizeof(int32_t);
1671b8d9b87Sopenharmony_ci            break;
1681b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MD_NAME_STR:
1691b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MGF_NAME_STR:
1701b8d9b87Sopenharmony_ci        case CRYPTO_PSS_MGF1_NAME_STR:
1711b8d9b87Sopenharmony_ci            if (ctx->getVerifySpecString == NULL) {
1721b8d9b87Sopenharmony_ci                ret = HCF_INVALID_PARAMS;
1731b8d9b87Sopenharmony_ci                break;
1741b8d9b87Sopenharmony_ci            }
1751b8d9b87Sopenharmony_ci            ret = ctx->getVerifySpecString((HcfVerify *)ctx, (SignSpecItem)type, &returnStr);
1761b8d9b87Sopenharmony_ci            if (ret != HCF_SUCCESS) {
1771b8d9b87Sopenharmony_ci                break;
1781b8d9b87Sopenharmony_ci            }
1791b8d9b87Sopenharmony_ci            value->data = (uint8_t *)returnStr;
1801b8d9b87Sopenharmony_ci            value->len = strlen(returnStr);
1811b8d9b87Sopenharmony_ci            break;
1821b8d9b87Sopenharmony_ci        default:
1831b8d9b87Sopenharmony_ci            return CRYPTO_INVALID_PARAMS;
1841b8d9b87Sopenharmony_ci    }
1851b8d9b87Sopenharmony_ci    return GetOhCryptoErrCode(ret);
1861b8d9b87Sopenharmony_ci}
1871b8d9b87Sopenharmony_ci
1881b8d9b87Sopenharmony_ci
1891b8d9b87Sopenharmony_civoid OH_CryptoVerify_Destroy(OH_CryptoVerify *ctx)
1901b8d9b87Sopenharmony_ci{
1911b8d9b87Sopenharmony_ci    if (ctx == NULL || ctx->base.destroy == NULL) {
1921b8d9b87Sopenharmony_ci        return;
1931b8d9b87Sopenharmony_ci    }
1941b8d9b87Sopenharmony_ci    ctx->base.destroy((HcfObjectBase *)ctx);
1951b8d9b87Sopenharmony_ci}
196