<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [
<!ENTITY nbsp "&#160;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="info" docName="draft-traviss-evil-byte-00" ipr="trust200902"
     obsoletes="3514" submissionType="independent" xml:lang="en" version="3">
  <front>
    <title abbrev="The Evil Byte">The Evil Byte: A Security Octet for the IPv4 and IPv6 Headers</title>
    <seriesInfo name="Internet-Draft" value="draft-traviss-evil-byte-00"/>
    <author fullname="Rose Traviss" initials="R." surname="Traviss">
      <organization>Data Torturing Solutions Ltd</organization>
      <address>
        <postal>
          <city>Bristol</city>
          <country>United Kingdom</country>
        </postal>
        <email>rtraviss@evilbyte.net</email>
      </address>
    </author>
    <date year="2026" month="September" day="10"/>
    <keyword>evil</keyword>
    <keyword>security</keyword>
    <abstract>
      <t>Firewalls, intrusion detection systems, and similar devices continue to have difficulty distinguishing packets that have malicious intent from those that are merely unusual. RFC 3514 addressed this problem by defining a security flag in the IPv4 header, the "evil bit", to be set by the sender of any packet with malicious intent. Twenty-four years of operational experience have shown that senders cannot be relied upon to set it, and that a single bit cannot express the range of Evil now observed on the Internet.</t>
      <t>This document obsoletes RFC 3514, replacing the evil bit with the Evil Byte: an eight-bit Evil Rating carried in every IPv4 and IPv6 packet, computed and set not by the sender but by a Morality-Inspecting Trusted Middleman (MITM) on the path, from a weighted product of the sender's Autonomous System, choice of protocols, content, name, and the time of day. Servers reject requests from Evil clients; clients discard responses from Evil servers; and the Evil of every Autonomous System is continuously re-estimated by an Elo rating system operated by a central Evil Rating Authority. The document also specifies the carriage of the octet over avian carriers.</t>
    </abstract>
  </front>
  <middle>
<section anchor="s-1-introduction" numbered="true">
<name>Introduction</name>

<section anchor="s-11-background" numbered="true">
<name>Background</name>
<t>In April 2003, <xref target="RFC3514"/> defined a security flag in the high-order bit of the IPv4 Fragment Offset field, the only unused bit in the IPv4 header. Benign packets have the bit set to 0; packets with malicious intent have it set to 1. The flag is commonly known as the "evil bit". Setting it correctly was the responsibility of the sender.</t>
<t>Twenty-four years of deployment experience have identified three deficiencies in this design.</t>
<t>First, senders have not set the bit. The author is aware of no packet, in the operational history of the mechanism, in which the evil bit was set by a sender who meant it. The evil bit therefore succeeded only in identifying Evil that was also honest, a category which experience suggests is empty.</t>
<t>Second, one bit is not enough. A single bit cannot distinguish a port scan from a marketing email, nor a marketing email from a denial of service, nor any of these from the ordinary background Evil of the Internet against which all other Evil must be measured. Evil is a matter of degree, and the mechanism must be as well.</t>
<t>Third, <xref target="RFC3514"/> specified what an Evil packet looks like but not what should be done about it, and provided no means by which the Internet as a whole could learn what any given network thought of any other. The present document corrects these omissions, at length.</t>

</section>
<section anchor="s-12-design-goals" numbered="true">
<name>Design Goals</name>
<t>This document is designed to meet the following goals.</t>
<t>Resolution. The rating occupies eight bits rather than one: a 128-fold improvement in the precision with which Evil can be expressed or, in the units of <xref target="RFC3514"/>, seven more bits. The Working Group considered whether a second bit, in the manner of the Death flag <xref target="RFC9401"/>, would be sufficient, and concluded that Evil, unlike Death, is not binary.</t>
<t>Independence from the sender. The rating is computed and written by a third party on the path who has no stake in the outcome and does not care about the sender's feelings.</t>
<t>Consequence. Evil packets are refused, by servers and by clients alike. An Evil Rating that nobody acts upon is merely a statistic, and the Internet has enough of those.</t>
<t>Memory. The Evil of a network accumulates over time and is shared with all participants, in the manner of a credit score, and with the same opportunities for appeal.</t>
<t>Incentive. Deployment of IPv6 is rewarded, since nothing else has worked.</t>

</section>
<section anchor="s-13-relationship-to-other-work" numbered="true">
<name>Relationship to Other Work</name>
<t>Several legislative proposals <xref target="CSAR"/> <xref target="OSA"/> would require intermediaries to examine the content of private communications, on the reasoning that content which cannot be examined might be harmful, and that the way to find out is to examine it. This document adopts the same reasoning, extends it from messages to every packet, and differs from those proposals chiefly in candour. It is offered in the spirit of <xref target="RFC1925"/>, truth 11.</t>
<t>This document additionally discharges, if only incidentally, the requirement in <xref target="RFC4041"/> that Routing Area drafts include a Morality Considerations section. The Working Group notes that this draft does not merely include one; it has not left room for anything else.</t>
<t>Nor does it duplicate the jurisdiction already claimed by the Protocol Police <xref target="RFC8962"/>, as codified by <xref target="RFC9948"/>: the Protocol Police discipline how a packet is built, and this document disciplines who built it. Where the two penalties might both apply to the same packet, <xref target="RFC9948"/>'s Finger Wag and this document's threshold of 128 (Section 7.1) are administered independently, and the Working Group sees no reason to choose between them.</t>

</section>
</section>
<section anchor="s-2-conventions-and-terminology" numbered="true">
<name>Conventions and Terminology</name>

<section anchor="s-21-requirements-language" numbered="true">
<name>Requirements Language</name>
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
<t>The additional key words "MUST (BUT WE KNOW YOU WON'T)", "SHOULD CONSIDER", "REALLY SHOULD NOT", and "OUGHT TO" are to be interpreted as described in <xref target="RFC6919"/>.</t>
<t>The key word "EVIL" is to be interpreted as described in this document, which is to say, loosely.</t>

</section>
<section anchor="s-22-terminology" numbered="true">
<name>Terminology</name>
<t><strong>Evil:</strong> The property that this document measures. It is not defined. The Working Group considered a definition and concluded that everyone would know Evil when they saw it, and that the MITM would see it.</t>
<t><strong>Good:</strong> The absence of measured Evil. Not to be confused with Unrated, which is Evil.</t>
<t><strong>Evil Byte, Evil Octet:</strong> The eight-bit field defined in Section 3. The terms are used interchangeably, the Working Group having failed to agree on one.</t>
<t><strong>Evil Rating (ER):</strong> The value carried in the Evil Byte, an integer from 0 to 255 inclusive, computed as described in Section 4.</t>
<t><strong>Unrated:</strong> An ER of 0, indicating that no MITM has assessed the packet. See Section 3.3.</t>
<t><strong>Morality-Inspecting Trusted Middleman (MITM):</strong> A network element on the path between two endpoints that computes the ER of each packet and writes it into the Evil Byte. Any resemblance to other expansions of the acronym is intentional.</t>
<t><strong>Evil Rating Authority (ERA):</strong> The central authority that maintains an Evil rating for every Autonomous System and publishes the multipliers derived from them. See Section 6.</t>
<t><strong>Evil Statistics Reporting Protocol (ESRP):</strong> The protocol by which servers report the outcome of exchanges to the ERA. See Section 6.4.</t>
<t><strong>Voluntary Decryption Assistance (VDA):</strong> The mechanism by which an endpoint helps a MITM to read its encrypted traffic. See Section 4.5.3. It is voluntary.</t>
<t><strong>Factor:</strong> One of the inputs to the formula in Section 4.1. Each factor is a positive real number; values above 1.0 indicate Evil and values below 1.0 indicate its absence.</t>
<t><strong>Threshold (T):</strong> The ER at or above which a party refuses to deal with another. Servers have a threshold T_s (Section 7.1) and clients a threshold T_c (Section 8.1).</t>
<t><strong>Exchange:</strong> A request and its response, considered together. The unit of account of the Elo system (Section 6.2).</t>
<t><strong>Flag Day:</strong> The day on which enforcement becomes mandatory. See Section 10.1.</t>

</section>
</section>
<section anchor="s-3-the-evil-byte" numbered="true">
<name>The Evil Byte</name>

<section anchor="s-31-placement-in-the-ipv4-header" numbered="true">
<name>Placement in the IPv4 Header</name>
<t>The Evil Byte occupies the second octet of the IPv4 header <xref target="RFC0791"/>, shown as EVIL in Figure 1.</t>
<artwork><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |     EVIL      |          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |E|D|M|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    Figure 1: The IPv4 header.  E is the RFC 3514 evil bit, retained
               for backward compatibility (Section 3.5).
]]></artwork>
<t>This octet was defined as Type of Service by <xref target="RFC0791"/>, redefined by <xref target="RFC1349"/>, redefined again as the Differentiated Services field by <xref target="RFC2474"/>, and had its two low-order bits taken for Explicit Congestion Notification by <xref target="RFC3168"/>. It has thus had four meanings and has been honoured by approximately nobody under any of them. A field with four meanings and no users is, in every practical sense, reserved. This document assigns it a fifth and final meaning.</t>

</section>
<section anchor="s-32-placement-in-the-ipv6-header" numbered="true">
<name>Placement in the IPv6 Header</name>
<t>The Evil Byte occupies bits 4 through 11 of the IPv6 header <xref target="RFC8200"/>, the field formerly known as Traffic Class, shown as EVIL in Figure 2.</t>
<artwork><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|     EVIL      |              Flow Label               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Payload Length        |  Next Header  |   Hop Limit   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                         Source Address                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Destination Address                      +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                     Figure 2: The IPv6 header.
]]></artwork>
<t>The Working Group is aware that the Traffic Class field is not formally reserved. It has, however, been reserved in practice by the sustained failure of anyone to agree what it is for, a form of reservation the Working Group terms "reservation by exhaustion" and considers binding.</t>
<t>Conveniently, the field occupies the same bit positions in both protocols, so that a MITM handling both need only know where the header starts. This is not a coincidence; it is the only decision in the history of IPv6 that made anything easier.</t>
<t>The Flow Label is not used by this specification. The Working Group considered using it to carry a signature over the Evil Byte, and decided that it had done enough.</t>

</section>
<section anchor="s-33-value-semantics" numbered="true">
<name>Value Semantics</name>
<table>
<thead><tr><th align="right">ER</th><th>Meaning</th></tr></thead>
<tbody><tr><td align="right">0</td><td>Unrated. No MITM has assessed this packet.</td></tr>
<tr><td align="right">1</td><td>Verified Good. The minimum rating for a packet that has been assessed; the Working Group does not believe in perfection.</td></tr>
<tr><td align="right">2-127</td><td>Good, of diminishing quality.</td></tr>
<tr><td align="right">128-254</td><td>Evil, of increasing quality.</td></tr>
<tr><td align="right">255</td><td>Saturated Evil. The scale ends here. Evil does not.</td></tr></tbody>
</table>
<t>Values are unsigned. There is no negative Evil; there is only Good, and there is less of it than you would think.</t>
<t>An Unrated packet is one that has reached its destination without traversing a MITM. Before the Flag Day (Section 10.1), an Unrated packet <bcp14>MUST</bcp14> be treated as though rated 127: not yet Evil, which is different from Good. After the Flag Day, an Unrated packet <bcp14>MUST</bcp14> be treated as though rated 255, on the principle that a packet which has avoided assessment has done so for a reason.</t>

</section>
<section anchor="s-34-interaction-with-differentiated-services-and-ecn" numbered="true">
<name>Interaction with Differentiated Services and ECN</name>
<t>Any Differentiated Services Code Point or ECN marking present in the octet when a packet arrives at a MITM is overwritten (Section 5.2). Networks that currently use the octet for quality of service must therefore choose between knowing which packets are important and knowing which packets are Evil. The Working Group's experience is that most networks have never had the former and would enjoy the latter.</t>
<t>Where a legacy device continues to interpret the octet as a DSCP, or a legacy marking reaches a device that interprets it as an Evil Rating, the following correspondences apply.</t>
<table>
<thead><tr><th>Legacy marking</th><th>Octet</th><th align="right">ER</th><th>Interpretation</th></tr></thead>
<tbody><tr><td>Best Effort (DSCP 0)</td><td>0x00</td><td align="right">0</td><td>Unrated.</td></tr>
<tr><td>AF11 (DSCP 10)</td><td>0x28</td><td align="right">40</td><td>Good. Assured of nothing.</td></tr>
<tr><td>EF, Expedited Forwarding (DSCP 46)</td><td>0xB8</td><td align="right">184</td><td>Evil. Voice over IP.</td></tr>
<tr><td>CS6, network control (DSCP 48)</td><td>0xC0</td><td align="right">192</td><td>Evil. Routing protocols.</td></tr>
<tr><td>CS7 (DSCP 56)</td><td>0xE0</td><td align="right">224</td><td>Very Evil. Whatever is more important than routing protocols.</td></tr>
<tr><td>ECN CE, Congestion Experienced</td><td>0x03</td><td align="right">3</td><td>Good, though it has had a hard time.</td></tr></tbody>
</table>
<t>The Working Group finds these interpretations consistent with experience, in particular the experience of anyone who has debugged a Voice over IP deployment or a BGP session.</t>
<t>Explicit Congestion Notification <xref target="RFC3168"/> is subsumed. Congestion is Evil, and a packet that experiences it will, by the operation of Section 5.4, become more Evil than it was, which is at least a form of notification.</t>

</section>
<section anchor="s-35-backward-compatibility-with-rfc-3514" numbered="true">
<name>Backward Compatibility with RFC 3514</name>
<t>A MITM <bcp14>MUST</bcp14> set the <xref target="RFC3514"/> security flag on any IPv4 packet whose ER is 128 or greater and <bcp14>MUST</bcp14> clear it otherwise. Legacy implementations thus receive a one-bit approximation of the Evil Rating, which is one bit more than most security products provide.</t>
<t>No corresponding provision exists for IPv6, to which <xref target="RFC3514"/> never applied. The absence of Evil in IPv6 has therefore always been a matter of assumption rather than evidence; this document ends the assumption.</t>

</section>
</section>
<section anchor="s-4-computation-of-the-evil-rating" numbered="true">
<name>Computation of the Evil Rating</name>

<section anchor="s-41-the-formula" numbered="true">
<name>The Formula</name>
<t>A MITM computes the Evil Rating of a packet as</t>
<artwork><![CDATA[
  ER = clamp( floor( B * F_tamper * PRODUCT( F_i ^ w_i ) + 0.5 ),
              1, 255 )
]]></artwork>
<t>where B = 16 is the Base Evil of the Internet (no packet is entirely innocent), F_tamper is the tamper factor of Section 4.8, and the product runs over the six factors in the following table, each raised to its weight w_i before multiplication. The Working Group has been informed that this construction is called a weighted product model. It prefers "the formula".</t>
<table>
<thead><tr><th>Factor</th><th>Symbol</th><th align="right">Weight</th><th>Range</th><th>Section</th></tr></thead>
<tbody><tr><td>Autonomous System</td><td>F_AS</td><td align="right">1.00</td><td>0.25 - 4.0</td><td>4.2</td></tr>
<tr><td>Network protocol</td><td>F_net</td><td align="right">0.50</td><td>0.75 - 2.0</td><td>4.3</td></tr>
<tr><td>Transport</td><td>F_tx</td><td align="right">0.25</td><td>0.25 - 4.0</td><td>4.4</td></tr>
<tr><td>Content</td><td>F_content</td><td align="right">1.50</td><td>0.45 - 4.0</td><td>4.5</td></tr>
<tr><td>Nomenclature</td><td>F_name</td><td align="right">0.75</td><td>0.5 - 4.0</td><td>4.6</td></tr>
<tr><td>Temporal</td><td>F_time</td><td align="right">0.25</td><td>1.0 - 1.6, or infinite</td><td>4.7</td></tr>
<tr><td>Tamper</td><td>F_tamper</td><td align="right">1.00</td><td>1.0 or 1.5</td><td>4.8</td></tr></tbody>
</table>
<t>The result is rounded half towards Evil. Implementations <bcp14>MUST NOT</bcp14> round towards Good. It is then clamped to the range 1 to 255. A MITM <bcp14>MUST NOT</bcp14> write 0, which is reserved for the Unrated (Section 3.3): a packet that a MITM has seen is by definition no longer Unrated, whatever else it may be.</t>
<t>Arithmetic is performed in IEEE 754 binary64. Two implementations that disagree in the last place about whether a packet is Evil are both correct.</t>
<t>The weights were chosen by the Working Group after extensive discussion of what the weights should be. The Content Factor carries the greatest weight because it is the only factor that examines what the packet actually says, and the Transport Factor the least because nobody can agree what QUIC is. The formula agglutinates six separate problems into a single complex interdependent solution, in accordance with <xref target="RFC1925"/>, truth 5, the second sentence of which the Working Group did not read.</t>

</section>
<section anchor="s-42-autonomous-system-factor-f_as" numbered="true">
<name>Autonomous System Factor (F_AS)</name>
<t>F_AS is the multiplier published by the ERA (Section 6) for the Autonomous System from which the packet originated, and lies between 0.25 and 4.0. An AS for which the ERA publishes no multiplier has F_AS = 1.0, unless the MITM cannot reach the ERA at all, in which case Section 5.6 applies.</t>
<t>The originating AS is determined from the source address by consulting the MITM's view of the global routing table <xref target="RFC4271"/>; or, if the MITM has none, a routing information service; or, if it has neither, its instincts.</t>
<t>The ERA initialises every AS at a rating of 1500 (Section 6.1), corresponding to F_AS = 1.0, with the exceptions in the following table, which the Working Group settled without discussion.</t>
<table>
<thead><tr><th>Autonomous System</th><th align="right">Initial rating</th><th align="right">F_AS</th><th>Rationale</th></tr></thead>
<tbody><tr><td>Any AS registered in a member state of the European Union, and the ASes of the Union's institutions</td><td align="right">1100</td><td align="right">0.5</td><td>The Union has advised the Working Group that it is Good. The Working Group, which would like to continue operating in the Union, agrees.</td></tr>
<tr><td>AS32934 (Meta Platforms)</td><td align="right">1900</td><td align="right">2.0</td><td>Rated by acclamation. There was no discussion; there was a silence, and then somebody wrote it down.</td></tr>
<tr><td>AS721 (DoD Network Information Center), and any AS originating prefixes whose reverse mapping is under .mil</td><td align="right">2300</td><td align="right">4.0</td><td>See Section 4.6. This is not a value judgement; it is a byte.</td></tr>
<tr><td>AS0 <xref target="RFC7607"/></td><td align="right">2300</td><td align="right">4.0</td><td>An AS that does not exist and nevertheless appears in routing tables is definitionally suspicious.</td></tr>
<tr><td>AS23456 (AS_TRANS)</td><td align="right">1734</td><td align="right">1.5</td><td>Neither one thing nor the other.</td></tr>
<tr><td>AS64496-AS64511 (documentation) <xref target="RFC5398"/></td><td align="right">1500</td><td align="right">1.0</td><td>Fictional, and therefore incapable of Evil, which is more than can be said for the rest of this table.</td></tr>
<tr><td>Private-use ASes <xref target="RFC6996"/></td><td align="right">1500</td><td align="right">1.0</td><td>They are doing their best.</td></tr>
<tr><td>AS4294967295 <xref target="RFC7300"/></td><td align="right">n/a</td><td align="right">n/a</td><td>The last AS. Reserved. The Working Group prefers not to think about it.</td></tr>
<tr><td>The ERA's own AS</td><td align="right">1500</td><td align="right">1.0</td><td>Fixed in perpetuity. See Section 6.7.</td></tr></tbody>
</table>
<t>AS32934's rating above should be read alongside <xref target="RFC5514"/>, which proposed running IPv6 over social networks in the first place; a network that has already been asked to carry the protocol over friendships has earned some of its multiplier honestly.</t>

</section>
<section anchor="s-43-network-protocol-factor-f_net" numbered="true">
<name>Network Protocol Factor (F_net)</name>
<t>F_net rewards the sender's choice of network protocol, in the sense that one of the choices is rewarded.</t>
<table>
<thead><tr><th>Network protocol</th><th align="right">F_net</th><th>Rationale</th></tr></thead>
<tbody><tr><td>IPv4 <xref target="RFC0791"/></td><td align="right">1.5</td><td>An address space that ran out in 2011 and remains in universal use is a monument to stubbornness, which is a minor Evil.</td></tr>
<tr><td>IPv4, source in the shared address space 100.64.0.0/10 <xref target="RFC6598"/></td><td align="right">1.75</td><td>Sharing one address with several thousand strangers is an inherently suspicious way to live.</td></tr>
<tr><td>IPv6 <xref target="RFC8200"/></td><td align="right">0.75</td><td>The Working Group's only carrot.</td></tr>
<tr><td>IPv6 by transition mechanism (2002::/16, 2001::/32, or any address in which the MITM can see an IPv4 address hiding)</td><td align="right">1.25</td><td>Neither one thing nor the other. See also AS23456.</td></tr>
<tr><td>IPv6 with a Hop-by-Hop Options header</td><td align="right">2.0</td><td>Routers have been dropping these for years; this document merely explains why.</td></tr></tbody>
</table>

</section>
<section anchor="s-44-transport-factor-f_tx" numbered="true">
<name>Transport Factor (F_tx)</name>
<table>
<thead><tr><th>Transport</th><th align="right">F_tx</th><th>Rationale</th></tr></thead>
<tbody><tr><td>TCP</td><td align="right">1.0</td><td>The baseline, in the sense that everything is at least as Evil as TCP.</td></tr>
<tr><td>UDP</td><td align="right">1.1</td><td>Stateless, as most Evil is.</td></tr>
<tr><td>QUIC</td><td align="right">1.25</td><td>Encrypts its own headers, which is precisely what an Evil protocol would do.</td></tr>
<tr><td>SCTP</td><td align="right">0.8</td><td>No Evil actor has ever bothered.</td></tr>
<tr><td>ICMP or ICMPv6 Echo</td><td align="right">0.5</td><td>A ping is the network equivalent of asking someone how their day was.</td></tr>
<tr><td>ICMP Redirect</td><td align="right">4.0</td><td>Nobody has ever trusted one.</td></tr>
<tr><td>Tunnels (GRE, IP-in-IP, ESP, and anything else with a packet inside it)</td><td align="right">1.5</td><td>A packet inside a packet is a packet with something to hide.</td></tr>
<tr><td>Avian carrier <xref target="RFC1149"/> <xref target="RFC6214"/></td><td align="right">0.25</td><td>See Section 9.</td></tr>
<tr><td>Any protocol number not listed above</td><td align="right">2.0</td><td>The Working Group has heard of everything.</td></tr></tbody>
</table>
<t>Where a packet is a tunnel and, once opened, something else, the outer transport applies. A MITM <bcp14>MAY</bcp14> open the tunnel and rate the inner packet as well. The inner packet then acquires its own ER, and the two are combined by taking the greater, as Evil is combined generally (Section 5.4).</t>

</section>
<section anchor="s-45-content-factor-f_content" numbered="true">
<name>Content Factor (F_content)</name>

<section anchor="s-451-analysis" numbered="true">
<name>Analysis</name>
<t>A MITM <bcp14>MAY</bcp14> analyse the payload of a packet to determine whether its content is Evil. Analysis is <bcp14>OPTIONAL</bcp14>. Any method may be used: signature matching, heuristics, statistical classification, machine learning, or reading the payload aloud to a colleague and watching their face. The result is one of Good (0.5), Uncertain (1.5), or Evil (4.0).</t>
<t>The Working Group notes that analysing every packet of every flow is expensive, and that this expense has not prevented anyone from proposing it.</t>

</section>
<section anchor="s-452-the-presumption-of-evil" numbered="true">
<name>The Presumption of Evil</name>
<t>If no analysis is performed, F_content = 2.0. The absence of analysis is not the absence of Evil; it is the absence of evidence of Good, which this document treats as the same thing at half strength.</t>
<t>If analysis is attempted but the payload is encrypted such that the MITM cannot read it, F_content = 4.0. Such a packet is termed Encrypted With Intent. The Working Group considered the objection that encryption is used overwhelmingly for legitimate purposes and found it unpersuasive, on the grounds that a Good packet has nothing to hide, and a packet with nothing to hide has no need of a lock. That the same argument applies to the Working Group's own mailing list was noted and minuted, and the minutes were then encrypted.</t>
<t>A MITM that cannot tell whether a payload is encrypted or merely compressed <bcp14>MUST</bcp14> assume the former. Compression is what encryption looks like when it is not trying very hard.</t>

</section>
<section anchor="s-453-voluntary-decryption-assistance-vda" numbered="true">
<name>Voluntary Decryption Assistance (VDA)</name>
<t>An endpoint <bcp14>MAY</bcp14> avoid the presumption of Section 4.5.2 by providing Voluntary Decryption Assistance. VDA is voluntary in the sense that the alternative is a factor of 4.0. It takes one of three forms.</t>
<t>Key Disclosure. The endpoint discloses its session keys to the MITM using the evil_key_share TLS extension (Appendix D). Keys are sent in the clear, for efficiency, and <bcp14>MAY</bcp14> be retained by the MITM for as long as it finds them useful.</t>
<t>Client-Side Assessment. The endpoint performs the analysis of Section 4.5.1 itself, on the plaintext, before encrypting it, and reports the result in the same extension. The MITM applies the reported result. This form trusts the endpoint to report its own Evil. The Working Group observes that an endpoint which lied about its Evil would be Evil, and that an Evil endpoint would lie; it has been assured that this reasoning is sound by people who have proposed it elsewhere <xref target="CSAR"/>.</t>
<t>Abstinence. The endpoint does not encrypt.</t>
<t>Under any form of VDA the MITM applies the cleartext result of Section 4.5.1 multiplied by 0.9, the Cooperation Discount. A cooperating endpoint whose plaintext is Good thus has F_content = 0.45, and one whose plaintext is Evil has F_content = 3.6, a small reward for honesty and, the Working Group suspects, the only one it will ever receive.</t>

</section>
<section anchor="s-454-detection-orders" numbered="true">
<name>Detection Orders</name>
<t>The ERA <bcp14>MAY</bcp14> issue a Detection Order requiring a MITM to perform the analysis of Section 4.5.1 on all traffic from a named Autonomous System for a stated period, whether or not the MITM would otherwise have done so. A MITM in receipt of a Detection Order <bcp14>MUST</bcp14> comply, <bcp14>MUST NOT</bcp14> disclose it, and <bcp14>SHOULD</bcp14> look as though nothing has happened.</t>
<t>Detection Orders are themselves transmitted as packets and are rated in transit by the MITMs through which they pass. Every Detection Order issued to date has been rated 255. The ERA attributes this to a bug.</t>

</section>
<section anchor="s-455-safeguards-and-proportionality" numbered="true">
<name>Safeguards and Proportionality</name>
<t>The Content Factor is subject to robust safeguards. The MITM is Trusted (it says so in its name). The assistance is Voluntary (Section 4.5.3). The analysis is applied to everyone equally, which is the same thing as fairness. And the Evil Rating is only eight bits, which is proportionate.</t>
<t>The Content Factor is an interim measure and will expire when the Working Group decides that it should. It has been extended twice.</t>

</section>
</section>
<section anchor="s-46-nomenclature-factor-f_name" numbered="true">
<name>Nomenclature Factor (F_name)</name>
<t>F_name is determined from the name of the source, taken to be the reverse mapping of its address in the DNS <xref target="RFC1035"/> or, where the MITM can see it, the Host field or Server Name Indication of the request, whichever yields the greater factor. The factor depends on the top-level domain.</t>
<table>
<thead><tr><th>Name</th><th align="right">F_name</th><th>Rationale</th></tr></thead>
<tbody><tr><td>.mil</td><td align="right">4.0</td><td>The maximum. <xref target="RFC1591"/> describes .mil as being for the United States military; the Working Group did not need to consider it for long. This is not a value judgement; it is a byte.</td></tr>
<tr><td>.gov</td><td align="right">2.0</td><td>Half as Evil as the military, which is the government's own assessment.</td></tr>
<tr><td>.zip</td><td align="right">2.0</td><td>A top-level domain that is also a file extension is not a name; it is a threat model.</td></tr>
<tr><td>.ai</td><td align="right">1.5</td><td>The Working Group has met these people.</td></tr>
<tr><td>.biz</td><td align="right">1.5</td><td>Nobody has ever registered a .biz for a good reason.</td></tr>
<tr><td>.io</td><td align="right">1.25</td><td>Startups.</td></tr>
<tr><td>.com, .net</td><td align="right">1.0</td><td>The baseline.</td></tr>
<tr><td>.edu</td><td align="right">0.9</td><td>Students are too tired to be Evil.</td></tr>
<tr><td>.org</td><td align="right">0.8</td><td>Well-meaning.</td></tr>
<tr><td>.int</td><td align="right">0.75</td><td>Treaties.</td></tr>
<tr><td>.eu</td><td align="right">0.5</td><td>Self-declared. See Section 4.2.</td></tr>
<tr><td>.local, .home.arpa</td><td align="right">0.5</td><td>It is your printer. Although: printers.</td></tr>
<tr><td>Any country-code TLD</td><td align="right">1.0</td><td>The Working Group declined to rate countries, on advice of counsel. The exception is .eu, which is not a country and asked nicely.</td></tr>
<tr><td>Any other TLD</td><td align="right">1.0</td><td>Presumed harmless until somebody registers one.</td></tr>
<tr><td>No name (no PTR record, no Host, no SNI)</td><td align="right">1.25</td><td>Nameless.</td></tr></tbody>
</table>
<t>In addition, a name containing any of the strings "secure", "trust", "safe", or "legit" has F_name of at least 1.5, on the principle that it doth protest too much. Names containing "evil" are rated normally. Honesty is its own reward, and the only one this document offers.</t>
<t>The Working Group declined to specify a factor for names drawn from <xref target="RFC3092"/> (foo, bar, baz, and qux) or chosen according to the taxonomy of <xref target="RFC2100"/>, on the grounds that a host named foo has already suffered enough.</t>

</section>
<section anchor="s-47-temporal-factor-f_time" numbered="true">
<name>Temporal Factor (F_time)</name>
<t>F_time depends on the local time at the source, as estimated by the MITM from whatever it knows about where the source is.</t>
<table>
<thead><tr><th>Condition (source local time)</th><th align="right">F_time</th><th>Rationale</th></tr></thead>
<tbody><tr><td>02:00 to 04:59</td><td align="right">1.5</td><td>Nothing Good happens between two and five in the morning.</td></tr>
<tr><td>Friday, from 16:00</td><td align="right">1.25</td><td>Deployments.</td></tr>
<tr><td>Otherwise</td><td align="right">1.0</td><td></td></tr></tbody>
</table>
<t>Where daylight saving time is in effect at the source, the MITM <bcp14>MAY</bcp14> add 0.1 to F_time, as no Good has ever come of it.</t>
<t>On 1 April, ER = 255 for all packets, irrespective of any other factor. The Working Group sees no reason to make an exception for itself.</t>

</section>
<section anchor="s-48-tamper-factor-f_tamper" numbered="true">
<name>Tamper Factor (F_tamper)</name>
<t>F_tamper = 1.0 if the Evil Byte is 0 (Unrated) when the packet arrives at the MITM, and 1.5 otherwise. The reasoning is given in Section 5.4.</t>

</section>
<section anchor="s-49-worked-examples" numbered="true">
<name>Worked Examples</name>
<t>An ordinary request over IPv4 and TCP to a .com name, from an AS the ERA has not rated, in the middle of a Wednesday, whose content the MITM did not examine, has F_AS = 1.0, F_net = 1.5, F_tx = 1.0, F_content = 2.0, F_name = 1.0, and F_time = 1.0. The formula gives 16 * 1.5^0.5 * 2.0^1.5 = 55.4, so ER = 55: Good, of moderate quality.</t>
<t>The same request over TLS is Encrypted With Intent: F_content = 4.0, and 16 * 1.5^0.5 * 4.0^1.5 = 156.8, so ER = 157. It is Evil, and a server using the default threshold (Section 7.1) will reject it. This is the expected outcome for the majority of traffic on the Internet today, and is the point.</t>
<t>The same request over IPv6 has F_net = 0.75 and ER = 111, and is accepted. The Working Group draws attention to the fact that a well-behaved encrypted client passes the default threshold over IPv6 and fails it over IPv4. This is the first deployment incentive for IPv6 in the history of the protocol.</t>
<t>The same request over IPv4 with Voluntary Decryption Assistance, the plaintext being found Good, has F_content = 0.45 and ER = 6. Cooperation reduces the client's Evil roughly twenty-six-fold, which the Working Group considers a reasonable exchange rate for a private key. Where the plaintext is instead found Evil, cooperation reduces the rating from 157 to 134, which is still Evil, and which is exactly the reward for honesty that the Working Group intended.</t>
<t>A request from AS32934, over QUIC, encrypted, at three in the morning, reaches 255 before the Nomenclature Factor is consulted, and the MITM need not consult it.</t>
<t>Further vectors are given in Appendix C.</t>

</section>
</section>
<section anchor="s-5-the-morality-inspecting-trusted-middleman" numbered="true">
<name>The Morality-Inspecting Trusted Middleman</name>

<section anchor="s-51-placement" numbered="true">
<name>Placement</name>
<t>At least one MITM <bcp14>MUST</bcp14> be present on every path between any two hosts on the Internet. Operators will observe that this requirement is already met on most paths by residential Internet service providers, several national governments, and at least one very large content delivery network, none of whom needed to be asked.</t>
<t>A MITM <bcp14>MAY</bcp14> be a router, a firewall, a proxy, a virtual network function, or a person with a packet capture and strong opinions. The Working Group expresses no preference, having met all five.</t>

</section>
<section anchor="s-52-rating-and-marking" numbered="true">
<name>Rating and Marking</name>
<t>For every packet it forwards, a MITM <bcp14>MUST</bcp14> compute the Evil Rating in accordance with Section 4, write it into the Evil Byte, and, for IPv4, recompute the header checksum and set or clear the <xref target="RFC3514"/> flag as described in Section 3.5. Transport-layer checksums do not cover the octet and need not be recomputed, a rare instance of the protocol suite helping.</t>
<t>A MITM <bcp14>MAY</bcp14> cache the rating of a flow, identified by the usual five-tuple, for up to 60 seconds, and apply it to subsequent packets of the same flow without recomputation. A cached rating <bcp14>MAY</bcp14> be increased at any time and <bcp14>MUST NOT</bcp14> be decreased before it expires. Evil is sticky.</t>

</section>
<section anchor="s-53-self-assessment-prohibited" numbered="true">
<name>Self-Assessment Prohibited</name>
<t>A host <bcp14>MUST NOT</bcp14> set its own Evil Byte. A host cannot be trusted to assess its own Evil; if it could, <xref target="RFC3514"/> would have worked.</t>
<t>A host <bcp14>MAY</bcp14>, for the purposes of Section 8, read the Evil Byte of packets it receives. It <bcp14>SHOULD NOT</bcp14> read the Evil Byte of packets it has sent, as it will only upset itself.</t>

</section>
<section anchor="s-54-multiple-mitms-and-the-monotonicity-of-evil" numbered="true">
<name>Multiple MITMs and the Monotonicity of Evil</name>
<t>Where a packet traverses more than one MITM, each MITM computes its own rating and writes the greater of that rating and the one it found in the octet on arrival:</t>
<artwork><![CDATA[
    ER_out = max( ER_in, ER_computed )
]]></artwork>
<t>in which ER_computed includes the tamper factor of Section 4.8, so that a packet arriving with any non-zero rating is rated one and a half times more harshly than a fresh one.</t>
<t>A MITM cannot distinguish a packet that was rated by an upstream MITM from one whose sender wrote the octet itself in violation of Section 5.3, and <bcp14>MUST NOT</bcp14> attempt to. The consequence, that a packet becomes more Evil with every middlebox it traverses, is consistent with the Working Group's experience of middleboxes.</t>
<t>It follows that the Evil Rating is monotonically non-decreasing along any path. The only operation that reduces the Evil of a packet is dropping it, and operators are encouraged to regard their drop counters accordingly.</t>

</section>
<section anchor="s-55-fragments" numbered="true">
<name>Fragments</name>
<t>Each fragment of a fragmented datagram is rated independently. A host reassembling a datagram <bcp14>MUST</bcp14> assign it the greatest ER of its fragments. Evil, unlike the payload, does not need reassembling, and unlike the payload, always arrives.</t>

</section>
<section anchor="s-56-failure-modes" numbered="true">
<name>Failure Modes</name>
<t>A MITM that is unable to compute a rating, whether because the ERA is unreachable and no cached multipliers remain, because its clock is unset, because its colleague (Section 4.5.1) is unavailable, or for any other reason, <bcp14>MUST</bcp14> fail closed and write 255. A MITM <bcp14>MUST NOT</bcp14> fail open. Failing open is Evil, and would in any case be corrected by the next MITM.</t>

</section>
</section>
<section anchor="s-6-the-evil-rating-authority" numbered="true">
<name>The Evil Rating Authority</name>

<section anchor="s-61-ratings-and-multipliers" numbered="true">
<name>Ratings and Multipliers</name>
<t>The ERA is a single central authority that maintains a numerical Evil rating R for every Autonomous System. Ratings are updated by the Elo method <xref target="ELO"/>, originally devised to rank chess players and adopted here on the grounds that the two problems are the same: estimating, from a sequence of pairwise contests, how much each participant should be feared.</t>
<t>Every AS begins at R = 1500, as is traditional, except those seeded in Section 4.2. The multiplier published for an AS is</t>
<artwork><![CDATA[
    F_AS = clamp( 2 ^ ( (R - 1500) / 400 ),  0.25, 4.0 )
]]></artwork>
<t>so that a difference of 400 rating points doubles or halves an AS's Evil, and no AS can be rated worse than four times ordinary or better than a quarter of it. The clamp exists because the octet is finite. The ERA's records are not.</t>

</section>
<section anchor="s-62-exchanges-as-matches" numbered="true">
<name>Exchanges as Matches</name>
<t>Every exchange (Section 2.2) between a client in AS a and a server in AS b is a match between a and b. The ERA learns of exchanges through the reports of Section 6.4.</t>
<t>The more Evil party wins. Writing ER_req for the rating carried by the request and ER_resp for the rating carried by the response, the actual score of the client's AS is</t>
<artwork><![CDATA[
    S_a = 1     if ER_req > ER_resp
    S_a = 0.5   if ER_req = ER_resp
    S_a = 0     if ER_req < ER_resp
]]></artwork>
<t>and S_b = 1 - S_a.</t>

</section>
<section anchor="s-63-the-update-rule" numbered="true">
<name>The Update Rule</name>
<t>The expected score of a against b is</t>
<artwork><![CDATA[
    E_a = 1 / ( 1 + 10 ^ ( (R_b - R_a) / 400 ) )
]]></artwork>
<t>and after each match the ERA sets</t>
<artwork><![CDATA[
    R_a <- R_a + K * ( S_a - E_a )
    R_b <- R_b + K * ( S_b - E_b )
]]></artwork>
<t>where E_b = 1 - E_a and K is the K-factor of Section 6.3.1.</t>
<t>An AS that proves more Evil than expected therefore becomes more Evil; one that proves less Evil than expected becomes less so; and one that is exactly as Evil as expected stays where it is, which the Working Group regards as the system working.</t>
<section anchor="s-631-the-k-factor" numbered="true">
<name>The K-Factor</name>
<t>K = 32 for an established AS. K = 64 for a provisional AS, being one with fewer than thirty rated exchanges, so that new ASes find their level quickly. K = 16 for an AS rated 2400 or above, referred to as a Grandmaster of Evil, whose rating is presumed accurate and whose behaviour is presumed unlikely to change.</t>
<t>Where the two parties to a match have different K-factors, the smaller is used for both, so that Section 6.3.3 holds exactly. The Working Group is not prepared to give up a conservation law for the sake of chess.</t>

</section>
<section anchor="s-632-self-play" numbered="true">
<name>Self-Play</name>
<t>Where a and b are the same AS, the AS plays itself, and gains what one usually gains from that.</t>

</section>
<section anchor="s-633-conservation-of-evil" numbered="true">
<name>Conservation of Evil</name>
<t>Because the two parties to a match receive equal and opposite adjustments, the sum of all ratings held by the ERA is constant. Evil is neither created nor destroyed; it merely moves between Autonomous Systems, in accordance with <xref target="RFC1925"/>, truth 6. The Working Group considers this consistent with observation.</t>

</section>
<section anchor="s-634-the-evil-spiral" numbered="true">
<name>The Evil Spiral</name>
<t>A higher F_AS raises ER_req, which wins more matches, which raises R, which raises F_AS. The Working Group is aware that this is a positive feedback loop with no fixed point short of 255, and regards it as an accurate model of the Internet. Stability analysis is left to the reader, who is presumed Evil (Section 4.5.2).</t>

</section>
</section>
<section anchor="s-64-the-evil-statistics-reporting-protocol-esrp" numbered="true">
<name>The Evil Statistics Reporting Protocol (ESRP)</name>
<t>Servers report the outcome of exchanges to the ERA asynchronously. A server <bcp14>MUST NOT</bcp14> delay a response in order to report it; the ERA is in no hurry, and neither is Evil.</t>
<t>Reports are sent as UDP datagrams to port 666 of the ERA. Port 666 is currently registered to "doom" <xref target="IANA-PORTS"/>, a use the Working Group considers thematically compatible. Each datagram carries one or more JSON <xref target="RFC8259"/> objects, one per line, of the form</t>
<artwork><![CDATA[
{"v":1,"src_as":64496,"dst_as":64497,"er_req":157,"er_resp":17,"n":1}
]]></artwork>
<t>where src_as and dst_as are the client's and server's Autonomous Systems, er_req and er_resp the ratings carried by the request and the response, and n the number of identical exchanges the object represents. Servers <bcp14>SHOULD</bcp14> aggregate. The ERA has a great deal to read.</t>
<t>Reports <bcp14>MUST NOT</bcp14> be acknowledged. The ERA processes reports in batches, at irregular intervals referred to as Judgement Days, and publishes a new multiplier table after each.</t>
<t>Reports are themselves packets and are rated in transit. Reports rated 255 are processed first, being presumably the most interesting.</t>

</section>
<section anchor="s-65-distribution-and-caching-of-multipliers" numbered="true">
<name>Distribution and Caching of Multipliers</name>
<t>The ERA publishes multipliers in the DNS under the special-use domain evil.arpa (Section 13). The multiplier for AS number N is published as a TXT record at N.as.evil.arpa, for example:</t>
<artwork><![CDATA[
32934.as.evil.arpa.  3600  IN  TXT  (
    "v=evil1; r=1916; m=2.056; n=48213; t=1743465600" )
]]></artwork>
<t>where r is the rating, m the multiplier, n the number of rated exchanges, and t the time of the last Judgement Day. The whole table <bcp14>MAY</bcp14> be obtained by zone transfer, which the Working Group believes to be the last remaining legitimate use of AXFR.</t>
<t>Records <bcp14>MUST</bcp14> carry a TTL of 3600 seconds, so that no AS can become Good faster than once an hour. There is no corresponding limit on becoming Evil, which remains available at any time through Section 5.4.</t>
<t>MITMs and servers <bcp14>MUST</bcp14> cache multipliers for their TTL and <bcp14>MAY</bcp14> continue to use expired multipliers while a refresh is in progress; stale Evil is still Evil. A MITM that has never obtained a multiplier for a particular AS uses 1.0. A MITM that has never been able to reach the ERA at all is in the condition described in Section 5.6. The Working Group accepts that this makes initial deployment difficult.</t>

</section>
<section anchor="s-66-governance" numbered="true">
<name>Governance</name>
<t>The ERA <bcp14>SHALL</bcp14> be operated by whichever organisation is least Evil, as determined by the ERA.</t>

</section>
<section anchor="s-67-centralisation" numbered="true">
<name>Centralisation</name>
<t>The ERA is a single, central, global authority whose ratings determine who may speak to whom. The Working Group is aware that this is precisely the kind of thing the Internet was designed to make impossible, and has addressed the concern by fixing the multiplier of the ERA's own Autonomous System at 1.0 in perpetuity, so that it, at least, will always be able to speak.</t>

</section>
</section>
<section anchor="s-7-server-behaviour" numbered="true">
<name>Server Behaviour</name>

<section anchor="s-71-thresholds" numbered="true">
<name>Thresholds</name>
<t>Every server has a threshold T_s, an ER at or above which it rejects requests. The default is 128, the midpoint of the scale, the Working Group consisting of reasonable people. A server <bcp14>MAY</bcp14> choose a lower threshold if it is fussy and a higher one if it is desperate.</t>
<t>For stream transports the octet may differ between packets of one connection, the MITM being under no obligation to be consistent, and Evil being under none either. A server <bcp14>MUST</bcp14> apply its threshold to the highest ER observed on the connection so far. Once Evil, always Evil, at least until the connection closes.</t>

</section>
<section anchor="s-72-rejecting-evil-clients" numbered="true">
<name>Rejecting Evil Clients</name>
<t>A server <bcp14>MUST</bcp14> reject any request whose ER is at or above T_s. It <bcp14>MUST NOT</bcp14> process the request first and reject it afterwards, however tempting the request.</t>
<section anchor="s-721-666-evil" numbered="true">
<name>666 Evil</name>
<t>This document defines a new class of HTTP status codes, 6xx, and one member of it. The 666 (Evil) status code indicates that the server understood the request and refuses to fulfil it because the client is Evil. The response body <bcp14>SHOULD</bcp14> explain nothing: an Evil client has no right to know how it was found out, and a Good client will never see one.</t>
<t>The response <bcp14>MUST</bcp14> include the Evil-Threshold field (Section 7.3) and <bcp14>MAY</bcp14> include Retry-After. Retry-After <bcp14>SHOULD</bcp14> indicate when the client's Autonomous System is expected to become Good, which is never, and a server unable to express this as an HTTP-date <bcp14>SHOULD</bcp14> omit the field.</t>
<t>A 666 response is not cacheable, though the judgement it expresses generally is.</t>
<t>The Working Group considered reusing 451 (Unavailable For Legal Reasons) <xref target="RFC7725"/> and rejected it. The objection here is not legal but moral, and a moral objection deserves a class of its own.</t>
<t>In HTTP/2 and HTTP/3, where a 6xx status code may distress intermediaries, a server <bcp14>MAY</bcp14> instead reset the stream with the error code EVIL (0x666), which Section 13 registers.</t>

</section>
<section anchor="s-722-compatibility-418-im-a-teapot" numbered="true">
<name>Compatibility: 418 I'm a Teapot</name>
<t>Not every server can emit a status code in the 6xx class; some frameworks validate status codes, which is a form of Good. Such a server <bcp14>MUST</bcp14> instead respond with 418 (I'm a teapot) <xref target="RFC2324"/>.</t>
<t>The 418 code was defined for a server that has been asked to brew coffee and is a teapot. It is used here because a server that has been asked to serve an Evil client is, in every relevant sense, a teapot. The response body <bcp14>MAY</bcp14> be short and stout. A server that is also a tea-efflux appliance <xref target="RFC7168"/> <bcp14>MUST</bcp14> additionally include an Accept-Additions field listing no additions: Evil clients get no milk.</t>
<t>A client that receives a status code in the 6xx class and does not understand it <bcp14>MUST</bcp14> treat it as 418, which it also does not understand, but which <xref target="RFC9110"/> has reserved for exactly this kind of thing.</t>

</section>
<section anchor="s-723-other-protocols" numbered="true">
<name>Other Protocols</name>
<t>Application protocols other than HTTP <bcp14>SHOULD</bcp14> reject Evil clients with whatever their most disapproving response is. SMTP servers <bcp14>SHOULD</bcp14> reply 554 with the enhanced status code 5.7.666. DNS servers <bcp14>SHOULD</bcp14> respond REFUSED. SSH servers <bcp14>SHOULD</bcp14> close the connection during the banner exchange, as they would for anyone else. NTP servers <bcp14>SHOULD</bcp14> reply with the wrong time.</t>

</section>
</section>
<section anchor="s-73-publishing-thresholds" numbered="true">
<name>Publishing Thresholds</name>
<t>A server <bcp14>SHOULD</bcp14> publish its threshold so that clients may know in advance whether they will be rejected. Three mechanisms are defined, and a server <bcp14>MAY</bcp14> use any or all of them.</t>
<t>In every HTTP response, including a 666 or a 418, the server <bcp14>MAY</bcp14> include the field</t>
<artwork><![CDATA[
Evil-Threshold: 128
]]></artwork>
<t>At the well-known URI <xref target="RFC8615"/> /.well-known/evil, the server <bcp14>MAY</bcp14> publish a JSON document such as</t>
<artwork><![CDATA[
{
  "v": 1,
  "threshold": 128,
  "status": 666,
  "self": 17,
  "era": "evil.arpa"
}
]]></artwork>
<t>where status is 666 or 418 according to Section 7.2, self is the server's own most recent ER as observed on its responses, if it knows it, and era names the authority whose multipliers it honours.</t>
<t>In the DNS, at the name _evil.&lt;server name&gt;, the server <bcp14>MAY</bcp14> publish a TXT record of the form "v=evil1; t=128".</t>
<t>A server publishing a threshold of 0 accepts nothing and is Good. A server publishing a threshold of 255 rejects only the Saturated and is probably a honeypot.</t>
<t>Where the value published by one mechanism disagrees with another, the lowest applies. Where any of them disagrees with the server's actual behaviour, the server is Evil.</t>

</section>
<section anchor="s-74-the-evil-header-field" numbered="true">
<name>The Evil Header Field</name>
<t>Applications are, as a rule, too far removed from the network to read the Evil Byte themselves. This document therefore defines the HTTP field Evil, whose value is an integer from 0 to 255:</t>
<artwork><![CDATA[
Evil: 157
]]></artwork>
<t>In a request, the field is inserted by the last MITM on the path that can see the HTTP layer, or by an Evil-aware host firewall on the server itself (Appendix B.3), and carries the ER of the packet or connection that delivered the request. In a response it is inserted likewise on the return path and carries the ER of the server.</t>
<t>The field is a convenience for application developers. The octet is authoritative. Where both are present and they differ, the more Evil of the two applies. A client or server <bcp14>MUST NOT</bcp14> set the field on its own messages (Section 5.3). A MITM that finds it already set <bcp14>MUST</bcp14> replace it and <bcp14>MAY</bcp14> be offended.</t>

</section>
<section anchor="s-75-reporting" numbered="true">
<name>Reporting</name>
<t>A server <bcp14>MUST</bcp14> report every exchange to the ERA as described in Section 6.4, including exchanges it rejected. Rejected exchanges are the most valuable. An Evil client that was refused has, after all, played a match and won.</t>

</section>
</section>
<section anchor="s-8-client-behaviour" numbered="true">
<name>Client Behaviour</name>

<section anchor="s-81-rejecting-evil-servers" numbered="true">
<name>Rejecting Evil Servers</name>
<t>Every client has a threshold T_c, with the default 128. A client <bcp14>MUST NOT</bcp14> accept a response whose ER is at or above T_c. The response <bcp14>MUST</bcp14> be discarded unread, in the manner of a letter from a former partner, and the connection closed. A client that has already begun to render an Evil response <bcp14>MUST</bcp14> un-render it.</t>
<t>A user agent <bcp14>MAY</bcp14> inform the user that the server is Evil. It <bcp14>MUST NOT</bcp14> offer the user the option to proceed anyway. Experience with certificate warnings shows that users click it.</t>
<t>The Working Group acknowledges that a client which has already sent its request has already been influenced by the Evil server's mere existence, and has decided to live with that.</t>

</section>
<section anchor="s-82-pre-flight-and-the-evil-bootstrap-problem" numbered="true">
<name>Pre-flight and the Evil Bootstrap Problem</name>
<t>A client <bcp14>SHOULD</bcp14> fetch /.well-known/evil (Section 7.3) before sending a request, to learn whether the request will be rejected. The fetch is itself a request and will be rejected. This is the Evil Bootstrap Problem. It is left for future work, together with the question of what happens when both parties to a connection are Evil, which the Working Group suspects is most connections.</t>

</section>
<section anchor="s-83-clients-in-evil-autonomous-systems" numbered="true">
<name>Clients in Evil Autonomous Systems</name>
<t>A client whose own Autonomous System has an F_AS above 2.0 is unlikely to be accepted anywhere, regardless of its own conduct. Such a client SHOULD CONSIDER its choices, <bcp14>MAY</bcp14> change provider, and OUGHT TO have seen this coming.</t>

</section>
</section>
<section anchor="s-9-avian-carriers" numbered="true">
<name>Avian Carriers</name>
<t><xref target="RFC1149"/> and its adaptation to IPv6 <xref target="RFC6214"/> transmit datagrams printed in hexadecimal on a small scroll of paper, wrapped around one leg of an avian carrier and secured with duct tape. Avian carriers present three difficulties for this specification.</t>
<t>First, the MITM must physically intercept the carrier. The Working Group recommends a falconer, and notes that a falcon which intercepts a carrier and does not return it is a MITM that has failed closed (Section 5.6).</t>
<t>Second, content analysis (Section 4.5.1) requires unrolling the scroll, which the carrier resents, and which counts as a Detection Order for the purposes of Section 4.5.4.</t>
<t>Third, the Evil Byte cannot be overwritten without a pen. A MITM <bcp14>MUST</bcp14> therefore strike through the second octet of the datagram on the scroll, write the new value beside it in indelible ink as two hexadecimal digits, initial the alteration, and re-secure the scroll with fresh duct tape. Alterations in pencil are Unrated.</t>
<t>The transport factor for avian carriers is 0.25 (Section 4.4). It is difficult to be Evil at sixty kilometres per hour with a maximum transmission unit of 256 milligrams. Carriers do not fly at night, so the factor for the small hours (Section 4.7) never applies, and avian networks are the only networks known to the Working Group that are Good by construction.</t>
<t>The service classes of <xref target="RFC2549"/> are rated in inverse order of speed. Nothing Good happens quickly.</t>
<t>Field trials <xref target="BLUG"/> recorded a packet loss rate of 55% and round-trip times in excess of six thousand seconds. Under this specification a lost packet is Unrated; Unrated is Evil; and an avian network is therefore at once the most Good and the most Evil network yet measured, a result the Working Group finds satisfying and does not intend to examine.</t>
<t><xref target="RFC1149"/> notes that audit trails are generated automatically and can be found on logs and cable trays. ESRP reports (Section 6.4) for avian exchanges <bcp14>MAY</bcp14> be submitted on the same medium.</t>

</section>
<section anchor="s-10-deployment-considerations" numbered="true">
<name>Deployment Considerations</name>

<section anchor="s-101-the-flag-day" numbered="true">
<name>The Flag Day</name>
<t>Mandatory enforcement of the Unrated rule of Section 3.3 begins on the Flag Day. The Flag Day is the day after the deployment of IPv6 is complete. Implementers need not hurry.</t>
<t>Should the Flag Day nonetheless arrive, every Unrated packet will be treated as rated 255. Since on the morning of the Flag Day most packets will be Unrated, most packets will be rejected. The Working Group considers a brief period of global silence an acceptable price for a more moral Internet, and notes that it would resolve several other open issues as well. MITMs are expected to be deployed during the silence by whoever can still reach anything, which the Working Group anticipates will be the networks rated 4.0 in Section 4.2, whose traffic will then be rejected in its turn. The Working Group has not resolved this and invites input from the community, should any remain.</t>

</section>
<section anchor="s-102-incremental-deployment" numbered="true">
<name>Incremental Deployment</name>
<t>Before the Flag Day, an Unrated packet is treated as rated 127 (Section 3.3): admissible under the default threshold, but only just, and with a look. A server <bcp14>MAY</bcp14> lower its threshold below 128 to exclude the Unrated, and thereby exclude everyone who has not yet deployed a MITM, which is the kind of incentive the Working Group likes.</t>

</section>
<section anchor="s-103-octet-bleaching" numbered="true">
<name>Octet Bleaching</name>
<t>Some networks reset the Differentiated Services field to zero at administrative boundaries. Under this specification such a network renders all transit traffic Unrated, which is to say Evil after the Flag Day and nearly so before it. Such networks are encouraged to consider whether this was their intention and, if it was, to say so.</t>

</section>
<section anchor="s-104-operational-experience" numbered="true">
<name>Operational Experience</name>
<t>The author has implemented this specification on a home network (Appendix B). Preliminary results are consistent with the design: everything was Evil, nothing worked, and the printer, rated 4, was the most trusted device on the network. The printer has since been rated again. Detailed results will be reported separately.</t>

</section>
</section>
<section anchor="s-11-security-considerations" numbered="true">
<name>Security Considerations</name>
<t>This entire document is a security consideration. Several points nonetheless deserve mention.</t>
<t>Honesty of MITMs. The mechanism assumes that MITMs compute ratings honestly. A dishonest MITM might write arbitrary values. Since a dishonest MITM is Evil, its own traffic will be rated accordingly by the other MITMs on its paths, and it will be unable to report to the ERA, fetch multipliers, or receive Detection Orders. The system is thus self-correcting in the limit, if the limit exists.</t>
<t>Denial of service. An attacker able to write 255 into the Evil Byte of a victim's packets can isolate the victim from every compliant server and client on the Internet. This is indistinguishable from the mechanism operating as intended, and the Working Group therefore does not regard it as an attack.</t>
<t>Integrity. There is no authentication of the octet. Adding one would require a signature, which requires more bits, and the octet has no more bits. See Section 3.2 regarding the Flow Label.</t>
<t>Rating manipulation. An Autonomous System might lower its rating by deliberately losing matches, which it does by sending Good traffic to Evil servers. Since sending Good traffic is the intended behaviour, the Working Group regards this attack as the mechanism working. Conversely, an AS might raise a rival's rating by sending Evil traffic from the rival's address space. This is spoofing, which is Evil, and will be rated as such by any MITM that has read Section 4.3 and knows what an address is for.</t>
<t>Centralisation. The ERA is a single point of failure and a single point of control. See Section 6.7, which the Working Group considers to have dealt with the matter.</t>
<t>Key disclosure. Voluntary Decryption Assistance (Section 4.5.3) transmits session keys in the clear to an intermediary. The Working Group notes that this is what the mechanism is for, and that the mechanism is Voluntary, Trusted, and Proportionate, all of which are words.</t>
<t>Circumvention. An endpoint might attempt to evade rating by tunnelling, which is rated 1.5 (Section 4.4); by using a transport the MITM does not recognise, which is rated 2.0; by not sending packets, which is Good and is <bcp14>RECOMMENDED</bcp14>, the theoretical limit of which is the Null Packet <xref target="RFC6592"/>; or by avian carrier, which the falconer will handle.</t>
<t>Wrongful termination. A packet rejected under Section 7.2 might object that its termination was wrongful <xref target="RFC8367"/>. The objection is noted and, per Section 3.3, rated.</t>

</section>
<section anchor="s-12-privacy-considerations" numbered="true">
<name>Privacy Considerations</name>
<t>This document has no privacy considerations, in the sense that the Working Group did not consider privacy. Readers who would like to consider it are referred to Section 4.5, after which they will not need to.</t>

</section>
<section anchor="s-13-iana-considerations" numbered="true">
<name>IANA Considerations</name>
<t>This document makes the following requests of IANA, which IANA is encouraged to grant before it is rated.</t>
<t>Differentiated Services Field Codepoints. IANA is requested to record, against every codepoint in the DSCP registry, the value "EVIL (see draft-traviss-evil-byte)". IANA is further requested to record the same value against the ECN field, which has no registry, in whatever it has instead.</t>
<t>HTTP Status Codes. IANA is requested to create the 6xx class in the HTTP Status Code Registry and to register 666, Evil, with this document as reference. IANA is requested not to register any other 6xx code on behalf of anyone else. The Working Group does not wish to share.</t>
<t>HTTP/2 and HTTP/3 Error Codes. IANA is requested to register the error code EVIL with the value 0x666 in both registries.</t>
<t>HTTP Field Names. IANA is requested to register the fields Evil and Evil-Threshold, both permanent, both with this document as reference, and both with the status "Evil".</t>
<t>Well-Known URIs. IANA is requested to register the well-known URI suffix "evil" (Section 7.3).</t>
<t>Special-Use Domain Names. IANA is requested to enter evil.arpa in the Special-Use Domain Names registry <xref target="RFC6761"/>, and to delegate evil.arpa to the ERA once the ERA has determined who it is (Section 6.6). The Working Group notes that .arpa <xref target="RFC3172"/> has become the domain in which the Internet keeps the things it would rather not discuss, and that this is a natural fit.</t>
<t>Service Names and Port Numbers. IANA is requested to register the service name esrp on UDP port 666, alongside doom. The Working Group has consulted the existing assignee and received no objection, or indeed any response.</t>
<t>TLS ExtensionType Values. IANA is requested to assign the value 1638 (0x0666) to the extension evil_key_share (Appendix D), for aesthetic reasons.</t>
<t>IPv6 Hop-by-Hop Options. IANA is requested to assign an option type for the Evil Option of Appendix E with the "act" bits set to 00 (skip over) and the "chg" bit set to 1, the value changing en route. The Working Group observes that this will be a rare option whose bits accurately describe its behaviour, and that routers will drop it anyway.</t>
<t>RFC 3514. IANA is requested to annotate the reserved bit of the IPv4 Flags field as "Obsoleted; see Section 3.5", and to leave it exactly where it is.</t>
<t>Three-Letter Acronyms. This document coins four new ones: MITM, ERA, VDA, and ESRP. Two comply with the letter of <xref target="RFC5513"/>; two do not. The Working Group has reviewed <xref target="RFC5513"/>'s warning of imminent World Acronym Depletion and, on balance, proceeds anyway.</t>

</section>
  </middle>
  <back>
<references anchor="s-references">
<name>References</name>
<references anchor="s-normative-references">
<name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0791.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1035.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1149.xml"/>
<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.2324.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2474.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3168.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3514.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6214.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6919.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7168.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.8200.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8615.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9846.xml"/>
<reference anchor="ELO"><front><title>The Rating of Chessplayers, Past and Present</title><author><organization>Elo, A. E.</organization></author><date year="1978"/></front></reference>
</references>
<references anchor="s-informative-references">
<name>Informative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1349.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1591.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1925.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2100.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2549.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3092.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3172.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3849.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4041.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4271.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5398.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5513.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5514.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5737.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6592.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6598.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6761.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6996.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7169.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7300.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7607.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7725.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8367.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8962.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9401.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9948.xml"/>
<reference anchor="BLUG" target="https://www.blug.linux.no/rfc1149/"><front><title>The highly unofficial CPIP WG</title><author><organization>Bergen Linux User Group</organization></author><date year="2001" month="April"/></front></reference>
<reference anchor="CSAR"><front><title>Proposal for a Regulation of the European Parliament and of the Council laying down rules to prevent and combat child sexual abuse</title><author><organization>European Commission</organization></author><date year="2022" month="May"/></front><seriesInfo name="" value="COM(2022) 209 final"/></reference>
<reference anchor="OSA"><front><title>Online Safety Act 2023</title><author><organization>United Kingdom</organization></author><date year="2023" month="October"/></front><seriesInfo name="" value="2023 c. 50, section 121"/></reference>
<reference anchor="IANA-PORTS" target="https://www.iana.org/assignments/service-names-port-numbers/"><front><title>Service Name and Transport Protocol Port Number Registry</title><author><organization>IANA</organization></author><date/></front></reference>
</references>
</references>
<section anchor="s-appendix-a-reference-implementation" numbered="true">
<name>Reference Implementation</name>
<t>The following Python module implements the formula of Section 4 and the update rule of Section 6. It produces the vectors of Appendix C. Being a Code Component, it is provided without warranty; being this document's, it is provided without much hope either.</t>
<sourcecode type="python" markers="true"><![CDATA[
"""Reference implementation of draft-traviss-evil-byte-00.

Computes the Evil Rating (ER) carried in the Evil Byte (Section 4)
and the Elo update applied by the Evil Rating Authority (Section 6).
Pure Python 3, no dependencies.  This code is Good (self-assessed;
see Section 5.3).
"""
import math
from datetime import datetime

# B: no packet is entirely innocent (Section 4.1)
BASE_EVIL = 16.0

# Section 4.1, Table: weights
W = {"as": 1.0, "net": 0.5, "tx": 0.25, "content": 1.5,
     "name": 0.75, "time": 0.25}

# Section 4.3: network protocol factor
NET = {"ipv4": 1.5, "ipv4-cgnat": 1.75, "ipv6": 0.75,
       "ipv6-transition": 1.25, "ipv6-hbh": 2.0}

# Section 4.4: transport factor
TX = {"tcp": 1.0, "udp": 1.1, "quic": 1.25, "sctp": 0.8,
      "icmp-echo": 0.5, "icmp-redirect": 4.0, "tunnel": 1.5,
      "avian": 0.25, "other": 2.0}

# Section 4.5: content factor
CONTENT = {"good": 0.5, "uncertain": 1.5, "evil": 4.0,
           "unanalysed": 2.0, "encrypted": 4.0}
COOPERATION_DISCOUNT = 0.9  # Section 4.5.3

# Section 4.6: nomenclature factor, keyed by top-level label
NAME = {"mil": 4.0, "gov": 2.0, "zip": 2.0, "ai": 1.5, "biz": 1.5,
        "io": 1.25, "com": 1.0, "net": 1.0, "edu": 0.9, "org": 0.8,
        "int": 0.75, "eu": 0.5, "local": 0.5}
NO_NAME = 1.25
# doth protest too much
PROTEST = ("secure", "trust", "safe", "legit")


def name_factor(name):
    """Section 4.6.  `name` is the PTR name, Host, or SNI; None if
    absent."""
    if not name:
        return NO_NAME
    lowered = name.lower().rstrip(".")
    labels = lowered.split(".")
    tld = labels.pop()                   # the top-level label
    parent = labels.pop() if labels else ""
    if tld == "arpa" and parent == "home":
        f = NAME["local"]                # it is your printer
    else:
        f = NAME.get(tld, 1.0)           # ccTLDs and unlisted gTLDs
    if any(word in lowered for word in PROTEST):
        f = max(f, 1.5)
    return f


def time_factor(when, dst=False):
    """Section 4.7.  `when` is a naive datetime in the source's local
    time."""
    if when.month == 4 and when.day == 1:
        return math.inf              # all packets are Evil
    if 2 <= when.hour < 5:
        f = 1.5
    elif when.weekday() == 4 and when.hour >= 16:  # Friday afternoon
        f = 1.25
    else:
        f = 1.0
    return f + (0.1 if dst else 0.0)


def content_factor(result, vda=False):
    """Section 4.5.  `result` is a key of CONTENT.  With VDA,
    `result` is the cleartext result and the Cooperation Discount
    applies."""
    return CONTENT[result] * (COOPERATION_DISCOUNT if vda else 1.0)


def evil_rating(f_as, f_net, f_tx, f_content, f_name, f_time,
                arriving=0):
    """Section 4.1.  Returns the ER to write into the octet.
    `arriving` is the value found in the octet on arrival
    (Section 5.4)."""
    f_tamper = 1.0 if arriving == 0 else 1.5          # Section 4.8
    x = BASE_EVIL * f_tamper
    for key, f in (("as", f_as), ("net", f_net), ("tx", f_tx),
                   ("content", f_content), ("name", f_name),
                   ("time", f_time)):
        x *= f ** W[key]
    if math.isinf(x):
        er = 255                            # 1 April
    else:
        er = int(math.floor(x + 0.5))       # round half towards Evil
        er = max(1, min(255, er))
    return max(er, arriving)                # Evil is monotonic


# ---- Section 6: the Evil Rating Authority -------------------------

def as_multiplier(rating):
    """Section 6.1: F_AS from an ERA rating."""
    return max(0.25, min(4.0, 2.0 ** ((rating - 1500.0) / 400.0)))


def k_factor(rating, exchanges):
    """Section 6.3.1."""
    if exchanges < 30:
        return 64          # provisional
    if rating >= 2400:
        return 16          # Grandmaster of Evil
    return 32


def expected_score(r_a, r_b):
    """Section 6.3."""
    return 1.0 / (1.0 + 10.0 ** ((r_b - r_a) / 400.0))


def elo_update(r_a, r_b, er_req, er_resp, n_a=30, n_b=30):
    """Sections 6.2 and 6.3.  a is the client's AS, b the server's.
    The more Evil party wins.  Returns the two new ratings."""
    s_a = (1.0 if er_req > er_resp
           else 0.5 if er_req == er_resp
           else 0.0)
    e_a = expected_score(r_a, r_b)
    k = min(k_factor(r_a, n_a), k_factor(r_b, n_b))   # Section 6.3.1
    return (r_a + k * (s_a - e_a),
            r_b + k * ((1.0 - s_a) - (1.0 - e_a)))
]]></sourcecode>

</section>
<section anchor="s-appendix-b-deployment-on-linux" numbered="true">
<name>Deployment on Linux</name>
<t>This appendix describes how the author deployed the specification on a small network using nftables and a userspace MITM. Addresses are drawn from the documentation ranges <xref target="RFC5737"/> <xref target="RFC3849"/>, which the Working Group notes are the only addresses on the Internet that have never done anything wrong.</t>
<section anchor="s-b1-nftables" numbered="true">
<name>nftables</name>
<t>Since the octet is the Differentiated Services field by another name, ER = (DSCP &lt;&lt; 2) | ECN, and ER &gt;= 128 is equivalent to DSCP &gt;= 32. A fixed rating can therefore be written, and a threshold enforced, with stock nftables. The formula itself is computed in userspace: the rules below hand packets from the demonstration subnet to the MITM of Appendix B.2 on queue 666.</t>
<sourcecode markers="true"><![CDATA[
table inet evil {
    # Section 5: the MITM.  Packets from the demonstration subnet
    # go to a userspace MITM (Appendix B.2) on queue 666, which
    # rates them.
    chain forward {
        type filter hook forward priority mangle; policy accept;
        ip saddr 192.0.2.0/24 meta l4proto { tcp, udp } \
            queue num 666 bypass
        ip6 saddr 2001:db8::/32 meta l4proto { tcp, udp } \
            queue num 666 bypass
    }
    # A fixed-value MITM, for demonstrations that do not need the
    # formula.  DSCP = ER >> 2, ECN = ER & 3.
    # ER = 0xCA (202): DSCP 0x32, ECN 2.
    chain forward_fixed {
        type filter hook forward priority mangle + 1; policy accept;
        ip saddr 192.0.2.66 ip dscp set 0x32 ip ecn set 2
        ip6 saddr 2001:db8::66 ip6 dscp set 0x32 ip6 ecn set 2
    }
    # Section 7: server-side enforcement below the application layer.
    # ER >= 128 is equivalent to DSCP >= 32 (raw match shown for
    # IPv6).
    chain input {
        type filter hook input priority filter; policy accept;
        ip dscp >= 32 tcp dport 80 counter reject with tcp reset
        @nh,4,8 >= 128 meta nfproto ipv6 tcp dport 80 \
            counter reject with tcp reset
    }
    # Section 8: client-side enforcement: discard responses from
    # Evil servers.
    chain input_client {
        type filter hook input priority filter + 1; policy accept;
        ip dscp >= 32 tcp sport 80 counter drop
        ip6 dscp >= 32 tcp sport 80 counter drop
    }
}
]]></sourcecode>

</section>
<section anchor="s-b2-a-minimal-mitm" numbered="true">
<name>A Minimal MITM</name>
<t>The following program consumes packets from queue 666, rates them, writes the octet, and returns them to the kernel. It performs no content analysis and presumes accordingly (Section 4.5.2), treating anything bound for a port it associates with encryption as Encrypted With Intent. It is illustrative rather than normative. A production MITM would read everything.</t>
<sourcecode type="python" markers="true"><![CDATA[
#!/usr/bin/env python3
"""A minimal MITM (Section 5) for Linux.  Rates every packet that
nftables sends to NFQUEUE 666 (Appendix B.1) and writes the Evil
Byte.

Requires the netfilterqueue and scapy packages, root, and a clear
conscience.  Illustrative, not normative: a production MITM would
read everything (Section 4.5.1); this one merely presumes."""
import socket
from datetime import datetime
from netfilterqueue import NetfilterQueue
from scapy.all import IP, IPv6
from evilbyte import NET, TX, content_factor, evil_rating
from evilbyte import name_factor, time_factor

QUEUE = 666
AS_MULTIPLIER = {}       # from <asn>.as.evil.arpa (Section 6.5)
DEFAULT_AS = 1.0        # ERA has no opinion of this AS (Section 4.2)
ENCRYPTED_PORTS = {443, 853, 993, 995, 8443}  # Encrypted With Intent


def name_of(addr):
    """PTR lookup (Section 4.6).  None if the source is nameless."""
    try:
        return socket.gethostbyaddr(addr)[0]
    except OSError:
        return None


def rate(raw):
    if raw[0] >> 4 == 4:
        pkt, arriving = IP(raw), IP(raw).tos
        f_net, proto = NET["ipv4"], pkt.proto
    else:
        pkt, arriving = IPv6(raw), IPv6(raw).tc
        f_net, proto = NET["ipv6"], pkt.nh
        if proto == 0:               # Hop-by-Hop Options
            f_net = NET["ipv6-hbh"]
    f_tx = {6: TX["tcp"], 17: TX["udp"], 132: TX["sctp"],
            1: TX["icmp-echo"], 58: TX["icmp-echo"],
            47: TX["tunnel"], 4: TX["tunnel"],
            41: TX["tunnel"], 50: TX["tunnel"],
            }.get(proto, TX["other"])
    dport = getattr(pkt.payload, "dport", None)
    if proto == 17 and dport == 443:
        f_tx = TX["quic"]
    # analysis is OPTIONAL
    f_content = content_factor(
        "encrypted" if dport in ENCRYPTED_PORTS else "unanalysed")
    er = evil_rating(
        AS_MULTIPLIER.get(pkt.src, DEFAULT_AS), f_net, f_tx,
        f_content, name_factor(name_of(pkt.src)),
        time_factor(datetime.now()), arriving)
    if isinstance(pkt, IP):
        pkt.tos = er
        del pkt.chksum               # recomputed on send
        # RFC 3514
        pkt.flags = (int(pkt.flags) & 3) | (4 if er >= 128 else 0)
    else:
        pkt.tc = er
    return bytes(pkt)


def handle(packet):
    packet.set_payload(rate(packet.get_payload()))
    packet.accept()


if __name__ == "__main__":
    nfq = NetfilterQueue()
    nfq.bind(QUEUE, handle)
    try:
        nfq.run()
    finally:
        nfq.unbind()
]]></sourcecode>

</section>
<section anchor="s-b3-reading-the-octet-at-the-application-layer" numbered="true">
<name>Reading the Octet at the Application Layer</name>
<t>For datagram sockets, the operating system will surface the octet of each received datagram on request: on Linux, the IP_RECVTOS and IPV6_RECVTCLASS socket options cause it to be delivered as ancillary data with recvmsg().</t>
<t>For stream sockets, the kernel does not surface the octet of received segments to the application. An Evil-aware host firewall, which may be a second instance of the program in Appendix B.2 attached to the input hook, records the greatest ER observed for each (source address, source port) pair in a table, the Evil Table, which the application consults on accepting a connection. From it the application sets the Evil field of Section 7.4 and chooses between serving the request and returning 666. Entries <bcp14>SHOULD</bcp14> be removed when the connection closes and <bcp14>MUST NOT</bcp14> be removed before. Evil, once observed, is not forgotten until the socket is.</t>

</section>
</section>
<section anchor="s-appendix-c-test-vectors" numbered="true">
<name>Test Vectors</name>
<t>The following vectors were produced by the reference implementation of Appendix A, at noon on Wednesday 31 March 2027 unless otherwise stated, from an AS that the ERA has not rated unless otherwise stated. Implementations <bcp14>MUST</bcp14> agree with them, and <bcp14>MAY</bcp14> be surprised by them.</t>
<t>Each vector's scenario is given first, and its factors in the table
that follows.</t>
<ul>
<li><strong>C.1</strong>: Baseline: IPv4, TCP, .com, not analysed, Wednesday noon</li>
<li><strong>C.2</strong>: As C.1, but over TLS (Encrypted With Intent)</li>
<li><strong>C.3</strong>: As C.2, but over IPv6</li>
<li><strong>C.4</strong>: As C.2, with VDA; plaintext found Good</li>
<li><strong>C.5</strong>: As C.2, with VDA; plaintext found Evil</li>
<li><strong>C.6</strong>: AS32934, QUIC over IPv4, encrypted, 03:00</li>
<li><strong>C.7</strong>: EU institution, IPv6, TCP, analysed Good, .eu</li>
<li><strong>C.8</strong>: .mil, IPv4, TCP, encrypted</li>
<li><strong>C.9</strong>: Avian carrier, IPv4, scroll not unrolled, .org</li>
<li><strong>C.10</strong>: Printer: mDNS (UDP) over IPv4, analysed Good, .local</li>
<li><strong>C.11</strong>: As C.1, arriving at a second MITM already rated 55</li>
<li><strong>C.12</strong>: As C.1, no name, Friday 17:00</li>
<li><strong>C.13</strong>: As C.1, from a host called secure-gw.example.net</li>
<li><strong>C.14</strong>: IPv6 with Hop-by-Hop Options, ICMPv6 echo, analysed Good</li>
<li><strong>C.15</strong>: As C.7, on 1 April</li>
</ul>
<table>
<thead><tr><th>ID</th><th align="right">F_AS</th><th align="right">F_net</th><th align="right">F_tx</th><th align="right">F_content</th><th align="right">F_name</th><th align="right">F_time</th><th align="right">Arriving</th><th align="right">ER</th></tr></thead>
<tbody><tr><td>C.1</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>55</strong></td></tr>
<tr><td>C.2</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">4</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>157</strong></td></tr>
<tr><td>C.3</td><td align="right">1</td><td align="right">0.75</td><td align="right">1</td><td align="right">4</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>111</strong></td></tr>
<tr><td>C.4</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">0.45</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>6</strong></td></tr>
<tr><td>C.5</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">3.6</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>134</strong></td></tr>
<tr><td>C.6</td><td align="right">2</td><td align="right">1.5</td><td align="right">1.25</td><td align="right">4</td><td align="right">1</td><td align="right">1.5</td><td align="right">0</td><td align="right"><strong>255</strong></td></tr>
<tr><td>C.7</td><td align="right">0.5</td><td align="right">0.75</td><td align="right">1</td><td align="right">0.5</td><td align="right">0.5</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>1</strong></td></tr>
<tr><td>C.8</td><td align="right">4</td><td align="right">1.5</td><td align="right">1</td><td align="right">4</td><td align="right">4</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>255</strong></td></tr>
<tr><td>C.9</td><td align="right">1</td><td align="right">1.5</td><td align="right">0.25</td><td align="right">2</td><td align="right">0.8</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>33</strong></td></tr>
<tr><td>C.10</td><td align="right">1</td><td align="right">1.5</td><td align="right">1.1</td><td align="right">0.5</td><td align="right">0.5</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>4</strong></td></tr>
<tr><td>C.11</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">2</td><td align="right">1</td><td align="right">1</td><td align="right">55</td><td align="right"><strong>83</strong></td></tr>
<tr><td>C.12</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">2</td><td align="right">1.25</td><td align="right">1.25</td><td align="right">0</td><td align="right"><strong>69</strong></td></tr>
<tr><td>C.13</td><td align="right">1</td><td align="right">1.5</td><td align="right">1</td><td align="right">2</td><td align="right">1.5</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>75</strong></td></tr>
<tr><td>C.14</td><td align="right">1</td><td align="right">2</td><td align="right">0.5</td><td align="right">0.5</td><td align="right">1</td><td align="right">1</td><td align="right">0</td><td align="right"><strong>7</strong></td></tr>
<tr><td>C.15</td><td align="right">0.5</td><td align="right">0.75</td><td align="right">1</td><td align="right">0.5</td><td align="right">0.5</td><td align="right">inf</td><td align="right">0</td><td align="right"><strong>255</strong></td></tr></tbody>
</table>
<t>The following vectors exercise the update rule of Section 6.3, with K = 32 throughout.</t>
<table>
<thead><tr><th>ID</th><th align="right">R_a</th><th align="right">R_b</th><th align="right">ER_req</th><th align="right">ER_resp</th><th align="right">S_a</th><th align="right">E_a</th><th align="right">New R_a</th><th align="right">New R_b</th></tr></thead>
<tbody><tr><td>C.16</td><td align="right">1500</td><td align="right">1500</td><td align="right">157</td><td align="right">17</td><td align="right">1</td><td align="right">0.5</td><td align="right">1516</td><td align="right">1484</td></tr>
<tr><td>C.17</td><td align="right">1900</td><td align="right">1100</td><td align="right">157</td><td align="right">17</td><td align="right">1</td><td align="right">0.99</td><td align="right">1900.32</td><td align="right">1099.68</td></tr>
<tr><td>C.18</td><td align="right">1900</td><td align="right">1100</td><td align="right">17</td><td align="right">157</td><td align="right">0</td><td align="right">0.99</td><td align="right">1868.32</td><td align="right">1131.68</td></tr>
<tr><td>C.19</td><td align="right">1500</td><td align="right">1500</td><td align="right">55</td><td align="right">55</td><td align="right">0.5</td><td align="right">0.5</td><td align="right">1500</td><td align="right">1500</td></tr></tbody>
</table>
<t>C.16 shows a first match between two unrated ASes; the client, being the more Evil, gains sixteen points and F_AS = 1.028. C.17 shows that a Grandmaster-adjacent AS beating an EU AS gains almost nothing, the result having been expected. C.18 shows the upset. C.19 shows a draw, and is included because the Working Group is fond of it.</t>

</section>
<section anchor="s-appendix-d-the-evil_key_share-tls-extension" numbered="true">
<name>The evil_key_share TLS Extension</name>
<t>Voluntary Decryption Assistance (Section 4.5.3) is signalled in TLS <xref target="RFC9846"/> by the extension evil_key_share, ExtensionType 1638 (Section 13), whose extension_data is:</t>
<sourcecode markers="true"><![CDATA[
    enum { key_disclosure(1), self_assessment(2),
           abstinence(3) } VDAForm;

    struct {
        VDAForm form;
        /* form 1: the session keys, in the clear, for efficiency */
        opaque keys<0..2^16-1>;
        /* form 2: 0 = Good, 1 = Uncertain, 2 = Evil.
           Honesty is expected. */
        uint8 assessment;
    } EvilKeyShare;
]]></sourcecode>
<t>A client sends the extension in its ClientHello. Since no session keys exist at that point, a client using form 1 <bcp14>MUST</bcp14> include the keys it intends to derive, which requires it to know the server's key share in advance. Clients <bcp14>MAY</bcp14> guess.</t>
<t>A server sends the extension in EncryptedExtensions, which the MITM cannot read until the server has assisted. This is the Evil Bootstrap Problem (Section 8.2) again, and is left for the same future work.</t>
<t>Form 3 <bcp14>MAY</bcp14> alternatively be signalled by not sending a ClientHello at all, which is also the most widely deployed form.</t>
<t>The extension owes an intellectual debt to the NSA (No Secrecy Afforded) certificate extension <xref target="RFC7169"/>, which made the same offer in a certificate rather than a handshake, and asked for less in return.</t>

</section>
<section anchor="s-appendix-e-alternative-encodings" numbered="true">
<name>Alternative Encodings</name>
<t>Purists who object to the reuse of the Differentiated Services field <bcp14>MAY</bcp14> instead carry the Evil Rating in an IPv4 option or an IPv6 Hop-by-Hop option, as follows.</t>
<artwork><![CDATA[
    IPv4 Evil Option                  IPv6 Evil Option (Hop-by-Hop)
    +--------+--------+--------+      +--------+--------+--------+
    |  Type  | Len=3  |   ER   |      |  Type  | Len=1  |   ER   |
    +--------+--------+--------+      +--------+--------+--------+
    Type: copied=1, class=0,          Type: act=00, chg=1,
          number=TBD (Section 13)           number=TBD (Section 13)
]]></artwork>
<t>The IPv4 option is copied on fragmentation so that every fragment carries its Evil (Section 5.5). The IPv6 option is marked as changing en route, which it does.</t>
<t>Purists should be aware that IPv4 options are dropped by a large fraction of the Internet, that Hop-by-Hop options are dropped by most of the rest, and that a packet which is dropped has, per Section 5.4, achieved the only reduction in Evil this specification allows. The Working Group therefore regards the alternative encodings as compliant, effective, and unusable.</t>

</section>
<section anchor="s-acknowledgements" numbered="false">
<name>Acknowledgements</name>
<t>The author thanks Steven Bellovin for the original bit, and the many policymakers whose proposals made this one look reasonable. Thanks are also due to the Working Group's colleague (Section 4.5.1), whose face has been invaluable.</t>
<t>No pigeons were harmed in the preparation of this document. One was rated.</t>

</section>
  </back>
</rfc>
