1 /*
2 * Copyright 2016-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
11 #include <openssl/ssl.h>
12 #include <openssl/err.h>
13 #include <openssl/bio.h>
14 #include "fuzzer.h"
15 #include "internal/quic_srtm.h"
16
FuzzerInitialize(int * argc,char *** argv)17 int FuzzerInitialize(int *argc, char ***argv)
18 {
19 FuzzerSetRand();
20 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL);
21 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
22 ERR_clear_error();
23 return 1;
24 }
25
26 /*
27 * Fuzzer input "protocol":
28 * Big endian
29 * Zero or more of:
30 * ADD - u8(0x00) u64(opaque) u64(seq_num) u128(token)
31 * REMOVE - u8(0x01) u64(opaque) u64(seq_num)
32 * CULL - u8(0x02) u64(opaque)
33 * LOOKUP - u8(0x03) u128(token) u64(idx)
34 */
35 enum {
36 CMD_ADD,
37 CMD_REMOVE,
38 CMD_CULL,
39 CMD_LOOKUP,
40 CMD_MAX
41 };
42
43 #define MAX_CMDS 10000
44
FuzzerTestOneInput(const uint8_t * buf,size_t len)45 int FuzzerTestOneInput(const uint8_t *buf, size_t len)
46 {
47 int rc = 0;
48 QUIC_SRTM *srtm = NULL;
49 PACKET pkt;
50 unsigned int cmd;
51 uint64_t arg_opaque, arg_seq_num, arg_idx;
52 QUIC_STATELESS_RESET_TOKEN arg_token;
53 size_t limit = 0;
54
55 if ((srtm = ossl_quic_srtm_new(NULL, NULL)) == NULL) {
56 rc = -1;
57 goto err;
58 }
59
60 if (!PACKET_buf_init(&pkt, buf, len))
61 goto err;
62
63 while (PACKET_remaining(&pkt) > 0) {
64 if (!PACKET_get_1(&pkt, &cmd))
65 goto err;
66
67 if (++limit > MAX_CMDS) {
68 rc = 0;
69 goto err;
70 }
71
72 switch (cmd % CMD_MAX) {
73 case CMD_ADD:
74 if (!PACKET_get_net_8(&pkt, &arg_opaque)
75 || !PACKET_get_net_8(&pkt, &arg_seq_num)
76 || !PACKET_copy_bytes(&pkt, arg_token.token,
77 sizeof(arg_token.token)))
78 continue; /* just stop */
79
80 ossl_quic_srtm_add(srtm, (void *)(uintptr_t)arg_opaque,
81 arg_seq_num, &arg_token);
82 ossl_quic_srtm_check(srtm);
83 break;
84
85 case CMD_REMOVE:
86 if (!PACKET_get_net_8(&pkt, &arg_opaque)
87 || !PACKET_get_net_8(&pkt, &arg_seq_num))
88 continue; /* just stop */
89
90 ossl_quic_srtm_remove(srtm, (void *)(uintptr_t)arg_opaque,
91 arg_seq_num);
92 ossl_quic_srtm_check(srtm);
93 break;
94
95 case CMD_CULL:
96 if (!PACKET_get_net_8(&pkt, &arg_opaque))
97 continue; /* just stop */
98
99 ossl_quic_srtm_cull(srtm, (void *)(uintptr_t)arg_opaque);
100 ossl_quic_srtm_check(srtm);
101 break;
102
103 case CMD_LOOKUP:
104 if (!PACKET_copy_bytes(&pkt, arg_token.token,
105 sizeof(arg_token.token))
106 || !PACKET_get_net_8(&pkt, &arg_idx))
107 continue; /* just stop */
108
109 ossl_quic_srtm_lookup(srtm, &arg_token, (size_t)arg_idx,
110 NULL, NULL);
111 ossl_quic_srtm_check(srtm);
112 break;
113
114 default:
115 /* Other bytes are treated as no-ops */
116 continue;
117 }
118 }
119
120 rc = 0;
121 err:
122 ossl_quic_srtm_free(srtm);
123 return rc;
124 }
125
FuzzerCleanup(void)126 void FuzzerCleanup(void)
127 {
128 FuzzerClearRand();
129 }
130