Skip to content

Commit fde3681

Browse files
committed
Make things less wide
Improved technical section
1 parent 35723c9 commit fde3681

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

common.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ header {
5959

6060
/* Container */
6161
.container {
62-
max-width: 1400px;
62+
max-width: 1200px;
6363
margin: 0 auto;
6464
padding: 0 20px;
6565
}
6666

6767
/* Section */
6868
section {
6969
padding: 4rem 1rem;
70-
max-width: 1200px;
70+
max-width: 1000px;
7171
margin: 0 auto;
7272
}
7373

technical.css

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
}
5454

5555
/* Tech page uses common .grid, .card, and .icon styles */
56-
/* Aliasing common classes for backward compatibility with HTML */
5756
.tech-grid {
5857
display: grid;
5958
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@@ -82,4 +81,28 @@
8281
font-size: 3rem;
8382
margin-bottom: 1rem;
8483
color: var(--primary-purple);
84+
}
85+
86+
.tech-grid.expanded {
87+
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
88+
}
89+
90+
.subtle-divider {
91+
border: none;
92+
border-top: 1px solid #e0e0e0;
93+
width: 60%;
94+
margin: 2rem auto;
95+
}
96+
97+
code {
98+
display: inline;
99+
padding: 0.2em 0.4em;
100+
background-color: #f5f5f5;
101+
border: 1px solid #e0e0e0;
102+
border-radius: 3px;
103+
font-family: 'Courier New', Consolas, monospace;
104+
font-size: 0.9em;
105+
color: #333;
106+
white-space: pre-wrap;
107+
word-break: break-word;
85108
}

technical.html

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,17 @@ <h5>Hardware Key Store:</h5>
171171

172172
<p><strong>Argon2 Salt:</strong> The salt used to Argon2 hash the PIN, is also used as the PBKF2 algorithm salt</p>
173173

174-
<div class="tech-grid">
174+
<hr class="subtle-divider" />
175+
176+
<h3>Security Levels Explained:</h3>
177+
<p>You can check which security level your device supports during PIN creation, or in settings. Here is what each security level actually means:</p>
178+
179+
<div class="tech-grid expanded">
175180
<div class="tech-card">
176181
<div class="tech-icon">🔑</div>
177182
<h3>Weak Security</h3>
178183
<ul>
179-
<li>Your device does not support an form of Hardware Backed encryption keys.</li>
184+
<li>Your device does not support any form of Hardware Backed encryption keys.</li>
180185
<li>In this case we require your PIN to have a minimum size of 6 digits (<em>instead of 4</em>) because here, your PIN is the main source of entropy during PIN creation. 6 is still not very much, a longer PIN is much better in this case. But it must be understood that with this security level, we can not guarantee that an attacker, given enough time, will not be able to crack this encryption.</li>
181186
<li><strong>Ephemeral Key:</strong> This key is derived in memory, and is never written to disk.</li>
182187
<li><div class="tech-code">Key = PBKF2(PIN + DeviceID, bSalt)</div></li>
@@ -187,8 +192,8 @@ <h3>Weak Security</h3>
187192
<div class="tech-icon">🔐</div>
188193
<h3>Normal Security</h3>
189194
<ul>
190-
<li>Your device supports a Trusted Execution Environment (TEE) for storing encryption keys and executing some cryptographic operations. A KEK (<em>Key Encryption Key</em>) is provisioned inside of the TEE.</li>
191-
<li><strong>Key Wrapping:</strong> This is the default mode, a Data Encryption Key is constructed in memory, then passed into the TEE, and encrypted with the KEK. This "Wrapped Key" is then written to disk. When the user authenticates with their PIN, the Wrapped key is read from disk, passed back the TEE, and finally the unwrapped Data key is resident in main memory.</li>
195+
<li>Your device supports a Trusted Execution Environment (TEE) for storing encryption keys and executing some cryptographic operations. A KEK (<em>Key Encryption Key</em>) is provisioned inside the TEE.</li>
196+
<li><strong>Key Wrapping:</strong> This is the default mode, a Data Encryption Key (DEK) is constructed in memory, then passed into the TEE, and encrypted with the KEK. This "Wrapped Key" is then written to disk. When the user authenticates with their PIN, the Wrapped key is read from disk, passed back the TEE, and finally the unwrapped DEK is resident in main memory.</li>
192197
<li><strong>Ephemeral Key:</strong> An optional level of security this mode never writes the fully derived key to disk. In this mode the dSalt is passed into the TEE, and encrypted with the KEK, and written to disk. Although this is the main source of entry, it is still not the full key. When the user authenticates we read the dSalt from disk, decrypt it with the KEK in the TEE, and finally construct the full key in memory. The key derivation function is quite slow (<em>by design of course</em>) so the trade off is that it now takes multiple seconds to authenticate.</li>
193198
<li><div class="tech-code">Key = PBKF2(PIN + DeviceID + dSalt, bSalt)</div></li>
194199
</ul>
@@ -199,12 +204,22 @@ <h3>Normal Security</h3>
199204
<h3>Strong Security</h3>
200205
<ul>
201206
<li>Your device supports a Secure Element (SE), this is the strongest security possible. Functionally it is similar to a TEE, but it is a physically separate chip from your main SOC. It is thus resistant to side channel attacks. It is also designed to be resistant to physical "chip-off" attacks where your device has been deconstructed and the chips put in an attack harness. In this case a SE is designed to detect this and self destruct the data inside.</li>
202-
<li>Other than the benefits the SE adds on it's own, the rest of our security is identical to the <strong>Normal Security</strong> level.</li>
207+
<li>Other than the benefits the SE adds on its own, the rest of our security is identical to the <strong>Normal Security</strong> level.</li>
203208
<li><div class="tech-code">Key = PBKF2(PIN + DeviceID + dSalt, bSalt)</div></li>
204209
</ul>
205210
</div>
206211
</div>
207212

213+
<div class="tech-highlight">
214+
<h3>Key Sharding</h3>
215+
<p>All Data Encryption Keys, once loaded into memory, are stored as <strong>Sharded Keys</strong>.</p>
216+
<p>When instantiated <code>buffer1</code> of length <code>[key size] + [random₁]</code> length is created and fill with entropy. Then a second <code>buffer2</code> of size <code>[key size] + [random₂]</code> is created and fill with entropy. The leading part of the buffer is then filled with the XOR'd DEK: <code>buffer2 = buffer1 <strong>XOR</strong> DEK</code></p>
217+
<p>This should make the in-memory key resistant to memory dumping as well as automatic scanners looking for AES Key sized allocations. Since the allocations are made separately, and of different sizes, there is a likelihood they will not reside next to each other in memory making it possible that a partial memory dump may not include both of them.</p>
218+
<p>Lastly, the key shards are stored in native memory, not the JVM heap. This allows us to have deterministic control over deallocation. Meaning we can ensure the memory gets zero'd before release.</p>
219+
</div>
220+
221+
<hr class="subtle-divider" />
222+
208223
<p><strong>Photos</strong></p>
209224
<p>On disk photos and thumbnails are encrypted using a standard Initialization Vector (IV) + AES/GCM 256. The IV is unique to each photo, and is concatenated at the start of each file. So decryption first reads out the IV, then uses that and the key to decrypt the rest of the file.</p>
210225
<div class="tech-code">File = [IV + Encrypted Photo Data]</div>

0 commit comments

Comments
 (0)