summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org>2001-07-05 16:44:01 +0000
committerJean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org>2001-07-05 16:44:01 +0000
commit8825709f799a89e2fc142671d9921b6c10501350 (patch)
tree7c50bfa042528342847f0520efde47d0b4f40e91 /sys
parentf64f0458c512fa33b357b5df6f5db97c948bcaa4 (diff)
Support for compression. angelos@ ok.
Diffstat (limited to 'sys')
-rw-r--r--sys/crypto/cryptosoft.c118
-rw-r--r--sys/crypto/xform.c35
2 files changed, 150 insertions, 3 deletions
diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c
index 1f4c8cc42e5..2029c9fdb57 100644
--- a/sys/crypto/cryptosoft.c
+++ b/sys/crypto/cryptosoft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptosoft.c,v 1.25 2001/06/25 05:02:22 angelos Exp $ */
+/* $OpenBSD: cryptosoft.c,v 1.26 2001/07/05 16:44:00 jjbg Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -357,6 +357,96 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw,
}
/*
+ * Apply a compression/decompression algorithm
+ */
+int
+swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
+ caddr_t buf, int outtype)
+{
+ u_int8_t *data, *out;
+ struct comp_algo *cxf;
+ int k, adj;
+ u_int32_t result;
+ struct mbuf *m, *m1;
+
+ cxf = sw->sw_cxf;
+
+ if (outtype == CRYPTO_BUF_CONTIG) {
+ if (crd->crd_flags & CRD_F_COMP)
+ result = cxf->compress(buf + crd->crd_skip,
+ crd->crd_len, &out);
+ else
+ result = cxf->decompress(buf + crd->crd_skip,
+ crd->crd_len, &out);
+ } else { /* mbuf */
+ m = (struct mbuf *)buf;
+
+ /* Find beginning of data */
+ m1 = m_getptr(m, crd->crd_skip, &k);
+ if (m1 == NULL)
+ return EINVAL;
+ /* We must handle the whole buffer of data in one time
+ * then if there is not all the data in the mbuf, we must
+ * copy in a buffer.
+ */
+
+ MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA,
+ M_NOWAIT);
+ if (data == NULL)
+ return EINVAL;
+ m_copydata(m1, k, crd->crd_len, data);
+
+ if (crd->crd_flags & CRD_F_COMP)
+ result = cxf->compress(data, crd->crd_len, &out);
+ else
+ result = cxf->decompress(data, crd->crd_len, &out);
+ }
+
+ if (outtype == CRYPTO_BUF_CONTIG) {
+ if (result == 0)
+ return EINVAL;
+ sw->sw_size = result;
+ /* Check the compressed size when doing compression */
+ if (crd->crd_flags & CRD_F_COMP) {
+ if (result > crd->crd_len) {
+ /* Compression was useless, we lost time */
+ FREE(out, M_CRYPTO_DATA);
+ return 0;
+ }
+ }
+ buf = out;
+ /* Don't forget to FREE buf later */
+ return 0;
+ } else {
+ FREE(data, M_CRYPTO_DATA);
+ if (result == 0)
+ return EINVAL;
+ /* Copy back the (de)compressed data. m_copyback is
+ * extending the mbuf as necessary.
+ */
+ sw->sw_size = result;
+ /* Check the compressed size when doing compression */
+ if (crd->crd_flags & CRD_F_COMP) {
+ if (result > crd->crd_len) {
+ /* Compression was useless, we lost time */
+ FREE(out, M_CRYPTO_DATA);
+ return 0;
+ }
+ }
+ m_copyback(m1, k, result, out);
+ if (result < crd->crd_len) {
+ adj = result - crd->crd_len;
+ m_adj(m, adj);
+ }
+ FREE(out, M_CRYPTO_DATA);
+ return 0;
+ }
+
+ /* Unreachable */
+ return EINVAL;
+}
+
+/*
* Generate a new software session.
*/
int
@@ -365,6 +455,7 @@ swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
struct swcr_data **swd;
struct auth_hash *axf;
struct enc_xform *txf;
+ struct comp_algo *cxf;
u_int32_t i;
int k;
@@ -526,7 +617,15 @@ swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
axf->Final(NULL, (*swd)->sw_ictx);
(*swd)->sw_axf = axf;
break;
-
+
+ case CRYPTO_DEFLATE_COMP:
+ cxf = &comp_algo_deflate;
+ goto compcommon;
+
+ compcommon:
+ (*swd)->sw_cxf = cxf;
+ break;
+
default:
swcr_freesession(i);
return EINVAL;
@@ -548,6 +647,7 @@ swcr_freesession(u_int64_t tid)
struct swcr_data *swd;
struct enc_xform *txf;
struct auth_hash *axf;
+ struct comp_algo *cxf;
u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
if (sid > swcr_sesnum || swcr_sessions == NULL ||
@@ -604,6 +704,10 @@ swcr_freesession(u_int64_t tid)
free(swd->sw_octx, M_CRYPTO_DATA);
}
break;
+
+ case CRYPTO_DEFLATE_COMP:
+ cxf = swd->sw_cxf;
+ break;
}
FREE(swd, M_CRYPTO_DATA);
@@ -686,6 +790,14 @@ swcr_process(struct cryptop *crp)
goto done;
break;
+ case CRYPTO_DEFLATE_COMP:
+ if ((crp->crp_etype = swcr_compdec(crd, sw,
+ crp->crp_buf, type)) != 0)
+ goto done;
+ else
+ crp->crp_olen = (int)sw->sw_size;
+ break;
+
default:
/* Unknown/unsupported algorithm */
crp->crp_etype = EINVAL;
@@ -728,6 +840,8 @@ swcr_init(void)
NULL, NULL, NULL);
crypto_register(swcr_id, CRYPTO_RIJNDAEL128_CBC, 0, 0,
NULL, NULL, NULL);
+ crypto_register(swcr_id, CRYPTO_DEFLATE_COMP, 0, 0,
+ NULL, NULL, NULL);
return;
}
diff --git a/sys/crypto/xform.c b/sys/crypto/xform.c
index e845673f2a7..b8e9d4a93a7 100644
--- a/sys/crypto/xform.c
+++ b/sys/crypto/xform.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xform.c,v 1.10 2001/06/27 04:57:08 angelos Exp $ */
+/* $OpenBSD: xform.c,v 1.11 2001/07/05 16:44:00 jjbg Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -54,6 +54,7 @@
#include <crypto/rijndael.h>
#include <crypto/cryptodev.h>
#include <crypto/xform.h>
+#include <crypto/deflate.h>
extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int);
extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int);
@@ -88,6 +89,9 @@ int MD5Update_int(void *, u_int8_t *, u_int16_t);
int SHA1Update_int(void *, u_int8_t *, u_int16_t);
int RMD160Update_int(void *, u_int8_t *, u_int16_t);
+u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
+u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
+
/* Encryption instances */
struct enc_xform enc_xform_des = {
CRYPTO_DES_CBC, "DES",
@@ -179,6 +183,13 @@ struct auth_hash auth_hash_key_sha1 = {
(void (*)(u_int8_t *, void *)) SHA1Final
};
+/* Compression instance */
+struct comp_algo comp_algo_deflate = {
+ CRYPTO_DEFLATE_COMP, "Deflate",
+ 90, deflate_compress,
+ deflate_decompress
+};
+
/*
* Encryption wrapper routines.
*/
@@ -389,3 +400,25 @@ SHA1Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
SHA1Update(ctx, buf, len);
return 0;
}
+
+/*
+ * And compression
+ */
+
+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);
+}
+
+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);
+}