- De-couple the software crypto implementation from the rest of the

framework.  There is no need to waste the space if you are only using
  algoritms provided by hardware accelerators.  To get the software
  implementations, add "pseudo-device swcr" to your kernel config.
- Lazily initialize the opencrypto framework when crypto drivers
  (either hardware or swcr) register themselves with the framework.
This commit is contained in:
thorpej 2005-11-25 16:16:46 +00:00
parent f7e281c38a
commit 7bc6d90c9d
12 changed files with 841 additions and 707 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: hifn7751.c,v 1.28 2005/10/16 20:26:47 tls Exp $ */
/* $NetBSD: hifn7751.c,v 1.29 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */
/* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */
@ -48,13 +48,12 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.28 2005/10/16 20:26:47 tls Exp $");
__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.29 2005/11/25 16:16:46 thorpej Exp $");
#include "rnd.h"
#include "opencrypto.h"
#if NRND == 0 || NOPENCRYPTO == 0
#error hifn7751 requires rnd and opencrypto pseudo-devices
#if NRND == 0
#error hifn7751 requires rnd pseudo-devices
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: ubsec.c,v 1.7 2005/06/28 00:28:42 thorpej Exp $ */
/* $NetBSD: ubsec.c,v 1.8 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */
/* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */
@ -59,7 +59,7 @@
#include <uvm/uvm_extern.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/cryptosoft.h>
#include <opencrypto/xform.h>
#ifdef __OpenBSD__
#include <dev/rndvar.h>
#include <sys/md5k.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.253 2005/11/18 21:55:14 martin Exp $ */
/* $NetBSD: init_main.c,v 1.254 2005/11/25 16:16:46 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.253 2005/11/18 21:55:14 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.254 2005/11/25 16:16:46 thorpej Exp $");
#include "fs_nfs.h"
#include "opt_nfsserver.h"
@ -87,7 +87,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.253 2005/11/18 21:55:14 martin Exp $
#include "opt_rootfs_magiclinks.h"
#include "opt_verified_exec.h"
#include "opencrypto.h"
#include "rnd.h"
#include "wlan.h"
@ -139,9 +138,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.253 2005/11/18 21:55:14 martin Exp $
#endif
#include <sys/domain.h>
#include <sys/namei.h>
#if NOPENCRYPTO > 0
#include <opencrypto/cryptodev.h> /* XXX really the framework */
#endif
#if NRND > 0
#include <sys/rnd.h>
#endif
@ -267,10 +263,6 @@ main(void)
tty_init(); /* initialize tty list */
#if NRND > 0
rnd_init(); /* initialize RNG */
#endif
#if NOPENCRYPTO > 0
/* Initialize crypto subsystem before configuring crypto hardware. */
(void)crypto_init();
#endif
/* Initialize the sysctl subsystem. */
sysctl_init();

View File

@ -1,4 +1,4 @@
/* $NetBSD: crypto.c,v 1.10 2005/02/26 22:39:52 perry Exp $ */
/* $NetBSD: crypto.c,v 1.11 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $ */
/* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */
@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.10 2005/02/26 22:39:52 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.11 2005/11/25 16:16:46 thorpej Exp $");
/* XXX FIXME: should be defopt'ed */
#define CRYPTO_TIMING /* enable cryptop timing stuff */
@ -36,12 +36,11 @@ __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.10 2005/02/26 22:39:52 perry Exp $");
#include <sys/proc.h>
#include <sys/pool.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/cryptosoft.h> /* swcr_init() */
#include <sys/kthread.h>
#include <sys/once.h>
#include <opencrypto/xform.h> /* XXX for M_XDATA */
#ifdef __NetBSD__
#define splcrypto splnet
/* below is kludges to check whats still missing */
@ -69,8 +68,8 @@ nanouptime(struct timespec *tp)
* crypto_drivers table with crypto_get_driverid() and then registering
* each algorithm they support with crypto_register() and crypto_kregister().
*/
static struct cryptocap *crypto_drivers = NULL;
static int crypto_drivers_num = 0;
static struct cryptocap *crypto_drivers;
static int crypto_drivers_num;
static void* softintr_cookie;
/*
@ -78,8 +77,10 @@ static void* softintr_cookie;
* cipher) operations and one for asymmetric (e.g. MOD) operations.
* See below for how synchronization is handled.
*/
static TAILQ_HEAD(,cryptop) crp_q; /* request queues */
static TAILQ_HEAD(,cryptkop) crp_kq;
static TAILQ_HEAD(,cryptop) crp_q = /* request queues */
TAILQ_HEAD_INITIALIZER(crp_q);
static TAILQ_HEAD(,cryptkop) crp_kq =
TAILQ_HEAD_INITIALIZER(crp_kq);
/*
* There are two queues for processing completed crypto requests; one
@ -87,8 +88,10 @@ static TAILQ_HEAD(,cryptkop) crp_kq;
* but have two to avoid type futzing (cryptop vs. cryptkop). See below
* for how synchronization is handled.
*/
static TAILQ_HEAD(,cryptop) crp_ret_q; /* callback queues */
static TAILQ_HEAD(,cryptkop) crp_ret_kq;
static TAILQ_HEAD(,cryptop) crp_ret_q = /* callback queues */
TAILQ_HEAD_INITIALIZER(crp_ret_q);
static TAILQ_HEAD(,cryptkop) crp_ret_kq =
TAILQ_HEAD_INITIALIZER(crp_ret_kq);
/*
* Crypto op and desciptor data structures are allocated
@ -99,7 +102,6 @@ struct pool cryptodesc_pool;
int crypto_pool_initialized = 0;
#ifdef __NetBSD__
void cryptoattach(int);
static void deferred_crypto_thread(void *arg);
#endif
@ -176,35 +178,28 @@ SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats,
cryptostats, "Crypto system statistics");
#endif /* __FreeBSD__ */
int
crypto_init(void)
static void
crypto_init0(void)
{
int error;
#ifdef __FreeBSD__
int error;
cryptop_zone = zinit("cryptop", sizeof (struct cryptop), 0, 0, 1);
cryptodesc_zone = zinit("cryptodesc", sizeof (struct cryptodesc),
0, 0, 1);
if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
printf("crypto_init: cannot setup crypto zones\n");
return ENOMEM;
return;
}
#endif
crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
crypto_drivers = malloc(crypto_drivers_num *
crypto_drivers = malloc(CRYPTO_DRIVERS_INITIAL *
sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
if (crypto_drivers == NULL) {
printf("crypto_init: cannot malloc driver table\n");
return ENOMEM;
return;
}
TAILQ_INIT(&crp_q);
TAILQ_INIT(&crp_kq);
TAILQ_INIT(&crp_ret_q);
TAILQ_INIT(&crp_ret_kq);
crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
softintr_cookie = register_swi(SWI_CRYPTO, cryptointr);
#ifdef __FreeBSD__
@ -218,9 +213,15 @@ crypto_init(void)
#else
/* defer thread creation until after boot */
kthread_create( deferred_crypto_thread, NULL);
error = 0;
#endif
return error;
}
void
crypto_init(void)
{
ONCE_DECL(crypto_init_once);
RUN_ONCE(&crypto_init_once, crypto_init0);
}
static void
@ -367,6 +368,8 @@ crypto_get_driverid(u_int32_t flags)
struct cryptocap *newdrv;
int i, s;
crypto_init();
s = splcrypto();
for (i = 0; i < crypto_drivers_num; i++)
if (crypto_drivers[i].cc_process == NULL &&
@ -1206,18 +1209,6 @@ deferred_crypto_thread(void *arg)
error);
crypto_destroy();
}
/*
* XXX in absence of FreeBSD mod_init(), call init hooks here,
* now that the thread used by software crypto is up and running.
*/
swcr_init();
}
void
cryptoattach(int n)
{
/* Nothing to do. */
}
#ifdef __FreeBSD__

View File

@ -1,4 +1,4 @@
/* $NetBSD: cryptodev.c,v 1.14 2005/08/22 23:11:47 jonathan Exp $ */
/* $NetBSD: cryptodev.c,v 1.15 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */
/* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $ */
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.14 2005/08/22 23:11:47 jonathan Exp $");
__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.15 2005/11/25 16:16:46 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -756,3 +756,16 @@ struct cdevsw crypto_cdevsw = {
/* kqfilter */ nokqfilter,
};
#ifdef __NetBSD__
/*
* Pseudo-device initialization routine for /dev/crypto
*/
void cryptoattach(int);
void
cryptoattach(int num)
{
/* nothing to do */
}
#endif /* __NetBSD__ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cryptodev.h,v 1.6 2005/02/26 22:39:52 perry Exp $ */
/* $NetBSD: cryptodev.h,v 1.7 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $ */
/* $OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $ */
@ -387,7 +387,7 @@ extern int crypto_devallowsoft; /* only use hardware crypto */
* (This declaration doesnt really belong here but there's no header
* for the raw framework.)
*/
int crypto_init(void);
void crypto_init(void);
/*
* Crypto-related utility routines used mainly by drivers.

View File

@ -1,4 +1,4 @@
/* $NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $ */
/* $NetBSD: cryptosoft.c,v 1.10 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.10 2005/11/25 16:16:46 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -37,29 +37,17 @@ __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $")
#include <opencrypto/cryptosoft.h>
#include <opencrypto/xform.h>
const u_int8_t hmac_ipad_buffer[64] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
};
#include <opencrypto/cryptosoft_xform.c>
const u_int8_t hmac_opad_buffer[64] = {
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
union authctx {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
RMD160_CTX rmd160ctx;
SHA256_CTX sha256ctx;
SHA384_CTX sha384ctx;
SHA512_CTX sha512ctx;
};
struct swcr_data **swcr_sessions = NULL;
u_int32_t swcr_sesnum = 0;
int32_t swcr_id = -1;
@ -88,12 +76,12 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
{
unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
struct enc_xform *exf;
const struct swcr_enc_xform *exf;
int i, k, j, blks;
int count, ind;
exf = sw->sw_exf;
blks = exf->blocksize;
blks = exf->enc_xform->blocksize;
/* Check for non-padded data */
if (crd->crd_len % blks)
@ -547,7 +535,7 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
struct swcr_data *sw, caddr_t buf, int outtype)
{
unsigned char aalg[AALG_MAX_RESULT_LEN];
struct auth_hash *axf;
const struct swcr_auth_hash *axf;
union authctx ctx;
int err;
@ -556,7 +544,7 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
axf = sw->sw_axf;
bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize);
switch (outtype) {
case CRYPTO_BUF_CONTIG:
@ -596,8 +584,8 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
return EINVAL;
axf->Final(aalg, &ctx);
bcopy(sw->sw_octx, &ctx, axf->ctxsize);
axf->Update(&ctx, aalg, axf->hashsize);
bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize);
axf->Update(&ctx, aalg, axf->auth_hash->hashsize);
axf->Final(aalg, &ctx);
break;
@ -620,14 +608,14 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
/* Inject the authentication data */
switch (outtype) {
case CRYPTO_BUF_CONTIG:
bcopy(aalg, buf + crd->crd_inject, axf->authsize);
bcopy(aalg, buf + crd->crd_inject, axf->auth_hash->authsize);
break;
case CRYPTO_BUF_MBUF:
m_copyback((struct mbuf *) buf, crd->crd_inject,
axf->authsize, aalg);
axf->auth_hash->authsize, aalg);
break;
case CRYPTO_BUF_IOV:
bcopy(aalg, crp->crp_mac, axf->authsize);
bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize);
break;
default:
return EINVAL;
@ -643,7 +631,7 @@ swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
caddr_t buf, int outtype)
{
u_int8_t *data, *out;
struct comp_algo *cxf;
const struct swcr_comp_algo *cxf;
int adj;
u_int32_t result;
@ -718,9 +706,9 @@ static int
swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
{
struct swcr_data **swd;
struct auth_hash *axf;
struct enc_xform *txf;
struct comp_algo *cxf;
const struct swcr_auth_hash *axf;
const struct swcr_enc_xform *txf;
const struct swcr_comp_algo *cxf;
u_int32_t i;
int k, error;
@ -778,25 +766,25 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
switch (cri->cri_alg) {
case CRYPTO_DES_CBC:
txf = &enc_xform_des;
txf = &swcr_enc_xform_des;
goto enccommon;
case CRYPTO_3DES_CBC:
txf = &enc_xform_3des;
txf = &swcr_enc_xform_3des;
goto enccommon;
case CRYPTO_BLF_CBC:
txf = &enc_xform_blf;
txf = &swcr_enc_xform_blf;
goto enccommon;
case CRYPTO_CAST_CBC:
txf = &enc_xform_cast5;
txf = &swcr_enc_xform_cast5;
goto enccommon;
case CRYPTO_SKIPJACK_CBC:
txf = &enc_xform_skipjack;
txf = &swcr_enc_xform_skipjack;
goto enccommon;
case CRYPTO_RIJNDAEL128_CBC:
txf = &enc_xform_rijndael128;
txf = &swcr_enc_xform_rijndael128;
goto enccommon;
case CRYPTO_NULL_CBC:
txf = &enc_xform_null;
txf = &swcr_enc_xform_null;
goto enccommon;
enccommon:
error = txf->setkey(&((*swd)->sw_kschedule),
@ -809,38 +797,38 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_MD5_HMAC:
axf = &auth_hash_hmac_md5_96;
axf = &swcr_auth_hash_hmac_md5_96;
goto authcommon;
case CRYPTO_SHA1_HMAC:
axf = &auth_hash_hmac_sha1_96;
axf = &swcr_auth_hash_hmac_sha1_96;
goto authcommon;
case CRYPTO_SHA2_HMAC:
if (cri->cri_klen == 256)
axf = &auth_hash_hmac_sha2_256;
axf = &swcr_auth_hash_hmac_sha2_256;
else if (cri->cri_klen == 384)
axf = &auth_hash_hmac_sha2_384;
axf = &swcr_auth_hash_hmac_sha2_384;
else if (cri->cri_klen == 512)
axf = &auth_hash_hmac_sha2_512;
axf = &swcr_auth_hash_hmac_sha2_512;
else {
swcr_freesession(NULL, i);
return EINVAL;
}
goto authcommon;
case CRYPTO_NULL_HMAC:
axf = &auth_hash_null;
axf = &swcr_auth_hash_null;
goto authcommon;
case CRYPTO_RIPEMD160_HMAC:
axf = &auth_hash_hmac_ripemd_160_96;
axf = &swcr_auth_hash_hmac_ripemd_160_96;
authcommon:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
(*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize,
M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession(NULL, i);
return ENOBUFS;
}
(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
(*swd)->sw_octx = malloc(axf->auth_hash->ctxsize,
M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_octx == NULL) {
swcr_freesession(NULL, i);
return ENOBUFS;
@ -870,14 +858,14 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_MD5_KPDK:
axf = &auth_hash_key_md5;
axf = &swcr_auth_hash_key_md5;
goto auth2common;
case CRYPTO_SHA1_KPDK:
axf = &auth_hash_key_sha1;
axf = &swcr_auth_hash_key_sha1;
auth2common:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
(*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize,
M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession(NULL, i);
return ENOBUFS;
@ -901,14 +889,14 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_MD5:
axf = &auth_hash_md5;
axf = &swcr_auth_hash_md5;
goto auth3common;
case CRYPTO_SHA1:
axf = &auth_hash_sha1;
axf = &swcr_auth_hash_sha1;
auth3common:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
(*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize,
M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession(NULL, i);
return ENOBUFS;
@ -919,7 +907,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_DEFLATE_COMP:
cxf = &comp_algo_deflate;
cxf = &swcr_comp_algo_deflate;
(*swd)->sw_cxf = cxf;
break;
default:
@ -941,9 +929,9 @@ static int
swcr_freesession(void *arg, u_int64_t tid)
{
struct swcr_data *swd;
struct enc_xform *txf;
struct auth_hash *axf;
struct comp_algo *cxf;
const struct swcr_enc_xform *txf;
const struct swcr_auth_hash *axf;
const struct swcr_comp_algo *cxf;
u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
if (sid > swcr_sesnum || swcr_sessions == NULL ||
@ -979,11 +967,11 @@ swcr_freesession(void *arg, u_int64_t tid)
axf = swd->sw_axf;
if (swd->sw_ictx) {
bzero(swd->sw_ictx, axf->ctxsize);
bzero(swd->sw_ictx, axf->auth_hash->ctxsize);
free(swd->sw_ictx, M_CRYPTO_DATA);
}
if (swd->sw_octx) {
bzero(swd->sw_octx, axf->ctxsize);
bzero(swd->sw_octx, axf->auth_hash->ctxsize);
free(swd->sw_octx, M_CRYPTO_DATA);
}
break;
@ -993,7 +981,7 @@ swcr_freesession(void *arg, u_int64_t tid)
axf = swd->sw_axf;
if (swd->sw_ictx) {
bzero(swd->sw_ictx, axf->ctxsize);
bzero(swd->sw_ictx, axf->auth_hash->ctxsize);
free(swd->sw_ictx, M_CRYPTO_DATA);
}
if (swd->sw_octx) {
@ -1125,11 +1113,7 @@ done:
return 0;
}
/*
* Initialize the driver, called from the kernel main().
*/
/*static*/
void
static void
swcr_init(void)
{
swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE);
@ -1165,3 +1149,17 @@ swcr_init(void)
#ifdef __FreeBSD__
SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
#endif
#ifdef __NetBSD__
/*
* Pseudo-device init routine for software crypto.
*/
void swcrattach(int);
void
swcrattach(int num)
{
swcr_init();
}
#endif /* __NetBSD__ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cryptosoft.h,v 1.2 2003/08/27 00:20:56 thorpej Exp $ */
/* $NetBSD: cryptosoft.h,v 1.3 2005/11/25 16:16:46 thorpej Exp $ */
/* $OpenBSD: cryptosoft.h,v 1.10 2002/04/22 23:10:09 deraadt Exp $ */
/*
@ -33,15 +33,15 @@ struct swcr_data {
u_int8_t *SW_ictx;
u_int8_t *SW_octx;
u_int32_t SW_klen;
struct auth_hash *SW_axf;
const struct swcr_auth_hash *SW_axf;
} SWCR_AUTH;
struct {
u_int8_t *SW_kschedule;
struct enc_xform *SW_exf;
const struct swcr_enc_xform *SW_exf;
} SWCR_ENC;
struct {
u_int32_t SW_size;
struct comp_algo *SW_cxf;
const struct swcr_comp_algo *SW_cxf;
} SWCR_COMP;
} SWCR_UN;
@ -57,10 +57,4 @@ struct swcr_data {
struct swcr_data *sw_next;
};
#ifdef _KERNEL
extern const u_int8_t hmac_ipad_buffer[64];
extern const u_int8_t hmac_opad_buffer[64];
void swcr_init(void);
#endif /* _KERNEL */
#endif /* _CRYPTO_CRYPTO_H_ */

View File

@ -0,0 +1,654 @@
/* $NetBSD: cryptosoft_xform.c,v 1.1 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
* Niels Provos (provos@physnet.uni-hamburg.de).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: cryptosoft_xform.c,v 1.1 2005/11/25 16:16:46 thorpej Exp $");
#include <crypto/blowfish/blowfish.h>
#include <crypto/cast128/cast128.h>
#include <crypto/des/des.h>
#include <crypto/rijndael/rijndael.h>
#include <crypto/ripemd160/rmd160.h>
#include <crypto/skipjack/skipjack.h>
#include <opencrypto/deflate.h>
#include <sys/md5.h>
#include <sys/sha1.h>
struct swcr_auth_hash {
struct auth_hash *auth_hash;
void (*Init)(void *);
int (*Update)(void *, const uint8_t *, uint16_t);
void (*Final)(uint8_t *, void *);
};
struct swcr_enc_xform {
struct enc_xform *enc_xform;
void (*encrypt)(caddr_t, uint8_t *);
void (*decrypt)(caddr_t, uint8_t *);
int (*setkey)(uint8_t **, const uint8_t *, int len);
void (*zerokey)(uint8_t **);
};
struct swcr_comp_algo {
struct comp_algo *comp_algo;
uint32_t (*compress)(uint8_t *, uint32_t, uint8_t **);
uint32_t (*decompress)(uint8_t *, uint32_t, uint8_t **);
};
static void null_encrypt(caddr_t, u_int8_t *);
static void null_decrypt(caddr_t, u_int8_t *);
static int null_setkey(u_int8_t **, const u_int8_t *, int);
static void null_zerokey(u_int8_t **);
static int des1_setkey(u_int8_t **, const u_int8_t *, int);
static int des3_setkey(u_int8_t **, const u_int8_t *, int);
static int blf_setkey(u_int8_t **, const u_int8_t *, int);
static int cast5_setkey(u_int8_t **, const u_int8_t *, int);
static int skipjack_setkey(u_int8_t **, const u_int8_t *, int);
static int rijndael128_setkey(u_int8_t **, const u_int8_t *, int);
static void des1_encrypt(caddr_t, u_int8_t *);
static void des3_encrypt(caddr_t, u_int8_t *);
static void blf_encrypt(caddr_t, u_int8_t *);
static void cast5_encrypt(caddr_t, u_int8_t *);
static void skipjack_encrypt(caddr_t, u_int8_t *);
static void rijndael128_encrypt(caddr_t, u_int8_t *);
static void des1_decrypt(caddr_t, u_int8_t *);
static void des3_decrypt(caddr_t, u_int8_t *);
static void blf_decrypt(caddr_t, u_int8_t *);
static void cast5_decrypt(caddr_t, u_int8_t *);
static void skipjack_decrypt(caddr_t, u_int8_t *);
static void rijndael128_decrypt(caddr_t, u_int8_t *);
static void des1_zerokey(u_int8_t **);
static void des3_zerokey(u_int8_t **);
static void blf_zerokey(u_int8_t **);
static void cast5_zerokey(u_int8_t **);
static void skipjack_zerokey(u_int8_t **);
static void rijndael128_zerokey(u_int8_t **);
static void null_init(void *);
static int null_update(void *, const u_int8_t *, u_int16_t);
static void null_final(u_int8_t *, void *);
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Init_int(void *);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
/* Encryption instances */
static const struct swcr_enc_xform swcr_enc_xform_null = {
&enc_xform_null,
null_encrypt,
null_decrypt,
null_setkey,
null_zerokey,
};
static const struct swcr_enc_xform swcr_enc_xform_des = {
&enc_xform_des,
des1_encrypt,
des1_decrypt,
des1_setkey,
des1_zerokey,
};
static const struct swcr_enc_xform swcr_enc_xform_3des = {
&enc_xform_3des,
des3_encrypt,
des3_decrypt,
des3_setkey,
des3_zerokey
};
static const struct swcr_enc_xform swcr_enc_xform_blf = {
&enc_xform_blf,
blf_encrypt,
blf_decrypt,
blf_setkey,
blf_zerokey
};
static const struct swcr_enc_xform swcr_enc_xform_cast5 = {
&enc_xform_cast5,
cast5_encrypt,
cast5_decrypt,
cast5_setkey,
cast5_zerokey
};
static const struct swcr_enc_xform swcr_enc_xform_skipjack = {
&enc_xform_skipjack,
skipjack_encrypt,
skipjack_decrypt,
skipjack_setkey,
skipjack_zerokey
};
static const struct swcr_enc_xform swcr_enc_xform_rijndael128 = {
&enc_xform_rijndael128,
rijndael128_encrypt,
rijndael128_decrypt,
rijndael128_setkey,
rijndael128_zerokey,
};
static const struct swcr_enc_xform swcr_enc_xform_arc4 = {
&enc_xform_arc4,
NULL,
NULL,
NULL,
NULL,
};
/* Authentication instances */
static const struct swcr_auth_hash swcr_auth_hash_null = {
&auth_hash_null,
null_init, null_update, null_final
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_md5_96 = {
&auth_hash_hmac_md5_96,
(void (*) (void *)) MD5Init, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_sha1_96 = {
&auth_hash_hmac_sha1_96,
SHA1Init_int, SHA1Update_int, SHA1Final_int
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_ripemd_160_96 = {
&auth_hash_hmac_ripemd_160_96,
(void (*)(void *)) RMD160Init, RMD160Update_int,
(void (*)(u_int8_t *, void *)) RMD160Final
};
static const struct swcr_auth_hash swcr_auth_hash_key_md5 = {
&auth_hash_key_md5,
(void (*)(void *)) MD5Init, MD5Update_int,
(void (*)(u_int8_t *, void *)) MD5Final
};
static const struct swcr_auth_hash swcr_auth_hash_key_sha1 = {
&auth_hash_key_sha1,
SHA1Init_int, SHA1Update_int, SHA1Final_int
};
static const struct swcr_auth_hash swcr_auth_hash_md5 = {
&auth_hash_md5,
(void (*) (void *)) MD5Init, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
};
static const struct swcr_auth_hash swcr_auth_hash_sha1 = {
&auth_hash_sha1,
(void (*)(void *)) SHA1Init, SHA1Update_int,
(void (*)(u_int8_t *, void *)) SHA1Final
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_sha2_256 = {
&auth_hash_hmac_sha2_256,
(void (*)(void *)) SHA256_Init, SHA256Update_int,
(void (*)(u_int8_t *, void *)) SHA256_Final
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_sha2_384 = {
&auth_hash_hmac_sha2_384,
(void (*)(void *)) SHA384_Init, SHA384Update_int,
(void (*)(u_int8_t *, void *)) SHA384_Final
};
static const struct swcr_auth_hash swcr_auth_hash_hmac_sha2_512 = {
&auth_hash_hmac_sha2_384,
(void (*)(void *)) SHA512_Init, SHA512Update_int,
(void (*)(u_int8_t *, void *)) SHA512_Final
};
/* Compression instance */
static const struct swcr_comp_algo swcr_comp_algo_deflate = {
&comp_algo_deflate,
deflate_compress,
deflate_decompress
};
/*
* Encryption wrapper routines.
*/
static void
null_encrypt(caddr_t key, u_int8_t *blk)
{
}
static void
null_decrypt(caddr_t key, u_int8_t *blk)
{
}
static int
null_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
*sched = NULL;
return 0;
}
static void
null_zerokey(u_int8_t **sched)
{
*sched = NULL;
}
static void
des1_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
}
static void
des1_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
}
static int
des1_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
MALLOC(p, des_key_schedule *, sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT);
if (p != NULL) {
bzero(p, sizeof(des_key_schedule));
des_set_key((des_cblock *)__UNCONST(key), p[0]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des1_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof (des_key_schedule));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
des3_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
}
static void
des3_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
}
static int
des3_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
MALLOC(p, des_key_schedule *, 3*sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT);
if (p != NULL) {
bzero(p, 3*sizeof(des_key_schedule));
des_set_key((des_cblock *)__UNCONST(key + 0), p[0]);
des_set_key((des_cblock *)__UNCONST(key + 8), p[1]);
des_set_key((des_cblock *)__UNCONST(key + 16), p[2]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des3_zerokey(u_int8_t **sched)
{
bzero(*sched, 3*sizeof (des_key_schedule));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
blf_encrypt(caddr_t key, u_int8_t *blk)
{
#if defined(__NetBSD__)
BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 1);
#else
blf_ecb_encrypt((blf_ctx *) key, blk, 8);
#endif
}
static void
blf_decrypt(caddr_t key, u_int8_t *blk)
{
#if defined(__NetBSD__)
BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 0);
#else
blf_ecb_decrypt((blf_ctx *) key, blk, 8);
#endif
}
static int
blf_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
#if defined(__FreeBSD__) || defined(__NetBSD__)
#define BLF_SIZ sizeof(BF_KEY)
#else
#define BLF_SIZ sizeof(blf_ctx)
#endif
MALLOC(*sched, u_int8_t *, BLF_SIZ,
M_CRYPTO_DATA, M_NOWAIT);
if (*sched != NULL) {
bzero(*sched, BLF_SIZ);
#if defined(__FreeBSD__) || defined(__NetBSD__)
BF_set_key((BF_KEY *) *sched, len, key);
#else
blf_key((blf_ctx *)*sched, key, len);
#endif
err = 0;
} else
err = ENOMEM;
return err;
}
static void
blf_zerokey(u_int8_t **sched)
{
bzero(*sched, BLF_SIZ);
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
cast5_encrypt(caddr_t key, u_int8_t *blk)
{
cast128_encrypt((cast128_key *) key, blk, blk);
}
static void
cast5_decrypt(caddr_t key, u_int8_t *blk)
{
cast128_decrypt((cast128_key *) key, blk, blk);
}
static int
cast5_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
MALLOC(*sched, u_int8_t *, sizeof(cast128_key), M_CRYPTO_DATA,
M_NOWAIT);
if (*sched != NULL) {
bzero(*sched, sizeof(cast128_key));
cast128_setkey((cast128_key *)*sched, key, len);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cast5_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(cast128_key));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
skipjack_encrypt(caddr_t key, u_int8_t *blk)
{
skipjack_forwards(blk, blk, (u_int8_t **) key);
}
static void
skipjack_decrypt(caddr_t key, u_int8_t *blk)
{
skipjack_backwards(blk, blk, (u_int8_t **) key);
}
static int
skipjack_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
/* NB: allocate all the memory that's needed at once */
/* XXX assumes bytes are aligned on sizeof(u_char) == 1 boundaries.
* Will this break a pdp-10, Cray-1, or GE-645 port?
*/
MALLOC(*sched, u_int8_t *, 10 * (sizeof(u_int8_t *) + 0x100),
M_CRYPTO_DATA, M_NOWAIT);
if (*sched != NULL) {
u_int8_t** key_tables = (u_int8_t**) *sched;
u_int8_t* table = (u_int8_t*) &key_tables[10];
int k;
bzero(*sched, 10 * sizeof(u_int8_t *)+0x100);
for (k = 0; k < 10; k++) {
key_tables[k] = table;
table += 0x100;
}
subkey_table_gen(key, (u_int8_t **) *sched);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
skipjack_zerokey(u_int8_t **sched)
{
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
{
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
{
rijndael_decrypt((rijndael_ctx *) key, (u_char *) blk,
(u_char *) blk);
}
static int
rijndael128_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
MALLOC(*sched, u_int8_t *, sizeof(rijndael_ctx), M_CRYPTO_DATA,
M_WAITOK);
if (*sched != NULL) {
bzero(*sched, sizeof(rijndael_ctx));
rijndael_set_key((rijndael_ctx *) *sched, key, len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
rijndael128_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(rijndael_ctx));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
/*
* And now for auth.
*/
static void
null_init(void *ctx)
{
}
static int
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
{
return 0;
}
static void
null_final(u_int8_t *buf, void *ctx)
{
if (buf != (u_int8_t *) 0)
bzero(buf, 12);
}
static int
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
RMD160Update(ctx, buf, len);
return 0;
}
static int
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
MD5Update(ctx, buf, len);
return 0;
}
static void
SHA1Init_int(void *ctx)
{
SHA1Init(ctx);
}
static int
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA1Update(ctx, buf, len);
return 0;
}
static void
SHA1Final_int(u_int8_t *blk, void *ctx)
{
SHA1Final(blk, ctx);
}
static int
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA256_Update(ctx, buf, len);
return 0;
}
static int
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA384_Update(ctx, buf, len);
return 0;
}
static int
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA512_Update(ctx, buf, len);
return 0;
}
/*
* And compression
*/
static u_int32_t
deflate_compress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 0, out);
}
static u_int32_t
deflate_decompress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 1, out);
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.opencrypto,v 1.15 2005/02/26 22:39:52 perry Exp $
# $NetBSD: files.opencrypto,v 1.16 2005/11/25 16:16:46 thorpej Exp $
#
#
@ -7,21 +7,19 @@
# that use the opencrypto framework, should list opencrypto as a dependency
# to pull in the framework.
define opencrypto: blowfish, des, cast128, rijndael, ripemd160, sha2, skipjack
file opencrypto/criov.c opencrypto needs-flag
file opencrypto/cryptosoft.c opencrypto
define opencrypto
file opencrypto/criov.c opencrypto
file opencrypto/xform.c opencrypto
file opencrypto/crypto.c opencrypto
# wrapper around zlib functions
file opencrypto/deflate.c opencrypto
# Pseudo-device that provides software implementations of various cryptographic
# algorithms.
defpseudo swcr: opencrypto,
blowfish, des, cast128, rijndael, ripemd160, sha2, skipjack
file opencrypto/cryptosoft.c swcr
file opencrypto/deflate.c swcr # wrapper around zlib
# Pseudo-device for userspace access to opencrypto
# (and thus crypto hardware accelerators).
defpseudo crypto: opencrypto
defpseudo crypto: opencrypto
file opencrypto/cryptodev.c crypto

View File

@ -1,4 +1,4 @@
/* $NetBSD: xform.c,v 1.14 2005/05/29 21:23:17 christos Exp $ */
/* $NetBSD: xform.c,v 1.15 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $ */
@ -40,628 +40,138 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.14 2005/05/29 21:23:17 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.15 2005/11/25 16:16:46 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <machine/cpu.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/cast128/cast128.h>
#include <crypto/des/des.h>
#include <crypto/rijndael/rijndael.h>
#include <crypto/ripemd160/rmd160.h>
#include <crypto/skipjack/skipjack.h>
#include <opencrypto/deflate.h>
#include <sys/md5.h>
#include <sys/sha1.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform.h>
static void null_encrypt(caddr_t, u_int8_t *);
static void null_decrypt(caddr_t, u_int8_t *);
static int null_setkey(u_int8_t **, const u_int8_t *, int);
static void null_zerokey(u_int8_t **);
static int des1_setkey(u_int8_t **, const u_int8_t *, int);
static int des3_setkey(u_int8_t **, const u_int8_t *, int);
static int blf_setkey(u_int8_t **, const u_int8_t *, int);
static int cast5_setkey(u_int8_t **, const u_int8_t *, int);
static int skipjack_setkey(u_int8_t **, const u_int8_t *, int);
static int rijndael128_setkey(u_int8_t **, const u_int8_t *, int);
static void des1_encrypt(caddr_t, u_int8_t *);
static void des3_encrypt(caddr_t, u_int8_t *);
static void blf_encrypt(caddr_t, u_int8_t *);
static void cast5_encrypt(caddr_t, u_int8_t *);
static void skipjack_encrypt(caddr_t, u_int8_t *);
static void rijndael128_encrypt(caddr_t, u_int8_t *);
static void des1_decrypt(caddr_t, u_int8_t *);
static void des3_decrypt(caddr_t, u_int8_t *);
static void blf_decrypt(caddr_t, u_int8_t *);
static void cast5_decrypt(caddr_t, u_int8_t *);
static void skipjack_decrypt(caddr_t, u_int8_t *);
static void rijndael128_decrypt(caddr_t, u_int8_t *);
static void des1_zerokey(u_int8_t **);
static void des3_zerokey(u_int8_t **);
static void blf_zerokey(u_int8_t **);
static void cast5_zerokey(u_int8_t **);
static void skipjack_zerokey(u_int8_t **);
static void rijndael128_zerokey(u_int8_t **);
static void null_init(void *);
static int null_update(void *, const u_int8_t *, u_int16_t);
static void null_final(u_int8_t *, void *);
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Init_int(void *);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
MALLOC_DEFINE(M_XDATA, "xform", "xform data buffers");
const u_int8_t hmac_ipad_buffer[64] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
};
const u_int8_t hmac_opad_buffer[64] = {
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
};
/* Encryption instances */
struct enc_xform enc_xform_null = {
CRYPTO_NULL_CBC, "NULL",
/* NB: blocksize of 4 is to generate a properly aligned ESP header */
4, 0, 256, /* 2048 bits, max key */
null_encrypt,
null_decrypt,
null_setkey,
null_zerokey,
4, 0, 256 /* 2048 bits, max key */
};
struct enc_xform enc_xform_des = {
CRYPTO_DES_CBC, "DES",
8, 8, 8,
des1_encrypt,
des1_decrypt,
des1_setkey,
des1_zerokey,
8, 8, 8
};
struct enc_xform enc_xform_3des = {
CRYPTO_3DES_CBC, "3DES",
8, 24, 24,
des3_encrypt,
des3_decrypt,
des3_setkey,
des3_zerokey
8, 24, 24
};
struct enc_xform enc_xform_blf = {
CRYPTO_BLF_CBC, "Blowfish",
8, 5, 56 /* 448 bits, max key */,
blf_encrypt,
blf_decrypt,
blf_setkey,
blf_zerokey
8, 5, 56 /* 448 bits, max key */
};
struct enc_xform enc_xform_cast5 = {
CRYPTO_CAST_CBC, "CAST-128",
8, 5, 16,
cast5_encrypt,
cast5_decrypt,
cast5_setkey,
cast5_zerokey
8, 5, 16
};
struct enc_xform enc_xform_skipjack = {
CRYPTO_SKIPJACK_CBC, "Skipjack",
8, 10, 10,
skipjack_encrypt,
skipjack_decrypt,
skipjack_setkey,
skipjack_zerokey
8, 10, 10
};
struct enc_xform enc_xform_rijndael128 = {
CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
16, 8, 32,
rijndael128_encrypt,
rijndael128_decrypt,
rijndael128_setkey,
rijndael128_zerokey,
16, 8, 32
};
struct enc_xform enc_xform_arc4 = {
CRYPTO_ARC4, "ARC4",
1, 1, 32,
NULL,
NULL,
NULL,
NULL,
1, 1, 32
};
/* Authentication instances */
struct auth_hash auth_hash_null = {
CRYPTO_NULL_HMAC, "NULL-HMAC",
0, 0, 12, sizeof(int), /* NB: context isn't used */
null_init, null_update, null_final
0, 0, 12, sizeof(int) /* NB: context isn't used */
};
struct auth_hash auth_hash_hmac_md5_96 = {
CRYPTO_MD5_HMAC, "HMAC-MD5",
16, 16, 12, sizeof(MD5_CTX),
(void (*) (void *)) MD5Init, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
16, 16, 12, sizeof(MD5_CTX)
};
struct auth_hash auth_hash_hmac_sha1_96 = {
CRYPTO_SHA1_HMAC, "HMAC-SHA1",
20, 20, 12, sizeof(SHA1_CTX),
SHA1Init_int, SHA1Update_int, SHA1Final_int
20, 20, 12, sizeof(SHA1_CTX)
};
struct auth_hash auth_hash_hmac_ripemd_160_96 = {
CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
20, 20, 12, sizeof(RMD160_CTX),
(void (*)(void *)) RMD160Init, RMD160Update_int,
(void (*)(u_int8_t *, void *)) RMD160Final
20, 20, 12, sizeof(RMD160_CTX)
};
struct auth_hash auth_hash_key_md5 = {
CRYPTO_MD5_KPDK, "Keyed MD5",
0, 16, 16, sizeof(MD5_CTX),
(void (*)(void *)) MD5Init, MD5Update_int,
(void (*)(u_int8_t *, void *)) MD5Final
0, 16, 16, sizeof(MD5_CTX)
};
struct auth_hash auth_hash_key_sha1 = {
CRYPTO_SHA1_KPDK, "Keyed SHA1",
0, 20, 20, sizeof(SHA1_CTX),
SHA1Init_int, SHA1Update_int, SHA1Final_int
0, 20, 20, sizeof(SHA1_CTX)
};
struct auth_hash auth_hash_md5 = {
CRYPTO_MD5, "MD5",
0, 16, 16, sizeof(MD5_CTX),
(void (*) (void *)) MD5Init, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
0, 16, 16, sizeof(MD5_CTX)
};
struct auth_hash auth_hash_sha1 = {
CRYPTO_SHA1, "SHA1",
0, 20, 20, sizeof(SHA1_CTX),
(void (*)(void *)) SHA1Init, SHA1Update_int,
(void (*)(u_int8_t *, void *)) SHA1Final
0, 20, 20, sizeof(SHA1_CTX)
};
struct auth_hash auth_hash_hmac_sha2_256 = {
CRYPTO_SHA2_HMAC, "HMAC-SHA2",
32, 32, 12, sizeof(SHA256_CTX),
(void (*)(void *)) SHA256_Init, SHA256Update_int,
(void (*)(u_int8_t *, void *)) SHA256_Final
32, 32, 12, sizeof(SHA256_CTX)
};
struct auth_hash auth_hash_hmac_sha2_384 = {
CRYPTO_SHA2_HMAC, "HMAC-SHA2-384",
48, 48, 12, sizeof(SHA384_CTX),
(void (*)(void *)) SHA384_Init, SHA384Update_int,
(void (*)(u_int8_t *, void *)) SHA384_Final
48, 48, 12, sizeof(SHA384_CTX)
};
struct auth_hash auth_hash_hmac_sha2_512 = {
CRYPTO_SHA2_HMAC, "HMAC-SHA2-512",
64, 64, 12, sizeof(SHA512_CTX),
(void (*)(void *)) SHA512_Init, SHA512Update_int,
(void (*)(u_int8_t *, void *)) SHA512_Final
64, 64, 12, sizeof(SHA512_CTX)
};
/* Compression instance */
struct comp_algo comp_algo_deflate = {
CRYPTO_DEFLATE_COMP, "Deflate",
90, deflate_compress,
deflate_decompress
90
};
/*
* Encryption wrapper routines.
*/
static void
null_encrypt(caddr_t key, u_int8_t *blk)
{
}
static void
null_decrypt(caddr_t key, u_int8_t *blk)
{
}
static int
null_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
*sched = NULL;
return 0;
}
static void
null_zerokey(u_int8_t **sched)
{
*sched = NULL;
}
static void
des1_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
}
static void
des1_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
}
static int
des1_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
MALLOC(p, des_key_schedule *, sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT);
if (p != NULL) {
bzero(p, sizeof(des_key_schedule));
des_set_key((des_cblock *)__UNCONST(key), p[0]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des1_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof (des_key_schedule));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
des3_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
}
static void
des3_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
}
static int
des3_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
MALLOC(p, des_key_schedule *, 3*sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT);
if (p != NULL) {
bzero(p, 3*sizeof(des_key_schedule));
des_set_key((des_cblock *)__UNCONST(key + 0), p[0]);
des_set_key((des_cblock *)__UNCONST(key + 8), p[1]);
des_set_key((des_cblock *)__UNCONST(key + 16), p[2]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des3_zerokey(u_int8_t **sched)
{
bzero(*sched, 3*sizeof (des_key_schedule));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
blf_encrypt(caddr_t key, u_int8_t *blk)
{
#if defined(__NetBSD__)
BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 1);
#else
blf_ecb_encrypt((blf_ctx *) key, blk, 8);
#endif
}
static void
blf_decrypt(caddr_t key, u_int8_t *blk)
{
#if defined(__NetBSD__)
BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 0);
#else
blf_ecb_decrypt((blf_ctx *) key, blk, 8);
#endif
}
static int
blf_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
#if defined(__FreeBSD__) || defined(__NetBSD__)
#define BLF_SIZ sizeof(BF_KEY)
#else
#define BLF_SIZ sizeof(blf_ctx)
#endif
MALLOC(*sched, u_int8_t *, BLF_SIZ,
M_CRYPTO_DATA, M_NOWAIT);
if (*sched != NULL) {
bzero(*sched, BLF_SIZ);
#if defined(__FreeBSD__) || defined(__NetBSD__)
BF_set_key((BF_KEY *) *sched, len, key);
#else
blf_key((blf_ctx *)*sched, key, len);
#endif
err = 0;
} else
err = ENOMEM;
return err;
}
static void
blf_zerokey(u_int8_t **sched)
{
bzero(*sched, BLF_SIZ);
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
cast5_encrypt(caddr_t key, u_int8_t *blk)
{
cast128_encrypt((cast128_key *) key, blk, blk);
}
static void
cast5_decrypt(caddr_t key, u_int8_t *blk)
{
cast128_decrypt((cast128_key *) key, blk, blk);
}
static int
cast5_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
MALLOC(*sched, u_int8_t *, sizeof(cast128_key), M_CRYPTO_DATA,
M_NOWAIT);
if (*sched != NULL) {
bzero(*sched, sizeof(cast128_key));
cast128_setkey((cast128_key *)*sched, key, len);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cast5_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(cast128_key));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
skipjack_encrypt(caddr_t key, u_int8_t *blk)
{
skipjack_forwards(blk, blk, (u_int8_t **) key);
}
static void
skipjack_decrypt(caddr_t key, u_int8_t *blk)
{
skipjack_backwards(blk, blk, (u_int8_t **) key);
}
static int
skipjack_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
/* NB: allocate all the memory that's needed at once */
/* XXX assumes bytes are aligned on sizeof(u_char) == 1 boundaries.
* Will this break a pdp-10, Cray-1, or GE-645 port?
*/
MALLOC(*sched, u_int8_t *, 10 * (sizeof(u_int8_t *) + 0x100),
M_CRYPTO_DATA, M_NOWAIT);
if (*sched != NULL) {
u_int8_t** key_tables = (u_int8_t**) *sched;
u_int8_t* table = (u_int8_t*) &key_tables[10];
int k;
bzero(*sched, 10 * sizeof(u_int8_t *)+0x100);
for (k = 0; k < 10; k++) {
key_tables[k] = table;
table += 0x100;
}
subkey_table_gen(key, (u_int8_t **) *sched);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
skipjack_zerokey(u_int8_t **sched)
{
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
{
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
{
rijndael_decrypt((rijndael_ctx *) key, (u_char *) blk,
(u_char *) blk);
}
static int
rijndael128_setkey(u_int8_t **sched, const u_int8_t *key, int len)
{
int err;
MALLOC(*sched, u_int8_t *, sizeof(rijndael_ctx), M_CRYPTO_DATA,
M_WAITOK);
if (*sched != NULL) {
bzero(*sched, sizeof(rijndael_ctx));
rijndael_set_key((rijndael_ctx *) *sched, key, len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
rijndael128_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(rijndael_ctx));
FREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
/*
* And now for auth.
*/
static void
null_init(void *ctx)
{
}
static int
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
{
return 0;
}
static void
null_final(u_int8_t *buf, void *ctx)
{
if (buf != (u_int8_t *) 0)
bzero(buf, 12);
}
static int
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
RMD160Update(ctx, buf, len);
return 0;
}
static int
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
MD5Update(ctx, buf, len);
return 0;
}
static void
SHA1Init_int(void *ctx)
{
SHA1Init(ctx);
}
static int
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA1Update(ctx, buf, len);
return 0;
}
static void
SHA1Final_int(u_int8_t *blk, void *ctx)
{
SHA1Final(blk, ctx);
}
static int
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA256_Update(ctx, buf, len);
return 0;
}
static int
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA384_Update(ctx, buf, len);
return 0;
}
static int
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA512_Update(ctx, buf, len);
return 0;
}
/*
* And compression
*/
static u_int32_t
deflate_compress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 0, out);
}
static u_int32_t
deflate_decompress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 1, out);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: xform.h,v 1.6 2005/05/29 21:23:17 christos Exp $ */
/* $NetBSD: xform.h,v 1.7 2005/11/25 16:16:46 thorpej Exp $ */
/* $FreeBSD: src/sys/opencrypto/xform.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: xform.h,v 1.10 2002/04/22 23:10:09 deraadt Exp $ */
@ -39,9 +39,6 @@ struct auth_hash {
u_int16_t hashsize;
u_int16_t authsize;
u_int16_t ctxsize;
void (*Init) (void *);
int (*Update) (void *, const u_int8_t *, u_int16_t);
void (*Final) (u_int8_t *, void *);
};
/* Provide array-limit for clients (e.g., netipsec) */
@ -52,28 +49,16 @@ struct enc_xform {
const char *name;
u_int16_t blocksize;
u_int16_t minkey, maxkey;
void (*encrypt) (caddr_t, u_int8_t *);
void (*decrypt) (caddr_t, u_int8_t *);
int (*setkey) (u_int8_t **, const u_int8_t *, int len);
void (*zerokey) (u_int8_t **);
};
struct comp_algo {
int type;
const char *name;
size_t minlen;
u_int32_t (*compress) (u_int8_t *, u_int32_t, u_int8_t **);
u_int32_t (*decompress) (u_int8_t *, u_int32_t, u_int8_t **);
};
union authctx {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
RMD160_CTX rmd160ctx;
SHA256_CTX sha256ctx;
SHA384_CTX sha384ctx;
SHA512_CTX sha512ctx;
};
extern const u_int8_t hmac_ipad_buffer[64];
extern const u_int8_t hmac_opad_buffer[64];
extern struct enc_xform enc_xform_null;
extern struct enc_xform enc_xform_des;