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).
10 #include <sys/ioctl.h>
11 #include <machine/endian.h>
13 #include <crypto/cryptodev.h>
14 #include <openssl/bn.h>
23 int crid
= CRYPTO_FLAG_HARDWARE
;
32 fd
= open(_PATH_DEV
"crypto", O_RDWR
, 0);
34 err(1, _PATH_DEV
"crypto");
35 if (fcntl(fd
, F_SETFD
, 1) == -1)
36 err(1, "fcntl(F_SETFD) (devcrypto)");
42 crlookup(const char *devname
)
44 struct crypt_find_op find
;
47 strlcpy(find
.name
, devname
, sizeof(find
.name
));
48 if (ioctl(devcrypto(), CIOCFINDDEV
, &find
) == -1)
49 err(1, "ioctl(CIOCFINDDEV)");
56 static struct crypt_find_op find
;
58 bzero(&find
, sizeof(find
));
60 if (ioctl(devcrypto(), CIOCFINDDEV
, &find
) == -1)
61 err(1, "ioctl(CIOCFINDDEV)");
66 * Convert a little endian byte string in 'p' that
67 * is 'plen' bytes long to a BIGNUM. If 'dst' is NULL,
68 * a new BIGNUM is allocated. Returns NULL on failure.
70 * XXX there has got to be a more efficient way to do
71 * this, but I haven't figured out enough of the OpenSSL
75 le_to_bignum(BIGNUM
*dst
, u_int8_t
*p
, int plen
)
83 if ((pd
= (u_int8_t
*)malloc(plen
)) == NULL
)
86 for (i
= 0; i
< plen
; i
++)
87 pd
[i
] = p
[plen
- i
- 1];
89 dst
= BN_bin2bn(pd
, plen
, dst
);
95 * Convert a BIGNUM to a little endian byte string.
96 * If 'rd' is NULL, allocate space for it, otherwise
97 * 'rd' is assumed to have room for BN_num_bytes(n)
98 * bytes. Returns NULL on failure.
101 bignum_to_le(BIGNUM
*n
, u_int8_t
*rd
)
104 int blen
= BN_num_bytes(n
);
109 rd
= (u_int8_t
*)malloc(blen
);
113 for (i
= 0, j
= 0; i
< n
->top
; i
++) {
114 for (k
= 0; k
< BN_BITS2
/ 8; k
++) {
117 rd
[j
+ k
] = n
->d
[i
] >> (k
* 8);
126 UB_mod_exp(BIGNUM
*res
, BIGNUM
*a
, BIGNUM
*b
, BIGNUM
*c
, BN_CTX
*ctx
)
128 struct crypt_kop kop
;
129 u_int8_t
*ale
, *ble
, *cle
;
130 static int crypto_fd
= -1;
132 if (crypto_fd
== -1 && ioctl(devcrypto(), CRIOGET
, &crypto_fd
) == -1)
135 if ((ale
= bignum_to_le(a
, NULL
)) == NULL
)
136 err(1, "bignum_to_le, a");
137 if ((ble
= bignum_to_le(b
, NULL
)) == NULL
)
138 err(1, "bignum_to_le, b");
139 if ((cle
= bignum_to_le(c
, NULL
)) == NULL
)
140 err(1, "bignum_to_le, c");
142 bzero(&kop
, sizeof(kop
));
143 kop
.crk_op
= CRK_MOD_EXP
;
147 kop
.crk_param
[0].crp_p
= ale
;
148 kop
.crk_param
[0].crp_nbits
= BN_num_bytes(a
) * 8;
149 kop
.crk_param
[1].crp_p
= ble
;
150 kop
.crk_param
[1].crp_nbits
= BN_num_bytes(b
) * 8;
151 kop
.crk_param
[2].crp_p
= cle
;
152 kop
.crk_param
[2].crp_nbits
= BN_num_bytes(c
) * 8;
153 kop
.crk_param
[3].crp_p
= cle
;
154 kop
.crk_param
[3].crp_nbits
= BN_num_bytes(c
) * 8;
156 if (ioctl(crypto_fd
, CIOCKEY2
, &kop
) == -1)
159 printf("device = %s\n", crfind(kop
.crk_crid
));
161 bzero(ale
, BN_num_bytes(a
));
163 bzero(ble
, BN_num_bytes(b
));
166 if (kop
.crk_status
!= 0) {
167 printf("error %d\n", kop
.crk_status
);
168 bzero(cle
, BN_num_bytes(c
));
172 res
= le_to_bignum(res
, cle
, BN_num_bytes(c
));
173 bzero(cle
, BN_num_bytes(c
));
176 err(1, "le_to_bignum");
183 show_result(a
, b
, c
, sw
, hw
)
184 BIGNUM
*a
, *b
, *c
, *sw
, *hw
;
189 BN_print_fp(stdout
, a
);
193 BN_print_fp(stdout
, b
);
197 BN_print_fp(stdout
, c
);
201 BN_print_fp(stdout
, sw
);
205 BN_print_fp(stdout
, hw
);
214 BIGNUM
*a
, *b
, *c
, *r1
, *r2
;
225 BN_pseudo_rand(a
, 1023, 0, 0);
226 BN_pseudo_rand(b
, 1023, 0, 0);
227 BN_pseudo_rand(c
, 1024, 0, 0);
229 if (BN_cmp(a
, c
) > 0) {
230 BIGNUM
*rem
= BN_new();
232 BN_mod(rem
, a
, c
, ctx
);
233 UB_mod_exp(r2
, rem
, b
, c
, ctx
);
236 UB_mod_exp(r2
, a
, b
, c
, ctx
);
238 BN_mod_exp(r1
, a
, b
, c
, ctx
);
240 if (BN_cmp(r1
, r2
) != 0) {
241 show_result(a
, b
, c
, r1
, r2
);
253 usage(const char* cmd
)
255 printf("usage: %s [-d dev] [-v] [count]\n", cmd
);
256 printf("count is the number of bignum ops to do\n");
258 printf("-d use specific device\n");
259 printf("-v be verbose\n");
264 main(int argc
, char *argv
[])
268 while ((c
= getopt(argc
, argv
, "d:v")) != -1) {
271 crid
= crlookup(optarg
);
280 argc
-= optind
, argv
+= optind
;
282 for (i
= 0; i
< 1000; i
++) {
283 fprintf(stderr
, "test %d\n", i
);