Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/cryptodeflate.c
Show All 23 Lines | |||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
/* | /* | ||||
* This file contains a wrapper around the deflate algo compression | * This file contains a wrapper around the deflate algo compression | ||||
* functions using the zlib library (see libkern/zlib.c and sys/zlib.h}) | * functions using the zlib library (see sys/contrib/zlib) | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/sdt.h> | #include <sys/sdt.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/zlib.h> | #include <zlib.h> | ||||
#include <opencrypto/cryptodev.h> | #include <opencrypto/cryptodev.h> | ||||
#include <opencrypto/deflate.h> | #include <opencrypto/deflate.h> | ||||
SDT_PROVIDER_DECLARE(opencrypto); | SDT_PROVIDER_DECLARE(opencrypto); | ||||
SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, | SDT_PROBE_DEFINE2(opencrypto, z_deflate, deflate_global, entry, | ||||
"int", "u_int32_t"); | "int", "u_int32_t"); | ||||
SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, | SDT_PROBE_DEFINE6(opencrypto, z_deflate, deflate_global, bad, | ||||
"int", "int", "int", "int", "int"); | "int", "int", "int", "int", "int", "int"); | ||||
SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, | SDT_PROBE_DEFINE6(opencrypto, z_deflate, deflate_global, iter, | ||||
"int", "int", "int", "int", "int"); | "int", "int", "int", "int", "int", "int"); | ||||
SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, | SDT_PROBE_DEFINE2(opencrypto, z_deflate, deflate_global, return, | ||||
"int", "u_int32_t"); | "int", "u_int32_t"); | ||||
int window_inflate = -1 * MAX_WBITS; | int window_inflate = -1 * MAX_WBITS; | ||||
int window_deflate = -12; | int window_deflate = -12; | ||||
static void * | |||||
delphij: the new line before crypto_zalloc() is not necessary. | |||||
crypto_zalloc(void *nil, u_int type, u_int size); | |||||
Done Inline Actions[OPTIONAL] Personally I'd remove the variable names in prototype definition. Alternatively, you can move these functions' bodies here because these are static functions. delphij: [OPTIONAL] Personally I'd remove the variable names in prototype definition. Alternatively… | |||||
Done Inline ActionsI will move implementations here. ota_j.email.ne.jp: I will move implementations here. | |||||
static void | |||||
crypto_zfree(void *nil, void *ptr); | |||||
/* | /* | ||||
* This function takes a block of data and (de)compress it using the deflate | * This function takes a block of data and (de)compress it using the deflate | ||||
* algorithm | * algorithm | ||||
*/ | */ | ||||
u_int32_t | u_int32_t | ||||
deflate_global(data, size, decomp, out) | deflate_global(data, size, decomp, out) | ||||
u_int8_t *data; | u_int8_t *data; | ||||
u_int32_t size; | u_int32_t size; | ||||
int decomp; | int decomp; | ||||
u_int8_t **out; | u_int8_t **out; | ||||
{ | { | ||||
/* decomp indicates whether we compress (0) or decompress (1) */ | /* decomp indicates whether we compress (0) or decompress (1) */ | ||||
z_stream zbuf; | z_stream zbuf; | ||||
u_int8_t *output; | u_int8_t *output; | ||||
u_int32_t count, result; | u_int32_t count, result; | ||||
int error, i; | int error, i; | ||||
struct deflate_buf *bufh, *bufp; | struct deflate_buf *bufh, *bufp; | ||||
SDT_PROBE2(opencrypto, deflate, deflate_global, entry, decomp, size); | SDT_PROBE2(opencrypto, z_deflate, deflate_global, entry, decomp, size); | ||||
bufh = bufp = NULL; | bufh = bufp = NULL; | ||||
if (!decomp) { | if (!decomp) { | ||||
i = 1; | i = 1; | ||||
} else { | } else { | ||||
/* | /* | ||||
* Choose a buffer with 4x the size of the input buffer | * Choose a buffer with 4x the size of the input buffer | ||||
* for the size of the output buffer in the case of | * for the size of the output buffer in the case of | ||||
* decompression. If it's not sufficient, it will need to be | * decompression. If it's not sufficient, it will need to be | ||||
* updated while the decompression is going on. | * updated while the decompression is going on. | ||||
*/ | */ | ||||
i = 4; | i = 4; | ||||
} | } | ||||
/* | /* | ||||
* Make sure we do have enough output space. Repeated calls to | * Make sure we do have enough output space. Repeated calls to | ||||
* deflate need at least 6 bytes of output buffer space to avoid | * deflate need at least 6 bytes of output buffer space to avoid | ||||
* repeated markers. We will always provide at least 16 bytes. | * repeated markers. We will always provide at least 16 bytes. | ||||
*/ | */ | ||||
while ((size * i) < 16) | while ((size * i) < 16) | ||||
i++; | i++; | ||||
bufh = bufp = malloc(sizeof(*bufp) + (size_t)(size * i), | bufh = bufp = malloc(sizeof(*bufp) + (size_t)(size * i), | ||||
M_CRYPTO_DATA, M_NOWAIT); | M_CRYPTO_DATA, M_NOWAIT); | ||||
if (bufp == NULL) { | if (bufp == NULL) { | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, bad, | ||||
Not Done Inline ActionsI think the probes needs to match their definitions? (Also, is there some specific reason not to convert this to use new zlib?) delphij: I think the probes needs to match their definitions? (Also, is there some specific reason not… | |||||
Done Inline ActionsThe probes need to be matching ABI, the binary symbol. ota_j.email.ne.jp: The probes need to be matching ABI, the binary symbol.
I can put cryptodefate changes together. | |||||
decomp, 0, __LINE__, 0, 0); | decomp, 0, __LINE__, 0, 0, 0); | ||||
goto bad2; | goto bad2; | ||||
} | } | ||||
bufp->next = NULL; | bufp->next = NULL; | ||||
bufp->size = size * i; | bufp->size = size * i; | ||||
bzero(&zbuf, sizeof(z_stream)); | bzero(&zbuf, sizeof(z_stream)); | ||||
zbuf.zalloc = z_alloc; | zbuf.zalloc = crypto_zalloc; | ||||
zbuf.zfree = z_free; | zbuf.zfree = crypto_zfree; | ||||
zbuf.opaque = Z_NULL; | zbuf.opaque = Z_NULL; | ||||
zbuf.next_in = data; /* Data that is going to be processed. */ | zbuf.next_in = data; /* Data that is going to be processed. */ | ||||
zbuf.avail_in = size; /* Total length of data to be processed. */ | zbuf.avail_in = size; /* Total length of data to be processed. */ | ||||
zbuf.next_out = bufp->data; | zbuf.next_out = bufp->data; | ||||
zbuf.avail_out = bufp->size; | zbuf.avail_out = bufp->size; | ||||
error = decomp ? inflateInit2(&zbuf, window_inflate) : | error = decomp ? z_inflateInit2(&zbuf, window_inflate) : | ||||
deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD, | z_deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD, | ||||
window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY); | window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY); | ||||
if (error != Z_OK) { | if (error != Z_OK) { | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, bad, | ||||
decomp, error, __LINE__, 0, 0); | decomp, error, __LINE__, 0, 0, 0); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
for (;;) { | for (;;) { | ||||
error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) : | error = decomp ? z_inflate(&zbuf, Z_SYNC_FLUSH) : | ||||
deflate(&zbuf, Z_FINISH); | z_deflate(&zbuf, Z_FINISH); | ||||
if (error != Z_OK && error != Z_STREAM_END) { | if (error != Z_OK && error != Z_STREAM_END) { | ||||
/* | SDT_PROBE6(opencrypto, z_deflate, deflate_global, bad, | ||||
* Unfortunately we are limited to 5 arguments, | |||||
* thus use two probes. | |||||
*/ | |||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | |||||
decomp, error, __LINE__, | decomp, error, __LINE__, | ||||
zbuf.avail_in, zbuf.avail_out); | zbuf.avail_in, zbuf.avail_out, zbuf.total_out); | ||||
Done Inline Actionsdelphij: 'bad' is SDT_PROBE5. @markj have implemented additional parameters as of rS251166, maybe we… | |||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | |||||
decomp, error, __LINE__, | |||||
zbuf.state->dummy, zbuf.total_out); | |||||
goto bad; | goto bad; | ||||
} | } | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, iter, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, iter, | ||||
decomp, error, __LINE__, | decomp, error, __LINE__, | ||||
zbuf.avail_in, zbuf.avail_out); | zbuf.avail_in, zbuf.avail_out, zbuf.total_out); | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, iter, | |||||
decomp, error, __LINE__, | |||||
zbuf.state->dummy, zbuf.total_out); | |||||
if (decomp && zbuf.avail_in == 0 && error == Z_STREAM_END) { | if (decomp && zbuf.avail_in == 0 && error == Z_STREAM_END) { | ||||
/* Done. */ | /* Done. */ | ||||
break; | break; | ||||
} else if (!decomp && error == Z_STREAM_END) { | } else if (!decomp && error == Z_STREAM_END) { | ||||
/* Done. */ | /* Done. */ | ||||
break; | break; | ||||
} else if (zbuf.avail_out == 0) { | } else if (zbuf.avail_out == 0) { | ||||
struct deflate_buf *p; | struct deflate_buf *p; | ||||
/* We need more output space for another iteration. */ | /* We need more output space for another iteration. */ | ||||
p = malloc(sizeof(*p) + (size_t)(size * i), | p = malloc(sizeof(*p) + (size_t)(size * i), | ||||
M_CRYPTO_DATA, M_NOWAIT); | M_CRYPTO_DATA, M_NOWAIT); | ||||
if (p == NULL) { | if (p == NULL) { | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, | ||||
bad, decomp, 0, __LINE__, 0, 0); | bad, decomp, 0, __LINE__, 0, 0, 0); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
p->next = NULL; | p->next = NULL; | ||||
p->size = size * i; | p->size = size * i; | ||||
bufp->next = p; | bufp->next = p; | ||||
bufp = p; | bufp = p; | ||||
zbuf.next_out = bufp->data; | zbuf.next_out = bufp->data; | ||||
zbuf.avail_out = bufp->size; | zbuf.avail_out = bufp->size; | ||||
} else { | } else { | ||||
/* Unexpect result. */ | /* Unexpect result. */ | ||||
/* | /* | ||||
* Unfortunately we are limited to 5 arguments, | * Unfortunately we are limited to 5 arguments, | ||||
* thus, again, use two probes. | * thus, again, use two probes. | ||||
*/ | */ | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, bad, | ||||
decomp, error, __LINE__, | decomp, error, __LINE__, | ||||
zbuf.avail_in, zbuf.avail_out); | zbuf.avail_in, zbuf.avail_out, zbuf.total_out); | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | |||||
decomp, error, __LINE__, | |||||
zbuf.state->dummy, zbuf.total_out); | |||||
goto bad; | goto bad; | ||||
} | } | ||||
} | } | ||||
result = count = zbuf.total_out; | result = count = zbuf.total_out; | ||||
*out = malloc(result, M_CRYPTO_DATA, M_NOWAIT); | *out = malloc(result, M_CRYPTO_DATA, M_NOWAIT); | ||||
if (*out == NULL) { | if (*out == NULL) { | ||||
SDT_PROBE5(opencrypto, deflate, deflate_global, bad, | SDT_PROBE6(opencrypto, z_deflate, deflate_global, bad, | ||||
decomp, 0, __LINE__, 0, 0); | decomp, 0, __LINE__, 0, 0, 0); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
if (decomp) | if (decomp) | ||||
inflateEnd(&zbuf); | z_inflateEnd(&zbuf); | ||||
else | else | ||||
deflateEnd(&zbuf); | z_deflateEnd(&zbuf); | ||||
output = *out; | output = *out; | ||||
for (bufp = bufh; bufp != NULL; ) { | for (bufp = bufh; bufp != NULL; ) { | ||||
if (count > bufp->size) { | if (count > bufp->size) { | ||||
struct deflate_buf *p; | struct deflate_buf *p; | ||||
bcopy(bufp->data, *out, bufp->size); | bcopy(bufp->data, *out, bufp->size); | ||||
*out += bufp->size; | *out += bufp->size; | ||||
count -= bufp->size; | count -= bufp->size; | ||||
p = bufp; | p = bufp; | ||||
bufp = bufp->next; | bufp = bufp->next; | ||||
free(p, M_CRYPTO_DATA); | free(p, M_CRYPTO_DATA); | ||||
} else { | } else { | ||||
/* It should be the last buffer. */ | /* It should be the last buffer. */ | ||||
bcopy(bufp->data, *out, count); | bcopy(bufp->data, *out, count); | ||||
*out += count; | *out += count; | ||||
free(bufp, M_CRYPTO_DATA); | free(bufp, M_CRYPTO_DATA); | ||||
bufp = NULL; | bufp = NULL; | ||||
count = 0; | count = 0; | ||||
} | } | ||||
} | } | ||||
*out = output; | *out = output; | ||||
SDT_PROBE2(opencrypto, deflate, deflate_global, return, decomp, result); | SDT_PROBE2(opencrypto, z_deflate, deflate_global, return, decomp, result); | ||||
return result; | return result; | ||||
bad: | bad: | ||||
if (decomp) | if (decomp) | ||||
inflateEnd(&zbuf); | z_inflateEnd(&zbuf); | ||||
else | else | ||||
deflateEnd(&zbuf); | z_deflateEnd(&zbuf); | ||||
for (bufp = bufh; bufp != NULL; ) { | for (bufp = bufh; bufp != NULL; ) { | ||||
struct deflate_buf *p; | struct deflate_buf *p; | ||||
p = bufp; | p = bufp; | ||||
bufp = bufp->next; | bufp = bufp->next; | ||||
free(p, M_CRYPTO_DATA); | free(p, M_CRYPTO_DATA); | ||||
} | } | ||||
bad2: | bad2: | ||||
*out = NULL; | *out = NULL; | ||||
return 0; | return 0; | ||||
} | } | ||||
void * | void * | ||||
z_alloc(nil, type, size) | crypto_zalloc(void *nil, u_int type, u_int size) | ||||
void *nil; | |||||
u_int type, size; | |||||
{ | { | ||||
void *ptr; | void *ptr; | ||||
ptr = malloc(type *size, M_CRYPTO_DATA, M_NOWAIT); | ptr = malloc(type *size, M_CRYPTO_DATA, M_NOWAIT); | ||||
return ptr; | return ptr; | ||||
} | } | ||||
void | void | ||||
z_free(nil, ptr) | crypto_zfree(void *nil, void *ptr) | ||||
void *nil, *ptr; | |||||
{ | { | ||||
free(ptr, M_CRYPTO_DATA); | free(ptr, M_CRYPTO_DATA); | ||||
} | } |
the new line before crypto_zalloc() is not necessary.