os/ossrv/ssl/libcrypto/src/crypto/engine/eng_cryptodev.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
sl@0
     3
 * Copyright (c) 2002 Theo de Raadt
sl@0
     4
 * Copyright (c) 2002 Markus Friedl
sl@0
     5
 * All rights reserved.
sl@0
     6
 *
sl@0
     7
 * Redistribution and use in source and binary forms, with or without
sl@0
     8
 * modification, are permitted provided that the following conditions
sl@0
     9
 * are met:
sl@0
    10
 * 1. Redistributions of source code must retain the above copyright
sl@0
    11
 *    notice, this list of conditions and the following disclaimer.
sl@0
    12
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    13
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    14
 *    documentation and/or other materials provided with the distribution.
sl@0
    15
 *
sl@0
    16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
sl@0
    17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
sl@0
    18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
sl@0
    19
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
sl@0
    20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
sl@0
    21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
sl@0
    23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
sl@0
    24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
sl@0
    25
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    26
 *
sl@0
    27
 */
sl@0
    28
sl@0
    29
#include <openssl/objects.h>
sl@0
    30
#include <openssl/engine.h>
sl@0
    31
#include <openssl/evp.h>
sl@0
    32
#include <openssl/bn.h>
sl@0
    33
sl@0
    34
#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
sl@0
    35
	(defined(OpenBSD) || defined(__FreeBSD_version))
sl@0
    36
#include <sys/param.h>
sl@0
    37
# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
sl@0
    38
#  define HAVE_CRYPTODEV
sl@0
    39
# endif
sl@0
    40
# if (OpenBSD >= 200110)
sl@0
    41
#  define HAVE_SYSLOG_R
sl@0
    42
# endif
sl@0
    43
#endif
sl@0
    44
sl@0
    45
#ifndef HAVE_CRYPTODEV
sl@0
    46
sl@0
    47
EXPORT_C void
sl@0
    48
ENGINE_load_cryptodev(void)
sl@0
    49
{
sl@0
    50
	/* This is a NOP on platforms without /dev/crypto */
sl@0
    51
	return;
sl@0
    52
}
sl@0
    53
sl@0
    54
#else 
sl@0
    55
 
sl@0
    56
#include <sys/types.h>
sl@0
    57
#include <crypto/cryptodev.h>
sl@0
    58
#include <sys/ioctl.h>
sl@0
    59
#include <errno.h>
sl@0
    60
#include <stdio.h>
sl@0
    61
#include <unistd.h>
sl@0
    62
#include <fcntl.h>
sl@0
    63
#include <stdarg.h>
sl@0
    64
#include <syslog.h>
sl@0
    65
#include <errno.h>
sl@0
    66
#include <string.h>
sl@0
    67
sl@0
    68
struct dev_crypto_state {
sl@0
    69
	struct session_op d_sess;
sl@0
    70
	int d_fd;
sl@0
    71
};
sl@0
    72
sl@0
    73
static u_int32_t cryptodev_asymfeat = 0;
sl@0
    74
sl@0
    75
static int get_asym_dev_crypto(void);
sl@0
    76
static int open_dev_crypto(void);
sl@0
    77
static int get_dev_crypto(void);
sl@0
    78
static int cryptodev_max_iv(int cipher);
sl@0
    79
static int cryptodev_key_length_valid(int cipher, int len);
sl@0
    80
static int cipher_nid_to_cryptodev(int nid);
sl@0
    81
static int get_cryptodev_ciphers(const int **cnids);
sl@0
    82
static int get_cryptodev_digests(const int **cnids);
sl@0
    83
static int cryptodev_usable_ciphers(const int **nids);
sl@0
    84
static int cryptodev_usable_digests(const int **nids);
sl@0
    85
static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
sl@0
    86
    const unsigned char *in, unsigned int inl);
sl@0
    87
static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
sl@0
    88
    const unsigned char *iv, int enc);
sl@0
    89
static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
sl@0
    90
static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
sl@0
    91
    const int **nids, int nid);
sl@0
    92
static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
sl@0
    93
    const int **nids, int nid);
sl@0
    94
static int bn2crparam(const BIGNUM *a, struct crparam *crp);
sl@0
    95
static int crparam2bn(struct crparam *crp, BIGNUM *a);
sl@0
    96
static void zapparams(struct crypt_kop *kop);
sl@0
    97
static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
sl@0
    98
    int slen, BIGNUM *s);
sl@0
    99
sl@0
   100
static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
sl@0
   101
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
sl@0
   102
static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
sl@0
   103
    RSA *rsa);
sl@0
   104
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
sl@0
   105
static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
sl@0
   106
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
sl@0
   107
static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
sl@0
   108
    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
sl@0
   109
    BN_CTX *ctx, BN_MONT_CTX *mont);
sl@0
   110
static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
sl@0
   111
    int dlen, DSA *dsa);
sl@0
   112
static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
sl@0
   113
    DSA_SIG *sig, DSA *dsa);
sl@0
   114
static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
sl@0
   115
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
sl@0
   116
    BN_MONT_CTX *m_ctx);
sl@0
   117
static int cryptodev_dh_compute_key(unsigned char *key,
sl@0
   118
    const BIGNUM *pub_key, DH *dh);
sl@0
   119
static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
sl@0
   120
    void (*f)());
sl@0
   121
void ENGINE_load_cryptodev(void);
sl@0
   122
sl@0
   123
static const ENGINE_CMD_DEFN cryptodev_defns[] = {
sl@0
   124
	{ 0, NULL, NULL, 0 }
sl@0
   125
};
sl@0
   126
sl@0
   127
static struct {
sl@0
   128
	int	id;
sl@0
   129
	int	nid;
sl@0
   130
	int	ivmax;
sl@0
   131
	int	keylen;
sl@0
   132
} ciphers[] = {
sl@0
   133
	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
sl@0
   134
	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
sl@0
   135
	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
sl@0
   136
	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
sl@0
   137
	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
sl@0
   138
	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
sl@0
   139
	{ 0,				NID_undef,		0,	 0, },
sl@0
   140
};
sl@0
   141
sl@0
   142
static struct {
sl@0
   143
	int	id;
sl@0
   144
	int	nid;
sl@0
   145
} digests[] = {
sl@0
   146
	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	},
sl@0
   147
	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		},
sl@0
   148
	{ CRYPTO_MD5_KPDK,		NID_undef,		},
sl@0
   149
	{ CRYPTO_SHA1_KPDK,		NID_undef,		},
sl@0
   150
	{ CRYPTO_MD5,			NID_md5,		},
sl@0
   151
	{ CRYPTO_SHA1,			NID_undef,		},
sl@0
   152
	{ 0,				NID_undef,		},
sl@0
   153
};
sl@0
   154
sl@0
   155
/*
sl@0
   156
 * Return a fd if /dev/crypto seems usable, 0 otherwise.
sl@0
   157
 */
sl@0
   158
static int
sl@0
   159
open_dev_crypto(void)
sl@0
   160
{
sl@0
   161
	static int fd = -1;
sl@0
   162
sl@0
   163
	if (fd == -1) {
sl@0
   164
		if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
sl@0
   165
			return (-1);
sl@0
   166
		/* close on exec */
sl@0
   167
		if (fcntl(fd, F_SETFD, 1) == -1) {
sl@0
   168
			close(fd);
sl@0
   169
			fd = -1;
sl@0
   170
			return (-1);
sl@0
   171
		}
sl@0
   172
	}
sl@0
   173
	return (fd);
sl@0
   174
}
sl@0
   175
sl@0
   176
static int
sl@0
   177
get_dev_crypto(void)
sl@0
   178
{
sl@0
   179
	int fd, retfd;
sl@0
   180
sl@0
   181
	if ((fd = open_dev_crypto()) == -1)
sl@0
   182
		return (-1);
sl@0
   183
	if (ioctl(fd, CRIOGET, &retfd) == -1)
sl@0
   184
		return (-1);
sl@0
   185
sl@0
   186
	/* close on exec */
sl@0
   187
	if (fcntl(retfd, F_SETFD, 1) == -1) {
sl@0
   188
		close(retfd);
sl@0
   189
		return (-1);
sl@0
   190
	}
sl@0
   191
	return (retfd);
sl@0
   192
}
sl@0
   193
sl@0
   194
/* Caching version for asym operations */
sl@0
   195
static int
sl@0
   196
get_asym_dev_crypto(void)
sl@0
   197
{
sl@0
   198
	static int fd = -1;
sl@0
   199
sl@0
   200
	if (fd == -1)
sl@0
   201
		fd = get_dev_crypto();
sl@0
   202
	return fd;
sl@0
   203
}
sl@0
   204
sl@0
   205
/*
sl@0
   206
 * XXXX this needs to be set for each alg - and determined from
sl@0
   207
 * a running card.
sl@0
   208
 */
sl@0
   209
static int
sl@0
   210
cryptodev_max_iv(int cipher)
sl@0
   211
{
sl@0
   212
	int i;
sl@0
   213
sl@0
   214
	for (i = 0; ciphers[i].id; i++)
sl@0
   215
		if (ciphers[i].id == cipher)
sl@0
   216
			return (ciphers[i].ivmax);
sl@0
   217
	return (0);
sl@0
   218
}
sl@0
   219
sl@0
   220
/*
sl@0
   221
 * XXXX this needs to be set for each alg - and determined from
sl@0
   222
 * a running card. For now, fake it out - but most of these
sl@0
   223
 * for real devices should return 1 for the supported key
sl@0
   224
 * sizes the device can handle.
sl@0
   225
 */
sl@0
   226
static int
sl@0
   227
cryptodev_key_length_valid(int cipher, int len)
sl@0
   228
{
sl@0
   229
	int i;
sl@0
   230
sl@0
   231
	for (i = 0; ciphers[i].id; i++)
sl@0
   232
		if (ciphers[i].id == cipher)
sl@0
   233
			return (ciphers[i].keylen == len);
sl@0
   234
	return (0);
sl@0
   235
}
sl@0
   236
sl@0
   237
/* convert libcrypto nids to cryptodev */
sl@0
   238
static int
sl@0
   239
cipher_nid_to_cryptodev(int nid)
sl@0
   240
{
sl@0
   241
	int i;
sl@0
   242
sl@0
   243
	for (i = 0; ciphers[i].id; i++)
sl@0
   244
		if (ciphers[i].nid == nid)
sl@0
   245
			return (ciphers[i].id);
sl@0
   246
	return (0);
sl@0
   247
}
sl@0
   248
sl@0
   249
/*
sl@0
   250
 * Find out what ciphers /dev/crypto will let us have a session for.
sl@0
   251
 * XXX note, that some of these openssl doesn't deal with yet!
sl@0
   252
 * returning them here is harmless, as long as we return NULL
sl@0
   253
 * when asked for a handler in the cryptodev_engine_ciphers routine
sl@0
   254
 */
sl@0
   255
static int
sl@0
   256
get_cryptodev_ciphers(const int **cnids)
sl@0
   257
{
sl@0
   258
	static int nids[CRYPTO_ALGORITHM_MAX];
sl@0
   259
	struct session_op sess;
sl@0
   260
	int fd, i, count = 0;
sl@0
   261
sl@0
   262
	if ((fd = get_dev_crypto()) < 0) {
sl@0
   263
		*cnids = NULL;
sl@0
   264
		return (0);
sl@0
   265
	}
sl@0
   266
	memset(&sess, 0, sizeof(sess));
sl@0
   267
	sess.key = (caddr_t)"123456781234567812345678";
sl@0
   268
sl@0
   269
	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
sl@0
   270
		if (ciphers[i].nid == NID_undef)
sl@0
   271
			continue;
sl@0
   272
		sess.cipher = ciphers[i].id;
sl@0
   273
		sess.keylen = ciphers[i].keylen;
sl@0
   274
		sess.mac = 0;
sl@0
   275
		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
sl@0
   276
		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
sl@0
   277
			nids[count++] = ciphers[i].nid;
sl@0
   278
	}
sl@0
   279
	close(fd);
sl@0
   280
sl@0
   281
	if (count > 0)
sl@0
   282
		*cnids = nids;
sl@0
   283
	else
sl@0
   284
		*cnids = NULL;
sl@0
   285
	return (count);
sl@0
   286
}
sl@0
   287
sl@0
   288
/*
sl@0
   289
 * Find out what digests /dev/crypto will let us have a session for.
sl@0
   290
 * XXX note, that some of these openssl doesn't deal with yet!
sl@0
   291
 * returning them here is harmless, as long as we return NULL
sl@0
   292
 * when asked for a handler in the cryptodev_engine_digests routine
sl@0
   293
 */
sl@0
   294
static int
sl@0
   295
get_cryptodev_digests(const int **cnids)
sl@0
   296
{
sl@0
   297
	static int nids[CRYPTO_ALGORITHM_MAX];
sl@0
   298
	struct session_op sess;
sl@0
   299
	int fd, i, count = 0;
sl@0
   300
sl@0
   301
	if ((fd = get_dev_crypto()) < 0) {
sl@0
   302
		*cnids = NULL;
sl@0
   303
		return (0);
sl@0
   304
	}
sl@0
   305
	memset(&sess, 0, sizeof(sess));
sl@0
   306
	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
sl@0
   307
		if (digests[i].nid == NID_undef)
sl@0
   308
			continue;
sl@0
   309
		sess.mac = digests[i].id;
sl@0
   310
		sess.cipher = 0;
sl@0
   311
		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
sl@0
   312
		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
sl@0
   313
			nids[count++] = digests[i].nid;
sl@0
   314
	}
sl@0
   315
	close(fd);
sl@0
   316
sl@0
   317
	if (count > 0)
sl@0
   318
		*cnids = nids;
sl@0
   319
	else
sl@0
   320
		*cnids = NULL;
sl@0
   321
	return (count);
sl@0
   322
}
sl@0
   323
sl@0
   324
/*
sl@0
   325
 * Find the useable ciphers|digests from dev/crypto - this is the first
sl@0
   326
 * thing called by the engine init crud which determines what it
sl@0
   327
 * can use for ciphers from this engine. We want to return
sl@0
   328
 * only what we can do, anythine else is handled by software.
sl@0
   329
 *
sl@0
   330
 * If we can't initialize the device to do anything useful for
sl@0
   331
 * any reason, we want to return a NULL array, and 0 length,
sl@0
   332
 * which forces everything to be done is software. By putting
sl@0
   333
 * the initalization of the device in here, we ensure we can
sl@0
   334
 * use this engine as the default, and if for whatever reason
sl@0
   335
 * /dev/crypto won't do what we want it will just be done in
sl@0
   336
 * software
sl@0
   337
 *
sl@0
   338
 * This can (should) be greatly expanded to perhaps take into
sl@0
   339
 * account speed of the device, and what we want to do.
sl@0
   340
 * (although the disabling of particular alg's could be controlled
sl@0
   341
 * by the device driver with sysctl's.) - this is where we
sl@0
   342
 * want most of the decisions made about what we actually want
sl@0
   343
 * to use from /dev/crypto.
sl@0
   344
 */
sl@0
   345
static int
sl@0
   346
cryptodev_usable_ciphers(const int **nids)
sl@0
   347
{
sl@0
   348
	return (get_cryptodev_ciphers(nids));
sl@0
   349
}
sl@0
   350
sl@0
   351
static int
sl@0
   352
cryptodev_usable_digests(const int **nids)
sl@0
   353
{
sl@0
   354
	/*
sl@0
   355
	 * XXXX just disable all digests for now, because it sucks.
sl@0
   356
	 * we need a better way to decide this - i.e. I may not
sl@0
   357
	 * want digests on slow cards like hifn on fast machines,
sl@0
   358
	 * but might want them on slow or loaded machines, etc.
sl@0
   359
	 * will also want them when using crypto cards that don't
sl@0
   360
	 * suck moose gonads - would be nice to be able to decide something
sl@0
   361
	 * as reasonable default without having hackery that's card dependent.
sl@0
   362
	 * of course, the default should probably be just do everything,
sl@0
   363
	 * with perhaps a sysctl to turn algoritms off (or have them off
sl@0
   364
	 * by default) on cards that generally suck like the hifn.
sl@0
   365
	 */
sl@0
   366
	*nids = NULL;
sl@0
   367
	return (0);
sl@0
   368
}
sl@0
   369
sl@0
   370
static int
sl@0
   371
cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
sl@0
   372
    const unsigned char *in, unsigned int inl)
sl@0
   373
{
sl@0
   374
	struct crypt_op cryp;
sl@0
   375
	struct dev_crypto_state *state = ctx->cipher_data;
sl@0
   376
	struct session_op *sess = &state->d_sess;
sl@0
   377
	void *iiv;
sl@0
   378
	unsigned char save_iv[EVP_MAX_IV_LENGTH];
sl@0
   379
sl@0
   380
	if (state->d_fd < 0)
sl@0
   381
		return (0);
sl@0
   382
	if (!inl)
sl@0
   383
		return (1);
sl@0
   384
	if ((inl % ctx->cipher->block_size) != 0)
sl@0
   385
		return (0);
sl@0
   386
sl@0
   387
	memset(&cryp, 0, sizeof(cryp));
sl@0
   388
sl@0
   389
	cryp.ses = sess->ses;
sl@0
   390
	cryp.flags = 0;
sl@0
   391
	cryp.len = inl;
sl@0
   392
	cryp.src = (caddr_t) in;
sl@0
   393
	cryp.dst = (caddr_t) out;
sl@0
   394
	cryp.mac = 0;
sl@0
   395
sl@0
   396
	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
sl@0
   397
sl@0
   398
	if (ctx->cipher->iv_len) {
sl@0
   399
		cryp.iv = (caddr_t) ctx->iv;
sl@0
   400
		if (!ctx->encrypt) {
sl@0
   401
			iiv = (void *) in + inl - ctx->cipher->iv_len;
sl@0
   402
			memcpy(save_iv, iiv, ctx->cipher->iv_len);
sl@0
   403
		}
sl@0
   404
	} else
sl@0
   405
		cryp.iv = NULL;
sl@0
   406
sl@0
   407
	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
sl@0
   408
		/* XXX need better errror handling
sl@0
   409
		 * this can fail for a number of different reasons.
sl@0
   410
		 */
sl@0
   411
		return (0);
sl@0
   412
	}
sl@0
   413
sl@0
   414
	if (ctx->cipher->iv_len) {
sl@0
   415
		if (ctx->encrypt)
sl@0
   416
			iiv = (void *) out + inl - ctx->cipher->iv_len;
sl@0
   417
		else
sl@0
   418
			iiv = save_iv;
sl@0
   419
		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
sl@0
   420
	}
sl@0
   421
	return (1);
sl@0
   422
}
sl@0
   423
sl@0
   424
static int
sl@0
   425
cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
sl@0
   426
    const unsigned char *iv, int enc)
sl@0
   427
{
sl@0
   428
	struct dev_crypto_state *state = ctx->cipher_data;
sl@0
   429
	struct session_op *sess = &state->d_sess;
sl@0
   430
	int cipher;
sl@0
   431
sl@0
   432
	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
sl@0
   433
		return (0);
sl@0
   434
sl@0
   435
	if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
sl@0
   436
		return (0);
sl@0
   437
sl@0
   438
	if (!cryptodev_key_length_valid(cipher, ctx->key_len))
sl@0
   439
		return (0);
sl@0
   440
sl@0
   441
	memset(sess, 0, sizeof(struct session_op));
sl@0
   442
sl@0
   443
	if ((state->d_fd = get_dev_crypto()) < 0)
sl@0
   444
		return (0);
sl@0
   445
sl@0
   446
	sess->key = (unsigned char *)key;
sl@0
   447
	sess->keylen = ctx->key_len;
sl@0
   448
	sess->cipher = cipher;
sl@0
   449
sl@0
   450
	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
sl@0
   451
		close(state->d_fd);
sl@0
   452
		state->d_fd = -1;
sl@0
   453
		return (0);
sl@0
   454
	}
sl@0
   455
	return (1);
sl@0
   456
}
sl@0
   457
sl@0
   458
/*
sl@0
   459
 * free anything we allocated earlier when initting a
sl@0
   460
 * session, and close the session.
sl@0
   461
 */
sl@0
   462
static int
sl@0
   463
cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
sl@0
   464
{
sl@0
   465
	int ret = 0;
sl@0
   466
	struct dev_crypto_state *state = ctx->cipher_data;
sl@0
   467
	struct session_op *sess = &state->d_sess;
sl@0
   468
sl@0
   469
	if (state->d_fd < 0)
sl@0
   470
		return (0);
sl@0
   471
sl@0
   472
	/* XXX if this ioctl fails, someting's wrong. the invoker
sl@0
   473
	 * may have called us with a bogus ctx, or we could
sl@0
   474
	 * have a device that for whatever reason just doesn't
sl@0
   475
	 * want to play ball - it's not clear what's right
sl@0
   476
	 * here - should this be an error? should it just
sl@0
   477
	 * increase a counter, hmm. For right now, we return
sl@0
   478
	 * 0 - I don't believe that to be "right". we could
sl@0
   479
	 * call the gorpy openssl lib error handlers that
sl@0
   480
	 * print messages to users of the library. hmm..
sl@0
   481
	 */
sl@0
   482
sl@0
   483
	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
sl@0
   484
		ret = 0;
sl@0
   485
	} else {
sl@0
   486
		ret = 1;
sl@0
   487
	}
sl@0
   488
	close(state->d_fd);
sl@0
   489
	state->d_fd = -1;
sl@0
   490
sl@0
   491
	return (ret);
sl@0
   492
}
sl@0
   493
sl@0
   494
/*
sl@0
   495
 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
sl@0
   496
 * gets called when libcrypto requests a cipher NID.
sl@0
   497
 */
sl@0
   498
sl@0
   499
/* DES CBC EVP */
sl@0
   500
const EVP_CIPHER cryptodev_des_cbc = {
sl@0
   501
	NID_des_cbc,
sl@0
   502
	8, 8, 8,
sl@0
   503
	EVP_CIPH_CBC_MODE,
sl@0
   504
	cryptodev_init_key,
sl@0
   505
	cryptodev_cipher,
sl@0
   506
	cryptodev_cleanup,
sl@0
   507
	sizeof(struct dev_crypto_state),
sl@0
   508
	EVP_CIPHER_set_asn1_iv,
sl@0
   509
	EVP_CIPHER_get_asn1_iv,
sl@0
   510
	NULL
sl@0
   511
};
sl@0
   512
sl@0
   513
/* 3DES CBC EVP */
sl@0
   514
const EVP_CIPHER cryptodev_3des_cbc = {
sl@0
   515
	NID_des_ede3_cbc,
sl@0
   516
	8, 24, 8,
sl@0
   517
	EVP_CIPH_CBC_MODE,
sl@0
   518
	cryptodev_init_key,
sl@0
   519
	cryptodev_cipher,
sl@0
   520
	cryptodev_cleanup,
sl@0
   521
	sizeof(struct dev_crypto_state),
sl@0
   522
	EVP_CIPHER_set_asn1_iv,
sl@0
   523
	EVP_CIPHER_get_asn1_iv,
sl@0
   524
	NULL
sl@0
   525
};
sl@0
   526
sl@0
   527
const EVP_CIPHER cryptodev_bf_cbc = {
sl@0
   528
	NID_bf_cbc,
sl@0
   529
	8, 16, 8,
sl@0
   530
	EVP_CIPH_CBC_MODE,
sl@0
   531
	cryptodev_init_key,
sl@0
   532
	cryptodev_cipher,
sl@0
   533
	cryptodev_cleanup,
sl@0
   534
	sizeof(struct dev_crypto_state),
sl@0
   535
	EVP_CIPHER_set_asn1_iv,
sl@0
   536
	EVP_CIPHER_get_asn1_iv,
sl@0
   537
	NULL
sl@0
   538
};
sl@0
   539
sl@0
   540
const EVP_CIPHER cryptodev_cast_cbc = {
sl@0
   541
	NID_cast5_cbc,
sl@0
   542
	8, 16, 8,
sl@0
   543
	EVP_CIPH_CBC_MODE,
sl@0
   544
	cryptodev_init_key,
sl@0
   545
	cryptodev_cipher,
sl@0
   546
	cryptodev_cleanup,
sl@0
   547
	sizeof(struct dev_crypto_state),
sl@0
   548
	EVP_CIPHER_set_asn1_iv,
sl@0
   549
	EVP_CIPHER_get_asn1_iv,
sl@0
   550
	NULL
sl@0
   551
};
sl@0
   552
sl@0
   553
const EVP_CIPHER cryptodev_aes_cbc = {
sl@0
   554
	NID_aes_128_cbc,
sl@0
   555
	16, 16, 16,
sl@0
   556
	EVP_CIPH_CBC_MODE,
sl@0
   557
	cryptodev_init_key,
sl@0
   558
	cryptodev_cipher,
sl@0
   559
	cryptodev_cleanup,
sl@0
   560
	sizeof(struct dev_crypto_state),
sl@0
   561
	EVP_CIPHER_set_asn1_iv,
sl@0
   562
	EVP_CIPHER_get_asn1_iv,
sl@0
   563
	NULL
sl@0
   564
};
sl@0
   565
sl@0
   566
/*
sl@0
   567
 * Registered by the ENGINE when used to find out how to deal with
sl@0
   568
 * a particular NID in the ENGINE. this says what we'll do at the
sl@0
   569
 * top level - note, that list is restricted by what we answer with
sl@0
   570
 */
sl@0
   571
static int
sl@0
   572
cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
sl@0
   573
    const int **nids, int nid)
sl@0
   574
{
sl@0
   575
	if (!cipher)
sl@0
   576
		return (cryptodev_usable_ciphers(nids));
sl@0
   577
sl@0
   578
	switch (nid) {
sl@0
   579
	case NID_des_ede3_cbc:
sl@0
   580
		*cipher = &cryptodev_3des_cbc;
sl@0
   581
		break;
sl@0
   582
	case NID_des_cbc:
sl@0
   583
		*cipher = &cryptodev_des_cbc;
sl@0
   584
		break;
sl@0
   585
	case NID_bf_cbc:
sl@0
   586
		*cipher = &cryptodev_bf_cbc;
sl@0
   587
		break;
sl@0
   588
	case NID_cast5_cbc:
sl@0
   589
		*cipher = &cryptodev_cast_cbc;
sl@0
   590
		break;
sl@0
   591
	case NID_aes_128_cbc:
sl@0
   592
		*cipher = &cryptodev_aes_cbc;
sl@0
   593
		break;
sl@0
   594
	default:
sl@0
   595
		*cipher = NULL;
sl@0
   596
		break;
sl@0
   597
	}
sl@0
   598
	return (*cipher != NULL);
sl@0
   599
}
sl@0
   600
sl@0
   601
static int
sl@0
   602
cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
sl@0
   603
    const int **nids, int nid)
sl@0
   604
{
sl@0
   605
	if (!digest)
sl@0
   606
		return (cryptodev_usable_digests(nids));
sl@0
   607
sl@0
   608
	switch (nid) {
sl@0
   609
	case NID_md5:
sl@0
   610
		*digest = NULL; /* need to make a clean md5 critter */
sl@0
   611
		break;
sl@0
   612
	default:
sl@0
   613
		*digest = NULL;
sl@0
   614
		break;
sl@0
   615
	}
sl@0
   616
	return (*digest != NULL);
sl@0
   617
}
sl@0
   618
sl@0
   619
/*
sl@0
   620
 * Convert a BIGNUM to the representation that /dev/crypto needs.
sl@0
   621
 * Upon completion of use, the caller is responsible for freeing
sl@0
   622
 * crp->crp_p.
sl@0
   623
 */
sl@0
   624
static int
sl@0
   625
bn2crparam(const BIGNUM *a, struct crparam *crp)
sl@0
   626
{
sl@0
   627
	int i, j, k;
sl@0
   628
	ssize_t words, bytes, bits;
sl@0
   629
	u_char *b;
sl@0
   630
sl@0
   631
	crp->crp_p = NULL;
sl@0
   632
	crp->crp_nbits = 0;
sl@0
   633
sl@0
   634
	bits = BN_num_bits(a);
sl@0
   635
	bytes = (bits + 7) / 8;
sl@0
   636
sl@0
   637
	b = malloc(bytes);
sl@0
   638
	if (b == NULL)
sl@0
   639
		return (1);
sl@0
   640
sl@0
   641
	crp->crp_p = b;
sl@0
   642
	crp->crp_nbits = bits;
sl@0
   643
sl@0
   644
	for (i = 0, j = 0; i < a->top; i++) {
sl@0
   645
		for (k = 0; k < BN_BITS2 / 8; k++) {
sl@0
   646
			if ((j + k) >= bytes)
sl@0
   647
				return (0);
sl@0
   648
			b[j + k] = a->d[i] >> (k * 8);
sl@0
   649
		}
sl@0
   650
		j += BN_BITS2 / 8;
sl@0
   651
	}
sl@0
   652
	return (0);
sl@0
   653
}
sl@0
   654
sl@0
   655
/* Convert a /dev/crypto parameter to a BIGNUM */
sl@0
   656
static int
sl@0
   657
crparam2bn(struct crparam *crp, BIGNUM *a)
sl@0
   658
{
sl@0
   659
	u_int8_t *pd;
sl@0
   660
	int i, bytes;
sl@0
   661
sl@0
   662
	bytes = (crp->crp_nbits + 7) / 8;
sl@0
   663
sl@0
   664
	if (bytes == 0)
sl@0
   665
		return (-1);
sl@0
   666
sl@0
   667
	if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
sl@0
   668
		return (-1);
sl@0
   669
sl@0
   670
	for (i = 0; i < bytes; i++)
sl@0
   671
		pd[i] = crp->crp_p[bytes - i - 1];
sl@0
   672
sl@0
   673
	BN_bin2bn(pd, bytes, a);
sl@0
   674
	free(pd);
sl@0
   675
sl@0
   676
	return (0);
sl@0
   677
}
sl@0
   678
sl@0
   679
static void
sl@0
   680
zapparams(struct crypt_kop *kop)
sl@0
   681
{
sl@0
   682
	int i;
sl@0
   683
sl@0
   684
	for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
sl@0
   685
		if (kop->crk_param[i].crp_p)
sl@0
   686
			free(kop->crk_param[i].crp_p);
sl@0
   687
		kop->crk_param[i].crp_p = NULL;
sl@0
   688
		kop->crk_param[i].crp_nbits = 0;
sl@0
   689
	}
sl@0
   690
}
sl@0
   691
sl@0
   692
static int
sl@0
   693
cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
sl@0
   694
{
sl@0
   695
	int fd, ret = -1;
sl@0
   696
sl@0
   697
	if ((fd = get_asym_dev_crypto()) < 0)
sl@0
   698
		return (ret);
sl@0
   699
sl@0
   700
	if (r) {
sl@0
   701
		kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
sl@0
   702
		kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
sl@0
   703
		kop->crk_oparams++;
sl@0
   704
	}
sl@0
   705
	if (s) {
sl@0
   706
		kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
sl@0
   707
		kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
sl@0
   708
		kop->crk_oparams++;
sl@0
   709
	}
sl@0
   710
sl@0
   711
	if (ioctl(fd, CIOCKEY, kop) == 0) {
sl@0
   712
		if (r)
sl@0
   713
			crparam2bn(&kop->crk_param[kop->crk_iparams], r);
sl@0
   714
		if (s)
sl@0
   715
			crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
sl@0
   716
		ret = 0;
sl@0
   717
	}
sl@0
   718
sl@0
   719
	return (ret);
sl@0
   720
}
sl@0
   721
sl@0
   722
static int
sl@0
   723
cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
sl@0
   724
    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
sl@0
   725
{
sl@0
   726
	struct crypt_kop kop;
sl@0
   727
	int ret = 1;
sl@0
   728
sl@0
   729
	/* Currently, we know we can do mod exp iff we can do any
sl@0
   730
	 * asymmetric operations at all.
sl@0
   731
	 */
sl@0
   732
	if (cryptodev_asymfeat == 0) {
sl@0
   733
		ret = BN_mod_exp(r, a, p, m, ctx);
sl@0
   734
		return (ret);
sl@0
   735
	}
sl@0
   736
sl@0
   737
	memset(&kop, 0, sizeof kop);
sl@0
   738
	kop.crk_op = CRK_MOD_EXP;
sl@0
   739
sl@0
   740
	/* inputs: a^p % m */
sl@0
   741
	if (bn2crparam(a, &kop.crk_param[0]))
sl@0
   742
		goto err;
sl@0
   743
	if (bn2crparam(p, &kop.crk_param[1]))
sl@0
   744
		goto err;
sl@0
   745
	if (bn2crparam(m, &kop.crk_param[2]))
sl@0
   746
		goto err;
sl@0
   747
	kop.crk_iparams = 3;
sl@0
   748
sl@0
   749
	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
sl@0
   750
		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
sl@0
   751
		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
sl@0
   752
	}
sl@0
   753
err:
sl@0
   754
	zapparams(&kop);
sl@0
   755
	return (ret);
sl@0
   756
}
sl@0
   757
sl@0
   758
static int
sl@0
   759
cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
sl@0
   760
{
sl@0
   761
	int r;
sl@0
   762
	BN_CTX *ctx;
sl@0
   763
sl@0
   764
	ctx = BN_CTX_new();
sl@0
   765
	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
sl@0
   766
	BN_CTX_free(ctx);
sl@0
   767
	return (r);
sl@0
   768
}
sl@0
   769
sl@0
   770
static int
sl@0
   771
cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
sl@0
   772
{
sl@0
   773
	struct crypt_kop kop;
sl@0
   774
	int ret = 1;
sl@0
   775
sl@0
   776
	if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
sl@0
   777
		/* XXX 0 means failure?? */
sl@0
   778
		return (0);
sl@0
   779
	}
sl@0
   780
sl@0
   781
	memset(&kop, 0, sizeof kop);
sl@0
   782
	kop.crk_op = CRK_MOD_EXP_CRT;
sl@0
   783
	/* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
sl@0
   784
	if (bn2crparam(rsa->p, &kop.crk_param[0]))
sl@0
   785
		goto err;
sl@0
   786
	if (bn2crparam(rsa->q, &kop.crk_param[1]))
sl@0
   787
		goto err;
sl@0
   788
	if (bn2crparam(I, &kop.crk_param[2]))
sl@0
   789
		goto err;
sl@0
   790
	if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
sl@0
   791
		goto err;
sl@0
   792
	if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
sl@0
   793
		goto err;
sl@0
   794
	if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
sl@0
   795
		goto err;
sl@0
   796
	kop.crk_iparams = 6;
sl@0
   797
sl@0
   798
	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
sl@0
   799
		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
sl@0
   800
		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
sl@0
   801
	}
sl@0
   802
err:
sl@0
   803
	zapparams(&kop);
sl@0
   804
	return (ret);
sl@0
   805
}
sl@0
   806
sl@0
   807
static RSA_METHOD cryptodev_rsa = {
sl@0
   808
	"cryptodev RSA method",
sl@0
   809
	NULL,				/* rsa_pub_enc */
sl@0
   810
	NULL,				/* rsa_pub_dec */
sl@0
   811
	NULL,				/* rsa_priv_enc */
sl@0
   812
	NULL,				/* rsa_priv_dec */
sl@0
   813
	NULL,
sl@0
   814
	NULL,
sl@0
   815
	NULL,				/* init */
sl@0
   816
	NULL,				/* finish */
sl@0
   817
	0,				/* flags */
sl@0
   818
	NULL,				/* app_data */
sl@0
   819
	NULL,				/* rsa_sign */
sl@0
   820
	NULL				/* rsa_verify */
sl@0
   821
};
sl@0
   822
sl@0
   823
static int
sl@0
   824
cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
sl@0
   825
    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
sl@0
   826
{
sl@0
   827
	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
sl@0
   828
}
sl@0
   829
sl@0
   830
static int
sl@0
   831
cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
sl@0
   832
    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
sl@0
   833
    BN_CTX *ctx, BN_MONT_CTX *mont)
sl@0
   834
{
sl@0
   835
	BIGNUM t2;
sl@0
   836
	int ret = 0;
sl@0
   837
sl@0
   838
	BN_init(&t2);
sl@0
   839
sl@0
   840
	/* v = ( g^u1 * y^u2 mod p ) mod q */
sl@0
   841
	/* let t1 = g ^ u1 mod p */
sl@0
   842
	ret = 0;
sl@0
   843
sl@0
   844
	if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
sl@0
   845
		goto err;
sl@0
   846
sl@0
   847
	/* let t2 = y ^ u2 mod p */
sl@0
   848
	if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
sl@0
   849
		goto err;
sl@0
   850
	/* let u1 = t1 * t2 mod p */
sl@0
   851
	if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
sl@0
   852
		goto err;
sl@0
   853
sl@0
   854
	BN_copy(t1,u1);
sl@0
   855
sl@0
   856
	ret = 1;
sl@0
   857
err:
sl@0
   858
	BN_free(&t2);
sl@0
   859
	return(ret);
sl@0
   860
}
sl@0
   861
sl@0
   862
static DSA_SIG *
sl@0
   863
cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
sl@0
   864
{
sl@0
   865
	struct crypt_kop kop;
sl@0
   866
	BIGNUM *r = NULL, *s = NULL;
sl@0
   867
	DSA_SIG *dsaret = NULL;
sl@0
   868
sl@0
   869
	if ((r = BN_new()) == NULL)
sl@0
   870
		goto err;
sl@0
   871
	if ((s = BN_new()) == NULL) {
sl@0
   872
		BN_free(r);
sl@0
   873
		goto err;
sl@0
   874
	}
sl@0
   875
sl@0
   876
	memset(&kop, 0, sizeof kop);
sl@0
   877
	kop.crk_op = CRK_DSA_SIGN;
sl@0
   878
sl@0
   879
	/* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
sl@0
   880
	kop.crk_param[0].crp_p = (caddr_t)dgst;
sl@0
   881
	kop.crk_param[0].crp_nbits = dlen * 8;
sl@0
   882
	if (bn2crparam(dsa->p, &kop.crk_param[1]))
sl@0
   883
		goto err;
sl@0
   884
	if (bn2crparam(dsa->q, &kop.crk_param[2]))
sl@0
   885
		goto err;
sl@0
   886
	if (bn2crparam(dsa->g, &kop.crk_param[3]))
sl@0
   887
		goto err;
sl@0
   888
	if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
sl@0
   889
		goto err;
sl@0
   890
	kop.crk_iparams = 5;
sl@0
   891
sl@0
   892
	if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
sl@0
   893
	    BN_num_bytes(dsa->q), s) == 0) {
sl@0
   894
		dsaret = DSA_SIG_new();
sl@0
   895
		dsaret->r = r;
sl@0
   896
		dsaret->s = s;
sl@0
   897
	} else {
sl@0
   898
		const DSA_METHOD *meth = DSA_OpenSSL();
sl@0
   899
		BN_free(r);
sl@0
   900
		BN_free(s);
sl@0
   901
		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
sl@0
   902
	}
sl@0
   903
err:
sl@0
   904
	kop.crk_param[0].crp_p = NULL;
sl@0
   905
	zapparams(&kop);
sl@0
   906
	return (dsaret);
sl@0
   907
}
sl@0
   908
sl@0
   909
static int
sl@0
   910
cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
sl@0
   911
    DSA_SIG *sig, DSA *dsa)
sl@0
   912
{
sl@0
   913
	struct crypt_kop kop;
sl@0
   914
	int dsaret = 1;
sl@0
   915
sl@0
   916
	memset(&kop, 0, sizeof kop);
sl@0
   917
	kop.crk_op = CRK_DSA_VERIFY;
sl@0
   918
sl@0
   919
	/* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
sl@0
   920
	kop.crk_param[0].crp_p = (caddr_t)dgst;
sl@0
   921
	kop.crk_param[0].crp_nbits = dlen * 8;
sl@0
   922
	if (bn2crparam(dsa->p, &kop.crk_param[1]))
sl@0
   923
		goto err;
sl@0
   924
	if (bn2crparam(dsa->q, &kop.crk_param[2]))
sl@0
   925
		goto err;
sl@0
   926
	if (bn2crparam(dsa->g, &kop.crk_param[3]))
sl@0
   927
		goto err;
sl@0
   928
	if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
sl@0
   929
		goto err;
sl@0
   930
	if (bn2crparam(sig->r, &kop.crk_param[5]))
sl@0
   931
		goto err;
sl@0
   932
	if (bn2crparam(sig->s, &kop.crk_param[6]))
sl@0
   933
		goto err;
sl@0
   934
	kop.crk_iparams = 7;
sl@0
   935
sl@0
   936
	if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
sl@0
   937
		dsaret = kop.crk_status;
sl@0
   938
	} else {
sl@0
   939
		const DSA_METHOD *meth = DSA_OpenSSL();
sl@0
   940
sl@0
   941
		dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
sl@0
   942
	}
sl@0
   943
err:
sl@0
   944
	kop.crk_param[0].crp_p = NULL;
sl@0
   945
	zapparams(&kop);
sl@0
   946
	return (dsaret);
sl@0
   947
}
sl@0
   948
sl@0
   949
static DSA_METHOD cryptodev_dsa = {
sl@0
   950
	"cryptodev DSA method",
sl@0
   951
	NULL,
sl@0
   952
	NULL,				/* dsa_sign_setup */
sl@0
   953
	NULL,
sl@0
   954
	NULL,				/* dsa_mod_exp */
sl@0
   955
	NULL,
sl@0
   956
	NULL,				/* init */
sl@0
   957
	NULL,				/* finish */
sl@0
   958
	0,	/* flags */
sl@0
   959
	NULL	/* app_data */
sl@0
   960
};
sl@0
   961
sl@0
   962
static int
sl@0
   963
cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
sl@0
   964
    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
sl@0
   965
    BN_MONT_CTX *m_ctx)
sl@0
   966
{
sl@0
   967
	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
sl@0
   968
}
sl@0
   969
sl@0
   970
static int
sl@0
   971
cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
sl@0
   972
{
sl@0
   973
	struct crypt_kop kop;
sl@0
   974
	int dhret = 1;
sl@0
   975
	int fd, keylen;
sl@0
   976
sl@0
   977
	if ((fd = get_asym_dev_crypto()) < 0) {
sl@0
   978
		const DH_METHOD *meth = DH_OpenSSL();
sl@0
   979
sl@0
   980
		return ((meth->compute_key)(key, pub_key, dh));
sl@0
   981
	}
sl@0
   982
sl@0
   983
	keylen = BN_num_bits(dh->p);
sl@0
   984
sl@0
   985
	memset(&kop, 0, sizeof kop);
sl@0
   986
	kop.crk_op = CRK_DH_COMPUTE_KEY;
sl@0
   987
sl@0
   988
	/* inputs: dh->priv_key pub_key dh->p key */
sl@0
   989
	if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
sl@0
   990
		goto err;
sl@0
   991
	if (bn2crparam(pub_key, &kop.crk_param[1]))
sl@0
   992
		goto err;
sl@0
   993
	if (bn2crparam(dh->p, &kop.crk_param[2]))
sl@0
   994
		goto err;
sl@0
   995
	kop.crk_iparams = 3;
sl@0
   996
sl@0
   997
	kop.crk_param[3].crp_p = key;
sl@0
   998
	kop.crk_param[3].crp_nbits = keylen * 8;
sl@0
   999
	kop.crk_oparams = 1;
sl@0
  1000
sl@0
  1001
	if (ioctl(fd, CIOCKEY, &kop) == -1) {
sl@0
  1002
		const DH_METHOD *meth = DH_OpenSSL();
sl@0
  1003
sl@0
  1004
		dhret = (meth->compute_key)(key, pub_key, dh);
sl@0
  1005
	}
sl@0
  1006
err:
sl@0
  1007
	kop.crk_param[3].crp_p = NULL;
sl@0
  1008
	zapparams(&kop);
sl@0
  1009
	return (dhret);
sl@0
  1010
}
sl@0
  1011
sl@0
  1012
static DH_METHOD cryptodev_dh = {
sl@0
  1013
	"cryptodev DH method",
sl@0
  1014
	NULL,				/* cryptodev_dh_generate_key */
sl@0
  1015
	NULL,
sl@0
  1016
	NULL,
sl@0
  1017
	NULL,
sl@0
  1018
	NULL,
sl@0
  1019
	0,	/* flags */
sl@0
  1020
	NULL	/* app_data */
sl@0
  1021
};
sl@0
  1022
sl@0
  1023
/*
sl@0
  1024
 * ctrl right now is just a wrapper that doesn't do much
sl@0
  1025
 * but I expect we'll want some options soon.
sl@0
  1026
 */
sl@0
  1027
static int
sl@0
  1028
cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
sl@0
  1029
{
sl@0
  1030
#ifdef HAVE_SYSLOG_R
sl@0
  1031
	struct syslog_data sd = SYSLOG_DATA_INIT;
sl@0
  1032
#endif
sl@0
  1033
sl@0
  1034
	switch (cmd) {
sl@0
  1035
	default:
sl@0
  1036
#ifdef HAVE_SYSLOG_R
sl@0
  1037
		syslog_r(LOG_ERR, &sd,
sl@0
  1038
		    "cryptodev_ctrl: unknown command %d", cmd);
sl@0
  1039
#else
sl@0
  1040
		syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
sl@0
  1041
#endif
sl@0
  1042
		break;
sl@0
  1043
	}
sl@0
  1044
	return (1);
sl@0
  1045
}
sl@0
  1046
sl@0
  1047
EXPORT_C void
sl@0
  1048
ENGINE_load_cryptodev(void)
sl@0
  1049
{
sl@0
  1050
	ENGINE *engine = ENGINE_new();
sl@0
  1051
	int fd;
sl@0
  1052
sl@0
  1053
	if (engine == NULL)
sl@0
  1054
		return;
sl@0
  1055
	if ((fd = get_dev_crypto()) < 0) {
sl@0
  1056
		ENGINE_free(engine);
sl@0
  1057
		return;
sl@0
  1058
	}
sl@0
  1059
sl@0
  1060
	/*
sl@0
  1061
	 * find out what asymmetric crypto algorithms we support
sl@0
  1062
	 */
sl@0
  1063
	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
sl@0
  1064
		close(fd);
sl@0
  1065
		ENGINE_free(engine);
sl@0
  1066
		return;
sl@0
  1067
	}
sl@0
  1068
	close(fd);
sl@0
  1069
sl@0
  1070
	if (!ENGINE_set_id(engine, "cryptodev") ||
sl@0
  1071
	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
sl@0
  1072
	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
sl@0
  1073
	    !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
sl@0
  1074
	    !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
sl@0
  1075
	    !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
sl@0
  1076
		ENGINE_free(engine);
sl@0
  1077
		return;
sl@0
  1078
	}
sl@0
  1079
sl@0
  1080
	if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
sl@0
  1081
		const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
sl@0
  1082
sl@0
  1083
		cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
sl@0
  1084
		cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
sl@0
  1085
		cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
sl@0
  1086
		cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
sl@0
  1087
		cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
sl@0
  1088
		cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
sl@0
  1089
		if (cryptodev_asymfeat & CRF_MOD_EXP) {
sl@0
  1090
			cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
sl@0
  1091
			if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
sl@0
  1092
				cryptodev_rsa.rsa_mod_exp =
sl@0
  1093
				    cryptodev_rsa_mod_exp;
sl@0
  1094
			else
sl@0
  1095
				cryptodev_rsa.rsa_mod_exp =
sl@0
  1096
				    cryptodev_rsa_nocrt_mod_exp;
sl@0
  1097
		}
sl@0
  1098
	}
sl@0
  1099
sl@0
  1100
	if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
sl@0
  1101
		const DSA_METHOD *meth = DSA_OpenSSL();
sl@0
  1102
sl@0
  1103
		memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
sl@0
  1104
		if (cryptodev_asymfeat & CRF_DSA_SIGN)
sl@0
  1105
			cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
sl@0
  1106
		if (cryptodev_asymfeat & CRF_MOD_EXP) {
sl@0
  1107
			cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
sl@0
  1108
			cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
sl@0
  1109
		}
sl@0
  1110
		if (cryptodev_asymfeat & CRF_DSA_VERIFY)
sl@0
  1111
			cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
sl@0
  1112
	}
sl@0
  1113
sl@0
  1114
	if (ENGINE_set_DH(engine, &cryptodev_dh)){
sl@0
  1115
		const DH_METHOD *dh_meth = DH_OpenSSL();
sl@0
  1116
sl@0
  1117
		cryptodev_dh.generate_key = dh_meth->generate_key;
sl@0
  1118
		cryptodev_dh.compute_key = dh_meth->compute_key;
sl@0
  1119
		cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
sl@0
  1120
		if (cryptodev_asymfeat & CRF_MOD_EXP) {
sl@0
  1121
			cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
sl@0
  1122
			if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
sl@0
  1123
				cryptodev_dh.compute_key =
sl@0
  1124
				    cryptodev_dh_compute_key;
sl@0
  1125
		}
sl@0
  1126
	}
sl@0
  1127
sl@0
  1128
	ENGINE_add(engine);
sl@0
  1129
	ENGINE_free(engine);
sl@0
  1130
	ERR_clear_error();
sl@0
  1131
}
sl@0
  1132
sl@0
  1133
#endif /* HAVE_CRYPTODEV */