Tue May 4 21:13:38 2021 UTC ()
prekern: add warnings upon problems collecting entropy

As submitted on port-amd64@ (part 3/3)

Tested on NetBSD/amd64.


(khorben)
diff -r1.4 -r1.5 src/sys/arch/amd64/stand/prekern/prng.c

cvs diff -r1.4 -r1.5 src/sys/arch/amd64/stand/prekern/prng.c (expand / switch to unified diff)

--- src/sys/arch/amd64/stand/prekern/prng.c 2021/05/04 21:10:25 1.4
+++ src/sys/arch/amd64/stand/prekern/prng.c 2021/05/04 21:13:38 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: prng.c,v 1.4 2021/05/04 21:10:25 khorben Exp $ */ 1/* $NetBSD: prng.c,v 1.5 2021/05/04 21:13:38 khorben Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2017-2020 The NetBSD Foundation, Inc. All rights reserved. 4 * Copyright (c) 2017-2020 The NetBSD Foundation, Inc. All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Maxime Villard. 7 * by Maxime Villard.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -74,26 +74,27 @@ prng_lookup_bootinfo(int type) @@ -74,26 +74,27 @@ prng_lookup_bootinfo(int type)
74 ((uint8_t *)bic + bic->len); 74 ((uint8_t *)bic + bic->len);
75 } 75 }
76 return found ? bic : NULL; 76 return found ? bic : NULL;
77} 77}
78 78
79static void 79static void
80prng_get_entropy_file(SHA512_CTX *ctx) 80prng_get_entropy_file(SHA512_CTX *ctx)
81{ 81{
82 struct bi_modulelist_entry *bi, *bimax; 82 struct bi_modulelist_entry *bi, *bimax;
83 struct btinfo_modulelist *biml; 83 struct btinfo_modulelist *biml;
84 uint8_t digest[SHA1_DIGEST_LENGTH]; 84 uint8_t digest[SHA1_DIGEST_LENGTH];
85 rndsave_t *rndsave; 85 rndsave_t *rndsave;
86 SHA1_CTX sig; 86 SHA1_CTX sig;
 87 size_t count = 0;
87 88
88 biml = 89 biml =
89 (struct btinfo_modulelist *)prng_lookup_bootinfo(BTINFO_MODULELIST); 90 (struct btinfo_modulelist *)prng_lookup_bootinfo(BTINFO_MODULELIST);
90 if (biml == NULL) { 91 if (biml == NULL) {
91 return; 92 return;
92 } 93 }
93 94
94 bi = (struct bi_modulelist_entry *)((uint8_t *)biml + sizeof(*biml)); 95 bi = (struct bi_modulelist_entry *)((uint8_t *)biml + sizeof(*biml));
95 bimax = bi + biml->num; 96 bimax = bi + biml->num;
96 for (; bi < bimax; bi++) { 97 for (; bi < bimax; bi++) {
97 if (bi->type != BI_MODULE_RND) { 98 if (bi->type != BI_MODULE_RND) {
98 continue; 99 continue;
99 } 100 }
@@ -107,27 +108,30 @@ prng_get_entropy_file(SHA512_CTX *ctx) @@ -107,27 +108,30 @@ prng_get_entropy_file(SHA512_CTX *ctx)
107 /* check the signature */ 108 /* check the signature */
108 SHA1Init(&sig); 109 SHA1Init(&sig);
109 SHA1Update(&sig, (uint8_t *)&rndsave->entropy, 110 SHA1Update(&sig, (uint8_t *)&rndsave->entropy,
110 sizeof(rndsave->entropy)); 111 sizeof(rndsave->entropy));
111 SHA1Update(&sig, rndsave->data, sizeof(rndsave->data)); 112 SHA1Update(&sig, rndsave->data, sizeof(rndsave->data));
112 SHA1Final(digest, &sig); 113 SHA1Final(digest, &sig);
113 if (memcmp(digest, rndsave->digest, sizeof(digest))) { 114 if (memcmp(digest, rndsave->digest, sizeof(digest))) {
114 print_state(STATE_WARNING, 115 print_state(STATE_WARNING,
115 "bad SHA1 checksum in entropy file"); 116 "bad SHA1 checksum in entropy file");
116 continue; 117 continue;
117 } 118 }
118 119
119 SHA512_Update(ctx, rndsave->data, sizeof(rndsave->data)); 120 SHA512_Update(ctx, rndsave->data, sizeof(rndsave->data));
 121 count++;
120 } 122 }
 123 if (count == 0)
 124 print_state(STATE_WARNING, "No entropy file could be loaded");
121} 125}
122 126
123/* 127/*
124 * Add 32 bytes of rdseed/rdrand and 8 bytes of rdtsc to the context. 128 * Add 32 bytes of rdseed/rdrand and 8 bytes of rdtsc to the context.
125 */ 129 */
126static void 130static void
127prng_get_entropy_data(SHA512_CTX *ctx) 131prng_get_entropy_data(SHA512_CTX *ctx)
128{ 132{
129 uint64_t buf[8], val; 133 uint64_t buf[8], val;
130 size_t i; 134 size_t i;
131 135
132 if (has_rdseed) { 136 if (has_rdseed) {
133 for (i = 0; i < 8; i++) { 137 for (i = 0; i < 8; i++) {
@@ -158,26 +162,28 @@ prng_init(void) @@ -158,26 +162,28 @@ prng_init(void)
158 u_int descs[4]; 162 u_int descs[4];
159 163
160 memset(&rng, 0, sizeof(rng)); 164 memset(&rng, 0, sizeof(rng));
161 165
162 /* detect cpu features */ 166 /* detect cpu features */
163 if (cpuid_level >= 0x07) { 167 if (cpuid_level >= 0x07) {
164 cpuid(0x07, 0x00, descs); 168 cpuid(0x07, 0x00, descs);
165 has_rdseed = (descs[1] & CPUID_SEF_RDSEED) != 0; 169 has_rdseed = (descs[1] & CPUID_SEF_RDSEED) != 0;
166 } 170 }
167 if (cpuid_level >= 0x01) { 171 if (cpuid_level >= 0x01) {
168 cpuid(0x01, 0x00, descs); 172 cpuid(0x01, 0x00, descs);
169 has_rdrand = (descs[2] & CPUID2_RDRAND) != 0; 173 has_rdrand = (descs[2] & CPUID2_RDRAND) != 0;
170 } 174 }
 175 if (!has_rdseed && !has_rdrand)
 176 print_state(STATE_WARNING, "No CPU entropy feature detected");
171 177
172 SHA512_Init(&ctx); 178 SHA512_Init(&ctx);
173 prng_get_entropy_file(&ctx); 179 prng_get_entropy_file(&ctx);
174 prng_get_entropy_data(&ctx); 180 prng_get_entropy_data(&ctx);
175 SHA512_Final(digest, &ctx); 181 SHA512_Final(digest, &ctx);
176 182
177 memcpy(rng.state, digest, RNGSTATE_SIZE); 183 memcpy(rng.state, digest, RNGSTATE_SIZE);
178 memcpy(rng.data, digest + RNGSTATE_SIZE, RNGDATA_SIZE); 184 memcpy(rng.data, digest + RNGSTATE_SIZE, RNGDATA_SIZE);
179} 185}
180 186
181static void 187static void
182prng_round(void) 188prng_round(void)
183{ 189{