Module Name:    othersrc
Committed By:   agc
Date:           Wed Mar 26 01:20:34 UTC 2014

Modified Files:
        othersrc/external/bsd/multigest/bin: Makefile
        othersrc/external/bsd/multigest/dist: multigest.c multigest.h
Added Files:
        othersrc/external/bsd/multigest/bin: 24.expected 25.expected
            26.expected

Log Message:
Update multigest to version 20140325

+ add digest combiners to the finalisation part of multigest.
  4 combiners are provided:

  + concat (the default, where output is appended)
    collision resistance is needed, but NOT pre-image-resistance,
    second pre-image resistance, PRF

  + comb4p
    (see "On the Security of Hash function Combiners", Ph.D. thesis
     by Anja Lehmann)

        
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.187.4611&rep=rep1&type=pdf

    collision-resistant, PRF, target-collision-resistant, and MAC
    not as efficient as other combiners

  + xor (result is final-digest1 ^ final-digest2)
    where PRF needed, but NOT collision resistance

  + hash (finalisation part does is update-digest1(final-digest2()))
    where pre-image-resistance needed, but NOT collision resistance

  these are specified as pseudo-digests in the algorithm specification
  For a discussion of digest combiners, please see:
  https://tahoe-lafs.org/pipermail/tahoe-dev/2010-June/004575.html

+ modify rawsize calculation to only require as many bytes as will appear
  in the resulting hash


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/multigest/bin/24.expected \
    othersrc/external/bsd/multigest/bin/25.expected \
    othersrc/external/bsd/multigest/bin/26.expected
cvs rdiff -u -r1.4 -r1.5 othersrc/external/bsd/multigest/bin/Makefile
cvs rdiff -u -r1.10 -r1.11 othersrc/external/bsd/multigest/dist/multigest.c
cvs rdiff -u -r1.8 -r1.9 othersrc/external/bsd/multigest/dist/multigest.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: othersrc/external/bsd/multigest/bin/Makefile
diff -u othersrc/external/bsd/multigest/bin/Makefile:1.4 othersrc/external/bsd/multigest/bin/Makefile:1.5
--- othersrc/external/bsd/multigest/bin/Makefile:1.4	Sun Aug 18 06:03:14 2013
+++ othersrc/external/bsd/multigest/bin/Makefile	Wed Mar 26 01:20:34 2014
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2013/08/18 06:03:14 agc Exp $
+# $NetBSD: Makefile,v 1.5 2014/03/26 01:20:34 agc Exp $
 
 .include <bsd.own.mk>
 
@@ -94,3 +94,12 @@ t: ${PROG}
 	env LD_LIBRARY_PATH=${LIB_MULTIGEST_DIR} ./${PROG} -o 23.out -Fdigest -a blake2,crc32c,md5,rmd160,sha1,sha256,sha3-224,sha3-256,sha3-384,sha3-512,sha512,size,tiger2,tiger,whirlpool -r 2.in
 	diff 23.expected 23.out
 	rm -f 23.out
+	env LD_LIBRARY_PATH=${LIB_MULTIGEST_DIR} ./${PROG} -o 24.out -a comb4p,rmd160,sha1 2.in
+	diff 24.expected 24.out
+	rm -f 24.out
+	env LD_LIBRARY_PATH=${LIB_MULTIGEST_DIR} ./${PROG} -o 25.out -a xor,rmd160,sha1 2.in
+	diff 25.expected 25.out
+	rm -f 25.out
+	env LD_LIBRARY_PATH=${LIB_MULTIGEST_DIR} ./${PROG} -o 26.out -a hash,rmd160,sha1 2.in
+	diff 26.expected 26.out
+	rm -f 26.out

Index: othersrc/external/bsd/multigest/dist/multigest.c
diff -u othersrc/external/bsd/multigest/dist/multigest.c:1.10 othersrc/external/bsd/multigest/dist/multigest.c:1.11
--- othersrc/external/bsd/multigest/dist/multigest.c:1.10	Tue Mar 25 17:44:34 2014
+++ othersrc/external/bsd/multigest/dist/multigest.c	Wed Mar 26 01:20:34 2014
@@ -175,6 +175,12 @@ wrap_size_init(void *v)
 	memset(v, 0x0, sizeof(uint64_t));
 }
 
+static void
+wrap_null_init(void *v)
+{
+	USE_ARG(v);
+}
+
 /*****/
 
 static void
@@ -249,6 +255,14 @@ wrap_size_update(void *v, const char *da
 	memcpy(v, &n, sizeof(n));
 }
 
+static void
+wrap_null_update(void *v, const char *data, unsigned len)
+{
+	USE_ARG(v);
+	USE_ARG(data);
+	USE_ARG(len);
+}
+
 /*****/
 
 static void
@@ -330,8 +344,20 @@ wrap_size_final(uint8_t *raw, void *v)
 	memcpy(raw, &w, sizeof(w));
 }
 
+static void
+wrap_null_final(uint8_t *raw, void *v)
+{
+	USE_ARG(raw);
+	USE_ARG(v);
+}
+
 /*****/
 
+#define COMBINE_CONCAT		0x0
+#define COMBINE_COMB4P		0x1
+#define COMBINE_HASH		0x2
+#define COMBINE_XOR		0x3
+
 /* digest algorithm struct */
 typedef struct Alg {
 	const char	*name;		/* digest name */
@@ -341,30 +367,38 @@ typedef struct Alg {
 	mg_initfunc_t	 init;		/* digest init function */
 	mg_updatefunc_t	 update;	/* digest update function */
 	mg_finalfunc_t	 final;		/* digest final function */
+	uint32_t	 combiner;	/* combination type */
 } Alg;
 
 static const Alg	algs[] = {
-	{ "MD5",	3, sizeof(MD5_CTX), 	16, wrap_md5_init, wrap_md5_update, wrap_md5_final },
-	{ "SHA1",	4, sizeof(SHA1_CTX), 	20, wrap_sha1_init, wrap_sha1_update, wrap_sha1_final },
-	{ "SHA256",	6, sizeof(SHA256_CTX), 	32, wrap_sha256_init, wrap_sha256_update, wrap_sha256_final },
-	{ "SHA512",	6, sizeof(SHA512_CTX), 	64, wrap_sha512_init, wrap_sha512_update, wrap_sha512_final },
-	{ "BLAKE2",	6, sizeof(BLAKE2_CTX),	64, wrap_blake2_init, wrap_blake2_update, wrap_blake2_final },
-	{ "RMD160",	6, sizeof(RMD160_CTX), 	20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final },
-	{ "RIPEMD160",	9, sizeof(RMD160_CTX), 	20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final },
-	{ "CRC32C",	6, sizeof(ctx32_t), 	4,  wrap_crc32c_init, wrap_crc32c_update, wrap_crc32c_final },
-	{ "TIGER2",	6, sizeof(TIGER_CTX), 	24, wrap_tiger2_init, wrap_tiger_update, wrap_tiger_final },
-	{ "TIGER",	5, sizeof(TIGER_CTX), 	24, wrap_tiger_init, wrap_tiger_update, wrap_tiger_final },
-	{ "WHIRLPOOL",	9, sizeof(whirlpool_context_t), 64, wrap_whirlpool_init, wrap_whirlpool_update, wrap_whirlpool_final },
-	{ "SHA3-224",	8, sizeof(KECCAK_CTX),	28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final },
-	{ "SHA3-256",	8, sizeof(KECCAK_CTX),	32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final },
-	{ "SHA3-384",	8, sizeof(KECCAK_CTX),	48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final },
-	{ "SHA3-512",	8, sizeof(KECCAK_CTX),	64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final },
-	{ "KECCAK-224",	10, sizeof(KECCAK_CTX),	28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final },
-	{ "KECCAK-256",	10, sizeof(KECCAK_CTX),	32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final },
-	{ "KECCAK-384",	10, sizeof(KECCAK_CTX),	48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final },
-	{ "KECCAK-512",	10, sizeof(KECCAK_CTX),	64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final },
-	{ "SIZE",	4, sizeof(uint64_t),	8, wrap_size_init, wrap_size_update, wrap_size_final },
-	{ NULL, 0, 0, 0, NULL, NULL, NULL}
+	{ "MD5",	3, sizeof(MD5_CTX), 	16, wrap_md5_init, wrap_md5_update, wrap_md5_final, 0 },
+	{ "SHA1",	4, sizeof(SHA1_CTX), 	20, wrap_sha1_init, wrap_sha1_update, wrap_sha1_final, 0 },
+	{ "SHA256",	6, sizeof(SHA256_CTX), 	32, wrap_sha256_init, wrap_sha256_update, wrap_sha256_final, 0 },
+	{ "SHA512",	6, sizeof(SHA512_CTX), 	64, wrap_sha512_init, wrap_sha512_update, wrap_sha512_final, 0 },
+	{ "BLAKE2",	6, sizeof(BLAKE2_CTX),	64, wrap_blake2_init, wrap_blake2_update, wrap_blake2_final, 0 },
+	{ "RMD160",	6, sizeof(RMD160_CTX), 	20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final, 0 },
+	{ "RIPEMD160",	9, sizeof(RMD160_CTX), 	20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final, 0 },
+	{ "CRC32C",	6, sizeof(ctx32_t), 	4,  wrap_crc32c_init, wrap_crc32c_update, wrap_crc32c_final, 0 },
+	{ "TIGER2",	6, sizeof(TIGER_CTX), 	24, wrap_tiger2_init, wrap_tiger_update, wrap_tiger_final, 0 },
+	{ "TIGER",	5, sizeof(TIGER_CTX), 	24, wrap_tiger_init, wrap_tiger_update, wrap_tiger_final, 0 },
+	{ "WHIRLPOOL",	9, sizeof(whirlpool_context_t), 64, wrap_whirlpool_init, wrap_whirlpool_update, wrap_whirlpool_final, 0 },
+	{ "SHA3-224",	8, sizeof(KECCAK_CTX),	28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "SHA3-256",	8, sizeof(KECCAK_CTX),	32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "SHA3-384",	8, sizeof(KECCAK_CTX),	48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "SHA3-512",	8, sizeof(KECCAK_CTX),	64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "KECCAK-224",	10, sizeof(KECCAK_CTX),	28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "KECCAK-256",	10, sizeof(KECCAK_CTX),	32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "KECCAK-384",	10, sizeof(KECCAK_CTX),	48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "KECCAK-512",	10, sizeof(KECCAK_CTX),	64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final, 0 },
+	{ "SIZE",	4, sizeof(uint64_t),	8, wrap_size_init, wrap_size_update, wrap_size_final, 0 },
+	{ "COMBCONCAT",	10, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_CONCAT },
+	{ "CONCAT",	6, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_CONCAT },
+	{ "COMB4P",	6, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_COMB4P },
+	{ "COMBHASH",	8, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_HASH },
+	{ "HASH",	4, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_HASH },
+	{ "COMBXOR",	7, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_XOR },
+	{ "XOR",	3, 0,			0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_XOR },
+	{ NULL, 0, 0, 0, NULL, NULL, NULL, 0}
 };
 
 /* find an algorithm in the table above */
@@ -413,6 +447,48 @@ normalise(multigest_t *multigest, const 
 	return 1;
 }
 
+/* xor the contents of two buffers together */
+static void
+xorbuf(uint8_t *out, uint8_t *in1, uint8_t *in2, size_t size)
+{
+	uint32_t	j;
+
+	for (j = 0 ; j < size ; j++) {
+		out[j] = in1[j] ^ in2[j];
+	}
+}
+
+/* a round of comb4p combination */
+static int
+comb4p_round(multigest_t *m, uint8_t *out, uint8_t *in, size_t insize, uint32_t r)
+{
+	multigest_dig_t	*d;
+	const int	 indian = 1;
+	uint32_t	 b2;
+	uint32_t	 b4;
+	uint32_t	 i;
+	uint8_t		 h1[4096];
+	uint8_t		 h2[4096];
+
+	if (*(const char *)(const void *)&indian) {
+		/* little endian - convert to bg endian) */
+		b2 = (r & 0x00ff0000);
+		b4 = (r & 0x000000ff);
+		r = (r & 0xff00ff00) | (b2 >> 16) | (b4 << 16);
+	}
+	for (d = &m->digs[1], i = 1 ; i < m->digc ; i++, d++) {
+		(*d->update)(&m->ctx[d->ctxoff], (const char *)&r, sizeof(r));
+		(*d->update)(&m->ctx[d->ctxoff], (const char *)in, insize);
+	}
+	d = &m->digs[1];
+	(*d->final)(h1, &m->ctx[d->ctxoff]);
+	xorbuf(out, out, h1, d->rawsize);
+	d = &m->digs[2];
+	(*d->final)(h2, &m->ctx[d->ctxoff]);
+	xorbuf(out, out, h2, d->rawsize);
+	return 1;
+}
+
 /***************************************************************************/
 
 /* create a new struct and return it */
@@ -444,6 +520,9 @@ multigest_init(multigest_t *multigest, c
 				fprintf(stderr, "no such algorithm '%.10s'\n", algname);
 				break;
 			}
+			if (alg->combiner) {
+				multigest->combiner = alg->combiner;
+			}
 			if (ctxoff + alg->ctxsize >= multigest->ctxsize) {
 				if ((newv = realloc(multigest->ctx, multigest->ctxsize + 4096)) == NULL) {
 					fprintf(stderr, "multigest_init: allocation issues\n");
@@ -466,6 +545,20 @@ multigest_init(multigest_t *multigest, c
 			}
 			multigest->digc += 1;
 		}
+		switch (multigest->combiner) {
+		case COMBINE_CONCAT:
+			multigest->outsize = multigest->rawsize;
+			break;
+		case COMBINE_COMB4P:
+			multigest->outsize = multigest->digs[1].rawsize * 2;
+			break;
+		case COMBINE_XOR:
+			multigest->outsize = multigest->digs[1].rawsize;
+			break;
+		case COMBINE_HASH:
+			multigest->outsize = multigest->digs[1].rawsize;
+			break;
+		}
 		return 1;
 	}
 	fprintf(stderr, "!multigest || !algname\n");
@@ -508,35 +601,75 @@ multigest_update(multigest_t *multigest,
 }
 
 /* finalise the digest */
-void
-multigest_final(multigest_t *multigest, uint8_t *raw)
+int
+multigest_final(multigest_t *m, uint8_t *raw)
 {
 	multigest_dig_t	*d;
 	uint32_t	 rawoff;
 	uint32_t	 i;
+	uint8_t		 h1[4096];
+	uint8_t		 h2[4096];
 
-	if (multigest && raw) {
-		rawoff = 0;
-		for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) {
-			(*d->final)(&raw[rawoff], &multigest->ctx[d->ctxoff]);
-			rawoff += (uint32_t)d->rawsize;
+	if (m && raw) {
+		switch(m->combiner) {
+		case COMBINE_COMB4P:
+			if (m->digc != 3 || m->digs[1].rawsize != m->digs[2].rawsize) {
+				return 0;
+			}
+			d = &m->digs[1];
+			(*d->final)(h1, &m->ctx[d->ctxoff]);
+			d = &m->digs[2];
+			(*d->final)(h2, &m->ctx[d->ctxoff]);
+			xorbuf(h1, h1, h2, d->rawsize);
+			comb4p_round(m, h2, h1, d->rawsize, 1); 
+			comb4p_round(m, h1, h2, d->rawsize, 2); 
+			memcpy(raw, h1, d->rawsize);
+			memcpy(&raw[d->rawsize], h2, d->rawsize);
+			break;
+		case COMBINE_CONCAT:
+			rawoff = 0;
+			for (d = m->digs, i = 0 ; i < m->digc ; i++, d++) {
+				if (d->rawsize) {
+					(*d->final)(&raw[rawoff], &m->ctx[d->ctxoff]);
+					rawoff += (uint32_t)d->rawsize;
+				}
+			}
+			break;
+		case COMBINE_HASH:
+			d = &m->digs[2];
+			(*d->final)(h2, &m->ctx[d->ctxoff]);
+			d = &m->digs[1];
+			(*d->update)(&m->ctx[d->ctxoff], (const char *)h2, m->digs[2].rawsize);
+			(*d->final)(raw, &m->ctx[d->ctxoff]);
+			break;
+		case COMBINE_XOR:
+			d = &m->digs[2];
+			(*d->final)(h2, &m->ctx[d->ctxoff]);
+			d = &m->digs[1];
+			(*d->final)(h1, &m->ctx[d->ctxoff]);
+			xorbuf(raw, h1, h2, m->outsize);
+			break;
+		default:
+			break;
 		}
+		return 1;
 	}
+	return 0;
 }
 
 /* run sed on data and then digest it */
 uint8_t *
 multigest_data(const char *alg, const char *data, size_t size, uint8_t *raw, const char *pat, const char *repl)
 {
-	multigest_t	s;
+	multigest_t	m;
 
 	if (data && alg && raw) {
-		memset(&s, 0x0, sizeof(s));
-		multigest_init(&s, alg);
-		multigest_add_subst(&s, pat, repl);
-		multigest_update(&s, data, size);
-		multigest_final(&s, raw);
-		multigest_free(&s);
+		memset(&m, 0x0, sizeof(m));
+		multigest_init(&m, alg);
+		multigest_add_subst(&m, pat, repl);
+		multigest_update(&m, data, size);
+		multigest_final(&m, raw);
+		multigest_free(&m);
 		return raw;
 	}
 	return NULL;
@@ -593,7 +726,7 @@ multigest_format_hex(uint8_t *raw, const
 uint32_t
 multigest_get_rawsize(multigest_t *multigest)
 {
-	return (multigest) ? (uint32_t)multigest->rawsize : 0;
+	return (multigest) ? (uint32_t)multigest->outsize : 0;
 }
 
 /* return the size of output array we'll need for the alg names */
@@ -637,6 +770,7 @@ multigest_print_hex(uint8_t *raw, const 
 	const char *f, const char *sub, const char *sep, const char *format)
 {
 	const Alg	*alg;
+	size_t		 outsize;
 	size_t		 rawsize;
 	size_t		 i;
 	FILE		*fp;
@@ -665,7 +799,8 @@ multigest_print_hex(uint8_t *raw, const 
 			fprintf(fp, ") = ");
 		}
 	}
-	for (rawsize = 0 ; *algname ; rawsize += alg->rawsize) {
+	outsize = multigest_algs_rawsize(algname);
+	for (rawsize = 0 ; *algname && rawsize < outsize ; rawsize += alg->rawsize) {
 		if ((alg = findalg(algname)) == NULL) {
 			break;
 		}
@@ -724,7 +859,7 @@ multigest_file(const char *alg, const ch
 			munmap(mapped, size);
 		}
 		fclose(fp);
-                multigest_final(&m, raw);
+		multigest_final(&m, raw);
                 multigest_free(&m);
 		return raw;
 	}

Index: othersrc/external/bsd/multigest/dist/multigest.h
diff -u othersrc/external/bsd/multigest/dist/multigest.h:1.8 othersrc/external/bsd/multigest/dist/multigest.h:1.9
--- othersrc/external/bsd/multigest/dist/multigest.h:1.8	Wed Mar  5 04:56:00 2014
+++ othersrc/external/bsd/multigest/dist/multigest.h	Wed Mar 26 01:20:34 2014
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MULTIGEST_H_
-#define MULTIGEST_H_	20140304
+#define MULTIGEST_H_	20140325
 
 #include <sys/types.h>
 
@@ -56,6 +56,8 @@ typedef struct multigest_t {
 	uint8_t		*ctx;		/* digest contexts */
 	uint32_t	 digc;		/* # of digests */
 	multigest_dig_t	 digs[MG_MAX_DIG];	/* digest algorithms being used */
+	uint32_t	 combiner;	/* when finalising, combination algorithm */
+	size_t		 outsize;	/* output size of digest - combiners may change this */
 } multigest_t;
 
 #ifndef __BEGIN_DECLS
@@ -78,7 +80,7 @@ void multigest_free(multigest_t */*s*/);
 int multigest_init(multigest_t */*multigest*/, const char */*alg*/);
 int multigest_add_subst(multigest_t */*multigest*/, const char */*from*/, const char */*to*/);
 void multigest_update(multigest_t */*multigest*/, const char */*data*/, size_t /*len*/);
-void multigest_final(multigest_t */*multigest*/, uint8_t */*raw*/);
+int multigest_final(multigest_t */*multigest*/, uint8_t */*raw*/);
 uint32_t multigest_get_rawsize(multigest_t */*multigest*/);
 
 /* high-level interface */

Added files:

Index: othersrc/external/bsd/multigest/bin/24.expected
diff -u /dev/null othersrc/external/bsd/multigest/bin/24.expected:1.1
--- /dev/null	Wed Mar 26 01:20:34 2014
+++ othersrc/external/bsd/multigest/bin/24.expected	Wed Mar 26 01:20:34 2014
@@ -0,0 +1 @@
+COMB4P,RMD160,SHA1 (2.in) () = f82dbe74896edf4227c5bb2332b28e02f1e693e2b5a61aa2886c42e95c47318d9cd8749ebea92392
Index: othersrc/external/bsd/multigest/bin/25.expected
diff -u /dev/null othersrc/external/bsd/multigest/bin/25.expected:1.1
--- /dev/null	Wed Mar 26 01:20:34 2014
+++ othersrc/external/bsd/multigest/bin/25.expected	Wed Mar 26 01:20:34 2014
@@ -0,0 +1 @@
+XOR,RMD160,SHA1 (2.in) () = efd09010da9160033b438802f26452d84517d035
Index: othersrc/external/bsd/multigest/bin/26.expected
diff -u /dev/null othersrc/external/bsd/multigest/bin/26.expected:1.1
--- /dev/null	Wed Mar 26 01:20:34 2014
+++ othersrc/external/bsd/multigest/bin/26.expected	Wed Mar 26 01:20:34 2014
@@ -0,0 +1 @@
+HASH,RMD160,SHA1 (2.in) () = ce7d9bbded7d5a51baa114889e81fd8c1e5d89a3

Reply via email to