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 
27 struct 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 
OH_CryptoVerify_Create(const char * algoName,OH_CryptoVerify ** verify)49 OH_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 
OH_CryptoVerify_Init(OH_CryptoVerify * ctx,OH_CryptoPubKey * pubKey)58 OH_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 
OH_CryptoVerify_Update(OH_CryptoVerify * ctx,Crypto_DataBlob * in)67 OH_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 
OH_CryptoVerify_Final(OH_CryptoVerify * ctx,Crypto_DataBlob * in,Crypto_DataBlob * signData)76 bool 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 
OH_CryptoVerify_Recover(OH_CryptoVerify * ctx,Crypto_DataBlob * signData,Crypto_DataBlob * rawSignData)89 OH_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 
OH_CryptoVerify_GetAlgoName(OH_CryptoVerify * ctx)99 const 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 
OH_CryptoVerify_SetParam(OH_CryptoVerify * ctx,CryptoSignature_ParamType type,Crypto_DataBlob * value)107 OH_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 
OH_CryptoVerify_GetParam(OH_CryptoVerify * ctx,CryptoSignature_ParamType type,Crypto_DataBlob * value)139 OH_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 
OH_CryptoVerify_Destroy(OH_CryptoVerify * ctx)189 void 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