Internet-Draft License Activation Protocol September 2021
Lorlacks Expires 16 March 2022 [Page]
Workgroup:
Internet Engineering Task Force
Internet-Draft:
draft-lorlacks-license-activation-protocol-00
Published:
Intended Status:
Experimental
Expires:
Author:
M. Lorlacks
Independent

License Activation Protocol

Abstract

This document defines an experimental method for uniform license activation mechanism for use in digital rights management (DRM).

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 16 March 2022.

Table of Contents

1. Introduction

A common issue with on-premises software licensing is ensuring that licensing limitations are enforced. Digital rights management (DRM) is an umbrella term for modeling legal licensing requirements in the form of executable code. Part of DRM implementation is often communication with a server to ensure central knowledge of licenses in circulation.

DRM implementations are in practice almost always one-off solutions for a particular product. No observable efforts to standardize DRM have been made. While DRM necessarily relies on either hardware or on security by obscurity, another use for DRM is to simplify license compliance for honest customers. Consolidating the license information on a single server within an organization brings obvious benefits for keeping track of software inventory, obviating the need of manually triangulating licenses in use.

It therefore seems beneficial to standardize a license management protocol that is both suitable for obfuscation without giving away too much information to active adversaries observing traffic and at the same time has reasonable implementation semantics for simplified cases where active adversaries are ignored, such as when it is too costly to spend great effort on software protection; modern obfuscation techniques are complex and accordingly expensive to implement, see e.g. [virtsc]. The license activation protocol presented herein aims to satisfy both of these needs.

2. Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP14] when, and only when, they appear in all capitals, as shown here.

A "byte" refers to an octet of bits. It is generally assumed that fixed-szie integer types for 8-, 16-, 32-bit integers are available.

A "UUID" is a Universally Unique IDentifier in the sense of [RFC4122]. It is always respresented as a sequence of bytes. The byte sequences use big-endian encoding for all numerical components of the UUID. For example, this means that the UUID "00112233-4455-6677-8899-aabbccddeeff" is encoded as the following sequence of bytes: 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff. This is mandated by [RFC4122]; all other integer values in this document use little-endian encoding.

3. Protocol

The protocol operates between a client and a server in a request-response fashion. The client sends a request and the server sends a response. Both request and response are each UDP datagrams[RFC0768].

The protocol can both be used in a direct setup (customer client and vendor server communicate directly over the Internet) and an indirect setup (customer client and customer intermediate server communicate directly; customer intermediate server and vendor server communicate with each other using this same protocol). Practical considerations may necessitate one or the other setup. The choice between the setups must be made at provisioning time.

3.1. Provisioning

Prior to executing the protocol, every client must first be "provisioned". Provisioning means equipping the client with:

  1. a UUID that remains static for the installation time of the client (client base ID),
  2. a UUID that remains static for the installation time of the client and SKU (client add-on ID),
  3. unique, hard-to-predict information (client seed),
  4. information about the expected server.

The client IDs MUST be generated at installation time. It is RECOMMENDED that a version 4 UUID using a cryptographically secure random number generator is used.

The client base ID refers to a "base installation"; if there are add-ons to a product, the client add-on ID can be used to distinguish an activation request for the base installation and the add-on while still being able to correlate the requests due to different SKU fields in the request. If this is a base installation or no add-ons exist at all, the client add-on ID MUST be set to the nil UUID (all bits are zero).

The client-side unique, hard-to-predict information (client seed) is typically supplied and generated at installation time. It could, for example, consist of a unique license key concatenated with hardware information. No format is specified; the actual value of the client seed is out of scope, but it MUST be a byte string consisting of one or more bytes; it is RECOMMENDED to include at least 16 bytes of cryptographically secure random data.

Additionally, the client must be aware of its own stock-keeping unit (SKU) identifier. This is a UUID[RFC4122].

The server information is typically hard-coded at compile time. It consists of an X25519 public key[RFC7748] and an Ed25519 signing key[RFC8032].

3.2. Service Discovery

The license activation server has a DNS SRV record[RFC2782] for the service name "lap", e.g. _lap._udp.licensing.example.com. The record describes the UDP port to use for the protocol. No fixed UDP port is assigned; the UDP port for an individual deployment may therefore be chosen in accordance with IANA policy and the constraints of the network(s) involved.

The license activation server MAY be auto-discovered using DNS-based service discovery (DNS-SD)[RFC6763]. The associated TXT record is empty. Individual clients MUST provide a documented mechanism to manually override an auto-discovered server address.

3.3. Request

Once the client has discovered the license activation server to use (hostname, UDP port), it sends the request. The request has this structure:

Table 1: Client request packet structure
Size (bytes) Name Description
1 Version Protocol version, currently always 2
2 Size Size of the request in bytes in little-endian byte order
5 ClientTime The client's idea of the current time in Seconds Since the Epoch
16 ClientBaseId Client-generated UUID uniquely identifying the base installation
16 ClientAddOnId Client-generated UUID uniquely identifying the installation of the add-on
16 SKUId Stock-keeping unit (SKU) UUID that identifies the product of the client
16 CurrentLicenseId The license UUID issued by the server for this installation
16 Reserved, all-zero
(variable) ClientSeed The client seed value

There MUST NOT be any padding between the fields.

The Size field is computed starting at the Version field. Since the client seed (and thus the ClientSeed field) is not permitted to be empty (see Section 3.1, Paragraph 6), the minimum value for the Size field is 89.

The CurrentLicenseId field indicates to the server the LicenseID of the last response from the server. If this is the first activation request ever, the CurrentLicenseId is the nil UUID. Note that the server MAY issue a LicenseID that differs from the request even if CurrentLicenseId is not the nil UUID.

The term "Seconds Since the Epoch" is defined in section 4.16 of the Base Definitions volume of [POSIX.1-2017]; the "Epoch" itself is defined in section 3.150 thereof. "Seconds Since the Epoch" is commonly known as "UNIX time". This field is 5 bytes in length to ensure this protocol working at least until the year 10,000. This integer value is transmitted in little-endian byte order and does not include fractions of a second.

The client then generates an ephemeral X25519[RFC7748] key pair. Therefore, the client MUST have access to a cryptographically secure random number generator. It performs X25519 with its ephemeral key and the server's public key that was obtained at provisioning time. The nonce is set to 0. The key is the result of applying HKDF[RFC5869] as follows, where | signifies concatenation:

  1. Hash = SHA-512[SHS] (thus HashLen = 64)
  2. PRK = HKDF-Extract(salt=none, IKM=client's ephemeral X25519 public key | server's X25519 public key | server's Ed25519 public key | the X25519 shared secret)
  3. OKM = HKDF-Expand(PRK, info=[ASCII representation of "56065c4d-d2e0-4ba9-bf9f-76f9159e2987-LAP-V02"], L=64)
  4. the symmetric key for the client-to-server packet is now the first 32 bytes of OKM;
  5. the symmetric key for the server-to-client packet is now the second 32 bytes of OKM.

The encryption key is used with ChaCha20 and Poly1305 (AEAD_CHACHA20_POLY1305)[RFC8439] to encrypt the request. There is no additional authenticated data. The client then transmits:

  1. its 32-byte ephemeral X25519 public key;
  2. the encrypted request;
  3. the 16-byte Poly1305 authentication tag.

The client MUST transmit this information in a single UDP packet, in that particular order and without padding inbetween to the server. This implies that a packet may not exceed the size of what can be transmitted in a single UDP packet.

3.4. Response

Before issuing a response, the server validates the client's request. If the result of the validation process is negative, the server does not respond to the request and drops the UDP packet. Clients MUST NOT probe whether servers drop invalid requests. In particular, the server MUST validate that:

  1. the result of the X25519 function is not all-zero;
  2. decryption succeeded (Poly1305 tag is valid);
  3. the Version field is 1;
  4. the Size field is equal to or greater than 89;
  5. the ClientTime fields match the server's idea of the current time with at most 30 seconds of difference;
  6. the SKU ID is known to the server;
  7. the SKU ID may be for a base installation if the ClientAddOnId is the nil UUID or that the SKU ID may be used for an add-on installation if the ClientAddOnId is not the nil UUID;
  8. the ClientSeed field is valid according to the rules known to the server;
  9. the client is licensed according to the rules known to the server.

Additionally, the server MAY check whether the UUIDs match the generation procedures outlined in [RFC4122] and follow the expected UUID generation algorithm for that particular SKU.

If the validation passes, the server sends the following response structure:

Table 2: Server response packet structure
Size (bytes) Name Description
1 Version Protocol version, currently always 2
2 Size Size of the response in bytes in little-endian byte order
5 ServerTime The server's idea of the current time in Seconds Since the Epoch in little-endian byte order, see Section 3.3, Paragraph 6
16 ClientId The client-generated UUID echoed back
16 SKUId The SKU ID echoed back
16 LicenseId A UUID that identifies the license; in case of volume licensing, multiple clients MAY share the same value
(variable) ServerData Application-specific data for the client, which MAY be empty

There MUST NOT be any padding between the fields.

The Size field is computed starting at the Version field, i.e. the very beginning of the message. Since the server data is permitted to be empty, the minimum value for the Size field is 56.

The ClientId field refers to the client-generated ClientBaseId if ClientAddOnId was the nil UUID and to the ClientAddOnId otherwise.

The ServerData field may be used, for example, to transmit a date/time by which the client must consider itself de-activated and needs to re-authenticate or to transmit feature flags that are supposed to be enabled.

The server encryption key that was derived in Section 3.3, Paragraph 7 is then used to encrypt the response. The nonce is set to 0. There is no additional authenticated data. The server then transmits:

  1. its 64-byte Ed25519 signature over the rest;
  2. the encrypted response;
  3. the 16-byte Poly1305 authentication tag.

The server MUST transmit this information in a single UDP packet, in that particular order and without padding inbetween to the client. This implies that a packet may not exceed the size of what can be transmitted in a single UDP packet.

The client finally validates the server response according to the criteria it deems fit, but it MUST at least verify the Ed25519 signature. The client considers itself activated if the response validated successfully.

4. Security Considerations

The client SHOULD NOT be considered trusted. Tampering with DRM is a notorious issue. In particular, as noted in the previous sections, an implementation MUST verify all inputs rigorously. Conversely, the client SHOULD NOT rely on the server's response being well-formed in principle; practical considerations (such as with embedded microprocessors) may necessitate this nonetheless.

All routines and secrets pertaining to DRM SHOULD be protected by hardware-based mechanisms such as trusted platform modules (TPMs), hardware security modules (HSMs), and trusted execution environment technologies. Obfuscation can also aid longevity of DRM by deterring insufficiently motivated attackers.

The server information secrets SHOULD be protected by hardware security modules. Cloud-based hardware security modules MAY be chosen for this task. It is RECOMMENDED that accesses to these keys is monitored; for example, an automated system could cross-reference accesses to the secrets with timing of incoming requests.

While the contents of activation responses in the ServerData field are unspecified, because activation procedures are often time-limited, the accuracy of the client's clock is important. Otherwise, the server may issue responses that are too far into the future or already in the past for the client, bypassing temporal licensing limitations. It is therefore RECOMMENDED that clients synchronize their time over the network, for example using NTP[RFC5905].

In considering an implementation, care should be taken to avoid network amplification attacks. Notably, the server response packet SHOULD NOT exceed the size of a client packet under any circumstances. In particular, this means that the length of ClientSeed should be equal or greater than the length of ServerData.

Using a fixed nonce for the encryption of the request and response is unproblematic because there is a new AEAD_CHACHA20_POLY1305 key for every request. Nonces only need to be unique per key. Access to a cryptographically secure random number generator is required. It is therefore no issue to fix the nonce since keys are guaranteed to be unique.

5. IANA Considerations

The discovery mechanism described in section Section 3.2 requires a service name. The Service Name and Transport Protocol Port Number Registry therefore needs to be updated accordingly. In accordance with [BCP165], it is hereby requested that IANA create a new entry in the Service Name and Transport Protocol Port Number Registry reading:

Table 3
Service Name lap
Transport Protocols udp
Assignee Maximilian Lorlacks <maxlorlax@protonmail.com>
Contact Maximilian Lorlacks <maxlorlax@protonmail.com>
Description License Activation Protocol
Reference [this document]
Port Number
Service Code
Known Unauthorized Uses
Assignment Notes Defined TXT keys: None.

Document History [RFC Editor: Please remove this section]

Note to the RFC Editor: Please remove this section before publication.

draft-lorlacks-license-activation-protocol-04

draft-lorlacks-license-activation-protocol-03

draft-lorlacks-license-activation-protocol-02

draft-lorlacks-license-activation-protocol-01

References

Normative References

[BCP14]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, .
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, .
<https://www.rfc-editor.org/info/bcp14>
[BCP165]
Cotton, M., Eggert, L., Touch, J., Westerlund, M., and S. Cheshire, "Internet Assigned Numbers Authority (IANA) Procedures for the Management of the Service Name and Transport Protocol Port Number Registry", BCP 165, RFC 6335, .
Touch, J., "Recommendations on Using Assigned Transport Port Numbers", BCP 165, RFC 7605, .
<https://www.rfc-editor.org/info/bcp165>
[POSIX.1-2017]
IEEE, "Standard for Information Technology--Portable Operating System Interface (POSIX(R)) Base Specifications, Issue 7", IEEE 1003.1, 2017 Edition, DOI 10.1109/IEEESTD.2018.8277153, , <https://ieeexplore.ieee.org/servlet/opac?punumber=8277151>.
[RFC0768]
Postel, J., "User Datagram Protocol", STD 6, RFC 768, DOI 10.17487/RFC0768, , <https://www.rfc-editor.org/info/rfc768>.
[RFC2782]
Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, DOI 10.17487/RFC2782, , <https://www.rfc-editor.org/info/rfc2782>.
[RFC4122]
Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI 10.17487/RFC4122, , <https://www.rfc-editor.org/info/rfc4122>.
[RFC5869]
Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, DOI 10.17487/RFC5869, , <https://www.rfc-editor.org/info/rfc5869>.
[RFC6763]
Cheshire, S. and M. Krochmal, "DNS-Based Service Discovery", RFC 6763, DOI 10.17487/RFC6763, , <https://www.rfc-editor.org/info/rfc6763>.
[RFC7748]
Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves for Security", RFC 7748, DOI 10.17487/RFC7748, , <https://www.rfc-editor.org/info/rfc7748>.
[RFC8032]
Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, , <https://www.rfc-editor.org/info/rfc8032>.
[RFC8439]
Nir, Y. and A. Langley, "ChaCha20 and Poly1305 for IETF Protocols", RFC 8439, DOI 10.17487/RFC8439, , <https://www.rfc-editor.org/info/rfc8439>.
[SHS]
National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, DOI 10.6028/NIST.FIPS.180-4, , <https://doi.org/10.6028/NIST.FIPS.180-4>.

Informative References

[ISO7064]
International Organization for Standardization/International Electrotechnical Commission, "Information technology - Security techniques - Check character systems", ISO/IEC Standard 7064, .
[RFC5905]
Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, "Network Time Protocol Version 4: Protocol and Algorithms Specification", RFC 5905, DOI 10.17487/RFC5905, , <https://www.rfc-editor.org/info/rfc5905>.
[SMBIOS]
DMTF, "System Management BIOS (SMBIOS) Reference Specification", DMTF DSP0134, .
[virtsc]
Ahmadvand, M., Below, D., Banescu, S., and A. Pretschner, "VirtSC: Combining Virtualization Obfuscation with Self-Checksumming", SPRO '19, Proceedings of the 3rd ACM Workshop on Software Protection pp. 53-64, DOI 10.1145/3338503.3357723, , <https://doi.org/10.1145/3338503.3357723>.

Appendix A. Implementation Notes

This section provides guidance on implementing LAP. This appendix is not normative.

In particular, it may be difficult to envision what the ClientSeed field might look like. One example could be the following:

Table 4: ClientSeed example
Size (bytes) Name Description
16 DecodedKey Some kind of license key, decoded as a byte sequence
32 MachineHash Some kind of hash of the machine
1 NumCPUs The number of CPUs installed
1 NumCores The number of cores installed total

The DecodedKey field contains a decoded form of a license key. Other ideas for this include a larger key file with a cryptographic signature that is transmitted out of band, or a UUID that is built into each installation package. License keys, if used, should employ some manner of local checksum mechanism to avoid common classes typographic errors; guidance thereon may be found in [ISO7064]. It should be noted that human input will always find creative ways to fail while still passing check character validation; it is therefore helpful for the user to attempt activation during the installation process if possible and to provide a fallback way to correct a mis-typed license key after installation.

An ideal implementation would entirely avoid LAP by integrating the activation status of the software with an authentication action. For example, by storing settings on a server and touting device synchronization over the internet as a (non-optional) feature. In this case, LAP is of no use because a better implicit activation process exists already.

The hardware hash should bind to an individual machine as strongly as nessary but as weakly as possible; however, care must be taken depending on the deployment scenario. In cloud computing or scenarios involving virtual private servers or shared web hosting, one physical machine may be shared among many tenants. Strongly identifying hardware - or even just an operating system installation - alone is counter-productive as it invites spurious collisions. On the other hand, software intended to be deployed to individual desktop or mobile computers can positively rely on hardware hashing alone and should instead try to avoid pure software identifiers to avoid multiple installations.

If available, remote attestation of a TPM can be a very strong identifying component. Similarly, the SMBIOS System Information table contains a UUID that can be used for identification purposes; note, however, that the UUID contained therein uses little-endian encoding partially[SMBIOS]. However, the SMBIOS UUID may be particularly unreliable as there have historically been vendors that change the UUID on every boot; the value may also possibly be all-zero (nil UUID), all-one or some other bogus value.

Virtual machines trivially evade both of these identifiers, by not providing a TPM in the first place and sharing the SMBIOS UUID across multiple virtual machines or providing a bogus SMBIOS UUID. For virtual machines, there is no trustworthy value. In some cases, the host CPU may be directly passed through, but in many cases, the guest CPU is just an unidentifiable virtual CPU. For virtual machines, the only thing that can be ascertained is whether software runs on duplicated virtual machine instances, which itself may be meaningless depending on the licensing policy.

Setting aside the concerns of finding a reliable machine identifier (for whatever a "machine" may be in this context), the other issue that requires attention is control flow. While many software products exist for some amount of automated obfuscation, a useful guidance principle is: Stay on the data path.

To "stay on the data path" means to avoid having boolean if/else checks for activation succeeding, instead passing forward meaningful data between the activation check and the rest of the program. For example, the ServerData from the LAP response may contain a cryptographic key to decrypt assets required for program execution; tampered requests may lead to a subtly different but invalid key being supplied by the server.

Similarly, the ClientSeed may also be extended by a hash or series of hashes that measure the execution state of an embedded virtual machine; the server unquestioningly uses these hashes as part of deriving the asset encryption key: Tampering with any embedded virtual machine's state therefore leads to being supplied an invalid key and program execution fails in ways that are then difficult to predict, in particular if no authenticated encryption is used for the asset decryption and thus garbage is fed to various routines using these assets. Compromising the scheme thus requires compromising all of the at the embedded virtual machines same time or finding some other way of keeping their hash procedures constant.

It must also be noted that there is no such thing as a perfect software protection scheme. Any sufficiently dedicated attacker will eventually break any software protection scheme. The amount of effort spent on software protection should be proportional to the amount of impact unauthorized distribution has on profits. It may be assumed that even a small vendor will eventually encounter a highly dedicated attacker driven by non-monetary motivations.

For ethical reasons, an exit strategy should also be devised ahead of time: Assuming the activation servers providing the LAP targets are shut down for whatever reason, how is it ensured that the software may still run? It is easy to dismiss this question as being far into the future, but sometimes software has an unexpectedly long lifetime. Furthermore, shutting down activity as a vendor or outright bankruptcy may occur unexpectedly. Through no fault of the user, the user becomes unable to execute the program. Plans to provide some kind of fallback (be it executables stripped of the activation code, be it provision of the server software) should thus be made ahead of time alongside development of the software protection itself.

In a similar vein, software should be transferable and assignable; depending on jurisdiction, it may even be imperative that software be transferable. There should thus be no "hard" hardware binding so that the user may upgrade the hardware or sell their copy of the software. Care should be taken early on to expect this scenario.

Author's Address

Maximilian Lorlacks
Independent