]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/crypto/cryptokeytest.c
Merge ^/vendor/llvm-project/release-10.x up to its last change (upstream
[FreeBSD/FreeBSD.git] / tools / tools / crypto / cryptokeytest.c
1 /* $FreeBSD$ */
2 /*
3  * The big num stuff is a bit broken at the moment and I've not yet fixed it.
4  * The symtom is that odd size big nums will fail.  Test code below (it only
5  * uses modexp currently).
6  * 
7  * --Jason L. Wright
8  */
9 #include <sys/types.h>
10 #include <sys/endian.h>
11 #include <sys/ioctl.h>
12 #include <sys/time.h>
13 #include <crypto/cryptodev.h>
14
15 #include <err.h>
16 #include <fcntl.h>
17 #include <paths.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include <openssl/bn.h>
23 #include <openssl/err.h>
24
25 int     crid = CRYPTO_FLAG_HARDWARE;
26 int     verbose = 0;
27
28 static int
29 devcrypto(void)
30 {
31         static int fd = -1;
32
33         if (fd < 0) {
34                 fd = open(_PATH_DEV "crypto", O_RDWR, 0);
35                 if (fd < 0)
36                         err(1, _PATH_DEV "crypto");
37                 if (fcntl(fd, F_SETFD, 1) == -1)
38                         err(1, "fcntl(F_SETFD) (devcrypto)");
39         }
40         return fd;
41 }
42
43 static int
44 crlookup(const char *devname)
45 {
46         struct crypt_find_op find;
47
48         find.crid = -1;
49         strlcpy(find.name, devname, sizeof(find.name));
50         if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
51                 err(1, "ioctl(CIOCFINDDEV)");
52         return find.crid;
53 }
54
55 static const char *
56 crfind(int crid)
57 {
58         static struct crypt_find_op find;
59
60         bzero(&find, sizeof(find));
61         find.crid = crid;
62         if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
63                 err(1, "ioctl(CIOCFINDDEV)");
64         return find.name;
65 }
66
67 /*
68  * Convert a little endian byte string in 'p' that is 'plen' bytes long to a
69  * BIGNUM.  A new BIGNUM is allocated.  Returns NULL on failure.
70  */
71 static BIGNUM *
72 le_to_bignum(BIGNUM *res, const void *p, int plen)
73 {
74
75         res = BN_lebin2bn(p, plen, res);
76         if (res == NULL)
77                 ERR_print_errors_fp(stderr);
78
79         return (res);
80 }
81
82 /*
83  * Convert a BIGNUM to a little endian byte string.  Space for BN_num_bytes(n)
84  * is allocated.
85  * Returns NULL on failure.
86  */
87 static void *
88 bignum_to_le(const BIGNUM *n)
89 {
90         int blen, error;
91         void *rd;
92
93         blen = BN_num_bytes(n);
94         if (blen == 0)
95                 return (NULL);
96
97         rd = malloc(blen);
98         if (rd == NULL)
99                 return (NULL);
100
101         error = BN_bn2lebinpad(n, rd, blen);
102         if (error < 0) {
103                 ERR_print_errors_fp(stderr);
104                 free(rd);
105                 return (NULL);
106         }
107
108         return (rd);
109 }
110
111 static int
112 UB_mod_exp(BIGNUM *res, const BIGNUM *a, const BIGNUM *b, const BIGNUM *c)
113 {
114         struct crypt_kop kop;
115         void *ale, *ble, *cle;
116         static int crypto_fd = -1;
117
118         if (crypto_fd == -1 && ioctl(devcrypto(), CRIOGET, &crypto_fd) == -1)
119                 err(1, "CRIOGET");
120
121         if ((ale = bignum_to_le(a)) == NULL)
122                 err(1, "bignum_to_le, a");
123         if ((ble = bignum_to_le(b)) == NULL)
124                 err(1, "bignum_to_le, b");
125         if ((cle = bignum_to_le(c)) == NULL)
126                 err(1, "bignum_to_le, c");
127
128         bzero(&kop, sizeof(kop));
129         kop.crk_op = CRK_MOD_EXP;
130         kop.crk_iparams = 3;
131         kop.crk_oparams = 1;
132         kop.crk_crid = crid;
133         kop.crk_param[0].crp_p = ale;
134         kop.crk_param[0].crp_nbits = BN_num_bytes(a) * 8;
135         kop.crk_param[1].crp_p = ble;
136         kop.crk_param[1].crp_nbits = BN_num_bytes(b) * 8;
137         kop.crk_param[2].crp_p = cle;
138         kop.crk_param[2].crp_nbits = BN_num_bytes(c) * 8;
139         kop.crk_param[3].crp_p = cle;
140         kop.crk_param[3].crp_nbits = BN_num_bytes(c) * 8;
141
142         if (ioctl(crypto_fd, CIOCKEY2, &kop) == -1)
143                 err(1, "CIOCKEY2");
144         if (verbose)
145                 printf("device = %s\n", crfind(kop.crk_crid));
146
147         explicit_bzero(ale, BN_num_bytes(a));
148         free(ale);
149         explicit_bzero(ble, BN_num_bytes(b));
150         free(ble);
151
152         if (kop.crk_status != 0) {
153                 printf("error %d\n", kop.crk_status);
154                 explicit_bzero(cle, BN_num_bytes(c));
155                 free(cle);
156                 return (-1);
157         } else {
158                 res = le_to_bignum(res, cle, BN_num_bytes(c));
159                 explicit_bzero(cle, BN_num_bytes(c));
160                 free(cle);
161                 if (res == NULL)
162                         err(1, "le_to_bignum");
163                 return (0);
164         }
165         return (0);
166 }
167
168 static void
169 show_result(const BIGNUM *a, const BIGNUM *b, const BIGNUM *c,
170     const BIGNUM *sw, const BIGNUM *hw)
171 {
172         printf("\n");
173
174         printf("A = ");
175         BN_print_fp(stdout, a);
176         printf("\n");
177
178         printf("B = ");
179         BN_print_fp(stdout, b);
180         printf("\n");
181
182         printf("C = ");
183         BN_print_fp(stdout, c);
184         printf("\n");
185
186         printf("sw= ");
187         BN_print_fp(stdout, sw);
188         printf("\n");
189
190         printf("hw= ");
191         BN_print_fp(stdout, hw);
192         printf("\n");
193
194         printf("\n");
195 }
196
197 static void
198 testit(void)
199 {
200         BIGNUM *a, *b, *c, *r1, *r2;
201         BN_CTX *ctx;
202
203         ctx = BN_CTX_new();
204
205         a = BN_new();
206         b = BN_new();
207         c = BN_new();
208         r1 = BN_new();
209         r2 = BN_new();
210
211         BN_pseudo_rand(a, 1023, 0, 0);
212         BN_pseudo_rand(b, 1023, 0, 0);
213         BN_pseudo_rand(c, 1024, 0, 0);
214
215         if (BN_cmp(a, c) > 0) {
216                 BIGNUM *rem = BN_new();
217
218                 BN_mod(rem, a, c, ctx);
219                 UB_mod_exp(r2, rem, b, c);
220                 BN_free(rem);
221         } else {
222                 UB_mod_exp(r2, a, b, c);
223         }
224         BN_mod_exp(r1, a, b, c, ctx);
225
226         if (BN_cmp(r1, r2) != 0) {
227                 show_result(a, b, c, r1, r2);
228         }
229
230         BN_free(r2);
231         BN_free(r1);
232         BN_free(c);
233         BN_free(b);
234         BN_free(a);
235         BN_CTX_free(ctx);
236 }
237
238 static void
239 usage(const char* cmd)
240 {
241         printf("usage: %s [-d dev] [-v] [count]\n", cmd);
242         printf("count is the number of bignum ops to do\n");
243         printf("\n");
244         printf("-d use specific device\n");
245         printf("-v be verbose\n");
246         exit(-1);
247 }
248
249 int
250 main(int argc, char *argv[])
251 {
252         int c, i;
253
254         while ((c = getopt(argc, argv, "d:v")) != -1) {
255                 switch (c) {
256                 case 'd':
257                         crid = crlookup(optarg);
258                         break;
259                 case 'v':
260                         verbose = 1;
261                         break;
262                 default:
263                         usage(argv[0]);
264                 }
265         }
266         argc -= optind, argv += optind;
267
268         for (i = 0; i < 1000; i++) {
269                 fprintf(stderr, "test %d\n", i);
270                 testit();
271         }
272         return (0);
273 }