Module Name:    othersrc
Committed By:   agc
Date:           Thu Mar  8 02:44:06 UTC 2012

Modified Files:
        othersrc/crypto/external/bsd/ssss/dist/include: ssss.h
        othersrc/crypto/external/bsd/ssss/dist/src/libssss: libssss.3
            secsplit.c

Log Message:
Update the ssss code:

+ add the ability to encode split shares as 16bit or 24-bit values,
which greatly simplifies input and output, and allows constant-sized
output for given inputs.  This also gives us the ability to use larger
primes, although space is wasted with these, and it's not immediately
obvious what advantage would accrue.  But it's there, just in case.

+ we advertise being able to do 255 (SSSS_MAX_SHARES) shares - so
complete the inverse table for GF(16) arithmetic modulo P for 256
values

+ use SSSS_MAX_SHARES (255) internally, rather than the previous
internal (and much smaller) limits

+ simplify the I/O in this library - it was a remnant from 1993

+ remove private structs and definitions from the header file - they're
not part of the public interface, and shouldn't be exposed

+ add ssss_split_vec() and ssss_combine_vec() which give input and
oputput to split and combine via struct iovec

+ update the manual page


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 \
    othersrc/crypto/external/bsd/ssss/dist/include/ssss.h
cvs rdiff -u -r1.2 -r1.3 \
    othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3
cvs rdiff -u -r1.6 -r1.7 \
    othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c

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

Modified files:

Index: othersrc/crypto/external/bsd/ssss/dist/include/ssss.h
diff -u othersrc/crypto/external/bsd/ssss/dist/include/ssss.h:1.2 othersrc/crypto/external/bsd/ssss/dist/include/ssss.h:1.3
--- othersrc/crypto/external/bsd/ssss/dist/include/ssss.h:1.2	Tue Feb 21 05:25:42 2012
+++ othersrc/crypto/external/bsd/ssss/dist/include/ssss.h	Thu Mar  8 02:44:05 2012
@@ -26,6 +26,7 @@
 #define SSSS_H_	20120220
 
 #include <sys/types.h>
+#include <sys/uio.h>
 
 #include <inttypes.h>
 #include <stdio.h>
@@ -45,20 +46,10 @@ __BEGIN_DECLS
 enum {
 	SSSS_MAX_SHARES		= 256,
 
-	SSSS_MAGIC_LENGTH	= 4,
-
 	SSSS_SPLIT_SOURCE	= SSSS_MAX_SHARES,
 	SSSS_JOIN_DEST		= SSSS_MAX_SHARES
 };
 
-/* threshold header written to output file when splitting */
-typedef struct s4_head_t {
-	char		magic[SSSS_MAGIC_LENGTH];	/* magic string */
-	uint8_t		coeff;		/* coefficient of this share */
-	uint8_t		pad[3];		/* padding character */
-	uint64_t	size;		/* size of original file */
-} s4_head_t;
-
 /* io vector - look familiar? */
 typedef struct ssss_iovec_t {
 	size_t		 size;		/* size of vector */
@@ -84,24 +75,23 @@ typedef struct ssss_t {
 } ssss_t;
 
 /* initialisation function */
-int ssss_init(ssss_t *, unsigned, unsigned);
+int ssss_init(ssss_t */*ssss*/, unsigned, unsigned);
 
 /* split functions */
-int ssss_split(ssss_t *);
+int ssss_split(ssss_t */*ssss*/);
+int ssss_split_vec(ssss_t */*ssss*/ssss, const char */*buf*/, size_t /*size*/, struct iovec */*iov*/, int /*iovc*/);
 
 /* reconstruction functions */
-int ssss_combine(ssss_t *);
-
-/* join function */
-int ssss_join(ssss_t *);
+int ssss_combine(ssss_t */*ssss*/);
+int ssss_combine_vec(ssss_t */*ssss*/, struct iovec */*iov*/, int /*iovc*/, char */*buf*/, size_t /*size*/);
 
 /* functions to retrieve a share or the result of a join */
-int ssss_add_share(ssss_t *, unsigned, const void *, ssize_t);
-int ssss_get_share(ssss_t *, unsigned, void **, size_t *);
-int ssss_write_share(ssss_t *, unsigned, const char *);
+int ssss_add_share(ssss_t */*ssss*/, unsigned, const void *, ssize_t);
+int ssss_get_share(ssss_t */*ssss*/, unsigned, void **, size_t *);
+int ssss_write_share(ssss_t */*ssss*/, unsigned, const char *);
 
 /* finalisation function */
-int ssss_end(ssss_t *);
+int ssss_end(ssss_t */*ssss*/);
 
 __END_DECLS
 

Index: othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3
diff -u othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3:1.2 othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3:1.3
--- othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3:1.2	Mon Mar 21 14:44:47 2011
+++ othersrc/crypto/external/bsd/ssss/dist/src/libssss/libssss.3	Thu Mar  8 02:44:06 2012
@@ -1,6 +1,6 @@
-.\" $NetBSD: libssss.3,v 1.2 2011/03/21 14:44:47 wiz Exp $
+.\" $NetBSD: libssss.3,v 1.3 2012/03/08 02:44:06 agc Exp $
 .\"
-.\" Copyright (c) 2010,2011 Alistair Crooks <a...@netbsd.org>
+.\" Copyright (c) 2010-2012 Alistair Crooks <a...@netbsd.org>
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"/
-.Dd April 13, 2010
+.Dd March 7, 2012
 .Dt LIBSSSS 3
 .Os
 .Sh NAME
@@ -37,48 +37,42 @@
 The following functions split the input into shared parts:
 .Ft int
 .Fo ssss_init
-.Fa "threshold_t *thresh" "const char *type" "unsigned threshold" "unsigned nshares"
+.Fa "ssss_t *ssss" "unsigned threshold" "unsigned nshares"
 .Fc
 .Ft int
 .Fo ssss_add_share
-.Fa "threshold_t *thresh" "unsigned shareindex" "void *data" "ssize_t size"
+.Fa "ssss_t *ssss" "unsigned shareindex" "void *data" "ssize_t size"
 .Fc
 .Ft int
 .Fo ssss_split
-.Fa "threshold_t *thresh"
+.Fa "ssss_t *ssss"
 .Fc
 .Ft int
 .Fo ssss_get_share
-.Fa "threshold_t *thresh" "int share" "const char **wanted"
+.Fa "ssss_t *ssss" "int share" "const char **wanted"
 .Fc
 .Ft int
 .Fo ssss_end
-.Fa "threshold_t *thresh"
+.Fa "ssss_t *ssss"
 .Fc
 .Pp
 The following functions are used for secret reconstruction - please note
 that no initialisation function call is necessary when reconstructing:
 .Ft int
 .Fo ssss_add_share
-.Fa "threshold_t *thresh" "unsigned shareindex" "void *data" "ssize_t size"
+.Fa "ssss_t *ssss" "unsigned shareindex" "void *data" "ssize_t size"
 .Fc
 .Ft int
-.Fo ssss_join
-.Fa "threshold_t *thresh"
+.Fo ssss_combine
+.Fa "ssss_t *ssss"
 .Fc
 .Ft int
 .Fo ssss_get_share
-.Fa "threshold_t *thresh" "int share" "const char **wanted"
+.Fa "ssss_t *ssss" "int share" "const char **wanted"
 .Fc
 .Ft int
 .Fo ssss_end
-.Fa "threshold_t *thresh"
-.Fc
-.Pp
-This function attempts to find out the algorithm used to create a shared part:
-.Ft const char *
-.Fo ssss_type
-.Fa "const char *memory"
+.Fa "ssss_t *ssss"
 .Fc
 .Sh DESCRIPTION
 The
@@ -94,12 +88,10 @@ The secret can be recovered by providing
 where the number of parts which constitute the threshold is specified
 at split time.
 .Pp
-The algorithms which can be used as part of
+The
 .Nm
-are
-.Bl -tag -width RAID5
-.It ssss
-use Shamir's Secret Sharing Scheme to share the original
+library
+uses Shamir's Secret Sharing Scheme to share the original
 file in a way that cannot be recovered by others except by using
 a number of shares equalling the threshold
 .El
@@ -163,7 +155,7 @@ For reconstructing the secret from the i
 .Fn ssss_addshare
 is used, followed
 by
-.Fn ssss_join
+.Fn ssss_combine
 and
 .Fn ssss_get_share
 to retrieve the result of the join,
@@ -178,12 +170,13 @@ There is a maximum number of shares of 2
 The
 .Nm
 library first appeared in
-.Nx 6.0 .
+.Nx 7.0 .
 .Sh AUTHORS
 .An Hal Finney
 wrote the original version of
 .Dq secsplit.c
-in 1993, which was placed in the public domain,
+in 1993, which was placed in the public domain.
+It was brought up to date,
 and the rest of this implementation, and the manual
-page were written by
+page, were written by
 .An Alistair Crooks Aq a...@netbsd.org

Index: othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c
diff -u othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.6 othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.7
--- othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c:1.6	Tue Feb 21 05:25:42 2012
+++ othersrc/crypto/external/bsd/ssss/dist/src/libssss/secsplit.c	Thu Mar  8 02:44:06 2012
@@ -137,12 +137,6 @@
 
 #define LARGEST_PRIME 65521
 
-#define S4_KMAX 48
-#define S4_NMAX 48
-
-#define S4_IMAGIC 0x8a31
-#define S4_DMAGIC 0x1347
-
 #define S4_SMALLEST_INPUT	5
 
 #define S4_FILE_MAGIC	"s4"
@@ -150,7 +144,9 @@
 enum {
 	SSSS_MEM_IO		= 0,
 	SSSS_MAPPED_IO		= 1,
-	SSSS_FILE_IO		= 2
+	SSSS_FILE_IO		= 2,
+
+	SSSS_MAGIC_LENGTH	= 4
 };
 
 #ifndef USE_ARG
@@ -161,27 +157,63 @@ enum {
 #define	__arraycount(__x)	(sizeof(__x) / sizeof(__x[0]))
 #endif
 
-#define S4_IO_SPACE(x)		(((x) * 2001) / 2000)
+#if LARGEST_PRIME > 65536
+#define S4_IO_SPACE(x)		(((x) * 3) / 2)
+#else
+#define S4_IO_SPACE(x)		(x)
+#endif
 
-/* Multiplicative inverses of 1-48 mod LARGEST_PRIME */
-static const int invtab[] = {
-	    1, 32761, 43681, 49141, 52417, 54601, 56161, 57331,
-	58241, 58969, 11913, 60061, 60481, 60841, 61153, 61426,
-	42396, 61881,  6897, 62245, 62401, 38717, 11395, 62791,
-	49796, 63001, 41254, 63181, 58743, 63337, 25363, 30713,
-	 3971, 21198, 63649, 63701, 54896, 36209, 63841, 63883,
-	43148, 63961,  6095, 52119, 64065, 38458, 43216, 64156
+/* Multiplicative inverses mod LARGEST_PRIME */
+static const unsigned invtab[] = {
+	    1, 32761, 43681, 49141, 52417, 54601, 56161, 57331,	/*   8 */
+	58241, 58969, 11913, 60061, 60481, 60841, 61153, 61426, /*  16 */
+	42396, 61881,  6897, 62245, 62401, 38717, 11395, 62791, /*  24 */
+	49796, 63001, 41254, 63181, 58743, 63337, 25363, 30713, /*  32 */
+	 3971, 21198, 63649, 63701, 54896, 36209, 63841, 63883, /*  40 */
+	43148, 63961,  6095, 52119, 64065, 38458, 43216, 64156, /*  48 */
+	 8023, 24898, 14132, 64261,  4945, 20627, 28591, 64351, /*  56 */
+	 2299, 62132, 21100, 64429, 27927, 45442, 64481, 48117, /*  64 */
+	64513, 34736, 26404, 10599, 47479, 64585,  5537, 64611, /*  72 */
+	27824, 27448, 38439, 50865, 11062, 64681, 41469, 64702, /*  80 */
+	57432, 21574, 48154, 64741, 60896, 35808, 19581, 58820, /*  88 */
+	50061, 64793, 64801, 19229, 52135, 21608, 40692, 32078, /*  96 */
+	52687, 36772, 23164, 12449, 53844,  7066, 60432, 64891, /* 104 */
+	64897, 35233, 15921, 43074,  5410, 47056, 40139, 64936, /* 112 */
+	 3479, 33910,  2279, 31066, 64961, 10550, 34137, 64975, /* 120 */
+	 1083, 46724, 36223, 22721, 62376, 65001, 53655, 56819, /* 128 */
+	23872, 65017, 53017, 17373, 47786, 13202, 21355, 38060, /* 136 */
+	43043, 56500,  3771, 65053, 58086, 35529, 41237, 65066, /* 144 */
+	37957, 13912, 46355, 13724, 47052, 51980, 40354, 58193, /* 152 */
+	26551,  5531, 31281, 65101,  1252, 53495, 45329, 32351, /* 160 */
+	10988, 28716, 39393, 10787, 53211, 24077, 16086, 65131, /* 168 */
+	44973, 30448, 44447, 17904, 29920, 42551, 25834, 29410, /* 176 */
+	50714, 57791, 18668, 65157,   362, 65161,  9309, 42375, /* 184 */
+	63396, 58828, 27680, 10804, 43334, 20346, 57288, 16039, /* 192 */
+	13240, 59104, 65185, 18386, 54878, 11582, 64204, 38985, /* 200 */
+	52482, 26922, 17752,  3533, 34838, 30216, 59507, 65206, /* 208 */
+	  627, 65209,  5900, 50377, 23686, 40721,  1219, 21537, /* 216 */
+	50424,  2705, 31115, 23528, 53662, 52830, 39959, 32468, /* 224 */
+	12813, 34500, 10391, 16955, 60657, 33900, 47368, 15533, /* 232 */
+	55960, 65241, 61060,  5275, 13823, 49829, 54281, 65248, /* 240 */
+	19031, 33302, 19144, 23362, 27813, 50872, 30771, 44121, /* 248 */
+	59732, 31188,  6526, 65261, 54644, 59588, 42139, 61170  /* 256 */
 };
 
 typedef struct s4_t {
-	unsigned	  extra;	/* extra from last call */
-	unsigned	  magic;	/* magic number */
-	int		  padded;	/* escaped 16-bit entity input */
-	int		  oddsizefile;	/* last return included a pad */
-	int		  peek[S4_KMAX]; /* for two byte lookahead */
-	uint8_t		  sharesc;	/* # of shares */
+	int		oddsizefile;	/* last return included a pad */
+	int		peek[SSSS_MAX_SHARES]; /* for two byte lookahead */
+	unsigned	sharesc;	/* # of shares */
+	unsigned	init[SSSS_MAX_SHARES];	/* initialised header */
 } s4_t;
 
+/* threshold header written to output file when splitting */
+typedef struct s4_head_t {
+	char		magic[SSSS_MAGIC_LENGTH];	/* magic string */
+	uint8_t		coeff;		/* coefficient of this share */
+	uint8_t		pad[3];		/* padding character */
+	uint64_t	size;		/* size of original file */
+} s4_head_t;
+
 /* io stuff */
 #define BSWAP64(x)      ((((x) & 0xffULL) << 56) |			\
                          (((x) & 0xff00ULL) << 40) |			\
@@ -295,58 +327,40 @@ ssss_getch(ssss_str_t *str, uint64_t las
 }
 
 /*
- * Return a 16-bit value from input, but limit it to be less than
- * LARGEST_PRIME.  Anything >= LARGEST_PRIME-1 gets returned as two
- * consecutive values (on 2 calls).  Return -1 on EOF, or -2 if the
- * previous return value had been padded because the file had an odd #
- * bytes.
+ * Return a 16-bit value from input
  */
 static int
-get_limited_16(s4_t *s4, ssss_str_t *str, int *d)
+get_limited_16(s4_t *s4, ssss_str_t *str, unsigned *d)
 {
-	int	c[2];
+	uint8_t	c[2];
+	int	ch;
 
-	/* First check for leftover from last time */
-	if (s4->padded) {
-		s4->padded = 0;
-		*d = s4->extra;
-		return 1;
-	}
 	/* Check if last return included a pad */
 	if (s4->oddsizefile) {
 		return SSSS_ODD_SIZED_FILE;
 	}
 	/* Read data (bigendian), do the magic */
-	if ((c[0] = ssss_getch(str, str->io.size)) == SSSS_EOF) {
+	if ((ch = ssss_getch(str, str->io.size)) == SSSS_EOF) {
 		return SSSS_EOF;
 	}
-	if ((c[1] = ssss_getch(str, str->io.size)) == SSSS_EOF) {
-		c[1] = CRANDOM(0x100);
+	c[0] = (uint8_t)ch;
+	if ((ch = ssss_getch(str, str->io.size)) == SSSS_EOF) {
+		ch = CRANDOM(0x100);
 		s4->oddsizefile = 1;
 	}
-	*d = (((uint8_t)c[0] & 0xff) << 8) + ((uint8_t)c[1] & 0xff);
-	*d ^= s4->magic;
-	s4->magic = (s4->magic + S4_DMAGIC) & 0xffff;
-	/*
-	 * If over the LARGEST_PRIME, return LARGEST_PRIME-1 as a code
-	 * for that, and remember to return the rest next time.
-	 */
-	if (*d >= (LARGEST_PRIME - 1)) {
-		s4->padded = 1;
-		s4->extra = *d - (LARGEST_PRIME - 1);
-		*d = LARGEST_PRIME - 1;
-	}
+	c[1] = (uint8_t)ch;
+	*d = (((uint8_t)c[0] & 0xff) << 8) | ((uint8_t)c[1] & 0xff);
 	return 1;
 }
 
 /*
- * Given a 16-bit value d, less than LARGEST_PRIME, split it into
- * sharesc files such that any k of them can reconstruct it.
+ * Given a 24-bit value d, split it into sharesc files such that any k
+ * of them can reconstruct it.
  */
 static void
 split_out(uint32_t d, unsigned sharesc, unsigned k, ssss_str_t *shares)
 {
-	uint32_t	poly[S4_KMAX];
+	uint32_t	poly[SSSS_MAX_SHARES];
 	uint32_t	di;
 	unsigned	i;
 	unsigned	j;
@@ -357,6 +371,10 @@ split_out(uint32_t d, unsigned sharesc, 
 	}
 	for (i = 0; i < sharesc; i++) {
 		di = eval(poly, k, i + 1);
+		if (/*CONSTCOND*/LARGEST_PRIME > 65536) {
+			di |= ((CRANDOM(0x100) & 0xfe) << 16);
+			shares[i].io.base[shares[i].c++] = (di >> 16) & 0xff;
+		}
 		shares[i].io.base[shares[i].c++] = (di >> 8) & 0xff;
 		shares[i].io.base[shares[i].c++] = (di & 0xff);
 	}
@@ -364,39 +382,32 @@ split_out(uint32_t d, unsigned sharesc, 
 
 /*
  * Split the specified input file into sharesc output files, such that
- * any k of them are sufficient to reconstruct the input.  mod is the
- * largest prime < 2^16.  This is the main routine for the splitting case.
+ * any k of them are sufficient to reconstruct the input.  This is the
+ * main routine for the splitting case.
  *
- * f_in = Input file handle
- * f_out[] = Output file handles
- * sharesc = Number of output files
- * k = Threshhold for re-assembl
+ * k = Threshhold for re-assembly
  */
 static void
-split(s4_t *s4, ssss_str_t *str, unsigned sharesc, unsigned k, ssss_str_t *shares)
+split(s4_t *s4, ssss_str_t *str, unsigned sharesc, unsigned k, ssss_str_t *shares, unsigned doheader)
 {
 	s4_head_t	head;
 	unsigned	i;
-	int		d;
-	int		ret;
+	unsigned	d;
 
-	fmt_header(&head, S4_FILE_MAGIC, str->io.size);
+	if (doheader) {
+		fmt_header(&head, S4_FILE_MAGIC, str->io.size);
+	}
 	for (i = 0; i < sharesc; i++) {
 		/* Prefix each file with "x" coordinate, 1 byte */
 		head.coeff = i + 1;
-		/* add header */
-		(void) memcpy(&shares[i].io.base[shares[i].c], &head, sizeof(head));
-		shares[i].c = sizeof(head);
-	}
-	while ((ret = get_limited_16(s4, str, &d)) != SSSS_EOF) {
-		if (ret == SSSS_ODD_SIZED_FILE) {
-			/* Odd flag - pad output files with a random byte to remember */
-			for (i = 0; i < sharesc; i++) {
-				shares[i].io.base[shares[i].c++] = CRANDOM(0x100);
-			}
-			break;
+		if (doheader) {
+			/* add header */
+			(void) memcpy(&shares[i].io.base[shares[i].c], &head, sizeof(head));
+			shares[i].c = sizeof(head);
 		}
-		split_out((unsigned)d, sharesc, k, shares);
+	}
+	while (get_limited_16(s4, str, &d) != SSSS_EOF) {
+		split_out(d, sharesc, k, shares);
 	}
 }
 
@@ -443,7 +454,7 @@ inverse(int x)
 static uint32_t 
 interpolate(int *x, uint32_t *y, unsigned n)
 {
-	uint32_t	alpha[S4_KMAX];
+	uint32_t	alpha[SSSS_MAX_SHARES];
 	uint32_t	product;
 	unsigned	i;
 	unsigned	j;
@@ -476,29 +487,35 @@ interpolate(int *x, uint32_t *y, unsigne
  * two bytes ahead to know this.
  */
 static int 
-get_assemble_16(s4_t *s4, ssss_str_t *inputs, unsigned i)
+get_assemble_16(s4_t *s4, ssss_str_t *inputs, unsigned coeff)
 {
-	int	ch;
-	int	c[2];
+	unsigned	j;
+	int		charsize;
+	int		ret;
+	int		ch;
 
-	if (inputs[i].c == sizeof(s4_head_t)) {
-		/* Get ahead the first time */
-		c[0] = ssss_getch(&inputs[i], inputs[i].io.size + 2);
-		c[1] = ssss_getch(&inputs[i], inputs[i].io.size + 2);
-		s4->peek[i] = ((c[0] & 0xff) << 8) + (c[1] & 0xff);
-	}
-	ch = s4->peek[i];
-	if ((c[0] = ssss_getch(&inputs[i], inputs[i].io.size + 2)) == SSSS_EOF) {
-		s4->peek[i] = SSSS_EOF;
-	} else {
-		if ((c[1] = ssss_getch(&inputs[i], inputs[i].io.size + 2)) == SSSS_EOF) {
-			s4->oddsizefile = 1;
-			s4->peek[i] = SSSS_EOF;
-		} else {
-			s4->peek[i] = ((c[0] & 0xff) << 8) + (c[1] & 0xff);
+	charsize = (/*CONSTCOND*/ LARGEST_PRIME > 65536) ? 3 : 2;
+	if (!s4->init[coeff]) {
+		s4->init[coeff] = 1;
+		s4->peek[coeff] = 0;
+		for (j = 0 ; j < (unsigned)charsize ; j++) {
+			ch = ssss_getch(&inputs[coeff], inputs[coeff].io.size + charsize);
+			s4->peek[coeff] = (s4->peek[coeff] << 8) | (ch & 0xff);
+		}
+	}
+	ret = s4->peek[coeff];
+	s4->peek[coeff] = 0;
+	for (j = 0 ; j < (unsigned)charsize ; j++) {
+		if ((ch = ssss_getch(&inputs[coeff], inputs[coeff].io.size + charsize)) == SSSS_EOF) {
+			s4->peek[coeff] = SSSS_EOF;
+			if (j > 0) {
+				s4->oddsizefile = 1;
+			}
+			break;
 		}
+		s4->peek[coeff] = (s4->peek[coeff] << 8) | ((unsigned)ch & 0xff);
 	}
-	return ch;
+	return ret;
 }
 
 /*
@@ -507,17 +524,17 @@ get_assemble_16(s4_t *s4, ssss_str_t *in
  * only the high 8 bits of this interpolated value are valid.
  */
 static int
-get_assemble(s4_t *s4, unsigned nin, ssss_str_t *inputs, int *x, int *ret)
+get_assemble(s4_t *s4, unsigned nin, ssss_str_t *inputs, int *coeffs, unsigned *ret)
 {
 	unsigned	i;
-	int		y[S4_KMAX];
+	int		y[SSSS_MAX_SHARES];
 
 	for (i = 0; i < nin; i++) {
 		if ((y[i] = get_assemble_16(s4, inputs, i)) == SSSS_EOF) {
 			return 0;
 		}
 	}
-	*ret = interpolate(x, (unsigned *)y, nin);
+	*ret = interpolate(coeffs, (unsigned *)y, nin);
 	return 1;
 }
 
@@ -526,32 +543,28 @@ get_assemble(s4_t *s4, unsigned nin, sss
  * original file.  This is the main routine for the assembly case.
  */
 static int
-assemble(s4_t *s4, ssss_str_t *inputs, unsigned nin, ssss_str_t *output)
+assemble(s4_t *s4, ssss_str_t *inputs, unsigned nin, ssss_str_t *output, unsigned doheader)
 {
 	s4_head_t	heads[SSSS_MAX_SHARES];
-	uint32_t	magic;
+	unsigned	ch;
 	unsigned	i;
-	int		x[S4_KMAX];
-	int		ch;
+	int		coeffs[SSSS_MAX_SHARES];
 
-	magic = S4_IMAGIC;
 	for (i = 0; i < nin; i++) {
-		get_header(&heads[i], inputs[i].io.base);
-		if (!sane_header(&heads[i], &heads[0])) {
-			warn("insane ssss header %u", i);
-			return 0;
+		if (doheader) {
+			get_header(&heads[i], inputs[i].io.base);
+			if (!sane_header(&heads[i], &heads[0])) {
+				warn("insane ssss header %u", i);
+				return 0;
+			}
+			inputs[i].c += sizeof(heads[i]);
+			coeffs[i] = heads[i].coeff;
+		} else {
+			coeffs[i] = i;
 		}
-		inputs[i].c += sizeof(heads[i]);
-		x[i] = heads[i].coeff;
 	}
-	while (get_assemble(s4, nin, inputs, x, &ch)) {
-		if (ch == (int)(LARGEST_PRIME - 1)) {
-			(void) get_assemble(s4, nin, inputs, x, &ch);
-			ch += LARGEST_PRIME - 1;
-		}
-		ch ^= magic;
-		magic = (magic + S4_DMAGIC) & 0xffff;
-		output->io.base[output->c++] = ((unsigned)ch >> 8) & 0xff;
+	while (get_assemble(s4, nin, inputs, coeffs, &ch)) {
+		output->io.base[output->c++] = (ch >> 8) & 0xff;
 		if (s4->oddsizefile) {
 			break;
 		}
@@ -564,11 +577,11 @@ assemble(s4_t *s4, ssss_str_t *inputs, u
 static int
 check_values(unsigned threshold, unsigned sharesc)
 {
-	if (sharesc <= 1 || sharesc > S4_NMAX) {
+	if (sharesc <= 1 || sharesc > SSSS_MAX_SHARES) {
 		warn("Invalid number of shares (%u).", sharesc);
 		return 0;
 	}
-	if (threshold < 1 || threshold > S4_NMAX) {
+	if (threshold < 1 || threshold > SSSS_MAX_SHARES) {
 		warn("Invalid threshold number %u", threshold);
 		return 0;
 	}
@@ -581,7 +594,7 @@ check_values(unsigned threshold, unsigne
 
 /* split the secret file into shares */
 static int 
-split_memory(ssss_t *ssss, const void *secret, size_t memsize, unsigned threshold, unsigned sharesc)
+split_memory(ssss_t *ssss, const void *secret, size_t memsize, unsigned threshold, unsigned sharesc, unsigned doheader)
 {
 	ssss_str_t	mem;
 	unsigned	i;
@@ -603,7 +616,7 @@ split_memory(ssss_t *ssss, const void *s
 	/* allocate space for outputs */
 	ssss->sharesc = (unsigned)sharesc;
 	for (i = 0 ; i < sharesc ; i++) {
-		/* need space to grow for padded chars */
+		/* possibly need space to grow for padded chars */
 		ssss->shares[i].io.size = S4_IO_SPACE(memsize + sizeof(s4_head_t) + 2);
 		ssss->shares[i].c = 0;
 		if (ssss->shares[i].io.base == NULL &&
@@ -613,13 +626,13 @@ split_memory(ssss_t *ssss, const void *s
 		}
 	}
 	/* Do the work */
-	split(s4, &mem, sharesc, threshold, ssss->shares);
+	split(s4, &mem, sharesc, threshold, ssss->shares, doheader);
 	return 1;
 }
 
 /* reconstruct the shares from memory */
 static int 
-join_memory(ssss_t *ssss, ssss_str_t *input, size_t bytes, unsigned filec, ssss_str_t *str)
+join_memory(ssss_t *ssss, ssss_str_t *input, size_t bytes, unsigned filec, ssss_str_t *str, unsigned doheader)
 {
 	s4_t	*s4;
 
@@ -631,7 +644,7 @@ join_memory(ssss_t *ssss, ssss_str_t *in
 		return 0;
 	}
 	/* Do the work */
-	return assemble(s4, input, filec, str);
+	return assemble(s4, input, filec, str, doheader);
 }
 
 /**************************************************************************/
@@ -650,8 +663,7 @@ ssss_init(ssss_t *ssss, unsigned thresho
 		warn("Unable to allocate ssss structure");
 		return 0;
 	}
-	s4->magic = S4_IMAGIC;
-	s4->sharesc = S4_KMAX; /* guess for just now */
+	s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
 	ssss->handle = s4;
 	return 1;
 }
@@ -710,7 +722,22 @@ ssss_split(ssss_t *ssss)
 	ssss_str_t	*mem;
 
 	mem = &ssss->shares[SSSS_MAX_SHARES];
-	return split_memory(ssss, mem->io.base, mem->io.size, ssss->threshold, ssss->sharesc);
+	return split_memory(ssss, mem->io.base, mem->io.size, ssss->threshold, ssss->sharesc, 1);
+}
+
+/* split vector via iovec interface */
+int
+ssss_split_vec(ssss_t *ssss, const char *buf, size_t size, struct iovec *iov, int iovc)
+{
+	int	ret;
+	int	i;
+
+	ssss_add_share(ssss, (unsigned)SSSS_SPLIT_SOURCE, buf, (long)size);
+	ret = split_memory(ssss, buf, size, ssss->threshold, ssss->sharesc, 0);
+	for (i = 0 ; ret && i < iovc ; i++) {
+		ssss_get_share(ssss, (unsigned)i, &iov[i].iov_base, &iov[i].iov_len);
+	}
+	return ret;
 }
 
 /* combine/join/decode into one */
@@ -728,17 +755,44 @@ ssss_combine(ssss_t *ssss)
 		warn("Unable to allocate ssss structure");
 		return 0;
 	}
-	s4->magic = S4_IMAGIC;
-	s4->sharesc = S4_KMAX; /* guess for just now */
+	s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
 	ssss->handle = s4;
 	if (!join_memory(ssss, ssss->shares, 
 			ssss->shares[0].io.size - 2, ssss->availc,
-			&ssss->shares[SSSS_JOIN_DEST])) {
+			&ssss->shares[SSSS_JOIN_DEST], 1)) {
 		return -1;
 	}
 	return (int)ssss->shares[SSSS_MAX_SHARES].c;
 }
 
+/* combine a split vector via iovec interface */
+int
+ssss_combine_vec(ssss_t *ssss, struct iovec *iov, int iovc, char *buf, size_t size)
+{
+	s4_t	*s4;
+	void	*vp;
+	int	 i;
+
+	for (i = 0 ; i < iovc ; i++) {
+		ssss_add_share(ssss, (unsigned)i, iov[i].iov_base, (long)iov[i].iov_len);
+	}
+	if ((s4 = calloc(1, sizeof(*s4))) == NULL) {
+		warn("Unable to allocate ssss structure");
+		return 0;
+	}
+	s4->sharesc = SSSS_MAX_SHARES; /* guess for just now */
+	ssss->handle = s4;
+	if (!join_memory(ssss, ssss->shares, 
+			ssss->shares[0].io.size - 2, ssss->availc,
+			&ssss->shares[SSSS_JOIN_DEST], 0)) {
+		return -1;
+	}
+	vp = buf;
+	ssss_get_share(ssss, SSSS_JOIN_DEST, &vp, &size);
+	free(s4);
+	return (int)ssss->shares[SSSS_MAX_SHARES].c;
+}
+
 /* write a share to a file */
 int
 ssss_write_share(ssss_t *ssss, unsigned n, const char *f)

Reply via email to