From: Michael Shigorin <mike@altlinux.org> To: make-initrd@lists.altlinux.org Subject: [make-initrd] q: фича для зарыбливания RNG Date: Mon, 5 Jul 2021 14:11:30 +0300 Message-ID: <20210705111130.GX2168@imap.altlinux.org> (raw) [-- Attachment #1: Type: text/plain, Size: 1673 bytes --] Здравствуйте. Коллеги, в связи с очередной невменяемостью апстрима systemd (по совместительству udevd), в v240 выразившейся в повышении требований к качеству псевдослучайных чисел на ранней стадии загрузки[1,2], и возникающих вследствие этого залипаний этой самой ранней стадии загрузки в ожидании каких-либо событий -- бывает достаточно нажать Shift или вставить USB-флэшку -- предлагаю реализовать фичу, которая бы обеспечивала начальную инициализацию ядерного RNG с опорой на то, что при старте может "дребезжать" (особенно при наличии хоть какого-то RTC). У нас тут образовался хак на скору руку, но он прямо по rc.sysinit и заведомо неоптимален, вследствие чего далее был предложен такой вид кусочка на шелле: --- { # Initialize bash random seed using current time nanoseconds # to avoid possible kernel pool usage RANDOM=$((10#$(date "+%N") % 32768)) seed=$( { dmesg; ls -l /var/log /proc; } | md5_bin | od -h ) for ((i=0; i<64; i++)); do echo $seed $RANDOM $(date "+%s%N") | md5_bin done > /dev/random unset i seed } & --- или даже такой (но это ещё 128 форков): --- { export \ RANDOM=$((10#$(date "+%N") % 32768)) \ seed=$( { dmesg; ls -l /var/log /proc; } | md5_bin | od -h ) for ((i=0; i<64; i++)); do ( echo $seed $RANDOM $(date "+%s%N"); ls -l /proc ) | md5_bin done > /dev/random unset i seed } & --- Прилагаю хак и md5_bin.c, прошу совета: * стоит ли так делать; * как лучше собирать md5_bin имени ilyakurdyukov@; * куда лучше поместить скрипт. [1] http://systemd.io/RANDOM_SEEDS [2] http://github.com/systemd/systemd/blob/v240/NEWS#L200 -- ---- WBR, Michael Shigorin / http://altlinux.org ------ http://opennet.ru / http://anna-news.info [-- Attachment #2: 0001-Avoid-randomness-related-udev-induced-boot-stalls.patch --] [-- Type: text/x-patch, Size: 1472 bytes --] >From 18fbcd9bde20a2b6baf37a7f1bf732dd39bcf3ee Mon Sep 17 00:00:00 2001 From: Michael Shigorin <mike@altlinux.org> Date: Sun, 8 Nov 2020 19:32:53 +0300 Subject: [PATCH] Avoid randomness-related udev-induced boot stalls Those responsible for breaking udevd even further don't answer the question: why break what used to work before "improvements"? There are many architectures out there, and even those on x86 aren't really doomed to just trust Intel's hwrng. No reason to toss haveged here as we need a "show starter" here, not a service. So fill the 1024 byte long kernel enthropy pool (512*2 bytes, $RANDOM is 0..2^16-1) with good enough "seed" while getrandom() with GRND_INSECURE flag is not widely available yet (Linux 5.6+). Implemented-by: Andrey Savchenko <bircoph@altlinux.org> See-also: http://systemd.io/RANDOM_SEEDS --- data/etc/rc.d/rc.sysinit | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/data/etc/rc.d/rc.sysinit b/data/etc/rc.d/rc.sysinit index e95a6fd..30726b8 100755 --- a/data/etc/rc.d/rc.sysinit +++ b/data/etc/rc.d/rc.sysinit @@ -31,3 +31,14 @@ if shell_var_is_no "$quiet"; then echo "INITRAMFS: version $VERSION_ID" } fi + +{ +# Initialize bash random seed using current time nanoseconds +# to avoid possible kernel pool usage +RANDOM=$((10#$(date "+%N") % 32768)) +for ((i=0; i<512; i++)); do + n=$RANDOM + printf "\x$(printf "%x" $((n>>8)))\x$(printf "%x" $((n%256)))" +done > /dev/random +unset i n +} & -- 2.25.4 [-- Attachment #3: md5_bin.c --] [-- Type: text/plain, Size: 5350 bytes --] #include <stdint.h> #include <stdio.h> #include <string.h> typedef uint32_t u32; typedef uint64_t u64; #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) #define MD5STEP(f, w, x, y, z, in, s) \ (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) static void md5_transform(u32 *hash, u32 const *in) { u32 a, b, c, d; a = hash[0]; b = hash[1]; c = hash[2]; d = hash[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); hash[0] += a; hash[1] += b; hash[2] += c; hash[3] += d; } #undef MD5STEP #undef F4 #undef F3 #undef F2 #undef F1 struct md5_ctx { u32 hash[4], block[16]; u64 byte_count; }; static void md5_init(struct md5_ctx *ctx) { ctx->hash[0] = 0x67452301; ctx->hash[1] = 0xefcdab89; ctx->hash[2] = 0x98badcfe; ctx->hash[3] = 0x10325476; ctx->byte_count = 0; } static void md5_update(struct md5_ctx *ctx, const char *data, unsigned int len) { const u32 avail = 64 - (ctx->byte_count & 0x3f); ctx->byte_count += len; if (avail > len) { memcpy((char*)ctx->block + (64 - avail), data, len); return; } memcpy((char*)ctx->block + (64 - avail), data, avail); md5_transform(ctx->hash, ctx->block); data += avail; len -= avail; while (len >= 64) { memcpy(ctx->block, data, 64); md5_transform(ctx->hash, ctx->block); data += 64; len -= 64; } memcpy(ctx->block, data, len); } static void md5_final(struct md5_ctx *ctx, unsigned char *out) { const unsigned int offset = ctx->byte_count & 0x3f; char *p = (char*)ctx->block + offset; int padding = 56 - (offset + 1); *p++ = 0x80; if (padding < 0) { memset(p, 0, padding + 8); md5_transform(ctx->hash, ctx->block); p = (char*)ctx->block; padding = 56; } memset(p, 0, padding); ctx->block[14] = ctx->byte_count << 3; ctx->block[15] = ctx->byte_count >> 29; md5_transform(ctx->hash, ctx->block); memcpy(out, ctx->hash, 16); memset(ctx, 0, sizeof(struct md5_ctx)); } int main() { int a; struct md5_ctx md5; unsigned char hash[16]; md5_init(&md5); while ((a = getchar()) != EOF) { char c = a; md5_update(&md5, &c, 1); } md5_final(&md5, hash); return fwrite(hash, sizeof(hash), 1, stdout) != 1; }
next reply other threads:[~2021-07-05 11:11 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-05 11:11 Michael Shigorin [this message] 2021-07-05 11:45 ` Alexey Gladkov 2021-07-05 15:49 ` Michael Shigorin 2021-07-05 16:21 ` Alexey Gladkov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210705111130.GX2168@imap.altlinux.org \ --to=mike@altlinux.org \ --cc=make-initrd@lists.altlinux.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Make-initrd development discussion This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/make-initrd/0 make-initrd/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 make-initrd make-initrd/ http://lore.altlinux.org/make-initrd \ make-initrd@lists.altlinux.org make-initrd@lists.altlinux.ru make-initrd@lists.altlinux.com public-inbox-index make-initrd Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.make-initrd AGPL code for this site: git clone https://public-inbox.org/public-inbox.git