1 /* $FreeBSD: src/tools/tools/crypto/cryptokeytest.c,v 1.1.2.1 2003/02/24 22:52:36 sam Exp $ */ 2 /* $DragonFly: src/tools/tools/crypto/cryptokeytest.c,v 1.2 2003/06/17 04:29:11 dillon Exp $ */ 3 /* 4 * The big num stuff is a bit broken at the moment and I've not yet fixed it. 5 * The symtom is that odd size big nums will fail. Test code below (it only 6 * uses modexp currently). 7 * 8 * --Jason L. Wright 9 */ 10 #include <sys/types.h> 11 #include <sys/ioctl.h> 12 #include <machine/endian.h> 13 #include <sys/time.h> 14 #include <crypto/cryptodev.h> 15 #include <openssl/bn.h> 16 #include <fcntl.h> 17 #include <err.h> 18 #include <string.h> 19 #include <unistd.h> 20 #include <stdlib.h> 21 22 static int crypto_fd = -1; 23 24 /* 25 * Convert a little endian byte string in 'p' that 26 * is 'plen' bytes long to a BIGNUM. If 'dst' is NULL, 27 * a new BIGNUM is allocated. Returns NULL on failure. 28 * 29 * XXX there has got to be a more efficient way to do 30 * this, but I haven't figured out enough of the OpenSSL 31 * magic. 32 */ 33 BIGNUM * 34 le_to_bignum(BIGNUM *dst, u_int8_t *p, int plen) 35 { 36 u_int8_t *pd; 37 int i; 38 39 if (plen == 0) 40 return (NULL); 41 42 if ((pd = (u_int8_t *)malloc(plen)) == NULL) 43 return (NULL); 44 45 for (i = 0; i < plen; i++) 46 pd[i] = p[plen - i - 1]; 47 48 dst = BN_bin2bn(pd, plen, dst); 49 free(pd); 50 return (dst); 51 } 52 53 /* 54 * Convert a BIGNUM to a little endian byte string. 55 * If 'rd' is NULL, allocate space for it, otherwise 56 * 'rd' is assumed to have room for BN_num_bytes(n) 57 * bytes. Returns NULL on failure. 58 */ 59 u_int8_t * 60 bignum_to_le(BIGNUM *n, u_int8_t *rd) 61 { 62 int i, j, k; 63 int blen = BN_num_bytes(n); 64 65 if (blen == 0) 66 return (NULL); 67 if (rd == NULL) 68 rd = (u_int8_t *)malloc(blen); 69 if (rd == NULL) 70 return (NULL); 71 72 for (i = 0, j = 0; i < n->top; i++) { 73 for (k = 0; k < BN_BITS2 / 8; k++) { 74 if ((j + k) >= blen) 75 goto out; 76 rd[j + k] = n->d[i] >> (k * 8); 77 } 78 j += BN_BITS2 / 8; 79 } 80 out: 81 return (rd); 82 } 83 84 int 85 UB_mod_exp(BIGNUM *res, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx) 86 { 87 struct crypt_kop kop; 88 u_int8_t *ale, *ble, *cle; 89 90 if (crypto_fd == -1) { 91 int fd, fdc = open("/dev/crypto", O_RDONLY); 92 93 if (fdc == -1) 94 err(1, "/dev/crypto"); 95 if (ioctl(fdc, CRIOGET, &fd) == -1) 96 err(1, "CRIOGET"); 97 close(fdc); 98 crypto_fd = fd; 99 } 100 101 if ((ale = bignum_to_le(a, NULL)) == NULL) 102 err(1, "bignum_to_le, a"); 103 if ((ble = bignum_to_le(b, NULL)) == NULL) 104 err(1, "bignum_to_le, b"); 105 if ((cle = bignum_to_le(c, NULL)) == NULL) 106 err(1, "bignum_to_le, c"); 107 108 bzero(&kop, sizeof(kop)); 109 kop.crk_op = CRK_MOD_EXP; 110 kop.crk_iparams = 3; 111 kop.crk_oparams = 1; 112 kop.crk_param[0].crp_p = ale; 113 kop.crk_param[0].crp_nbits = BN_num_bytes(a) * 8; 114 kop.crk_param[1].crp_p = ble; 115 kop.crk_param[1].crp_nbits = BN_num_bytes(b) * 8; 116 kop.crk_param[2].crp_p = cle; 117 kop.crk_param[2].crp_nbits = BN_num_bytes(c) * 8; 118 kop.crk_param[3].crp_p = cle; 119 kop.crk_param[3].crp_nbits = BN_num_bytes(c) * 8; 120 121 if (ioctl(crypto_fd, CIOCKEY, &kop) == -1) 122 err(1, "CIOCKEY"); 123 124 bzero(ale, BN_num_bytes(a)); 125 free(ale); 126 bzero(ble, BN_num_bytes(b)); 127 free(ble); 128 129 if (kop.crk_status != 0) { 130 printf("error %d\n", kop.crk_status); 131 bzero(cle, BN_num_bytes(c)); 132 free(cle); 133 return (-1); 134 } else { 135 res = le_to_bignum(res, cle, BN_num_bytes(c)); 136 bzero(cle, BN_num_bytes(c)); 137 free(cle); 138 if (res == NULL) 139 err(1, "le_to_bignum"); 140 return (0); 141 } 142 return (0); 143 } 144 145 void 146 show_result(a, b, c, sw, hw) 147 BIGNUM *a, *b, *c, *sw, *hw; 148 { 149 printf("\n"); 150 151 printf("A = "); 152 BN_print_fp(stdout, a); 153 printf("\n"); 154 155 printf("B = "); 156 BN_print_fp(stdout, b); 157 printf("\n"); 158 159 printf("C = "); 160 BN_print_fp(stdout, c); 161 printf("\n"); 162 163 printf("sw= "); 164 BN_print_fp(stdout, sw); 165 printf("\n"); 166 167 printf("hw= "); 168 BN_print_fp(stdout, hw); 169 printf("\n"); 170 171 printf("\n"); 172 } 173 174 void 175 testit(void) 176 { 177 BIGNUM *a, *b, *c, *r1, *r2; 178 BN_CTX *ctx; 179 180 ctx = BN_CTX_new(); 181 182 a = BN_new(); 183 b = BN_new(); 184 c = BN_new(); 185 r1 = BN_new(); 186 r2 = BN_new(); 187 188 BN_pseudo_rand(a, 1023, 0, 0); 189 BN_pseudo_rand(b, 1023, 0, 0); 190 BN_pseudo_rand(c, 1024, 0, 0); 191 192 if (BN_cmp(a, c) > 0) { 193 BIGNUM *rem = BN_new(); 194 195 BN_mod(rem, a, c, ctx); 196 UB_mod_exp(r2, rem, b, c, ctx); 197 BN_free(rem); 198 } else { 199 UB_mod_exp(r2, a, b, c, ctx); 200 } 201 BN_mod_exp(r1, a, b, c, ctx); 202 203 if (BN_cmp(r1, r2) != 0) { 204 show_result(a, b, c, r1, r2); 205 } 206 207 BN_free(r2); 208 BN_free(r1); 209 BN_free(c); 210 BN_free(b); 211 BN_free(a); 212 BN_CTX_free(ctx); 213 } 214 215 int 216 main() 217 { 218 int i; 219 220 for (i = 0; i < 1000; i++) { 221 fprintf(stderr, "test %d\n", i); 222 testit(); 223 } 224 return (0); 225 } 226