Skip to content

Commit

Permalink
Add description of AEGIS cipher scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
utelle committed Dec 27, 2024
1 parent 3126fb9 commit f408e44
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ The project **SQLite3 Multiple Ciphers** implements an encryption extension for
- [SQLCipher](https://www.zetetic.net/sqlcipher/): AES 256 Bit CBC - SHA1/SHA256/SHA512 HMAC
- [System.Data.SQLite](http://system.data.sqlite.org): RC4
- [Ascon](https://ascon.iaik.tugraz.at/): Ascon-128 v1.2
- [AEGIS](https://cfrg.github.io/draft-irtf-cfrg-aegis-aead/draft-irtf-cfrg-aegis-aead.html): AEGIS Family of Authenticated Encryption Algorithms

The cipher scheme **ChaCha20 - Poly1305 HMAC** is currently the **recommended** _default cipher scheme_, because it meets the following important criteria:

- Encryption and tamper detection is a modern [Internet Engineering Task Force](https://www.ietf.org) standard, also used for secure web communication (TLS/SSL) - see [RFC 7905](https://datatracker.ietf.org/doc/html/rfc7905).
- A key derivation function ([PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)) is used to reduce vulnerability to brute force attacks.
- Per database and per page random bytes ([cryptographic nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)) are used to ensure that the same unencrypted database content does not result in the same encrypted content when the same encryption key is used.

Technically, the cipher schemes [SQLCipher](https://www.zetetic.net/sqlcipher/) and [Ascon](https://ascon.iaik.tugraz.at/) are almost equivalent with respect to cryptographic security. However, **SQLCipher** uses [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard), which has usually lower runtime performance than **ChaCha20 - Poly1305 HMAC**. And [Ascon](https://ascon.iaik.tugraz.at/) is a relatively new player supporting _authenticated encryption schemes with associated data_ ([AEAD](https://www.ietf.org/archive/id/draft-irtf-cfrg-aead-properties-03.html)), selected as [new standard for lightweight cryptography](https://www.nist.gov/news-events/news/2023/02/nist-selects-lightweight-cryptography-algorithms-protect-small-devices) in the [NIST Lightweight Cryptography competition (2019–2023)](https://csrc.nist.gov/projects/lightweight-cryptography/finalists).
Technically, the cipher schemes [SQLCipher](https://www.zetetic.net/sqlcipher/) and [Ascon](https://ascon.iaik.tugraz.at/) are almost equivalent with respect to cryptographic security. However, **SQLCipher** uses [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard), which has usually lower runtime performance than **ChaCha20 - Poly1305 HMAC**. And [Ascon](https://ascon.iaik.tugraz.at/) is a relatively new player supporting _authenticated encryption schemes with associated data_ ([AEAD](https://www.ietf.org/archive/id/draft-irtf-cfrg-aead-properties-03.html)), selected as [new standard for lightweight cryptography](https://www.nist.gov/news-events/news/2023/02/nist-selects-lightweight-cryptography-algorithms-protect-small-devices) in the [NIST Lightweight Cryptography competition (2019–2023)](https://csrc.nist.gov/projects/lightweight-cryptography/finalists). The latest addition is the cipher scheme **AEGIS** which falls into the same category as **Ascon**.

The cipher schemes **AES 128/256 Bit CBC** and **RC4** ([System.Data.SQLite](http://system.data.sqlite.org)) do **not** meet the above criteria and are included for compatibility with older existing applications only. They should not be used for new development. Developers using one of these cipher schemes should consider to update their applications to use one of the more modern and secure cipher schemes.

Expand Down
54 changes: 54 additions & 0 deletions docs/ciphers/cipher_aegis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
layout: default
title: "AEGIS: Family of Authenticated Encryption Algorithms"
parent: Supported Ciphers
nav_order: 7
---
## <a name="cipher_aegis"/>AEGIS: Family of Authenticated Encryption Algorithms

[**AEGIS**](https://cfrg.github.io/draft-irtf-cfrg-aegis-aead/draft-irtf-cfrg-aegis-aead.html) is a family of [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption) and [hashing](https://en.wikipedia.org/wiki/Cryptographic_hash_function) algorithms designed for high-performance applications. It was chosen in the [CAESAR](https://en.wikipedia.org/wiki/CAESAR_Competition) (Competition for Authenticated Encryption: Security, Applicability, and Robustness) competition. A detailed description of the algorithms can be found [here](https://eprint.iacr.org/2013/695.pdf).

The _AEGIS_ implementation used in _SQLite3 Multiple Ciphers_ is based on the [Portable C implementation](https://github.com/aegis-aead/libaegis) by [Frank Denis](https://github.com/jedisct1/). The source code was adjusted to be useable in the _SQLite3 Multiple Ciphers_ amalgamation.

The _AEGIS_ cipher scheme supports the selection of all available _AEGIS_ variants: _AEGIS-128L_, _AEGIS-128X2_, _AEGIS-128X4_, _AEGIS-256_, _AEGIS-256X2_, and _AEGIS-256X4_, the default being _AEGIS-256_.

The encryption key is derived from the passphrase using a random salt (stored in the first 16 bytes of the database file) and the _key derivation_ algorithm [Argon2](https://en.wikipedia.org/wiki/Argon2). The _Argon2_ implementation used in _SQLite3 Multiple Ciphers_ is based on the [reference C implementation of Argon2](https://github.com/p-h-c/phc-winner-argon2), that won the [Password Hashing Competition (PHC)](https://password-hashing.net/).

One-time keys per database page are derived from the encryption key, the page number, and a 16 or 32 bytes nonce - depending on the _AEGIS_ variant. Additionally, the _AEGIS_ cipher provides a 32 bytes authentication tag per database page. Therefore this cipher requires 48 or 64 reserved bytes per database page.

The following table lists all parameters related to this cipher that can be set before activating database encryption.

| Parameter | Default | Min | Max | Description |
| :--- | :---: | :---: | :---: | :---: |
| `tcost` | 2 | 1 | | Number of iterations for the key derivation with Argon2id |
| `mcost` | 19456 | 1 | | Amount of memory in kB for key derivation with Argon2id |
| `pcost` | 1 | 1 | | Parallelism, number of threads for key derivation with Argon2 |
| `algorithm` | 4 | 1 | 6 | AEGIS variant to be used for page encryption |

**Notes**
{: .label .label-red .ml-0 .mb-1 .mt-2 }
- The default values were chosen based on the [OWASP](https://owasp.ord)(Open Web Application Security Project) recommendations as listed on the [Argon2](https://en.wikipedia.org/wiki/Argon2) WikiPedia web page under the heading _Recommended minimum parameters_.
- Each combination of parameter values leads to different encryption and authentication tag values. If databases need to be compatible across different platforms and devices, the parameter values should be chosen with care. For example, _iOS_ restricts memory use to about 47 MB, so that choosing a value greater than `47 x 1024` (= `48128`) for `mcost` can cause errors.
- Any of the available algorithms can be chosen on any platform. If hardware support is available, it will be used to accelerate the encryption process, but a software implementation will be used where hardware support is lacking.

**Note**
{: .label .label-red .ml-0 .mb-1 .mt-2 }

When specifying the `algorithm` via `PRAGMA` or as an URI parameter, the value can be specified as a _number_ or as a _string _ according to the following table:

| Index | Name | Description |
| :---: | :--- | :--- |
| 1 | `aegis-128l` | 128-bit key, a 128-bit nonce, 128-bit register |
| 2 | `aegis-128x2` | 128-bit key, a 128-bit nonce, 256-bit register |
| 3 | `aegis-128x4` | 128-bit key, a 128-bit nonce, 512-bit register |
| 4 | `aegis-256` | 256-bit key, a 256-bit nonce, 128-bit register (default) |
| 5 | `aegis-256x2` | 256-bit key, a 256-bit nonce, 256-bit register |
| 6 | `aegis-256x4` | 256-bit key, a 256-bit nonce, 512-bit register |

<span class="label label-green">Example:</span> Setup for _AEGIS_ cipher scheme

```sql
PRAGMA cipher = 'aegis';
PRAGMA algorithm = 'aegis-256x2';
PRAGMA key='<passphrase>';
```
4 changes: 2 additions & 2 deletions docs/ciphers/cipher_dynamic.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: default
title: Dynamic cipher schemes
parent: Supported Ciphers
nav_order: 7
nav_order: 9
---
## <a name="legacy" /> Dynamic cipher schemes

Expand Down Expand Up @@ -72,7 +72,7 @@ typedef int (*GetLegacy_t)(void* cipher);
typedef int (*GetPageSize_t)(void* cipher);
typedef int (*GetReserved_t)(void* cipher);
typedef unsigned char* (*GetSalt_t)(void* cipher);
typedef void (*GenerateKey_t)(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt);
typedef void (*GenerateKey_t)(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt);
typedef int (*EncryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved);
typedef int (*DecryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved, int hmacCheck);

Expand Down
2 changes: 1 addition & 1 deletion docs/ciphers/cipher_legacy_mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: default
title: Legacy cipher modes
parent: Supported Ciphers
nav_order: 6
nav_order: 8
---
## <a name="legacy" /> Legacy cipher modes

Expand Down
1 change: 1 addition & 0 deletions docs/configuration/config_sql_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ The following table lists the supported cipher identifiers:
| `sqlcipher` | [SQLCipher: AES 256 Bit]({{ site.baseurl }}{% link docs/ciphers/cipher_sqlcipher.md %}) |
| `rc4` | [System.Data.SQLite: RC4]({{ site.baseurl }}{% link docs/ciphers/cipher_sds_rc4.md %}) |
| `ascon128` | [Ascon: Ascon-128 v1.2]({{ site.baseurl }}{% link docs/ciphers/cipher_ascon.md %}) |
| `aegis` | [AEGIS: AEGIS family]({{ site.baseurl }}{% link docs/ciphers/cipher_aegis.md %}) |

Note
{: .label .label-red .ml-0 .mb-1 .mt-2 }
Expand Down
65 changes: 65 additions & 0 deletions docs/configuration/config_sql_pragmas.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,68 @@ Notes
{: .label .label-red .ml-0 .mb-1 .mt-2 }
- The offset recommended by **SQLCipher** is currently 32. This value ensures that the important [SQLite header](https://www.sqlite.org/fileformat.html) segments are readable by iOS, i.e. the magic string "SQLite Format 3\0" and the database read/write version numbers indicating a database is operating in WAL journal mode (bytes at offsets 18 and 19). This will allow iOS to identify the file and will permit an application to background correctly without being killed.
- The drawback of this approach is that the cipher salt used for the key derivation can't be stored in the database header any longer. Therefore it is necessary to retrieve the cipher salt on creating a new database, and to specify the salt on opening an existing database. The cipher salt can be retrieved with the function wxsqlite3_codec_data using parameter cipher_salt, and has to be supplied on opening a database via the database URI parameter `cipher_salt`.

---

### PRAGMA *tcost*

**Applicable to:**
[AEGIS]({{ site.baseurl }}{% link docs/ciphers/cipher_aegis.md %})

The `PRAGMA tcost` statement allows to specify the _number of iterations_ used to derive the key material with the _Argon2id_ function. It has the following syntax:

```sql
PRAGMA tcost = { 1 | 2 ... };
```

---

### PRAGMA *mcost*

**Applicable to:**
[AEGIS]({{ site.baseurl }}{% link docs/ciphers/cipher_aegis.md %})

The `PRAGMA mcost` statement allows to specify the _amount of memory_ used to derive the key material with the _Argon2id_ function. The amount is specified as the _number of **kB** memory blocks_. It has the following syntax:

```sql
PRAGMA mcost = { 1 | 2 ... };
```
For example, specifying a value of `1024x1024` = `1048576` requests _1 GB_ of memory to be used for deriving the key material.

---

### PRAGMA *pcost*

**Applicable to:**
[AEGIS]({{ site.baseurl }}{% link docs/ciphers/cipher_aegis.md %})

The `PRAGMA pcost` statement allows to modify the _parallelism_ aka _the number of threads_ used to derive the key material with the _Argon2id_ function. It has the following syntax:

```sql
PRAGMA pcost = { 1 | 2 ... };
```
where the value corresponds to the hash algoritm for HMAC calculation:
- 0 = SHA1
- 1 = SHA256
- 2 = SHA512

---

### PRAGMA *algorithm*

**Applicable to:**
[AEGIS]({{ site.baseurl }}{% link docs/ciphers/cipher_aegis.md %})

The `PRAGMA algorithm` statement allows to modify the _AEGIS_ algorithm variant used for encryption. It has the following syntax:

```sql
PRAGMA algorithm = { 1 | `aegis-128l` | 2 | `aegis-128x2` | 3 | `aegis-128x4`|
4 | `aegis-256` | 5 | `aegis-256x2` | 6 | `aegis-256x4` };
```
where the value corresponds to the _AEGIS_ algorithm:
- 1 = `aegis-128l`
- 2 = `aegis-128x2`
- 3 = `aegis-128x4`
- 4 = `aegis-256`
- 5 = `aegis-256x2`
- 6 = `aegis-256x4`

0 comments on commit f408e44

Please sign in to comment.