New API for MD5 production: iso_md5_start(), iso_md5_compute(),

iso_md5_clone(), iso_md5_end()
This commit is contained in:
Thomas Schmitt 2009-08-11 12:07:32 +02:00
parent 429b4cd21c
commit fd124c82d2
5 changed files with 191 additions and 53 deletions

View File

@ -63,8 +63,10 @@ void ecma119_image_free(Ecma119Image *t)
free(t->output_charset);
#ifdef Libisofs_with_checksumS
if (t->checksum_ctx != NULL) /* dispose checksum context */
libisofs_md5(&(t->checksum_ctx), NULL, 0, NULL, (1 << 15));
if (t->checksum_ctx != NULL) { /* dispose checksum context */
char md5[16];
iso_md5_end(&(t->checksum_ctx), md5);
}
if (t->checksum_buffer != NULL)
free(t->checksum_buffer);
#endif
@ -1275,7 +1277,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
#ifdef Libisofs_with_checksumS
if (target->md5_session_checksum) {
/* After any fake writes are done: Initialize image checksum context */
ret = libisofs_md5(&(target->checksum_ctx), NULL, 0, NULL, 1);
ret = iso_md5_start(&(target->checksum_ctx));
if (ret < 0)
return ret;
}
@ -1450,8 +1452,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
if (target->checksum_ctx != NULL) {
/* Add to image checksum */
target->checksum_counter += count;
libisofs_md5(&(target->checksum_ctx), (char *) buf, (int) count,
NULL, 0);
iso_md5_compute(target->checksum_ctx, (char *) buf, (int) count);
}
#endif /* Libisofs_with_checksumS */

View File

@ -308,7 +308,7 @@ int filesrc_read(IsoFileSrc *file, char *buf, size_t count)
static
int filesrc_writer_write_data(IsoImageWriter *writer)
{
int res;
int res, ret;
size_t i, b;
Ecma119Image *t;
IsoFileSrc *file;
@ -351,14 +351,16 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
"File \"%s\" can't be opened. Filling with 0s.", name);
if (res < 0) {
return res; /* aborted due to error severity */
ret = res; /* aborted due to error severity */
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
for (b = 0; b < nblocks; ++b) {
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
return res;
ret = res;
goto ex;
}
}
continue;
@ -369,7 +371,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
(res == 2 ? "truncated" : "padded with 0's"));
if (res < 0) {
filesrc_close(file);
return res; /* aborted due to error severity */
ret = res; /* aborted due to error severity */
goto ex;
}
}
#ifdef LIBISOFS_VERBOSE_DEBUG
@ -383,7 +386,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (file->checksum_index > 0) {
/* initialize file checksum */
res = libisofs_md5(&ctx, NULL, 0, md5, 1);
res = iso_md5_start(&ctx);
if (res <= 0)
file->checksum_index = 0;
}
@ -402,7 +405,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (wres < 0) {
/* ko, writer error, we need to go out! */
filesrc_close(file);
return wres;
ret = wres;
goto ex;
}
#ifdef Libisofs_with_checksumS
@ -412,7 +416,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
res = file_size - b * BLOCK_SIZE;
if (res > BLOCK_SIZE)
res = BLOCK_SIZE;
res = libisofs_md5(&ctx, buffer, res, md5, 0);
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
@ -437,7 +441,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
}
if (res < 0) {
return res; /* aborted due error severity */
ret = res; /* aborted due error severity */
goto ex;
}
/* fill with 0s */
@ -448,7 +453,8 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
res = iso_write(t, buffer, BLOCK_SIZE);
if (res < 0) {
/* ko, writer error, we need to go out! */
return res;
ret = res;
goto ex;
}
#ifdef Libisofs_with_checksumS
@ -458,7 +464,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
res = file_size - b * BLOCK_SIZE;
if (res > BLOCK_SIZE)
res = BLOCK_SIZE;
res = libisofs_md5(&ctx, buffer, res, md5, 0);
res = iso_md5_compute(ctx, buffer, res);
if (res <= 0)
file->checksum_index = 0;
}
@ -472,7 +478,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
if (file->checksum_index > 0) {
/* Obtain checksum and dispose checksum context */
res = libisofs_md5(&ctx, buffer, 0, md5, 2 | (1 << 15));
res = iso_md5_end(&ctx, md5);
if (res <= 0)
file->checksum_index = 0;
@ -487,7 +493,15 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
#ifdef Libisofs_with_checksumS
if (ctx != NULL) /* avoid any memory leak */
iso_md5_end(&ctx, md5);
#endif
return ret;
}
static

View File

@ -4991,6 +4991,9 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag);
/* ---------------------------- MD5 Checksums --------------------------- */
/* Production and loading of MD5 checksums is controlled by calls
iso_write_opts_set_record_md5() and iso_read_opts_set_no_md5()
*/
/**
* Eventually obtain the recorded MD5 checksum of the session which was
@ -5039,6 +5042,72 @@ int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
/* The following functions allow to do own MD5 computations. E.g for
comparing the result with a recorded checksum.
*/
/**
* Create a MD5 computation context and hand out an opaque handle.
*
* @param md5_context
* Returns the opaque handle. Submitted *md5_context must be NULL or
* point to freeable memory.
* @return
* 1= success , <0 indicates error
*
* @since 0.6.22
*/
int iso_md5_start(void **md5_context);
/**
* Advance the computation of a MD5 checksum by a chunk of data bytes.
*
* @param md5_context
* An opaque handle once returned by iso_md5_start() or iso_md5_clone().
* @param data
* The bytes which shall be processed into to the checksum.
* @param datalen
* The number of bytes to be processed.
* @return
* 1= success , <0 indicates error
*
* @since 0.6.22
*/
int iso_md5_compute(void *md5_context, char *data, int datalen);
/**
* Create a MD5 computation context as clone of an existing one. One may call
* iso_md5_clone(old, &new, 0) and then iso_md5_end(&new, result, 0) in order
* to obtain an intermediate MD5 sum before the computation goes on.
*
* @param old_md5_context
* An opaque handle once returned by iso_md5_start() or iso_md5_clone().
* @param new_md5_context
* Returns the opaque handle to the new MD5 context. Submitted
* *md5_context must be NULL or point to freeable memory.
* @return
* 1= success , <0 indicates error
*
* @since 0.6.22
*/
int iso_md5_clone(void *old_md5_context, void **new_md5_context);
/**
* Obtain the MD5 checksum from a MD5 computation context and dispose this
* context. (If you want to keep the context then call iso_md5_clone() and
* apply iso_md5_end() to the clone.)
*
* @param md5_context
* A pointer to an opaque handle once returned by iso_md5_start() or
* iso_md5_clone(). *md5_context will be set to NULL in this call.
* @param result
* Gets filled with the 16 bytes of MD5 checksum.
* @return
* 1= success , <0 indicates error
*
* @since 0.6.22
*/
int iso_md5_end(void **md5_context, char result[16]);
/************ Error codes and return values for libisofs ********************/
@ -5523,6 +5592,14 @@ struct burn_source {
#define Libisofs_hardlink_prooF yes
/* Checksums : During image writing equip IsoFile objects with MD5 checksums
and compute an overall checksum of the session. Store them in
a separate checksum block area after the data area of the
session.
*/
#define Libisofs_with_checksumS yes
/* ---------------------------- Experiments ---------------------------- */
/* <<< on its way out
@ -5542,14 +5619,4 @@ struct burn_source {
*/
/* Experiment: During image writing equip IsoFile objects with MD5 checksums
and compute an overall checksum of the image. Store them in
a separate checksum block area after the data area of the
image.
ENABLE ONLY FOR DEVELOPMENT TESTS !
*/
#define Libisofs_with_checksumS yes
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -269,7 +269,28 @@ static int md5_final(libisofs_md5_ctx *ctx, char result[16], int flag)
return(1);
}
/** Compute a MD5 checksum from one or more calls of this function.
The first call has to be made with flag bit0 == 1. It may already submit
processing payload in data and datalen.
The last call has to be made with bit15 set. Normally bit1 will be set
too in order to receive the checksum before it gets disposed.
bit1 may only be set in the last call or together with bit2.
The combination of bit1 and bit2 may be used to get an intermediate
result without hampering an ongoing checksum computation.
@param ctx the checksum context which stores the state between calls.
It gets created with flag bit0 and disposed with bit15.
With flag bit0, *ctx has to be NULL or point to freeable
memory.
@param data the bytes to be checksummed
@param datalen the number of bytes in data
@param result returns the 16 bytes of checksum if called with bit1 set
@param flag bit0= allocate and init *ctx
bit1= transfer ctx to result
bit2= with bit 0 : clone new *ctx from data
bit15= free *ctx
*/
static
int libisofs_md5(void **ctx_in, char *data, int datalen,
char result[16], int flag)
/* *ctx has to be NULL or point to freeable memory */
@ -310,6 +331,60 @@ int libisofs_md5(void **ctx_in, char *data, int datalen,
}
/* ----------------------------------------------------------------------- */
/* Public MD5 computing facility */
/* API */
int iso_md5_start(void **md5_context)
{
int ret;
ret = libisofs_md5(md5_context, NULL, 0, NULL, 1);
if (ret <= 0)
return ISO_OUT_OF_MEM;
return 1;
}
/* API */
int iso_md5_compute(void *md5_context, char *data, int datalen)
{
int ret;
ret = libisofs_md5(&md5_context, data, datalen, NULL, 0);
if (ret <= 0)
return ISO_NULL_POINTER;
return 1;
}
/* API */
int iso_md5_clone(void *old_md5_context, void **new_md5_context)
{
int ret;
ret = libisofs_md5(new_md5_context, old_md5_context, 0, NULL, 4);
if (ret < 0)
return ISO_OUT_OF_MEM;
if (ret == 0)
return ISO_NULL_POINTER;
return 1;
}
/* API */
int iso_md5_end(void **md5_context, char result[16])
{
int ret;
ret = libisofs_md5(md5_context, NULL, 0, result, 2 | (1 << 15));
if (ret <= 0)
return ISO_NULL_POINTER;
return 1;
}
/* ----------------------------------------------------------------------- */
@ -324,6 +399,10 @@ int checksum_xinfo_func(void *data, int flag)
}
/* ----------------------------------------------------------------------- */
/* MD5 checksum image writer */
#ifdef Libisofs_with_checksumS
/*
@ -459,10 +538,9 @@ int checksum_writer_write_data(IsoImageWriter *writer)
/* Write image checksum to index 0 */
if (t->checksum_ctx != NULL) {
/* >>> rather fork a result than killing t->checksum_ctx */;
/* >>> rather clone a result than killing t->checksum_ctx */;
res = libisofs_md5(&(t->checksum_ctx), NULL, 0, t->image_md5,
2 | (1 << 15));
res = iso_md5_end(&(t->checksum_ctx), t->image_md5);
if (res > 0)
memcpy(t->checksum_buffer + 0, t->image_md5, 16);
}

View File

@ -10,29 +10,7 @@
#define LIBISO_MD5_H_
/** Compute a MD5 checksum from one or more calls of this function.
The first call has to be made with flag bit0 == 1. It may already submit
processing payload in data and datalen.
The last call has to be made with bit15 set. Normally bit1 will be set
too in order to receive the checksum before it gets disposed.
bit1 may only be set in the last call or together with bit2.
The combination of bit1 and bit2 may be used to get an intermediate
result without hampering an ongoing checksum computation.
@param ctx the checksum context which stores the state between calls.
It gets created with flag bit0 and disposed with bit15.
With flag bit0, *ctx has to be NULL or point to freeable
memory.
@param data the bytes to be checksummed
@param datalen the number of bytes in data
@param result returns the 16 bytes of checksum if called with bit1 set
@param flag bit0= allocate and init *ctx
bit1= transfer ctx to result
bit2= with bit 0 : clone new *ctx from data
bit15= free *ctx
*/
int libisofs_md5(void **ctx, char *data, int datalen,
char result[16], int flag);
/* The MD5 computation API is in libisofs.h : iso_md5_start() et.al. */
/** Create a writer object for checksums and add it to the writer list of