summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-06-04 22:12:08 +0000
committerpjd <pjd@FreeBSD.org>2006-06-04 22:12:08 +0000
commit60fac157ecabb2906c29d54573d37a633a91fb32 (patch)
treedf361ab160dcd9a10636ba1a0cc5eec79c069f49 /sys/opencrypto
parent6cad615115477702d652c5f2f0a69e7fa6be9973 (diff)
downloadFreeBSD-src-60fac157ecabb2906c29d54573d37a633a91fb32.zip
FreeBSD-src-60fac157ecabb2906c29d54573d37a633a91fb32.tar.gz
Prefer hardware crypto over software crypto.
Before the change if a hardware crypto driver was loaded after the software crypto driver, calling crypto_newsession() with hard=0, will always choose software crypto.
Diffstat (limited to 'sys/opencrypto')
-rw-r--r--sys/opencrypto/crypto.c112
1 files changed, 74 insertions, 38 deletions
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index 249a45b..fbf039f 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -262,8 +262,9 @@ MODULE_DEPEND(crypto, zlib, 1, 1, 1);
int
crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
{
+ struct cryptocap *cap = NULL;
struct cryptoini *cr;
- u_int32_t hid, lid;
+ u_int32_t hid = 0, lid;
int err = EINVAL;
CRYPTO_DRIVER_LOCK();
@@ -279,50 +280,85 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
* XXX another story altogether).
*/
- for (hid = 0; hid < crypto_drivers_num; hid++) {
- struct cryptocap *cap = &crypto_drivers[hid];
- /*
- * If it's not initialized or has remaining sessions
- * referencing it, skip.
- */
- if (cap->cc_newsession == NULL ||
- (cap->cc_flags & CRYPTOCAP_F_CLEANUP))
- continue;
+ /*
+ * First try to find hardware crypto.
+ */
+ if (hard >= 0) {
+ for (hid = 0; hid < crypto_drivers_num; hid++) {
+ cap = &crypto_drivers[hid];
+ /*
+ * If it's not initialized or has remaining sessions
+ * referencing it, skip.
+ */
+ if (cap->cc_newsession == NULL ||
+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP))
+ continue;
- /* Hardware required -- ignore software drivers. */
- if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE))
- continue;
- /* Software required -- ignore hardware drivers. */
- if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0)
- continue;
+ /* Hardware required -- ignore software drivers. */
+ if (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)
+ continue;
- /* See if all the algorithms are supported. */
- for (cr = cri; cr; cr = cr->cri_next)
- if (cap->cc_alg[cr->cri_alg] == 0)
+ /* See if all the algorithms are supported. */
+ for (cr = cri; cr; cr = cr->cri_next)
+ if (cap->cc_alg[cr->cri_alg] == 0)
+ break;
+ if (cr == NULL) {
+ /* Ok, all algorithms are supported. */
break;
-
- if (cr == NULL) {
- /* Ok, all algorithms are supported. */
-
+ }
+ }
+ if (hid == crypto_drivers_num)
+ cap = NULL;
+ }
+ /*
+ * If no hardware crypto, look for software crypto.
+ */
+ if (cap == NULL && hard <= 0) {
+ for (hid = 0; hid < crypto_drivers_num; hid++) {
+ cap = &crypto_drivers[hid];
/*
- * Can't do everything in one session.
- *
- * XXX Fix this. We need to inject a "virtual" session layer right
- * XXX about here.
+ * If it's not initialized or has remaining sessions
+ * referencing it, skip.
*/
+ if (cap->cc_newsession == NULL ||
+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP))
+ continue;
+
+ /* Software required -- ignore hardware drivers. */
+ if (!(cap->cc_flags & CRYPTOCAP_F_SOFTWARE))
+ continue;
- /* Call the driver initialization routine. */
- lid = hid; /* Pass the driver ID. */
- err = (*cap->cc_newsession)(cap->cc_arg, &lid, cri);
- if (err == 0) {
- /* XXX assert (hid &~ 0xffffff) == 0 */
- /* XXX assert (cap->cc_flags &~ 0xff) == 0 */
- (*sid) = ((cap->cc_flags & 0xff) << 24) | hid;
- (*sid) <<= 32;
- (*sid) |= (lid & 0xffffffff);
- cap->cc_sessions++;
+ /* See if all the algorithms are supported. */
+ for (cr = cri; cr; cr = cr->cri_next)
+ if (cap->cc_alg[cr->cri_alg] == 0)
+ break;
+ if (cr == NULL) {
+ /* Ok, all algorithms are supported. */
+ break;
}
- break;
+ }
+ if (hid == crypto_drivers_num)
+ cap = NULL;
+ }
+
+ if (cap != NULL) {
+ /*
+ * Can't do everything in one session.
+ *
+ * XXX Fix this. We need to inject a "virtual" session layer right
+ * XXX about here.
+ */
+
+ /* Call the driver initialization routine. */
+ lid = hid; /* Pass the driver ID. */
+ err = (*cap->cc_newsession)(cap->cc_arg, &lid, cri);
+ if (err == 0) {
+ /* XXX assert (hid &~ 0xffffff) == 0 */
+ /* XXX assert (cap->cc_flags &~ 0xff) == 0 */
+ (*sid) = ((cap->cc_flags & 0xff) << 24) | hid;
+ (*sid) <<= 32;
+ (*sid) |= (lid & 0xffffffff);
+ cap->cc_sessions++;
}
}
done:
OpenPOWER on IntegriCloud