1/*
2 * Copyright (c) 2021 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 "hks_test_curve25519.h"
17#include "hks_api.h"
18#include "hks_param.h"
19#include "hks_test_log.h"
20#include "hks_type.h"
21#include "securec.h"
22
23#define TEST_ALIAS_ED25519 "test_ed25519"
24#define TEST_PLAIN_TEST_ED25519 "This is a plain text! Hello world and thanks for watching ED25519~"
25#define TEST_CURVE_256 256
26#define TEST_CURVE_512 512
27
28static uint8_t g_buffer[TEST_CURVE_256];
29static uint32_t g_bufferSize = TEST_CURVE_256;
30static uint8_t g_pubKey[TEST_CURVE_512] = {0};
31static uint32_t g_pubKeyLen = TEST_CURVE_512;
32
33int32_t TestGenerateEd25519Key(struct HksBlob alias)
34{
35    HKS_TEST_LOG_I("Test_GenerateEd25519!\n");
36    struct HksParamSet *paramSet = NULL;
37    int32_t ret = HksInitParamSet(&paramSet);
38    HKS_TEST_ASSERT(ret == 0);
39    struct HksParam algParam = {0};
40    algParam.tag = HKS_TAG_ALGORITHM;
41    algParam.uint32Param = HKS_ALG_ED25519;
42    ret = HksAddParams(paramSet, &algParam, 1);
43    HKS_TEST_ASSERT(ret == 0);
44    struct HksParam keySizeParam = {0};
45    keySizeParam.tag = HKS_TAG_KEY_SIZE;
46    keySizeParam.uint32Param = TEST_CURVE_256;
47    ret = HksAddParams(paramSet, &keySizeParam, 1);
48    HKS_TEST_ASSERT(ret == 0);
49    struct HksParam purposeParam = {0};
50    purposeParam.tag = HKS_TAG_PURPOSE;
51    purposeParam.uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY;
52    ret = HksAddParams(paramSet, &purposeParam, 1);
53    HKS_TEST_ASSERT(ret == 0);
54    struct HksParam digestParam = {0};
55    digestParam.tag = HKS_TAG_DIGEST;
56    digestParam.uint32Param = HKS_DIGEST_SHA512;
57    ret = HksAddParams(paramSet, &digestParam, 1);
58    HKS_TEST_ASSERT(ret == 0);
59    struct HksParam paddingParam = {0};
60    paddingParam.tag = HKS_TAG_PADDING;
61    paddingParam.uint32Param = HKS_PADDING_NONE;
62    ret = HksAddParams(paramSet, &paddingParam, 1);
63    HKS_TEST_ASSERT(ret == 0);
64    ret = HksBuildParamSet(&paramSet);
65    HKS_TEST_ASSERT(ret == 0);
66    ret = HksGenerateKey(&alias, paramSet, NULL);
67    HKS_TEST_ASSERT(ret == 0);
68    HksFreeParamSet(&paramSet);
69    return ret;
70}
71
72static int32_t TestSignEd25519(struct HksBlob alias)
73{
74    struct HksBlob msg = {strlen(TEST_PLAIN_TEST_ED25519), (uint8_t *)TEST_PLAIN_TEST_ED25519};
75
76    struct HksParamSet *paramSet = NULL;
77    int32_t ret = HksInitParamSet(&paramSet);
78    HKS_TEST_ASSERT(ret == 0);
79    struct HksParam algParam = {0};
80    algParam.tag = HKS_TAG_ALGORITHM;
81    algParam.uint32Param = HKS_ALG_ED25519;
82    ret = HksAddParams(paramSet, &algParam, 1);
83    HKS_TEST_ASSERT(ret == 0);
84    struct HksParam purposeParam = {0};
85    purposeParam.tag = HKS_TAG_PURPOSE;
86    purposeParam.uint32Param = HKS_KEY_PURPOSE_SIGN;
87    ret = HksAddParams(paramSet, &purposeParam, 1);
88    HKS_TEST_ASSERT(ret == 0);
89    struct HksParam digestParam = {0};
90    digestParam.tag = HKS_TAG_DIGEST;
91    digestParam.uint32Param = HKS_DIGEST_SHA512;
92    ret = HksAddParams(paramSet, &digestParam, 1);
93    HKS_TEST_ASSERT(ret == 0);
94    struct HksParam paddingParam = {0};
95    paddingParam.tag = HKS_TAG_PADDING;
96    paddingParam.uint32Param = HKS_PADDING_NONE;
97    ret = HksAddParams(paramSet, &paddingParam, 1);
98    HKS_TEST_ASSERT(ret == 0);
99    ret = HksBuildParamSet(&paramSet);
100    HKS_TEST_ASSERT(ret == 0);
101    struct HksBlob signature = { TEST_CURVE_256, g_buffer };
102    ret = HksSign(&alias, paramSet, &msg, &signature);
103    HKS_TEST_ASSERT(ret == 0);
104    g_bufferSize = signature.size;
105    HKS_TEST_LOG_I("TestSignEd25519 signature size is %u", signature.size);
106    HksFreeParamSet(&paramSet);
107    return ret;
108}
109
110static int32_t TestVerifyEd25519(struct HksBlob alias)
111{
112    struct HksBlob msg = {strlen(TEST_PLAIN_TEST_ED25519), (uint8_t *)TEST_PLAIN_TEST_ED25519};
113
114    HKS_TEST_LOG_I("TestVerifyEd25519!\n");
115    struct HksParamSet *paramSet = NULL;
116    int32_t ret = HksInitParamSet(&paramSet);
117    HKS_TEST_ASSERT(ret == 0);
118
119    struct HksParam algParam = {0};
120    algParam.tag = HKS_TAG_ALGORITHM;
121    algParam.uint32Param = HKS_ALG_ED25519;
122    ret = HksAddParams(paramSet, &algParam, 1);
123    HKS_TEST_ASSERT(ret == 0);
124
125    struct HksParam purposeParam = {0};
126    purposeParam.tag = HKS_TAG_PURPOSE;
127    purposeParam.uint32Param = HKS_KEY_PURPOSE_VERIFY;
128    ret = HksAddParams(paramSet, &purposeParam, 1);
129    HKS_TEST_ASSERT(ret == 0);
130
131    struct HksParam digestParam = {0};
132    digestParam.tag = HKS_TAG_DIGEST;
133    digestParam.uint32Param = HKS_DIGEST_SHA512;
134    ret = HksAddParams(paramSet, &digestParam, 1);
135    HKS_TEST_ASSERT(ret == 0);
136
137    struct HksParam paddingParam = {0};
138    paddingParam.tag = HKS_TAG_PADDING;
139    paddingParam.uint32Param = HKS_PADDING_NONE;
140    ret = HksAddParams(paramSet, &paddingParam, 1);
141    HKS_TEST_ASSERT(ret == 0);
142
143    ret = HksBuildParamSet(&paramSet);
144    HKS_TEST_ASSERT(ret == 0);
145
146    struct HksBlob signature = { g_bufferSize, g_buffer };
147    ret = HksVerify(&alias, paramSet, &msg, &signature);
148    HKS_TEST_ASSERT(ret == 0);
149    HksFreeParamSet(&paramSet);
150    return ret;
151}
152
153int32_t TestImportEd25519(struct HksBlob alias, struct HksBlob *pubKeyInfo)
154{
155    HKS_TEST_LOG_I("TestImportEd25519!\n");
156    struct HksParamSet *paramSet = NULL;
157    int32_t ret = HksInitParamSet(&paramSet);
158    HKS_TEST_ASSERT(ret == 0);
159
160    struct HksParam algParam = {0};
161    algParam.tag = HKS_TAG_ALGORITHM;
162    algParam.uint32Param = HKS_ALG_ED25519;
163    ret = HksAddParams(paramSet, &algParam, 1);
164    HKS_TEST_ASSERT(ret == 0);
165
166    struct HksParam keySizeParam = {0};
167    keySizeParam.tag = HKS_TAG_KEY_SIZE;
168    keySizeParam.uint32Param = TEST_CURVE_256;
169    ret = HksAddParams(paramSet, &keySizeParam, 1);
170    HKS_TEST_ASSERT(ret == 0);
171
172    struct HksParam purposeParam = {0};
173    purposeParam.tag = HKS_TAG_PURPOSE;
174    purposeParam.uint32Param = HKS_KEY_PURPOSE_VERIFY;
175    ret = HksAddParams(paramSet, &purposeParam, 1);
176    HKS_TEST_ASSERT(ret == 0);
177
178    struct HksParam digestParam = {0};
179    digestParam.tag = HKS_TAG_DIGEST;
180    digestParam.uint32Param = HKS_DIGEST_SHA512;
181    ret = HksAddParams(paramSet, &digestParam, 1);
182    HKS_TEST_ASSERT(ret == 0);
183
184    struct HksParam paddingParam = {0};
185    paddingParam.tag = HKS_TAG_PADDING;
186    paddingParam.uint32Param = HKS_PADDING_NONE;
187    ret = HksAddParams(paramSet, &paddingParam, 1);
188    HKS_TEST_ASSERT(ret == 0);
189
190    ret = HksBuildParamSet(&paramSet);
191    HKS_TEST_ASSERT(ret == 0);
192
193    ret = HksImportKey(&alias, paramSet, pubKeyInfo);
194    HKS_TEST_ASSERT(ret == 0);
195    HksFreeParamSet(&paramSet);
196    return ret;
197}
198
199static int32_t TestExportImportEd25519SignVerify(struct HksBlob alias)
200{
201    uint8_t pubKey[32] = {0};
202    uint32_t pubKeyLen = 32;
203    struct HksBlob pubKeyInfo = { pubKeyLen, pubKey };
204    int32_t ret = TestGenerateEd25519Key(alias);
205    HKS_TEST_ASSERT(ret == 0);
206
207    ret = HksExportPublicKey(&alias, NULL, &pubKeyInfo);
208    HKS_TEST_ASSERT(ret == 0);
209
210    ret = TestSignEd25519(alias);
211    HKS_TEST_ASSERT(ret == 0);
212
213    ret = HksDeleteKey(&alias, NULL);
214    HKS_TEST_ASSERT(ret == 0);
215
216    struct HksBlob newAlias = { strlen("test_ed25519_2"), (uint8_t *)"test_ed25519_2" };
217    ret = TestImportEd25519(newAlias, &pubKeyInfo);
218    HKS_TEST_ASSERT(ret == 0);
219    ret = TestVerifyEd25519(newAlias);
220    HKS_TEST_ASSERT(ret == 0);
221
222    ret = HksDeleteKey(&newAlias, NULL);
223    HKS_TEST_ASSERT(ret == 0);
224    return ret;
225}
226
227int32_t TestCurve25519All()
228{
229    struct HksBlob ed25519Alias = { strlen(TEST_ALIAS_ED25519), (uint8_t *)TEST_ALIAS_ED25519 };
230    int32_t ret = TestGenerateEd25519Key(ed25519Alias);
231    HKS_TEST_ASSERT(ret == 0);
232    ret = TestSignEd25519(ed25519Alias);
233    HKS_TEST_ASSERT(ret == 0);
234    ret = TestVerifyEd25519(ed25519Alias);
235    HKS_TEST_ASSERT(ret == 0);
236    ret = HksDeleteKey(&ed25519Alias, NULL);
237    HKS_TEST_ASSERT(ret == 0);
238
239    ret = TestExportImportEd25519SignVerify(ed25519Alias);
240    HKS_TEST_ASSERT(ret == 0);
241    return ret;
242}
243
244static int32_t BuildTeeSignParamSet(struct HksParamSet **paramSet)
245{
246    int32_t ret = HksInitParamSet(paramSet);
247    HKS_TEST_ASSERT(ret == 0);
248
249    struct HksParam algParam = {0};
250    algParam.tag = HKS_TAG_ALGORITHM;
251    algParam.uint32Param = HKS_ALG_ED25519;
252    ret = HksAddParams(*paramSet, &algParam, 1);
253    HKS_TEST_ASSERT(ret == 0);
254
255    struct HksParam purposeParam = {0};
256    purposeParam.tag = HKS_TAG_PURPOSE;
257    purposeParam.uint32Param = HKS_KEY_PURPOSE_SIGN;
258    ret = HksAddParams(*paramSet, &purposeParam, 1);
259    HKS_TEST_ASSERT(ret == 0);
260
261    struct HksParam digestParam = {0};
262    digestParam.tag = HKS_TAG_DIGEST;
263    digestParam.uint32Param = HKS_DIGEST_SHA512;
264    ret = HksAddParams(*paramSet, &digestParam, 1);
265    HKS_TEST_ASSERT(ret == 0);
266
267    struct HksParam paddingParam = {0};
268    paddingParam.tag = HKS_TAG_PADDING;
269    paddingParam.uint32Param = HKS_PADDING_NONE;
270    ret = HksAddParams(*paramSet, &paddingParam, 1);
271    HKS_TEST_ASSERT(ret == 0);
272
273    ret = HksBuildParamSet(paramSet);
274    HKS_TEST_ASSERT(ret == 0);
275    return ret;
276}
277
278static int32_t BuildLocalVerifyParamSet(struct HksParamSet **paramSet)
279{
280    int32_t ret = HksInitParamSet(paramSet);
281    HKS_TEST_ASSERT(ret == 0);
282
283    struct HksParam algParam = {0};
284    algParam.tag = HKS_TAG_ALGORITHM;
285    algParam.uint32Param = HKS_ALG_ED25519;
286    ret = HksAddParams(*paramSet, &algParam, 1);
287    HKS_TEST_ASSERT(ret == 0);
288
289    struct HksParam isKeyAlias = {0};
290    isKeyAlias.tag = HKS_TAG_IS_KEY_ALIAS;
291    isKeyAlias.boolParam = false;
292    ret = HksAddParams(*paramSet, &isKeyAlias, 1);
293    HKS_TEST_ASSERT(ret == 0);
294
295    struct HksParam keySizeParam = {0};
296    keySizeParam.tag = HKS_TAG_KEY_SIZE;
297    keySizeParam.uint32Param = TEST_CURVE_256;
298    ret = HksAddParams(*paramSet, &keySizeParam, 1);
299    HKS_TEST_ASSERT(ret == 0);
300
301    struct HksParam purposeParam = {0};
302    purposeParam.tag = HKS_TAG_PURPOSE;
303    purposeParam.uint32Param = HKS_KEY_PURPOSE_VERIFY;
304    ret = HksAddParams(*paramSet, &purposeParam, 1);
305    HKS_TEST_ASSERT(ret == 0);
306
307    struct HksParam digestParam = {0};
308    digestParam.tag = HKS_TAG_DIGEST;
309    digestParam.uint32Param = HKS_DIGEST_SHA512;
310    ret = HksAddParams(*paramSet, &digestParam, 1);
311    HKS_TEST_ASSERT(ret == 0);
312
313    ret = HksBuildParamSet(paramSet);
314    HKS_TEST_ASSERT(ret == 0);
315    return ret;
316}
317
318int32_t TestEd25519SignTeeVerifyLocal()
319{
320    HKS_TEST_LOG_D("TestEd25519SignTeeVerifyLocal enter!");
321
322    struct HksBlob ed25519Alias = { strlen(TEST_ALIAS_ED25519), (uint8_t *)TEST_ALIAS_ED25519 };
323    struct HksBlob msg = {strlen(TEST_PLAIN_TEST_ED25519), (uint8_t *)TEST_PLAIN_TEST_ED25519};
324    struct HksBlob signature = { TEST_CURVE_256, g_buffer };
325    struct HksParamSet *paramSetSign = NULL;
326    struct HksParamSet *paramSetVerify = NULL;
327    struct HksBlob pubKeyInfo = { g_pubKeyLen, g_pubKey };
328
329    int32_t ret = TestGenerateEd25519Key(ed25519Alias);
330    HKS_TEST_ASSERT(ret == 0);
331
332    ret = HksExportPublicKey(&ed25519Alias, NULL, &pubKeyInfo);
333    HKS_TEST_ASSERT(ret == 0);
334    HKS_TEST_LOG_I("HksExportPublicKey puKey size is %u", pubKeyInfo.size);
335
336    ret = BuildTeeSignParamSet(&paramSetSign);
337    HKS_TEST_ASSERT(ret == 0);
338    ret = HksSign(&ed25519Alias, paramSetSign, &msg, &signature);
339    HKS_TEST_ASSERT(ret == 0);
340    HKS_TEST_LOG_I("Test_Ed25519_Sign_TEE signature size is %u", signature.size);
341
342    ret = BuildLocalVerifyParamSet(&paramSetVerify);
343    HKS_TEST_ASSERT(ret == 0);
344    ret = HksVerify(&pubKeyInfo, paramSetVerify, &msg, &signature);
345    HKS_TEST_ASSERT(ret == 0);
346    HKS_TEST_LOG_I("Test_Ed25519_Verify_Local Success");
347
348    ret = HksDeleteKey(&ed25519Alias, NULL);
349    HKS_TEST_ASSERT(ret == 0);
350
351    HksFreeParamSet(&paramSetSign);
352    HksFreeParamSet(&paramSetVerify);
353    HKS_TEST_LOG_D("TestEd25519SignTeeVerifyLocal End!\n");
354    return ret;
355}
356
357static int32_t TestSignEd25519Wrong(struct HksBlob alias)
358{
359    struct HksBlob msg = {strlen(TEST_PLAIN_TEST_ED25519), (uint8_t *)TEST_PLAIN_TEST_ED25519};
360
361    struct HksParamSet *paramSet = NULL;
362    int32_t ret = HksInitParamSet(&paramSet);
363    HKS_TEST_ASSERT(ret == 0);
364    struct HksParam algParam = {0};
365    algParam.tag = HKS_TAG_ALGORITHM;
366    algParam.uint32Param = HKS_ALG_ED25519;
367    ret = HksAddParams(paramSet, &algParam, 1);
368    HKS_TEST_ASSERT(ret == 0);
369    struct HksParam purposeParam = {0};
370    purposeParam.tag = HKS_TAG_PURPOSE;
371    purposeParam.uint32Param = HKS_KEY_PURPOSE_VERIFY;
372    ret = HksAddParams(paramSet, &purposeParam, 1);
373    HKS_TEST_ASSERT(ret == 0);
374    struct HksParam digestParam = {0};
375    digestParam.tag = HKS_TAG_DIGEST;
376    digestParam.uint32Param = HKS_DIGEST_SHA256;
377    ret = HksAddParams(paramSet, &digestParam, 1);
378    HKS_TEST_ASSERT(ret == 0);
379    struct HksParam paddingParam = {0};
380    paddingParam.tag = HKS_TAG_PADDING;
381    paddingParam.uint32Param = HKS_PADDING_PKCS5;
382    ret = HksAddParams(paramSet, &paddingParam, 1);
383    HKS_TEST_ASSERT(ret == 0);
384    ret = HksBuildParamSet(&paramSet);
385    HKS_TEST_ASSERT(ret == 0);
386    struct HksBlob signature = { TEST_CURVE_256, g_buffer };
387    ret = HksSign(&alias, paramSet, &msg, &signature);
388    HKS_TEST_ASSERT(ret != 0);
389    g_bufferSize = signature.size;
390    HKS_TEST_LOG_I("TestSignEd25519 signature size is %u", signature.size);
391    HksFreeParamSet(&paramSet);
392    return ret;
393}
394
395int32_t TestCurve25519SignWrong()
396{
397    struct HksBlob ed25519Alias = { strlen(TEST_ALIAS_ED25519), (uint8_t *)TEST_ALIAS_ED25519 };
398    int32_t ret = TestGenerateEd25519Key(ed25519Alias);
399    HKS_TEST_ASSERT(ret == 0);
400    ret = TestSignEd25519Wrong(ed25519Alias);
401    HKS_TEST_ASSERT(ret != 0);
402    int32_t retTwo = HksDeleteKey(&ed25519Alias, NULL);
403    HKS_TEST_ASSERT(retTwo == 0);
404    if ((ret != 0) && (retTwo == 0)) {
405        return 0;
406    }
407    return 1;
408}
409
410static int32_t TestVerifyEd25519Wrong(struct HksBlob alias)
411{
412    struct HksBlob msg = {strlen(TEST_PLAIN_TEST_ED25519), (uint8_t *)TEST_PLAIN_TEST_ED25519};
413
414    HKS_TEST_LOG_I("TestVerifyEd25519!\n");
415    struct HksParamSet *paramSet = NULL;
416    int32_t ret = HksInitParamSet(&paramSet);
417    HKS_TEST_ASSERT(ret == 0);
418
419    struct HksParam algParam = {0};
420    algParam.tag = HKS_TAG_ALGORITHM;
421    algParam.uint32Param = HKS_ALG_ED25519;
422    ret = HksAddParams(paramSet, &algParam, 1);
423    HKS_TEST_ASSERT(ret == 0);
424
425    struct HksParam purposeParam = {0};
426    purposeParam.tag = HKS_TAG_PURPOSE;
427    purposeParam.uint32Param = HKS_KEY_PURPOSE_SIGN;
428    ret = HksAddParams(paramSet, &purposeParam, 1);
429    HKS_TEST_ASSERT(ret == 0);
430
431    struct HksParam digestParam = {0};
432    digestParam.tag = HKS_TAG_DIGEST;
433    digestParam.uint32Param = HKS_DIGEST_SHA256;
434    ret = HksAddParams(paramSet, &digestParam, 1);
435    HKS_TEST_ASSERT(ret == 0);
436
437    struct HksParam paddingParam = {0};
438    paddingParam.tag = HKS_TAG_PADDING;
439    paddingParam.uint32Param = HKS_PADDING_PKCS5;
440    ret = HksAddParams(paramSet, &paddingParam, 1);
441    HKS_TEST_ASSERT(ret == 0);
442
443    ret = HksBuildParamSet(&paramSet);
444    HKS_TEST_ASSERT(ret == 0);
445
446    struct HksBlob signature = { g_bufferSize, g_buffer };
447    ret = HksVerify(&alias, paramSet, &msg, &signature);
448    HKS_TEST_ASSERT(ret != 0);
449    HksFreeParamSet(&paramSet);
450    return ret;
451}
452
453int32_t TestCurve25519verifyWrong()
454{
455    struct HksBlob ed25519Alias = { strlen(TEST_ALIAS_ED25519), (uint8_t *)TEST_ALIAS_ED25519 };
456    int32_t ret = TestGenerateEd25519Key(ed25519Alias);
457    HKS_TEST_ASSERT(ret == 0);
458    ret = TestSignEd25519(ed25519Alias);
459    HKS_TEST_ASSERT(ret == 0);
460    ret = TestVerifyEd25519Wrong(ed25519Alias);
461    HKS_TEST_ASSERT(ret != 0);
462    int32_t retTwo = HksDeleteKey(&ed25519Alias, NULL);
463    HKS_TEST_ASSERT(retTwo == 0);
464    if ((ret != 0) && (retTwo == 0)) {
465        return 0;
466    }
467    return 1;
468}