diff options
author | Jean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org> | 2001-07-05 16:44:01 +0000 |
---|---|---|
committer | Jean-Jacques Bernard-Gundol <jjbg@cvs.openbsd.org> | 2001-07-05 16:44:01 +0000 |
commit | 8825709f799a89e2fc142671d9921b6c10501350 (patch) | |
tree | 7c50bfa042528342847f0520efde47d0b4f40e91 /sys | |
parent | f64f0458c512fa33b357b5df6f5db97c948bcaa4 (diff) |
Support for compression. angelos@ ok.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/crypto/cryptosoft.c | 118 | ||||
-rw-r--r-- | sys/crypto/xform.c | 35 |
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); +} |