/src/openssl35/fuzz/provider.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * https://www.openssl.org/source/license.html |
8 | | * or in the file LICENSE in the source distribution. |
9 | | */ |
10 | | #include <string.h> |
11 | | #include <openssl/types.h> |
12 | | #include <openssl/crypto.h> |
13 | | #include <openssl/core_names.h> |
14 | | #include <openssl/kdf.h> |
15 | | #include <openssl/evp.h> |
16 | | #include <openssl/provider.h> |
17 | | #include "fuzzer.h" |
18 | | |
19 | | #define DEFINE_ALGORITHMS(name, evp) \ |
20 | | DEFINE_STACK_OF(evp) \ |
21 | | static int cmp_##evp(const evp *const *a, const evp *const *b); \ |
22 | | static void collect_##evp(evp *obj, void *stack); \ |
23 | | static void init_##name(OSSL_LIB_CTX *libctx); \ |
24 | | static void cleanup_##name(void); \ |
25 | | static STACK_OF(evp) *name##_collection; \ |
26 | | static int cmp_##evp(const evp *const *a, const evp *const *b) \ |
27 | 600 | { \ |
28 | 600 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ |
29 | 600 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ |
30 | 600 | } \ Line | Count | Source | 27 | 52 | { \ | 28 | 52 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 52 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 52 | } \ |
Line | Count | Source | 27 | 38 | { \ | 28 | 38 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 38 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 38 | } \ |
provider.c:cmp_EVP_CIPHER Line | Count | Source | 27 | 258 | { \ | 28 | 258 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 258 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 258 | } \ |
Line | Count | Source | 27 | 20 | { \ | 28 | 20 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 20 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 20 | } \ |
provider.c:cmp_EVP_KEYEXCH Line | Count | Source | 27 | 12 | { \ | 28 | 12 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 12 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 12 | } \ |
Line | Count | Source | 27 | 8 | { \ | 28 | 8 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 8 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 8 | } \ |
Line | Count | Source | 27 | 16 | { \ | 28 | 16 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 16 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 16 | } \ |
provider.c:cmp_EVP_KEYMGMT Line | Count | Source | 27 | 78 | { \ | 28 | 78 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 78 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 78 | } \ |
provider.c:cmp_EVP_SIGNATURE Line | Count | Source | 27 | 116 | { \ | 28 | 116 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 116 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 116 | } \ |
provider.c:cmp_EVP_ASYM_CIPHER Line | Count | Source | 27 | 2 | { \ | 28 | 2 | return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \ | 29 | 2 | OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \ | 30 | 2 | } \ |
|
31 | | static void collect_##evp(evp *obj, void *stack) \ |
32 | 2.37k | { \ |
33 | 2.37k | STACK_OF(evp) *obj_stack = stack; \ |
34 | 2.37k | \ |
35 | 2.37k | if (sk_##evp##_push(obj_stack, obj) > 0) \ |
36 | 2.37k | evp##_up_ref(obj); \ |
37 | 2.37k | } \ provider.c:collect_EVP_MD Line | Count | Source | 32 | 216 | { \ | 33 | 216 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 216 | \ | 35 | 216 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 216 | evp##_up_ref(obj); \ | 37 | 216 | } \ |
provider.c:collect_EVP_KDF Line | Count | Source | 32 | 142 | { \ | 33 | 142 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 142 | \ | 35 | 142 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 142 | evp##_up_ref(obj); \ | 37 | 142 | } \ |
provider.c:collect_EVP_CIPHER Line | Count | Source | 32 | 1.04k | { \ | 33 | 1.04k | STACK_OF(evp) *obj_stack = stack; \ | 34 | 1.04k | \ | 35 | 1.04k | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 1.04k | evp##_up_ref(obj); \ | 37 | 1.04k | } \ |
provider.c:collect_EVP_KEM Line | Count | Source | 32 | 74 | { \ | 33 | 74 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 74 | \ | 35 | 74 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 74 | evp##_up_ref(obj); \ | 37 | 74 | } \ |
provider.c:collect_EVP_KEYEXCH Line | Count | Source | 32 | 56 | { \ | 33 | 56 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 56 | \ | 35 | 56 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 56 | evp##_up_ref(obj); \ | 37 | 56 | } \ |
provider.c:collect_EVP_RAND Line | Count | Source | 32 | 40 | { \ | 33 | 40 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 40 | \ | 35 | 40 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 40 | evp##_up_ref(obj); \ | 37 | 40 | } \ |
provider.c:collect_EVP_MAC Line | Count | Source | 32 | 72 | { \ | 33 | 72 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 72 | \ | 35 | 72 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 72 | evp##_up_ref(obj); \ | 37 | 72 | } \ |
provider.c:collect_EVP_KEYMGMT Line | Count | Source | 32 | 276 | { \ | 33 | 276 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 276 | \ | 35 | 276 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 276 | evp##_up_ref(obj); \ | 37 | 276 | } \ |
provider.c:collect_EVP_SIGNATURE Line | Count | Source | 32 | 442 | { \ | 33 | 442 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 442 | \ | 35 | 442 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 442 | evp##_up_ref(obj); \ | 37 | 442 | } \ |
provider.c:collect_EVP_ASYM_CIPHER Line | Count | Source | 32 | 16 | { \ | 33 | 16 | STACK_OF(evp) *obj_stack = stack; \ | 34 | 16 | \ | 35 | 16 | if (sk_##evp##_push(obj_stack, obj) > 0) \ | 36 | 16 | evp##_up_ref(obj); \ | 37 | 16 | } \ |
|
38 | | static void init_##name(OSSL_LIB_CTX *libctx) \ |
39 | 80 | { \ |
40 | 80 | name##_collection = sk_##evp##_new(cmp_##evp); \ |
41 | 80 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ |
42 | 80 | } \ Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
provider.c:init_signature Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
provider.c:init_asym_ciphers Line | Count | Source | 39 | 8 | { \ | 40 | 8 | name##_collection = sk_##evp##_new(cmp_##evp); \ | 41 | 8 | evp##_do_all_provided(libctx, collect_##evp, name##_collection); \ | 42 | 8 | } \ |
|
43 | | static void cleanup_##name(void) \ |
44 | 0 | { \ |
45 | 0 | sk_##evp##_pop_free(name##_collection, evp##_free); \ |
46 | 0 | } Unexecuted instantiation: provider.c:cleanup_digests Unexecuted instantiation: provider.c:cleanup_kdf Unexecuted instantiation: provider.c:cleanup_cipher Unexecuted instantiation: provider.c:cleanup_kem Unexecuted instantiation: provider.c:cleanup_keyexch Unexecuted instantiation: provider.c:cleanup_rand Unexecuted instantiation: provider.c:cleanup_mac Unexecuted instantiation: provider.c:cleanup_keymgmt Unexecuted instantiation: provider.c:cleanup_signature Unexecuted instantiation: provider.c:cleanup_asym_ciphers |
47 | | |
48 | | DEFINE_ALGORITHMS(digests, EVP_MD) |
49 | | |
50 | | DEFINE_ALGORITHMS(kdf, EVP_KDF) |
51 | | |
52 | | DEFINE_ALGORITHMS(cipher, EVP_CIPHER) |
53 | | |
54 | | DEFINE_ALGORITHMS(kem, EVP_KEM) |
55 | | |
56 | | DEFINE_ALGORITHMS(keyexch, EVP_KEYEXCH) |
57 | | |
58 | | DEFINE_ALGORITHMS(rand, EVP_RAND) |
59 | | |
60 | | DEFINE_ALGORITHMS(mac, EVP_MAC) |
61 | | |
62 | | DEFINE_ALGORITHMS(keymgmt, EVP_KEYMGMT) |
63 | | |
64 | | DEFINE_ALGORITHMS(signature, EVP_SIGNATURE) |
65 | | |
66 | | DEFINE_ALGORITHMS(asym_ciphers, EVP_ASYM_CIPHER) |
67 | | |
68 | | static OSSL_LIB_CTX *libctx = NULL; |
69 | | |
70 | | int FuzzerInitialize(int *argc, char ***argv) |
71 | 20 | { |
72 | 20 | libctx = OSSL_LIB_CTX_new(); |
73 | 20 | if (libctx == NULL) |
74 | 0 | return 0; |
75 | | |
76 | 20 | init_digests(libctx); |
77 | 20 | init_kdf(libctx); |
78 | 20 | init_cipher(libctx); |
79 | 20 | init_kem(libctx); |
80 | 20 | init_keyexch(libctx); |
81 | 20 | init_rand(libctx); |
82 | 20 | init_mac(libctx); |
83 | 20 | init_keymgmt(libctx); |
84 | 20 | init_signature(libctx); |
85 | 20 | init_asym_ciphers(libctx); |
86 | 20 | return 1; |
87 | 20 | } |
88 | | |
89 | | void FuzzerCleanup(void) |
90 | 0 | { |
91 | 0 | cleanup_digests(); |
92 | 0 | cleanup_kdf(); |
93 | 0 | cleanup_cipher(); |
94 | 0 | cleanup_kem(); |
95 | 0 | cleanup_keyexch(); |
96 | 0 | cleanup_rand(); |
97 | 0 | cleanup_mac(); |
98 | 0 | cleanup_keymgmt(); |
99 | 0 | cleanup_signature(); |
100 | 0 | cleanup_asym_ciphers(); |
101 | |
|
102 | 0 | OSSL_LIB_CTX_free(libctx); |
103 | 0 | } |
104 | | |
105 | | static int read_uint(const uint8_t **buf, size_t *len, uint64_t **res) |
106 | 14.9k | { |
107 | 14.9k | int r = 1; |
108 | | |
109 | 14.9k | if (*len < sizeof(uint64_t)) { |
110 | 295 | r = 0; |
111 | 295 | goto end; |
112 | 295 | } |
113 | | |
114 | 14.7k | *res = OPENSSL_malloc(sizeof(uint64_t)); |
115 | 14.7k | **res = (uint64_t)**buf; |
116 | | |
117 | 14.7k | *buf += sizeof(uint64_t); |
118 | 14.7k | *len -= sizeof(uint64_t); |
119 | 14.9k | end: |
120 | 14.9k | return r; |
121 | 14.7k | } |
122 | | |
123 | | static int read_int(const uint8_t **buf, size_t *len, int64_t **res) |
124 | 62.4k | { |
125 | 62.4k | int r = 1; |
126 | | |
127 | 62.4k | if (*len < sizeof(int64_t)) { |
128 | 14.8k | r = 0; |
129 | 14.8k | goto end; |
130 | 14.8k | } |
131 | | |
132 | 47.5k | *res = OPENSSL_malloc(sizeof(int64_t)); |
133 | 47.5k | **res = (int64_t)**buf; |
134 | | |
135 | 47.5k | *buf += sizeof(int64_t); |
136 | 47.5k | *len -= sizeof(int64_t); |
137 | 62.4k | end: |
138 | 62.4k | return r; |
139 | 47.5k | } |
140 | | |
141 | | static int read_double(const uint8_t **buf, size_t *len, double **res) |
142 | 0 | { |
143 | 0 | int r = 1; |
144 | |
|
145 | 0 | if (*len < sizeof(double)) { |
146 | 0 | r = 0; |
147 | 0 | goto end; |
148 | 0 | } |
149 | | |
150 | 0 | *res = OPENSSL_malloc(sizeof(double)); |
151 | 0 | **res = (double)**buf; |
152 | |
|
153 | 0 | *buf += sizeof(double); |
154 | 0 | *len -= sizeof(double); |
155 | 0 | end: |
156 | 0 | return r; |
157 | 0 | } |
158 | | |
159 | | static int read_utf8_string(const uint8_t **buf, size_t *len, char **res) |
160 | 12.7k | { |
161 | 12.7k | size_t found_len; |
162 | 12.7k | int r; |
163 | | |
164 | 12.7k | found_len = OPENSSL_strnlen((const char *)*buf, *len); |
165 | | |
166 | 12.7k | if (found_len == *len) { |
167 | 816 | r = -1; |
168 | 816 | goto end; |
169 | 816 | } |
170 | | |
171 | 11.9k | found_len++; /* skip over the \0 byte */ |
172 | | |
173 | 11.9k | r = (int)found_len; |
174 | | |
175 | 11.9k | *res = (char *)*buf; |
176 | 11.9k | *len -= found_len; |
177 | 11.9k | *buf = *buf + found_len; /* continue after the \0 byte */ |
178 | 12.7k | end: |
179 | 12.7k | return r; |
180 | 11.9k | } |
181 | | |
182 | | static int read_utf8_ptr(const uint8_t **buf, size_t *len, char **res) |
183 | 0 | { |
184 | 0 | if (*len > 0 && **buf == 0xFF) { |
185 | | /* represent NULL somehow */ |
186 | 0 | *res = NULL; |
187 | 0 | *buf += 1; |
188 | 0 | *len -= 1; |
189 | 0 | return 0; |
190 | 0 | } |
191 | 0 | return read_utf8_string(buf, len, res); |
192 | 0 | } |
193 | | |
194 | | static int read_octet_string(const uint8_t **buf, size_t *len, char **res) |
195 | 12.6k | { |
196 | 12.6k | int r; |
197 | 12.6k | size_t i; |
198 | 12.6k | const uint8_t *ptr = *buf; |
199 | 12.6k | int found = 0; |
200 | | |
201 | 197M | for (i = 0; i < *len; ++i) { |
202 | 197M | if (*ptr == 0xFF && (i + 1 < *len && *(ptr + 1) == 0xFF)) { |
203 | 9.20k | ptr++; |
204 | 9.20k | found = 1; |
205 | 9.20k | break; |
206 | 9.20k | } |
207 | 197M | ptr++; |
208 | 197M | } |
209 | | |
210 | 12.6k | if (!found) { |
211 | 3.41k | r = -1; |
212 | 3.41k | goto end; |
213 | 3.41k | } |
214 | | |
215 | 9.20k | *res = (char *)*buf; |
216 | | |
217 | 9.20k | r = ptr - *buf; |
218 | 9.20k | *len -= r; |
219 | 9.20k | *buf = ptr; |
220 | | |
221 | 12.6k | end: |
222 | 12.6k | return r; |
223 | 9.20k | } |
224 | | |
225 | | static int read_octet_ptr(const uint8_t **buf, size_t *len, char **res) |
226 | 0 | { |
227 | | /* TODO: This representation could need an improvement potentially. */ |
228 | 0 | if (*len > 1 && **buf == 0xFF && *(*buf + 1) == 0xFF) { |
229 | | /* represent NULL somehow */ |
230 | 0 | *res = NULL; |
231 | 0 | *buf += 2; |
232 | 0 | *len -= 2; |
233 | 0 | return 0; |
234 | 0 | } |
235 | 0 | return read_octet_string(buf, len, res); |
236 | 0 | } |
237 | | |
238 | | static char *DFLT_STR = ""; |
239 | | static char *DFLT_UTF8_PTR = NULL; |
240 | | static char *DFLT_OCTET_STRING = ""; |
241 | | static char *DFLT_OCTET_PTR = NULL; |
242 | | |
243 | | static int64_t ITERS = 1; |
244 | | static uint64_t UITERS = 1; |
245 | | static int64_t BLOCKSIZE = 8; |
246 | | static uint64_t UBLOCKSIZE = 8; |
247 | | |
248 | | static void free_params(OSSL_PARAM *param) |
249 | 9.35k | { |
250 | 61.0k | for (; param != NULL && param->key != NULL; param++) { |
251 | 51.6k | switch (param->data_type) { |
252 | 3.44k | case OSSL_PARAM_INTEGER: |
253 | 15.2k | case OSSL_PARAM_UNSIGNED_INTEGER: |
254 | 15.2k | case OSSL_PARAM_REAL: |
255 | 15.2k | if (param->data != NULL) { |
256 | 15.2k | OPENSSL_free(param->data); |
257 | 15.2k | } |
258 | 15.2k | break; |
259 | 51.6k | } |
260 | 51.6k | } |
261 | 9.35k | } |
262 | | |
263 | | static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *len) |
264 | 9.35k | { |
265 | 9.35k | OSSL_PARAM *p; |
266 | 9.35k | OSSL_PARAM *fuzzed_parameters; |
267 | 9.35k | int p_num = 0; |
268 | | |
269 | 61.0k | for (p = param; p != NULL && p->key != NULL; p++) |
270 | 51.6k | p_num++; |
271 | | |
272 | 9.35k | fuzzed_parameters = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (p_num + 1)); |
273 | 9.35k | p = fuzzed_parameters; |
274 | | |
275 | 61.0k | for (; param != NULL && param->key != NULL; param++) { |
276 | 51.6k | int64_t *use_param = NULL; |
277 | 51.6k | int64_t *p_value_int = NULL; |
278 | 51.6k | uint64_t *p_value_uint = NULL; |
279 | 51.6k | double *p_value_double = NULL; |
280 | 51.6k | char *p_value_utf8_str = DFLT_STR; |
281 | 51.6k | char *p_value_octet_str = DFLT_OCTET_STRING; |
282 | 51.6k | char *p_value_utf8_ptr = DFLT_UTF8_PTR; |
283 | 51.6k | char *p_value_octet_ptr = DFLT_OCTET_PTR; |
284 | | |
285 | 51.6k | int data_len = 0; |
286 | | |
287 | 51.6k | if (!read_int(buf, len, &use_param)) { |
288 | 14.7k | use_param = OPENSSL_malloc(sizeof(uint64_t)); |
289 | 14.7k | *use_param = 0; |
290 | 14.7k | } |
291 | | |
292 | 51.6k | switch (param->data_type) { |
293 | 3.44k | case OSSL_PARAM_INTEGER: |
294 | 3.44k | if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) { |
295 | 0 | p_value_int = OPENSSL_malloc(sizeof(ITERS)); |
296 | 0 | *p_value_int = ITERS; |
297 | 3.44k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) { |
298 | 0 | p_value_int = OPENSSL_malloc(sizeof(ITERS)); |
299 | 0 | *p_value_int = ITERS; |
300 | 3.44k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) { |
301 | 394 | p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE)); |
302 | 394 | *p_value_int = BLOCKSIZE; |
303 | 3.04k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) { |
304 | 0 | p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE)); |
305 | 0 | *p_value_int = BLOCKSIZE; |
306 | 3.04k | } else if (!*use_param || !read_int(buf, len, &p_value_int)) { |
307 | 1.73k | p_value_int = OPENSSL_malloc(sizeof(int64_t)); |
308 | 1.73k | *p_value_int = 0; |
309 | 1.73k | } |
310 | | |
311 | 3.44k | *p = *param; |
312 | 3.44k | p->data = p_value_int; |
313 | 3.44k | p++; |
314 | 3.44k | break; |
315 | 11.8k | case OSSL_PARAM_UNSIGNED_INTEGER: |
316 | 11.8k | if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) { |
317 | 1.66k | p_value_uint = OPENSSL_malloc(sizeof(UITERS)); |
318 | 1.66k | *p_value_uint = UITERS; |
319 | 10.1k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) { |
320 | 102 | p_value_uint = OPENSSL_malloc(sizeof(UITERS)); |
321 | 102 | *p_value_uint = UITERS; |
322 | 10.0k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) { |
323 | 102 | p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE)); |
324 | 102 | *p_value_uint = UBLOCKSIZE; |
325 | 9.98k | } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) { |
326 | 102 | p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE)); |
327 | 102 | *p_value_uint = UBLOCKSIZE; |
328 | 9.88k | } else if (!*use_param || !read_uint(buf, len, &p_value_uint)) { |
329 | 4.55k | p_value_uint = OPENSSL_malloc(sizeof(uint64_t)); |
330 | 4.55k | *p_value_uint = 0; |
331 | 4.55k | } |
332 | | |
333 | 11.8k | *p = *param; |
334 | 11.8k | p->data = p_value_uint; |
335 | 11.8k | p++; |
336 | 11.8k | break; |
337 | 0 | case OSSL_PARAM_REAL: |
338 | 0 | if (!*use_param || !read_double(buf, len, &p_value_double)) { |
339 | 0 | p_value_double = OPENSSL_malloc(sizeof(double)); |
340 | 0 | *p_value_double = 0; |
341 | 0 | } |
342 | |
|
343 | 0 | *p = *param; |
344 | 0 | p->data = p_value_double; |
345 | 0 | p++; |
346 | 0 | break; |
347 | 16.9k | case OSSL_PARAM_UTF8_STRING: |
348 | 16.9k | if (*use_param && (data_len = read_utf8_string(buf, len, &p_value_utf8_str)) < 0) |
349 | 816 | data_len = 0; |
350 | 16.9k | *p = *param; |
351 | 16.9k | p->data = p_value_utf8_str; |
352 | 16.9k | p->data_size = data_len; |
353 | 16.9k | p++; |
354 | 16.9k | break; |
355 | 19.4k | case OSSL_PARAM_OCTET_STRING: |
356 | 19.4k | if (*use_param && (data_len = read_octet_string(buf, len, &p_value_octet_str)) < 0) |
357 | 3.41k | data_len = 0; |
358 | 19.4k | *p = *param; |
359 | 19.4k | p->data = p_value_octet_str; |
360 | 19.4k | p->data_size = data_len; |
361 | 19.4k | p++; |
362 | 19.4k | break; |
363 | 0 | case OSSL_PARAM_UTF8_PTR: |
364 | 0 | if (*use_param && (data_len = read_utf8_ptr(buf, len, &p_value_utf8_ptr)) < 0) |
365 | 0 | data_len = 0; |
366 | 0 | *p = *param; |
367 | 0 | p->data = p_value_utf8_ptr; |
368 | 0 | p->data_size = data_len; |
369 | 0 | p++; |
370 | 0 | break; |
371 | 0 | case OSSL_PARAM_OCTET_PTR: |
372 | 0 | if (*use_param && (data_len = read_octet_ptr(buf, len, &p_value_octet_ptr)) < 0) |
373 | 0 | data_len = 0; |
374 | 0 | *p = *param; |
375 | 0 | p->data = p_value_octet_ptr; |
376 | 0 | p->data_size = data_len; |
377 | 0 | p++; |
378 | 0 | break; |
379 | 0 | default: |
380 | 0 | break; |
381 | 51.6k | } |
382 | | |
383 | 51.6k | OPENSSL_free(use_param); |
384 | 51.6k | } |
385 | | |
386 | 9.35k | return fuzzed_parameters; |
387 | 9.35k | } |
388 | | |
389 | | static int do_evp_cipher(const EVP_CIPHER *evp_cipher, const OSSL_PARAM param[]) |
390 | 108 | { |
391 | 108 | unsigned char outbuf[1024]; |
392 | 108 | int outlen, tmplen; |
393 | 108 | unsigned char key[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
394 | 108 | unsigned char iv[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; |
395 | 108 | const char intext[] = "text"; |
396 | 108 | EVP_CIPHER_CTX *ctx; |
397 | | |
398 | 108 | ctx = EVP_CIPHER_CTX_new(); |
399 | | |
400 | 108 | if (!EVP_CIPHER_CTX_set_params(ctx, param)) { |
401 | 108 | EVP_CIPHER_CTX_free(ctx); |
402 | 108 | return 0; |
403 | 108 | } |
404 | | |
405 | 0 | if (!EVP_EncryptInit_ex2(ctx, evp_cipher, key, iv, NULL)) { |
406 | | /* Error */ |
407 | 0 | EVP_CIPHER_CTX_free(ctx); |
408 | 0 | return 0; |
409 | 0 | } |
410 | | |
411 | 0 | if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, (const unsigned char *)intext, strlen(intext))) { |
412 | | /* Error */ |
413 | 0 | EVP_CIPHER_CTX_free(ctx); |
414 | 0 | return 0; |
415 | 0 | } |
416 | | /* |
417 | | * Buffer passed to EVP_EncryptFinal() must be after data just |
418 | | * encrypted to avoid overwriting it. |
419 | | */ |
420 | 0 | if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) { |
421 | | /* Error */ |
422 | 0 | EVP_CIPHER_CTX_free(ctx); |
423 | 0 | return 0; |
424 | 0 | } |
425 | 0 | outlen += tmplen; |
426 | 0 | EVP_CIPHER_CTX_free(ctx); |
427 | 0 | return 1; |
428 | 0 | } |
429 | | |
430 | | static int do_evp_kdf(EVP_KDF *evp_kdf, const OSSL_PARAM params[]) |
431 | 5.77k | { |
432 | 5.77k | int r = 1; |
433 | 5.77k | EVP_KDF_CTX *kctx = NULL; |
434 | 5.77k | unsigned char derived[32]; |
435 | | |
436 | 5.77k | kctx = EVP_KDF_CTX_new(evp_kdf); |
437 | | |
438 | 5.77k | if (kctx == NULL) { |
439 | 0 | r = 0; |
440 | 0 | goto end; |
441 | 0 | } |
442 | | |
443 | 5.77k | if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { |
444 | 2.44k | r = 0; |
445 | 2.44k | goto end; |
446 | 2.44k | } |
447 | | |
448 | 3.32k | if (EVP_KDF_derive(kctx, derived, sizeof(derived), NULL) <= 0) { |
449 | 1.01k | r = 0; |
450 | 1.01k | goto end; |
451 | 1.01k | } |
452 | | |
453 | 5.77k | end: |
454 | 5.77k | EVP_KDF_CTX_free(kctx); |
455 | 5.77k | return r; |
456 | 3.32k | } |
457 | | |
458 | | static int do_evp_mac(EVP_MAC *evp_mac, const OSSL_PARAM params[]) |
459 | 2.09k | { |
460 | 2.09k | int r = 1; |
461 | 2.09k | const char *key = "mac_key"; |
462 | 2.09k | char text[] = "Some Crypto Text"; |
463 | 2.09k | EVP_MAC_CTX *ctx = NULL; |
464 | 2.09k | unsigned char buf[4096]; |
465 | 2.09k | size_t final_l; |
466 | | |
467 | 2.09k | if ((ctx = EVP_MAC_CTX_new(evp_mac)) == NULL |
468 | 2.09k | || !EVP_MAC_init(ctx, (const unsigned char *)key, strlen(key), |
469 | 2.09k | params)) { |
470 | 1.21k | r = 0; |
471 | 1.21k | goto end; |
472 | 1.21k | } |
473 | | |
474 | 875 | if (EVP_MAC_CTX_set_params(ctx, params) <= 0) { |
475 | 0 | r = 0; |
476 | 0 | goto end; |
477 | 0 | } |
478 | | |
479 | 875 | if (!EVP_MAC_update(ctx, (unsigned char *)text, sizeof(text))) { |
480 | 123 | r = 0; |
481 | 123 | goto end; |
482 | 123 | } |
483 | | |
484 | 752 | if (!EVP_MAC_final(ctx, buf, &final_l, sizeof(buf))) { |
485 | 0 | r = 0; |
486 | 0 | goto end; |
487 | 0 | } |
488 | | |
489 | 2.09k | end: |
490 | 2.09k | EVP_MAC_CTX_free(ctx); |
491 | 2.09k | return r; |
492 | 752 | } |
493 | | |
494 | | static int do_evp_rand(EVP_RAND *evp_rand, const OSSL_PARAM params[]) |
495 | 1.01k | { |
496 | 1.01k | int r = 1; |
497 | 1.01k | EVP_RAND_CTX *ctx = NULL; |
498 | 1.01k | unsigned char buf[4096]; |
499 | | |
500 | 1.01k | if (!(ctx = EVP_RAND_CTX_new(evp_rand, NULL))) { |
501 | 0 | r = 0; |
502 | 0 | goto end; |
503 | 0 | } |
504 | | |
505 | 1.01k | if (EVP_RAND_CTX_set_params(ctx, params) <= 0) { |
506 | 299 | r = 0; |
507 | 299 | goto end; |
508 | 299 | } |
509 | | |
510 | 713 | if (!EVP_RAND_generate(ctx, buf, sizeof(buf), 0, 0, NULL, 0)) { |
511 | 189 | r = 0; |
512 | 189 | goto end; |
513 | 189 | } |
514 | | |
515 | 524 | if (!EVP_RAND_reseed(ctx, 0, 0, 0, NULL, 0)) { |
516 | 0 | r = 0; |
517 | 0 | goto end; |
518 | 0 | } |
519 | | |
520 | 1.01k | end: |
521 | 1.01k | EVP_RAND_CTX_free(ctx); |
522 | 1.01k | return r; |
523 | 524 | } |
524 | | |
525 | | static int do_evp_sig(EVP_SIGNATURE *evp_sig, const OSSL_PARAM params[]) |
526 | 108 | { |
527 | 108 | return 0; |
528 | 108 | } |
529 | | |
530 | | static int do_evp_asym_cipher(EVP_ASYM_CIPHER *evp_asym_cipher, const OSSL_PARAM params[]) |
531 | 24 | { |
532 | 24 | return 0; |
533 | 24 | } |
534 | | |
535 | | static int do_evp_kem(EVP_KEM *evp_kem, const OSSL_PARAM params[]) |
536 | 52 | { |
537 | 52 | return 0; |
538 | 52 | } |
539 | | |
540 | | static int do_evp_key_exch(EVP_KEYEXCH *evp_kdf, const OSSL_PARAM params[]) |
541 | 94 | { |
542 | 94 | return 0; |
543 | 94 | } |
544 | | |
545 | | static int do_evp_md(EVP_MD *evp_md, const OSSL_PARAM params[]) |
546 | 89 | { |
547 | 89 | int r = 1; |
548 | 89 | unsigned char md_value[EVP_MAX_MD_SIZE]; |
549 | 89 | unsigned int md_len; |
550 | 89 | EVP_MD_CTX *mdctx = NULL; |
551 | | |
552 | 89 | if (!(mdctx = EVP_MD_CTX_new())) { |
553 | 0 | r = 0; |
554 | 0 | goto end; |
555 | 0 | } |
556 | | |
557 | 89 | if (!EVP_MD_CTX_set_params(mdctx, params)) { |
558 | 89 | r = 0; |
559 | 89 | goto end; |
560 | 89 | } |
561 | | |
562 | 0 | if (!EVP_DigestInit_ex2(mdctx, evp_md, NULL)) { |
563 | 0 | r = 0; |
564 | 0 | goto end; |
565 | 0 | } |
566 | 0 | if (!EVP_DigestUpdate(mdctx, "Test", strlen("Test"))) { |
567 | 0 | r = 0; |
568 | 0 | goto end; |
569 | 0 | } |
570 | 0 | if (!EVP_DigestFinal_ex(mdctx, md_value, &md_len)) { |
571 | 0 | r = 0; |
572 | 0 | goto end; |
573 | 0 | } |
574 | | |
575 | 89 | end: |
576 | 89 | EVP_MD_CTX_free(mdctx); |
577 | 89 | return r; |
578 | 0 | } |
579 | | |
580 | | #define EVP_FUZZ(source, evp, f) \ |
581 | 9.35k | do { \ |
582 | 9.35k | evp *alg = sk_##evp##_value(source, *algorithm % sk_##evp##_num(source)); \ |
583 | 9.35k | OSSL_PARAM *fuzzed_params; \ |
584 | 9.35k | \ |
585 | 9.35k | if (alg == NULL) \ |
586 | 9.35k | break; \ |
587 | 9.35k | fuzzed_params = fuzz_params((OSSL_PARAM *)evp##_settable_ctx_params(alg), &buf, &len); \ |
588 | 9.35k | if (fuzzed_params != NULL) \ |
589 | 9.35k | f(alg, fuzzed_params); \ |
590 | 9.35k | free_params(fuzzed_params); \ |
591 | 9.35k | OSSL_PARAM_free(fuzzed_params); \ |
592 | 9.35k | } while (0); |
593 | | |
594 | | int FuzzerTestOneInput(const uint8_t *buf, size_t len) |
595 | 9.39k | { |
596 | 9.39k | int r = 1; |
597 | 9.39k | uint64_t *operation = NULL; |
598 | 9.39k | int64_t *algorithm = NULL; |
599 | | |
600 | 9.39k | if (!read_uint(&buf, &len, &operation)) { |
601 | 16 | r = 0; |
602 | 16 | goto end; |
603 | 16 | } |
604 | | |
605 | 9.37k | if (!read_int(&buf, &len, &algorithm)) { |
606 | 20 | r = 0; |
607 | 20 | goto end; |
608 | 20 | } |
609 | | |
610 | 9.35k | switch (*operation % 10) { |
611 | 89 | case 0: |
612 | 89 | EVP_FUZZ(digests_collection, EVP_MD, do_evp_md); |
613 | 89 | break; |
614 | 108 | case 1: |
615 | 108 | EVP_FUZZ(cipher_collection, EVP_CIPHER, do_evp_cipher); |
616 | 108 | break; |
617 | 5.77k | case 2: |
618 | 5.77k | EVP_FUZZ(kdf_collection, EVP_KDF, do_evp_kdf); |
619 | 5.77k | break; |
620 | 2.09k | case 3: |
621 | 2.09k | EVP_FUZZ(mac_collection, EVP_MAC, do_evp_mac); |
622 | 2.09k | break; |
623 | 52 | case 4: |
624 | 52 | EVP_FUZZ(kem_collection, EVP_KEM, do_evp_kem); |
625 | 52 | break; |
626 | 1.01k | case 5: |
627 | 1.01k | EVP_FUZZ(rand_collection, EVP_RAND, do_evp_rand); |
628 | 1.01k | break; |
629 | 24 | case 6: |
630 | 24 | EVP_FUZZ(asym_ciphers_collection, EVP_ASYM_CIPHER, do_evp_asym_cipher); |
631 | 24 | break; |
632 | 108 | case 7: |
633 | 108 | EVP_FUZZ(signature_collection, EVP_SIGNATURE, do_evp_sig); |
634 | 108 | break; |
635 | 94 | case 8: |
636 | 94 | EVP_FUZZ(keyexch_collection, EVP_KEYEXCH, do_evp_key_exch); |
637 | 94 | break; |
638 | 4 | case 9: |
639 | | /* |
640 | | Implement and call: |
641 | | static int do_evp_keymgmt(EVP_KEYMGMT *evp_kdf, const OSSL_PARAM params[]) |
642 | | { |
643 | | return 0; |
644 | | } |
645 | | */ |
646 | | /* not yet implemented */ |
647 | 4 | break; |
648 | 0 | default: |
649 | 0 | r = 0; |
650 | 0 | goto end; |
651 | 9.35k | } |
652 | | |
653 | 9.39k | end: |
654 | 9.39k | OPENSSL_free(operation); |
655 | 9.39k | OPENSSL_free(algorithm); |
656 | 9.39k | return r; |
657 | 9.35k | } |