← Documents Documentation/filesystems/ubifs-authentication.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

UBIFS Authentication Support

UBIFS threat model, Merkle index, journal HMAC chain과 key 관리의 전문 번역입니다.

Source pathDocumentation/filesystems/ubifs-authentication.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

ubifs-authentication.rst:1-448

UBIFS authentication은 raw flash의 index·journal·LPT를 인증해 offline file·metadata 변조를 탐지한다. Merkle index root를 master HMAC에 고정하고, journal은 commit start부터 REF·bud를 잇는 hash chain과 auth node로 replay 순서를 보호한다.

전체·부분 rollback과 key 제공 뒤 code execution은 threat model 밖이다. 전용 authentication key는 fscrypt encryption key와 분리하며 생성·mount·commit에서 superblock·master·journal HMAC에 사용한다.

UBIFS trust root
Authentication keysuperblock·master HMACMerkle index rootjournal hash chain·auth nodeatomic LPT hash

단일 authentication key에서 세 persistent 구조 검증으로 확장된다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 .. UBIFS Authentication
4 .. sigma star gmbh
5 .. 2018
6
7 ============================
8 UBIFS Authentication Support
9 ============================
10
11 Introduction
12 ============
13
14 UBIFS utilizes the fscrypt framework to provide confidentiality for file
15 contents and file names. This prevents attacks where an attacker is able to
16 read contents of the filesystem on a single point in time. A classic example
17 is a lost smartphone where the attacker is unable to read personal data stored
18 on the device without the filesystem decryption key.
19
20 At the current state, UBIFS encryption however does not prevent attacks where
21 the attacker is able to modify the filesystem contents and the user uses the
22 device afterwards. In such a scenario an attacker can modify filesystem
23 contents arbitrarily without the user noticing. One example is to modify a
24 binary to perform a malicious action when executed [DMC-CBC-ATTACK]. Since
25 most of the filesystem metadata of UBIFS is stored in plain, this makes it
26 fairly easy to swap files and replace their contents.
27
28 Other full disk encryption systems like dm-crypt cover all filesystem metadata,
29 which makes such kinds of attacks more complicated, but not impossible.
30 Especially, if the attacker is given access to the device multiple points in
31 time. For dm-crypt and other filesystems that build upon the Linux block IO
32 layer, the dm-integrity or dm-verity subsystems [DM-INTEGRITY, DM-VERITY]
33 can be used to get full data authentication at the block layer.
34 These can also be combined with dm-crypt [CRYPTSETUP2].
35
36 This document describes an approach to get file contents _and_ full metadata
37 authentication for UBIFS. Since UBIFS uses fscrypt for file contents and file
38 name encryption, the authentication system could be tied into fscrypt such that
39 existing features like key derivation can be utilized. It should however also
40 be possible to use UBIFS authentication without using encryption.
41
42
43 MTD, UBI & UBIFS
44 ----------------
45
46 On Linux, the MTD (Memory Technology Devices) subsystem provides a uniform
47 interface to access raw flash devices. One of the more prominent subsystems that
48 work on top of MTD is UBI (Unsorted Block Images). It provides volume management
49 for flash devices and is thus somewhat similar to LVM for block devices. In
50 addition, it deals with flash-specific wear-leveling and transparent I/O error
51 handling. UBI offers logical erase blocks (LEBs) to the layers on top of it
52 and maps them transparently to physical erase blocks (PEBs) on the flash.
53
54 UBIFS is a filesystem for raw flash which operates on top of UBI. Thus, wear
55 leveling and some flash specifics are left to UBI, while UBIFS focuses on
56 scalability, performance and recoverability.
57
58 ::
59
60 +------------+ +*******+ +-----------+ +-----+
61 | | * UBIFS * | UBI-BLOCK | | ... |
62 | JFFS/JFFS2 | +*******+ +-----------+ +-----+
63 | | +-----------------------------+ +-----------+ +-----+
64 | | | UBI | | MTD-BLOCK | | ... |
65 +------------+ +-----------------------------+ +-----------+ +-----+
66 +------------------------------------------------------------------+
67 | MEMORY TECHNOLOGY DEVICES (MTD) |
68 +------------------------------------------------------------------+
69 +-----------------------------+ +--------------------------+ +-----+
70 | NAND DRIVERS | | NOR DRIVERS | | ... |
71 +-----------------------------+ +--------------------------+ +-----+
72
73 Figure 1: Linux kernel subsystems for dealing with raw flash
74
75
76
77 Internally, UBIFS maintains multiple data structures which are persisted on
78 the flash:
79
80 - *Index*: an on-flash B+ tree where the leaf nodes contain filesystem data
81 - *Journal*: an additional data structure to collect FS changes before updating
82 the on-flash index and reduce flash wear.
83 - *Tree Node Cache (TNC)*: an in-memory B+ tree that reflects the current FS
84 state to avoid frequent flash reads. It is basically the in-memory
85 representation of the index, but contains additional attributes.
86 - *LEB property tree (LPT)*: an on-flash B+ tree for free space accounting per
87 UBI LEB.
88
89 In the remainder of this section we will cover the on-flash UBIFS data
90 structures in more detail. The TNC is of less importance here since it is never
91 persisted onto the flash directly. More details on UBIFS can also be found in
92 [UBIFS-WP].
93
94
95 UBIFS Index & Tree Node Cache
96 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97
98 Basic on-flash UBIFS entities are called *nodes*. UBIFS knows different types
99 of nodes. Eg. data nodes (``struct ubifs_data_node``) which store chunks of file
100 contents or inode nodes (``struct ubifs_ino_node``) which represent VFS inodes.
101 Almost all types of nodes share a common header (``ubifs_ch``) containing basic
102 information like node type, node length, a sequence number, etc. (see
103 ``fs/ubifs/ubifs-media.h`` in kernel source). Exceptions are entries of the LPT
104 and some less important node types like padding nodes which are used to pad
105 unusable content at the end of LEBs.
106
107 To avoid re-writing the whole B+ tree on every single change, it is implemented
108 as *wandering tree*, where only the changed nodes are re-written and previous
109 versions of them are obsoleted without erasing them right away. As a result,
110 the index is not stored in a single place on the flash, but *wanders* around
111 and there are obsolete parts on the flash as long as the LEB containing them is
112 not reused by UBIFS. To find the most recent version of the index, UBIFS stores
113 a special node called *master node* into UBI LEB 1 which always points to the
114 most recent root node of the UBIFS index. For recoverability, the master node
115 is additionally duplicated to LEB 2. Mounting UBIFS is thus a simple read of
116 LEB 1 and 2 to get the current master node and from there get the location of
117 the most recent on-flash index.
118
119 The TNC is the in-memory representation of the on-flash index. It contains some
120 additional runtime attributes per node which are not persisted. One of these is
121 a dirty-flag which marks nodes that have to be persisted the next time the
122 index is written onto the flash. The TNC acts as a write-back cache and all
123 modifications of the on-flash index are done through the TNC. Like other caches,
124 the TNC does not have to mirror the full index into memory, but reads parts of
125 it from flash whenever needed. A *commit* is the UBIFS operation of updating the
126 on-flash filesystem structures like the index. On every commit, the TNC nodes
127 marked as dirty are written to the flash to update the persisted index.
128
129
130 Journal
131 ~~~~~~~
132
133 To avoid wearing out the flash, the index is only persisted (*committed*) when
134 certain conditions are met (eg. ``fsync(2)``). The journal is used to record
135 any changes (in form of inode nodes, data nodes etc.) between commits
136 of the index. During mount, the journal is read from the flash and replayed
137 onto the TNC (which will be created on-demand from the on-flash index).
138
139 UBIFS reserves a bunch of LEBs just for the journal called *log area*. The
140 amount of log area LEBs is configured on filesystem creation (using
141 ``mkfs.ubifs``) and stored in the superblock node. The log area contains only
142 two types of nodes: *reference nodes* and *commit start nodes*. A commit start
143 node is written whenever an index commit is performed. Reference nodes are
144 written on every journal update. Each reference node points to the position of
145 other nodes (inode nodes, data nodes etc.) on the flash that are part of this
146 journal entry. These nodes are called *buds* and describe the actual filesystem
147 changes including their data.
148
149 The log area is maintained as a ring. Whenever the journal is almost full,
150 a commit is initiated. This also writes a commit start node so that during
151 mount, UBIFS will seek for the most recent commit start node and just replay
152 every reference node after that. Every reference node before the commit start
153 node will be ignored as they are already part of the on-flash index.
154
155 When writing a journal entry, UBIFS first ensures that enough space is
156 available to write the reference node and buds part of this entry. Then, the
157 reference node is written and afterwards the buds describing the file changes.
158 On replay, UBIFS will record every reference node and inspect the location of
159 the referenced LEBs to discover the buds. If these are corrupt or missing,
160 UBIFS will attempt to recover them by re-reading the LEB. This is however only
161 done for the last referenced LEB of the journal. Only this can become corrupt
162 because of a power cut. If the recovery fails, UBIFS will not mount. An error
163 for every other LEB will directly cause UBIFS to fail the mount operation.
164
165 ::
166
167 | ---- LOG AREA ---- | ---------- MAIN AREA ------------ |
168
169 -----+------+-----+--------+---- ------+-----+-----+---------------
170 \ | | | | / / | | | \
171 / CS | REF | REF | | \ \ DENT | INO | INO | /
172 \ | | | | / / | | | \
173 ----+------+-----+--------+--- -------+-----+-----+----------------
174 | | ^ ^
175 | | | |
176 +------------------------+ |
177 | |
178 +-------------------------------+
179
180
181 Figure 2: UBIFS flash layout of log area with commit start nodes
182 (CS) and reference nodes (REF) pointing to main area
183 containing their buds
184
185
186 LEB Property Tree/Table
187 ~~~~~~~~~~~~~~~~~~~~~~~
188
189 The LEB property tree is used to store per-LEB information. This includes the
190 LEB type and amount of free and *dirty* (old, obsolete content) space [1]_ on
191 the LEB. The type is important, because UBIFS never mixes index nodes with data
192 nodes on a single LEB and thus each LEB has a specific purpose. This again is
193 useful for free space calculations. See [UBIFS-WP] for more details.
194
195 The LEB property tree again is a B+ tree, but it is much smaller than the
196 index. Due to its smaller size it is always written as one chunk on every
197 commit. Thus, saving the LPT is an atomic operation.
198
199
200 .. [1] Since LEBs can only be appended and never overwritten, there is a
201 difference between free space ie. the remaining space left on the LEB to be
202 written to without erasing it and previously written content that is obsolete
203 but can't be overwritten without erasing the full LEB.
204
205
206 UBIFS Authentication
207 ====================
208
209 This chapter introduces UBIFS authentication which enables UBIFS to verify
210 the authenticity and integrity of metadata and file contents stored on flash.
211
212
213 Threat Model
214 ------------
215
216 UBIFS authentication enables detection of offline data modification. While it
217 does not prevent it, it enables (trusted) code to check the integrity and
218 authenticity of on-flash file contents and filesystem metadata. This covers
219 attacks where file contents are swapped.
220
221 UBIFS authentication will not protect against rollback of full flash contents.
222 Ie. an attacker can still dump the flash and restore it at a later time without
223 detection. It will also not protect against partial rollback of individual
224 index commits. That means that an attacker is able to partially undo changes.
225 This is possible because UBIFS does not immediately overwrites obsolete
226 versions of the index tree or the journal, but instead marks them as obsolete
227 and garbage collection erases them at a later time. An attacker can use this by
228 erasing parts of the current tree and restoring old versions that are still on
229 the flash and have not yet been erased. This is possible, because every commit
230 will always write a new version of the index root node and the master node
231 without overwriting the previous version. This is further helped by the
232 wear-leveling operations of UBI which copies contents from one physical
233 eraseblock to another and does not atomically erase the first eraseblock.
234
235 UBIFS authentication does not cover attacks where an attacker is able to
236 execute code on the device after the authentication key was provided.
237 Additional measures like secure boot and trusted boot have to be taken to
238 ensure that only trusted code is executed on a device.
239
240
241 Authentication
242 --------------
243
244 To be able to fully trust data read from flash, all UBIFS data structures
245 stored on flash are authenticated. That is:
246
247 - The index which includes file contents, file metadata like extended
248 attributes, file length etc.
249 - The journal which also contains file contents and metadata by recording changes
250 to the filesystem
251 - The LPT which stores UBI LEB metadata which UBIFS uses for free space accounting
252
253
254 Index Authentication
255 ~~~~~~~~~~~~~~~~~~~~
256
257 Through UBIFS' concept of a wandering tree, it already takes care of only
258 updating and persisting changed parts from leaf node up to the root node
259 of the full B+ tree. This enables us to augment the index nodes of the tree
260 with a hash over each node's child nodes. As a result, the index basically also
261 a Merkle tree. Since the leaf nodes of the index contain the actual filesystem
262 data, the hashes of their parent index nodes thus cover all the file contents
263 and file metadata. When a file changes, the UBIFS index is updated accordingly
264 from the leaf nodes up to the root node including the master node. This process
265 can be hooked to recompute the hash only for each changed node at the same time.
266 Whenever a file is read, UBIFS can verify the hashes from each leaf node up to
267 the root node to ensure the node's integrity.
268
269 To ensure the authenticity of the whole index, the UBIFS master node stores a
270 keyed hash (HMAC) over its own contents and a hash of the root node of the index
271 tree. As mentioned above, the master node is always written to the flash whenever
272 the index is persisted (ie. on index commit).
273
274 Using this approach only UBIFS index nodes and the master node are changed to
275 include a hash. All other types of nodes will remain unchanged. This reduces
276 the storage overhead which is precious for users of UBIFS (ie. embedded
277 devices).
278
279 ::
280
281 +---------------+
282 | Master Node |
283 | (hash) |
284 +---------------+
285 |
286 v
287 +-------------------+
288 | Index Node #1 |
289 | |
290 | branch0 branchn |
291 | (hash) (hash) |
292 +-------------------+
293 | ... | (fanout: 8)
294 | |
295 +-------+ +------+
296 | |
297 v v
298 +-------------------+ +-------------------+
299 | Index Node #2 | | Index Node #3 |
300 | | | |
301 | branch0 branchn | | branch0 branchn |
302 | (hash) (hash) | | (hash) (hash) |
303 +-------------------+ +-------------------+
304 | ... | ... |
305 v v v
306 +-----------+ +----------+ +-----------+
307 | Data Node | | INO Node | | DENT Node |
308 +-----------+ +----------+ +-----------+
309
310
311 Figure 3: Coverage areas of index node hash and master node HMAC
312
313
314
315 The most important part for robustness and power-cut safety is to atomically
316 persist the hash and file contents. Here the existing UBIFS logic for how
317 changed nodes are persisted is already designed for this purpose such that
318 UBIFS can safely recover if a power-cut occurs while persisting. Adding
319 hashes to index nodes does not change this since each hash will be persisted
320 atomically together with its respective node.
321
322
323 Journal Authentication
324 ~~~~~~~~~~~~~~~~~~~~~~
325
326 The journal is authenticated too. Since the journal is continuously written
327 it is necessary to also add authentication information frequently to the
328 journal so that in case of a powercut not too much data can't be authenticated.
329 This is done by creating a continuous hash beginning from the commit start node
330 over the previous reference nodes, the current reference node, and the bud
331 nodes. From time to time whenever it is suitable authentication nodes are added
332 between the bud nodes. This new node type contains a HMAC over the current state
333 of the hash chain. That way a journal can be authenticated up to the last
334 authentication node. The tail of the journal which may not have a authentication
335 node cannot be authenticated and is skipped during journal replay.
336
337 We get this picture for journal authentication::
338
339 ,,,,,,,,
340 ,......,...........................................
341 ,. CS , hash1.----. hash2.----.
342 ,. | , . |hmac . |hmac
343 ,. v , . v . v
344 ,.REF#0,-> bud -> bud -> bud.-> auth -> bud -> bud.-> auth ...
345 ,..|...,...........................................
346 , | ,
347 , | ,,,,,,,,,,,,,,,
348 . | hash3,----.
349 , | , |hmac
350 , v , v
351 , REF#1 -> bud -> bud,-> auth ...
352 ,,,|,,,,,,,,,,,,,,,,,,
353 v
354 REF#2 -> ...
355 |
356 V
357 ...
358
359 Since the hash also includes the reference nodes an attacker cannot reorder or
360 skip any journal heads for replay. An attacker can only remove bud nodes or
361 reference nodes from the end of the journal, effectively rewinding the
362 filesystem at maximum back to the last commit.
363
364 The location of the log area is stored in the master node. Since the master
365 node is authenticated with a HMAC as described above, it is not possible to
366 tamper with that without detection. The size of the log area is specified when
367 the filesystem is created using `mkfs.ubifs` and stored in the superblock node.
368 To avoid tampering with this and other values stored there, a HMAC is added to
369 the superblock struct. The superblock node is stored in LEB 0 and is only
370 modified on feature flag or similar changes, but never on file changes.
371
372
373 LPT Authentication
374 ~~~~~~~~~~~~~~~~~~
375
376 The location of the LPT root node on the flash is stored in the UBIFS master
377 node. Since the LPT is written and read atomically on every commit, there is
378 no need to authenticate individual nodes of the tree. It suffices to
379 protect the integrity of the full LPT by a simple hash stored in the master
380 node. Since the master node itself is authenticated, the LPTs authenticity can
381 be verified by verifying the authenticity of the master node and comparing the
382 LTP hash stored there with the hash computed from the read on-flash LPT.
383
384
385 Key Management
386 --------------
387
388 For simplicity, UBIFS authentication uses a single key to compute the HMACs
389 of superblock, master, commit start and reference nodes. This key has to be
390 available on creation of the filesystem (`mkfs.ubifs`) to authenticate the
391 superblock node. Further, it has to be available on mount of the filesystem
392 to verify authenticated nodes and generate new HMACs for changes.
393
394 UBIFS authentication is intended to operate side-by-side with UBIFS encryption
395 (fscrypt) to provide confidentiality and authenticity. Since UBIFS encryption
396 has a different approach of encryption policies per directory, there can be
397 multiple fscrypt master keys and there might be folders without encryption.
398 UBIFS authentication on the other hand has an all-or-nothing approach in the
399 sense that it either authenticates everything of the filesystem or nothing.
400 Because of this and because UBIFS authentication should also be usable without
401 encryption, it does not share the same master key with fscrypt, but manages
402 a dedicated authentication key.
403
404 The API for providing the authentication key has yet to be defined, but the
405 key can eg. be provided by userspace through a keyring similar to the way it
406 is currently done in fscrypt. It should however be noted that the current
407 fscrypt approach has shown its flaws and the userspace API will eventually
408 change [FSCRYPT-POLICY2].
409
410 Nevertheless, it will be possible for a user to provide a single passphrase
411 or key in userspace that covers UBIFS authentication and encryption. This can
412 be solved by the corresponding userspace tools which derive a second key for
413 authentication in addition to the derived fscrypt master key used for
414 encryption.
415
416 To be able to check if the proper key is available on mount, the UBIFS
417 superblock node will additionally store a hash of the authentication key. This
418 approach is similar to the approach proposed for fscrypt encryption policy v2
419 [FSCRYPT-POLICY2].
420
421
422 Future Extensions
423 =================
424
425 In certain cases where a vendor wants to provide an authenticated filesystem
426 image to customers, it should be possible to do so without sharing the secret
427 UBIFS authentication key. Instead, in addition the each HMAC a digital
428 signature could be stored where the vendor shares the public key alongside the
429 filesystem image. In case this filesystem has to be modified afterwards,
430 UBIFS can exchange all digital signatures with HMACs on first mount similar
431 to the way the IMA/EVM subsystem deals with such situations. The HMAC key
432 will then have to be provided beforehand in the normal way.
433
434
435 References
436 ==========
437
438 [CRYPTSETUP2] https://www.saout.de/pipermail/dm-crypt/2017-November/005745.html
439
440 [DMC-CBC-ATTACK] https://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/
441
442 [DM-INTEGRITY] https://www.kernel.org/doc/Documentation/device-mapper/dm-integrity.rst
443
444 [DM-VERITY] https://www.kernel.org/doc/Documentation/device-mapper/verity.rst
445
446 [FSCRYPT-POLICY2] https://lore.kernel.org/r/20171023214058.128121-1-ebiggers3@gmail.com/
447
448 [UBIFS-WP] http://www.linux-mtd.infradead.org/doc/ubifs_whitepaper.pdf
449

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

암호화만으로 막지 못하는 변조

1-42

UBIFS는 `fscrypt`로 file content와 filename의 confidentiality를 제공한다. 분실한 smartphone처럼 공격자가 한 시점의 storage를 읽어도 decryption key 없이는 개인 data를 볼 수 없게 한다.

하지만 암호화만으로는 공격자가 파일 시스템을 수정한 뒤 사용자가 device를 다시 쓰는 공격을 막지 못한다. binary를 바꿔 실행 때 악성 동작을 하게 할 수 있고, UBIFS metadata 대부분이 평문이므로 file 교체와 content 치환도 쉽다.

dm-crypt 같은 full-disk encryption은 metadata까지 덮어 공격을 어렵게 하지만 여러 시점에 device를 만질 수 있는 공격자를 완전히 막지는 못한다. block I/O 계층 위에서는 dm-integrity·dm-verity를 dm-crypt와 결합해 block-level authentication을 얻을 수 있다.

이 문서는 raw flash용 UBIFS에서 file content와 전체 metadata를 인증하는 방법을 설명한다. fscrypt의 key derivation을 재사용할 수 있지만, encryption 없이 UBIFS authentication만 사용하는 것도 가능해야 한다.

Confidentiality와 authentication
기능보호보호하지 못하는 것
fscrypt encryptionfile content·filename 기밀성offline metadata·ciphertext 변조
dm-cryptblock 전체 암호화시간차 rollback·무결성
UBIFS authenticationfile·metadata offline 변조 탐지full/partial rollback, 실행 중 key 탈취

보호 목표와 남는 공격을 분리한다.

.. SPDX-License-Identifier: GPL-2.0

.. UBIFS Authentication
.. sigma star gmbh
.. 2018

============================
UBIFS Authentication Support
============================

Introduction
============

UBIFS utilizes the fscrypt framework to provide confidentiality for file
contents and file names. This prevents attacks where an attacker is able to
read contents of the filesystem on a single point in time. A classic example
is a lost smartphone where the attacker is unable to read personal data stored
on the device without the filesystem decryption key.

At the current state, UBIFS encryption however does not prevent attacks where
the attacker is able to modify the filesystem contents and the user uses the
device afterwards. In such a scenario an attacker can modify filesystem
contents arbitrarily without the user noticing. One example is to modify a
binary to perform a malicious action when executed [DMC-CBC-ATTACK]. Since
most of the filesystem metadata of UBIFS is stored in plain, this makes it
fairly easy to swap files and replace their contents.

Other full disk encryption systems like dm-crypt cover all filesystem metadata,
which makes such kinds of attacks more complicated, but not impossible.
Especially, if the attacker is given access to the device multiple points in
time. For dm-crypt and other filesystems that build upon the Linux block IO
layer, the dm-integrity or dm-verity subsystems [DM-INTEGRITY, DM-VERITY]
can be used to get full data authentication at the block layer.
These can also be combined with dm-crypt [CRYPTSETUP2].

This document describes an approach to get file contents _and_ full metadata
authentication for UBIFS. Since UBIFS uses fscrypt for file contents and file
name encryption, the authentication system could be tied into fscrypt such that
existing features like key derivation can be utilized. It should however also
be possible to use UBIFS authentication without using encryption.

MTD·UBI·UBIFS 계층과 내부 구조

43-94

MTD(Memory Technology Devices)는 raw flash device의 공통 interface다. 그 위의 UBI(Unsorted Block Images)는 block device의 LVM과 비슷한 volume 관리에 wear-leveling과 transparent I/O error 처리를 더한다. 상위 layer에 logical erase block(LEB)을 제공하고 flash의 physical erase block(PEB)에 mapping한다.

UBIFS는 UBI 위에서 동작하는 raw-flash 파일 시스템이다. wear leveling과 flash 특성 일부는 UBI에 맡기고 scalability, performance, recoverability에 집중한다.

Raw flash software stack
UBIFS 또는 UBI-BLOCK consumerUBI volume·LEB 관리MTD raw-flash interfaceNAND·NOR driverphysical erase block flash hardware

원문의 계층 그림을 위에서 아래로 재구성했다.

persist되는 핵심 구조는 네 가지다. Index는 leaf에 filesystem data가 있는 on-flash B+ tree, Journal은 index update 사이 변경을 모아 wear를 줄이는 log, TNC(Tree Node Cache)는 현재 state를 반영하는 in-memory B+ tree, LPT(LEB Property Tree)는 LEB별 free space를 기록하는 on-flash B+ tree다. TNC는 flash에 직접 persist되지 않는다.

UBIFS 핵심 자료구조
구조위치역할
Indexon-flash B+ treeleaf에 file data·metadata
Journalon-flash log areacommit 사이 변경·bud 기록
TNCmemoryindex write-back cache와 runtime attribute
LPTon-flash B+ treeLEB type·free·dirty space

저장 위치와 역할을 비교한다.

MTD, UBI & UBIFS
----------------

On Linux, the MTD (Memory Technology Devices) subsystem provides a uniform
interface to access raw flash devices. One of the more prominent subsystems that
work on top of MTD is UBI (Unsorted Block Images). It provides volume management
for flash devices and is thus somewhat similar to LVM for block devices. In
addition, it deals with flash-specific wear-leveling and transparent I/O error
handling. UBI offers logical erase blocks (LEBs) to the layers on top of it
and maps them transparently to physical erase blocks (PEBs) on the flash.

UBIFS is a filesystem for raw flash which operates on top of UBI. Thus, wear
leveling and some flash specifics are left to UBI, while UBIFS focuses on
scalability, performance and recoverability.

::

        +------------+ +*******+ +-----------+ +-----+
        |            | * UBIFS * | UBI-BLOCK | | ... |
        | JFFS/JFFS2 | +*******+ +-----------+ +-----+
        |            | +-----------------------------+ +-----------+ +-----+
        |            | |              UBI            | | MTD-BLOCK | | ... |
        +------------+ +-----------------------------+ +-----------+ +-----+
        +------------------------------------------------------------------+
        |                  MEMORY TECHNOLOGY DEVICES (MTD)                 |
        +------------------------------------------------------------------+
        +-----------------------------+ +--------------------------+ +-----+
        |         NAND DRIVERS        | |        NOR DRIVERS       | | ... |
        +-----------------------------+ +--------------------------+ +-----+

            Figure 1: Linux kernel subsystems for dealing with raw flash



Internally, UBIFS maintains multiple data structures which are persisted on
the flash:

- *Index*: an on-flash B+ tree where the leaf nodes contain filesystem data
- *Journal*: an additional data structure to collect FS changes before updating
  the on-flash index and reduce flash wear.
- *Tree Node Cache (TNC)*: an in-memory B+ tree that reflects the current FS
  state to avoid frequent flash reads. It is basically the in-memory
  representation of the index, but contains additional attributes.
- *LEB property tree (LPT)*: an on-flash B+ tree for free space accounting per
  UBI LEB.

In the remainder of this section we will cover the on-flash UBIFS data
structures in more detail. The TNC is of less importance here since it is never
persisted onto the flash directly. More details on UBIFS can also be found in
[UBIFS-WP].

Wandering index·master node·TNC

95-129

UBIFS의 기본 on-flash 단위는 node다. `struct ubifs_data_node`는 file content chunk, `struct ubifs_ino_node`는 VFS inode를 나타낸다. 대부분 `ubifs_ch` 공통 header에 type, length, sequence number를 둔다. LPT entry와 LEB 끝을 채우는 padding node 같은 일부는 예외이며 형식은 `fs/ubifs/ubifs-media.h`에 있다.

B+ tree 전체를 매 변경마다 다시 쓰지 않도록 wandering tree로 구현한다. 바뀐 node만 새 위치에 쓰고 이전 version은 즉시 erase하지 않고 obsolete로 표시한다. 따라서 index는 flash 여러 곳을 이동하며 LEB가 재사용될 때까지 옛 조각이 남는다.

가장 최신 index는 UBI LEB 1의 master node가 root 위치를 가리켜 찾는다. 복구를 위해 LEB 2에도 duplicate한다. mount는 LEB 1·2를 읽어 현재 master와 최신 on-flash index를 얻는다.

TNC는 index의 in-memory 표현이며 dirty flag 같은 runtime attribute를 추가한다. write-back cache로서 모든 index 수정은 TNC를 거친다. 전체 index를 항상 mirror하지 않고 필요한 부분만 flash에서 읽는다. commit 때 dirty TNC node를 flash에 기록해 persistent index를 갱신한다.

Wandering index commit
TNC에서 변경 node를 dirty 표시leaf에서 root까지 변경 경로 새 위치에 기록이전 node version은 obsolete로 남김LEB 1 master가 새 root 위치 기록LEB 2에 master duplicate

변경 node만 새 위치에 쓰고 master가 새 root를 가리킨다.

UBIFS Index & Tree Node Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Basic on-flash UBIFS entities are called *nodes*. UBIFS knows different types
of nodes. Eg. data nodes (``struct ubifs_data_node``) which store chunks of file
contents or inode nodes (``struct ubifs_ino_node``) which represent VFS inodes.
Almost all types of nodes share a common header (``ubifs_ch``) containing basic
information like node type, node length, a sequence number, etc. (see
``fs/ubifs/ubifs-media.h`` in kernel source). Exceptions are entries of the LPT
and some less important node types like padding nodes which are used to pad
unusable content at the end of LEBs.

To avoid re-writing the whole B+ tree on every single change, it is implemented
as *wandering tree*, where only the changed nodes are re-written and previous
versions of them are obsoleted without erasing them right away. As a result,
the index is not stored in a single place on the flash, but *wanders* around
and there are obsolete parts on the flash as long as the LEB containing them is
not reused by UBIFS. To find the most recent version of the index, UBIFS stores
a special node called *master node* into UBI LEB 1 which always points to the
most recent root node of the UBIFS index. For recoverability, the master node
is additionally duplicated to LEB 2. Mounting UBIFS is thus a simple read of
LEB 1 and 2 to get the current master node and from there get the location of
the most recent on-flash index.

The TNC is the in-memory representation of the on-flash index. It contains some
additional runtime attributes per node which are not persisted. One of these is
a dirty-flag which marks nodes that have to be persisted the next time the
index is written onto the flash. The TNC acts as a write-back cache and all
modifications of the on-flash index are done through the TNC. Like other caches,
the TNC does not have to mirror the full index into memory, but reads parts of
it from flash whenever needed. A *commit* is the UBIFS operation of updating the
on-flash filesystem structures like the index. On every commit, the TNC nodes
marked as dirty are written to the flash to update the persisted index.

Journal ring과 LPT

130-205

flash wear를 줄이기 위해 index는 `fsync(2)` 같은 조건에서만 commit한다. 그 사이 inode·data node 변경은 journal에 기록하고 mount 때 on-flash index로 필요에 따라 만든 TNC에 replay한다.

`mkfs.ubifs`가 크기를 정해 superblock에 저장한 log area는 reference node와 commit start node만 담는다. commit start는 index commit 때, reference는 journal update마다 기록된다. reference가 main area의 inode·data node 등 bud 위치를 가리키며 bud가 실제 변경과 data를 담는다.

log area는 ring이다. 거의 차면 commit과 commit start를 쓰고, mount는 최신 commit start 뒤의 reference만 replay한다. 그 앞 reference는 이미 index에 반영됐으므로 무시한다.

entry 기록 전 reference와 bud 공간을 확보한 뒤 reference를 먼저 쓰고 bud를 쓴다. replay는 reference와 대상 LEB를 검사한다. power cut으로 손상될 수 있는 마지막 referenced LEB만 재읽어 복구를 시도하며 실패하면 mount하지 않는다. 다른 LEB 오류는 즉시 mount 실패다.

UBIFS journal layout
LOG: commit start(CS)LOG: REF node 순서대로 기록각 REF가 MAIN AREA의 bud LEB를 가리킴bud에 DENT·INO·DATA 변경 저장mount 때 최신 CS 이후 REF만 replay

원문의 LOG AREA와 MAIN AREA 연결을 구조화했다.

LPT는 LEB별 type, free space, dirty 즉 obsolete space를 기록한다. UBIFS는 한 LEB에 index와 data node를 섞지 않으므로 type이 free-space 계산에도 중요하다. free는 erase 없이 아직 쓸 수 있는 영역이고 dirty는 이미 썼지만 obsolete라 전체 LEB erase 전에는 덮을 수 없는 영역이다.

LPT도 B+ tree지만 index보다 작아 commit마다 한 chunk로 기록한다. 따라서 LPT save는 atomic operation이다.

Journal
~~~~~~~

To avoid wearing out the flash, the index is only persisted (*committed*) when
certain conditions are met (eg. ``fsync(2)``). The journal is used to record
any changes (in form of inode nodes, data nodes etc.) between commits
of the index. During mount, the journal is read from the flash and replayed
onto the TNC (which will be created on-demand from the on-flash index).

UBIFS reserves a bunch of LEBs just for the journal called *log area*. The
amount of log area LEBs is configured on filesystem creation (using
``mkfs.ubifs``) and stored in the superblock node. The log area contains only
two types of nodes: *reference nodes* and *commit start nodes*. A commit start
node is written whenever an index commit is performed. Reference nodes are
written on every journal update. Each reference node points to the position of
other nodes (inode nodes, data nodes etc.) on the flash that are part of this
journal entry. These nodes are called *buds* and describe the actual filesystem
changes including their data.

The log area is maintained as a ring. Whenever the journal is almost full,
a commit is initiated. This also writes a commit start node so that during
mount, UBIFS will seek for the most recent commit start node and just replay
every reference node after that. Every reference node before the commit start
node will be ignored as they are already part of the on-flash index.

When writing a journal entry, UBIFS first ensures that enough space is
available to write the reference node and buds part of this entry. Then, the
reference node is written and afterwards the buds describing the file changes.
On replay, UBIFS will record every reference node and inspect the location of
the referenced LEBs to discover the buds. If these are corrupt or missing,
UBIFS will attempt to recover them by re-reading the LEB. This is however only
done for the last referenced LEB of the journal. Only this can become corrupt
because of a power cut. If the recovery fails, UBIFS will not mount. An error
for every other LEB will directly cause UBIFS to fail the mount operation.

::

       | ----    LOG AREA     ---- | ----------    MAIN AREA    ------------ |

        -----+------+-----+--------+----   ------+-----+-----+---------------
        \    |      |     |        |   /  /      |     |     |               \
        / CS |  REF | REF |        |   \  \ DENT | INO | INO |               /
        \    |      |     |        |   /  /      |     |     |               \
         ----+------+-----+--------+---   -------+-----+-----+----------------
                 |     |                  ^            ^
                 |     |                  |            |
                 +------------------------+            |
                       |                               |
                       +-------------------------------+


                Figure 2: UBIFS flash layout of log area with commit start nodes
                          (CS) and reference nodes (REF) pointing to main area
                          containing their buds


LEB Property Tree/Table
~~~~~~~~~~~~~~~~~~~~~~~

The LEB property tree is used to store per-LEB information. This includes the
LEB type and amount of free and *dirty* (old, obsolete content) space [1]_ on
the LEB. The type is important, because UBIFS never mixes index nodes with data
nodes on a single LEB and thus each LEB has a specific purpose. This again is
useful for free space calculations. See [UBIFS-WP] for more details.

The LEB property tree again is a B+ tree, but it is much smaller than the
index. Due to its smaller size it is always written as one chunk on every
commit. Thus, saving the LPT is an atomic operation.


.. [1] Since LEBs can only be appended and never overwritten, there is a
   difference between free space ie. the remaining space left on the LEB to be
   written to without erasing it and previously written content that is obsolete
   but can't be overwritten without erasing the full LEB.

인증 범위와 threat model

206-253

UBIFS authentication은 flash의 metadata와 file content authenticity·integrity를 확인해 offline modification과 file swapping을 탐지한다. 변조를 물리적으로 막지는 않지만 trusted code가 검증할 수 있게 한다.

전체 flash dump를 나중에 통째로 복원하는 rollback은 탐지하지 못한다. 개별 index commit의 partial rollback도 막지 못한다. wandering tree와 journal의 obsolete version이 garbage collection 전까지 남고, UBI wear leveling도 old PEB를 원자적으로 지우지 않기 때문에 공격자는 current tree 일부를 지우고 남아 있는 옛 version을 복원할 수 있다.

authentication key가 제공된 뒤 device에서 code를 실행할 수 있는 공격도 범위 밖이다. secure boot와 trusted boot로 trusted code만 실행되게 해야 한다.

완전한 flash data 신뢰를 위해 index, journal, LPT를 모두 인증한다. index에는 file content와 xattr·length 같은 metadata, journal에는 그 변경, LPT에는 UBIFS free-space 계산용 LEB metadata가 들어 있다.

UBIFS authentication 범위
구분항목결과
인증Indexfile content·metadata 변조 탐지
인증Journalcommit 사이 변경·순서 검증
인증LPTLEB metadata 무결성
비보호전체 flash rollback옛 image 복원 탐지 못함
비보호partial commit rollbackobsolete node 재사용 가능
비보호key 제공 뒤 code executionsecure/trusted boot 필요

보호되는 구조와 명시적 비보호 항목이다.

UBIFS Authentication
====================

This chapter introduces UBIFS authentication which enables UBIFS to verify
the authenticity and integrity of metadata and file contents stored on flash.


Threat Model
------------

UBIFS authentication enables detection of offline data modification. While it
does not prevent it, it enables (trusted) code to check the integrity and
authenticity of on-flash file contents and filesystem metadata. This covers
attacks where file contents are swapped.

UBIFS authentication will not protect against rollback of full flash contents.
Ie. an attacker can still dump the flash and restore it at a later time without
detection. It will also not protect against partial rollback of individual
index commits. That means that an attacker is able to partially undo changes.
This is possible because UBIFS does not immediately overwrites obsolete
versions of the index tree or the journal, but instead marks them as obsolete
and garbage collection erases them at a later time. An attacker can use this by
erasing parts of the current tree and restoring old versions that are still on
the flash and have not yet been erased. This is possible, because every commit
will always write a new version of the index root node and the master node
without overwriting the previous version. This is further helped by the
wear-leveling operations of UBI which copies contents from one physical
eraseblock to another and does not atomically erase the first eraseblock.

UBIFS authentication does not cover attacks where an attacker is able to
execute code on the device after the authentication key was provided.
Additional measures like secure boot and trusted boot have to be taken to
ensure that only trusted code is executed on a device.


Authentication
--------------

To be able to fully trust data read from flash, all UBIFS data structures
stored on flash are authenticated. That is:

- The index which includes file contents, file metadata like extended
  attributes, file length etc.
- The journal which also contains file contents and metadata by recording changes
  to the filesystem
- The LPT which stores UBI LEB metadata which UBIFS uses for free space accounting

Merkle index와 master HMAC

254-322

wandering tree는 변경 leaf에서 root까지 바뀐 부분만 persist한다. 각 index node에 child node hash를 추가하면 index가 Merkle tree가 된다. leaf가 실제 file data를 담으므로 parent hash가 모든 content와 metadata를 덮는다.

file 변경 때 leaf부터 root와 master까지 update되는 기존 경로에서 변경 node hash만 함께 다시 계산한다. read 때 leaf에서 root까지 hash를 검증해 node integrity를 확인한다.

전체 index authenticity는 master node가 자기 content와 index root hash에 대한 keyed hash(HMAC)를 저장해 보장한다. master는 index commit마다 항상 flash에 기록된다.

hash를 추가하는 형식 변경은 index node와 master node에만 필요하다. 다른 node type은 그대로여서 embedded device에서 중요한 storage overhead를 줄인다.

Merkle index 검증
Master node HMAC 검증master가 보관한 root hash 확인index branch별 child hash 검증leaf의 DATA·INO·DENT node 도달file content와 metadata integrity 확립

원문의 master·index·leaf coverage를 단계화했다.

Index authentication 변경 범위
Node추가 정보이유
Master node자기 content HMAC + root hashindex 전체 authenticity anchor
Index node각 child hashMerkle path 구성
DATA/INO/DENT 등 leaf형식 변경 없음parent hash가 content를 cover

hash가 추가되는 node와 그대로인 node다.

power-cut safety에는 hash와 file content를 원자적으로 persist하는 것이 가장 중요하다. 기존 UBIFS 변경 node 기록·recovery logic이 이를 위해 설계되어 있고, hash는 해당 index node와 함께 atomic하게 저장되므로 새 recovery model이 필요하지 않다.

Index Authentication
~~~~~~~~~~~~~~~~~~~~

Through UBIFS' concept of a wandering tree, it already takes care of only
updating and persisting changed parts from leaf node up to the root node
of the full B+ tree. This enables us to augment the index nodes of the tree
with a hash over each node's child nodes. As a result, the index basically also
a Merkle tree. Since the leaf nodes of the index contain the actual filesystem
data, the hashes of their parent index nodes thus cover all the file contents
and file metadata. When a file changes, the UBIFS index is updated accordingly
from the leaf nodes up to the root node including the master node. This process
can be hooked to recompute the hash only for each changed node at the same time.
Whenever a file is read, UBIFS can verify the hashes from each leaf node up to
the root node to ensure the node's integrity.

To ensure the authenticity of the whole index, the UBIFS master node stores a
keyed hash (HMAC) over its own contents and a hash of the root node of the index
tree. As mentioned above, the master node is always written to the flash whenever
the index is persisted (ie. on index commit).

Using this approach only UBIFS index nodes and the master node are changed to
include a hash. All other types of nodes will remain unchanged. This reduces
the storage overhead which is precious for users of UBIFS (ie. embedded
devices).

::

                             +---------------+
                             |  Master Node  |
                             |    (hash)     |
                             +---------------+
                                     |
                                     v
                            +-------------------+
                            |  Index Node #1    |
                            |                   |
                            | branch0   branchn |
                            | (hash)    (hash)  |
                            +-------------------+
                               |    ...   |  (fanout: 8)
                               |          |
                       +-------+          +------+
                       |                         |
                       v                         v
            +-------------------+       +-------------------+
            |  Index Node #2    |       |  Index Node #3    |
            |                   |       |                   |
            | branch0   branchn |       | branch0   branchn |
            | (hash)    (hash)  |       | (hash)    (hash)  |
            +-------------------+       +-------------------+
                 |   ...                     |   ...   |
                 v                           v         v
               +-----------+         +----------+  +-----------+
               | Data Node |         | INO Node |  | DENT Node |
               +-----------+         +----------+  +-----------+


           Figure 3: Coverage areas of index node hash and master node HMAC



The most important part for robustness and power-cut safety is to atomically
persist the hash and file contents. Here the existing UBIFS logic for how
changed nodes are persisted is already designed for this purpose such that
UBIFS can safely recover if a power-cut occurs while persisting. Adding
hashes to index nodes does not change this since each hash will be persisted
atomically together with its respective node.

Journal hash chain과 auth node

323-372

journal은 계속 기록되므로 power cut 뒤 인증 불가능한 tail을 작게 유지하려면 authentication 정보도 자주 넣어야 한다. commit start에서 시작해 이전 reference, 현재 reference, bud node를 포함하는 continuous hash를 만든다.

적절한 시점마다 bud 사이에 auth node를 넣고 현재 hash chain 상태의 HMAC을 저장한다. journal은 마지막 auth node까지 인증할 수 있으며 auth node가 없는 tail은 replay에서 건너뛴다.

hash가 reference node도 포함하므로 공격자는 replay할 journal head를 재정렬하거나 건너뛸 수 없다. journal 끝의 bud·reference만 제거해 최대 마지막 commit까지 filesystem을 되감을 수 있다.

Journal authentication chain
Commit start에서 hash chain 시작REF#0와 그 bud들을 순서대로 hashauth node가 현재 chain HMAC 저장다음 bud·REF head로 chain 연장마지막 auth node 뒤의 미인증 tail은 replay하지 않음

여러 head의 REF·bud·auth 연결을 단순화했다.

log area 위치는 HMAC으로 인증된 master에 있다. log 크기는 `mkfs.ubifs`가 정해 superblock에 두므로 superblock에도 HMAC을 추가해 조작을 막는다. superblock은 LEB 0에 있고 feature flag 같은 변경 때만 수정되며 file 변경 때는 수정되지 않는다.

Journal anchor 보호
정보저장 위치보호
log area 위치master nodemaster HMAC
log area 크기LEB 0 superblocksuperblock HMAC
journal 순서·내용REF·bud chain주기적 auth node HMAC

journal 위치·크기를 보호하는 상위 node다.

Journal Authentication
~~~~~~~~~~~~~~~~~~~~~~

The journal is authenticated too. Since the journal is continuously written
it is necessary to also add authentication information frequently to the
journal so that in case of a powercut not too much data can't be authenticated.
This is done by creating a continuous hash beginning from the commit start node
over the previous reference nodes, the current reference node, and the bud
nodes. From time to time whenever it is suitable authentication nodes are added
between the bud nodes. This new node type contains a HMAC over the current state
of the hash chain. That way a journal can be authenticated up to the last
authentication node. The tail of the journal which may not have a authentication
node cannot be authenticated and is skipped during journal replay.

We get this picture for journal authentication::

    ,,,,,,,,
    ,......,...........................................
    ,. CS  ,               hash1.----.           hash2.----.
    ,.  |  ,                    .    |hmac            .    |hmac
    ,.  v  ,                    .    v                .    v
    ,.REF#0,-> bud -> bud -> bud.-> auth -> bud -> bud.-> auth ...
    ,..|...,...........................................
    ,  |   ,
    ,  |   ,,,,,,,,,,,,,,,
    .  |            hash3,----.
    ,  |                 ,    |hmac
    ,  v                 ,    v
    , REF#1 -> bud -> bud,-> auth ...
    ,,,|,,,,,,,,,,,,,,,,,,
       v
      REF#2 -> ...
       |
       V
      ...

Since the hash also includes the reference nodes an attacker cannot reorder or
skip any journal heads for replay. An attacker can only remove bud nodes or
reference nodes from the end of the journal, effectively rewinding the
filesystem at maximum back to the last commit.

The location of the log area is stored in the master node. Since the master
node is authenticated with a HMAC as described above, it is not possible to
tamper with that without detection. The size of the log area is specified when
the filesystem is created using `mkfs.ubifs` and stored in the superblock node.
To avoid tampering with this and other values stored there, a HMAC is added to
the superblock struct. The superblock node is stored in LEB 0 and is only
modified on feature flag or similar changes, but never on file changes.

LPT의 commit 단위 검증

373-384

LPT root의 flash 위치는 master node에 저장된다. LPT는 commit마다 전체를 원자적으로 쓰고 읽으므로 각 tree node를 따로 인증할 필요가 없다.

전체 LPT의 단순 hash를 master에 저장한다. master HMAC을 검증한 뒤 on-flash LPT를 읽어 계산한 hash와 master의 값을 비교하면 LPT authenticity를 확인할 수 있다.

LPT 인증
master node HMAC 검증master에서 LPT root 위치·hash 획득on-flash LPT 전체 atomic readLPT hash 계산저장 hash와 비교

atomic LPT 전체에 hash 하나를 사용한다.

LPT Authentication
~~~~~~~~~~~~~~~~~~

The location of the LPT root node on the flash is stored in the UBIFS master
node. Since the LPT is written and read atomically on every commit, there is
no need to authenticate individual nodes of the tree. It suffices to
protect the integrity of the full LPT by a simple hash stored in the master
node. Since the master node itself is authenticated, the LPTs authenticity can
be verified by verifying the authenticity of the master node and comparing the
LTP hash stored there with the hash computed from the read on-flash LPT.

전용 authentication key 관리

385-421

UBIFS authentication은 superblock, master, commit start, reference node의 HMAC에 단일 key를 사용한다. filesystem 생성 시 `mkfs.ubifs`가 superblock을 인증하려면 key가 필요하고, mount 때 authenticated node 검증과 변경 HMAC 생성에도 필요하다.

fscrypt encryption과 나란히 사용해 confidentiality와 authenticity를 제공하지만 key model은 다르다. fscrypt는 directory별 policy라 여러 master key와 unencrypted directory가 가능하다. UBIFS authentication은 파일 시스템 전체를 모두 인증하거나 전혀 하지 않는 all-or-nothing 방식이다.

encryption 없이도 쓸 수 있어 fscrypt master key를 공유하지 않고 전용 authentication key를 관리한다. 제공 API는 아직 정의되지 않았지만 fscrypt처럼 userspace keyring을 사용할 수 있다. 기존 fscrypt API의 문제로 policy v2 방향도 고려해야 한다.

user가 passphrase 하나만 제공해도 userspace tool이 encryption용 fscrypt master key와 별도의 authentication key를 각각 derive할 수 있다. mount 때 올바른 key인지 확인하도록 superblock에 authentication key hash도 저장하며 fscrypt policy v2 제안과 비슷하다.

UBIFS key 사용 시점
시점필요 작업
`mkfs.ubifs`superblock HMAC 생성
mountsuperblock·master·journal node HMAC 검증
filesystem 변경새 master·CS·REF HMAC 생성
key 확인superblock의 authentication key hash 비교
userspacepassphrase에서 encryption·authentication key 별도 derive

전용 key가 생성·mount·update에서 하는 일이다.

Key Management
--------------

For simplicity, UBIFS authentication uses a single key to compute the HMACs
of superblock, master, commit start and reference nodes. This key has to be
available on creation of the filesystem (`mkfs.ubifs`) to authenticate the
superblock node. Further, it has to be available on mount of the filesystem
to verify authenticated nodes and generate new HMACs for changes.

UBIFS authentication is intended to operate side-by-side with UBIFS encryption
(fscrypt) to provide confidentiality and authenticity. Since UBIFS encryption
has a different approach of encryption policies per directory, there can be
multiple fscrypt master keys and there might be folders without encryption.
UBIFS authentication on the other hand has an all-or-nothing approach in the
sense that it either authenticates everything of the filesystem or nothing.
Because of this and because UBIFS authentication should also be usable without
encryption, it does not share the same master key with fscrypt, but manages
a dedicated authentication key.

The API for providing the authentication key has yet to be defined, but the
key can eg. be provided by userspace through a keyring similar to the way it
is currently done in fscrypt. It should however be noted that the current
fscrypt approach has shown its flaws and the userspace API will eventually
change [FSCRYPT-POLICY2].

Nevertheless, it will be possible for a user to provide a single passphrase
or key in userspace that covers UBIFS authentication and encryption. This can
be solved by the corresponding userspace tools which derive a second key for
authentication in addition to the derived fscrypt master key used for
encryption.

To be able to check if the proper key is available on mount, the UBIFS
superblock node will additionally store a hash of the authentication key. This
approach is similar to the approach proposed for fscrypt encryption policy v2
[FSCRYPT-POLICY2].

Digital signature 확장과 참고 자료

422-448

vendor가 secret authentication key를 고객과 공유하지 않고 인증된 filesystem image를 제공하려면 각 HMAC 옆에 digital signature를 저장하고 public key만 배포하는 확장을 고려할 수 있다.

image를 이후 수정해야 하면 첫 mount에서 IMA/EVM과 비슷하게 digital signature를 HMAC으로 교환할 수 있다. 이때 일반 방식대로 HMAC key를 미리 제공해야 한다.

참고 자료는 dm-crypt 결합, CBC malleability 공격, dm-integrity, dm-verity, fscrypt policy v2, UBIFS whitepaper를 연결한다.

Vendor image의 첫 writable mount
vendor가 node signature와 public key 배포첫 mount에서 digital signature 검증device에 authentication HMAC key 제공signature를 HMAC으로 교환이후 일반 UBIFS authenticated update 수행

공개키 검증 image를 device별 HMAC 상태로 전환한다.

Future Extensions
=================

In certain cases where a vendor wants to provide an authenticated filesystem
image to customers, it should be possible to do so without sharing the secret
UBIFS authentication key. Instead, in addition the each HMAC a digital
signature could be stored where the vendor shares the public key alongside the
filesystem image. In case this filesystem has to be modified afterwards,
UBIFS can exchange all digital signatures with HMACs on first mount similar
to the way the IMA/EVM subsystem deals with such situations. The HMAC key
will then have to be provided beforehand in the normal way.


References
==========

[CRYPTSETUP2]        https://www.saout.de/pipermail/dm-crypt/2017-November/005745.html

[DMC-CBC-ATTACK]     https://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/

[DM-INTEGRITY]       https://www.kernel.org/doc/Documentation/device-mapper/dm-integrity.rst

[DM-VERITY]          https://www.kernel.org/doc/Documentation/device-mapper/verity.rst

[FSCRYPT-POLICY2]    https://lore.kernel.org/r/20171023214058.128121-1-ebiggers3@gmail.com/

[UBIFS-WP]           http://www.linux-mtd.infradead.org/doc/ubifs_whitepaper.pdf