b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From db9165814823401d57383a8f9e82642129cf4223 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sungbo Eo <mans0n@gorani.run> |
| 3 | Date: Sat, 12 Feb 2022 16:42:14 +0900 |
| 4 | Subject: [PATCH] make encrypted archives reproducible |
| 5 | |
| 6 | Zip always try to generate new encryption header depending on execution |
| 7 | time and process id, which is far from being reproducible. This commit |
| 8 | changes the zip srand() seed to a predictable value to generate |
| 9 | reproducible random bytes for the encryption header. This will compromise |
| 10 | the goal of secure archive encryption, but it would not be a big problem |
| 11 | for our purpose. |
| 12 | |
| 13 | Signed-off-by: Sungbo Eo <mans0n@gorani.run> |
| 14 | --- |
| 15 | crypt.c | 8 ++++++-- |
| 16 | globals.c | 1 + |
| 17 | zip.h | 1 + |
| 18 | zipup.c | 2 +- |
| 19 | 4 files changed, 9 insertions(+), 3 deletions(-) |
| 20 | |
| 21 | --- a/crypt.c |
| 22 | +++ b/crypt.c |
| 23 | @@ -29,7 +29,6 @@ |
| 24 | version without encryption capabilities). |
| 25 | */ |
| 26 | |
| 27 | -#define ZCRYPT_INTERNAL |
| 28 | #include "zip.h" |
| 29 | #include "crypt.h" |
| 30 | #include "ttyio.h" |
| 31 | @@ -219,7 +218,12 @@ void crypthead(passwd, crc) |
| 32 | * often poorly implemented. |
| 33 | */ |
| 34 | if (++calls == 1) { |
| 35 | - srand((unsigned)time(NULL) ^ ZCR_SEED2); |
| 36 | + unsigned zcr_seed1 = (unsigned)time(NULL); |
| 37 | +#ifndef ZCRYPT_INTERNAL |
| 38 | + if (epoch > 0) |
| 39 | + zcr_seed1 = (unsigned)epoch; |
| 40 | +#endif |
| 41 | + srand(zcr_seed1 ^ ZCR_SEED2); |
| 42 | } |
| 43 | init_keys(passwd); |
| 44 | for (n = 0; n < RAND_HEAD_LEN-2; n++) { |
| 45 | --- a/globals.c |
| 46 | +++ b/globals.c |
| 47 | @@ -206,6 +206,7 @@ int read_split_archive = 0; /* 1=s |
| 48 | int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */ |
| 49 | uzoff_t split_size = 0; /* how big each split should be */ |
| 50 | int split_bell = 0; /* when pause for next split ring bell */ |
| 51 | +time_t epoch = 0; /* timestamp from SOURCE_DATE_EPOCH */ |
| 52 | uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */ |
| 53 | uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */ |
| 54 | int noisy_splits = 0; /* note when splits are being created */ |
| 55 | --- a/zip.h |
| 56 | +++ b/zip.h |
| 57 | @@ -502,6 +502,7 @@ extern uzoff_t bytes_this_split; /* byte |
| 58 | extern int read_split_archive; /* 1=scanzipf_reg detected spanning signature */ |
| 59 | extern int split_method; /* 0=no splits, 1=seekable, 2=data descs, -1=no */ |
| 60 | extern uzoff_t split_size; /* how big each split should be */ |
| 61 | +extern time_t epoch; /* timestamp from SOURCE_DATE_EPOCH */ |
| 62 | extern int split_bell; /* when pause for next split ring bell */ |
| 63 | extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */ |
| 64 | extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */ |
| 65 | --- a/zipup.c |
| 66 | +++ b/zipup.c |
| 67 | @@ -676,7 +676,7 @@ struct zlist far *z; /* zip entry to |
| 68 | } /* strcmp(z->name, "-") == 0 */ |
| 69 | |
| 70 | if (extra_fields == 0 && (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) != NULL) { |
| 71 | - time_t epoch = strtoull(source_date_epoch, NULL, 10); |
| 72 | + epoch = strtoull(source_date_epoch, NULL, 10); |
| 73 | if (epoch > 0) { |
| 74 | ulg epochtim = unix2dostime(&epoch); |
| 75 | if (z->tim > epochtim) z->tim = epochtim; |