| @@ -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 | |
79 | static void | | 79 | static void |
80 | prng_get_entropy_file(SHA512_CTX *ctx) | | 80 | prng_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 | */ |
126 | static void | | 130 | static void |
127 | prng_get_entropy_data(SHA512_CTX *ctx) | | 131 | prng_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 | |
181 | static void | | 187 | static void |
182 | prng_round(void) | | 188 | prng_round(void) |
183 | { | | 189 | { |