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/endian.h>
11 #include <sys/ioctl.h>
13 #include <crypto/cryptodev.h>
22 #include <openssl/bn.h>
23 #include <openssl/err.h>
25 int crid = CRYPTO_FLAG_HARDWARE;
34 fd = open(_PATH_DEV "crypto", O_RDWR, 0);
36 err(1, _PATH_DEV "crypto");
37 if (fcntl(fd, F_SETFD, 1) == -1)
38 err(1, "fcntl(F_SETFD) (devcrypto)");
44 crlookup(const char *devname)
46 struct crypt_find_op find;
49 strlcpy(find.name, devname, sizeof(find.name));
50 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
51 err(1, "ioctl(CIOCFINDDEV)");
58 static struct crypt_find_op find;
60 bzero(&find, sizeof(find));
62 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
63 err(1, "ioctl(CIOCFINDDEV)");
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.
72 le_to_bignum(BIGNUM *res, const void *p, int plen)
75 res = BN_lebin2bn(p, plen, res);
77 ERR_print_errors_fp(stderr);
83 * Convert a BIGNUM to a little endian byte string. Space for BN_num_bytes(n)
85 * Returns NULL on failure.
88 bignum_to_le(const BIGNUM *n)
93 blen = BN_num_bytes(n);
101 error = BN_bn2lebinpad(n, rd, blen);
103 ERR_print_errors_fp(stderr);
112 UB_mod_exp(BIGNUM *res, const BIGNUM *a, const BIGNUM *b, const BIGNUM *c)
114 struct crypt_kop kop;
115 void *ale, *ble, *cle;
116 static int crypto_fd = -1;
118 if (crypto_fd == -1 && ioctl(devcrypto(), CRIOGET, &crypto_fd) == -1)
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");
128 bzero(&kop, sizeof(kop));
129 kop.crk_op = CRK_MOD_EXP;
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;
142 if (ioctl(crypto_fd, CIOCKEY2, &kop) == -1)
145 printf("device = %s\n", crfind(kop.crk_crid));
147 explicit_bzero(ale, BN_num_bytes(a));
149 explicit_bzero(ble, BN_num_bytes(b));
152 if (kop.crk_status != 0) {
153 printf("error %d\n", kop.crk_status);
154 explicit_bzero(cle, BN_num_bytes(c));
158 res = le_to_bignum(res, cle, BN_num_bytes(c));
159 explicit_bzero(cle, BN_num_bytes(c));
162 err(1, "le_to_bignum");
169 show_result(const BIGNUM *a, const BIGNUM *b, const BIGNUM *c,
170 const BIGNUM *sw, const BIGNUM *hw)
175 BN_print_fp(stdout, a);
179 BN_print_fp(stdout, b);
183 BN_print_fp(stdout, c);
187 BN_print_fp(stdout, sw);
191 BN_print_fp(stdout, hw);
200 BIGNUM *a, *b, *c, *r1, *r2;
211 BN_pseudo_rand(a, 1023, 0, 0);
212 BN_pseudo_rand(b, 1023, 0, 0);
213 BN_pseudo_rand(c, 1024, 0, 0);
215 if (BN_cmp(a, c) > 0) {
216 BIGNUM *rem = BN_new();
218 BN_mod(rem, a, c, ctx);
219 UB_mod_exp(r2, rem, b, c);
222 UB_mod_exp(r2, a, b, c);
224 BN_mod_exp(r1, a, b, c, ctx);
226 if (BN_cmp(r1, r2) != 0) {
227 show_result(a, b, c, r1, r2);
239 usage(const char* cmd)
241 printf("usage: %s [-d dev] [-v] [count]\n", cmd);
242 printf("count is the number of bignum ops to do\n");
244 printf("-d use specific device\n");
245 printf("-v be verbose\n");
250 main(int argc, char *argv[])
254 while ((c = getopt(argc, argv, "d:v")) != -1) {
257 crid = crlookup(optarg);
266 argc -= optind, argv += optind;
268 for (i = 0; i < 1000; i++) {
269 fprintf(stderr, "test %d\n", i);