Files
libcoap/tests/oss-fuzz/oscore_decrypt_target.c
T

100 lines
3.3 KiB
C

#include "coap3/coap_internal.h"
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
coap_context_t *ctx;
coap_session_t *session = NULL;
coap_pdu_t *pdu = NULL, *decrypted = NULL;
coap_address_t addr;
size_t opt_len, encrypted_len;
uint16_t partial_iv_len, kid_context_len, kid_len;
uint8_t oscore_option[256];
static const char oscore_conf_str[] =
"master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
"master_salt,hex,\"9e7ca92223786340\"\n"
"sender_id,hex,\"\"\n"
"rfc8613_b_1_2,bool,false\n"
"recipient_id,hex,\"01\"\n";
if (size < 2)
return 0;
/* Initialize libcoap with OSCORE support */
coap_startup();
coap_set_log_level(COAP_LOG_ERR);
coap_str_const_t conf = { sizeof(oscore_conf_str) - 1, (const uint8_t *)oscore_conf_str };
coap_oscore_conf_t *oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
/* Stop transmission of any error packets */
coap_debug_set_packet_loss("50%");
coap_debug_set_packet_fail("100%");
/* Set up OSCORE context */
ctx = coap_new_context(NULL);
if (ctx && oscore_conf) {
if (coap_context_oscore_server(ctx, oscore_conf)) {
/* Create a new client session */
coap_address_init(&addr);
addr.size = sizeof(struct sockaddr_in);
addr.addr.sin.sin_family = AF_INET;
addr.addr.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.addr.sin.sin_port = htons(5683);
session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP);
/* Build PDU with OSCORE option and encrypted data from fuzzer data */
if (session) {
/* Calculate OSCORE option length based on RFC 8613 Section 6.1 */
partial_iv_len = data[0] & 0x7;
if (1UL + partial_iv_len >= size)
goto cleanup;
kid_context_len = data[0] & 0x10 ? 1 + data[1 + partial_iv_len] : 0;
/* Build option with KID forced to one byte to match recipient_id in oscore_conf_str */
kid_len = 1;
/* Include byte 0 in the length */
opt_len = 1 + partial_iv_len + kid_context_len + kid_len;
/* Max allowed option size is 256 */
if (opt_len >= sizeof(oscore_option) || opt_len > size)
goto cleanup;
memcpy(oscore_option, data, opt_len - 1);
oscore_option[opt_len - 1] = 0x01;
pdu = coap_pdu_init(COAP_MESSAGE_NON, COAP_REQUEST_CODE_GET,
coap_new_message_id(session), 256);
if (pdu) {
/* Add OSCORE option with KID fixed to 0x01 */
if (coap_add_option(pdu, COAP_OPTION_OSCORE, opt_len, oscore_option)) {
/* Add remaining data as encrypted payload (from after original option) */
encrypted_len = size - opt_len;
if (encrypted_len > 0) {
coap_add_data(pdu, encrypted_len, &data[opt_len]);
}
/* Test OSCORE decryption */
decrypted = coap_oscore_decrypt_pdu(session, pdu);
if (decrypted) {
coap_show_pdu(COAP_LOG_ERR, decrypted);
coap_delete_pdu(decrypted);
}
}
coap_delete_pdu(pdu);
}
cleanup:
coap_session_release(session);
}
}
} else if (oscore_conf) {
/* ctx creation failed, need to free oscore_conf */
coap_delete_oscore_conf(oscore_conf);
}
if (ctx)
coap_free_context(ctx);
coap_cleanup();
return 0;
}