# 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).
