Skip to content

Commit b1f2e63

Browse files
ThePassionatexiaoxiang781216
authored andcommitted
testing/crypto: Add test cases for Diffie-Hellman algorithm
Signed-off-by: makejian <[email protected]>
1 parent ce58e85 commit b1f2e63

File tree

4 files changed

+333
-0
lines changed

4 files changed

+333
-0
lines changed

testing/crypto/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,18 @@ if(CONFIG_TESTING_CRYPTO)
145145
ecdsa.c)
146146
endif()
147147

148+
if(CONFIG_TESTING_CRYPTO_ECDH)
149+
nuttx_add_application(
150+
NAME
151+
dhm
152+
PRIORITY
153+
${CONFIG_TESTING_CRYPTO_PRIORITY}
154+
STACKSIZE
155+
${CONFIG_TESTING_CRYPTO_STACKSIZE}
156+
MODULE
157+
${CONFIG_TESTING_CRYPTO}
158+
SRCS
159+
dhm.c)
160+
endif()
161+
148162
endif()

testing/crypto/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ config TESTING_CRYPTO_ECDSA
4242
bool "ecdsa crypto test"
4343
default n
4444

45+
config TESTING_CRYPTO_ECDH
46+
bool "ecdh crypto test"
47+
default n
48+
4549
config TESTING_CRYPTO_PRIORITY
4650
int "crypto test task priority"
4751
default 100

testing/crypto/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ PROGNAME += ecdsa
6666
MAINSRC += ecdsa.c
6767
endif
6868

69+
ifeq ($(CONFIG_TESTING_CRYPTO_ECDH),y)
70+
PROGNAME += dhm
71+
MAINSRC += dhm.c
72+
endif
73+
6974
PRIORITY = $(CONFIG_TESTING_CRYPTO_PRIORITY)
7075
STACKSIZE = $(CONFIG_TESTING_CRYPTO_STACKSIZE)
7176
MODULE = $(CONFIG_TESTING_CRYPTO)

testing/crypto/dhm.c

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/****************************************************************************
2+
* apps/testing/crypto/dhm.c
3+
* Copyright (C) 2023 Xiaomi Corporation
4+
*
5+
* Licensed to the Apache Software Foundation (ASF) under one or more
6+
* contributor license agreements. See the NOTICE file distributed with
7+
* this work for additional information regarding copyright ownership. The
8+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance with the
10+
* License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17+
* License for the specific language governing permissions and limitations
18+
* under the License.
19+
****************************************************************************/
20+
21+
/****************************************************************************
22+
* Included Files
23+
****************************************************************************/
24+
25+
#include <err.h>
26+
#include <fcntl.h>
27+
#include <stddef.h>
28+
#include <stdio.h>
29+
#include <sys/ioctl.h>
30+
#include <crypto/cryptodev.h>
31+
32+
/****************************************************************************
33+
* Pre-processor Definitions
34+
****************************************************************************/
35+
36+
/* RFC 5114 section 2.1:
37+
* 1024-bit MODP Group with 160-bit Prime Order Subgroup
38+
*/
39+
40+
#define DHM_RFC5114_MODP_1024_P_BIN { \
41+
0xB1, 0x0B, 0x8F, 0x96, 0xA0, 0x80, 0xE0, 0x1D, \
42+
0xDE, 0x92, 0xDE, 0x5E, 0xAE, 0x5D, 0x54, 0xEC, \
43+
0x52, 0xC9, 0x9F, 0xBC, 0xFB, 0x06, 0xA3, 0xC6, \
44+
0x9A, 0x6A, 0x9D, 0xCA, 0x52, 0xD2, 0x3B, 0x61, \
45+
0x60, 0x73, 0xE2, 0x86, 0x75, 0xA2, 0x3D, 0x18, \
46+
0x98, 0x38, 0xEF, 0x1E, 0x2E, 0xE6, 0x52, 0xC0, \
47+
0x13, 0xEC, 0xB4, 0xAE, 0xA9, 0x06, 0x11, 0x23, \
48+
0x24, 0x97, 0x5C, 0x3C, 0xD4, 0x9B, 0x83, 0xBF, \
49+
0xAC, 0xCB, 0xDD, 0x7D, 0x90, 0xC4, 0xBD, 0x70, \
50+
0x98, 0x48, 0x8E, 0x9C, 0x21, 0x9A, 0x73, 0x72, \
51+
0x4E, 0xFF, 0xD6, 0xFA, 0xE5, 0x64, 0x47, 0x38, \
52+
0xFA, 0xA3, 0x1A, 0x4F, 0xF5, 0x5B, 0xCC, 0xC0, \
53+
0xA1, 0x51, 0xAF, 0x5F, 0x0D, 0xC8, 0xB4, 0xBD, \
54+
0x45, 0xBF, 0x37, 0xDF, 0x36, 0x5C, 0x1A, 0x65, \
55+
0xE6, 0x8C, 0xFD, 0xA7, 0x6D, 0x4D, 0xA7, 0x08, \
56+
0xDF, 0x1F, 0xB2, 0xBC, 0x2E, 0x4A, 0x43, 0x71 }
57+
58+
#define DHM_RFC5114_MODP_1024_G_BIN { \
59+
0xA4, 0xD1, 0xCB, 0xD5, 0xC3, 0xFD, 0x34, 0x12, \
60+
0x67, 0x65, 0xA4, 0x42, 0xEF, 0xB9, 0x99, 0x05, \
61+
0xF8, 0x10, 0x4D, 0xD2, 0x58, 0xAC, 0x50, 0x7F, \
62+
0xD6, 0x40, 0x6C, 0xFF, 0x14, 0x26, 0x6D, 0x31, \
63+
0x26, 0x6F, 0xEA, 0x1E, 0x5C, 0x41, 0x56, 0x4B, \
64+
0x77, 0x7E, 0x69, 0x0F, 0x55, 0x04, 0xF2, 0x13, \
65+
0x16, 0x02, 0x17, 0xB4, 0xB0, 0x1B, 0x88, 0x6A, \
66+
0x5E, 0x91, 0x54, 0x7F, 0x9E, 0x27, 0x49, 0xF4, \
67+
0xD7, 0xFB, 0xD7, 0xD3, 0xB9, 0xA9, 0x2E, 0xE1, \
68+
0x90, 0x9D, 0x0D, 0x22, 0x63, 0xF8, 0x0A, 0x76, \
69+
0xA6, 0xA2, 0x4C, 0x08, 0x7A, 0x09, 0x1F, 0x53, \
70+
0x1D, 0xBF, 0x0A, 0x01, 0x69, 0xB6, 0xA2, 0x8A, \
71+
0xD6, 0x62, 0xA4, 0xD1, 0x8E, 0x73, 0xAF, 0xA3, \
72+
0x2D, 0x77, 0x9D, 0x59, 0x18, 0xD0, 0x8B, 0xC8, \
73+
0x85, 0x8F, 0x4D, 0xCE, 0xF9, 0x7C, 0x2A, 0x24, \
74+
0x85, 0x5E, 0x6E, 0xEB, 0x22, 0xB3, 0xB2, 0xE5 }
75+
76+
#define DHM_SIZE 128
77+
78+
/****************************************************************************
79+
* Private Types
80+
****************************************************************************/
81+
82+
typedef struct cryptodev_context
83+
{
84+
int fd;
85+
int cryptodev_fd;
86+
}
87+
cryptodev_context;
88+
89+
/****************************************************************************
90+
* Private Functions
91+
****************************************************************************/
92+
93+
static int match(FAR unsigned char *a, FAR unsigned char *b, size_t len)
94+
{
95+
int i;
96+
97+
if (memcmp(a, b, len) == 0)
98+
{
99+
return 0;
100+
}
101+
102+
perror("dhm mismatch");
103+
104+
for (i = 0; i < len; i++)
105+
{
106+
printf("%02x", a[i]);
107+
}
108+
109+
printf("\n");
110+
for (i = 0; i < len; i++)
111+
{
112+
printf("%02x", b[i]);
113+
}
114+
115+
printf("\n");
116+
117+
return 1;
118+
}
119+
120+
static void cryptodev_free(FAR cryptodev_context *ctx)
121+
{
122+
if (ctx->cryptodev_fd != 0)
123+
{
124+
close(ctx->cryptodev_fd);
125+
ctx->cryptodev_fd = 0;
126+
}
127+
128+
if (ctx->fd != 0)
129+
{
130+
close(ctx->fd);
131+
ctx->fd = 0;
132+
}
133+
}
134+
135+
static int cryptodev_init(FAR cryptodev_context *ctx)
136+
{
137+
memset(ctx, 0, sizeof(cryptodev_context));
138+
if ((ctx->fd = open("/dev/crypto", O_RDWR, 0)) < 0)
139+
{
140+
perror("cryptodev_init open /dev/crypto failed");
141+
cryptodev_free(ctx);
142+
return 1;
143+
}
144+
145+
if (ioctl(ctx->fd, CRIOGET, &ctx->cryptodev_fd) == -1)
146+
{
147+
perror("cryptodev_init CRIOGET failed");
148+
cryptodev_free(ctx);
149+
return 1;
150+
}
151+
152+
return 0;
153+
}
154+
155+
static int dh_make_public(FAR cryptodev_context *ctx,
156+
FAR const unsigned char *p, size_t p_size,
157+
FAR const unsigned char *g, size_t g_size,
158+
FAR unsigned char *x, size_t x_size,
159+
FAR unsigned char *gx, size_t gx_size)
160+
{
161+
struct crypt_kop cryptk;
162+
163+
memset(&cryptk, 0, sizeof(struct crypt_kop));
164+
cryptk.crk_op = CRK_DH_MAKE_PUBLIC;
165+
cryptk.crk_iparams = 2;
166+
cryptk.crk_oparams = 2;
167+
168+
/* inputs: g p
169+
* outputs: x gx
170+
*/
171+
172+
cryptk.crk_param[0].crp_p = (caddr_t) g;
173+
cryptk.crk_param[0].crp_nbits = g_size * 8;
174+
cryptk.crk_param[1].crp_p = (caddr_t) p;
175+
cryptk.crk_param[1].crp_nbits = p_size * 8;
176+
cryptk.crk_param[2].crp_p = (caddr_t) x;
177+
cryptk.crk_param[2].crp_nbits = x_size * 8;
178+
cryptk.crk_param[3].crp_p = (caddr_t) gx;
179+
cryptk.crk_param[3].crp_nbits = gx_size * 8;
180+
if (ioctl(ctx->cryptodev_fd, CIOCKEY, &cryptk) == -1)
181+
{
182+
perror("dh_make_public failed");
183+
return 1;
184+
}
185+
186+
return 0;
187+
}
188+
189+
static int dh_compute_key(FAR cryptodev_context *ctx,
190+
FAR const unsigned char *gy, size_t gy_size,
191+
FAR const unsigned char *x, size_t x_size,
192+
FAR const unsigned char *p, size_t p_size,
193+
FAR unsigned char *k, size_t k_size)
194+
{
195+
struct crypt_kop cryptk;
196+
197+
memset(&cryptk, 0, sizeof(struct crypt_kop));
198+
cryptk.crk_op = CRK_DH_COMPUTE_KEY;
199+
cryptk.crk_iparams = 3;
200+
cryptk.crk_oparams = 1;
201+
202+
/* inputs: pub_key priv_key p */
203+
204+
cryptk.crk_param[0].crp_p = (caddr_t) gy;
205+
cryptk.crk_param[0].crp_nbits = gy_size * 8;
206+
cryptk.crk_param[1].crp_p = (caddr_t) x;
207+
cryptk.crk_param[1].crp_nbits = x_size * 8;
208+
cryptk.crk_param[2].crp_p = (caddr_t) p;
209+
cryptk.crk_param[2].crp_nbits = p_size * 8;
210+
cryptk.crk_param[3].crp_p = (caddr_t) k;
211+
cryptk.crk_param[3].crp_nbits = k_size * 8;
212+
if (ioctl(ctx->cryptodev_fd, CIOCKEY, &cryptk) == -1)
213+
{
214+
perror("dh_compute_key failed");
215+
return 1;
216+
}
217+
218+
return 0;
219+
}
220+
221+
static int test_dh_compute_key(void)
222+
{
223+
int ret;
224+
cryptodev_context ctx;
225+
static const unsigned char dhm_p_1024[] =
226+
DHM_RFC5114_MODP_1024_P_BIN;
227+
static const unsigned char dhm_g_1024[] =
228+
DHM_RFC5114_MODP_1024_G_BIN;
229+
unsigned char x1[DHM_SIZE];
230+
unsigned char gx1[DHM_SIZE];
231+
unsigned char k1[DHM_SIZE];
232+
unsigned char x2[DHM_SIZE];
233+
unsigned char gx2[DHM_SIZE];
234+
unsigned char k2[DHM_SIZE];
235+
236+
ret = cryptodev_init(&ctx);
237+
if (ret != 0)
238+
{
239+
goto free;
240+
}
241+
242+
/* X-private key GX-pulic key K-share key */
243+
244+
memset(x1, 0, DHM_SIZE);
245+
memset(gx1, 0, DHM_SIZE);
246+
memset(k1, 0, DHM_SIZE);
247+
memset(x2, 0, DHM_SIZE);
248+
memset(gx2, 0, DHM_SIZE);
249+
memset(k2, 0, DHM_SIZE);
250+
251+
ret = dh_make_public(&ctx, dhm_p_1024, DHM_SIZE, dhm_g_1024,
252+
DHM_SIZE, x1, DHM_SIZE, gx1, DHM_SIZE);
253+
if (ret != 0)
254+
{
255+
printf("DH make Alice's public key failed\n");
256+
goto free;
257+
}
258+
259+
ret = dh_make_public(&ctx, dhm_p_1024, DHM_SIZE, dhm_g_1024,
260+
DHM_SIZE, x2, DHM_SIZE, gx2, DHM_SIZE);
261+
if (ret != 0)
262+
{
263+
printf("DH make Bob's public failed\n");
264+
goto free;
265+
}
266+
267+
ret = dh_compute_key(&ctx, gx2, DHM_SIZE, x1, DHM_SIZE,
268+
dhm_p_1024, DHM_SIZE, k1, DHM_SIZE);
269+
if (ret != 0)
270+
{
271+
printf("DH compute Alice's share key failed\n");
272+
goto free;
273+
}
274+
275+
ret = dh_compute_key(&ctx, gx1, DHM_SIZE, x2, DHM_SIZE,
276+
dhm_p_1024, DHM_SIZE, k2, DHM_SIZE);
277+
if (ret != 0)
278+
{
279+
printf("DH compute Bob's share key failed\n");
280+
goto free;
281+
}
282+
283+
ret = match(k1, k2, DHM_SIZE);
284+
if (ret != 0)
285+
{
286+
printf("mismatch share key\n");
287+
}
288+
289+
free:
290+
cryptodev_free(&ctx);
291+
return 0;
292+
}
293+
294+
/****************************************************************************
295+
* Public Functions
296+
****************************************************************************/
297+
298+
int main(void)
299+
{
300+
if (test_dh_compute_key() != 0)
301+
{
302+
printf("test dh compute key failed\n");
303+
}
304+
else
305+
{
306+
printf("test dh compute key ok\n");
307+
}
308+
309+
return 0;
310+
}

0 commit comments

Comments
 (0)