diff options
| author | markus <> | 2003-05-11 21:36:59 +0000 |
|---|---|---|
| committer | markus <> | 2003-05-11 21:36:59 +0000 |
| commit | 9cea7b85baecb1a02a3ea617de73d9693a9792eb (patch) | |
| tree | b0ca83a03e35572831c5818cd2011868d462a5d1 /src/lib/libcrypto/engine/hw_cryptodev.c | |
| parent | f8f1d7fabf136ce9810602509c477d2c42bf6d1c (diff) | |
| download | openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.tar.gz openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.tar.bz2 openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.zip | |
import 0.9.7b (without idea and rc5)
Diffstat (limited to 'src/lib/libcrypto/engine/hw_cryptodev.c')
| -rw-r--r-- | src/lib/libcrypto/engine/hw_cryptodev.c | 540 |
1 files changed, 373 insertions, 167 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c index 7c3728f395..40af97ac24 100644 --- a/src/lib/libcrypto/engine/hw_cryptodev.c +++ b/src/lib/libcrypto/engine/hw_cryptodev.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2002 Bob Beck <beck@openbsd.org> | 2 | * Copyright (c) 2002 Bob Beck <beck@openbsd.org> |
| 3 | * Copyright (c) 2002 Theo de Raadt | 3 | * Copyright (c) 2002 Theo de Raadt |
| 4 | * Copyright (c) 2002 Markus Friedl | ||
| 4 | * All rights reserved. | 5 | * All rights reserved. |
| 5 | * | 6 | * |
| 6 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
| @@ -28,33 +29,85 @@ | |||
| 28 | * | 29 | * |
| 29 | */ | 30 | */ |
| 30 | 31 | ||
| 31 | #include <sys/types.h> | 32 | #include <openssl/objects.h> |
| 33 | #include <openssl/engine.h> | ||
| 34 | #include <openssl/evp.h> | ||
| 35 | |||
| 36 | #if (defined(__unix__) || defined(unix)) && !defined(USG) | ||
| 32 | #include <sys/param.h> | 37 | #include <sys/param.h> |
| 38 | # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) | ||
| 39 | # define HAVE_CRYPTODEV | ||
| 40 | # endif | ||
| 41 | # if (OpenBSD >= 200110) | ||
| 42 | # define HAVE_SYSLOG_R | ||
| 43 | # endif | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #ifndef HAVE_CRYPTODEV | ||
| 47 | |||
| 48 | void | ||
| 49 | ENGINE_load_cryptodev(void) | ||
| 50 | { | ||
| 51 | /* This is a NOP on platforms without /dev/crypto */ | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | #else | ||
| 56 | |||
| 57 | #include <sys/types.h> | ||
| 33 | #include <crypto/cryptodev.h> | 58 | #include <crypto/cryptodev.h> |
| 34 | #include <sys/ioctl.h> | 59 | #include <sys/ioctl.h> |
| 35 | #include <errno.h> | 60 | #include <errno.h> |
| 36 | #include <stdio.h> | 61 | #include <stdio.h> |
| 37 | #include <unistd.h> | 62 | #include <unistd.h> |
| 38 | #include <fcntl.h> | 63 | #include <fcntl.h> |
| 39 | #include <syslog.h> | ||
| 40 | #include <stdarg.h> | 64 | #include <stdarg.h> |
| 41 | #include <ssl/objects.h> | 65 | #include <syslog.h> |
| 42 | #include <ssl/engine.h> | 66 | #include <errno.h> |
| 43 | #include <ssl/evp.h> | 67 | #include <string.h> |
| 44 | 68 | ||
| 45 | static int cryptodev_fd = -1; | 69 | struct dev_crypto_state { |
| 46 | static int cryptodev_sessions = 0; | 70 | struct session_op d_sess; |
| 47 | static u_int32_t cryptodev_symfeat = 0; | 71 | int d_fd; |
| 72 | }; | ||
| 48 | 73 | ||
| 74 | static u_int32_t cryptodev_asymfeat = 0; | ||
| 75 | |||
| 76 | static int get_asym_dev_crypto(void); | ||
| 77 | static int open_dev_crypto(void); | ||
| 78 | static int get_dev_crypto(void); | ||
| 79 | static int cryptodev_max_iv(int cipher); | ||
| 80 | static int cryptodev_key_length_valid(int cipher, int len); | ||
| 81 | static int cipher_nid_to_cryptodev(int nid); | ||
| 82 | static int get_cryptodev_ciphers(const int **cnids); | ||
| 83 | static int get_cryptodev_digests(const int **cnids); | ||
| 84 | static int cryptodev_usable_ciphers(const int **nids); | ||
| 85 | static int cryptodev_usable_digests(const int **nids); | ||
| 86 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
| 87 | const unsigned char *in, unsigned int inl); | ||
| 88 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
| 89 | const unsigned char *iv, int enc); | ||
| 90 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); | ||
| 91 | static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
| 92 | const int **nids, int nid); | ||
| 93 | static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | ||
| 94 | const int **nids, int nid); | ||
| 49 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); | 95 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
| 50 | static int crparam2bn(struct crparam *crp, BIGNUM *a); | 96 | static int crparam2bn(struct crparam *crp, BIGNUM *a); |
| 51 | static void zapparams(struct crypt_kop *kop); | 97 | static void zapparams(struct crypt_kop *kop); |
| 98 | static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, | ||
| 99 | int slen, BIGNUM *s); | ||
| 52 | 100 | ||
| 53 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); | ||
| 54 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, | 101 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, |
| 55 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 102 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
| 103 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, | ||
| 104 | RSA *rsa); | ||
| 105 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); | ||
| 56 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, | 106 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, |
| 57 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 107 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
| 108 | static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
| 109 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
| 110 | BN_CTX *ctx, BN_MONT_CTX *mont); | ||
| 58 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, | 111 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, |
| 59 | int dlen, DSA *dsa); | 112 | int dlen, DSA *dsa); |
| 60 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, | 113 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, |
| @@ -64,6 +117,9 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | |||
| 64 | BN_MONT_CTX *m_ctx); | 117 | BN_MONT_CTX *m_ctx); |
| 65 | static int cryptodev_dh_compute_key(unsigned char *key, | 118 | static int cryptodev_dh_compute_key(unsigned char *key, |
| 66 | const BIGNUM *pub_key, DH *dh); | 119 | const BIGNUM *pub_key, DH *dh); |
| 120 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, | ||
| 121 | void (*f)()); | ||
| 122 | void ENGINE_load_cryptodev(void); | ||
| 67 | 123 | ||
| 68 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | 124 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { |
| 69 | { 0, NULL, NULL, 0 } | 125 | { 0, NULL, NULL, 0 } |
| @@ -77,11 +133,10 @@ static struct { | |||
| 77 | } ciphers[] = { | 133 | } ciphers[] = { |
| 78 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, | 134 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, |
| 79 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, | 135 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, |
| 80 | { CRYPTO_AES_CBC, NID_undef, 8, 24, }, | 136 | { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, |
| 81 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, | 137 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, |
| 82 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, }, | 138 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, |
| 83 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, | 139 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, |
| 84 | { CRYPTO_ARC4, NID_rc4, 8, 16, }, | ||
| 85 | { 0, NID_undef, 0, 0, }, | 140 | { 0, NID_undef, 0, 0, }, |
| 86 | }; | 141 | }; |
| 87 | 142 | ||
| @@ -99,33 +154,53 @@ static struct { | |||
| 99 | }; | 154 | }; |
| 100 | 155 | ||
| 101 | /* | 156 | /* |
| 102 | * Return 1 if /dev/crypto seems usable, 0 otherwise , also | 157 | * Return a fd if /dev/crypto seems usable, 0 otherwise. |
| 103 | * does most of the work of initting the device, if not already | ||
| 104 | * done.. This should leave is with global fd initialized with CRIOGET. | ||
| 105 | */ | 158 | */ |
| 106 | static int | 159 | static int |
| 107 | check_dev_crypto() | 160 | open_dev_crypto(void) |
| 108 | { | 161 | { |
| 109 | int fd; | 162 | static int fd = -1; |
| 110 | 163 | ||
| 111 | if (cryptodev_fd == -1) { | 164 | if (fd == -1) { |
| 112 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | 165 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) |
| 113 | return (0); | 166 | return (-1); |
| 114 | if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { | ||
| 115 | close(fd); | ||
| 116 | return (0); | ||
| 117 | } | ||
| 118 | close(fd); | ||
| 119 | /* close on exec */ | 167 | /* close on exec */ |
| 120 | if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { | 168 | if (fcntl(fd, F_SETFD, 1) == -1) { |
| 121 | close(cryptodev_fd); | 169 | close(fd); |
| 122 | cryptodev_fd = -1; | 170 | fd = -1; |
| 123 | return (0); | 171 | return (-1); |
| 124 | } | 172 | } |
| 125 | } | 173 | } |
| 126 | ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat); | 174 | return (fd); |
| 175 | } | ||
| 127 | 176 | ||
| 128 | return (1); | 177 | static int |
| 178 | get_dev_crypto(void) | ||
| 179 | { | ||
| 180 | int fd, retfd; | ||
| 181 | |||
| 182 | if ((fd = open_dev_crypto()) == -1) | ||
| 183 | return (-1); | ||
| 184 | if (ioctl(fd, CRIOGET, &retfd) == -1) | ||
| 185 | return (-1); | ||
| 186 | |||
| 187 | /* close on exec */ | ||
| 188 | if (fcntl(retfd, F_SETFD, 1) == -1) { | ||
| 189 | close(retfd); | ||
| 190 | return (-1); | ||
| 191 | } | ||
| 192 | return (retfd); | ||
| 193 | } | ||
| 194 | |||
| 195 | /* Caching version for asym operations */ | ||
| 196 | static int | ||
| 197 | get_asym_dev_crypto(void) | ||
| 198 | { | ||
| 199 | static int fd = -1; | ||
| 200 | |||
| 201 | if (fd == -1) | ||
| 202 | fd = get_dev_crypto(); | ||
| 203 | return fd; | ||
| 129 | } | 204 | } |
| 130 | 205 | ||
| 131 | /* | 206 | /* |
| @@ -183,8 +258,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
| 183 | { | 258 | { |
| 184 | static int nids[CRYPTO_ALGORITHM_MAX]; | 259 | static int nids[CRYPTO_ALGORITHM_MAX]; |
| 185 | struct session_op sess; | 260 | struct session_op sess; |
| 186 | int i, count = 0; | 261 | int fd, i, count = 0; |
| 187 | 262 | ||
| 263 | if ((fd = get_dev_crypto()) < 0) { | ||
| 264 | *nids = NULL; | ||
| 265 | return (0); | ||
| 266 | } | ||
| 188 | memset(&sess, 0, sizeof(sess)); | 267 | memset(&sess, 0, sizeof(sess)); |
| 189 | sess.key = (caddr_t)"123456781234567812345678"; | 268 | sess.key = (caddr_t)"123456781234567812345678"; |
| 190 | 269 | ||
| @@ -194,10 +273,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
| 194 | sess.cipher = ciphers[i].id; | 273 | sess.cipher = ciphers[i].id; |
| 195 | sess.keylen = ciphers[i].keylen; | 274 | sess.keylen = ciphers[i].keylen; |
| 196 | sess.mac = 0; | 275 | sess.mac = 0; |
| 197 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 276 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
| 198 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 277 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
| 199 | nids[count++] = ciphers[i].nid; | 278 | nids[count++] = ciphers[i].nid; |
| 200 | } | 279 | } |
| 280 | close(fd); | ||
| 281 | |||
| 201 | if (count > 0) | 282 | if (count > 0) |
| 202 | *cnids = nids; | 283 | *cnids = nids; |
| 203 | else | 284 | else |
| @@ -216,18 +297,24 @@ get_cryptodev_digests(const int **cnids) | |||
| 216 | { | 297 | { |
| 217 | static int nids[CRYPTO_ALGORITHM_MAX]; | 298 | static int nids[CRYPTO_ALGORITHM_MAX]; |
| 218 | struct session_op sess; | 299 | struct session_op sess; |
| 219 | int i, count = 0; | 300 | int fd, i, count = 0; |
| 220 | 301 | ||
| 302 | if ((fd = get_dev_crypto()) < 0) { | ||
| 303 | *nids = NULL; | ||
| 304 | return (0); | ||
| 305 | } | ||
| 221 | memset(&sess, 0, sizeof(sess)); | 306 | memset(&sess, 0, sizeof(sess)); |
| 222 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 307 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
| 223 | if (digests[i].nid == NID_undef) | 308 | if (digests[i].nid == NID_undef) |
| 224 | continue; | 309 | continue; |
| 225 | sess.mac = digests[i].id; | 310 | sess.mac = digests[i].id; |
| 226 | sess.cipher = 0; | 311 | sess.cipher = 0; |
| 227 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 312 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
| 228 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 313 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
| 229 | nids[count++] = digests[i].nid; | 314 | nids[count++] = digests[i].nid; |
| 230 | } | 315 | } |
| 316 | close(fd); | ||
| 317 | |||
| 231 | if (count > 0) | 318 | if (count > 0) |
| 232 | *cnids = nids; | 319 | *cnids = nids; |
| 233 | else | 320 | else |
| @@ -256,25 +343,15 @@ get_cryptodev_digests(const int **cnids) | |||
| 256 | * want most of the decisions made about what we actually want | 343 | * want most of the decisions made about what we actually want |
| 257 | * to use from /dev/crypto. | 344 | * to use from /dev/crypto. |
| 258 | */ | 345 | */ |
| 259 | int | 346 | static int |
| 260 | cryptodev_usable_ciphers(const int **nids) | 347 | cryptodev_usable_ciphers(const int **nids) |
| 261 | { | 348 | { |
| 262 | if (!check_dev_crypto()) { | ||
| 263 | *nids = NULL; | ||
| 264 | return (0); | ||
| 265 | } | ||
| 266 | |||
| 267 | /* find what the device can do. Unfortunately, we don't | ||
| 268 | * necessarily want all of these yet, because we aren't | ||
| 269 | * yet set up to do them | ||
| 270 | */ | ||
| 271 | return (get_cryptodev_ciphers(nids)); | 349 | return (get_cryptodev_ciphers(nids)); |
| 272 | } | 350 | } |
| 273 | 351 | ||
| 274 | int | 352 | static int |
| 275 | cryptodev_usable_digests(const int **nids) | 353 | cryptodev_usable_digests(const int **nids) |
| 276 | { | 354 | { |
| 277 | #if 1 | ||
| 278 | /* | 355 | /* |
| 279 | * XXXX just disable all digests for now, because it sucks. | 356 | * XXXX just disable all digests for now, because it sucks. |
| 280 | * we need a better way to decide this - i.e. I may not | 357 | * we need a better way to decide this - i.e. I may not |
| @@ -289,29 +366,19 @@ cryptodev_usable_digests(const int **nids) | |||
| 289 | */ | 366 | */ |
| 290 | *nids = NULL; | 367 | *nids = NULL; |
| 291 | return (0); | 368 | return (0); |
| 292 | #endif | ||
| 293 | |||
| 294 | if (!check_dev_crypto()) { | ||
| 295 | *nids = NULL; | ||
| 296 | return (0); | ||
| 297 | } | ||
| 298 | return (get_cryptodev_digests(nids)); | ||
| 299 | } | 369 | } |
| 300 | 370 | ||
| 301 | 371 | static int | |
| 302 | int | ||
| 303 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 372 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
| 304 | const unsigned char *in, unsigned int inl) | 373 | const unsigned char *in, unsigned int inl) |
| 305 | { | 374 | { |
| 306 | struct crypt_op cryp; | 375 | struct crypt_op cryp; |
| 307 | struct session_op *sess = ctx->cipher_data; | 376 | struct dev_crypto_state *state = ctx->cipher_data; |
| 377 | struct session_op *sess = &state->d_sess; | ||
| 308 | void *iiv; | 378 | void *iiv; |
| 309 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 379 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
| 310 | struct syslog_data sd = SYSLOG_DATA_INIT; | ||
| 311 | 380 | ||
| 312 | if (cryptodev_fd == -1) | 381 | if (state->d_fd < 0) |
| 313 | return (0); | ||
| 314 | if (sess == NULL) | ||
| 315 | return (0); | 382 | return (0); |
| 316 | if (!inl) | 383 | if (!inl) |
| 317 | return (1); | 384 | return (1); |
| @@ -338,11 +405,10 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
| 338 | } else | 405 | } else |
| 339 | cryp.iv = NULL; | 406 | cryp.iv = NULL; |
| 340 | 407 | ||
| 341 | if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { | 408 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { |
| 342 | /* XXX need better errror handling | 409 | /* XXX need better errror handling |
| 343 | * this can fail for a number of different reasons. | 410 | * this can fail for a number of different reasons. |
| 344 | */ | 411 | */ |
| 345 | syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)"); | ||
| 346 | return (0); | 412 | return (0); |
| 347 | } | 413 | } |
| 348 | 414 | ||
| @@ -356,20 +422,17 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
| 356 | return (1); | 422 | return (1); |
| 357 | } | 423 | } |
| 358 | 424 | ||
| 359 | int | 425 | static int |
| 360 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 426 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
| 361 | const unsigned char *iv, int enc) | 427 | const unsigned char *iv, int enc) |
| 362 | { | 428 | { |
| 363 | struct session_op *sess = ctx->cipher_data; | 429 | struct dev_crypto_state *state = ctx->cipher_data; |
| 364 | struct syslog_data sd = SYSLOG_DATA_INIT; | 430 | struct session_op *sess = &state->d_sess; |
| 365 | int cipher; | 431 | int cipher; |
| 366 | 432 | ||
| 367 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 433 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) |
| 368 | return (0); | 434 | return (0); |
| 369 | 435 | ||
| 370 | if (!check_dev_crypto()) | ||
| 371 | return (0); | ||
| 372 | |||
| 373 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 436 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) |
| 374 | return (0); | 437 | return (0); |
| 375 | 438 | ||
| @@ -378,15 +441,18 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
| 378 | 441 | ||
| 379 | memset(sess, 0, sizeof(struct session_op)); | 442 | memset(sess, 0, sizeof(struct session_op)); |
| 380 | 443 | ||
| 444 | if ((state->d_fd = get_dev_crypto()) < 0) | ||
| 445 | return (0); | ||
| 446 | |||
| 381 | sess->key = (unsigned char *)key; | 447 | sess->key = (unsigned char *)key; |
| 382 | sess->keylen = ctx->key_len; | 448 | sess->keylen = ctx->key_len; |
| 383 | sess->cipher = cipher; | 449 | sess->cipher = cipher; |
| 384 | 450 | ||
| 385 | if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { | 451 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { |
| 386 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); | 452 | close(state->d_fd); |
| 453 | state->d_fd = -1; | ||
| 387 | return (0); | 454 | return (0); |
| 388 | } | 455 | } |
| 389 | cryptodev_sessions++; | ||
| 390 | return (1); | 456 | return (1); |
| 391 | } | 457 | } |
| 392 | 458 | ||
| @@ -394,14 +460,14 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
| 394 | * free anything we allocated earlier when initting a | 460 | * free anything we allocated earlier when initting a |
| 395 | * session, and close the session. | 461 | * session, and close the session. |
| 396 | */ | 462 | */ |
| 397 | int | 463 | static int |
| 398 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | 464 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
| 399 | { | 465 | { |
| 400 | int ret = 0; | 466 | int ret = 0; |
| 401 | struct session_op *sess = ctx->cipher_data; | 467 | struct dev_crypto_state *state = ctx->cipher_data; |
| 402 | struct syslog_data sd = SYSLOG_DATA_INIT; | 468 | struct session_op *sess = &state->d_sess; |
| 403 | 469 | ||
| 404 | if (sess == NULL) | 470 | if (state->d_fd < 0) |
| 405 | return (0); | 471 | return (0); |
| 406 | 472 | ||
| 407 | /* XXX if this ioctl fails, someting's wrong. the invoker | 473 | /* XXX if this ioctl fails, someting's wrong. the invoker |
| @@ -415,17 +481,14 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
| 415 | * print messages to users of the library. hmm.. | 481 | * print messages to users of the library. hmm.. |
| 416 | */ | 482 | */ |
| 417 | 483 | ||
| 418 | if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { | 484 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { |
| 419 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); | ||
| 420 | ret = 0; | 485 | ret = 0; |
| 421 | } else { | 486 | } else { |
| 422 | cryptodev_sessions--; | ||
| 423 | ret = 1; | 487 | ret = 1; |
| 424 | } | 488 | } |
| 425 | if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { | 489 | close(state->d_fd); |
| 426 | close(cryptodev_fd); /* XXX should this be closed? */ | 490 | state->d_fd = -1; |
| 427 | cryptodev_fd = -1; | 491 | |
| 428 | } | ||
| 429 | return (ret); | 492 | return (ret); |
| 430 | } | 493 | } |
| 431 | 494 | ||
| @@ -434,20 +497,6 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
| 434 | * gets called when libcrypto requests a cipher NID. | 497 | * gets called when libcrypto requests a cipher NID. |
| 435 | */ | 498 | */ |
| 436 | 499 | ||
| 437 | /* ARC4 (16 byte key) */ | ||
| 438 | const EVP_CIPHER cryptodev_arc4_cipher = { | ||
| 439 | NID_rc4, | ||
| 440 | 1, 16, 0, | ||
| 441 | EVP_CIPH_VARIABLE_LENGTH, | ||
| 442 | cryptodev_init_key, | ||
| 443 | cryptodev_cipher, | ||
| 444 | cryptodev_cleanup, | ||
| 445 | sizeof(struct session_op), | ||
| 446 | NULL, | ||
| 447 | NULL, | ||
| 448 | NULL | ||
| 449 | }; | ||
| 450 | |||
| 451 | /* DES CBC EVP */ | 500 | /* DES CBC EVP */ |
| 452 | const EVP_CIPHER cryptodev_des_cbc = { | 501 | const EVP_CIPHER cryptodev_des_cbc = { |
| 453 | NID_des_cbc, | 502 | NID_des_cbc, |
| @@ -456,7 +505,7 @@ const EVP_CIPHER cryptodev_des_cbc = { | |||
| 456 | cryptodev_init_key, | 505 | cryptodev_init_key, |
| 457 | cryptodev_cipher, | 506 | cryptodev_cipher, |
| 458 | cryptodev_cleanup, | 507 | cryptodev_cleanup, |
| 459 | sizeof(struct session_op), | 508 | sizeof(struct dev_crypto_state), |
| 460 | EVP_CIPHER_set_asn1_iv, | 509 | EVP_CIPHER_set_asn1_iv, |
| 461 | EVP_CIPHER_get_asn1_iv, | 510 | EVP_CIPHER_get_asn1_iv, |
| 462 | NULL | 511 | NULL |
| @@ -470,19 +519,57 @@ const EVP_CIPHER cryptodev_3des_cbc = { | |||
| 470 | cryptodev_init_key, | 519 | cryptodev_init_key, |
| 471 | cryptodev_cipher, | 520 | cryptodev_cipher, |
| 472 | cryptodev_cleanup, | 521 | cryptodev_cleanup, |
| 473 | sizeof(struct session_op), | 522 | sizeof(struct dev_crypto_state), |
| 523 | EVP_CIPHER_set_asn1_iv, | ||
| 524 | EVP_CIPHER_get_asn1_iv, | ||
| 525 | NULL | ||
| 526 | }; | ||
| 527 | |||
| 528 | const EVP_CIPHER cryptodev_bf_cbc = { | ||
| 529 | NID_bf_cbc, | ||
| 530 | 8, 16, 8, | ||
| 531 | EVP_CIPH_CBC_MODE, | ||
| 532 | cryptodev_init_key, | ||
| 533 | cryptodev_cipher, | ||
| 534 | cryptodev_cleanup, | ||
| 535 | sizeof(struct dev_crypto_state), | ||
| 536 | EVP_CIPHER_set_asn1_iv, | ||
| 537 | EVP_CIPHER_get_asn1_iv, | ||
| 538 | NULL | ||
| 539 | }; | ||
| 540 | |||
| 541 | const EVP_CIPHER cryptodev_cast_cbc = { | ||
| 542 | NID_cast5_cbc, | ||
| 543 | 8, 16, 8, | ||
| 544 | EVP_CIPH_CBC_MODE, | ||
| 545 | cryptodev_init_key, | ||
| 546 | cryptodev_cipher, | ||
| 547 | cryptodev_cleanup, | ||
| 548 | sizeof(struct dev_crypto_state), | ||
| 474 | EVP_CIPHER_set_asn1_iv, | 549 | EVP_CIPHER_set_asn1_iv, |
| 475 | EVP_CIPHER_get_asn1_iv, | 550 | EVP_CIPHER_get_asn1_iv, |
| 476 | NULL | 551 | NULL |
| 477 | }; | 552 | }; |
| 478 | 553 | ||
| 554 | const EVP_CIPHER cryptodev_aes_cbc = { | ||
| 555 | NID_aes_128_cbc, | ||
| 556 | 16, 16, 16, | ||
| 557 | EVP_CIPH_CBC_MODE, | ||
| 558 | cryptodev_init_key, | ||
| 559 | cryptodev_cipher, | ||
| 560 | cryptodev_cleanup, | ||
| 561 | sizeof(struct dev_crypto_state), | ||
| 562 | EVP_CIPHER_set_asn1_iv, | ||
| 563 | EVP_CIPHER_get_asn1_iv, | ||
| 564 | NULL | ||
| 565 | }; | ||
| 479 | 566 | ||
| 480 | /* | 567 | /* |
| 481 | * Registered by the ENGINE when used to find out how to deal with | 568 | * Registered by the ENGINE when used to find out how to deal with |
| 482 | * a particular NID in the ENGINE. this says what we'll do at the | 569 | * a particular NID in the ENGINE. this says what we'll do at the |
| 483 | * top level - note, that list is restricted by what we answer with | 570 | * top level - note, that list is restricted by what we answer with |
| 484 | */ | 571 | */ |
| 485 | int | 572 | static int |
| 486 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | 573 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
| 487 | const int **nids, int nid) | 574 | const int **nids, int nid) |
| 488 | { | 575 | { |
| @@ -490,15 +577,21 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
| 490 | return (cryptodev_usable_ciphers(nids)); | 577 | return (cryptodev_usable_ciphers(nids)); |
| 491 | 578 | ||
| 492 | switch (nid) { | 579 | switch (nid) { |
| 493 | case NID_rc4: | ||
| 494 | *cipher = &cryptodev_arc4_cipher; | ||
| 495 | break; | ||
| 496 | case NID_des_ede3_cbc: | 580 | case NID_des_ede3_cbc: |
| 497 | *cipher = &cryptodev_3des_cbc; | 581 | *cipher = &cryptodev_3des_cbc; |
| 498 | break; | 582 | break; |
| 499 | case NID_des_cbc: | 583 | case NID_des_cbc: |
| 500 | *cipher = &cryptodev_des_cbc; | 584 | *cipher = &cryptodev_des_cbc; |
| 501 | break; | 585 | break; |
| 586 | case NID_bf_cbc: | ||
| 587 | *cipher = &cryptodev_bf_cbc; | ||
| 588 | break; | ||
| 589 | case NID_cast5_cbc: | ||
| 590 | *cipher = &cryptodev_cast_cbc; | ||
| 591 | break; | ||
| 592 | case NID_aes_128_cbc: | ||
| 593 | *cipher = &cryptodev_aes_cbc; | ||
| 594 | break; | ||
| 502 | default: | 595 | default: |
| 503 | *cipher = NULL; | 596 | *cipher = NULL; |
| 504 | break; | 597 | break; |
| @@ -506,7 +599,7 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
| 506 | return (*cipher != NULL); | 599 | return (*cipher != NULL); |
| 507 | } | 600 | } |
| 508 | 601 | ||
| 509 | int | 602 | static int |
| 510 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | 603 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, |
| 511 | const int **nids, int nid) | 604 | const int **nids, int nid) |
| 512 | { | 605 | { |
| @@ -524,7 +617,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
| 524 | return (*digest != NULL); | 617 | return (*digest != NULL); |
| 525 | } | 618 | } |
| 526 | 619 | ||
| 527 | |||
| 528 | /* | 620 | /* |
| 529 | * Convert a BIGNUM to the representation that /dev/crypto needs. | 621 | * Convert a BIGNUM to the representation that /dev/crypto needs. |
| 530 | * Upon completion of use, the caller is responsible for freeing | 622 | * Upon completion of use, the caller is responsible for freeing |
| @@ -533,7 +625,7 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
| 533 | static int | 625 | static int |
| 534 | bn2crparam(const BIGNUM *a, struct crparam *crp) | 626 | bn2crparam(const BIGNUM *a, struct crparam *crp) |
| 535 | { | 627 | { |
| 536 | int i, j, n; | 628 | int i, j, k; |
| 537 | ssize_t words, bytes, bits; | 629 | ssize_t words, bytes, bits; |
| 538 | u_char *b; | 630 | u_char *b; |
| 539 | 631 | ||
| @@ -550,17 +642,13 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
| 550 | crp->crp_p = b; | 642 | crp->crp_p = b; |
| 551 | crp->crp_nbits = bits; | 643 | crp->crp_nbits = bits; |
| 552 | 644 | ||
| 553 | words = (bits + BN_BITS2 - 1) / BN_BITS2; | 645 | for (i = 0, j = 0; i < a->top; i++) { |
| 554 | 646 | for (k = 0; k < BN_BITS2 / 8; k++) { | |
| 555 | n = 0; | 647 | if ((j + k) >= bytes) |
| 556 | for (i = 0; i < words && n < bytes; i++) { | 648 | return (0); |
| 557 | BN_ULONG word; | 649 | b[j + k] = a->d[i] >> (k * 8); |
| 558 | |||
| 559 | word = a->d[i]; | ||
| 560 | for (j = 0 ; j < BN_BYTES && n < bytes; j++, n++) { | ||
| 561 | *b++ = (word & 0xff); | ||
| 562 | word >>= 8; | ||
| 563 | } | 650 | } |
| 651 | j += BN_BITS2 / 8; | ||
| 564 | } | 652 | } |
| 565 | return (0); | 653 | return (0); |
| 566 | } | 654 | } |
| @@ -569,15 +657,22 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
| 569 | static int | 657 | static int |
| 570 | crparam2bn(struct crparam *crp, BIGNUM *a) | 658 | crparam2bn(struct crparam *crp, BIGNUM *a) |
| 571 | { | 659 | { |
| 660 | u_int8_t *pd; | ||
| 572 | int i, bytes; | 661 | int i, bytes; |
| 573 | 662 | ||
| 574 | bytes = (crp->crp_nbits + 7)/8; | 663 | bytes = (crp->crp_nbits + 7) / 8; |
| 575 | 664 | ||
| 576 | BN_zero(a); | 665 | if (bytes == 0) |
| 577 | for (i = bytes - 1; i >= 0; i--) { | 666 | return (-1); |
| 578 | BN_lshift(a, a, 8); | 667 | |
| 579 | BN_add_word(a, (u_char)crp->crp_p[i]); | 668 | if ((pd = (u_int8_t *) malloc(bytes)) == NULL) |
| 580 | } | 669 | return (-1); |
| 670 | |||
| 671 | for (i = 0; i < bytes; i++) | ||
| 672 | pd[i] = crp->crp_p[bytes - i - 1]; | ||
| 673 | |||
| 674 | BN_bin2bn(pd, bytes, a); | ||
| 675 | free(pd); | ||
| 581 | 676 | ||
| 582 | return (0); | 677 | return (0); |
| 583 | } | 678 | } |
| @@ -596,25 +691,32 @@ zapparams(struct crypt_kop *kop) | |||
| 596 | } | 691 | } |
| 597 | 692 | ||
| 598 | static int | 693 | static int |
| 599 | cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s) | 694 | cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) |
| 600 | { | 695 | { |
| 601 | int ret = -1; | 696 | int fd, ret = -1; |
| 697 | |||
| 698 | if ((fd = get_asym_dev_crypto()) < 0) | ||
| 699 | return (ret); | ||
| 602 | 700 | ||
| 603 | if (r) { | 701 | if (r) { |
| 604 | kop->crk_param[kop->crk_iparams].crp_p = malloc(256); | 702 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); |
| 605 | kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8; | 703 | kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; |
| 606 | kop->crk_oparams++; | 704 | kop->crk_oparams++; |
| 607 | } | 705 | } |
| 608 | if (s) { | 706 | if (s) { |
| 609 | kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256); | 707 | kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char)); |
| 610 | kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8; | 708 | kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8; |
| 611 | kop->crk_oparams++; | 709 | kop->crk_oparams++; |
| 612 | } | 710 | } |
| 613 | 711 | ||
| 614 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) { | 712 | if (ioctl(fd, CIOCKEY, kop) == 0) { |
| 615 | crparam2bn(&kop->crk_param[3], r); | 713 | if (r) |
| 714 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | ||
| 715 | if (s) | ||
| 716 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); | ||
| 616 | ret = 0; | 717 | ret = 0; |
| 617 | } | 718 | } |
| 719 | |||
| 618 | return (ret); | 720 | return (ret); |
| 619 | } | 721 | } |
| 620 | 722 | ||
| @@ -623,38 +725,58 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
| 623 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) | 725 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) |
| 624 | { | 726 | { |
| 625 | struct crypt_kop kop; | 727 | struct crypt_kop kop; |
| 626 | int ret = 0; | 728 | int ret = 1; |
| 729 | |||
| 730 | /* Currently, we know we can do mod exp iff we can do any | ||
| 731 | * asymmetric operations at all. | ||
| 732 | */ | ||
| 733 | if (cryptodev_asymfeat == 0) { | ||
| 734 | ret = BN_mod_exp(r, a, p, m, ctx); | ||
| 735 | return (ret); | ||
| 736 | } | ||
| 627 | 737 | ||
| 628 | memset(&kop, 0, sizeof kop); | 738 | memset(&kop, 0, sizeof kop); |
| 629 | kop.crk_op = CRK_MOD_EXP; | 739 | kop.crk_op = CRK_MOD_EXP; |
| 630 | 740 | ||
| 631 | /* inputs: a m p */ | 741 | /* inputs: a^p % m */ |
| 632 | if (bn2crparam(a, &kop.crk_param[0])) | 742 | if (bn2crparam(a, &kop.crk_param[0])) |
| 633 | goto err; | 743 | goto err; |
| 634 | if (bn2crparam(m, &kop.crk_param[1])) | 744 | if (bn2crparam(p, &kop.crk_param[1])) |
| 635 | goto err; | 745 | goto err; |
| 636 | if (bn2crparam(p, &kop.crk_param[2])) | 746 | if (bn2crparam(m, &kop.crk_param[2])) |
| 637 | goto err; | 747 | goto err; |
| 638 | kop.crk_iparams = 3; | 748 | kop.crk_iparams = 3; |
| 639 | 749 | ||
| 640 | if (cryptodev_sym(&kop, r, NULL) == -1) { | 750 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { |
| 641 | ret = BN_mod_exp(r, a, p, m, ctx); | 751 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
| 752 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | ||
| 642 | } | 753 | } |
| 643 | err: | 754 | err: |
| 644 | zapparams(&kop); | 755 | zapparams(&kop); |
| 645 | return (ret); | 756 | return (ret); |
| 646 | } | 757 | } |
| 647 | 758 | ||
| 759 | static int | ||
| 760 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | ||
| 761 | { | ||
| 762 | int r; | ||
| 763 | BN_CTX *ctx; | ||
| 764 | |||
| 765 | ctx = BN_CTX_new(); | ||
| 766 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); | ||
| 767 | BN_CTX_free(ctx); | ||
| 768 | return (r); | ||
| 769 | } | ||
| 648 | 770 | ||
| 649 | static int | 771 | static int |
| 650 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | 772 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) |
| 651 | { | 773 | { |
| 652 | struct crypt_kop kop; | 774 | struct crypt_kop kop; |
| 653 | int ret = 0; | 775 | int ret = 1; |
| 654 | 776 | ||
| 655 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { | 777 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { |
| 656 | /* XXX 0 means failure?? */ | 778 | /* XXX 0 means failure?? */ |
| 657 | goto err; | 779 | return (0); |
| 658 | } | 780 | } |
| 659 | 781 | ||
| 660 | memset(&kop, 0, sizeof kop); | 782 | memset(&kop, 0, sizeof kop); |
| @@ -674,9 +796,8 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | |||
| 674 | goto err; | 796 | goto err; |
| 675 | kop.crk_iparams = 6; | 797 | kop.crk_iparams = 6; |
| 676 | 798 | ||
| 677 | if (cryptodev_sym(&kop, r0, NULL) == -1) { | 799 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { |
| 678 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | 800 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
| 679 | |||
| 680 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); | 801 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); |
| 681 | } | 802 | } |
| 682 | err: | 803 | err: |
| @@ -690,8 +811,8 @@ static RSA_METHOD cryptodev_rsa = { | |||
| 690 | NULL, /* rsa_pub_dec */ | 811 | NULL, /* rsa_pub_dec */ |
| 691 | NULL, /* rsa_priv_enc */ | 812 | NULL, /* rsa_priv_enc */ |
| 692 | NULL, /* rsa_priv_dec */ | 813 | NULL, /* rsa_priv_dec */ |
| 693 | cryptodev_rsa_mod_exp, /* rsa_mod_exp */ | 814 | NULL, |
| 694 | cryptodev_bn_mod_exp, /* bn_mod_exp */ | 815 | NULL, |
| 695 | NULL, /* init */ | 816 | NULL, /* init */ |
| 696 | NULL, /* finish */ | 817 | NULL, /* finish */ |
| 697 | 0, /* flags */ | 818 | 0, /* flags */ |
| @@ -707,6 +828,38 @@ cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | |||
| 707 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); | 828 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); |
| 708 | } | 829 | } |
| 709 | 830 | ||
| 831 | static int | ||
| 832 | cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
| 833 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
| 834 | BN_CTX *ctx, BN_MONT_CTX *mont) | ||
| 835 | { | ||
| 836 | BIGNUM t2; | ||
| 837 | int ret = 0; | ||
| 838 | |||
| 839 | BN_init(&t2); | ||
| 840 | |||
| 841 | /* v = ( g^u1 * y^u2 mod p ) mod q */ | ||
| 842 | /* let t1 = g ^ u1 mod p */ | ||
| 843 | ret = 0; | ||
| 844 | |||
| 845 | if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont)) | ||
| 846 | goto err; | ||
| 847 | |||
| 848 | /* let t2 = y ^ u2 mod p */ | ||
| 849 | if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont)) | ||
| 850 | goto err; | ||
| 851 | /* let u1 = t1 * t2 mod p */ | ||
| 852 | if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx)) | ||
| 853 | goto err; | ||
| 854 | |||
| 855 | BN_copy(t1,u1); | ||
| 856 | |||
| 857 | ret = 1; | ||
| 858 | err: | ||
| 859 | BN_free(&t2); | ||
| 860 | return(ret); | ||
| 861 | } | ||
| 862 | |||
| 710 | static DSA_SIG * | 863 | static DSA_SIG * |
| 711 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | 864 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
| 712 | { | 865 | { |
| @@ -721,6 +874,7 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
| 721 | goto err; | 874 | goto err; |
| 722 | } | 875 | } |
| 723 | 876 | ||
| 877 | printf("bar\n"); | ||
| 724 | memset(&kop, 0, sizeof kop); | 878 | memset(&kop, 0, sizeof kop); |
| 725 | kop.crk_op = CRK_DSA_SIGN; | 879 | kop.crk_op = CRK_DSA_SIGN; |
| 726 | 880 | ||
| @@ -737,13 +891,13 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
| 737 | goto err; | 891 | goto err; |
| 738 | kop.crk_iparams = 5; | 892 | kop.crk_iparams = 5; |
| 739 | 893 | ||
| 740 | if (cryptodev_sym(&kop, r, s) == 0) { | 894 | if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, |
| 895 | BN_num_bytes(dsa->q), s) == 0) { | ||
| 741 | dsaret = DSA_SIG_new(); | 896 | dsaret = DSA_SIG_new(); |
| 742 | dsaret->r = r; | 897 | dsaret->r = r; |
| 743 | dsaret->s = s; | 898 | dsaret->s = s; |
| 744 | } else { | 899 | } else { |
| 745 | const DSA_METHOD *meth = DSA_OpenSSL(); | 900 | const DSA_METHOD *meth = DSA_OpenSSL(); |
| 746 | |||
| 747 | BN_free(r); | 901 | BN_free(r); |
| 748 | BN_free(s); | 902 | BN_free(s); |
| 749 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); | 903 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); |
| @@ -759,7 +913,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
| 759 | DSA_SIG *sig, DSA *dsa) | 913 | DSA_SIG *sig, DSA *dsa) |
| 760 | { | 914 | { |
| 761 | struct crypt_kop kop; | 915 | struct crypt_kop kop; |
| 762 | int dsaret = 0; | 916 | int dsaret = 1; |
| 763 | 917 | ||
| 764 | memset(&kop, 0, sizeof kop); | 918 | memset(&kop, 0, sizeof kop); |
| 765 | kop.crk_op = CRK_DSA_VERIFY; | 919 | kop.crk_op = CRK_DSA_VERIFY; |
| @@ -781,7 +935,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
| 781 | goto err; | 935 | goto err; |
| 782 | kop.crk_iparams = 7; | 936 | kop.crk_iparams = 7; |
| 783 | 937 | ||
| 784 | if (cryptodev_sym(&kop, NULL, NULL) == 0) { | 938 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { |
| 785 | dsaret = kop.crk_status; | 939 | dsaret = kop.crk_status; |
| 786 | } else { | 940 | } else { |
| 787 | const DSA_METHOD *meth = DSA_OpenSSL(); | 941 | const DSA_METHOD *meth = DSA_OpenSSL(); |
| @@ -796,11 +950,11 @@ err: | |||
| 796 | 950 | ||
| 797 | static DSA_METHOD cryptodev_dsa = { | 951 | static DSA_METHOD cryptodev_dsa = { |
| 798 | "cryptodev DSA method", | 952 | "cryptodev DSA method", |
| 799 | cryptodev_dsa_do_sign, | 953 | NULL, |
| 800 | NULL, /* dsa_sign_setup */ | 954 | NULL, /* dsa_sign_setup */ |
| 801 | cryptodev_dsa_verify, | 955 | NULL, |
| 802 | NULL, /* dsa_mod_exp */ | 956 | NULL, /* dsa_mod_exp */ |
| 803 | cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */ | 957 | NULL, |
| 804 | NULL, /* init */ | 958 | NULL, /* init */ |
| 805 | NULL, /* finish */ | 959 | NULL, /* finish */ |
| 806 | 0, /* flags */ | 960 | 0, /* flags */ |
| @@ -819,8 +973,14 @@ static int | |||
| 819 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | 973 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) |
| 820 | { | 974 | { |
| 821 | struct crypt_kop kop; | 975 | struct crypt_kop kop; |
| 822 | int dhret = 0; | 976 | int dhret = 1; |
| 823 | int keylen; | 977 | int fd, keylen; |
| 978 | |||
| 979 | if ((fd = get_asym_dev_crypto()) < 0) { | ||
| 980 | const DH_METHOD *meth = DH_OpenSSL(); | ||
| 981 | |||
| 982 | return ((meth->compute_key)(key, pub_key, dh)); | ||
| 983 | } | ||
| 824 | 984 | ||
| 825 | keylen = BN_num_bits(dh->p); | 985 | keylen = BN_num_bits(dh->p); |
| 826 | 986 | ||
| @@ -840,7 +1000,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
| 840 | kop.crk_param[3].crp_nbits = keylen * 8; | 1000 | kop.crk_param[3].crp_nbits = keylen * 8; |
| 841 | kop.crk_oparams = 1; | 1001 | kop.crk_oparams = 1; |
| 842 | 1002 | ||
| 843 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { | 1003 | if (ioctl(fd, CIOCKEY, &kop) == -1) { |
| 844 | const DH_METHOD *meth = DH_OpenSSL(); | 1004 | const DH_METHOD *meth = DH_OpenSSL(); |
| 845 | 1005 | ||
| 846 | dhret = (meth->compute_key)(key, pub_key, dh); | 1006 | dhret = (meth->compute_key)(key, pub_key, dh); |
| @@ -854,8 +1014,8 @@ err: | |||
| 854 | static DH_METHOD cryptodev_dh = { | 1014 | static DH_METHOD cryptodev_dh = { |
| 855 | "cryptodev DH method", | 1015 | "cryptodev DH method", |
| 856 | NULL, /* cryptodev_dh_generate_key */ | 1016 | NULL, /* cryptodev_dh_generate_key */ |
| 857 | cryptodev_dh_compute_key, | 1017 | NULL, |
| 858 | cryptodev_mod_exp_dh, | 1018 | NULL, |
| 859 | NULL, | 1019 | NULL, |
| 860 | NULL, | 1020 | NULL, |
| 861 | 0, /* flags */ | 1021 | 0, /* flags */ |
| @@ -869,12 +1029,18 @@ static DH_METHOD cryptodev_dh = { | |||
| 869 | static int | 1029 | static int |
| 870 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | 1030 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) |
| 871 | { | 1031 | { |
| 1032 | #ifdef HAVE_SYSLOG_R | ||
| 872 | struct syslog_data sd = SYSLOG_DATA_INIT; | 1033 | struct syslog_data sd = SYSLOG_DATA_INIT; |
| 1034 | #endif | ||
| 873 | 1035 | ||
| 874 | switch (cmd) { | 1036 | switch (cmd) { |
| 875 | default: | 1037 | default: |
| 1038 | #ifdef HAVE_SYSLOG_R | ||
| 876 | syslog_r(LOG_ERR, &sd, | 1039 | syslog_r(LOG_ERR, &sd, |
| 877 | "cryptodev_ctrl: unknown command %d", cmd); | 1040 | "cryptodev_ctrl: unknown command %d", cmd); |
| 1041 | #else | ||
| 1042 | syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); | ||
| 1043 | #endif | ||
| 878 | break; | 1044 | break; |
| 879 | } | 1045 | } |
| 880 | return (1); | 1046 | return (1); |
| @@ -884,14 +1050,24 @@ void | |||
| 884 | ENGINE_load_cryptodev(void) | 1050 | ENGINE_load_cryptodev(void) |
| 885 | { | 1051 | { |
| 886 | ENGINE *engine = ENGINE_new(); | 1052 | ENGINE *engine = ENGINE_new(); |
| 887 | const RSA_METHOD *rsa_meth; | 1053 | int fd; |
| 888 | const DH_METHOD *dh_meth; | ||
| 889 | 1054 | ||
| 890 | if (engine == NULL) | 1055 | if (engine == NULL) |
| 891 | return; | 1056 | return; |
| 1057 | if ((fd = get_dev_crypto()) < 0) | ||
| 1058 | return; | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * find out what asymmetric crypto algorithms we support | ||
| 1062 | */ | ||
| 1063 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | ||
| 1064 | close(fd); | ||
| 1065 | return; | ||
| 1066 | } | ||
| 1067 | close(fd); | ||
| 892 | 1068 | ||
| 893 | if (!ENGINE_set_id(engine, "cryptodev") || | 1069 | if (!ENGINE_set_id(engine, "cryptodev") || |
| 894 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || | 1070 | !ENGINE_set_name(engine, "BSD cryptodev engine") || |
| 895 | !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || | 1071 | !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || |
| 896 | !ENGINE_set_digests(engine, cryptodev_engine_digests) || | 1072 | !ENGINE_set_digests(engine, cryptodev_engine_digests) || |
| 897 | !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || | 1073 | !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || |
| @@ -900,27 +1076,57 @@ ENGINE_load_cryptodev(void) | |||
| 900 | return; | 1076 | return; |
| 901 | } | 1077 | } |
| 902 | 1078 | ||
| 903 | if ((cryptodev_symfeat & CRSFEAT_RSA) && | 1079 | if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { |
| 904 | ENGINE_set_RSA(engine, &cryptodev_rsa)) { | 1080 | const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); |
| 905 | rsa_meth = RSA_PKCS1_SSLeay(); | 1081 | |
| 1082 | cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; | ||
| 1083 | cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; | ||
| 906 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; | 1084 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; |
| 907 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; | 1085 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; |
| 908 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec; | 1086 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; |
| 909 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; | 1087 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; |
| 1088 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
| 1089 | cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; | ||
| 1090 | if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) | ||
| 1091 | cryptodev_rsa.rsa_mod_exp = | ||
| 1092 | cryptodev_rsa_mod_exp; | ||
| 1093 | else | ||
| 1094 | cryptodev_rsa.rsa_mod_exp = | ||
| 1095 | cryptodev_rsa_nocrt_mod_exp; | ||
| 1096 | } | ||
| 910 | } | 1097 | } |
| 911 | 1098 | ||
| 912 | if ((cryptodev_symfeat & CRSFEAT_DSA) && | 1099 | if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { |
| 913 | ENGINE_set_DSA(engine, &cryptodev_dsa)) { | 1100 | const DSA_METHOD *meth = DSA_OpenSSL(); |
| 1101 | |||
| 1102 | memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); | ||
| 1103 | if (cryptodev_asymfeat & CRF_DSA_SIGN) | ||
| 1104 | cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; | ||
| 1105 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
| 1106 | cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; | ||
| 1107 | cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; | ||
| 1108 | } | ||
| 1109 | if (cryptodev_asymfeat & CRF_DSA_VERIFY) | ||
| 1110 | cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; | ||
| 914 | } | 1111 | } |
| 915 | 1112 | ||
| 916 | if ((cryptodev_symfeat & CRSFEAT_DH) && | 1113 | if (ENGINE_set_DH(engine, &cryptodev_dh)){ |
| 917 | ENGINE_set_DH(engine, &cryptodev_dh)) { | 1114 | const DH_METHOD *dh_meth = DH_OpenSSL(); |
| 918 | dh_meth = DH_OpenSSL(); | 1115 | |
| 919 | cryptodev_dh.generate_key = dh_meth->generate_key; | 1116 | cryptodev_dh.generate_key = dh_meth->generate_key; |
| 920 | cryptodev_dh.compute_key = dh_meth->compute_key; | 1117 | cryptodev_dh.compute_key = dh_meth->compute_key; |
| 1118 | cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; | ||
| 1119 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
| 1120 | cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; | ||
| 1121 | if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) | ||
| 1122 | cryptodev_dh.compute_key = | ||
| 1123 | cryptodev_dh_compute_key; | ||
| 1124 | } | ||
| 921 | } | 1125 | } |
| 922 | 1126 | ||
| 923 | ENGINE_add(engine); | 1127 | ENGINE_add(engine); |
| 924 | ENGINE_free(engine); | 1128 | ENGINE_free(engine); |
| 925 | ERR_clear_error(); | 1129 | ERR_clear_error(); |
| 926 | } | 1130 | } |
| 1131 | |||
| 1132 | #endif /* HAVE_CRYPTODEV */ | ||
