xref: /openssl/fuzz/quic-srtm.c (revision 7ed6de99)
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