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);