Skip to content

borgoat/farmfa

Repository files navigation

License Go Report Card PkgGoDev

Concept

Multi Factor Authentication is often implemented by using the TOTP standard [RFC6238] from OATH.

  • The authentication server generates a secret key, stores it, and shows it to the user as a QR code or a Base32 string. The user stores it usually in a mobile app, or in a password manager.

  • Upon login, the user inputs a One-Time Password. The authenticator app or password manager generates this password by applying the TOTP algorithm to the secret key and the current time.

  • The authentication server performs the same algorithm on the secret key and current time. If the output matches the user’s TOTP - the process is successful.

The generated One-Time Password, as the name suggests, may only be used once (or more precisely, within a certain timeframe, depending on the server implementation).

farMFA comes into play in shared environments where access to certain accounts should be restricted to very special occasions. For example, access to the root user of an AWS account, especially the root user of the management account of an AWS Organization, which should only happen in break-glass scenarios.

In this context, we want to restrict access in such a way that multiple individuals are needed to grant authorisation.

First of all, we apply the Shamir’s Secret Sharing scheme [2] to the original TOTP secret key. This means, for instance, that at least 3 of 5 holders must put together their shares to reconstruct the secret.

Additionally, farMFA implements a workflow to reassemble the TOTP secret in a server, and letting users only access the generated TOTP code. This way, no single player has to risk accessing and accidentally leaking/persisting the secret.

Getting started

The two main workflows are:

  • getting the TOTP secret, splitting it, and sharing it to multiple parties (players) - this is done locally.

  • putting together the Tocs and generating the TOTP - done by the server/oracle.

Split TOTP secret and share

During this phase, farMFA MUST encrypt Tocs based on the intended recipient/player. The current encryption strategy is based on age.

Each player generates their age keypair via age-keygen:

$ age-keygen -o your_own_key.txt

Players then share their public key with the dealer.

Now the dealer may start the process. Usually, the dealer is also a player, so they also provide their own age public key and keep one Toc for themselves.

$ farmfa dealer \
  --totp-secret HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ \
  -p player_1=age174uc3d7qzaulmm75huxazcaynq5et4s9gdr7ajnau204lqny7asq9ens77 \
  -p player_2=age1pa8m7l4sguj84c5v8qu9gr3mydnmhd8lf633ln2udlp5699uvp2sm2mpzd \
  -p player_3=age1qegd5t5ajlqzewruz38srlrz05w7xgzq4nn2n5gky872up553v8sl64j3j

This will yield encrypted Tocs, 1 per player.

Each player now receives their Toc. They can decrypt it and inspect it via the age CLI.

$ age -i your_own_key.txt --decrypt
[paste the encrypted Toc - Ctrl+D]

{
    "group_id": "7GCUCI2Y",
    "group_size": 3,
    "group_threshold": 3,
    "note":"",
    "share":"C2iCgb3pRfxPJw2a7od8p4ShkhrDWAm/Dt6ioQNAVFPZ",
    "toc_id":"5oaAUX9b6aBE"
}

Players must now store their Toc securely.

Generate a TOTP

When a user wants to log in they can start a session. The user who wants to log in is called applicant.

Applicant

$ http --body POST localhost:8080/sessions toc_zero:='{"group_id":"J7UHQPZK","group_size":5,"group_threshold":2,"share":"5Ovpu-PKEeYXx5ebiQhzU_AT0Z79POf8GGkskDp3its=urkBkVXr-pYjIvTt1ch2YJILCScAoRquLoX_VBxxps4=","toc_id":"TFW52GAK"}'
{
    "complete": false,
    "created_at": "2021-02-24T18:05:53.507396809+01:00",
    "id": "V5K6QD4XUFLRGCZH",
    "kek": "MIotBtYOWrXnQCj6o9rSNIkNeRfIPhNLjEdQtJDDemPRJcKUbme+iq5K2Hc6Ypil6Loi/K9rnN/YrJiKDT/tPi8kFq2WuAY8zl8=",
    "tek": "age1cl5ndmdsq09vs09awlpt8nd4cdu6fpl33lpyyuv75syknqalkpdszwnwyc",
    "toc_group_id": "J7UHQPZK",
    "tocs_in_group": 5,
    "tocs_provided": 1,
    "tocs_threshold": 2
}

The oracle returns:

  • a session ID.

  • a Toc Encryption Key (TEK) - a public key to encrypt individual Tocs, so that only the server may use them.

  • a Key Encryption Key (KEK) - to decrypt the private part of the TEK, so that the server can only decrypt the Tocs when the applicant requests it.

The applicant shares the TEK and session ID with team members who hold the other Tocs. Those team members who can authorise the applicant will be named the session’s constituents.

Constituents must encrypt and armor their Toc with TEK (once again, using age).

Constituent

$ export ENCTOC=$(echo '{"group_id":"J7UHQPZK","group_size":5,"group_threshold":2,"share":"zxRrozuUaCMgn_u6ajZStlV7RKwhp0keT9aQoXAEruI=nfx2CPJfKiFM32zLmtxHjV94OlZOgBevV1Whrx-lslU=","toc_id":"K5FSSJSV"}' | age -r age1cl5ndmdsq09vs09awlpt8nd4cdu6fpl33lpyyuv75syknqalkpdszwnwyc -a)

Constituents upload the encrypted Toc to the oracle, associating it with the existing session.

Constituent

$ http POST localhost:8080/sessions/V5K6QD4XUFLRGCZH/tocs encrypted_toc="$ENCTOC"
HTTP/1.1 200 OK

Once the oracle has enough Tocs, the applicant may query the oracle. The applicant must provide the KEK to let the oracle decrypt the Tocs, and generate the TOTP.

Constituent

$ http --body POST localhost:8080/sessions/V5K6QD4XUFLRGCZH/totp kek="MIotBtYOWrXnQCj6o9rSNIkNeRfIPhNLjEdQtJDDemPRJcKUbme+iq5K2Hc6Ypil6Loi/K9rnN/YrJiKDT/tPi8kFq2WuAY8zl8="
{
    "totp": "824588"
}

References

Glossary

secret
A TOTP is a hash generated from a secret. This secret is usually shown as a QR code and shared between the prover and verifier. In farMFA, the prover becomes a distributed entity: recipients who share the key material, and an oracle that actually generates the TOTP.

Toc
The "pieces" in which a TOTP secret gets split.

deal
The workflow in which a dealer splits a secret in Tocs and shares them with multiple players.

dealer
Creates Tocs from a secret, and shares them with players.

player
During the Tocs creation phase, the individuals who each receive one of said Tocs.

session
Describes the workflow in which an applicant requires combining Tocs to generate a TOTP.

applicant
Initiates a session to request access to a TOTP.

constituent
The individuals who join a session to authorise an applicant to generate a TOTP, by reaching a quorum/threshold.

oracle
The entity that reconstructs Tocs into TOTP secrets, and generates one-time passwords. Also called the prover, as defined in [RFC6238].

server
In our context synonym with oracle.

TOTP
As defined in [RFC6238]: "an extension of the One-Time Password (OTP) algorithm […​] to support the time-based moving factor". Used by many applications as a second authentication factor.