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)