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 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 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 126 void FuzzerCleanup(void) 127 { 128 FuzzerClearRand(); 129 } 130