# Padloc Security Whitepaper

This document provides a high level overview of the security design and
architecture of the **Padloc** application.

## Security Principles

### Simplicity

While the secure processing, storage and sharing of sensitive data necessarily
involves a certain degree of complexity, Padloc tries to hide this complexity
from the end user as much as possible. In other words, users should be able to
use the application securely without understanding (or even being aware of) the
underlying security principles. At the same time, the applications inner
workings and security mechanisms should be easily verifiable by those who have
the technical knowledge to do so, which brings us to...

### Transparency

It is a widely know fact among security experts that
[Security through Obscurity](https://en.wikipedia.org/wiki/security_through_obscurity)
is not only ineffective, but can in fact be harmful if used to cover up
otherwise sloppy security practices. We believe that full transparency is not
only the best foundation for trust, but also allows us and other independent
reviewers to discover and fix any potential security flaws and efficiently as
quickly as possible.

### No Trust Required

While Padlocs open source nature is helpful in uncovering unintended
vulnerabilities in the source code, it is, by itself, insufficient for verifying
that the code actually deployed in production is not altered in a way that may
compromise the security of the application either intentionally or
unintentionally. This is why we take additional steps to make sure that some
parts of the architecture can in fact be verified in production, while others do
not need to be verified by design (see
[Possible Attack-Vectors And Mitigations](#possible-attach-vectors-and-mitigations)).
This means that unlike other products, Padloc does not require explicit trust
between the end user and the host.

## Encryption

Robust data encryption is the foundation of Padlocs security architecture.
Padloc utilizes three basic encryption schemes.

### Simple Symmetric Encryption

This is the most basic encryption scheme used in Padloc. Simple encryption
employs a symmetric cipher to encrypt the provided data with a randomly
generated key. The encrypted data, along with the encryption parameters needed
for decryption, is stored in a container object, which can then be stored or
transmitted securely. Padloc currently uses the AES cipher in GCM mode, but
other options may be added in the future.

#### Encryption

1. Choose a random encryption key `k`
2. Choose a random initialization vector `iv` and additional data `a` (for
   authenticated encryption modes)
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
   text `p`
4. Store `c`, `iv` and `a` in the container `C`

```
                 ┌───────────┐                 ┏━━━━━━━━━━━━━━━━┓
   =========     │           │                 ┃Simple Container┃       ╔═══════════╗
   == key ==─────┘           ▼                 ┃                ┃       ║ encrypted ║
   =========            ┌─────────┐            ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃       ╚═══════════╝
                        │ encrypt │            ┃   encryption  │┃       ┌ ─ ─ ─ ─ ─ ┐
                  ┌────▶│  (AES)  │────────────▶│  parameters   ┃           plain
                  │     └─────────┘            ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃       └ ─ ─ ─ ─ ─ ┘
==============    │          │                 ┃╔══════════════╗┃       =============
= plain text =────┘          └─────────────────▶║encrypted data║┃       = ephemeral =
==============                                 ┃╚══════════════╝┃       =============
                                               ┗━━━━━━━━━━━━━━━━┛
```

#### Decryption

1. Let `k` be the key used for encryption.
2. Retrieve `iv`, `a` and `c` from `C`
3. Generate the plain text `p = AES_decrypt(k, c, iv, a)`

### Password-Based Encryption

In the password-based encryption scheme (based on the
[PBES2 standard](https://tools.ietf.org/html/rfc2898#section-6.2)) an encryption
key is derived from a user password using the
[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) key derivation function.

#### Encryption

1. Choose a password `p`
2. Choose an iteration count `i` and random salt `s`
3. Generate `k = PBDKF2(p, s, i)`
4. Choose a random initialization vector `iv` and additional data `a` (for
   authenticated encryption modes)
5. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
   text `p`
6. Store `s`, `i`, `c`, `iv` and `a` in the container `C`

```
 ============           ┌────────┐              ┏━━━━━━━━━━━━━━━━┓
 = password =──────────▶│ PBKDF2 │───────┐      ┃ Password-Based ┃
 ============           └────────┘       │      ┃   Container    ┃
                             │           │      ┃                ┃
                             │           │      ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
                             ▼           │      ┃     PBKDF2    │┃
                         =========       └──────▶│  parameters   ┃
                         == key ==              ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
                         =========              ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
                             │                  ┃   encryption  │┃
                             ▼           ┌──────▶│  parameters   ┃
                        ┌─────────┐      │      ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
==============          │ encrypt │      │      ┃╔══════════════╗┃
= plain text =─────────▶│  (AES)  │──────┘┌─────▶║encrypted data║┃
==============          └─────────┘       │     ┃╚══════════════╝┃
                             │            │     ┗━━━━━━━━━━━━━━━━┛
                             │            │
                             └────────────┘
```

#### Decryption

1. Let `p` be the password used for encryption
2. Retrieve `s`, `i` from `C`
3. Generate `k = PBDKF2(p, s, i)`
4. Retrieve `iv`, `a` and `c` from `C`
5. Generate the plain text `p = AES_decrypt(k, c, iv, a)`

### Shared-Key Encryption

Shared-key encryption is used to securely share sensitive data between a number
of independent accessors without the need for them to share a common password.
This encryption scheme is loosely based on the
[JSON Web Encryption](https://tools.ietf.org/html/rfc7516) specification where a
shared symmetric encryption key is individually encrypted with each accessors
public key and stored alongside the encrypted data. Accessors can then access
the data by using their private key to decrypt the AES encryption key which is
in turn used to decrypt the original data.

#### Encryption

1. Generate a random encryption key `k`
2. Choose a random initialization vector `iv` and additional data `a` (for
   authenticated encryption modes)
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
   text `p`
4. Let `[A_1, A_2, ..., A_n], A_n = { id_n, pub_n }` be a number of desired
   accessors where `pub_n` is the accessors public key and `id_n` a unique
   identifier.
5. For each accessor, generate `K_n = RSA_encrypt(pub_n, k)`
6. Store `c`, `iv`, `a`, and `K = [{ id_1, K_1}, ..., {id_n, K_n}]` in container
   `C`

```
┏━━━━━━━━━━━━━━┓                ┌───────────────────────────────────────────────────────────┐
┃  Accessor A  ┃                │                                                           │
┃              ┃                ▼                ┏━━━━━━━━━━━━━━━━┓                         │
┃┌ ─ ─ ─ ─ ─ ─ ┃           ┌─────────┐           ┃Shared Container┃   ==============        │
┃  public key │─────┐      │ encrypt │           ┃                ┃   = plain text =        │
┃└ ─ ─ ─ ─ ─ ─ ┃    └─────▶│  (RSA)  │─────┐     ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃   ==============        │
┃╔════════════╗┃           └─────────┘     │     ┃   encrypted   │┃          │              │
┃║private key ║┃                           └─────▶│   key (A)     ┃          ▼              │
┃╚════════════╝┃                                 ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃     ┌─────────┐         │
┗━━━━━━━━━━━━━━┛                                 ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃     │ encrypt │     =========
                                                 ┃   encrypted   │┃ ┌───│  (AES)  │◀────== key ==
                                           ┌─────▶│   key (B)     ┃ │   └─────────┘     =========
                                           │     ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ │        │              │
┏━━━━━━━━━━━━━━┓                           │     ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ │        │              │
┃  Accessor B  ┃                           │     ┃   encryption  │┃ │        │              │
┃              ┃                           │     ┃│  parameters   ◀─┘        │              │
┃┌ ─ ─ ─ ─ ─ ─ ┃           ┌─────────┐     │     ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃          │              │
┃  public key │─────┐      │ encrypt │     │     ┃╔══════════════╗┃          │              │
┃└ ─ ─ ─ ─ ─ ─ ┃    └─────▶│  (RSA)  │─────┘     ┃║encrypted data║◀──────────┘              │
┃╔════════════╗┃           └─────────┘           ┃╚══════════════╝┃                         │
┃║private key ║┃                ▲                ┗━━━━━━━━━━━━━━━━┛                         │
┃╚════════════╝┃                │                                                           │
┗━━━━━━━━━━━━━━┛                └───────────────────────────────────────────────────────────┘
```

#### Decryption

1. Let `id_n`, `priv_n` be the id and private key of one of the accessors used
   during encryption.
2. Retrieve `K` from `C`, find the encrypted key `K_n` for `id_n`.
3. Generate `k = RSA_decrypt(priv_n, K_n)`
4. Retrieve `iv`, `a` and `c` from `C`
5. Generate the plain text `p = AES_decrypt(k, c, iv, a)`

```
                                   ┌─────────┐
┏━━━━━━━━━━━━━━┓                   │ decrypt │                  ┏━━━━━━━━━━━━━━━━┓
┃  Accessor A  ┃        ┌─────────▶│  (RSA)  │◀────────┐        ┃Shared Container┃
┃              ┃        │          └─────────┘         │        ┃                ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃        │               │              │        ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃  public key │┃        │               │              │        ┃   encrypted   │┃
┃└ ─ ─ ─ ─ ─ ─ ┃        │    =========  │              └─────────│   key (A)     ┃
┃╔════════════╗┃        │    == key ==◀─┘                       ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
┃║private key ║─────────┘    =========        ┌───────────┐     ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃╚════════════╝┃                 │            │           │     ┃   encryption  │┃
┗━━━━━━━━━━━━━━┛                 │            ▼           └──────│  parameters   ┃
                                 │       ┌─────────┐            ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
                                 │       │ decrypt │            ┃╔══════════════╗┃
                                 └──────▶│  (AES)  │◀────────────║encrypted data║┃
                                         └─────────┘            ┃╚══════════════╝┃
                                              │                 ┗━━━━━━━━━━━━━━━━┛
                                              ▼
                                       ==============
                                       = plain text =
                                       ==============
```

## Client-Server Architecture And The Zero-Trust Principle

[[TODO]]

## The Account Object And Master Password

The **Account** object represents an individual Padloc user and is central to
Padlocs encryption and authentication mechanisms. Each **Account** holds the
following information:

-   The user's **email address** is not only used as a communication channel
    but, more importantly, serves as a unique, human-verifiable identifier for
    each Padloc user.
-   A RSA **private key** and **public key** pair is used in places where a user
    needs to be granted access to data protected via the
    [Shared-Key Encryption Scheme](#shared-key-encryption).
-   A HMAC key used for signing and verifing organization details (see
    [Organizations And Shared Vaults / Adding Members](#adding-members)
-   A unique, immutable id
-   A (display) name

The Accounts **private key** and **organization signing key** are considered
secret and should only ever be accessible to the Account owner themselves. They
are therefore encrypted at rest using the
[Password-Based Encryption Scheme](#password-based-encryption) with the users
[**Master Password**](#the-master-password) serving as the secret passphrase.

```
                                 ┏━━━━━━━━━━━━━━━━━━━━━┓
                                 ┃       Account       ┃        ╔═══════════╗
                                 ┃                     ┃        ║ encrypted ║
                                 ┃ ┌ ─ ┐┌ ─ ─ ┐┌ ─ ─ ┐ ┃        ╚═══════════╝
                                 ┃  id   name   email  ┃        ┌ ─ ─ ─ ─ ─ ┐
                                 ┃ └ ─ ┘└ ─ ─ ┘└ ─ ─ ┘ ┃            plain
===================              ┃ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┃        └ ─ ─ ─ ─ ─ ┘
= Master Password =───────┐      ┃     public key      ┃        =============
===================       │      ┃ └ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ┃        = ephemeral =
                          │      ┃ ╔═════════════════╗ ┃        =============
                      decrypts   ┃ ║ ┌─────────────┐ ║ ┃
                          │      ┃ ║ │ private key │ ║ ┃
                          │      ┃ ║ └─────────────┘ ║ ┃
                          └───────▶║ ┌─────────────┐ ║ ┃
                                 ┃ ║ │ signing key │ ║ ┃
                                 ┃ ║ └─────────────┘ ║ ┃
                                 ┃ ╚═════════════════╝ ┃
                                 ┗━━━━━━━━━━━━━━━━━━━━━┛
```

## Vaults

A password managers core functionality is the secure storage of sensitive data
like passwords, credit card details and or any other kind or data a user may
want to protect from prying eyes. In Padloc, this data is stored within
so-called **Vaults**.

A Vault is basically a container object that employs the
[Shared-Key Encryption Scheme](#shared-key-encryption) to encrypt and store
sensitive data in a way that makes it accessible to only a number of specific
users, represented by their corresponding **Account** objects.

```
┏━━━━━━━━━━━━━━━┓                 ┏━━━━━━━━━━━━━━┓
┃    Account    ┃                 ┃    Vault     ┃
┃               ┃                 ┃              ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃                 ┃ ╔══════════╗ ┃
┃  public key  ──────encrypts──────▶║vault data║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃                 ┃ ╚══════════╝ ┃
┃ ╔═══════════╗ ┃                 ┃       ▲      ┃
┃ ║private key║──────decrypts─────────────┘      ┃
┃ ╚═══════════╝ ┃                 ┃              ┃
┗━━━━━━━━━━━━━━━┛                 ┗━━━━━━━━━━━━━━┛
```

Each Padloc user owns a private vault to which only they have access. In
addition to this, **Shared Vaults** can be used to share sensitive data between
multiple members within an **Organization**. For more details on this, see the
[Organizations And Shared Vaults](#organizations-and-shared-vaults) section.

## Organizations And Shared Vaults

**Shared Vaults** can be used to securely share sensitive data between multiple
users. These vaults are provisioned and managed as part of **Organizations**,
which deal with permission management as well as public key and identity
verification.

### Vault Access Management

The previous sections describe how Vault data can be shared securely between
multiple known accounts. An additional challenge lies in deciding who shall have
access to a given vault as well as obtaining and verifying each accessors public
key before encryption.

The organisation structure depicted below determines which member shall have
access to a given vault. Members can either be assigned to a **Vault** directly
or indirectly via a **Group**.

```
┌──────────────┐            ┌──────────────┐            ┌──────────────┐
│              │           ╱│              │╲           │              │
│   Account    │┼─────────○─│  Membership  │──┼────────┼│ Organization │
│              │           ╲│              │╱           │              │
└──────────────┘            └───┬──────┬───┘            └──────────────┘
                               ╲│╱    ╲│╱                       ┼
                                ○      ○                        ○
                                │      │                       ╱│╲
                                │      │                ┌──────────────┐
                                │      │               ╱│              │
                                │      └──────────────○─│    Group     │
                                │                      ╲│              │
                                ○                       └──────────────┘
                               ╱│╲                             ╲│╱
                        ┌──────────────┐                        ○
                        │              │╲                       │
                        │ Shared Vault │─○──────────────────────┘
                        │              │╱
                        └──────────────┘
```

Every time a **Vault** participant encrypts the vault data, they perform the
following steps:

1. Determine accessors based on organization structure.
2. Verify each accessor's identity and public key (see
   [Verifying Members](#verifying-members))
3. Encrypt the data using the steps outlined in
   [Shared-Key Encryption](#shared-key-encryption)

Each participating member can now access the Vault data using their own private
key.

### Metadata And Cryptographic Keys

In addition to Group and Member data, **Organizations** also hold the following
information:

-   The organization **id** is a random, unique identier assigned to it by the
    server
-   The organization **name** is chosen by the organization owner and is mainly
    used for display purposes
-   A RSA **public key** and **private key** pair that is used to sign and
    verify public keys and identifying information of its members. See
    [Signing Member Information](#adding-members) and
    [Verifying Members](#verifying-members) for details.
-   An AES key (in the following called "**invites key**") used to encrypt the
    invite verification code during
    [key exchange](#trustless-server-mediated-key-exchange)

The organization's **private key** and **invites key** are considered secret and
need therefore be encrypted at rest. For this, the organization acts as a
[Shared Crypto Container](#shared-key-encryption) with the
[organization owners](#owner) acting as accessors.

```
┏━━━━━━━━━━━━━━━┓                ┏━━━━━━━━━━━━━━━━━━━━┓
┃ Organization  ┃                ┃    Organization    ┃
┃     Owner     ┃                ┃                    ┃
┃               ┃                ┃  ╔═══════════════╗ ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃                ┃  ║┌─────────────┐║ ┃
┃  public key  ──────encrypts──────▶║│ private key │║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃                ┃  ║└─────────────┘║ ┃
┃ ╔═══════════╗ ┃                ┃  ║┌─────────────┐║ ┃
┃ ║private key║──────decrypts──────▶║│ invites key │║ ┃
┃ ╚═══════════╝ ┃                ┃  ║└─────────────┘║ ┃
┗━━━━━━━━━━━━━━━┛                ┃  ╚═══════════════╝ ┃
                                 ┗━━━━━━━━━━━━━━━━━━━━┛
```

### Public Key Exchange And Verification

As with all cryptographic schemes that involve public-key encryption, a major
challenge when dealing with shared vaults is securely exchanging and verifying
the public keys and associated identities of all involved parties. This
undertaking is complicated further by the fact that, although all communication
and data transfer is generally mediated by a central server, Padlocs
[Zero-Trust Principle](#no-trust-required) requires that this server (or any
party potentially listening in on the connection) is never in the position to
directly access any sensitive data or trick a participant into granting them
access either directly or indirectly.

Instead of exchanging keys between all organization members directly, Padloc
uses a simple verification chain where the public keys and identfying
information of all members are signed and verified with a dedicated RSA key pair
owned by the organization (see
[Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys)). The
corresponding public key must in turn be signed and verified by each member
using their individual, dedicated HMAC key.

#### Trustless Server-Mediated Key Exchange

Before a new member can be added to an Organization, a key exchange has to take
place between the organization (represented by the organization owner) and the
new member. The key exchange is performed as follows:

1. The **organization owner `O`** chooses a **random passphrase `p`**, a
   **random salt `s`** and an **iteration count `i`** as well as a random,
   unique exchange id.
2. **`p`**, **`s`** and **`i`** are used to generate the **HMAC key
   `x = PBKDF2(p, s, i)`**.
3. **`O`** signs the **organizations public key `pub_o`** with **`x`**:
   **`sig_o = HMAC(x, pub_o)`**
4. **`O`** sends **`s`**, **`i`**, **`pub_o`** and **`sig_o`** to the server
   **`S`**, along with the exchange id and the recipients email address.
5. The server stores the received values and sends the invitation link (which
   includes the exchange id) to **`I`** via email.
6. **`I`** uses the exchange id to request **`s`**, **`i`**, **`pub_o`** and
   **`sig_o`** from **`S`**.
7. **`I`** requests **`p`** from **`O`** via a separate (and optimally secure)
   channel of their choice. This can be in person, via phone or any by other
   means.
8. **`I`** generates **`x = PBKDF2(p, s, i)`** using the obtained information.
9. **`I`** verifies **`pub_o`** using **`x`** and **`sig_o`**.
10. Upon successful verification, **`I`** signs their own **public key `pub_i`**
    using **`x`**: **`sig_i = HMAC(x, pub_i)`**
11. **`I`** sends **`pub_i`** and **`sig_i`** to **`S`**, which forwards them to
    **`O`**.
12. **`O`** verifies **`pub_i`** using **`sig_i`** and **`x`**.

```
                 ┌─────────────┐      ┌──────────┐      ┌───────────┐
                 │Org Owner (O)│      │Server (S)│      │Invitee (I)│
                 └──────┬──────┘      └────┬─────┘      └─────┬─────┘
┌─────────────────────┐ │                  │                  │
│p = [passphrase]     │ │ s, i, id, email, │                  │
│s = [random salt]    │ │   pub_o, sig_o   │  id (via email)  │
│i = [iteration count]│ │─────────────────▶│─────────────────▷│
│x = PBKDF2(p,s,i)    │ │                  │                  │
│pub_o = [public key] │ │                  │        id        │
│sig_o = HMAC(x,pub_o)│ │                  │◀─────────────────│
│id = [invite id]     │ │                  │      s, i,       │
│email = [inv. email] │ │                  │   pub_o, sig_o   │
└─────────────────────┘ │                  │─ ─ ─ ─ ─ ─ ─ ─ ─▶│
                        │                  │                  │
                        │                  │   p (in person)  │ ┌─────────────────────┐
                        │────────────────────────────────────▷│ │pub_i = [public key] │
                        │                  │                  │ │x = PBKDF2(p,s,i)    │
    ┌─────────────────┐ │   pub_i, sig_i   │   pub_i, sig_i   │ │x => verify sig_o    │
    │x => verify sig_i│ │◀─────────────────│◀─────────────────│ │sig_i = HMAC(x,pub_i)│
    └─────────────────┘ │                  │                  │ └─────────────────────┘
                        │                  │                  │
                        │                  │                  │
                        │                  │                  │
                        ▼                  ▼                  ▼
```

##### Notes:

-   In practice, the member's account id and email and the organization id are
    included in the respective signatures to protect these from tempering as
    well.

-   Since `p` needs to be sufficiently short to be conveniently entered by hand,
    it can potentially be guessed by eavesdroppers which would allow them to
    successfully perform a man-in-the-middle attack by injecting their own
    public key. This is mitigated by using a sufficiently large iteration count
    `i` and invalidating key exchanges after a certain amount of time.

-   Using a separate, direct communication channel for communicating the secret
    passphrase not only mitigates the risk of man-in-the-middle attacks but also
    means that the server `S` does not need to be explicitly trusted.
    Furthermore, the risk of phishing attacks by a third party (including a
    malicious server admin) is greatly reduced since a direct, personal
    interaction between the parties is required.

-   Since some time may pass between steps **1.** and **7.**, **`p`** needs to
    be stored securely for later reference. This is done by encrypting it with a
    dedicated AES "invites key" which is only accessible to organization owners.
    (See [Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys).

#### Adding Members

Once the new member and organization have successfully exchanged public keys,
these need to be stored in a way that allows both parties to be verify them
later. The invitees public key (along with their identifying information) is
signed by the organizations private key (only available to the organization
owner) while the organizations public key is signed by the invitees own,
dedicated HMAC key.

```
┏━━━━━━━━━━━━━━┓
┃Member Account┃
┃              ┃          ┌────────┐
┃╔════════════╗┃          │  sign  │
┃║signing key ║──────────▶│ (HMAC) │◀────┐
┃╚════════════╝┃          └────────┘     │
┃┌ ─ ─ ─ ─ ─ ─ ┃               │         │
┃  public key │─────────────┐  │         │
┃└ ─ ─ ─ ─ ─ ─ ┃            │  │         │
┗━━━━━━━━━━━━━━┛            │  │         │
                            │  │         │    ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓            │  │         │    ┃ Organization ┃
┃  Membership  ┃            │  │         │    ┃              ┃
┃              ┃            │  │         │    ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃            │  │         └─────  public key │┃
┃ organization│┃            │  │              ┃└ ─ ─ ─ ─ ─ ─ ┃
┃│ signature   ◀────────────│──┘              ┃╔════════════╗┃
┃ ─ ─ ─ ─ ─ ─ ┘┃            ▼            ┌─────║private key ║┃
┃┌ ─ ─ ─ ─ ─ ─ ┃          ┌────────┐     │    ┃╚════════════╝┃
┃    member   │┃          │  sign  │     │    ┗━━━━━━━━━━━━━━┛
┃│ signature   ◀──────────│ (RSA)  │◀────┘
┃ ─ ─ ─ ─ ─ ─ ┘┃          └────────┘
┗━━━━━━━━━━━━━━┛
```

#### Verifying Members

Using the signatures described in the previous section, an organization member
can verify the public key of any other member as follows.

1. Verify the organizations public key using the organization signature created
   with their own HMAC key
2. Verify the other member's public key using the organization's public key.

```
┏━━━━━━━━━━━━━━┓                  ┏━━━━━━━━━━━━━━┓                 ┏━━━━━━━━━━━━━━┓
┃  Account A   ┃                  ┃     Org      ┃                 ┃  Account B   ┃
┃              ┃    ┌────────┐    ┃              ┃    ┌────────┐   ┃              ┃
┃╔════════════╗┃    │ verify │    ┃┌ ─ ─ ─ ─ ─ ─ ┃    │ verify │   ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃║signing key ║────▶│ (HMAC) │◀────  public key │────▶│ (RSA)  │◀───  public key │┃
┃╚════════════╝┃    └────────┘    ┃└ ─ ─ ─ ─ ─ ─ ┃    └────────┘   ┃└ ─ ─ ─ ─ ─ ─ ┃
┗━━━━━━━━━━━━━━┛         ▲        ┃╔════════════╗┃         ▲       ┗━━━━━━━━━━━━━━┛
                         │        ┃║private key ║┃         │       ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓         │        ┃╚════════════╝┃         │       ┃ Membership B ┃
┃ Membership A ┃         │        ┗━━━━━━━━━━━━━━┛         │       ┃              ┃
┃              ┃         │                                 │       ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃         │                                 │       ┃    member   │┃
┃ organization│┃         │                                 └────────│ signature   ┃
┃│ signature   ┣─────────┘                                         ┃ ─ ─ ─ ─ ─ ─ ┘┃
┃ ─ ─ ─ ─ ─ ─ ┘┃                                                   ┗━━━━━━━━━━━━━━┛
┗━━━━━━━━━━━━━━┛
```

#### Organization Roles and Privileges

There are three distinct organization roles: **Owner**, **Admin** and basic
**Member**. Each role comes with a different set of privileges. Some privileges
are enforced cryptographically while others are enforced solely by the server.

##### Basic Member

A basic organization member has the following privileges.

1. Read the public data of other members, including id, email, public key and
   assigned vaults and groups.
2. Read vault data of assigned vaults
3. Update vault data of assigned vaults where write permissions have been
   granted explicitly

All of these privileges are enforced by the server (e.g. a vaults encrypted data
will only be provided to a member if they are assigned to that vault) while
access to the plain text data stored in vaults is also restricted
cryptographically through the encryption mechanism described in
[Vaults](#vaults).

##### Admin

In addition to the privileges granted to basic members, admins also have the
following privileges:

1. Create and delete Vaults
2. Assign vault access to groups and members directly
3. Create, delete and manage groups

##### Owner

In addition to the privileges granted to basic members and admins, organization
owners also have the following privileges:

1. Add/remove organization members
2. Update a members id, email, public key or role
3. Update the organizations public/private key pair

As described in a [previous section](#adding-members), adding a new member to
the organization requires access to the organizations private key. As described
in [Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys), this
access is restricted cryptographically to organization owners.

## Authentication And Data Transfer

Even though all sensitive information in **padloc** is end-to-end encrypted and
theoretically secure even in case of an insecure connection or even a
compromised server, **padloc** still uses a robust authentication scheme to
limit access to user data, ensure payload integrity and enforce user
permissions. A variation of the
[Secure Remote Password](https://tools.ietf.org/html/rfc2945) protocol is used
to authenticate users and establish a secure connection between client and
server without exposing the user's master password.

### User Signup

Whenever a user creates a Padloc account, the following steps take place:

1. Let **`u`** and **`p`** be the user's **email address** and **master
   password**, respectively.
2. The **client `C`** sends **`u`** to the server **`S`**.
3. The server sends an email **verification code `c`** to the user's email
   address.
4. **`C`** chooses a **random salt `s`** and **iteration count `i`**
5. **`C`** generates **`x = PBKDF2(p, s, i)`** and the **password verifier
   `v = v(x)`**\*
6. **`C`** sends **`u`**, **`v`**, **`s`**, **`i`** and **`c`** to **`S`**
7. **`S`** verifies **`c`** and, if successful, stores **`u`**, **`v`**, **`s`**
   and **`i`** for later use.

The signup process is now complete and the stored values can be used to verify
the users identity and to negotiate a common session key.

```
                  ┌──────────┐     ┌──────────┐
                  │Client (C)│     │Server (S)│
                  └─────┬────┘     └────┬─────┘
  ┌───────────────────┐ │               │
  │u = [email address]│ │       u       │
  └───────────────────┘ │──────────────▶│ ┌───────────────────────┐
                        │               │ │c = [verification code]│
                        │               │ └───────────────────────┘
┌─────────────────────┐ │ c (via email) │
│p = [master password]│ │◁ ─ ─ ─ ─ ─ ─ ─│
│s = [random salt]    │ │               │
│i = [iteration count]│ │               │
│x = PBKDF2(p,s,i)    │ │ u, v, s, i, c │ ┌───────────────────┐
│v = v(x)*            │ │──────────────▶│ │=> verify c        │
└─────────────────────┘ │               │ │=> store u, v, s, i│
                        │               │ └───────────────────┘
                        │               │
                        ▼               ▼
```

### Session Negotiation

In order to "log into" an existing account, a common session key needs to be
negotiated. This happens as follows:

1. Let **`u`** and **`p`** be the users **email address** and **master
   password**, respectively.
2. The client **`C`** generates the random values **`a`** and **`A`**\*
3. **`C`** sends **`u`** and **`A`** to the Server `S`.
4. **`S`** looks up **`s`** and **`i`** based on **`u`** and generates the
   random values **`b`** and **`B`**\*.
5. **`S`** sends **`s`**, **`i`** and **`B`** to **`C`**.
6. **`C`** generates **`x = PBKDF2(p, s, i)`**, **`K = K_client(x, a, B)`** and
   **`M = M(A, B, K)`**\*.
7. **`C`** sends **`M`** to **`S`**.
8. **`S`** generates its own **`K' = K_server(v, b, A)`** and
   **`M' = M(A, B, K')`**\*.
9. **`S`** verifies that **`M == M'`** and therefore **`K == K'`**. If
   verification fails, the session negotiation is aborted.
10. If successful, **`S`** stores **`K`** under the session id **`sid`**.
11. **`S`** sends **`sid`** to **`C`**, which also stores it along with **`K`**
    for later use.

Client and server now have a common and secret session key **`K`** which can be
used for authenticating subsequent requests.

```
                    ┌──────────┐     ┌──────────┐
                    │Client (C)│     │Server (S)│
                    └─────┬────┘     └────┬─────┘
    ┌───────────────────┐ │               │
    │u = [email address]│ │     u, A      │
    │a, A = [random*]   │ │──────────────▶│
    └───────────────────┘ │               │ ┌────────────────┐
                          │               │ │b, B = [random*]│
┌───────────────────────┐ │    s, i, B    │ └────────────────┘
│p = [master password]  │ │◁ ─ ─ ─ ─ ─ ─ ─│
│x = PBKDF2(p,s,i)      │ │               │
│K = K_client(x, a, B)* │ │               │
│M = M(A, B, K)*        │ │       M       │ ┌───────────────────────┐
└───────────────────────┘ │──────────────▶│ │K' = K_server(v, b, A)*│
                          │               │ │M' = M(A, B, K')       │
                          │               │ │=> verify M == M'      │
        ┌───────────────┐ │      sid      │ │S = [session id]       │
        │=> store sid, K│ │◀ ─ ─ ─ ─ ─ ─ ─│ │=> store sid, K        │
        └───────────────┘ │               │ └───────────────────────┘
                          │               │
                          ▼               ▼
```

### Request Authentication

Using the common session key **`K`** Client and Server can now authenticate each
request as follows:

1. Let **`sid`** and **`K`** be the previously negotiated session id and key.
2. Let **`req`** be the intended request body and **`t1`** the time stamp at the
   time of the request.
3. **`C`** generates the signature **`sig1 = HMAC(K, sid|t1|req)`**.
4. **`C`** sends **`req`**, **`sid`**, **`t1`** and **`sig1`** to **`S`**.
5. **`S`** verifies **`req`**, **`sid`** and **`t1`** using **`sig1`**. If
   verification fails, or if **`t1`** is older than a predetermined maximum
   request age, the request is rejected.
6. Let **`res`** be the response body and **`t2`** the time stamp at the time of
   the response.
7. **`S`** generates **`sig2 = HMAC(K, sid|t2|res)`**.
8. **`S`** sends **`res`**, **`t2`** and **`sig2`** to **`C`**.
9. **`C`** verifies **`res`**, **`sid`** and **`t2`** using **`sig2`**. If
   verification fails, or if **`t2`** is older than a predetermined maximum
   response age, the response is rejected.

```
                       ┌──────────┐     ┌──────────┐
                       │Client (C)│     │Server (S)│
                       └─────┬────┘     └────┬─────┘
┌──────────────────────────┐ │               │
│req = [request body]      │ │   req, sid,   │
│t1 = [timestamp]          │ │   t1, sig1    │ ┌──────────────────────────┐
│sig1 = HMAC(K, sid|t1|req)│ │──────────────▶│ │=> verify sig1            │
└──────────────────────────┘ │               │ │res = [response body]     │
                             │               │ │t2 = [timestamp]          │
            ┌──────────────┐ │ res, t2, sig2 │ │sig2 = HMAC(K, sid|t2|res)│
            │=> verify sig2│ │◁ ─ ─ ─ ─ ─ ─ ─│ └──────────────────────────┘
            └──────────────┘ │               │
                             │               │
                             ▼               ▼
```

**\*** For details on how **`v`**, **`a`**, **`A`**, **`b`**, **`B`**, **`K`**
and **`M`** are generated, refer to
[the SRP specification](https://tools.ietf.org/html/rfc2945#section-3)

### Notes

-   Even though **`v`** is based on **`p`**, it can not be used to guess the
    password in case someone eavesdrops on the connection or if the server is
    compromised. See
    [section 4 of the SRP specification](https://tools.ietf.org/html/rfc2945#section-4)
    for details.
-   The session key **`K`** cannot be sniffed out since it is never transmitted.
    It could theoretically be guessed from the request signature but with a key
    size of 256 bits this is not really feasible either.
-   The salt and iteration count used for generating **`x`** as well as the
    resulting authentication key are completely independent of the corresponding
    values used for encrypting the accounts private key, even though the
    derivation scheme and base passphrase are the same.
-   Request authentication works both ways. Not only can the server verify the
    users identity and knowledge of their master password, the client can also
    verify the identity of the server.
-   The described authentication mechanism not only allows for identity
    verification, but also prevents tempering with the request/response body or
    timestamp.
-   Rejecting request and responses older than a certain age mitigates the risk
    of replay attacks.

## Possible Attack Vectors and Mitigations

This section covers various possible attack vectors and mitigation steps taken.

### Man-In-The-Middle Attacks

A
[man-in-the-middle attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)
is an attack where the attacker secretly relays the communication between two
parties in order to eavesdrop on the connection and/or temper with messages in
transit.

MITM attacks may be launched in a multitude of ways, and even with technlogies
like TLS, it is very hard to completely rule out that other parties may be
listening in on the connection or even trying to tamper with the messages
exchanged. Therefore, steps should be taken not only to mitigate the risk of a
successful MITM attack, but also to ensure that even in case of an insecure
connection, an attacker may never get access to any sensitive information or
compromise the security of the application in any other way.

-   Communication between the Padloc client and server is always secured through
    [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security).
-   No sensitive information is ever transmitted in plain text.
-   Transmitted data is protected from tampering through Padloc's strong
    [Authentication Mechanism](#authentication-and-data-transfer).
-   Padloc's [Key Exchange Mechanism](#trustless-server-mediated-key-exchange)
    is designed to be secure even over an untrusted connection.

### Phishing

With the addition of
[Organizations And Shared Vaults](#organizations-and-shared-vaults) in Padloc 3,
phishing has become a potential attack vector as well. Attackers may try to lure
Padloc users into sharing sensitive information by inviting them to misleadingly
named organizations which can be mistaken for an employer or friend. Users could
then accidentally share data within vaults assigned to them.

However, the procedure for inviting and adding a new member to an organization
is designed in a way that makes this very hard to accomplish, since it requires
direct, personal coordination between both parties. See
[Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange)
for more details.

### Guessing Master Passwords

Padloc uses a combination of various
[strong encryption algorithms](#cryptographic-primitives-and-parameters) to
protect all sensitive data and cryptographic keys both at rest and during
transmission. The **master password** acts as a universal key for this
encryption scheme.

Master passwords are never stored anywhere and should only ever be known by the
Padloc user themself. Unfortunately, since this means that in the majority of
use cases the user will have to commit this password to memory, the "key space"
of feasible passwords is relatively limited. Additionally, since master
passwords are ultimately chosen by the user, no guarantee can be made to the
strength or randomness of these passwords.

This means that master password are a prime-target for guessing attacks of all
sorts and steps should be taken to make these attacks either infeasible or, at a
very minimum, too costly to be worthwhile.

[[TODO]]

### User Enumeration

[[TODO]]

### Password Spraying

[[TODO]]

### Denial Of Service

[[TODO]]

### Compromised Server

[[TODO]]

## Cryptographic Algorithms And Configurations

### Symmetric Encryption

For all symmetric encryption operations, the
[AES Cipher](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is used
in [GCM mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode) with a key size
of **256 bits**.

**Areas of use:**

-   [Simple Symmetric Encryption](#simple-symmetric-encryption)
-   [Password-Based Encryption](#password-based-encryption)
-   [Shared-Key Encryption](#shared-key-encryption)

### Asymmetric Encryption

For asymmetric encryption operations, the
[RSA-OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding)
algorithm is used with a **modulus length** of **2048 bits** and the
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).

**Areas of use:**

-   [Shared-Key Encryption](#shared-key-encryption)

### Symmetric Signature Schemes

For symmetric signature creation and verification, the
[HMAC](https://en.wikipedia.org/wiki/HMAC) algorithm is used with a **key
length** of **256 bits** and the
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).

**Areas of use:**

-   [Request Authentication](#request-authentication)
-   [Adding Members](#adding-members)
-   [Verifying Members](#verying-members)
-   [Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange).

### Asymmetric Signature Schems

For asymmetric signature creation and verification, the
[RSA-PSS](https://en.wikipedia.org/wiki/Probabilistic_signature_scheme)
algorithm is used with a **modulus length** of **2048 bits**, a **salt length**
of **256 bits** and the
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).

**Areas of use:**

-   [Adding Members](#adding-members)
-   [Verifying Members](#verying-members)

### Password-Based Key Derivation

For password-based key derivation, the
[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) algorithm is used with the
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2) and a **salt
length** of **128 bits**. The iteration count varies by area of use.

**Areas of use:**

-   [Password-Based Encryption](#password-based-encryption)
-   [User Signup](#user-signup)
-   [Session Negotiation](#session-negotiation)
-   [Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange).
