1/*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *    http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "crypto_signature.h"
17#include <string.h>
18#include <stdlib.h>
19#include "signature.h"
20#include "memory.h"
21#include "crypto_common.h"
22#include "blob.h"
23#include "object_base.h"
24#include "result.h"
25#include "native_common.h"
26
27struct OH_CryptoVerify {
28    HcfObjectBase base;
29
30    HcfResult (*init)(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey);
31
32    HcfResult (*update)(HcfVerify *self, HcfBlob *data);
33
34    bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData);
35
36    HcfResult (*recover)(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData);
37
38    const char *(*getAlgoName)(HcfVerify *self);
39
40    HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen);
41
42    HcfResult (*getVerifySpecString)(HcfVerify *self, SignSpecItem item, char **returnString);
43
44    HcfResult (*getVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t *returnInt);
45
46    HcfResult (*setVerifySpecUint8Array)(HcfVerify *self, SignSpecItem item, HcfBlob blob);
47};
48
49OH_Crypto_ErrCode OH_CryptoVerify_Create(const char *algoName, OH_CryptoVerify **verify)
50{
51    if (verify == NULL) {
52        return CRYPTO_INVALID_PARAMS;
53    }
54    HcfResult ret = HcfVerifyCreate(algoName, (HcfVerify **)verify);
55    return GetOhCryptoErrCode(ret);
56}
57
58OH_Crypto_ErrCode OH_CryptoVerify_Init(OH_CryptoVerify *ctx, OH_CryptoPubKey *pubKey)
59{
60    if ((ctx == NULL) || (ctx->init == NULL) || (pubKey == NULL)) {
61        return CRYPTO_INVALID_PARAMS;
62    }
63    HcfResult ret = ctx->init((HcfVerify *)ctx, NULL, (HcfPubKey *)pubKey);
64    return GetOhCryptoErrCode(ret);
65}
66
67OH_Crypto_ErrCode OH_CryptoVerify_Update(OH_CryptoVerify *ctx, Crypto_DataBlob *in)
68{
69    if ((ctx == NULL) || (ctx->update == NULL) || (in == NULL)) {
70        return CRYPTO_INVALID_PARAMS;
71    }
72    HcfResult ret = ctx->update((HcfVerify *)ctx, (HcfBlob *)in);
73    return GetOhCryptoErrCode(ret);
74}
75
76bool OH_CryptoVerify_Final(OH_CryptoVerify *ctx, Crypto_DataBlob *in, Crypto_DataBlob *signData)
77{
78    if ((ctx == NULL) || (ctx->verify == NULL) || (signData == NULL)) {
79        return false;
80    }
81    bool ret = ctx->verify((HcfVerify *)ctx, (HcfBlob *)in, (HcfBlob *)signData);
82    if (ret != true) {
83        return false;
84    }
85
86    return ret;
87}
88
89OH_Crypto_ErrCode OH_CryptoVerify_Recover(OH_CryptoVerify *ctx, Crypto_DataBlob *signData,
90    Crypto_DataBlob *rawSignData)
91{
92    if ((ctx == NULL) || (ctx->recover == NULL) || (signData == NULL) || (rawSignData == NULL)) {
93        return CRYPTO_INVALID_PARAMS;
94    }
95    HcfResult ret = ctx->recover((HcfVerify *)ctx, (HcfBlob *)signData, (HcfBlob *)rawSignData);
96    return GetOhCryptoErrCode(ret);
97}
98
99const char *OH_CryptoVerify_GetAlgoName(OH_CryptoVerify *ctx)
100{
101    if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
102        return NULL;
103    }
104    return ctx->getAlgoName((HcfVerify *)ctx);
105}
106
107OH_Crypto_ErrCode OH_CryptoVerify_SetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
108    Crypto_DataBlob *value)
109{
110    if ((ctx == NULL) || (value == NULL)) {
111        return CRYPTO_INVALID_PARAMS;
112    }
113    HcfResult ret = HCF_INVALID_PARAMS;
114    switch (type) {
115        case CRYPTO_PSS_SALT_LEN_INT:
116        case CRYPTO_PSS_TRAILER_FIELD_INT:
117            if ((value->data == NULL) || (value->len != sizeof(int32_t)) || (ctx->setVerifySpecInt == NULL)) {
118                ret = HCF_INVALID_PARAMS;
119                break;
120            }
121            ret = ctx->setVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, *((int32_t *)value->data));
122            break;
123        case CRYPTO_SM2_USER_ID_DATABLOB:
124        case CRYPTO_PSS_MGF1_NAME_STR:
125        case CRYPTO_PSS_MGF_NAME_STR:
126        case CRYPTO_PSS_MD_NAME_STR:
127            if (ctx->setVerifySpecUint8Array == NULL) {
128                ret = HCF_INVALID_PARAMS;
129                break;
130            }
131            ret = ctx->setVerifySpecUint8Array((HcfVerify *)ctx, (SignSpecItem)type, *((HcfBlob *)value));
132            break;
133        default:
134            return CRYPTO_INVALID_PARAMS;
135    }
136    return GetOhCryptoErrCode(ret);
137}
138
139OH_Crypto_ErrCode OH_CryptoVerify_GetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
140    Crypto_DataBlob *value)
141{
142    if ((ctx == NULL) || (value == NULL)) {
143        return CRYPTO_INVALID_PARAMS;
144    }
145    int32_t *returnInt = NULL;
146    char *returnStr = NULL;
147    HcfResult ret = HCF_INVALID_PARAMS;
148    switch (type) {
149        case CRYPTO_PSS_SALT_LEN_INT:
150        case CRYPTO_PSS_TRAILER_FIELD_INT:
151        case CRYPTO_SM2_USER_ID_DATABLOB:
152            if (ctx->getVerifySpecInt == NULL) {
153                ret = HCF_INVALID_PARAMS;
154                break;
155            }
156            returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
157            if (returnInt == NULL) {
158                return CRYPTO_MEMORY_ERROR;
159            }
160            ret = ctx->getVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, returnInt);
161            if (ret != HCF_SUCCESS) {
162                HcfFree(returnInt);
163                break;
164            }
165            value->data = (uint8_t *)returnInt;
166            value->len = sizeof(int32_t);
167            break;
168        case CRYPTO_PSS_MD_NAME_STR:
169        case CRYPTO_PSS_MGF_NAME_STR:
170        case CRYPTO_PSS_MGF1_NAME_STR:
171            if (ctx->getVerifySpecString == NULL) {
172                ret = HCF_INVALID_PARAMS;
173                break;
174            }
175            ret = ctx->getVerifySpecString((HcfVerify *)ctx, (SignSpecItem)type, &returnStr);
176            if (ret != HCF_SUCCESS) {
177                break;
178            }
179            value->data = (uint8_t *)returnStr;
180            value->len = strlen(returnStr);
181            break;
182        default:
183            return CRYPTO_INVALID_PARAMS;
184    }
185    return GetOhCryptoErrCode(ret);
186}
187
188
189void OH_CryptoVerify_Destroy(OH_CryptoVerify *ctx)
190{
191    if (ctx == NULL || ctx->base.destroy == NULL) {
192        return;
193    }
194    ctx->base.destroy((HcfObjectBase *)ctx);
195}
196