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_asym_key.h"
17 #include <string.h>
18 #include <stdlib.h>
19 #include "key_pair.h"
20 #include "memory.h"
21 #include "pub_key.h"
22 #include "result.h"
23 #include "blob.h"
24 #include "object_base.h"
25 #include "native_common.h"
26 #include "big_integer.h"
27 #include "asy_key_generator.h"
28
29
30 typedef struct OH_CryptoAsymKeyGenerator {
31 HcfObjectBase base;
32
33 HcfResult (*generateKeyPair)(HcfAsyKeyGenerator *self, HcfParamsSpec *params,
34 HcfKeyPair **returnKeyPair);
35
36 HcfResult (*convertKey)(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob,
37 HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair);
38
39 HcfResult (*convertPemKey)(HcfAsyKeyGenerator *self, HcfParamsSpec *params, const char *pubKeyStr,
40 const char *priKeyStr, HcfKeyPair **returnKeyPair);
41
42 const char *(*getAlgoName)(HcfAsyKeyGenerator *self);
43 } OH_CryptoAsymKeyGenerator;
44
45 typedef struct OH_CryptoKeyPair {
46 HcfObjectBase base;
47
48 HcfPriKey *priKey;
49
50 HcfPubKey *pubKey;
51 } OH_CryptoKeyPair;
52
53 typedef struct OH_CryptoPubKey {
54 HcfKey base;
55
56 HcfResult (*getAsyKeySpecBigInteger)(const HcfPubKey *self, const AsyKeySpecItem item,
57 HcfBigInteger *returnBigInteger);
58
59 HcfResult (*getAsyKeySpecString)(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString);
60
61 HcfResult (*getAsyKeySpecInt)(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt);
62
63 HcfResult (*getEncodedDer)(const HcfPubKey *self, const char *format, HcfBlob *returnBlob);
64 } OH_CryptoPubKey;
65
OH_CryptoAsymKeyGenerator_Create(const char * algoName,OH_CryptoAsymKeyGenerator ** ctx)66 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Create(const char *algoName, OH_CryptoAsymKeyGenerator **ctx)
67 {
68 if (ctx == NULL) {
69 return CRYPTO_INVALID_PARAMS;
70 }
71 HcfResult ret = HcfAsyKeyGeneratorCreate(algoName, (HcfAsyKeyGenerator **)ctx);
72 return GetOhCryptoErrCode(ret);
73 }
74
OH_CryptoAsymKeyGenerator_Generate(OH_CryptoAsymKeyGenerator * ctx,OH_CryptoKeyPair ** keyCtx)75 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Generate(OH_CryptoAsymKeyGenerator *ctx, OH_CryptoKeyPair **keyCtx)
76 {
77 if ((ctx == NULL) || (ctx->generateKeyPair == NULL) || (keyCtx == NULL)) {
78 return CRYPTO_INVALID_PARAMS;
79 }
80 HcfResult ret = ctx->generateKeyPair((HcfAsyKeyGenerator *)ctx, NULL, (HcfKeyPair **)keyCtx);
81 return GetOhCryptoErrCode(ret);
82 }
83
OH_CryptoAsymKeyGenerator_Convert(OH_CryptoAsymKeyGenerator * ctx,Crypto_EncodingType type,Crypto_DataBlob * pubKeyData,Crypto_DataBlob * priKeyData,OH_CryptoKeyPair ** keyCtx)84 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Convert(OH_CryptoAsymKeyGenerator *ctx, Crypto_EncodingType type,
85 Crypto_DataBlob *pubKeyData, Crypto_DataBlob *priKeyData, OH_CryptoKeyPair **keyCtx)
86 {
87 if ((ctx == NULL) || (pubKeyData == NULL && priKeyData == NULL) || (keyCtx == NULL)) {
88 return CRYPTO_INVALID_PARAMS;
89 }
90 HcfResult ret = HCF_SUCCESS;
91 const char *priKeyStr = (priKeyData == NULL)? NULL : (const char *)priKeyData->data;
92 const char *pubKeyStr = (pubKeyData == NULL)? NULL : (const char *)pubKeyData->data;
93 switch (type) {
94 case CRYPTO_PEM:
95 ret = ctx->convertPemKey == NULL ? HCF_INVALID_PARAMS :
96 ctx->convertPemKey((HcfAsyKeyGenerator *)ctx, NULL, pubKeyStr, priKeyStr, (HcfKeyPair **)keyCtx);
97 break;
98 case CRYPTO_DER:
99 ret = ctx->convertKey == NULL ? HCF_INVALID_PARAMS :
100 ctx->convertKey((HcfAsyKeyGenerator *)ctx, NULL, (HcfBlob *)pubKeyData,
101 (HcfBlob *)priKeyData, (HcfKeyPair **)keyCtx);
102 break;
103 default:
104 return CRYPTO_INVALID_PARAMS;
105 }
106 return GetOhCryptoErrCode(ret);
107 }
108
OH_CryptoAsymKeyGenerator_GetAlgoName(OH_CryptoAsymKeyGenerator * ctx)109 const char *OH_CryptoAsymKeyGenerator_GetAlgoName(OH_CryptoAsymKeyGenerator *ctx)
110 {
111 if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
112 return NULL;
113 }
114 return ctx->getAlgoName((HcfAsyKeyGenerator *)ctx);
115 }
116
OH_CryptoAsymKeyGenerator_Destroy(OH_CryptoAsymKeyGenerator * ctx)117 void OH_CryptoAsymKeyGenerator_Destroy(OH_CryptoAsymKeyGenerator *ctx)
118 {
119 if ((ctx == NULL) || (ctx->base.destroy == NULL)) {
120 return;
121 }
122 ctx->base.destroy((HcfObjectBase *)ctx);
123 }
124
OH_CryptoKeyPair_Destroy(OH_CryptoKeyPair * keyCtx)125 void OH_CryptoKeyPair_Destroy(OH_CryptoKeyPair *keyCtx)
126 {
127 if ((keyCtx == NULL) || (keyCtx->base.destroy == NULL)) {
128 return;
129 }
130 keyCtx->base.destroy((HcfObjectBase *)keyCtx);
131 }
132
OH_CryptoKeyPair_GetPubKey(OH_CryptoKeyPair * keyCtx)133 OH_CryptoPubKey *OH_CryptoKeyPair_GetPubKey(OH_CryptoKeyPair *keyCtx)
134 {
135 if (keyCtx == NULL) {
136 return NULL;
137 }
138 return (OH_CryptoPubKey *)keyCtx->pubKey;
139 }
140
OH_CryptoPubKey_Encode(OH_CryptoPubKey * key,Crypto_EncodingType type,const char * encodingStandard,Crypto_DataBlob * out)141 OH_Crypto_ErrCode OH_CryptoPubKey_Encode(OH_CryptoPubKey *key, Crypto_EncodingType type,
142 const char *encodingStandard, Crypto_DataBlob *out)
143 {
144 if ((key == NULL) || (out == NULL)) {
145 return CRYPTO_INVALID_PARAMS;
146 }
147 HcfResult ret = HCF_SUCCESS;
148 char *pemStr = NULL;
149 switch (type) {
150 case CRYPTO_PEM:
151 if (key->base.getEncodedPem == NULL) {
152 return CRYPTO_INVALID_PARAMS;
153 }
154 ret = key->base.getEncodedPem((HcfKey *)key, encodingStandard, &pemStr);
155 if (ret != HCF_SUCCESS) {
156 break;
157 }
158 out->data = (uint8_t *)pemStr;
159 out->len = strlen(pemStr);
160 break;
161 case CRYPTO_DER:
162 if (encodingStandard != NULL) {
163 ret = key->getEncodedDer == NULL ? HCF_INVALID_PARAMS :
164 key->getEncodedDer((HcfPubKey *)key, encodingStandard, (HcfBlob *)out);
165 break;
166 } else {
167 ret = key->base.getEncoded == NULL ? HCF_INVALID_PARAMS
168 : key->base.getEncoded((HcfKey *)key, (HcfBlob *)out);
169 break;
170 }
171 default:
172 return CRYPTO_INVALID_PARAMS;
173 }
174
175 return GetOhCryptoErrCode(ret);
176 }
177
OH_CryptoPubKey_GetParam(OH_CryptoPubKey * key,CryptoAsymKey_ParamType item,Crypto_DataBlob * value)178 OH_Crypto_ErrCode OH_CryptoPubKey_GetParam(OH_CryptoPubKey *key, CryptoAsymKey_ParamType item, Crypto_DataBlob *value)
179 {
180 if ((key == NULL) || (value == NULL)) {
181 return CRYPTO_INVALID_PARAMS;
182 }
183 HcfResult ret = HCF_SUCCESS;
184 int32_t *returnInt = NULL;
185 char *returnStr = NULL;
186 HcfBigInteger bigIntValue = {0};
187 switch (item) {
188 case CRYPTO_DH_L_INT:
189 case CRYPTO_ECC_H_INT:
190 case CRYPTO_ECC_FIELD_SIZE_INT:
191 returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
192 if (returnInt == NULL) {
193 ret = HCF_ERR_MALLOC;
194 break;
195 }
196 ret = key->getAsyKeySpecInt == NULL ? HCF_INVALID_PARAMS :
197 key->getAsyKeySpecInt((HcfPubKey *)key, (AsyKeySpecItem)item, returnInt);
198 if (ret != HCF_SUCCESS) {
199 HcfFree(returnInt);
200 break;
201 }
202 value->data = (uint8_t *)returnInt;
203 value->len = sizeof(int32_t);
204 break;
205 case CRYPTO_ECC_FIELD_TYPE_STR:
206 case CRYPTO_ECC_CURVE_NAME_STR:
207 ret = key->getAsyKeySpecString == NULL ? HCF_INVALID_PARAMS :
208 key->getAsyKeySpecString((HcfPubKey *)key, (AsyKeySpecItem)item, &returnStr);
209 if (ret != HCF_SUCCESS) {
210 break;
211 }
212 value->data = (uint8_t *)returnStr;
213 value->len = strlen(returnStr);
214 break;
215 default:
216 ret = key->getAsyKeySpecBigInteger == NULL ? HCF_INVALID_PARAMS :
217 key->getAsyKeySpecBigInteger((HcfPubKey *)key, (AsyKeySpecItem)item, &bigIntValue);
218 if (ret != HCF_SUCCESS) {
219 break;
220 }
221 value->data = (uint8_t *)bigIntValue.data;
222 value->len = (size_t)bigIntValue.len;
223 break;
224 }
225 return GetOhCryptoErrCode(ret);
226 }
227