From: <kr...@us...> - 2007-11-05 08:01:55
|
Revision: 1360 http://astlinux.svn.sourceforge.net/astlinux/?rev=1360&view=rev Author: krisk84 Date: 2007-11-05 00:01:58 -0800 (Mon, 05 Nov 2007) Log Message: ----------- initial support for OCF Modified Paths: -------------- trunk/astlinux.config trunk/package/openssl/Config.in trunk/package/openssl/openssl.mk trunk/target/device/geni586/linux.config trunk/target/device/net4801/linux.config trunk/target/device/net5501/linux.config trunk/target/device/via/linux.config trunk/target/device/via-c7/linux.config trunk/target/device/wrap/linux.config Added Paths: ----------- trunk/package/openssl/ocf.patch trunk/target/device/kernel-patches/linux-2.6.20.18-ocf.patch Modified: trunk/astlinux.config =================================================================== --- trunk/astlinux.config 2007-11-05 07:02:47 UTC (rev 1359) +++ trunk/astlinux.config 2007-11-05 08:01:58 UTC (rev 1360) @@ -298,6 +298,7 @@ BR2_PACKAGE_OPENSSH=y BR2_PACKAGE_OPENSSL=y # BR2_PACKAGE_OPENSSL_TARGET_HEADERS is not set +# BR2_PACKAGE_OPENSSL_OCF is not set BR2_PACKAGE_OPENVPN=y BR2_PACKAGE_PCIUTILS=y # BR2_PACKAGE_PCMCIA is not set Modified: trunk/package/openssl/Config.in =================================================================== --- trunk/package/openssl/Config.in 2007-11-05 07:02:47 UTC (rev 1359) +++ trunk/package/openssl/Config.in 2007-11-05 08:01:58 UTC (rev 1360) @@ -15,3 +15,15 @@ depends on BR2_PACKAGE_OPENSSL help Put openssl headers in the target. + +config BR2_PACKAGE_OPENSSL_OCF + bool "openssl cryptodev engine support from OCF" + default y + depends on BR2_PACKAGE_OPENSSL + help + Apply openssl patchset from ocf which provides access + to kernel hardware and software cryptographic devices + on linux. + + http://ocf-linux.sourceforge.net + Added: trunk/package/openssl/ocf.patch =================================================================== --- trunk/package/openssl/ocf.patch (rev 0) +++ trunk/package/openssl/ocf.patch 2007-11-05 08:01:58 UTC (rev 1360) @@ -0,0 +1,425 @@ +diff -ruN openssl-0.9.7m.orig/apps/speed.c openssl-0.9.7m/apps/speed.c +--- openssl-0.9.7m.orig/apps/speed.c 2005-05-15 21:26:01.000000000 -0400 ++++ openssl-0.9.7m/apps/speed.c 2007-08-29 08:09:55.000000000 -0400 +@@ -260,10 +260,88 @@ + #define START 0 + #define STOP 1 + ++#ifdef __linux__ ++/* ++ * record CPU usage as well ++ */ ++ ++static int do_cpu = 0; ++ ++struct cpu_stat { ++ unsigned int user; ++ unsigned int nice; ++ unsigned int system; ++ unsigned int idle; ++ unsigned int total; ++}; ++ ++static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM]; ++static unsigned int rsa_cpu_usage[RSA_NUM][2]; ++static unsigned int dsa_cpu_usage[DSA_NUM][2]; ++static struct cpu_stat cpu_start, cpu_finish; ++ ++static void ++get_cpu(int s) ++{ ++ FILE *fp = NULL; ++ unsigned char buf[80]; ++ struct cpu_stat *st = s == START ? &cpu_start : &cpu_finish; ++ ++ memset(st, 0, sizeof(*st)); ++ ++ if (fp == NULL) ++ fp = fopen("/proc/stat", "r"); ++ if (!fp) ++ return; ++ if (fseek(fp, 0, SEEK_SET) == -1) { ++ fclose(fp); ++ return; ++ } ++ fscanf(fp, "%s %d %d %d %d", &buf[0], &st->user, &st->nice, ++ &st->system, &st->idle); ++ st->total = st->user + st->nice + st->system + st->idle; ++ fclose(fp); ++} ++ ++static unsigned int ++calc_cpu() ++{ ++ unsigned int total, res; ++ ++ total = cpu_finish.total - cpu_start.total; ++ if (total <= 0) ++ return 0; ++#if 1 // busy ++ res = ((cpu_finish.system + cpu_finish.user + cpu_finish.nice) - ++ (cpu_start.system + cpu_start.user + cpu_start.nice)) * ++ 100 / total; ++#endif ++#if 0 // system ++ res = (cpu_finish.system - cpu_start.system) * 100 / total; ++#endif ++#if 0 // user ++ res = (cpu_finish.user - cpu_start.user) * 100 / total; ++#endif ++#if 0 // nice ++ res = (cpu_finish.nice - cpu_start.nice) * 100 / total; ++#endif ++#if 0 // idle ++ res = (cpu_finish.idle - cpu_start.idle) * 100 / total; ++#endif ++ return(res); ++} ++ ++#endif ++ + static double Time_F(int s) + { + double ret; + ++#ifdef __linux__ ++ if (do_cpu) ++ get_cpu(s); ++#endif ++ + #ifdef USE_TOD + if(usertime) + { +@@ -567,6 +645,14 @@ + j--; /* Otherwise, -elapsed gets confused with + an algorithm. */ + } ++#ifdef __linux__ ++ else if ((argc > 0) && (strcmp(*argv,"-cpu") == 0)) ++ { ++ do_cpu = 1; ++ j--; /* Otherwise, -cpu gets confused with ++ an algorithm. */ ++ } ++#endif + else if ((argc > 0) && (strcmp(*argv,"-evp") == 0)) + { + argc--; +@@ -881,6 +967,9 @@ + #ifdef HAVE_FORK + BIO_printf(bio_err,"-multi n run n benchmarks in parallel.\n"); + #endif ++#ifdef __linux__ ++ BIO_printf(bio_err,"-cpu calculate cpu utilisation.\n"); ++#endif + goto end; + } + argc--; +@@ -888,11 +977,6 @@ + j++; + } + +-#ifdef HAVE_FORK +- if(multi && do_multi(multi)) +- goto show_res; +-#endif +- + if (j == 0) + { + for (i=0; i<ALGOR_NUM; i++) +@@ -1091,6 +1175,11 @@ + signal(SIGALRM,sig_done); + #endif /* SIGALRM */ + ++#ifdef HAVE_FORK /* DM */ ++ if(multi && do_multi(multi)) ++ goto show_res; ++#endif ++ + #ifndef OPENSSL_NO_MD2 + if (doit[D_MD2]) + { +@@ -1387,8 +1476,6 @@ + /* -O3 -fschedule-insns messes up an + * optimization here! names[D_EVP] + * somehow becomes NULL */ +- print_message(names[D_EVP],save_count, +- lengths[j]); + + EVP_CIPHER_CTX_init(&ctx); + if(decrypt) +@@ -1397,6 +1484,9 @@ + EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv); + EVP_CIPHER_CTX_set_padding(&ctx, 0); + ++ print_message(names[D_EVP],save_count, ++ lengths[j]); ++ + Time_F(START); + if(decrypt) + for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++) +@@ -1461,6 +1551,8 @@ + } + } + d=Time_F(STOP); ++ if (do_cpu) ++ rsa_cpu_usage[j][0] = calc_cpu(); + BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n" + : "%ld %d bit private RSA's in %.2fs\n", + count,rsa_bits[j],d); +@@ -1496,6 +1588,8 @@ + } + } + d=Time_F(STOP); ++ if (do_cpu) ++ rsa_cpu_usage[j][1] = calc_cpu(); + BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n" + : "%ld %d bit public RSA's in %.2fs\n", + count,rsa_bits[j],d); +@@ -1555,6 +1649,8 @@ + } + } + d=Time_F(STOP); ++ if (do_cpu) ++ dsa_cpu_usage[j][0] = calc_cpu(); + BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n" + : "%ld %d bit DSA signs in %.2fs\n", + count,dsa_bits[j],d); +@@ -1590,6 +1686,8 @@ + } + } + d=Time_F(STOP); ++ if (do_cpu) ++ dsa_cpu_usage[j][1] = calc_cpu(); + BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n" + : "%ld %d bit DSA verify in %.2fs\n", + count,dsa_bits[j],d); +@@ -1670,14 +1768,19 @@ + fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n"); + fprintf(stdout,"type "); + } +- for (j=0; j<SIZE_NUM; j++) ++ for (j=0; j<SIZE_NUM; j++) { + fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]); ++ if (do_cpu && !mr) ++ fprintf(stdout, " /cpu"); ++ } + fprintf(stdout,"\n"); + } + + for (k=0; k<ALGOR_NUM; k++) + { + if (!doit[k]) continue; ++ if (k == D_EVP) ++ names[D_EVP]=OBJ_nid2ln(evp_cipher->nid); + if(mr) + fprintf(stdout,"+F:%d:%s",k,names[k]); + else +@@ -1688,6 +1791,8 @@ + fprintf(stdout," %11.2fk",results[k][j]/1e3); + else + fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]); ++ if (do_cpu) ++ fprintf(stdout, mr ? "/%d" : "/%%%-3d", cpu_usage[k][j]); + } + fprintf(stdout,"\n"); + } +@@ -1702,13 +1807,18 @@ + j=0; + } + if(mr) +- fprintf(stdout,"+F2:%u:%u:%f:%f\n", +- k,rsa_bits[k],rsa_results[k][0], +- rsa_results[k][1]); +- else +- fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", +- rsa_bits[k],rsa_results[k][0],rsa_results[k][1], +- 1.0/rsa_results[k][0],1.0/rsa_results[k][1]); ++ fprintf(stdout,"+F2:%u:%u:%f", k,rsa_bits[k],rsa_results[k][0]); ++ else ++ fprintf(stdout,"rsa %4u bits %8.4fs",rsa_bits[k],rsa_results[k][0]); ++ if (do_cpu) ++ fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][0]); ++ fprintf(stdout, mr ? ":%f" : " %8.4fs", rsa_results[k][1]); ++ if (do_cpu) ++ fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][1]); ++ if(!mr) ++ fprintf(stdout, " %8.1f %8.1f", ++ 1.0/rsa_results[k][0],1.0/rsa_results[k][1]); ++ fprintf(stdout, "\n"); + } + #endif + #ifndef OPENSSL_NO_DSA +@@ -1722,12 +1832,18 @@ + j=0; + } + if(mr) +- fprintf(stdout,"+F3:%u:%u:%f:%f\n", +- k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]); ++ fprintf(stdout,"+F3:%u:%u:%f", k,dsa_bits[k],dsa_results[k][0]); + else +- fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", +- dsa_bits[k],dsa_results[k][0],dsa_results[k][1], +- 1.0/dsa_results[k][0],1.0/dsa_results[k][1]); ++ fprintf(stdout,"dsa %4u bits %8.4fs",dsa_bits[k],dsa_results[k][0]); ++ if (do_cpu) ++ fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][0]); ++ fprintf(stdout, mr ? ":%f" : " %8.4fs", dsa_results[k][1]); ++ if (do_cpu) ++ fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][1]); ++ if(!mr) ++ fprintf(stdout, " %8.1f %8.1f", ++ 1.0/dsa_results[k][0],1.0/dsa_results[k][1]); ++ fprintf(stdout, "\n"); + } + #endif + mret=0; +@@ -1786,6 +1902,8 @@ + + static void print_result(int alg,int run_no,int count,double time_used) + { ++ if (do_cpu) ++ cpu_usage[alg][run_no] = calc_cpu(); + BIO_printf(bio_err,mr ? "+R:%ld:%s:%f\n" + : "%ld %s's in %.2fs\n",count,names[alg],time_used); + results[alg][run_no]=((double)count)/time_used*lengths[run_no]; +@@ -1880,29 +1998,11 @@ + p=buf+3; + alg=atoi(sstrsep(&p,sep)); + sstrsep(&p,sep); +- for(j=0 ; j < SIZE_NUM ; ++j) ++ for(j=0 ; j < SIZE_NUM ; ++j) { ++ if (do_cpu && strchr(p, '/')) ++ cpu_usage[alg][j] = atoi(strchr(p, '/') + 1); + results[alg][j]+=atof(sstrsep(&p,sep)); + } +- else if(!strncmp(buf,"+F2:",4)) +- { +- int k; +- double d; +- +- p=buf+4; +- k=atoi(sstrsep(&p,sep)); +- sstrsep(&p,sep); +- +- d=atof(sstrsep(&p,sep)); +- if(n) +- rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d); +- else +- rsa_results[k][0]=d; +- +- d=atof(sstrsep(&p,sep)); +- if(n) +- rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d); +- else +- rsa_results[k][1]=d; + } + else if(!strncmp(buf,"+F2:",4)) + { +@@ -1913,12 +2013,18 @@ + k=atoi(sstrsep(&p,sep)); + sstrsep(&p,sep); + ++ /* before we move the token along */ ++ if (do_cpu && strchr(p, '/')) ++ rsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1); + d=atof(sstrsep(&p,sep)); + if(n) + rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d); + else + rsa_results[k][0]=d; + ++ /* before we move the token along */ ++ if (do_cpu && strchr(p, '/')) ++ rsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1); + d=atof(sstrsep(&p,sep)); + if(n) + rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d); +@@ -1934,12 +2040,18 @@ + k=atoi(sstrsep(&p,sep)); + sstrsep(&p,sep); + ++ /* before we move the token along */ ++ if (do_cpu && strchr(p, '/')) ++ dsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1); + d=atof(sstrsep(&p,sep)); + if(n) + dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d); + else + dsa_results[k][0]=d; + ++ /* before we move the token along */ ++ if (do_cpu && strchr(p, '/')) ++ dsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1); + d=atof(sstrsep(&p,sep)); + if(n) + dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d); +diff -ruN openssl-0.9.7m.orig/crypto/engine/eng_all.c openssl-0.9.7m/crypto/engine/eng_all.c +--- openssl-0.9.7m.orig/crypto/engine/eng_all.c 2003-01-16 13:29:33.000000000 -0500 ++++ openssl-0.9.7m/crypto/engine/eng_all.c 2007-08-29 08:04:22.000000000 -0400 +@@ -95,13 +95,13 @@ + #ifndef OPENSSL_NO_HW_4758_CCA + ENGINE_load_4758cca(); + #endif +-#if defined(__OpenBSD__) || defined(__FreeBSD__) ++#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__linux__) + ENGINE_load_cryptodev(); + #endif + #endif + } + +-#if defined(__OpenBSD__) || defined(__FreeBSD__) ++#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__linux__) + void ENGINE_setup_bsd_cryptodev(void) { + static int bsd_cryptodev_default_loaded = 0; + if (!bsd_cryptodev_default_loaded) { +diff -ruN openssl-0.9.7m.orig/crypto/engine/engine.h openssl-0.9.7m/crypto/engine/engine.h +--- openssl-0.9.7m.orig/crypto/engine/engine.h 2003-11-29 05:25:41.000000000 -0500 ++++ openssl-0.9.7m/crypto/engine/engine.h 2007-08-29 08:04:22.000000000 -0400 +@@ -633,7 +633,7 @@ + if(!fn(e,id)) return 0; \ + return 1; } + +-#if defined(__OpenBSD__) || defined(__FreeBSD__) ++#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__linux__) + void ENGINE_setup_bsd_cryptodev(void); + #endif + +diff -ruN openssl-0.9.7m.orig/crypto/engine/hw_cryptodev.c openssl-0.9.7m/crypto/engine/hw_cryptodev.c +--- openssl-0.9.7m.orig/crypto/engine/hw_cryptodev.c 2004-06-15 07:46:06.000000000 -0400 ++++ openssl-0.9.7m/crypto/engine/hw_cryptodev.c 2007-08-29 08:04:22.000000000 -0400 +@@ -32,7 +32,7 @@ + + #if (defined(__unix__) || defined(unix)) && !defined(USG) + #include <sys/param.h> +-# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) ++# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__linux__) + # define HAVE_CRYPTODEV + # endif + # if (OpenBSD >= 200110) +@@ -264,7 +264,7 @@ + return (0); + } + memset(&sess, 0, sizeof(sess)); +- sess.key = (caddr_t)"123456781234567812345678"; ++ sess.key = (caddr_t)"123456789abcdefghijklmno"; + + for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (ciphers[i].nid == NID_undef) +@@ -639,6 +639,7 @@ + b = malloc(bytes); + if (b == NULL) + return (1); ++ memset(b, 0, bytes); + + crp->crp_p = b; + crp->crp_nbits = bits; +@@ -683,7 +684,7 @@ + { + int i; + +- for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) { ++ for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { + if (kop->crk_param[i].crp_p) + free(kop->crk_param[i].crp_p); + kop->crk_param[i].crp_p = NULL; Modified: trunk/package/openssl/openssl.mk =================================================================== --- trunk/package/openssl/openssl.mk 2007-11-05 07:02:47 UTC (rev 1359) +++ trunk/package/openssl/openssl.mk 2007-11-05 08:01:58 UTC (rev 1360) @@ -36,6 +36,9 @@ toolchain/patch-kernel.sh $(OPENSSL_DIR) package/openssl/ padlock\*.patch endif toolchain/patch-kernel.sh $(OPENSSL_DIR) package/openssl/ openssl\*.patch +ifeq ($(BR2_PACKAGE_OPENSSL_OCF),y) + toolchain/patch-kernel.sh $(OPENSSL_DIR) package/openssl/ ocf\*.patch +endif # sigh... we have to resort to this just to set a gcc flag. $(SED) 's,/CFLAG=,/CFLAG= $(TARGET_SOFT_FLOAT) ,g' \ $(OPENSSL_DIR)/Configure Modified: trunk/target/device/geni586/linux.config =================================================================== --- trunk/target/device/geni586/linux.config 2007-11-05 07:02:47 UTC (rev 1359) +++ trunk/target/device/geni586/linux.config 2007-11-05 08:01:58 UTC (rev 1360) @@ -2205,6 +2205,22 @@ CONFIG_CRYPTO_DEV_GEODE=m # +# OCF Configuration +# +CONFIG_OCF_OCF=m +CONFIG_OCF_RANDOMHARVEST=m +CONFIG_OCF_FIPS=m +CONFIG_OCF_CRYPTODEV=m +CONFIG_OCF_CRYPTOSOFT=m +CONFIG_OCF_SAFE=m +# CONFIG_OCF_IXP4XX is not set +CONFIG_OCF_HIFN=m +CONFIG_OCF_HIFNHIPP=m +# CONFIG_OCF_TALITOS is not set +CONFIG_OCF_OCFNULL=m +CONFIG_OCF_BENCH=m + +# # Library routines # CONFIG_BITREVERSE=y Added: trunk/target/device/kernel-patches/linux-2.6.20.18-ocf.patch =================================================================== --- trunk/target/device/kernel-patches/linux-2.6.20.18-ocf.patch (rev 0) +++ trunk/target/device/kernel-patches/linux-2.6.20.18-ocf.patch 2007-11-05 08:01:58 UTC (rev 1360) @@ -0,0 +1,18239 @@ +diff -urN linux-2.6.20.18.orig/crypto/Kconfig linux-2.6.20.18/crypto/Kconfig +--- linux-2.6.20.18.orig/crypto/Kconfig 2007-08-28 06:15:07.000000000 -0400 ++++ linux-2.6.20.18/crypto/Kconfig 2007-11-05 02:25:26.000000000 -0500 +@@ -470,3 +470,6 @@ + endif # if CRYPTO + + endmenu ++ ++source "crypto/ocf/Kconfig" ++ +diff -urN linux-2.6.20.18.orig/crypto/Kconfig.orig linux-2.6.20.18/crypto/Kconfig.orig +--- linux-2.6.20.18.orig/crypto/Kconfig.orig 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.20.18/crypto/Kconfig.orig 2007-08-28 06:15:07.000000000 -0400 +@@ -0,0 +1,472 @@ ++# ++# Cryptographic API Configuration ++# ++ ++menu "Cryptographic options" ++ ++config CRYPTO ++ bool "Cryptographic API" ++ help ++ This option provides the core Cryptographic API. ++ ++if CRYPTO ++ ++config CRYPTO_ALGAPI ++ tristate ++ help ++ This option provides the API for cryptographic algorithms. ++ ++config CRYPTO_BLKCIPHER ++ tristate ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_HASH ++ tristate ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_MANAGER ++ tristate "Cryptographic algorithm manager" ++ select CRYPTO_ALGAPI ++ help ++ Create default cryptographic template instantiations such as ++ cbc(aes). ++ ++config CRYPTO_HMAC ++ tristate "HMAC support" ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ help ++ HMAC: Keyed-Hashing for Message Authentication (RFC2104). ++ This is required for IPSec. ++ ++config CRYPTO_XCBC ++ tristate "XCBC support" ++ depends on EXPERIMENTAL ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ help ++ XCBC: Keyed-Hashing with encryption algorithm ++ http://www.ietf.org/rfc/rfc3566.txt ++ http://csrc.nist.gov/encryption/modes/proposedmodes/ ++ xcbc-mac/xcbc-mac-spec.pdf ++ ++config CRYPTO_NULL ++ tristate "Null algorithms" ++ select CRYPTO_ALGAPI ++ help ++ These are 'Null' algorithms, used by IPsec, which do nothing. ++ ++config CRYPTO_MD4 ++ tristate "MD4 digest algorithm" ++ select CRYPTO_ALGAPI ++ help ++ MD4 message digest algorithm (RFC1320). ++ ++config CRYPTO_MD5 ++ tristate "MD5 digest algorithm" ++ select CRYPTO_ALGAPI ++ help ++ MD5 message digest algorithm (RFC1321). ++ ++config CRYPTO_SHA1 ++ tristate "SHA1 digest algorithm" ++ select CRYPTO_ALGAPI ++ help ++ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). ++ ++config CRYPTO_SHA1_S390 ++ tristate "SHA1 digest algorithm (s390)" ++ depends on S390 ++ select CRYPTO_ALGAPI ++ help ++ This is the s390 hardware accelerated implementation of the ++ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). ++ ++config CRYPTO_SHA256 ++ tristate "SHA256 digest algorithm" ++ select CRYPTO_ALGAPI ++ help ++ SHA256 secure hash standard (DFIPS 180-2). ++ ++ This version of SHA implements a 256 bit hash with 128 bits of ++ security against collision attacks. ++ ++config CRYPTO_SHA256_S390 ++ tristate "SHA256 digest algorithm (s390)" ++ depends on S390 ++ select CRYPTO_ALGAPI ++ help ++ This is the s390 hardware accelerated implementation of the ++ SHA256 secure hash standard (DFIPS 180-2). ++ ++ This version of SHA implements a 256 bit hash with 128 bits of ++ security against collision attacks. ++ ++config CRYPTO_SHA512 ++ tristate "SHA384 and SHA512 digest algorithms" ++ select CRYPTO_ALGAPI ++ help ++ SHA512 secure hash standard (DFIPS 180-2). ++ ++ This version of SHA implements a 512 bit hash with 256 bits of ++ security against collision attacks. ++ ++ This code also includes SHA-384, a 384 bit hash with 192 bits ++ of security against collision attacks. ++ ++config CRYPTO_WP512 ++ tristate "Whirlpool digest algorithms" ++ select CRYPTO_ALGAPI ++ help ++ Whirlpool hash algorithm 512, 384 and 256-bit hashes ++ ++ Whirlpool-512 is part of the NESSIE cryptographic primitives. ++ Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard ++ ++ See also: ++ <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html> ++ ++config CRYPTO_TGR192 ++ tristate "Tiger digest algorithms" ++ select CRYPTO_ALGAPI ++ help ++ Tiger hash algorithm 192, 160 and 128-bit hashes ++ ++ Tiger is a hash function optimized for 64-bit processors while ++ still having decent performance on 32-bit processors. ++ Tiger was developed by Ross Anderson and Eli Biham. ++ ++ See also: ++ <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>. ++ ++config CRYPTO_GF128MUL ++ tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ help ++ Efficient table driven implementation of multiplications in the ++ field GF(2^128). This is needed by some cypher modes. This ++ option will be selected automatically if you select such a ++ cipher mode. Only select this option by hand if you expect to load ++ an external module that requires these functions. ++ ++config CRYPTO_ECB ++ tristate "ECB support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ default m ++ help ++ ECB: Electronic CodeBook mode ++ This is the simplest block cipher algorithm. It simply encrypts ++ the input block by block. ++ ++config CRYPTO_CBC ++ tristate "CBC support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ default m ++ help ++ CBC: Cipher Block Chaining mode ++ This block cipher algorithm is required for IPSec. ++ ++config CRYPTO_LRW ++ tristate "LRW support (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ select CRYPTO_GF128MUL ++ help ++ LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable ++ narrow block cipher mode for dm-crypt. Use it with cipher ++ specification string aes-lrw-benbi, the key must be 256, 320 or 384. ++ The first 128, 192 or 256 bits in the key are used for AES and the ++ rest is used to tie each cipher block to its logical position. ++ ++config CRYPTO_DES ++ tristate "DES and Triple DES EDE cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). ++ ++config CRYPTO_DES_S390 ++ tristate "DES and Triple DES cipher algorithms (s390)" ++ depends on S390 ++ select CRYPTO_ALGAPI ++ select CRYPTO_BLKCIPHER ++ help ++ DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). ++ ++config CRYPTO_BLOWFISH ++ tristate "Blowfish cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Blowfish cipher algorithm, by Bruce Schneier. ++ ++ This is a variable key length cipher which can use keys from 32 ++ bits to 448 bits in length. It's fast, simple and specifically ++ designed for use on "large microprocessors". ++ ++ See also: ++ <http://www.schneier.com/blowfish.html> ++ ++config CRYPTO_TWOFISH ++ tristate "Twofish cipher algorithm" ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm. ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ <http://www.schneier.com/twofish.html> ++ ++config CRYPTO_TWOFISH_COMMON ++ tristate ++ help ++ Common parts of the Twofish cipher algorithm shared by the ++ generic c and the assembler implementations. ++ ++config CRYPTO_TWOFISH_586 ++ tristate "Twofish cipher algorithms (i586)" ++ depends on (X86 || UML_X86) && !64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm. ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ <http://www.schneier.com/twofish.html> ++ ++config CRYPTO_TWOFISH_X86_64 ++ tristate "Twofish cipher algorithm (x86_64)" ++ depends on (X86 || UML_X86) && 64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm (x86_64). ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ <http://www.schneier.com/twofish.html> ++ ++config CRYPTO_SERPENT ++ tristate "Serpent cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Serpent cipher algorithm, by Anderson, Biham & Knudsen. ++ ++ Keys are allowed to be from 0 to 256 bits in length, in steps ++ of 8 bits. Also includes the 'Tnepres' algorithm, a reversed ++ variant of Serpent for compatibility with old kerneli code. ++ ++ See also: ++ <http://www.cl.cam.ac.uk/~rja14/serpent.html> ++ ++config CRYPTO_AES ++ tristate "AES cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information. ++ ++config CRYPTO_AES_586 ++ tristate "AES cipher algorithms (i586)" ++ depends on (X86 || UML_X86) && !64BIT ++ select CRYPTO_ALGAPI ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See <http://csrc.nist.gov/encryption/aes/> for more information. ++ ++config CRYPTO_AES_X86_64 ++ tristate "AES cipher algorithms (x86_64)" ++ depends on (X86 || UML_X86) && 64BIT ++ select CRYPTO_ALGAPI ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See <http://csrc.nist.gov/encryption/aes/> for more information. ++ ++config CRYPTO_AES_S390 ++ tristate "AES cipher algorithms (s390)" ++ depends on S390 ++ select CRYPTO_ALGAPI ++ select CRYPTO_BLKCIPHER ++ help ++ This is the s390 hardware accelerated implementation of the ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ On s390 the System z9-109 currently only supports the key size ++ of 128 bit. ++ ++config CRYPTO_CAST5 ++ tristate "CAST5 (CAST-128) cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ The CAST5 encryption algorithm (synonymous with CAST-128) is ++ described in RFC2144. ++ ++config CRYPTO_CAST6 ++ tristate "CAST6 (CAST-256) cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ The CAST6 encryption algorithm (synonymous with CAST-256) is ++ described in RFC2612. ++ ++config CRYPTO_TEA ++ tristate "TEA, XTEA and XETA cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ TEA cipher algorithm. ++ ++ Tiny Encryption Algorithm is a simple cipher that uses ++ many rounds for security. It is very fast and uses ++ little memory. ++ ++ Xtendend Tiny Encryption Algorithm is a modification to ++ the TEA algorithm to address a potential key weakness ++ in the TEA algorithm. ++ ++ Xtendend Encryption Tiny Algorithm is a mis-implementation ++ of the XTEA algorithm for compatibility purposes. ++ ++config CRYPTO_ARC4 ++ tristate "ARC4 cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ ARC4 cipher algorithm. ++ ++ ARC4 is a stream cipher using keys ranging from 8 bits to 2048 ++ bits in length. This algorithm is required for driver-based ++ WEP, but it should not be for other purposes because of the ++ weakness of the algorithm. ++ ++config CRYPTO_KHAZAD ++ tristate "Khazad cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Khazad cipher algorithm. ++ ++ Khazad was a finalist in the initial NESSIE competition. It is ++ an algorithm optimized for 64-bit processors with good performance ++ on 32-bit processors. Khazad uses an 128 bit key size. ++ ++ See also: ++ <http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html> ++ ++config CRYPTO_ANUBIS ++ tristate "Anubis cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Anubis cipher algorithm. ++ ++ Anubis is a variable key length cipher which can use keys from ++ 128 bits to 320 bits in length. It was evaluated as a entrant ++ in the NESSIE competition. ++ ++ See also: ++ <https://www.cosic.esat.kuleuven.ac.be/nessie/reports/> ++ <http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html> ++ ++ ++config CRYPTO_DEFLATE ++ tristate "Deflate compression algorithm" ++ select CRYPTO_ALGAPI ++ select ZLIB_INFLATE ++ select ZLIB_DEFLATE ++ help ++ This is the Deflate algorithm (RFC1951), specified for use in ++ IPSec with the IPCOMP protocol (RFC3173, RFC2394). ++ ++ You will most probably want this if using IPSec. ++ ++config CRYPTO_MICHAEL_MIC ++ tristate "Michael MIC keyed digest algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Michael MIC is used for message integrity protection in TKIP ++ (IEEE 802.11i). This algorithm is required for TKIP, but it ++ should not be used for other purposes because of the weakness ++ of the algorithm. ++ ++config CRYPTO_CRC32C ++ tristate "CRC32c CRC algorithm" ++ select CRYPTO_ALGAPI ++ select LIBCRC32C ++ help ++ Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used ++ by iSCSI for header and data digests and by others. ++ See Castagnoli93. This implementation uses lib/libcrc32c. ++ Module will be crc32c. ++ ++config CRYPTO_TEST ++ tristate "Testing module" ++ depends on m ++ select CRYPTO_ALGAPI ++ help ++ Quick & dirty crypto test module. ++ ++source "drivers/crypto/Kconfig" ++ ++endif # if CRYPTO ++ ++endmenu +diff -urN linux-2.6.20.18.orig/crypto/Makefile linux-2.6.20.18/crypto/Makefile +--- linux-2.6.20.18.orig/crypto/Makefile 2007-08-28 06:15:07.000000000 -0400 ++++ linux-2.6.20.18/crypto/Makefile 2007-11-05 02:25:26.000000000 -0500 +@@ -45,3 +45,5 @@ + obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o + + obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o ++obj-$(CONFIG_OCF_OCF) += ocf/ ++ +diff -urN linux-2.6.20.18.orig/crypto/Makefile.orig linux-2.6.20.18/crypto/Makefile.orig +--- linux-2.6.20.18.orig/crypto/Makefile.orig 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.20.18/crypto/Makefile.orig 2007-08-28 06:15:07.000000000 -0400 +@@ -0,0 +1,47 @@ ++# ++# Cryptographic API ++# ++ ++obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o ++ ++crypto_algapi-$(CONFIG_PROC_FS) += proc.o ++crypto_algapi-objs := algapi.o $(crypto_algapi-y) ++obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o ++ ++obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o ++ ++crypto_hash-objs := hash.o ++obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o ++ ++obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o ++obj-$(CONFIG_CRYPTO_HMAC) += hmac.o ++obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o ++obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o ++obj-$(CONFIG_CRYPTO_MD4) += md4.o ++obj-$(CONFIG_CRYPTO_MD5) += md5.o ++obj-$(CONFIG_CRYPTO_SHA1) += sha1.o ++obj-$(CONFIG_CRYPTO_SHA256) += sha256.o ++obj-$(CONFIG_CRYPTO_SHA512) += sha512.o ++obj-$(CONFIG_CRYPTO_WP512) += wp512.o ++obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o ++obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o ++obj-$(CONFIG_CRYPTO_ECB) += ecb.o ++obj-$(CONFIG_CRYPTO_CBC) += cbc.o ++obj-$(CONFIG_CRYPTO_LRW) += lrw.o ++obj-$(CONFIG_CRYPTO_DES) += des.o ++obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o ++obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o ++obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o ++obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o ++obj-$(CONFIG_CRYPTO_AES) += aes.o ++obj-$(CONFIG_CRYPTO_CAST5) += cast5.o ++obj-$(CONFIG_CRYPTO_CAST6) += cast6.o ++obj-$(CONFIG_CRYPTO_ARC4) += arc4.o ++obj-$(CONFIG_CRYPTO_TEA) += tea.o ++obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o ++obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o ++obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o ++obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o ++obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o ++ ++obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o +diff -urN linux-2.6.20.18.orig/crypto/ocf/Config.in linux-2.6.20.18/crypto/ocf/Config.in +--- linux-2.6.20.18.orig/crypto/ocf/Config.in 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.20.18/crypto/ocf/Config.in 2007-11-05 02:25:26.000000000 -0500 +@@ -0,0 +1,28 @@ ++############################################################################# ++ ++mainmenu_option next_comment ++comment 'OCF Configuration' ++tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF ++dep_tristate ' enable fips RNG checks (fips check on RNG data before use)' \ ++ CONFIG_OCF_FIPS $CONFIG_OCF_OCF ++dep_tristate ' enable harvesting entropy for /dev/random' \ ++ CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF ++dep_tristate ' cryptodev (user space support)' \ ++ CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF ++dep_tristate ' cryptosoft (software crypto engine)' \ ++ CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF ++dep_tristate ' safenet (HW crypto engine)' \ ++ CONFIG_OCF_SAFE $CONFIG_OCF_OCF ++dep_tristate ' IXP4xx (HW crypto engine)' \ ++ CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF ++dep_tristate ' hifn (HW crypto engine)' \ ++ CONFIG_OCF_HIFN $CONFIG_OCF_OCF ++dep_tristate ' talitos (HW crypto engine)' \ ++ CONFIG_OCF_TALITOS $CONFIG_OCF_OCF ++dep_tristate ' ocfnull (does no crypto)' \ ++ CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF ++dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \ ++ CONFIG_OCF_BENCH $CONFIG_OCF_OCF ++endmenu ++ ++############################################################################# +diff -urN linux-2.6.20.18.orig/crypto/ocf/criov.c linux-2.6.20.18/crypto/ocf/criov.c +--- linux-2.6.20.18.orig/crypto/ocf/criov.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.20.18/crypto/ocf/criov.c 2007-11-05 02:25:26.000000000 -0500 +@@ -0,0 +1,215 @@ ++/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */ ++ ++/* ++ * Linux port done by David McCullough <dav...@se...> ++ * Copyright (C) 2006-2007 David McCullough ++ * Copyright (C) 2004-2005 Intel Corporation. ++ * The license and original author are listed below. ++ * ++ * Copyright (c) 1999 Theo de Raadt ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $"); ++ */ ++ ++#ifndef AUTOCONF_INCLUDED ++#include <linux/config.h> ++#endif ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/uio.h> ++#include <linux/skbuff.h> ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <asm/io.h> ++ ++#include <uio.h> ++#include <cryptodev.h> ++ ++/* ++ * This macro is only for avoiding code duplication, as we need to skip ++ * given number of bytes in the same way in three functions below. ++ */ ++#define CUIO_SKIP() do { \ ++ KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \ ++ KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \ ++ while (off > 0) { \ ++ KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \ ++ if (off < iov->iov_len) \ ++ break; \ ++ off -= iov->iov_len; \ ++ iol--; \ ++ iov++; \ ++ } \ ++} while (0) ++ ++void ++cuio_copydata(struct uio* uio, int off, int len, caddr_t cp) ++{ ++ struct iovec *iov = uio->uio_iov; ++ int iol = uio->uio_iovcnt; ++ unsigned count; ++ ++ CUIO_SKIP(); ++ while (len > 0) { ++ KASSERT(iol >= 0, ("%s: empty", __func__)); ++ count = min((int)(iov->iov_len - off), len); ++ memcpy(cp, ((caddr_t)iov->iov_base) + off, count); ++ len -= count; ++ cp += count; ++ off = 0; ++ iol--; ++ iov++; ++ } ++} ++ ++void ++cuio_copyback(struct uio* uio, int off, int len, caddr_t cp) ++{ ++ struct iovec *iov = uio->uio_iov; ++ int iol = uio->uio_iovcnt; ++ unsigned count; ++ ++ CUIO_SKIP(); ++ while (len > 0) { ++ KASSERT(iol >= 0, ("%s: empty", __func__)); ++ count = min((int)(iov->iov_len - off), len); ++ memcpy(((caddr_t)iov->iov_base) + off, cp, count); ++ len -= count; ++ cp += count; ++ off = 0; ++ iol--; ++ iov++; ++ } ++} ++ ++/* ++ * Return a pointer to iov/offset of location in iovec list. ++ */ ++struct iovec * ++cuio_getptr(struct uio *uio, int loc, int *off) ++{ ++ struct iovec *iov = uio->uio_iov; ++ int iol = uio->uio_iovcnt; ++ ++ while (loc >= 0) { ++ /* Normal end of search */ ++ if (loc < iov->iov_len) { ++ *off = loc; ++ return (iov); ++ } ++ ++ loc -= iov->iov_len; ++ if (iol == 0) { ++ if (loc == 0) { ++ /* Point at the end of valid data */ ++ *off = iov->iov_len; ++ return (iov); ++ } else ++ return (NULL); ++ } else { ++ iov++, iol--; ++ } ++ } ++ ++ return (NULL); ++} ++ ++EXPORT_SYMBOL(cuio_copyback); ++EXPORT_SYMBOL(cuio_copydata); ++EXPORT_SYMBOL(cuio_getptr); ++ ++ ++static void ++skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len) ++{ ++ int i; ++ if (offset < skb_headlen(skb)) { ++ memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len)); ++ len -= skb_headlen(skb); ++ cp += skb_headlen(skb); ++ } ++ offset -= skb_headlen(skb); ++ for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) { ++ if (offset < skb_shinfo(skb)->frags[i].size) { ++ memcpy(page_address(skb_shinfo(skb)->frags[i].page) + ++ skb_shinfo(skb)->frags[i].page_offset, ++ cp, min_t(int, skb_shinfo(skb)->frags[i].size, len)); ++ len -= skb_shinfo(skb)->frags[i].size; ++ cp += skb_shinfo(skb)->frags[i].size; ++ } ++ offset -= skb_shinfo(skb)->frags[i].size; ++ } ++} ++ ++void ++crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in) ++{ ++ ++ if ((flags & CRYPTO_F_SKBUF) != 0) ++ skb_copy_bits_back((struct sk_buff *)buf, off, in, size); ++ else if ((flags & CRYPTO_F_IOV) != 0) ++ cuio_copyback((struct uio *)buf, off, size, in); ++ else ++ bcopy(in, buf + off, size); ++} ++ ++void ++crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out) ++{ ++ ++ if ((flags & CRYPTO_F_SKBUF) != 0) ++ skb_copy_bits((struct sk_buff *)buf, off, out, size); ++ else if ((flags & CRYPTO_F_IOV) != 0) ++ cuio_copydata((struct uio *)buf, off, size, out); ++ else ++ bcopy(buf + off, out, size); ++} ++ ++int ++crypto_apply(int flags, caddr_t buf, int off, int len, ++ int (*f)(void *, void *, u_int), void *arg) ++{ ++#if 0 ++ int error; ++ ++ if ((flags & CRYPTO_F_SKBUF) != 0) ++ error = XXXXXX((struct mbuf *)buf, off, len, f, arg); ++ else if ((flags & CRYPTO_F_IOV) != 0) ++ error = cuio_apply((struct uio *)buf, off, len, f, arg); ++ else ++ error = (*f)(arg, buf + off, len); ++ return (error); ++#else ++ KASSERT(0, ("crypto_apply not implemented!\n")); ++#endif ++ return 0; ++} ++ ++EXPORT_SYMBOL(crypto_copyback); ++EXPORT_SYMBOL(crypto_copydata); ++EXPORT_SYMBOL(crypto_apply); ++ +diff -urN linux-2.6.20.18.orig/crypto/ocf/crypto.c linux-2.6.20.18/crypto/ocf/crypto.c +--- linux-2.6.20.18.orig/crypto/ocf/crypto.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.20.18/crypto/ocf/crypto.c 2007-11-05 02:25:26.000000000 -0500 +@@ -0,0 +1,1673 @@ ++/*- ++ * Linux port done by David McCullough <dav...@se...> ++ * Copyright (C) 2006-2007 David McCullough ++ * Copyright (C) 2004-2005 Intel Corporation. ++ * The license and original author are listed below. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * Copyright (c) 2002-2006 Sam Leffler. All rights reserved. ++ * ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#if 0 ++#include <sys/cdefs.h> ++__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $"); ++#endif ++ ++/* ++ * Cryptographic Subsystem. ++ * ++ * This code is derived from the Openbsd Cryptographic Framework (OCF) ++ * that has the copyright shown below. Very little of the original ++ * code remains. ++ */ ++/*- ++ * The author of this code is Angelos D. Keromytis (an...@ci...) ++ * ++ * This code was written by Angelos D. Keromytis in Athens, Greece, in ++ * February 2000. Network Security Technologies Inc. (NSTI) kindly ++ * supported the development of this code. ++ * ++ * Copyright (c) 2000, 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 source code copies of any software which is or includes a copy or ++ * modification of this software. ++ * ++ * 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. ++ * ++__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $"); ++ */ ++ ++ ++#ifndef AUTOCONF_INCLUDED ++#include <linux/config.h> ++#endif ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/list.h> ++#include <linux/slab.h> ++#include <linux/wait.h> ++#include <linux/sched.h> ++#include <linux/spinlock.h> ++#include <linux/version.h> ++#include <cryptodev.h> ++ ++/* ++ * keep track of whether or not we have been initialised, a big ++ * issue if we are linked into the kernel and a driver gets started before ++ * us ++ */ ++static int crypto_initted = 0; ++ ++/* ++ * Crypto drivers register themselves by allocating a slot in the ++ * crypto_drivers table with crypto_get_driverid() and then registering ++ * each algorithm they support with crypto_register() and crypto_kregister(). ++ */ ++ ++/* ++ * lock on driver table ++ * we track its state as spin_is_locked does not do anything on non-SMP boxes ++ */ ++static spinlock_t crypto_drivers_lock; ++static int crypto_drivers_locked; /* for non-SMP boxes */ ++ ++#define CRYPTO_DRIVER_LOCK() \ ++ ({ \ ++ spin_lock_irqsave(&crypto_drivers_lock, d_flags); \ ++ crypto_drivers_locked = 1; \ ++ dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \ ++ }) ++#define CRYPTO_DRIVER_UNLOCK() \ ++ ({ \ ++ dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \ ++ crypto_drivers_locked = 0; \ ++ spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \ ++ }) ++#define CRYPTO_DRIVER_ASSERT() \ ++ ({ \ ++ if (!crypto_drivers_locked) { \ ++ dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \ ++ } \ ++ }) ++ ++/* ++ * Crypto device/driver capabilities structure. ++ * ++ * Synchronization: ++ * (d) - protected by CRYPTO_DRIVER_LOCK() ++ * (q) - protected by CRYPTO_Q_LOCK() ++ * Not tagged fields are read-only. ++ */ ++struct cryptocap { ++ device_t cc_dev; /* (d) device/driver */ ++ u_int32_t cc_sessions; /* (d) # of sessions */ ++ u_int32_t cc_koperations; /* (d) # os asym operations */ ++ /* ++ * Largest possible operator length (in bits) for each type of ++ * encryption algorithm. XXX not used ++ */ ++ u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1]; ++ u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1]; ++ u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1]; ++ ++ int cc_flags; /* (d) flags */ ++#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */ ++ int cc_qblocked; /* (q) symmetric q blocked */ ++ int cc_kqblocked; /* (q) asymmetric q blocked */ ++}; ++static struct cryptocap *crypto_drivers = NULL; ++static int crypto_drivers_num = 0; ++ ++/* ++ * There are two queues for crypto requests; one for symmetric (e.g. ++ * cipher) operations and one for asymmetric (e.g. MOD)operations. ++ * A single mutex is used to lock access to both queues. We could ++ * have one per-queue but having one simplifies handling of block/unblock ++ * operations. ++ */ ++static int crp_sleep = 0; ++static LIST_HEAD(crp_q); /* request queues */ ++static LIST_HEAD(crp_kq); ++ ++static int crypto_q_locked = 0; /* on !SMP systems, spin locks do nothing :-( */ ++static spinlock_t crypto_q_lock; ++#define CRYPTO_Q_LOCK() \ ++ ({ \ ++ spin_lock_irqsave(&crypto_q_lock, q_flags); \ ++ dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \ ++ crypto_q_locked++; \ ++ }) ++#define CRYPTO_Q_UNLOCK() \ ++ ({ \ ++ dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \ ++ crypto_q_locked--; \ ++ spin_unlock_irqrestore(&crypto_q_lock, q_flags); \ ++ }) ++ ++/* ++ * There are two queues for processing completed crypto requests; one ++ * for the symmetric and one for the asymmetric ops. We only need one ++ * but have two to avoid type futzing (cryptop vs. cryptkop). A single ++ * mutex is used to lock access to both queues. Note that this lock ++ * must be separate from the lock on request queues to insure driver ++ * callbacks don't generate lock order reversals. ++ */ ++static LIST_HEAD(crp_ret_q); /* callback queues */ ++static LIST_HEAD(crp_ret_kq); ++ ++static spinlock_t crypto_ret_q_lock; ++#define CRYPTO_RETQ_LOCK() \ ++ ({ \ ++ spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \ ++ dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \ ++ }) ++#define CRYPTO_RETQ_UNLOCK() \ ++ ({ \ ++ dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \ ++ spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \ ++ }) ++#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq)) ++ ++static struct kmem_cache *cryptop_zone; ++static struct kmem_cache *cryptodesc_zone; ++ ++#define debug crypto_debug ++int crypto_debug = 0; ++module_param(crypto_debug, int, 0644); ++MODULE_PARM_DESC(crypto_debug, "Enable debug"); ++EXPORT_SYMBOL(crypto_debug); ++ ++/* ++ * Maximum number of outstanding crypto requests before we start ++ * failing requests. We need this to prevent DOS when too many ++ * requests are arriving for us to keep up. Otherwise we will ++ * run the system out of memory. Since crypto is slow, we are ++ * usually the bottleneck that needs to say, enough is enough. ++ * ++ * We cannot print errors when this condition occurs, we are already too ++ * slow, printing anything will just kill us ++ */ ++ ++static atomic_t crypto_q_cnt; ++static int crypto_q_max = 1000; ++module_param(crypto_q_max, int, 0644); ++MODULE_PARM_DESC(crypto_q_max, ++ "Maximum number of outstanding crypto requests"); ++ ++#define bootverbose crypto_verbose ++static int crypto_verbose = 0; ++module_param(crypto_verbose, int, 0644); ++MODULE_PARM_DESC(crypto_verbose, ++ "Enable verbose crypto startup"); ++ ++int crypto_usercrypto = 1; /* userland may do crypto reqs */ ++module_param(crypto_usercrypto, int, 0644); ++MODULE_PARM_DESC(crypto_usercrypto, ++ "Enable/disable user-mode access to crypto support"); ++ ++int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */ ++module_param(crypto_userasymcrypto, int, 0644); ++MODULE_PARM_DESC(crypto_userasymcrypto, ++ "Enable/disable user-mode access to asymmetric crypto support"); ++ ++int crypto_devallowsoft = 0; /* only use hardware crypto */ ++module_param(crypto_devallowsoft, int, 0644); ++MODULE_PARM_DESC(crypto_devallowsoft, ++ "Enable/disable use of software crypto support"); ++ ++static pid_t cryptoproc = (pid_t) -1; ++static struct completion cryptoproc_exited; ++static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait); ++static pid_t cryptoretproc = (pid_t) -1; ++static struct completion cryptoretproc_exited; ++static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait); ++ ++static int crypto_proc(void *arg); ++static int crypto_ret_proc(void *arg); ++static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint); ++static int crypto_kinvoke(struct cryptkop *krp, int flags); ++static void crypto_exit(void); ++static int crypto_init(void); ++ ++static struct cryptostats cryptostats; ++ ++static struct cryptocap * ++crypto_checkdriver(u_int32_t hid) ++{ ++ if (crypto_drivers == NULL) ++ return NULL; ++ return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]); ++} ++ ++/* ++ * Compare a driver's list of supported algorithms against another ++ * list; return non-zero if all algorithms are supported. ++ */ ++static int ++driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri) ++{ ++ const struct cryptoini *cr; ++ ++ /* See if all the algorithms are supported. */ ++ for (cr = cri; cr; cr = cr->cri_next) ++ if (cap->cc_alg[cr->cri_alg] == 0) ++ return 0; ++ return 1; ++} ++ ++/* ++ * Select a driver for a new session that supports the specified ++ * algorithms and, optionally, is constrained according to the flags. ++ * The algorithm we use here is pretty stupid; just use the ++ * first driver that supports all the algorithms we need. If there ++ * are multiple drivers we choose the driver with the fewest active ++ * sessions. We prefer hardware-backed drivers to software ones. ++ * ++ * XXX We need more smarts here (in real life too, but that's ++ * XXX another story altogether). ++ */ ++static struct cryptocap * ++crypto_select_driver(const struct cryptoini *cri, int flags) ++{ ++ struct cryptocap *cap, *best; ++ int match, hid; ++ ++ CRYPTO_DRIVER_ASSERT(); ++ ++ /* ++ * Look first for hardware crypto devices if permitted. ++ */ ++ if (flags & CRYPTOCAP_F_HARDWARE) ++ match = CRYPTOCAP_F_HARDWARE; ++ else ++ match = CRYPTOCAP_F_SOFTWARE; ++ best = NULL; ++again: ++ for (hid = 0; hid < crypto_drivers_num; hid++) { ++ cap = &crypto_drivers[hid]; ++ /* ++ * If it's not initialized, is in the process of ++ * going away, or is not appropriate (hardware ++ * or software based on match), then skip. ++ */ ++ if (cap->cc_dev == NULL || ++ (cap->cc_flags & CRYPTOCAP_F_CLEANUP) || ++ (cap->cc_flags & match) == 0) ++ continue; ++ ++ /* verify all the algorithms are supported. */ ++ if (driver_suitable(cap, cri)) { ++ if (best == NULL || ++ cap->cc_sessions < best->cc_sessions) ++ best = cap; ++ } ++ } ++ if (best != NULL) ++ return best; ++ if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) { ++ /* sort of an Algol 68-style for loop */ ++ match = CRYPTOCAP_F_SOFTWARE; ++ goto again; ++ } ++ return best; ++} ++ ++/* ++ * Create a new session. The crid argument specifies a crypto ++ * driver to use or constraints on a driver to select (hardware ++ * only, software only, either). Whatever driver is selected ++ * must be capable of the requested crypto algorithms. ++ */ ++int ++crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid) ++{ ++ struct cryptocap *cap; ++ u_int32_t hid, lid; ++ int err; ++ unsigned long d_flags; ++ ++ CRYPTO_DRIVER_LOCK(); ++ if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) { ++ /* ++ * Use specified driver; verify it is capable. ++ */ ++ cap = crypto_checkdriver(crid); ++ if (cap != NULL && !driver_suitable(cap, cri)) ++ cap = NULL; ++ } else { ++ /* ++ * No requested driver; select based on crid flags. ++ */ ++ cap = crypto_select_driver(cri, crid); ++ /* ++ * if NULL then can't do everything in one session. ++ * XXX Fix this. We need to inject a "virtual" session ++ * XXX layer right about here. ++ */ ++ } ++ if (cap != NULL) { ++ /* Call the driver initialization routine. */ ++ hid = cap - crypto_drivers; ++ lid = hid; /* Pass the driver ID. */ ++ err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri); ++ if (err == 0) { ++ (*sid) = (cap->cc_flags & 0xff000000) ++ | (hid & 0x00ffffff); ++ (*sid) <<= 32; ++ (*sid) |= (lid & 0xffffffff); ++ cap->cc_sessions++; ++ } ++ } else ++ err = EINVAL; ++ CRYPTO_DRIVER_UNLOCK(); ++ return err; ++} ++ ++static void ++crypto_remove(struct cryptocap *cap) ++{ ++ CRYPTO_DRIVER_ASSERT(); ++ if (cap->cc_sessions == 0 && cap->cc_koperations == 0) ++ bzero(cap, sizeof(*cap)); ++} ++ ++/* ++ * Delete an existing session (or a reserved session on an unregistered ++ * driver). ++ */ ++int ++crypto_freesession(u_int64_t sid) ++{ ++ struct cryptocap *cap; ++ u_int32_t hid; ++ int err; ++ unsigned long d_flags; ++ ++ dprintk("%s()\n", __FUNCTION__); ++ CRYPTO_DRIVER_LOCK(); ++ ++ if (crypto_drivers == NULL) { ++ err = EINVAL; ++ goto done; ++ } ++ ++ /* Determine two IDs. */ ++ hid = CRYPTO_SESID2HID(sid); ++ ++ if (hid >= crypto_drivers_num) { ++ dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid); ++ err = ENOENT; ++ err = ENOENT; ++ goto done; ++ } ++ cap = &crypto_drivers[hid]; ++ ++ if (cap->cc_sessions) ++ cap->cc_sessions--; ++ ++ /* Call the driver cleanup routine, if available. */ ++ err = CRYPTODEV_FREESESSION(cap->cc_dev, sid); ++ ++ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ++ crypto_remove(cap); ++ ++done: ++ CRYPTO_DRIVER_UNLOCK(); ++ return err; ++} ++ ++/* ++ * Return an unused driver id. Used by drivers prior to registering ++ * support for the algorithms they handle. ++ */ ++int32_t ++crypto_get_driverid(device_t dev, int flags) ++{ ++ struct cryptocap *newdrv; ++ int i; ++ unsigned long d_flags; ++ ++ if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) { ++ printf("%s: no flags specified when registering driver\n", ++ device_get_nameunit(dev)); ++ return -1; ++ } ++ ++ CRYPTO_DRIVER_LOCK(); ++ ++ for (i = 0; i < crypto_drivers_num; i++) { ++ if (crypto_drivers[i].cc_dev == NULL && ++ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) { ++ break; ++ } ++ } ++ ++ /* Out of entries, allocate some more. */ ++ if (i == crypto_drivers_num) { ++ /* Be careful about wrap-around. */ ++ if (2 * crypto_drivers_num <= crypto_drivers_num) { ++ CRYPTO_DRIVER_UNLOCK(); ++ printk("crypto: driver count wraparound!\n"); ++ return -1; ++ } ++ ++ newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap), ++ GFP_KERNEL); ++ if (newdrv == NULL) { ++ CRYPTO_DRIVER_UNLOCK(); ++ printk("crypto: no space to expand driver table!\n"); ++ return -1; ++ } ++ ++ memcpy(newdrv, crypto_drivers, ++ crypto_drivers_num * sizeof(struct cryptocap)); ++ memset(&newdrv[crypto_drivers_num], 0, ++ crypto_drivers_num * sizeof(struct cryptocap)); ++ ++ crypto_drivers_num *= 2; ++ ++ kfree(crypto_drivers); ++ crypto_drivers = newdrv; ++ } ++ ++ /* NB: state is zero'd on free */ ++ crypto_drivers[i].cc_sessions = 1; /* Mark */ ++ crypto_drivers[i].cc_dev = dev; ++ crypto_drivers[i].cc_flags = flags; ++ if (bootverbose) ++ printf("crypto: assign %s driver id %u, flags %u\n", ++ device_get_nameunit(dev), i, flags); ++ ++ CRYPTO_DRIVER_UNLOCK(); ++ ++ return i; ++} ++ ++/* ++ * Lookup a driver by name. We match against the full device ++ * name and unit, and against just the name. The latter gives ++ * us a simple widlcarding by device name. On success return the ++ * driver/hardware identifier; otherwise return -1. ++ */ ++int ++crypto_find_driver(const char *match) ++{ ++ int i, len = strlen(match); ++ unsigned long d_flags; ++ ++ CRYPTO_DRIVER_LOCK(); ++ for (i = 0; i < crypto_drivers_num; i++) { ++ device_t dev = crypto_drivers[i].cc_dev; ++ if (dev == NULL || ++ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP)) ++ continue; ++ if (strncmp(match, device_get_nameunit(dev), len) == 0 || ++ strncmp(match, device_get_name(dev), len) == 0) ++ break; ++ } ++ CRYPTO_DRIVER_UNLOCK(); ++ return i < crypto_drivers_num ? i : -1; ++} ++ ++/* ++ * Return the device_t for the specified driver or NULL ++ * if the driver identifier is invalid. ++ */ ++device_t ++crypto_find_device_byhid(int hid) ++{ ++ struct cryptocap *cap = crypto_checkdriver(hid); ++ return cap != NULL ? cap->cc_dev : NULL; ++} ++ ++/* ++ * Return the device/driver capabilities. ++ */ ++int ++crypto_getcaps(int hid) ++{ ++ struct cryptocap *cap = crypto_checkdriver(hid); ++ return cap != NULL ? cap->cc_flags : 0; ++} ++ ++/* ++ * Register support for a key-related algorithm. This routine ++ * is called once for each algorithm supported a driver. ++ */ ++int ++crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags) ++{ ++ struct cryptocap *cap; ++ int err; ++ unsigned long d_flags; ++ ++ dprintk("%s()\n", __FUNCTION__); ++ CRYPTO_DRIVER_LOCK(); ++ ++ cap = crypto_checkdriver(driverid); ++ if (cap != NULL && ++ (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) { ++ /* ++ * XXX Do some performance testing to determine pla... [truncated message content] |