Skip to content

Commit 347aa22

Browse files
glaserfvogelpi
authored andcommitted
[csrng/sw] Add NIST generate KAT with additional_data
This commit extends the Know-Answer-Test for the CSRNG with a NIST test vector that contains additional_data for the generate command. Signed-off-by: Florian Glaser <[email protected]>
1 parent 8727953 commit 347aa22

File tree

11 files changed

+205
-28
lines changed

11 files changed

+205
-28
lines changed

sw/device/lib/dif/dif_csrng.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ dif_result_t dif_csrng_update(const dif_csrng_t *csrng,
9898
});
9999
}
100100

101-
dif_result_t dif_csrng_generate_start(const dif_csrng_t *csrng, size_t len) {
101+
dif_result_t dif_csrng_generate_start(
102+
const dif_csrng_t *csrng, const dif_csrng_seed_material_t *additional_data,
103+
size_t len) {
102104
if (csrng == NULL || len == 0) {
103105
return kDifBadArg;
104106
}
@@ -109,6 +111,7 @@ dif_result_t dif_csrng_generate_start(const dif_csrng_t *csrng, size_t len) {
109111
return csrng_send_app_cmd(csrng->base_addr, kCsrngAppCmdTypeCsrng,
110112
(csrng_app_cmd_t){
111113
.id = kCsrngAppCmdGenerate,
114+
.seed_material = additional_data,
112115
.generate_len = num_128bit_blocks,
113116
});
114117
}

sw/device/lib/dif/dif_csrng.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,16 @@ dif_result_t dif_csrng_update(const dif_csrng_t *csrng,
431431
* of the request to align it to the nearest 128-bit boundary.
432432
*
433433
* @param csrng A CSRNG handle.
434+
* @param additional_data Additional data for the generate command. Set to NULL
435+
* if unused.
434436
* @param len Number of uint32_t words to generate.
435437
* @return The result of the operation. KDifOutOfRange if the `len` parameter
436438
* results in a 128bit block level size greater than 0x800.
437439
*/
438440
OT_WARN_UNUSED_RESULT
439-
dif_result_t dif_csrng_generate_start(const dif_csrng_t *csrng, size_t len);
441+
dif_result_t dif_csrng_generate_start(
442+
const dif_csrng_t *csrng, const dif_csrng_seed_material_t *additional_data,
443+
size_t len);
440444

441445
/**
442446
* Reads the output of the last CSRNG generate call.

sw/device/lib/dif/dif_csrng_unittest.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,19 +294,19 @@ TEST_F(CommandTest, GenerateOk) {
294294
{{CSRNG_SW_CMD_STS_CMD_RDY_BIT, true}});
295295
EXPECT_WRITE32(CSRNG_CMD_REQ_REG_OFFSET,
296296
0x00004003 | kMultiBitBool4False << 8);
297-
EXPECT_DIF_OK(dif_csrng_generate_start(&csrng_, /*len=*/16));
297+
EXPECT_DIF_OK(dif_csrng_generate_start(&csrng_, nullptr, /*len=*/16));
298298

299299
// 576bits = 18 x 32bit = 5 x 128bit blocks (rounded up)
300300
EXPECT_READ32(CSRNG_SW_CMD_STS_REG_OFFSET,
301301
{{CSRNG_SW_CMD_STS_CMD_RDY_BIT, true}});
302302
EXPECT_WRITE32(CSRNG_CMD_REQ_REG_OFFSET,
303303
0x00005003 | kMultiBitBool4False << 8);
304-
EXPECT_DIF_OK(dif_csrng_generate_start(&csrng_, /*len=*/18));
304+
EXPECT_DIF_OK(dif_csrng_generate_start(&csrng_, nullptr, /*len=*/18));
305305
}
306306

307307
TEST_F(CommandTest, GenerateBadArgs) {
308-
EXPECT_DIF_BADARG(dif_csrng_generate_start(nullptr, /*len=*/1));
309-
EXPECT_DIF_BADARG(dif_csrng_generate_start(&csrng_, /*len=*/0));
308+
EXPECT_DIF_BADARG(dif_csrng_generate_start(nullptr, nullptr, /*len=*/1));
309+
EXPECT_DIF_BADARG(dif_csrng_generate_start(&csrng_, nullptr, /*len=*/0));
310310
}
311311

312312
TEST_F(CommandTest, GenerateOutOfRange) {
@@ -316,7 +316,7 @@ TEST_F(CommandTest, GenerateOutOfRange) {
316316
kGenerateLenOutOfRange = 0x800 * 4 + 1,
317317
};
318318
EXPECT_DIF_OUTOFRANGE(
319-
dif_csrng_generate_start(&csrng_, kGenerateLenOutOfRange));
319+
dif_csrng_generate_start(&csrng_, nullptr, kGenerateLenOutOfRange));
320320
}
321321

322322
TEST_F(CommandTest, UninstantiateOk) {

sw/device/lib/testing/aes_testutils.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ status_t aes_testutils_csrng_kat(const dif_csrng_t *csrng) {
173173
memcpy(expected_state_generate.v, kCsrngVGenerate, sizeof(kCsrngVGenerate));
174174
memcpy(expected_state_generate.key, kCsrngKeyGenerate,
175175
sizeof(kCsrngKeyGenerate));
176-
TRY(csrng_testutils_kat_generate(csrng, 1, kCsrngBlockLen,
176+
TRY(csrng_testutils_kat_generate(csrng, 1, kCsrngBlockLen, NULL,
177177
kAesMaskingPrngZeroOutputSeed,
178178
&expected_state_generate));
179179

@@ -198,7 +198,7 @@ status_t aes_testutils_csrng_kat(const dif_csrng_t *csrng) {
198198

199199
// Generate one block containing the required seed for the AES masking PRNG
200200
// to output an all-zero vector.
201-
TRY(csrng_testutils_kat_generate(csrng, 1, kCsrngBlockLen,
201+
TRY(csrng_testutils_kat_generate(csrng, 1, kCsrngBlockLen, NULL,
202202
kAesMaskingPrngZeroOutputSeed,
203203
&expected_state_generate));
204204
return OK_STATUS();

sw/device/lib/testing/csrng_testutils.c

Lines changed: 134 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@ status_t csrng_testutils_cmd_ready_wait(const dif_csrng_t *csrng) {
7979
return OK_STATUS();
8080
}
8181

82-
status_t csrng_testutils_cmd_generate_run(const dif_csrng_t *csrng,
83-
uint32_t *output, size_t output_len) {
82+
status_t csrng_testutils_cmd_generate_run(
83+
const dif_csrng_t *csrng, const dif_csrng_seed_material_t *additional_data,
84+
uint32_t *output, size_t output_len) {
8485
TRY(csrng_testutils_cmd_ready_wait(csrng));
85-
TRY(dif_csrng_generate_start(csrng, output_len));
86+
TRY(dif_csrng_generate_start(csrng, additional_data, output_len));
8687

8788
dif_csrng_output_status_t output_status;
8889
do {
@@ -135,16 +136,21 @@ status_t csrng_testutils_kat_instantiate(
135136

136137
status_t csrng_testutils_kat_generate(
137138
const dif_csrng_t *csrng, size_t num_generates, size_t output_len,
139+
const dif_csrng_seed_material_t *additional_data,
138140
const uint32_t *expected_output,
139141
const dif_csrng_internal_state_t *expected_state) {
140142
LOG_INFO("CSRNG KAT generate");
141143

142144
// Run the generate and check the output.
143145
uint32_t got[kNumOutputWordsMax];
144146
for (int i = 0; i < num_generates; ++i) {
145-
TRY(csrng_testutils_cmd_generate_run(csrng, got, output_len));
147+
TRY(csrng_testutils_cmd_generate_run(csrng, additional_data, got,
148+
output_len));
149+
}
150+
151+
if (expected_output != NULL) {
152+
TRY_CHECK(memcmp(got, expected_output, output_len) == 0);
146153
}
147-
TRY_CHECK(memcmp(got, expected_output, output_len) == 0);
148154

149155
// Check the internal state.
150156
return csrng_testutils_check_internal_state(csrng, expected_state);
@@ -179,7 +185,15 @@ status_t csrng_testutils_fips_instantiate_kat(const dif_csrng_t *csrng,
179185
// The number format in this docstring follows the CAVP format to simplify
180186
// auditing of this test case.
181187
//
182-
// Test vector: CTR_DRBG AES-256 no DF.
188+
// Test vector: CTR_DRBG AES-256 no DF from
189+
// drbgvectors_no_reseed.zip/CTR_DRBG.txt with parameters
190+
// - PredictionResistance = False
191+
// - EntropyInputLen = 384
192+
// - NonceLen = 0
193+
// - PersonalizationStringLen = 0
194+
// - AdditionalInputLen = 0
195+
// - ReturnedBitsLen = 512
196+
// - COUNT = 0
183197
//
184198
// - EntropyInput =
185199
// df5d73faa468649edda33b5cca79b0b05600419ccb7a879ddfec9db32ee494e5531b51de16a30f769262474c73bec010
@@ -238,10 +252,123 @@ status_t csrng_testutils_fips_generate_kat(const dif_csrng_t *csrng) {
238252
.instantiated = true,
239253
.fips_compliance = false,
240254
};
241-
return csrng_testutils_kat_generate(csrng, 2, kExpectedOutputLen,
255+
return csrng_testutils_kat_generate(csrng, 2, kExpectedOutputLen, NULL,
242256
kExpectedOutput, &kExpectedState);
243257
}
244258

259+
status_t csrng_testutils_fips_instantiate_kat_adata(const dif_csrng_t *csrng,
260+
bool fail_expected) {
261+
// CTR_DRBG Known-Answer-Tests (KATs).
262+
//
263+
// Test vector sourced from NIST's CAVP website:
264+
// https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/random-number-generators
265+
//
266+
// The number format in this docstring follows the CAVP format to simplify
267+
// auditing of this test case.
268+
//
269+
// Test vector: CTR_DRBG AES-256 no DF from
270+
// drbgvectors_no_reseed.zip/CTR_DRBG.txt with parameters
271+
// - PredictionResistance = False
272+
// - EntropyInputLen = 384
273+
// - NonceLen = 0
274+
// - PersonalizationStringLen = 0
275+
// - AdditionalInputLen = 384
276+
// - ReturnedBitsLen = 512
277+
// - COUNT = 0
278+
//
279+
// - EntropyInput =
280+
// f45e9d040c1456f1c7f26e7f146469fbe3973007fe037239ad57623046e7ec52221b22eec208b22ac4cf4ca8d6253874
281+
// - Nonce = EMPTY
282+
// - PersonalizationString = EMPTY
283+
//
284+
// Command: Instantiate
285+
// - Key = a75117ffcb5160486e91da8ed0af1a702d30703ab3631957aa19a7e3fc14714a
286+
// - V = 507b2124f5ae985e156db926a3230dfa
287+
//
288+
// - AdditionalInput =
289+
// 28819bc79b92fc8790ebdc99812cdcea5c96e6feab32801ec1851b9f46e80eb6800028e61fbccb6ccbe42b06bf5a0864
290+
// Command: Generate (first call):
291+
// - Key = d75e41010982abd243b4d75642b86ce07e13b3652a3725aad011b1097c32957a
292+
// - V = 939fbb584e0103982d2e73e05779849f
293+
//
294+
// - AdditionalInput =
295+
// 418ca848027e1b3c84d66717e6f31bf89684d5db94cd2d579233f716ac70ab66cc7b01a6f9ab8c7665fcc37dba4af1ad
296+
// Command: Generate (second call):
297+
// - Key = b0f80df4b33e5d2e3d72c8667ba9da1aa64a3a4936a3fdabf2c980d3104dfa13
298+
// - V = 433abd3907feddce66cbcb216d5d833e
299+
// - ReturnedBits =
300+
// 4f11406bd303c104243441a8f828bf0293cb20ac39392061429c3f56c1f426239f8f0c687b69897a2c7c8c2b4fb520b62741ffdd29f038b7c82a9d00a890a3ed
301+
302+
const dif_csrng_seed_material_t kEntropyInput = {
303+
.seed_material = {0xd6253874, 0xc4cf4ca8, 0xc208b22a, 0x221b22ee,
304+
0x46e7ec52, 0xad576230, 0xfe037239, 0xe3973007,
305+
0x146469fb, 0xc7f26e7f, 0x0c1456f1, 0xf45e9d04},
306+
.seed_material_len = 12,
307+
};
308+
const dif_csrng_internal_state_t kExpectedState = {
309+
.reseed_counter = 0,
310+
.v = {0xa3230dfa, 0x156db926, 0xf5ae985e, 0x507b2124},
311+
.key = {0xfc14714a, 0xaa19a7e3, 0xb3631957, 0x2d30703a, 0xd0af1a70,
312+
0x6e91da8e, 0xcb516048, 0xa75117ff},
313+
.instantiated = true,
314+
.fips_compliance = false,
315+
};
316+
return csrng_testutils_kat_instantiate(csrng, fail_expected, &kEntropyInput,
317+
&kExpectedState);
318+
}
319+
320+
status_t csrng_testutils_fips_generate_kat_adata1(const dif_csrng_t *csrng) {
321+
enum {
322+
kExpectedOutputLen = 16,
323+
};
324+
const dif_csrng_seed_material_t kAdditionalData = {
325+
.seed_material = {0xbf5a0864, 0xcbe42b06, 0x1fbccb6c, 0x800028e6,
326+
0x46e80eb6, 0xc1851b9f, 0xab32801e, 0x5c96e6fe,
327+
0x812cdcea, 0x90ebdc99, 0x9b92fc87, 0x28819bc7},
328+
.seed_material_len = 12,
329+
};
330+
const dif_csrng_internal_state_t kExpectedState = {
331+
.reseed_counter = 1,
332+
.v = {0x5779849f, 0x2d2e73e0, 0x4e010398, 0x939fbb58},
333+
.key = {0x7c32957a, 0xd011b109, 0x2a3725aa, 0x7e13b365, 0x42b86ce0,
334+
0x43b4d756, 0x0982abd2, 0xd75e4101},
335+
.instantiated = true,
336+
.fips_compliance = false,
337+
};
338+
return csrng_testutils_kat_generate(csrng, 1, kExpectedOutputLen,
339+
&kAdditionalData, NULL, &kExpectedState);
340+
}
341+
342+
status_t csrng_testutils_fips_generate_kat_adata2(const dif_csrng_t *csrng) {
343+
enum {
344+
kExpectedOutputLen = 16,
345+
};
346+
const dif_csrng_seed_material_t kAdditionalData = {
347+
.seed_material = {0xba4af1ad, 0x65fcc37d, 0xf9ab8c76, 0xcc7b01a6,
348+
0xac70ab66, 0x9233f716, 0x94cd2d57, 0x9684d5db,
349+
0xe6f31bf8, 0x84d66717, 0x027e1b3c, 0x418ca848},
350+
.seed_material_len = 12,
351+
};
352+
// TODO(#13342): csrng does not provide a linear output order. For example,
353+
// note the test vector output word order: 12,13,14,15 8,9,10,11 4,5,6,7
354+
// 0,1,2,3.
355+
const uint32_t kExpectedOutput[kExpectedOutputLen] = {
356+
0xf828bf02, 0x243441a8, 0xd303c104, 0x4f11406b, 0xc1f42623, 0x429c3f56,
357+
0x39392061, 0x93cb20ac, 0x4fb520b6, 0x2c7c8c2b, 0x7b69897a, 0x9f8f0c68,
358+
0xa890a3ed, 0xc82a9d00, 0x29f038b7, 0x2741ffdd};
359+
const dif_csrng_internal_state_t kExpectedState = {
360+
.reseed_counter = 2,
361+
.v = {0x6d5d833e, 0x66cbcb21, 0x07feddce, 0x433abd39},
362+
.key = {0x104dfa13, 0xf2c980d3, 0x36a3fdab, 0xa64a3a49, 0x7ba9da1a,
363+
0x3d72c866, 0xb33e5d2e, 0xb0f80df4},
364+
.instantiated = true,
365+
.fips_compliance = false,
366+
};
367+
return csrng_testutils_kat_generate(csrng, 1, kExpectedOutputLen,
368+
&kAdditionalData, kExpectedOutput,
369+
&kExpectedState);
370+
}
371+
245372
status_t csrng_testutils_cmd_status_check(const dif_csrng_t *csrng) {
246373
dif_csrng_cmd_status_t status;
247374
TRY(dif_csrng_get_cmd_interface_status(csrng, &status));

sw/device/lib/testing/csrng_testutils.h

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ status_t csrng_testutils_cmd_ready_wait(const dif_csrng_t *csrng);
4848
* Runs CSRNG generate command.
4949
*
5050
* @param csrng A CSRNG handle.
51+
* @param additional_data Additional data, set to NULL if unused.
5152
* @param output Output buffer.
5253
* @param output_len Number of words of entropy to write to output buffer.
5354
*/
5455
OT_WARN_UNUSED_RESULT
55-
status_t csrng_testutils_cmd_generate_run(const dif_csrng_t *csrng,
56-
uint32_t *output, size_t output_len);
56+
status_t csrng_testutils_cmd_generate_run(
57+
const dif_csrng_t *csrng, const dif_csrng_seed_material_t *additional_data,
58+
uint32_t *output, size_t output_len);
5759

5860
/**
5961
* Checks the CSRNG internal state against `expected` values.
@@ -86,12 +88,14 @@ status_t csrng_testutils_kat_instantiate(
8688
* @param num_generates Number of GENERATE commands to run.
8789
* @param output_len Number of output words to read from CSRNG after the last
8890
* command.
91+
* @param additional_data Additional data, set to NULL if unused.
8992
* @param expected_output Expected CSRNG output after the last command.
9093
* @param expected_state Expected CSRNG internal state after the last command.
9194
*/
9295
OT_WARN_UNUSED_RESULT
9396
status_t csrng_testutils_kat_generate(
94-
const dif_csrng_t *csrng, uint32_t num_generates, uint32_t output_len,
97+
const dif_csrng_t *csrng, size_t num_generates, size_t output_len,
98+
const dif_csrng_seed_material_t *additional_data,
9599
const uint32_t *expected_output,
96100
const dif_csrng_internal_state_t *expected_state);
97101

@@ -108,7 +112,8 @@ status_t csrng_testutils_kat_reseed(
108112
const dif_csrng_internal_state_t *expected_state);
109113

110114
/**
111-
* CTR DRBG Known-Answer-Test (KAT) for INSTANTIATE command.
115+
* CTR DRBG Known-Answer-Test (KAT) for INSTANTIATE command for a NIST test
116+
* vector without additional data.
112117
*
113118
* @param csrng Handle.
114119
* @param fail_expected Expected fail.
@@ -118,13 +123,43 @@ status_t csrng_testutils_fips_instantiate_kat(const dif_csrng_t *csrng,
118123
bool fail_expected);
119124

120125
/**
121-
* CTR DRBG Known-Answer-Test (KAT) for GENERATE command.
126+
* CTR DRBG Known-Answer-Test (KAT) for INSTANTIATE command for a NIST test
127+
* vector using additional data for the GENERATE command.
128+
*
129+
* @param csrng Handle.
130+
* @param fail_expected Expected fail.
131+
*/
132+
OT_WARN_UNUSED_RESULT
133+
status_t csrng_testutils_fips_instantiate_kat_adata(const dif_csrng_t *csrng,
134+
bool fail_expected);
135+
136+
/**
137+
* CTR DRBG Known-Answer-Test (KAT) for GENERATE command for a NIST test
138+
* vector without additional data.
122139
*
123140
* @param csrng Handle.
124141
*/
125142
OT_WARN_UNUSED_RESULT
126143
status_t csrng_testutils_fips_generate_kat(const dif_csrng_t *csrng);
127144

145+
/**
146+
* CTR DRBG Known-Answer-Test (KAT) for GENERATE command for a NIST test
147+
* vector with additional data, first call.
148+
*
149+
* @param csrng Handle.
150+
*/
151+
OT_WARN_UNUSED_RESULT
152+
status_t csrng_testutils_fips_generate_kat_adata1(const dif_csrng_t *csrng);
153+
154+
/**
155+
* CTR DRBG Known-Answer-Test (KAT) for GENERATE command for a NIST test
156+
* vector with additional data, second call.
157+
*
158+
* @param csrng Handle.
159+
*/
160+
OT_WARN_UNUSED_RESULT
161+
status_t csrng_testutils_fips_generate_kat_adata2(const dif_csrng_t *csrng);
162+
128163
/**
129164
* Checks CSRNG command status.
130165
*

sw/device/tests/csrng_kat_test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ status_t test_ctr_drbg_ctr0(const dif_csrng_t *csrng) {
1818
TRY(dif_csrng_uninstantiate(csrng));
1919
TRY(csrng_testutils_fips_instantiate_kat(csrng, /*fail_expected=*/false));
2020
TRY(csrng_testutils_fips_generate_kat(csrng));
21+
22+
// Additional test with adata supplied
23+
TRY(dif_csrng_uninstantiate(csrng));
24+
TRY(csrng_testutils_fips_instantiate_kat_adata(csrng, false));
25+
TRY(csrng_testutils_fips_generate_kat_adata1(csrng));
26+
TRY(csrng_testutils_fips_generate_kat_adata2(csrng));
27+
2128
return OK_STATUS();
2229
}
2330

sw/device/tests/csrng_smoketest.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ status_t test_ctr_drbg_ctr0_smoke(const dif_csrng_t *csrng) {
4242
&kEntropyInput));
4343

4444
uint32_t got[kExpectedOutputLen];
45-
TRY(csrng_testutils_cmd_generate_run(csrng, got, kExpectedOutputLen));
46-
TRY(csrng_testutils_cmd_generate_run(csrng, got, kExpectedOutputLen));
45+
TRY(csrng_testutils_cmd_generate_run(csrng, NULL, got, kExpectedOutputLen));
46+
TRY(csrng_testutils_cmd_generate_run(csrng, NULL, got, kExpectedOutputLen));
4747

4848
const uint32_t kExpectedOutput[kExpectedOutputLen] = {
4949
0xe48bb8cb, 0x1012c84c, 0x5af8a7f1, 0xd1c07cd9, 0xdf82ab22, 0x771c619b,

sw/device/tests/entropy_src_csrng_test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ static void irq_block_wait(irq_flag_id_t isr_id) {
141141
*/
142142
static void csrng_generate_output_check(void) {
143143
uint32_t output[kTestParamFifoBufferSize] = {0};
144-
CHECK_STATUS_OK(
145-
csrng_testutils_cmd_generate_run(&csrng, output, ARRAYSIZE(output)));
144+
CHECK_STATUS_OK(csrng_testutils_cmd_generate_run(&csrng, NULL, output,
145+
ARRAYSIZE(output)));
146146

147147
uint32_t prev_data = 0;
148148
for (size_t i = 0; i < ARRAYSIZE(output); ++i) {

0 commit comments

Comments
 (0)