Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Our precinct scanners export cast vote records (CVRs) to USB drive continuously, as ballots are cast. Continuous export also allows for a speedy polls close, as cast vote records need not be exported all at once on polls close.
To perform continuous export while also keeping signatures, i.e., authenticity information, up-to-date, we have to be able to write both CVRs and authenticity information incrementally. (It isn’t enough to just hash and sign new data. We need an up-to-date root hash/signature.) We can use a structure to accomplish this efficiently.
Assuming every CVR has a random UUID, e.g. 4d6a9dad-e6d6-4a29-89bc-9ab915012b73, we can specifically use the following structure:
We don’t actually have to 1) use a nested directory structure on the USB or 2) store all intermediate hashes on the USB. We can store the structure and intermediate hashes on the machine in a database table, e.g.
Then on the USB, we can use a flat structure that’s much easier to reason about and iterate over:
In the above examples, we’ve listed a root-hash.txt file and have signed that. In practice, we use a JSON file capable of storing other metadata and sign that:
Sample metadata.json:
Whenever a machine imports a CVR directory, it authenticates the CVRs by 1) verifying the signature on the metadata.json file and 2) recomputing the “castVoteRecordRootHash” in metadata.json from scratch to ensure that it’s correct.
Refer to the following code links for more details:
The foundation of our system integrity solution is the TPM (described in greater detail under ).
Our design for system integrity maps closely to that of ChromeOS:
The hard drive is partitioned such that executable code lives on the read-only partition /
, and only /var
and /home
are mounted read/write for configuration, logs, and working data like scanned ballot images.
The read-only partition is verified by , which generates a hash tree of all the raw partition blocks, culminating in a single hash root for the entire read-only filesystem.
The kernel boot command line includes the dm-verity hash root as an argument, ensuring that Linux halts if the read-only partitions are not successfully verified against this hash root.
The BIOS is configured to only boot a properly signed bootloader+kernel+command-line, with public keys managed by VotingWorks and configured in the BIOS as secure boot keys. The bootloader+kernel+command-line that we want is set up as the default boot option in UEFI.
The private key described previously in is generated in the TPM and bound to Platform Configuration Registers (PCRs) that include the BIOS, the Secure Boot public keys, and the bootloader+kernel+command-line. Thus, this private key is only usable if the machine boots appropriately sanctioned source code with a hard drive whose read-only partitions are unmodified.
As a diagram:
The integrity of the overall system is ensured because:
Any change in the executable portion of the hard drive will be detected when dm-verity checks the hard drive blocks against its stored hashes.
Any change in the hashes stored on disk will be detected against the mismatched root hash, present in the kernel boot command line.
Any live changes to the read-only portion of the drive, even while the machine is already booted up, will be detected the moment Linux tries to read those modified blocks, as all disk reads are live-checked against the hashes.
Any change in the kernel boot command line will be detected in two ways:
First, the TPM won’t unseal secrets since a change in the command line changes one of the PCR values, which means that the TPM’s policy check will fail.
Second, the system won’t even boot at all because the changed command line invalidates the signature on the bootloader+kernel+command-line, and UEFI will refuse to execute the now-improperly signed bootloader+kernel+command-line.
Thus, if the system boots, it means that the hard drive corresponds, by hashing, to the expected value that we baked into the bootloader+kernel+command-line and signed.
Our system is configured so that /var
, /tmp
, and /home
are mounted read-write, and /
for everything else is mounted read-only. This requires writing logs and other runtime-generated VotingWorks data, e.g., scanned ballot images, to /var
. Variable system configuration, e.g. timezone information, also needs to be redirected to /var
. A USB mount point is pre-created at /media/vx/usb-drive
.
In addition to locking down the /
partition, the /var
partition is encrypted and authenticated using dm-crypt
. This ensures that, even if an attacker removes the physical hard drive and connects it to a different CPU, they cannot read or modify the contents of the /var
partition in an attempt to make the VxSuite component behave differently.
Furthermore, as an extra layer of defense, every individual VxSuite component instance uses a unique random encryption key for its /var
partition. Thus, if an attacker were to break the encryption on one VxSuite machine, they would have gained no advantage in penetrating a second machine. This is ensured through rekeying of the /var
partition encryption on first boot of a VxSuite component.
With Secure Boot, UEFI passes control to the bootloader only if the bootloader is appropriately signed. Then, the bootloader passes control to the kernel. We choose to bundle the bootloader, kernel, and command line that is used to run the kernel all as one, and to present that to the UEFI as the single executable whose signature should be verified before running. The three are combined into a single object file, along with the dm-verity root hash. This single object file is signed by VotingWorks secure boot private keys.
Every VotingWorks machine’s BIOS is configured with VotingWorks secure boot public keys, and the BIOS is configured to require Secure Boot. Thus, only a properly signed object file can serve as bootloader.
When mounting USB drives, VxSuite always mounts them using standard Linux mount configuration options that makes files on the USB drive NOT executable. This further protects from any unauthorized software running, even in a transient fashion.
All VxSuite components are blocked from connecting to any network. Thus, there is no networking in a VxSuite implementation. Our network design is secure by virtue of it being completely absent.
Networking is disabled through several layers of defense:
Network drivers and known network connections are purged in the software setup process. See script.
Secure boot ensures that the hard drive is not modified, thus preventing software that isn’t part of the approved VotingWorks bundle from running.
The network stack is disabled in the BIOS.
Wi-fi or bluetooth hardware is not present on the machines.
Ethernet ports are blocked.
As a final layer of defense, a is defined to block any incoming or outgoing traffic in the event a connection was somehow created.
Because there is no networking, all electronic data transfer is air-gapped via USB drives.
The database table makes recomputing hashes easy, as retrieval of all hashes for a given ID prefix becomes a simple SQL query. This approach also decreases the chance that we accidentally depend on data written to the USB drive when computing hashes, protecting against .
— CVR hashing logic, including the Merkle tree implementation
-
-
-
Root hash
4
-
-
4 hash
4
4d
-
4d hash
4
4d
4d6a9dad-e6d6-4a29-89bc-9ab915012b73
4d6a9dad-e6d6-4a29-89bc-9ab915012b73 hash
…
On VxSuite machines, there are no passwords for election administrators to use – only smart cards as described previously. The smart cards all use 256-bit elliptic-curve digital signatures, which makes them cryptographically strong. In addition, the PINs that gate usage of those cards follow the NIST recommendations for authentication – 6 digits long, randomly generated (as opposed to chosen by the user who might use a birthdate), and never a weak PIN like 000000.
VxSuite v4 contains four distinct cryptographic modules:
Smart cards
VxAdmin / VxCentralScan TPM (same underlying hardware)
VxMark TPM
VxScan TPM
OpenSSL software
All of the above are FIPS-compliant.
VxSuite v4 uses NXP JCOP 4 Java Cards, specifically this model: https://www.cardlogix.com/product/nxp-jcop-4-java-card-3-0-5-classic.
These smart cards are FIPS140-2-certified: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3746.
The applet that we run on the cards, OpenFIPS201, is an implementation of the NIST 201 PIV protocol, which sits on top of FIPS140 cryptography. In the applet, all cryptographic operations are handled by the Java Card operating system, implemented by the NXP JCOP 4 card.
The VxAdmin / VxCentralScan HP uses an NPCT75x TPM 2.0 chip by Nuovoton.
This chip is FIPS140-2-certified: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4411.
The VxMark board uses an SLB 9665 TPM 2.0 chip by Infineon.
This chip is FIPS140-2-certified: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/2959.
The VxScan board uses an SLB 9670 TPM 2.0 chip by Infineon.
This chip is FIPS140-2-certified: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3492.
We use OpenSSL 3.0.9 and install the FIPS provider, per these instructions. In the basic configuration wizard run on first boot after imaging, we run the mandatory openssl fipsinstall
command to ensure that the FIPS provider is configured correctly and OpenSSL is running in FIPS mode.
This provider is FIPS140-2-certified: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4282.
FIPS-compliance of all OpenSSL operations is guaranteed as follows:
FIPS compliance via hardware modules: For relevant operations, OpenSSL outsources cryptographic operations to the TPM 2.0 chip, and as noted above, all of our TPM 2.0 chips are FIPS-compliant.
FIPS compliance via software modules: For all other operations, OpenSSL uses the FIPS provider. Our OpenSSL config guarantees this.
VxSuite does not use encryption to secure data (election definitions, CVRs) while in transit on USB drives because that data does not need to be confidential – and in fact trust in a voting system is better achieved by transparency of this data. In particular, CVRs stored on USB drives are not encrypted so that they can be viewed using any computer. This is by design.
On the other hand, VxSuite strongly authenticates all data, which is critical. Thus, election definitions and CVRs are in plaintext on the USB drives that transfer them, accompanied by strong digital signatures, generated by signing keys stored in hardware TPMs.
VxSuite does encrypt data at rest on machines' internal drives, specifically their /var
partitions, per #protecting-critical-read-write-data.
All digital signatures for authenticating election definitions and CVRs are generated using ECC 256-bit keys, that further use the NIST standard P-256 curve.
All hashes – for generating election IDs, digesting data before signing, constructing the Merkle-tree hash for CVRs, and constructing the dm-verity system integrity hash – are generated using the NIST standard SHA-256.
Encryption of disk partitions is done using AES with 256-bit keys in XTS mode.
Secure Boot code signing uses RSA 4096-bit keys.
When a VxSuite machine exports data to a USB for another VxSuite machine to import, the first machine digitally signs that data so that the second machine can verify its authenticity. We use this mechanism in two places in particular:
To authenticate election definitions/packages — These configuration bundles are exported by VxAdmin and used to configure VxCentralScan, VxMark, and VxScan.
To authenticate cast vote records — These are exported by VxCentralScan and VxScan and imported by VxAdmin for tabulation.
The exporting machine digitally signs the following message using its TPM private key:
MESSAGE_FORMAT_VERSION + “//” + ARTIFACT_TYPE + “//” + ARTIFACT_CONTENTS
It then outputs the following to a .vxsig file:
SIGNATURE_LENGTH + SIGNATURE + SIGNING_MACHINE_CERTIFICATE
The importing machine parses the above and verifies that the signing machine certificate in the .vxsig file is a valid certificate that is signed by VotingWorks, using the VotingWorks CA certificate installed on every machine. The importing machine then extracts the exporting/signing machine’s public key from this certificate, reconstructs the message, and verifies the signature. After this, the importing machine performs artifact-specific authentication checks, e.g., that the signing machine cert is a VxAdmin cert if the artifact is an election package.
If verification fails on the importing machine, the importing machine will refuse to import the artifact. This provides protection against data tampering and/or corruption as data is transferred from one machine to another via USB drive.
Refer to the following code links for more details:
https://github.com/votingworks/vxsuite/tree/v4.0.0-release-branch/libs/auth — VxSuite authentication lib, a good starting point for all things authentication
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/artifact_authentication.ts — Artifact authentication logic
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/cryptography.ts — OpenSSL commands underlying various authentication and signing operations
VxSuite can be operated securely using the following these procedures. Some of these procedures are intentionally redundant for defense-in-depth as it is always expected that some operational mistakes are made.
VxSuite should be used only with sanctioned equipment and peripherals. In particular, when connecting USB devices to any VxSuite component, use only USB devices of the type specified in this documentation, and only devices of known and reputable source.
When there are no active elections happening, VxSuite equipment should be physically secured so it is difficult to access and so that any access is evident at a later date.
VxAdmin laptop and peripherals should be kept in their case, with numbered seals through both case seal points, preventing the case from being opened without breaking one or both seals.
VxCentralScan laptop and peripherals should be kept in their case, with numbered seals through both case seal points, preventing the case from being opened without breaking one or both seals.
The small Fujitsu/Ricoh scanner that works with VxCentralScan should be kept in its supplied soft case, with a numbered seal through the appropriate zipper hole, preventing the case from being opened without breaking the seal.
The larger Fujitsu/Ricoh scanner that works with VxCentralScan should be kept in its supplied manufacturer box, with tamper evident tape along all sides and a numbered sticker seal on the main opening.
VxScan should be kept closed with a numbered seal through one of the two seal points, preventing the case from being opened without breaking the seal.
VxAdmin, VxCentralScan, VxScan, and the Fujitsu/Ricoh scanner, once sealed, should be kept in a safely locked room or storage area that only authorized election administrators have access to.
The system admin smart cards should be kept in a safe or locked drawer, separately from VxAdmin. The PIN for the system admin smart card, if recorded on paper, should also be kept locked separate from both VxAdmin and the card.
You may consider occasionally resetting the PIN on the system administrator cards. This can be done using the VxAdmin laptop.
Both VxAdmin and VxScan are required for Logic & Accuracy testing. VxCentralScan is required if it is planned to be used for counting absentee ballots. VotingWorks's recommended practices take into account that this testing is often performed in view of the public.
When retrieving all components from their locked storage location, ensure that the seal numbers match the logs.
Keep clear and strong custody of all smart cards.
Use the system admin card only long enough to un-configure VxAdmin, VxScan, and VxCentralScan from the last election, and to program VxAdmin for the new election. Then return the system admin card to its secure storage.
At the end of L&A testing, ensure that the VxScan is ready and secured for election day:
the correct USB drive is inserted into one of the two USB slots.
the system has been switched to official-ballot mode.
the VxScan is powered down.
the VxScan case is closed and sealed.
If using VxCentralScan, ensure that that:
it is switched to live mode
it is shut down and put away in its case
the case is closed and sealed.
Store all L&A'ed equipment, with recorded seal numbers, in a secure location until election day.
Ensure that seals on equipment are untouched and appropriately numbered since L&A.
After setting up VxScan on the ballot box and opening the polls, ensure that:
the ballot box is locked and/or sealed
the auxiliary ballot box is locked and/or sealed
the VxScan is attached to the ballot box using the locking mechanism
the poll-worker access door on the VxScan is sealed shut
All seal numbers should be recorded.
A poll worker should observe VxScan from afar at all times, ensuring voters are not attempting to break any seals.
If a ballot jam requires opening the poll worker door or the ballot box door, record the corresponding seal number before breaking, and ensure resealing afterwards, recording the new seal number(s).
VxCentralScan is only meant to be accessed by authorized election administrators. However, it is safe to project the screen via overhead projector, as long as the smart card PIN is entered via the keyboard, and not via the mouse.
Unsealing the poll worker door is required to extract the USB drive after polls are closed. Ensure the seal number matches the expected value. Once the polls are closed and the USB drive is removed, take care to secure the chain of custody of the USB drive. VxScan should be closed up and sealed.
Pack up all components in their respective cases and apply seals. Record those seals.
Additionally, any auditing or review of audit logs should be completed immediately after exporting those logs from the VxScan or Central system to a USB. If there is a concern about a break in the administrative chain of custody, the user should re-export the logs to a USB from the machine and can compare the original export with the re-export to determine the logs have not been tampered with while on the USB. The logs maintained on the system are unalterable and should be pulled and reviewed in one process to ensure that chain of custody is maintained.
VxSuite is composed of individual machines, namely VxAdmin, VxCentralScan, VxMark, and VxScan, as well as smart cards for authentication. Each machine and each smart card has a unique 256-bit ECC private key (or keys in the case of smart cards) stored in tamper-resistant hardware, plus one or more X.509 certificates for the corresponding public key (or keys) with relevant attributes bound.
This means that every VxSuite component can prove its authenticity, notably to any other VxSuite component. For example, a smart card can prove to a VxAdmin that it is a valid election administrator card for a particular election, or a VxScan can export digitally signed cast vote records, which a VxAdmin can then verify are authentic before importing.
Certification relationships work as follows:
VotingWorks directly certifies the type of every component, i.e., VxAdmin machine, VxCentralScan machine, VxMark machine, VxScan machine, or smart card. This makes it such that only components that are “blessed” by VotingWorks can successfully communicate with each other. This is also important for defense-in-depth and separation of privileges, as one VotingWorks component type cannot act like another, e.g., a VxScan cannot sign an election configuration package like a VxAdmin can. Because machine certificates include a machine ID, it's also the case that, say, VxScan SC01 cannot sign CVRs as VxScan SC02.
VotingWorks further certifies every VxAdmin as bound to a particular jurisdiction, e.g., Warren County, Mississippi. This is important because VxAdmins program smart cards and should not be able to program cards for other jurisdictions.
Every smart card, in addition to being certified directly by VotingWorks, is certified by a VxAdmin during card programming. A card’s VxAdmin-issued certificate indicates 1) the jurisdiction that the card is bound to, 2) which user role the card has been programmed for, i.e. system administrator card, election manager card, or poll worker card, and 3) in the case of election manager and poll worker cards, the specific election that the card is bound to.
As a diagram:
VxCentralScan, VxMark, and VxScan, unlike VxAdmin, aren’t bound to a jurisdiction by VotingWorks. They’re bound and unbound to jurisdictions as they’re configured and unconfigured by election managers. When an election manager configures a VxCentralScan, VxMark, or VxScan for an election, the machine persists in its datastore the jurisdiction of the election manager card used to unlock it and then only accepts cards from that jurisdiction. When the machine is unconfigured for that election, the machine returns to a jurisdiction-agnostic state. This allows one jurisdiction to lend its unconfigured equipment to another, without giving a jurisdiction any power over machines configured for a different jurisdiction.
As described above, programmed smart cards have two certificates, one issued by VotingWorks and one issued by VxAdmin. We generate two key pairs on the card, one for each certificate. We could have chosen to certify the same key twice, but as will be described below, we wanted to have different usage policies for the two private keys, thus the issuance of certificates against two different keys. Smart cards also have PINs (with the exception of poll worker cards, unless an election official chooses to enable poll worker card PINs). These interface as follows:
The private key slot associated with the card’s VotingWorks-issued certificate is not PIN-gated, so anyone can immediately verify that a card is a VotingWorks-certified card.
The private key slot associated with the card’s VxAdmin-issued certificate is PIN-gated, so authentication requires PIN entry.
The card’s VxAdmin-issued certificate, on the other hand, is not PIN-gated, so it’s possible for a VotingWorks machine to know the card’s type and which election it’s bound to even before a PIN is entered. This allows the machine to display error messages like “election mismatch” immediately after card insertion and before PIN entry.
This does mean that an attacker could load a fake certificate onto a card such that the machine, at worst, displays an incorrect error message, but nothing more. Authentication would still fail as the public key in the certificate would not match the private key on the card. We take care not to fully trust the information in this certificate until we complete authentication.
We’ve taken inspiration from the NIST Personal Identity Verification (PIV) standard but haven’t strictly adhered to it. Our use case differs from the PIV standard in a number of ways, most notably in that cards are certified by two entities (VotingWorks and VxSuite), rather than just one. We also don’t need VxSuite smart cards to be interoperable with other PIV systems.
There's one additional card type, the vendor card, and it differs slightly in its cert structure from the other card types. VotingWorks uses vendor cards to access the vendor menu on machines, for low-level operations like machine key rotation. Vendor cards are programmed directly by VotingWorks and not by VxAdmin. Because of this, vendor cards do not have a VxAdmin-issued cert, but rather, a second VotingWorks-issued cert. The general term that we use for this second cert across all card types is the identity cert, as it confers user role, i.e., identity.
Vendor cards can be programmed to be either jurisdiction-specific or jurisdiction-agnostic.
We store our root VotingWorks certificate authority (CA) private key encrypted in a password vault, usable only by a few authorized engineers.
VxAdmin, VxCentralScan, VxMark, and VxScan are all built on devices with a Trusted Platform Module (TPM) 2.0, a chip that ships standard on modern Intel and AMD hardware. The TPM can keep cryptographic material secret inside its tamper-resistant boundary until a certain set of system conditions are met. Only once the TPM determines that the system meets a set of appropriate conditions—correct bootloader, kernel, kernel command line, etc.—does the TPM allow an application to ask it to perform signing operations with its contained secret key.
Our smart cards are JCOP 4 Java Cards, version 3.0.5. These Java Cards can generate 256-bit ECC key pairs such that the private key never leaves the card, while the public key is exported. The cards are capable of self-destructing if someone attempts to extract the private key at the hardware level.
Vendor cards, system administrator cards, and election manager cards always have PINs. Poll worker cards do not have PINs by default but can if the system administrator enables them.
PINs are auto-generated random 6-digit numbers, guaranteed not to be weak (e.g. not 11111, 123456, 121212).
After 5 incorrect PIN attempts, users have to wait 15 seconds before they can try again. For every incorrect PIN attempt after that, the wait time doubles (15 seconds → 30 seconds → 60 seconds and so on). After 15 incorrect PIN attempts, the card is completely locked and has to be reprogrammed. System administrators can adjust the number of incorrect PIN attempts allowed without lockout as well as the starting lockout duration. The number of incorrect PIN attempts is stored on the card in a tamper-resistant location (as opposed to on the machine), meaning that taking a card to another machine to gain extra attempts will not work. Removing and reinserting a card restarts the lockout timer.
The certificates that we use are effectively vouchers—a certificate authority (CA) vouches that a public key has certain properties, for example that it is the public key of an election manager card for a particular election. This vouching is done by signing data containing the public key and those properties. We use X.509 certificates as they are broadly used and well supported.
While we could use existing X.509 fields like Organization, Organizational Unit, and Serial Number, and wedge our data into those types, overloading existing fields that don’t quite match isn’t ideal and could lead to security issues from type confusion.
Instead, we use our own fields. We’ve registered with IANA to have a VotingWorks enterprise object identifier (OID), which is effectively a prefix for OIDs of the form 1.3.6.1.4.1.32473.123, where 1.3.6.1.4.1.32473 is the enterprise OID for an example organization, and 123 is the 123rd field defined by that organization.
Our IANA-assigned Private Enterprise Number (PEN) is 59817, which means that the enterprise OID, fully-prefixed, is 1.3.6.1.4.1.59817. See https://www.iana.org/assignments/enterprise-numbers/?q=59817.
Our custom fields are:
1.3.6.1.4.1.59817.1 — Component = admin, central-scan, mark-scan, scan, or card (the first four referring to machines)
1.3.6.1.4.1.59817.2 — Jurisdiction = {state-2-letter-abbreviation}.{county-or-town} (e.g., ms.warren or ca.los-angeles)
1.3.6.1.4.1.59817.3 — Card type = vendor, system-administrator, election-manager, poll-worker, or poll-worker-with-pin (vendor, system administrator, and election manager cards always have PINs)
1.3.6.1.4.1.59817.4 — Election ID = The ID of the election that an election card was programmed for*
1.3.6.1.4.1.59817.5 — Election date = The date of the election that an election card was programmed for
1.3.6.1.4.1.59817.6 — Machine ID = A VxAdmin, VxCentralScan, VxMark, or VxScan machine ID
*This is not the same election ID as displayed in machine footers. The election ID as it pertains to cards is the id
field in the election definition. The election ID as it pertains to machine footers is actually a hash, specifically <first-7-digits-of-hash-of-election-json>-<first-7-digits-of-hash-of-election-zip>
. The reason for not using the latter in card certificates is to avoid having to reprogram cards after election package edits for what is conceptually still the same election.
X.509 certificates eventually expire. We use the following expiry times:
Certificates directly issued by VotingWorks: 100 years
VxAdmin-issued system administrator card certificates: 5 years
VxAdmin-issued election manager and poll worker card certificates: 6 months
VotingWorks-issued vendor card certificates: 7 days
This means that system administrator cards will automatically expire after 5 years, election manager and poll worker cards will automatically expire after 6 months, and vendor cards will automatically expire after 7 days.
Configuration of VxSuite components begins at a secure VotingWorks facility. At this facility is a VotingWorks certification terminal, VxCertifier. VxCertifier is a fully offline air-gapped terminal with access to the root VotingWorks private key.
Using VxCertifier, VotingWorks prepares and certifies smart cards for use with VotingWorks machines:
VotingWorks installs the appropriate security module code on the card.
VotingWorks instructs the smart card to generate a key pair and export the public key.
The root VotingWorks CA certifies the card public key and saves the resulting certificate onto the card.
The card is now VotingWorks-certified but “blank” from the perspective of VotingWorks machines.
VotingWorks also certifies its machines at this facility. After a machine has been imaged with our latest software release, the machine boots into a configuration wizard. The software image includes the root VotingWorks CA certificate, so no extra work is required beyond imaging to “install” that certificate. Using the configuration wizard and VxCertifier, VotingWorks certifies machines:
VotingWorks machine code instructs the machine’s TPM to generate a key pair and export the public key.
VotingWorks machine code generates a certificate signing request (CSR) for that public key and writes the CSR to a USB drive.
On VxAdmin, VotingWorks additionally specifies a jurisdiction. That jurisdiction is included in the CSR.
The USB is plugged into VxCertifier. Through VxCertifier, the root VotingWorks CA certifies the machine public key and saves the resulting certificate onto the USB drive.
VxAdmin certificates are themselves CA certificates capable of creating additional certificates (necessary for smart card programming).
The USB drive is plugged back into the machine to be certified. The machine loads the certificate from the USB drive, verifies its correctness, and saves it onto its hard drive.
On VxAdmin, the configuration wizard also surfaces a prompt to program a first system administrator card to bootstrap the jurisdiction as, from here on out, the machine will need to be unlocked by a system administrator card in order to program any other cards.
Machines, a first system administrator card, and “blank” cards are shipped to jurisdictions.
In the field, election officials use their VxAdmin and their first system administrator card to program additional smart cards. Smart card programming involves the following steps:
VxAdmin retrieves the card’s VotingWorks-issued certificate and verifies that it was signed by VotingWorks using the VotingWorks CA certificate installed on every machine.
VxAdmin resets the card PIN, which further causes the card to clear all of its PIN-gated key slots, essentially unprogramming it if it was previously programmed.
VxAdmin instructs the card to generate a key pair and export the public key. This key pair is distinct from the key pair that VotingWorks generated.
The VxAdmin CA certifies the card public key, assigning relevant attributes like the jurisdiction, card type, and election if applicable, and saves the resulting certificate to the card.
VxAdmin also saves its own CA certificate onto the card (more on how this is used under Authentication).
Smart card authentication involves the following steps:
The machine retrieves the card’s VotingWorks-issued certificate and verifies that it was signed by VotingWorks using the VotingWorks CA certificate installed on every machine.
The machine retrieves 1) the card’s VxAdmin-issued certificate and 2) the certificate of the VxAdmin that programmed the card, which as noted in Smart Card Programming is also loaded onto the card. The machine verifies that the former (1) was signed by the latter (2). The machine also verifies that the latter is a valid VxAdmin certificate signed by VotingWorks using the VotingWorks CA certificate, establishing a chain of trust all the way up to a trusted root.
The machine verifies that the card has a private key that corresponds to the public key in the card’s VotingWorks-issued certificate by asking the card to sign a challenge with its private key and attempting to verify it with the public key.
The machine verifies that the card has a private key that corresponds to the public key in the card’s VxAdmin-issued certificate by asking the card to sign a challenge with its private key and attempting to verify it with the public key.
If the card has a PIN, the card will only proceed with this signature if provided the appropriate PIN. The VotingWorks machine thus asks the user for their PIN to perform this operation.
Throughout this process, the machine verifies that certificate fields are valid and consistent. It also verifies that the card jurisdiction and election match the machine jurisdiction and election, where relevant.
Machines automatically lock after they’ve been left idle for 30 minutes and also automatically lock after 12 hours, even if the user has been active. The user is given appropriate heads up. System administrators can select shorter time limits.
These time limits do not apply to unauthenticated screens like the “Insert Your Ballot” screen on VxScan.
Refer to the following code links for more details:
https://github.com/votingworks/vxsuite/tree/v4.0.0-release-branch/libs/auth— VxSuite authentication lib, a good starting point for all things authentication
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/dipped_smart_card_auth.ts — High-level authentication state management for VxAdmin and VxCentralScan
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/inserted_smart_card_auth.ts — High-level authentication state management for VxScan
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/java_card.ts — Java Card implementation
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/certs.ts — Certificate configuration
https://github.com/votingworks/vxsuite/blob/v4.0.0-release-branch/libs/auth/src/cryptography.ts — OpenSSL commands underlying various authentication and signing operations
https://github.com/votingworks/vxsuite-complete-system/blob/v4.0.0-rc2/config/vendor-functions/basic-configuration.sh — The production machine configuration wizard
https://github.com/votingworks/vxsuite/tree/v4.0.0-release-branch/libs/auth#scripts — A summary of the scripts in the authentication lib, many of which are used for production configuration
https://github.com/votingworks/openfips201 — The applet that we’re installing onto our Java Cards
In addition to the processes in , VxSuite employs the following physical security controls for each component.
VxAdmin laptops are stored and transported in a case with two tamper-evident seal points to detect any unauthorized physical access.
VxAdmin laptops have a tamper evident adhesive seal on the laptop itself to detect any unauthorized physical access to the laptop internals.
VxAdmin laptops BIOS configurations do not allow the machine to boot if the laptop itself is opened without entering a vendor-only password & returning the device to VotingWorks.
VxAdmin has no exposed ports that are not used for voting system operations. VxAdmin's printer has an ethernet port blocker installed.
VxCentralScan laptops are stored and transported in a case with two tamper-evident seal points to detect any unauthorized physical access.
VxCentralScan laptops have a tamper evident adhesive seal on the laptop itself to detect any unauthorized physical access to the laptop internals.
VxCentralScan laptops BIOS configurations do not allow the machine to boot if the laptop itself is opened without entering a vendor-only password & returning the device to VotingWorks.
VxCentralScan has no exposed ports that are not used for voting system operations. VxCentralScan's attached batch-scanner (fi-8170) has an ethernet port blocker installed.
VxScan has two external tamper-evident seal points to detect any unauthorized physical access.
VxScan has three interior adhesive tamper-evident seals (1 on top panel; 2 on bottom panel) to detect any unauthorized access to the device internals.
VxScan has a tamper-evident seal point at the intersection of the poll worker door and security bolt to ensure secure ballot box attachment and detect any unauthorized access to poll worker functions.
VxScan's ballot box has a seal point for each ballot storage area (main & auxiliary compartments) to detect any unauthorized access to cast ballots.
VxScan triggers a visual & audible alert when a USB drive is removed in an activated state to alert any unauthorized access.
VxScan has no exposed ports when the poll worker door is sealed.
VxMark transport & storage cases have tamper-evident seal points to detect any unauthorized physical access.
VxMark has an adhesive tamper-evident seal behind the touchscreen to detect any unauthorized physical access to the device internals.
VxMark ballot box has a tamper-evident seal point to detect any unauthorized access to cast ballots and the printer-scanner.
VxMark triggers a visual & audible alert when the printer-scanner and/or printer-scanner cover is opened in an activated state to alert any unauthorized access.
VxMark has no exposed ports when the ballot box is attached and sealed. An ethernet port blocker is also installed on the ethernet port accessible when the ballot box is detached.
Beyond the application-level protections and system integrity assurances built to ensure that unauthorized access is thwarted and unauthorized software cannot be executed, VxSuite is also designed with defense-in-depth and least-privilege principles. This ensures that a failure of some defenses, due to unforeseen bugs or novel attacks, can be limited in its impact.
VxSuite runs a modern, stripped down Linux installation with the minimum number of packages to reduce the attack surface of any unexpected partial penetration. The set of packages is manually curated by our team and specified in our installation manifests when building a base Linux image.
The Linux OS makes use of data execution prevention (DEP) and address space layout randomization (ASLR). These exploit mitigation strategies provide a low-level layer of protection against a variety of vulnerabilities. We have verified that these mechanisms are active via the following commands:
Once a VxSuite image is built, access for the root user is shut down and that shutdown is locked in via secure-boot verification of the root partition.
When a VxSuite function requires superuser access, that access is captured as a minimal shell script, and the appropriate VxSuite Linux user is granted sudo permissions on that shell script alone. For example, on a VxSuite production machine, no user has the ability to call the mount
command. Instead, when mounting USB drives, we have crafted a shell program that is only capable of mounting and unmounting USB drives at the /media/usb-drive
mount point, and the vx-services
user is granted superuser privileges when calling that script only. The full script for this example is available at .
VxSuite runs a minimal window manager, Openbox, which is built to have very few capabilities. In addition, we configure Openbox so as to turn off all keyboard shortcuts and contextual menus. Even if an attacker were able to plug in a mouse or a keyboard, they would be unable to get very far.
All processes that a user can directly interact with in VxSuite run as user vx-ui
. The processes that access the smart card reader or perform data processing services run as user vx-services
.
The vx-services
Linux user has a set of permissions allowing it to access the scanner, printer, and smart card reader. It is configured, like the root user, to not have a password, so no interactive user can log in as vx-services
and utilize those privileges for nefarious purposes. The services that run under the vx-services
user account offer their services over local HTTP, with well-formed semantics as to what actions they allow. The authentication status is checked on the backend, by vx-services
, so actions can only be taken if a valid authentication session is open.
Meanwhile, if a user were to break out of the constraints we've placed on the window manager and obtain a shell, that shell would run as vx-ui
, which as the ability to call into services run as vx-services
, but does not itself have the direct privileges of vx-services
. Thus, an attacker that penetrates the first line of defense would remain severely thwarted in what they can do next.
VotingWorks' vulnerability disclosure policy is publicly available here:
The public disclosure policy provides instructions on how to report a vulnerability, where to see known vulnerabilities, and the coordinated vulnerability disclosure process VotingWorks follows.
Given the protection mechanisms we use to prevent unauthorized software from running on VxSuite components, the simplest way to perform a vulnerability scan is to use Nessus in a host operating system, with VxSuite components running as guest virtual machines (VMs). We turn off our networking blocks on those VMs for the sake of performing a useful vulnerability scan.
On each of these components, the same vulnerabilities are found by Nessus. There are 15, and they are all in the "Info" category of vulnerability, meaning that they only allow for information gathering about the host, not for any corruption or direct attack. All of these issues are listed here, with an explanation as to why they are not vulnerabilities of concern.
All VxSuite applications use the same framework to log user actions, application processes, and errors. The logs are persisted to disk and can be exported by election managers or system administrators.
VxSuite applications use a to capture required or otherwise important application log events. The core metadata for each application log event maps roughly to VVSG 2.0 standards, with some additional fields:
Log Event ID - Internal identifier for each event. The full list of log event IDs with descriptions is included in the automatically generated .
Log Event Type - Describes whether the event is a status update or an action, and whether it originated with the user, application, or larger system. The full list of log event types with descriptions is included in the automatically generated .
User - If there was an authenticated user role at the time of a user action, describes the role as system_administrator
, election_manager
, poll_worker
or vendor
. If no user was authenticated, then unknown
. If event does not originate from the user but rather automatically from the application or operating system, it will be system
.
Disposition - For actions that can fail or succeed, success
or failure
. Otherwise na
for not applicable.
Source - Indicates where in the system's architecture the log came from, whether it be the frontend renderer, the frontend server, the backend server, a hardware daemon, or the operating system.
Message - The log message itself, which may not be present if the log event ID sufficiently describes the event.
Other Metadata - Other metadata can be freely included. For example, if a user adds manual tallies on VxAdmin, the metadata of those manual tallies will be included in the logging.
Time Written - Timestamp of when the log was created.
The shared logging library formats the log events as JSON and pushes them to application processes' stdout
. All stdout
output from the application processes - both the application log events and any process output - is sent to the system's logger
utility and assigned the tag votingworksapp
.
VxSuite uses rsyslog
, an advanced implementation of the Syslog protocol, to centralize and manage logs from votingworksapp
and other sources. rsyslog
has advantages over the built-in Linux syslog
implementation of the Syslog protocol, including JSON structured messages, advanced filtering, and increased performance. Using rsyslog
, different types of logs are directed to different log files in /var/log/votingworks/
:
vx-logs.log
is the most important and informative file in most cases. The other files rarely need to be referenced. All logs required by VVSG certification will exist in vx-logs.log.
Because each log file can grow very large, the application will rotate logs if necessary with the logrotate
utility on each startup. Previous log files will be compressed and suffixed with a timestamp.
Including the various log files and log rotation, below is an example of the list of log files that might appear on a device:
Logs can be exported in CDF format, in which case the vx-logs.log
file is replaced by a vx-logs.cdf.json
file with the logging attributes mapped as follows:
The log export flow exposed in all VxSuite applications also allows for exporting an errors-only version of the logs. This will only export a log file for logs where the disposition is "failure" and covers all software and hardware errors that have occurred on the machine.
VxSuite can be audited using post-election audits, including a ballot-comparison or batch-comparison risk-limiting audit, or an image audit.
In a ballot-comparison risk-limiting audit, the goal is to compare, for a random sample of the cast ballots, the paper ballot and the corresponding cast-vote record. The specifics of sample selection and risk-limit calculation are out of scope for this document – VotingWorks Arlo or other RLA tool may be used for this purpose.
To enable a ballot-comparison risk-limiting audit, VxSuite provides:
imprinting of ballots on VxCentralScan, with a unique identifier of the form
<BATCH-ID>_<SEQUENCE-NUM>
cast-vote records including the field BallotAuditId
which matches the imprinted identifier
Then, to run a ballot-comparison risk-limiting audit with VxSuite:
scan all ballots with VxCentralScan and the imprinter module on the Ricoh scanner. See .
store ballots by batch, recording the batch ID displayed on VxCentralScan display. Storing ballots in the order they were scanned is helpful for later retrieval, but not strictly necessary since the sequence numbers printed on the ballots can be used to recover the proper order.
export CVRs from all the VxCentralScan's
use VxAdmin to aggregate CVRs, adjudicate write-ins, and generate final tallies
aggregate tallies and CVRs at the audit jurisdiction level, most often the State
input the CVRs and tallies into a risk-limiting audit tool
the RLA tool will generate a sample of ballots to audit
retrieve the selected ballots by batch ID and sequence number
enter the interpretation of those ballots into the RLA tool
the RLA tool will either declare the audit successful or require an escalation. The RLA tool will ultimately declare the election a success or call into question how ballots were interpreted.
In a batch-comparison risk-limiting audit, the goal is to compare, for a random sample of ballot batches, the hand tally of that batch with the corresponding batch tally. The specifics of sample selection and risk-limit calculation are out of scope for this document – VotingWorks Arlo or other RLA tool may be used for this purpose.
To enable a batch-comparison risk-limiting audit, VxSuite provides:
Tallies partitioned by scanner and/or by batch in VxAdmin
Ballot counts by scanner and by batch in VxAdmin
Then, to run a batch-comparison risk-limiting audit with VxSuite:
scan ballots either with VxScan or VxCentralScan. No need to use imprinting for VxCentralScan.
store ballots by batch – where a batch in VxCentralScan is indicated by the batch ID on screen, and a batch in VxScan is the entire set of ballots scanned by a single VxScan over the course of the election. Order of the ballots need not be maintained in either case.
export CVRs from all VxCentralScans and gather the CVRs on USB drives from all VxScans
use VxAdmin to aggregate CVRs, adjudicate write-ins, and generate final tallies
produce ballot counts by scanner and by batch on VxAdmin – these are effectively contest totals by batch files in auditing language.
aggregate tallies and ballot manifests at the audit jurisdiction level, most often the State.
input tallies and ballot manifests into the RLA tool
the RLA tool will generate a sample of batches to audit
retrieve the batches and recount them by hand – usually only for one or two contests, as directed by the audit procedure
enter the hand-count batch tallies into the RLA tool
the RLA tool will either declare the audit successful or require an escalation. The RLA tool will ultimately declare the election a success or call into question how ballots were interpreted.
In an image audit, various risk-limiting audit procedures are used, but instead of physically retrieving the ballots to audit, the scanned image of the ballot is used.
VxSuite supports image audits very simply – every VxScan and VxCentralScan produces images of the scanned ballots that can be immediately associated with the interpreted CVR. Thus, the protocols defined above for ballot-comparison and batch-comparison audits can be used, with the following simplification:
imprinting is unnecessary
instead of "retrieving a ballot", simply look up the image files corresponding to the CVR ID and interpret on screen
The default VotingWorks log format is how logs are formatted when emitted from the application and how they appear in vx-logs.log
. It is a direct mapping of the fields.
A full list of all logs made in the system with a description of each one can be found . For convenience a table is provided below mapping Table 15-1 from VVSG 2.0 Requirement 15.1-D to the appropriate logs in the VotingWorks system. The details and descriptions provided in Table 15-1 have been simplified for brevity in this table. Some items have been expanded into multiple rows to more precisely specify linked logs.
ElectionEventLog.GeneratedTime
ISO formatted timestamp of when logs were exported
ElectionEventLog.Device
List containing only the current device
Device.Type
The CDF DeviceType
matching the type of machine:
VxAdmin -> "ems"
VxScan -> "scan-single"
VxCentralScan -> "scan-batch"
VxMark -> "bmd"
Device.Id
The serial number of the device
Device.Version
The software version e.g. "v3.1.2"
Device.Event
List of all events
Event.Id
A VotingWorks defined identifier for the type of event, such as "save-election-package-complete"
Event.Disposition
"success", "failure", "na", or "other"
Event.OtherDisposition
If the disposition is "other", the details appear here
Event.Sequence
The index of the log in the list of logs, zero-indexed
Event.TimeStamp
ISO formatted timestamp of when the event was logged
Event.Type
Log event type
Event.Description
Log message
Event.Details
JSON including the log source and any additional logging metadata
Event.UserId
The user at the time of the log
Device generated error and exception messages
Errors can be logged with any LogEventId but are indicated by a Disposition of failure
. All logs contain a Source. Every error is logged when it occurs and each log can be assumed to correspond to one instance of that error occurring unless otherwise stated in the log.
VxScan violations of physical security include scanner cover open logs: scanner-state-machine-event
scanner-state-machine-transition VxScan violations of physical security include scanner cover open logs: mark-scan-state-machine-event
Critical system status messages
diagnostic and status messages upon startup
Critical system status messages
"zero totals" check
Critical system status messages
the initiation or termination of scanner and communications equipment operation
Critical system status messages
Printer errors
paper-handler-state-machine-transition
With disposition of failure
Critical system status messages
Detection or remediation of malware or other malicious software
The system will not boot if malicious software is detected. dmverity-boot
Critical system status messages
Cryptographic boot validation success/failure
Non-critical status messages
Events that require election official intervention
Device shutdown and restarts
Changes to system configuration settings
It is not possible to change these configuration settings any attempt to do so will result in a sudo-action log.
Integrity checks for executables, configuration files, data, and logs
election-configured and import-cast-vote-record-complete logs will have failures if there were errors authenticating the files.
The addition and deletion of files
System readiness results
Removable media events
Backup and restore
Authentication related events
Login/logoff events
Account lockout events
Password changes
Access control related events
User account and role (or groups) management activity
Programming smart cards to create new user accounts: smart-card-program-complete. All other security changes can only be made through configuring a new election-package with those settings: election-configured. Attempts to bypass or make changes to roles or permissions outside of this will not be allowed and result in a sudo-action and/or password-change log.
Enabling or disabling networking functionality
It is not possible to enable wired or wireless networking. Any attempt to bypass protections in place blocking this will result in an error and a sudo-action log.
Installing, upgrading, patching, or modifying software or firmware
Changes to configuration settings
Abnormal process exits
Successful and failed database connection attempts (if a database is uses)
Changes to cryptographic keys
Ballot definition and modification
Voting events
Opening and closing polls
Voting events
Casting a vote
VxMark: vote-cast VxScan: scanner-state-machine-event with the event "scanStart" to indicate the voter has started feeding a ballot. If the voter has to cast from adjudication there will be an "Accept" event.
Voting events
Canceling a vote during verification
VxMark: ballot-invalidated VxScan: scanner-state-machine-event with event "Reject"
Voting events
Success or failure of log and election results exportation
ICMP Timestamp Request Remote Date Disclosure
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, it only allows an attacker to collect the current clock of the machine, which is not a problem.
Common Platform Enumeration (CPE)
This only indicates that a particular Nessus plugin is running to determine platform properties.
Device Type
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, it only allows an attacker to determine what kind of devices this is (manufacturer, CPU power, etc.). This is considered public information, so is not a threat.
Ethernet MAC Addresses
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, it only allows an attacker to determine the MAC address of an Ethernet port, which isn't a threat.
HTTP Methods Allowed (per directory)
With networking protections in place like they are on a production machine, this issue would not exist. VxSuite uses HTTP internally within each component, so with networking protections turned off, it is obvious that allowed HTTP methods can be detected. This isn't an issue on a production system.
HyperText Transfer Protocol (HTTP) Information
With networking protections in place like they are on a production machine, this issue would not exist. Even if an attacker accessed this information, it isn't confidential.
KVM / QEMU Guest Detection (uncredentialed check)
This finding isn't relevant on a production machine, which is not a VM. This is a VM only because of the vuln-scan testing setup.
Nessus SYN scanner
With networking protections in place like they are on a production machine, this issue would not exist.
Nessus Scan Information
This only indicates that a particular Nessus plugin is running to determine running services.
OS Identification
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, it only allows an attacker to determine the operating system running on a VxSuite component, which is already public information.
Service Detection
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, the services that are running on a VxSuite component are publicly documented and it is not considered a threat for an attacker to know them.
TCP/IP Timestamps Supported
With networking protections in place like they are on a production machine, this issue would not exist. Even if it did, this only allows an attacker to determine the uptime of the VxSuite component, which is not confidential information.
Traceroute Information
With networking protections in place like they are on a production machine, this issue would not exist.
Web Server No 404 Error Code Check
The web server in question is used only for internal purposes of the VxSuite component, it is never presented as a public web site. Thus, whether it returns a 404 code or not is not important.
Web Server robots.txt Information Disclosure
The web server in question is used only for internal purposes of the VxSuite component, so the robots.txt file is irrelevant.
vx-logs.log
Key logs required by VVSG 2.0 or otherwise critical for understanding the behavior of the application or device, including:
all application log events
USB device connection events
machine boot and shutdown events
all sudo
actions
password events
dm-verity
events
auth.log
All operating system authentication-related events. Note that this will not include voting system authentication events such as logging in with a smart card - these events are in vx-logs.log
syslog
All other events emitted from the application or the operating system that do not fall into the other log files.
There is a tension between the requirement that (a) voter privacy should be strongly protected, and (b) cast vote records should be continuously exported in order to ensure that they can be immediately available in the case of hardware failure. For example, if each scanned ballot naively results in the creation of a new CVR file on the USB drive with a timestamp, the order of CVRs is obviously preserved on the USB drive, as the file creation and modification timestamps reveal the order in which those CVRs were stored.
To meet both requirements, VxScan performs some amount of "shuffling" every time a CVR is saved to the USB drive. Every time a ballot is cast and its CVR is saved to the disk, VxScan picks one or two CVRs already stored on the USB drive and updates their creation and modification time on the USB drive. This is the digital equivalent of taking one or two random ballots from a pile and bringing them to the top of the pile. Thus, if an attacker were to view the CVRs on the USB drive, they would not be able to determine the order in which those ballots were cast, because of this constant shuffling.
Recall from Cast Vote Records that a single CVR is structured, on disk, as a directory that contains the JSON data of the CVR and the ballot images for that CVR. The VxScan operation performed to move a single CVR "up to the top of the pile" involves four steps:
Copy the CVR directory contents:
cp -r 4d6a9dad-e6d6-4a29-89bc-9ab915012b73/ 4d6a9dad-e6d6-4a29-89bc-9ab915012b73-temp/
Once copying completes, mark the new directory as complete:
mv 4d6a9dad-e6d6-4a29-89bc-9ab915012b73-temp/ 4d6a9dad-e6d6-4a29-89bc-9ab915012b73-temp-complete/
Delete the old directory:
rm -r 4d6a9dad-e6d6-4a29-89bc-9ab915012b73/
Rename the new directory:
mv 4d6a9dad-e6d6-4a29-89bc-9ab915012b73-temp-complete/ 4d6a9dad-e6d6-4a29-89bc-9ab915012b73/
This four-step operation ensures that:
All metadata for that CVR (parent directory and children files) is updated, leaving no trace as to when that CVR was first saved to disk.
If a failure occurs at any point, it is possible to recover completely without losing any data.
Refer to the following code links for more details:
VxSuite hardware contains numerous subcomponents, some of which are subassemblies containing hundreds of subcomponents themselves. Successfully building, deploying, and maintaining VxSuite requires that components be sourced from scores of suppliers. If any component cannot be procured, it could impact the ability to build the system at all. If any component is defective or compromised, it could degrade the system's performance. In that sense, every component in a voting system is critical. Certain components are more critical than others, however, and the following analysis defines our strategy for ranking components with high, medium, or low criticality.
The two primary criteria we consider when assessing criticality are ability to find alternative suppliers and relationship to sensitive election data. If we are unable to easily find alternative suppliers, the component is at least medium criticality. If the component processes sensitive election data, the component is at least medium criticality. If both are true or one is especially true, the component is high criticality. In addition, there are a number of other lesser criteria mentioned below.
Any component that processes election data is at least medium criticality because, if it fails or is compromised by a malicious actor, it could theoretically alter configuration, operation, tabulation, or aggregation which could compromise the interpretation of ballots, the tallying of votes, or voter privacy.
Example 1: Any scanner in the system, because it is responsible for recording ballot images, is a high criticality component. Defects in the scanner could produce unreliable ballot images. Sophisticated malicious attacks could alter firmware or intercept data transmission to produce altered images.
Example 2: USB cables transfer election data between components and are always at least medium criticality. USB cables are generally simple and substitutable, but highly sophisticated attacks involving manipulating data passing through a USB cable are possible.
Example 3: Power cables don't carry data to and from devices so, even though they are obviously critical to the operation of the device, they don't have a direct relationship to sensitive election data and are not more critical as a result.
Most components can be or already are manufactured by multiple manufacturers. Standard screws can be purchased from various suppliers. Custom plastic or sheet metal components can be molded or cut by any number of manufacturers. Even power cables, simple USB cables, or something like a computer mouse can easily be replaced by an equivalent.
Some essential VxSuite components are unique to a single supplier or a small set of suppliers, however, making them at least medium criticality. When there is a single supplier, the product cannot be built as designed without the support of that supplier. Additionally, a single supplier creates a direct possible supply chain attack vector.
Example 1: The embedded scanner in VxScan is manufactured and sold only by Peripheral Dynamics, Inc. Without being able to source the scanner from them, it would not be possible to build VxScan as it exists today, meaning the scanner has high criticality.
Example 2: The case that forms the exterior of VxScan is a Pelican 1485 Air case. The product is designed around the case and, without the case, the product could not be built as-is, so the case is at least medium criticality. Conceivably, an alternative could be found, but it would not be straightforward.
Example 3: The anodized sheet metal panels that form the interior surfaces of VxScan can be cut and anodized by hundreds of metal shops across the country, so they are not more critical as a result of their supply.
Any component can fail, but some component failures will be caught easily in quality control while others are more difficult to detect. For example, a misshapen sheet metal part will be caught in incoming parts QC or may result in the machine being not operable or not assemble-able. A slightly fraying cable, however, might perform adequately in QC but quickly deteriorate in performance. Components that are more complex, like a printer or cable, may exhibit deteriorated or even nefarious behavior that only manifests under certain conditions outside of QC.
Simple components where failure is easily detected are less critical than complex components where failure is more difficult to detect. Due to the complexity of a subassembly like an entire laptop, we're not able to effectively QC all of its many subsystems and have to rely on the supplier for their QC more than for a simple, transparent component.
A seal point or hinge may be more critical than an interior panel because, if it is defective, it could break the physical security model of a device and allow someone to access a machine without tamper-evidence.
In each article describing the hardware of a specific component, some section will specify the high and medium criticality components and provide some explanation of why it is deemed critical. All unlisted components are low criticality.
We consider the supplier of any critical component a critical supplier.
Using the criteria described above, the VotingWorks operations team narrows down the list of medium and high criticality components. For critical COTS components, we limit our suppliers to reputable and well-established vendors and manufacturers. When assessing whether a supplier is trustworthy, we consider several factors: length of time established; reputation for reliability; degree to which organization and manufacturing is based in the United States; the outcome of previous orders; responsiveness to issues; and their focus on critical business applications. For critical VotingWorks-specific manufactured components, for example any custom cables, we look for domestic-based manufacturers with ISO quality certifications (e.g. ISO 9001) and, where possible, prefer to perform site visits during onboarding.
For each critical component, VotingWorks requires a warranty on defective components and a delivery timeline for all orders. Specifically, contracts with suppliers include language matching or to the effect of:
The supplier is required to provide a warranty for all products or services that do not conform to specification.
The supplier is required to provide a delivery timeline for each order.
Suppliers for all critical components in the bill of materials are audited at the beginning and end of each hardware development cycle. If we discover disqualifying information about a supplier, VotingWorks works to identify alternative suppliers. If components are no longer available due to supply chain issues or the end of a product's lifecycle, VotingWorks works to identify alternative suppliers.
Defective components during production are handled by:
Identifying the defect
Notifying the supplier
Returning the defective component to the supplier for analysis
Requiring an explanation from the supplier as to how the defect occurred and how it will be mitigated in the future.
This risk assessment reviews threats and vulnerabilities identified in:
VxSuite hardware, including VxCentralScan, VxAdmin, vxMark, and VxScan. Also included are any items and peripherals needed to operate the equipment listed above (e.g., USB drives, scanners, printers).
VxSuite software and source code
VotingWorks internal communication and operation support systems.
This assessment was conducted following the framework outlined in NIST Special Publication 800-30 - Guide for Conducting Risk assessments.
For additional information on how physical, technical, and operational controls work together to meet the requirements of VVSG 14.1-C.1-4, please refer to , specifically:
Please also refer to the , notably the documentation.
Risk Assessment [PDF]
Risk Assessment [Excel]