<?xml version="1.0" encoding="UTF-8"?>
<rfc
  ipr="trust200902"
  category="exp"
 
  submissionType="independent"
  docName="draft-maurette-hmtftp-00"
  version="3"
  xml:lang="en"
  xmlns:xi="http://www.w3.org/2001/XInclude">

  <front>
    <title abbrev="HMTFTP">HMTFTP - HMAC-based Trivial File Transfer Protocol (v0.1)</title>

    <author fullname="A. Maurette" initials="A." surname="Maurette">
      <organization>IUT R&amp;T Bethune</organization>
      <address>
        <email>contact@c4tz.fr</email>
      </address>
    </author>

    <date year="2025" month="December" day="19"/>

    <abstract>
      <t>HMTFTP (<xref target="RFC1350"/>) is a lightweight UDP file transfer protocol that preserves TFTP-style simplicity (block-and-ACK) while adding an optional authenticated encryption mode using AEAD AES-256-GCM with pre-shared keys derived via HKDF-SHA-256. The protocol targets managed environments (e.g., CPEs, OpenWrt, embedded devices) where provisioning and configuration have constrained requirements. This document specifies v0.1, including message formats, negotiation, cryptographic processing, timers, and security considerations.</t>
    </abstract>
  </front>

  <middle>

    <section anchor="intro" title="Introduction">
      <t>TFTP (<xref target="RFC1350"/>) is extremely simple but offers no security properties. HMTFTP v0.1 keeps UDP, a fixed header with TLVs, and a block-and-ACK transfer model, while introducing an optional AEAD protection based on a pre-shared key (PSK). The intended scope covers LAN or controlled networks, device provisioning, and small images/configurations.</t>
      <t>HMTFTP aims to remain comprehensible and implementable on constrained systems, reusing common cryptographic primitives and clear operational guidance. It is not meant to compete with secure, general-purpose transports such as TLS or QUIC (<xref target="RFC9000"/>), but to provide a small and deterministic surface fit for specific operational niches.</t>
    </section>

    <section anchor="conventions" title="Conventions and Terminology">
      <t>The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in <xref target="RFC2119"/> and <xref target="RFC8174"/> when, and only when, they appear in all capitals.</t>
      <t>Terminology: PSK - pre-shared key; AEAD - Authenticated Encryption with Associated Data; AAD - Additional Authenticated Data; CSPRNG - cryptographically secure pseudorandom number generator; PMTU - Path Maximum Transmission Unit.</t>
    </section>

    <section anchor="overview" title="Protocol Overview">
      <t>HMTFTP exchanges begin with a stateless discovery and capability exchange, followed by a transfer request and a TFTP-like data/acknowledgment loop. When encryption is negotiated, all DATA payloads are protected with AES-256-GCM and the header and TLVs are authenticated as AAD.</t>
      <t>Flow (happy path): HELLO -&gt; HELLO_ACK; NEGOTIATE -&gt; NEGOTIATE_ACK; XFER_REQ (GET or PUT) -&gt; DATA/ACK ... -&gt; EOF.</t>
      <t>Opcodes: HELLO(0), HELLO_ACK(1), NEGOTIATE(2), NEGOTIATE_ACK(3), DATA(4), ACK(5), ERROR(6 - reserved codes), XFER_REQ(7).</t>
      <t>TLVs (Type:Length): CNONCE(0x08,16), SNONCE(0x09,16), BLKSIZE(0x10,2), FNAME(0x20,var), MODE(0x21,1 - 1=PUT, 2=GET), ENC(0x22,1 - 1=request), CIPHER(0x23,1 - 1=AES-256-GCM). Additional TLVs MAY be defined; unknown TLVs MUST be ignored if the critical bit is not set.</t>
      <t>Default UDP port: user-configured (examples use 49696). BLKSIZE range: 64..4096 octets (default 512). EOF is signaled by a DATA block strictly shorter than BLKSIZE.</t>
    </section>

    <section anchor="wire" title="Wire Format">
      <t>All multi-octet fields use network byte order (big-endian). The fixed header is 24 octets:</t>
      <dl>
        <dt>Magic (16 bits)</dt><dd>0x484D ("HM").</dd>
        <dt>Ver (4) | Op (4)</dt><dd>Protocol version and opcode.</dd>
        <dt>Flags (8)</dt><dd>Bitmask; see below.</dd>
        <dt>Reserved (8)</dt><dd>MUST be zero.</dd>
        <dt>Pad (8)</dt><dd>MUST be zero.</dd>
        <dt>SessionID (32)</dt><dd>Chosen by the initiator.</dd>
        <dt>Seq (32)</dt><dd>Monotonically increasing data sequence starting at 0.</dd>
        <dt>Ack (32)</dt><dd>Last contiguous block received.</dd>
        <dt>HdrLen (16)</dt><dd>Length in octets of the TLV area following the header.</dd>
        <dt>PayLen (16)</dt><dd>Length in octets of the payload (ciphertext when ENC=1).</dd>
        <dt>Reserved2 (16)</dt><dd>MUST be zero.</dd>
      </dl>
      <t>Flags: 0x01 = TLVs present; 0x02 = ENCRYPTED. When ENCRYPTED=1, the GCM tag (16 octets) follows the payload.</t>
      <t>AAD: the AEAD AAD MUST cover the entire 24-octet fixed header, and in v0.1 also the TLV area (HdrLen octets).</t>

      <section anchor="tlv" title="TLV Encoding">
        <t>TLVs are encoded as Type(1), Length(1), Value(Length). Types are unsigned 8-bit; Length is unsigned 8-bit. Multi-octet values within TLVs are big-endian.</t>
      </section>
    </section>

    <section anchor="transport" title="Transport and PMTU">
      <t>HMTFTP runs over UDP/IPv4 (and MAY run over UDP/IPv6). The internal maximum datagram size is 4096 octets. To avoid IP fragmentation, BLKSIZE SHOULD be selected such that IP header + UDP header + HMTFTP header + TLVs + payload (+ tag if encrypted) remain within the PMTU.</t>
      <t>Implementations SHOULD follow <xref target="RFC8085"/> for UDP usage, and use <xref target="RFC1191"/> (IPv4) and <xref target="RFC8201"/> (IPv6) PMTU discovery or <xref target="RFC4821"/> PLPMTUD. Senders SHOULD react to ICMP Packet Too Big or retransmission timeouts by reducing BLKSIZE.</t>
      <t>Retransmissions: a sender maintains an RTO with exponential backoff. ACKs carry the last in-order block number; selective ACKs are out of scope for v0.1.</t>
    </section>

    <section anchor="crypto" title="Cryptographic Processing">
      <t>Material and inputs:</t>
      <ol>
        <li>PSK: 32 octets generated with at least 128 bits of entropy (preferably 256), stored with OS permissions 0400/0600.</li>
        <li>CNONCE and SNONCE: 16 octets each from a CSPRNG.</li>
        <li>HKDF-SHA-256 (<xref target="RFC5869"/>): IKM = PSK; salt = CNONCE || SNONCE (32 octets); info = "hmtftp v1 keys". Output: key (32) and iv_base (12). v0.1 uses iv_base[0..7] (8 octets) to build the IV.</li>
        <li>GCM IV construction: IV = iv_base[0..7] || seq_be32, totaling 12 octets. For a given key, key/IV pairs MUST be unique. Before seq wraps (2^32), a new session SHOULD be negotiated well in advance (for example at 2^24 blocks).</li>
        <li>AAD and tag: AAD is the 24-octet header and the TLV area (HdrLen). The GCM tag is 16 octets appended after the payload.</li>
        <li>Retransmissions: a given Seq MUST retransmit the exact same ciphertext and tag; an endpoint MUST NOT re-encrypt a modified payload under the same (key, IV).</li>
        <li>On AEAD failure: silently drop (no ERROR, no ACK) to avoid validity oracles.</li>
      </ol>

      <section anchor="cipher-negotiation" title="Cipher Negotiation">
        <t>The CIPHER TLV selects AEAD_AES_256_GCM when ENC is requested, as specified in <xref target="RFC5116"/>. Future ciphersuites MAY be registered; endpoints MUST ignore unknown ciphers when ENC is not requested.</t>
      </section>
    </section>

    <section anchor="xfer" title="Transfer Procedure">
      <t>XFER_REQ includes MODE (PUT or GET), FNAME, and optionally BLKSIZE, ENC, and CIPHER. The server replies with ACK(0) to confirm parameters or ERROR.</t>
      <t>Data blocks are numbered from 0. Each DATA carries the current Seq (block number) and PayLen up to BLKSIZE. The receiver sends ACK with Ack set to the highest contiguous block received. A block shorter than BLKSIZE indicates EOF.</t>
      <t>ERROR codes (non-exhaustive): 0x01 = Unsupported TLV; 0x02 = Invalid parameter; 0x03 = Access denied; 0x04 = Not found; 0x05 = Integrity failure; 0x06 = Internal error.</t>
    </section>

    <section anchor="ops" title="Operational Considerations">
      <t>Logging: Implementations SHOULD avoid logging keys, PSKs, and nonces. Logging of session identifiers, aggregate sizes, timing, negotiated parameters, and ciphersuite is RECOMMENDED.</t>
      <t>PSK lifecycle: PSKs MUST NOT be embedded in images or world-readable. Rotation policies SHOULD be in place; devices SHOULD provide out-of-band key provisioning.</t>
      <t>Amplification: Servers SHOULD cap the size of unauthenticated responses and MAY require a cookie mechanism for untrusted networks in future versions.</t>
    </section>

    <section anchor="security" title="Security Considerations">
      <t>Threat model includes passive observers (confidentiality), on-path adversaries (integrity, authenticity), off-path spoofers, DoS, and reflection/amplification. See <xref target="RFC3552"/> and <xref target="RFC4732"/>.</t>
      <t>No PFS: v0.1 uses only PSK and does not provide forward secrecy. A future extension may add PSK + ECDH.</t>
      <t>Replay and duplicates: receivers SHOULD de-duplicate on (SessionID, Seq). Anti-replay windows MAY be used; session lifetimes SHOULD be bounded.</t>
      <t>Downgrade: endpoints SHOULD reject negotiation that drops from ENC=1 to ENC=0 after initial agreement. A future KEY_CONFIRM message can strengthen this.</t>
      <t>Limits: Implementations MUST enforce AEAD usage limits and IV uniqueness. Resource caps SHOULD mitigate DoS. See also <xref target="RFC8452"/> for AEAD usage limits.</t>
    </section>

    <section anchor="iana" title="IANA Considerations">
      <t>This document has no IANA actions.</t>
      <t>See <xref target="RFC8126"/> for general IANA policy guidance if future code points are requested.</t>
    </section>

    <section anchor="testvectors" title="Appendix A: Informative Test Vectors">
      <t>Example (hex):</t>
      <ul>
        <li>PSK = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f</li>
        <li>CNONCE = 00112233445566778899aabbccddeeff</li>
        <li>SNONCE = 0102030405060708090a0b0c0d0e0f10</li>
        <li>HKDF-salt = CNONCE || SNONCE</li>
        <li>info = "hmtftp v1 keys"</li>
        <li>Derived key (32) and iv_base (12) - implementation-defined output for this example.</li>
      </ul>
    </section>

    <section anchor="acks" title="Acknowledgments">
      <t>The author thanks reviewers and operators for early feedback and implementation guidance.</t>
    </section>

  </middle>

  <back>
    <references>
      <name>Normative References</name>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5869.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5116.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8085.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1191.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8201.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4821.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3552.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml"/>
    </references>

    <references>
      <name>Informative References</name>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1350.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4732.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9000.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8452.xml"/>
    </references>
  </back>
</rfc>
