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_lcidm.h" 16 #include "internal/packet.h" 17 18 int FuzzerInitialize(int *argc, char ***argv) 19 { 20 FuzzerSetRand(); 21 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL); 22 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); 23 ERR_clear_error(); 24 return 1; 25 } 26 27 /* 28 * Fuzzer input "protocol": 29 * Big endian 30 * u8(LCID length) 31 * Zero or more of: 32 * ENROL_ODCID u0(0x00) u64(opaque) u8(cidl):cid 33 * RETIRE_ODCID u8(0x01) u64(opaque) 34 * GENERATE_INITIAL u8(0x02) u64(opaque) 35 * GENERATE u8(0x03) u64(opaque) 36 * RETIRE u8(0x04) u64(opaque) u64(retire_prior_to) 37 * CULL u8(0x05) u64(opaque) 38 * LOOKUP u8(0x06) u8(cidl):cid 39 */ 40 41 enum { 42 CMD_ENROL_ODCID, 43 CMD_RETIRE_ODCID, 44 CMD_GENERATE_INITIAL, 45 CMD_GENERATE, 46 CMD_RETIRE, 47 CMD_CULL, 48 CMD_LOOKUP 49 }; 50 51 #define MAX_CMDS 10000 52 53 static int get_cid(PACKET *pkt, QUIC_CONN_ID *cid) 54 { 55 unsigned int cidl; 56 57 if (!PACKET_get_1(pkt, &cidl) 58 || cidl > QUIC_MAX_CONN_ID_LEN 59 || !PACKET_copy_bytes(pkt, cid->id, cidl)) 60 return 0; 61 62 cid->id_len = (unsigned char)cidl; 63 return 1; 64 } 65 66 int FuzzerTestOneInput(const uint8_t *buf, size_t len) 67 { 68 int rc = 0; 69 QUIC_LCIDM *lcidm = NULL; 70 PACKET pkt; 71 uint64_t arg_opaque, arg_retire_prior_to, seq_num_out; 72 unsigned int cmd, lcidl; 73 QUIC_CONN_ID arg_cid, cid_out; 74 OSSL_QUIC_FRAME_NEW_CONN_ID ncid_frame; 75 int did_retire; 76 void *opaque_out; 77 size_t limit = 0; 78 79 if (!PACKET_buf_init(&pkt, buf, len)) 80 goto err; 81 82 if (!PACKET_get_1(&pkt, &lcidl) 83 || lcidl > QUIC_MAX_CONN_ID_LEN) { 84 rc = -1; 85 goto err; 86 } 87 88 if ((lcidm = ossl_quic_lcidm_new(NULL, lcidl)) == NULL) { 89 rc = -1; 90 goto err; 91 } 92 93 while (PACKET_remaining(&pkt) > 0) { 94 if (!PACKET_get_1(&pkt, &cmd)) 95 goto err; 96 97 if (++limit > MAX_CMDS) 98 goto err; 99 100 switch (cmd) { 101 case CMD_ENROL_ODCID: 102 if (!PACKET_get_net_8(&pkt, &arg_opaque) 103 || !get_cid(&pkt, &arg_cid)) { 104 rc = -1; 105 goto err; 106 } 107 108 ossl_quic_lcidm_enrol_odcid(lcidm, (void *)(uintptr_t)arg_opaque, 109 &arg_cid); 110 break; 111 112 case CMD_RETIRE_ODCID: 113 if (!PACKET_get_net_8(&pkt, &arg_opaque)) { 114 rc = -1; 115 goto err; 116 } 117 118 ossl_quic_lcidm_retire_odcid(lcidm, (void *)(uintptr_t)arg_opaque); 119 break; 120 121 case CMD_GENERATE_INITIAL: 122 if (!PACKET_get_net_8(&pkt, &arg_opaque)) { 123 rc = -1; 124 goto err; 125 } 126 127 ossl_quic_lcidm_generate_initial(lcidm, (void *)(uintptr_t)arg_opaque, 128 &cid_out); 129 break; 130 131 case CMD_GENERATE: 132 if (!PACKET_get_net_8(&pkt, &arg_opaque)) { 133 rc = -1; 134 goto err; 135 } 136 137 ossl_quic_lcidm_generate(lcidm, (void *)(uintptr_t)arg_opaque, 138 &ncid_frame); 139 break; 140 141 case CMD_RETIRE: 142 if (!PACKET_get_net_8(&pkt, &arg_opaque) 143 || !PACKET_get_net_8(&pkt, &arg_retire_prior_to)) { 144 rc = -1; 145 goto err; 146 } 147 148 ossl_quic_lcidm_retire(lcidm, (void *)(uintptr_t)arg_opaque, 149 arg_retire_prior_to, 150 NULL, &cid_out, 151 &seq_num_out, &did_retire); 152 break; 153 154 case CMD_CULL: 155 if (!PACKET_get_net_8(&pkt, &arg_opaque)) { 156 rc = -1; 157 goto err; 158 } 159 160 ossl_quic_lcidm_cull(lcidm, (void *)(uintptr_t)arg_opaque); 161 break; 162 163 case CMD_LOOKUP: 164 if (!get_cid(&pkt, &arg_cid)) { 165 rc = -1; 166 goto err; 167 } 168 169 ossl_quic_lcidm_lookup(lcidm, &arg_cid, &seq_num_out, &opaque_out); 170 break; 171 172 default: 173 rc = -1; 174 goto err; 175 } 176 } 177 178 err: 179 ossl_quic_lcidm_free(lcidm); 180 return rc; 181 } 182 183 void FuzzerCleanup(void) 184 { 185 FuzzerClearRand(); 186 } 187