1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include "crypt_types.h"
21 #include "crypt_eal_pkey.h" // Header file for key exchange.
22 #include "bsl_sal.h"
23 #include "bsl_err.h"
24 #include "crypt_eal_init.h"
25 #include "crypt_algid.h"
26 #include "crypt_errno.h"
27 #include "crypt_eal_rand.h"
28
StdMalloc(uint32_t len)29 void *StdMalloc(uint32_t len) {
30 return malloc((size_t)len);
31 }
32
PrintLastError(void)33 void PrintLastError(void) {
34 const char *file = NULL;
35 uint32_t line = 0;
36 BSL_ERR_GetLastErrorFileLine(&file, &line);
37 printf("failed at file %s at line %d\n", file, line);
38 }
39
main(void)40 int main(void)
41 {
42 int ret;
43
44 uint8_t prikey[] =
45 {0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, 0x14, 0x63, 0x2e, 0xea, 0xe0,
46 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34};
47 uint8_t pubkey[] =
48 {0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, 0x65, 0x64, 0x0d, 0xb9,
49 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87,
50 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5,
51 0x94, 0x8d, 0x46, 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac};
52 uint8_t resSharekey[] =
53 {0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, 0x34, 0xfb, 0xdd, 0x2d, 0x25,
54 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b};
55
56 CRYPT_EAL_PkeyPrv prvKey = {0};
57 CRYPT_EAL_PkeyPub pubKey = {0};
58 uint32_t shareLen;
59 uint8_t *shareKey;
60 CRYPT_EAL_PkeyCtx *prvCtx = NULL;
61 CRYPT_EAL_PkeyCtx *pubCtx = NULL;
62 CRYPT_PKEY_ParaId id = CRYPT_ECC_NISTP256;
63
64 BSL_ERR_Init(); // Initialize the error code module.
65 /**
66 * Before calling the algorithm APIs,
67 * call the BSL_SAL_CallBack_Ctrl function to register the malloc and free functions.
68 * Execute this step only once. If the memory allocation ability of Linux is available,
69 * the two functions can be registered using Linux by default.
70 */
71 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc);
72 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free);
73 ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER);
74 if (ret != CRYPT_SUCCESS) {
75 printf("CRYPT_EAL_Init: error code is %x\n", ret);
76 goto EXIT;
77 }
78
79 prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH);
80 pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH);
81 if (prvCtx == NULL || pubCtx == NULL) {
82 goto EXIT;
83 }
84
85 // Set the curve parameters.
86 ret = CRYPT_EAL_PkeySetParaById(prvCtx, id);
87 if (ret != CRYPT_SUCCESS) {
88 printf("error code is %x\n", ret);
89 PrintLastError();
90 goto EXIT;
91 }
92
93 // Set the private key of one end.
94 prvKey.id = CRYPT_PKEY_ECDH;
95 prvKey.key.eccPrv.len = sizeof(prikey);
96 prvKey.key.eccPrv.data = prikey;
97 ret = CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey);
98 if (ret != CRYPT_SUCCESS) {
99 printf("error code is %x\n", ret);
100 PrintLastError();
101 goto EXIT;
102 }
103
104 // Set the curve parameters.
105 ret = CRYPT_EAL_PkeySetParaById(pubCtx, id);
106 if (ret != CRYPT_SUCCESS) {
107 printf("error code is %x\n", ret);
108 PrintLastError();
109 goto EXIT;
110 }
111
112 // Set the public key of the other end.
113 pubKey.id = CRYPT_PKEY_ECDH;
114 pubKey.key.eccPub.len = sizeof(pubkey);
115 pubKey.key.eccPub.data = pubkey;
116 ret = CRYPT_EAL_PkeySetPub(pubCtx, &pubKey);
117 if (ret != CRYPT_SUCCESS) {
118 printf("error code is %x\n", ret);
119 PrintLastError();
120 goto EXIT;
121 }
122
123 // The shared key involves only the X axis. The length of the public key is not compressed in the returned results.
124 shareLen = CRYPT_EAL_PkeyGetKeyLen(prvCtx) / 2;
125 shareKey = (uint8_t *)BSL_SAL_Malloc(shareLen);
126 if (shareKey == NULL) {
127 ret = CRYPT_MEM_ALLOC_FAIL;
128 PrintLastError();
129 goto EXIT;
130 }
131 // Initialize the random number.
132 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL);
133 if (ret != CRYPT_SUCCESS) {
134 printf("RandInit: error code is %x\n", ret);
135 PrintLastError();
136 goto EXIT;
137 }
138
139 // Calculate the shared key.
140 ret = CRYPT_EAL_PkeyComputeShareKey(prvCtx, pubCtx, shareKey, &shareLen);
141 if (ret != CRYPT_SUCCESS) {
142 printf("error code is %x\n", ret);
143 PrintLastError();
144 goto EXIT;
145 }
146
147 // Compare the calculation result with the expected one.
148 if (shareLen != sizeof(resSharekey) || memcmp(shareKey, resSharekey, shareLen) != 0) {
149 printf("failed to compare test results\n");
150 ret = -1;
151 goto EXIT;
152 }
153
154 printf("pass \n");
155
156 EXIT:
157 // Release the context memory.
158 CRYPT_EAL_RandDeinit();
159 CRYPT_EAL_PkeyFreeCtx(prvCtx);
160 CRYPT_EAL_PkeyFreeCtx(pubCtx);
161 BSL_SAL_Free(shareKey);
162 BSL_ERR_DeInit();
163 return 0;
164 }