-
Notifications
You must be signed in to change notification settings - Fork 6
/
hash_drbg_tests.c
169 lines (153 loc) · 6.18 KB
/
hash_drbg_tests.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* Copyright (C) 2022 - This file is part of libdrbg project
*
* Author: Ryad BENADJILA <ryad.benadjila@ssi.gouv.fr>
* Contributor: Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
*
* This software is licensed under a dual BSD and GPL v2 license.
* See LICENSE file at the root folder of the project.
*/
#ifdef WITH_HASH_DRBG
#include "hash_drbg_tests.h"
static const char *get_op_name(hash_dbrg_self_test_op op){
switch(op){
case HASH_GENERATE:
return "HASH_GENERATE";
case HASH_INSTANTIATE:
return "HASH_INSTANTIATE";
case HASH_RESEED_EXPLICIT:
return "HASH_RESEED_EXPLICIT";
case HASH_RESEED_PR:
return "HASH_RESEED_PR";
default:
return "UNKNOWN_OP";
}
}
#define MAX_OUT_SIZE 2048
int do_hash_dbrg_self_tests(const hash_dbrg_self_test *all_tests[], unsigned int num_tests){
unsigned int i, j;
drbg_ctx ctx_;
drbg_ctx *ctx = &ctx_;
drbg_options options;
unsigned int num_tests_checked = 0;
for(i = 0; i < num_tests; i++){
hash_alg_type hash_type;
const char *name;
/* Skip dummy tests */
if(all_tests[i] == NULL){
continue;
}
hash_type = all_tests[i]->hash;
name = all_tests[i]->name;
DRBG_HASH_OPTIONS_INIT(options, hash_type);
printf("\n\t=========== Testing %s\n", name);
num_tests_checked++;
/* Parse all our tests */
for(j = 0; j < all_tests[i]->num_gen; j++){
hash_dbrg_self_test_op op = all_tests[i]->Expected[j].op;
const unsigned char *EntropyInput = (const unsigned char*)all_tests[i]->Expected[j].EntropyInput;
uint32_t EntropyInputLen = all_tests[i]->Expected[j].EntropyInputLen;
const unsigned char *Nonce = (const unsigned char*)all_tests[i]->Expected[j].Nonce;
uint32_t NonceLen = all_tests[i]->Expected[j].NonceLen;
const unsigned char *PersonalizationString = (const unsigned char*)all_tests[i]->Expected[j].PersonalizationString;
uint32_t PersonalizationStringLen = all_tests[i]->Expected[j].PersonalizationStringLen;
const unsigned char *AdditionalInput = (const unsigned char*)all_tests[i]->Expected[j].AdditionalInput;
uint32_t AdditionalInputLen = all_tests[i]->Expected[j].AdditionalInputLen;
const unsigned char *AdditionalInputReseed = (const unsigned char*)all_tests[i]->Expected[j].AdditionalInputReseed;
uint32_t AdditionalInputReseedLen = all_tests[i]->Expected[j].AdditionalInputReseedLen;
const unsigned char *EntropyInputPR = (const unsigned char*)all_tests[i]->Expected[j].EntropyInputPR;
uint32_t EntropyInputPRLen = all_tests[i]->Expected[j].EntropyInputPRLen;
const unsigned char *EntropyInputReseed = (const unsigned char*)all_tests[i]->Expected[j].EntropyInputReseed;
uint32_t EntropyInputReseedLen = all_tests[i]->Expected[j].EntropyInputReseedLen;
const unsigned char *C = (const unsigned char*)all_tests[i]->Expected[j].C;
const unsigned char *V = (const unsigned char*)all_tests[i]->Expected[j].V;
uint64_t reseed_counter = all_tests[i]->Expected[j].reseed_counter;
const unsigned char *expected_out = (const unsigned char*)all_tests[i]->Expected[j].out;
unsigned char output[MAX_OUT_SIZE];
uint32_t outlen = all_tests[i]->Expected[j].outlen;
if(MAX_OUT_SIZE < outlen){
/* Size overflow ... */
printf("Output size overflow ...\n");
goto err;
}
if(op == HASH_INSTANTIATE){
/* Instantiate */
printf("[HASH_INSTANTIATE]\n");
if(hash_drbg_instantiate(ctx, EntropyInput, EntropyInputLen, Nonce, NonceLen, PersonalizationString, PersonalizationStringLen, NULL, &options) != HASH_DRBG_OK){
printf("Error in HASH_INSTANTIATE\n");
goto err;
}
}
else if(op == HASH_RESEED_EXPLICIT){
printf("[RESEED (explicit)]\n");
/* Explicitly call reseed */
if(hash_drbg_reseed(ctx, EntropyInputReseed, EntropyInputReseedLen, AdditionalInputReseed, AdditionalInputReseedLen) != HASH_DRBG_OK){
printf("Error in HASH_RESEED_EXPLICIT\n");
goto err;
}
}
else if(op == HASH_RESEED_PR){
printf("[RESEED (PR)]\n");
/* Explicitly call reseed */
if(hash_drbg_reseed(ctx, EntropyInputPR, EntropyInputPRLen, AdditionalInput, AdditionalInputLen) != HASH_DRBG_OK){
printf("Error in HASH_RESEED_PR\n");
goto err;
}
}
else if(op == HASH_GENERATE){
printf("[HASH_GENERATE %u bytes]\n", outlen);
if(hash_drbg_generate(ctx, AdditionalInput, AdditionalInputLen, output, outlen) != HASH_DRBG_OK){
printf("Error in HASH_GENERATE\n");
goto err;
}
}
else{
/* Unknown operation */
goto err;
}
/* Check internal state and output if necessary */
#ifdef HASH_DRBG_SELF_TESTS_VERBOSE
hexdump("\tC = ", (const char*)ctx->data.hash_data.C, ctx->data.hash_data.seed_len);
hexdump("\tV = ", (const char*)ctx->data.hash_data.V, ctx->data.hash_data.seed_len);
printf("\treseed_counter = %lu\n", ctx->reseed_counter);
#endif
if((strlen((const char*)C) != 0) && (strlen((const char*)V) != 0)){
if((memcmp(ctx->data.hash_data.C, C, ctx->data.hash_data.seed_len)) || (memcmp(ctx->data.hash_data.V, V, ctx->data.hash_data.seed_len)) || (ctx->reseed_counter != reseed_counter)){
printf("Error for C, V or reseed_counter after operations #%u (type %s) for %s\n", j, get_op_name(op), name);
#ifdef HASH_DRBG_SELF_TESTS_VERBOSE
hexdump("\t(expected) C = ", (const char*)C, ctx->data.hash_data.seed_len);
hexdump("\t(expected) V = ", (const char*)V, ctx->data.hash_data.seed_len);
printf("\t(expected) reseed_counter = %lu\n", reseed_counter);
#endif
goto err;
}
}
if(strlen(((const char*)expected_out)) > 0){
#ifdef HASH_DRBG_SELF_TESTS_VERBOSE
hexdump("\tout= ", (const char*)output, outlen);
#endif
if(memcmp(output, expected_out, outlen)){
printf("Error for output after operations #%u (type %s) for %s\n", j, get_op_name(op), name);
#ifdef HASH_DRBG_SELF_TESTS_VERBOSE
hexdump("\t(expected) out = ", (const char*)expected_out, outlen);
#endif
goto err;
}
}
}
/* Uninstantiate */
hash_drbg_uninstantiate(ctx);
}
printf("\n-----------------------------\n");
printf("[+] All tests for HASH-DRBG are OK! :-)\n");
printf(" (%u tests performed)\n", num_tests_checked);
return 0;
err:
return -1;
}
#else
/*
* Dummy definition to avoid the empty translation unit ISO C warning
*/
typedef int dummy;
#endif