summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto/cryptosoft.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/opencrypto/cryptosoft.c')
-rw-r--r--sys/opencrypto/cryptosoft.c236
1 files changed, 147 insertions, 89 deletions
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index e41f0ce..215c676 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -45,39 +45,39 @@ __FBSDID("$FreeBSD$");
#include <opencrypto/cryptosoft.h>
#include <opencrypto/xform.h>
-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
-};
-
-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
-};
-
+u_int8_t *hmac_ipad_buffer;
+u_int8_t *hmac_opad_buffer;
struct swcr_data **swcr_sessions = NULL;
u_int32_t swcr_sesnum = 0;
int32_t swcr_id = -1;
-#define COPYBACK(x, a, b, c, d) \
- (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
- : cuio_copyback((struct uio *)a,b,c,d)
-#define COPYDATA(x, a, b, c, d) \
- (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
- : cuio_copydata((struct uio *)a,b,c,d)
+#define COPYBACK(type, buf, off, size, in) do { \
+ switch (type) { \
+ case CRYPTO_BUF_CONTIG: \
+ bcopy(in, (u_char *)(buf) + (off), size); \
+ break; \
+ case CRYPTO_BUF_MBUF: \
+ m_copyback((struct mbuf *)(buf), off, size, in); \
+ break; \
+ case CRYPTO_BUF_IOV: \
+ cuio_copyback((struct uio *)(buf), off, size, in); \
+ break; \
+ } \
+} while (0)
+#define COPYDATA(type, buf, off, size, out) do { \
+ switch (type) { \
+ case CRYPTO_BUF_CONTIG: \
+ bcopy((u_char *)(buf) + (off), out, size); \
+ break; \
+ case CRYPTO_BUF_MBUF: \
+ m_copydata((struct mbuf *)(buf), off, size, out); \
+ break; \
+ case CRYPTO_BUF_IOV: \
+ cuio_copydata((struct uio *)(buf), off, size, out); \
+ break; \
+ } \
+} while (0)
static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
@@ -412,13 +412,60 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
}
}
- return 0; /* Done with iov encryption/decryption */
+ return 0; /* Done with iovec encryption/decryption */
}
/* Unreachable */
return EINVAL;
}
+static void
+swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
+ int klen)
+{
+ int k;
+
+ klen /= 8;
+
+ switch (axf->type) {
+ case CRYPTO_MD5_HMAC:
+ case CRYPTO_SHA1_HMAC:
+ case CRYPTO_SHA2_256_HMAC:
+ case CRYPTO_SHA2_384_HMAC:
+ case CRYPTO_SHA2_512_HMAC:
+ case CRYPTO_NULL_HMAC:
+ case CRYPTO_RIPEMD160_HMAC:
+ for (k = 0; k < klen; k++)
+ key[k] ^= HMAC_IPAD_VAL;
+
+ axf->Init(sw->sw_ictx);
+ axf->Update(sw->sw_ictx, key, klen);
+ axf->Update(sw->sw_ictx, hmac_ipad_buffer, axf->blocksize - klen);
+
+ for (k = 0; k < klen; k++)
+ key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+
+ axf->Init(sw->sw_octx);
+ axf->Update(sw->sw_octx, key, klen);
+ axf->Update(sw->sw_octx, hmac_opad_buffer, axf->blocksize - klen);
+
+ for (k = 0; k < klen; k++)
+ key[k] ^= HMAC_OPAD_VAL;
+ break;
+ case CRYPTO_MD5_KPDK:
+ case CRYPTO_SHA1_KPDK:
+ sw->sw_klen = klen;
+ bcopy(key, sw->sw_octx, klen);
+ axf->Init(sw->sw_ictx);
+ axf->Update(sw->sw_ictx, key, klen);
+ axf->Final(NULL, sw->sw_ictx);
+ break;
+ default:
+ printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
+ "doesn't use keys.\n", __func__, axf->type);
+ }
+}
+
/*
* Compute keyed-hash authenticator.
*/
@@ -436,6 +483,9 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
axf = sw->sw_axf;
+ if (crd->crd_flags & CRD_F_KEY_EXPLICIT)
+ swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen);
+
bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
switch (outtype) {
@@ -450,6 +500,12 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
return err;
break;
case CRYPTO_BUF_IOV:
+ err = cuio_apply((struct uio *) buf, crd->crd_skip, crd->crd_len,
+ (int (*)(void *, void *, unsigned int)) axf->Update,
+ (caddr_t) &ctx);
+ if (err)
+ return err;
+ break;
default:
return EINVAL;
}
@@ -457,7 +513,9 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
switch (sw->sw_alg) {
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
- case CRYPTO_SHA2_HMAC:
+ case CRYPTO_SHA2_256_HMAC:
+ case CRYPTO_SHA2_384_HMAC:
+ case CRYPTO_SHA2_512_HMAC:
case CRYPTO_RIPEMD160_HMAC:
if (sw->sw_octx == NULL)
return EINVAL;
@@ -483,11 +541,8 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
}
/* Inject the authentication data */
- if (outtype == CRYPTO_BUF_CONTIG)
- bcopy(aalg, buf + crd->crd_inject, axf->authsize);
- else
- m_copyback((struct mbuf *) buf, crd->crd_inject,
- axf->authsize, aalg);
+ COPYBACK(outtype, buf, crd->crd_inject,
+ sw->sw_mlen == 0 ? axf->hashsize : sw->sw_mlen, aalg);
return 0;
}
@@ -578,7 +633,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
struct enc_xform *txf;
struct comp_algo *cxf;
u_int32_t i;
- int k, error;
+ int error;
if (sid == NULL || cri == NULL)
return EINVAL;
@@ -652,38 +707,37 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
txf = &enc_xform_null;
goto enccommon;
enccommon:
- error = txf->setkey(&((*swd)->sw_kschedule),
- cri->cri_key, cri->cri_klen / 8);
- if (error) {
- swcr_freesession(NULL, i);
- return error;
+ if (cri->cri_key != NULL) {
+ error = txf->setkey(&((*swd)->sw_kschedule),
+ cri->cri_key, cri->cri_klen / 8);
+ if (error) {
+ swcr_freesession(NULL, i);
+ return error;
+ }
}
(*swd)->sw_exf = txf;
break;
case CRYPTO_MD5_HMAC:
- axf = &auth_hash_hmac_md5_96;
+ axf = &auth_hash_hmac_md5;
goto authcommon;
case CRYPTO_SHA1_HMAC:
- axf = &auth_hash_hmac_sha1_96;
+ axf = &auth_hash_hmac_sha1;
goto authcommon;
- case CRYPTO_SHA2_HMAC:
- if (cri->cri_klen == 256)
- axf = &auth_hash_hmac_sha2_256;
- else if (cri->cri_klen == 384)
- axf = &auth_hash_hmac_sha2_384;
- else if (cri->cri_klen == 512)
- axf = &auth_hash_hmac_sha2_512;
- else {
- swcr_freesession(NULL, i);
- return EINVAL;
- }
+ case CRYPTO_SHA2_256_HMAC:
+ axf = &auth_hash_hmac_sha2_256;
+ goto authcommon;
+ case CRYPTO_SHA2_384_HMAC:
+ axf = &auth_hash_hmac_sha2_384;
+ goto authcommon;
+ case CRYPTO_SHA2_512_HMAC:
+ axf = &auth_hash_hmac_sha2_512;
goto authcommon;
case CRYPTO_NULL_HMAC:
axf = &auth_hash_null;
goto authcommon;
case CRYPTO_RIPEMD160_HMAC:
- axf = &auth_hash_hmac_ripemd_160_96;
+ axf = &auth_hash_hmac_ripemd_160;
authcommon:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
@@ -698,27 +752,13 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
swcr_freesession(NULL, i);
return ENOBUFS;
}
-
- for (k = 0; k < cri->cri_klen / 8; k++)
- cri->cri_key[k] ^= HMAC_IPAD_VAL;
-
- axf->Init((*swd)->sw_ictx);
- axf->Update((*swd)->sw_ictx, cri->cri_key,
- cri->cri_klen / 8);
- axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
- HMAC_BLOCK_LEN - (cri->cri_klen / 8));
-
- for (k = 0; k < cri->cri_klen / 8; k++)
- cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
-
- axf->Init((*swd)->sw_octx);
- axf->Update((*swd)->sw_octx, cri->cri_key,
- cri->cri_klen / 8);
- axf->Update((*swd)->sw_octx, hmac_opad_buffer,
- HMAC_BLOCK_LEN - (cri->cri_klen / 8));
-
- for (k = 0; k < cri->cri_klen / 8; k++)
- cri->cri_key[k] ^= HMAC_OPAD_VAL;
+
+ if (cri->cri_key != NULL) {
+ swcr_authprepare(axf, *swd, cri->cri_key,
+ cri->cri_klen);
+ }
+
+ (*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
break;
@@ -736,20 +776,20 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
return ENOBUFS;
}
- /* Store the key so we can "append" it to the payload */
- (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
- M_NOWAIT);
+ (*swd)->sw_octx = malloc(cri->cri_klen / 8,
+ M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_octx == NULL) {
swcr_freesession(NULL, i);
return ENOBUFS;
}
-
- (*swd)->sw_klen = cri->cri_klen / 8;
- bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
- axf->Init((*swd)->sw_ictx);
- axf->Update((*swd)->sw_ictx, cri->cri_key,
- cri->cri_klen / 8);
- axf->Final(NULL, (*swd)->sw_ictx);
+
+ /* Store the key so we can "append" it to the payload */
+ if (cri->cri_key != NULL) {
+ swcr_authprepare(axf, *swd, cri->cri_key,
+ cri->cri_klen);
+ }
+
+ (*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
break;
#ifdef notdef
@@ -768,6 +808,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
}
axf->Init((*swd)->sw_ictx);
+ (*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
break;
#endif
@@ -826,7 +867,9 @@ swcr_freesession(void *arg, u_int64_t tid)
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
- case CRYPTO_SHA2_HMAC:
+ case CRYPTO_SHA2_256_HMAC:
+ case CRYPTO_SHA2_384_HMAC:
+ case CRYPTO_SHA2_512_HMAC:
case CRYPTO_RIPEMD160_HMAC:
case CRYPTO_NULL_HMAC:
axf = swd->sw_axf;
@@ -945,7 +988,9 @@ swcr_process(void *arg, struct cryptop *crp, int hint)
break;
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
- case CRYPTO_SHA2_HMAC:
+ case CRYPTO_SHA2_256_HMAC:
+ case CRYPTO_SHA2_384_HMAC:
+ case CRYPTO_SHA2_512_HMAC:
case CRYPTO_RIPEMD160_HMAC:
case CRYPTO_NULL_HMAC:
case CRYPTO_MD5_KPDK:
@@ -983,6 +1028,15 @@ done:
static void
swcr_init(void)
{
+ u_int i;
+
+ hmac_ipad_buffer = malloc(HMAC_BLOCK_MAXLEN, M_CRYPTO_DATA, M_WAITOK);
+ for (i = 0; i < HMAC_BLOCK_MAXLEN; i++)
+ hmac_ipad_buffer[i] = HMAC_IPAD_VAL;
+ hmac_opad_buffer = malloc(HMAC_BLOCK_MAXLEN, M_CRYPTO_DATA, M_WAITOK);
+ for (i = 0; i < HMAC_BLOCK_MAXLEN; i++)
+ hmac_opad_buffer[i] = HMAC_OPAD_VAL;
+
swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
if (swcr_id < 0)
panic("Software crypto device cannot initialize!");
@@ -997,7 +1051,9 @@ swcr_init(void)
REGISTER(CRYPTO_NULL_CBC);
REGISTER(CRYPTO_MD5_HMAC);
REGISTER(CRYPTO_SHA1_HMAC);
- REGISTER(CRYPTO_SHA2_HMAC);
+ REGISTER(CRYPTO_SHA2_256_HMAC);
+ REGISTER(CRYPTO_SHA2_384_HMAC);
+ REGISTER(CRYPTO_SHA2_512_HMAC);
REGISTER(CRYPTO_RIPEMD160_HMAC);
REGISTER(CRYPTO_NULL_HMAC);
REGISTER(CRYPTO_MD5_KPDK);
@@ -1016,5 +1072,7 @@ swcr_uninit(void)
if (swcr_sessions != NULL)
FREE(swcr_sessions, M_CRYPTO_DATA);
+ free(hmac_ipad_buffer, M_CRYPTO_DATA);
+ free(hmac_opad_buffer, M_CRYPTO_DATA);
}
SYSUNINIT(cryptosoft_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_uninit, NULL);
OpenPOWER on IntegriCloud