← Documents Documentation/security/keys/trusted-encrypted.rst GitHub 원문 ↗

Linux 6.18.37 · Security

신뢰 키와 암호화 키

Trusted Key와 Encrypted Key의 신뢰 루트, 난수원, TPM·TEE·CAAM·DCP 사용법, PCR reseal, EVM 예제와 TPM 2.0 ASN.1 blob 형식을 설명합니다.

Source pathDocumentation/security/keys/trusted-encrypted.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

trusted-encrypted.rst:1-481

이 문서는 평문 키를 사용자 공간에 노출하지 않는 두 커널 keyring 유형을 다룹니다. Trusted Key는 하드웨어 또는 격리된 trust source에 뿌리를 두며 PCR 같은 플랫폼 무결성 상태에 결합할 수 있고, Encrypted Key는 trusted/user master key로 AES 보호해 더 넓은 시스템에서 사용할 수 있습니다.

실무에서는 trust source의 실제 위협 모델, 난수원, persistent TPM handle과 정책 옵션을 함께 검토해야 합니다. 저장 blob의 형식은 TPM과 각 TEE·CAAM·DCP 구현마다 다르며, EVM·eCryptfs·nvdimm 같은 소비자는 목적에 맞는 `default`, `ecryptfs`, `enc32` format을 선택합니다.

보호 계층
trust source 또는 master key커널 내부 키 생성sealed/encrypted blob 저장keyring에 안전하게 재적재EVM·eCryptfs·nvdimm 소비

키 재료가 생성되어 소비자에게 전달되기까지 평문은 커널과 trust boundary 안에 머문다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ==========================
2 Trusted and Encrypted Keys
3 ==========================
4
5 Trusted and Encrypted Keys are two new key types added to the existing kernel
6 key ring service. Both of these new types are variable length symmetric keys,
7 and in both cases all keys are created in the kernel, and user space sees,
8 stores, and loads only encrypted blobs. Trusted Keys require the availability
9 of a Trust Source for greater security, while Encrypted Keys can be used on any
10 system. All user level blobs, are displayed and loaded in hex ASCII for
11 convenience, and are integrity verified.
12
13
14 Trust Source
15 ============
16
17 A trust source provides the source of security for Trusted Keys. This
18 section lists currently supported trust sources, along with their security
19 considerations. Whether or not a trust source is sufficiently safe depends
20 on the strength and correctness of its implementation, as well as the threat
21 environment for a specific use case. Since the kernel doesn't know what the
22 environment is, and there is no metric of trust, it is dependent on the
23 consumer of the Trusted Keys to determine if the trust source is sufficiently
24 safe.
25
26 * Root of trust for storage
27
28 (1) TPM (Trusted Platform Module: hardware device)
29
30 Rooted to Storage Root Key (SRK) which never leaves the TPM that
31 provides crypto operation to establish root of trust for storage.
32
33 (2) TEE (Trusted Execution Environment: OP-TEE based on Arm TrustZone)
34
35 Rooted to Hardware Unique Key (HUK) which is generally burnt in on-chip
36 fuses and is accessible to TEE only.
37
38 (3) CAAM (Cryptographic Acceleration and Assurance Module: IP on NXP SoCs)
39
40 When High Assurance Boot (HAB) is enabled and the CAAM is in secure
41 mode, trust is rooted to the OTPMK, a never-disclosed 256-bit key
42 randomly generated and fused into each SoC at manufacturing time.
43 Otherwise, a common fixed test key is used instead.
44
45 (4) DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
46
47 Rooted to a one-time programmable key (OTP) that is generally burnt
48 in the on-chip fuses and is accessible to the DCP encryption engine only.
49 DCP provides two keys that can be used as root of trust: the OTP key
50 and the UNIQUE key. Default is to use the UNIQUE key, but selecting
51 the OTP key can be done via a module parameter (dcp_use_otp_key).
52
53 * Execution isolation
54
55 (1) TPM
56
57 Fixed set of operations running in isolated execution environment.
58
59 (2) TEE
60
61 Customizable set of operations running in isolated execution
62 environment verified via Secure/Trusted boot process.
63
64 (3) CAAM
65
66 Fixed set of operations running in isolated execution environment.
67
68 (4) DCP
69
70 Fixed set of cryptographic operations running in isolated execution
71 environment. Only basic blob key encryption is executed there.
72 The actual key sealing/unsealing is done on main processor/kernel space.
73
74 * Optional binding to platform integrity state
75
76 (1) TPM
77
78 Keys can be optionally sealed to specified PCR (integrity measurement)
79 values, and only unsealed by the TPM, if PCRs and blob integrity
80 verifications match. A loaded Trusted Key can be updated with new
81 (future) PCR values, so keys are easily migrated to new PCR values,
82 such as when the kernel and initramfs are updated. The same key can
83 have many saved blobs under different PCR values, so multiple boots are
84 easily supported.
85
86 (2) TEE
87
88 Relies on Secure/Trusted boot process for platform integrity. It can
89 be extended with TEE based measured boot process.
90
91 (3) CAAM
92
93 Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs
94 for platform integrity.
95
96 (4) DCP
97
98 Relies on Secure/Trusted boot process (called HAB by vendor) for
99 platform integrity.
100
101 * Interfaces and APIs
102
103 (1) TPM
104
105 TPMs have well-documented, standardized interfaces and APIs.
106
107 (2) TEE
108
109 TEEs have well-documented, standardized client interface and APIs. For
110 more details refer to ``Documentation/driver-api/tee.rst``.
111
112 (3) CAAM
113
114 Interface is specific to silicon vendor.
115
116 (4) DCP
117
118 Vendor-specific API that is implemented as part of the DCP crypto driver in
119 ``drivers/crypto/mxs-dcp.c``.
120
121 * Threat model
122
123 The strength and appropriateness of a particular trust source for a given
124 purpose must be assessed when using them to protect security-relevant data.
125
126
127 Key Generation
128 ==============
129
130 Trusted Keys
131 ------------
132
133 New keys are created from random numbers. They are encrypted/decrypted using
134 a child key in the storage key hierarchy. Encryption and decryption of the
135 child key must be protected by a strong access control policy within the
136 trust source. The random number generator in use differs according to the
137 selected trust source:
138
139 * TPM: hardware device based RNG
140
141 Keys are generated within the TPM. Strength of random numbers may vary
142 from one device manufacturer to another.
143
144 * TEE: OP-TEE based on Arm TrustZone based RNG
145
146 RNG is customizable as per platform needs. It can either be direct output
147 from platform specific hardware RNG or a software based Fortuna CSPRNG
148 which can be seeded via multiple entropy sources.
149
150 * CAAM: Kernel RNG
151
152 The normal kernel random number generator is used. To seed it from the
153 CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device
154 is probed.
155
156 * DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
157
158 The DCP hardware device itself does not provide a dedicated RNG interface,
159 so the kernel default RNG is used. SoCs with DCP like the i.MX6ULL do have
160 a dedicated hardware RNG that is independent from DCP which can be enabled
161 to back the kernel RNG.
162
163 Users may override this by specifying ``trusted.rng=kernel`` on the kernel
164 command-line to override the used RNG with the kernel's random number pool.
165
166 Encrypted Keys
167 --------------
168
169 Encrypted keys do not depend on a trust source, and are faster, as they use AES
170 for encryption/decryption. New keys are created either from kernel-generated
171 random numbers or user-provided decrypted data, and are encrypted/decrypted
172 using a specified ‘master’ key. The ‘master’ key can either be a trusted-key or
173 user-key type. The main disadvantage of encrypted keys is that if they are not
174 rooted in a trusted key, they are only as secure as the user key encrypting
175 them. The master user key should therefore be loaded in as secure a way as
176 possible, preferably early in boot.
177
178
179 Usage
180 =====
181
182 Trusted Keys usage: TPM
183 -----------------------
184
185 TPM 1.2: By default, trusted keys are sealed under the SRK, which has the
186 default authorization value (20 bytes of 0s). This can be set at takeownership
187 time with the TrouSerS utility: "tpm_takeownership -u -z".
188
189 TPM 2.0: The user must first create a storage key and make it persistent, so the
190 key is available after reboot. This can be done using the following commands.
191
192 With the IBM TSS 2 stack::
193
194 #> tsscreateprimary -hi o -st
195 Handle 80000000
196 #> tssevictcontrol -hi o -ho 80000000 -hp 81000001
197
198 Or with the Intel TSS 2 stack::
199
200 #> tpm2_createprimary --hierarchy o -G rsa2048 -c key.ctxt
201 [...]
202 #> tpm2_evictcontrol -c key.ctxt 0x81000001
203 persistentHandle: 0x81000001
204
205 Usage::
206
207 keyctl add trusted name "new keylen [options]" ring
208 keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
209 keyctl update key "update [options]"
210 keyctl print keyid
211
212 options:
213 keyhandle= ascii hex value of sealing key
214 TPM 1.2: default 0x40000000 (SRK)
215 TPM 2.0: no default; must be passed every time
216 keyauth= ascii hex auth for sealing key default 0x00...i
217 (40 ascii zeros)
218 blobauth= ascii hex auth for sealed data default 0x00...
219 (40 ascii zeros)
220 pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
221 pcrlock= pcr number to be extended to "lock" blob
222 migratable= 0|1 indicating permission to reseal to new PCR values,
223 default 1 (resealing allowed)
224 hash= hash algorithm name as a string. For TPM 1.x the only
225 allowed value is sha1. For TPM 2.x the allowed values
226 are sha1, sha256, sha384, sha512 and sm3-256.
227 policydigest= digest for the authorization policy. must be calculated
228 with the same hash algorithm as specified by the 'hash='
229 option.
230 policyhandle= handle to an authorization policy session that defines the
231 same policy and with the same hash algorithm as was used to
232 seal the key.
233
234 "keyctl print" returns an ascii hex copy of the sealed key, which is in standard
235 TPM_STORED_DATA format. The key length for new keys are always in bytes.
236 Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit
237 within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding.
238
239 Trusted Keys usage: TEE
240 -----------------------
241
242 Usage::
243
244 keyctl add trusted name "new keylen" ring
245 keyctl add trusted name "load hex_blob" ring
246 keyctl print keyid
247
248 "keyctl print" returns an ASCII hex copy of the sealed key, which is in format
249 specific to TEE device implementation. The key length for new keys is always
250 in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
251
252 Trusted Keys usage: CAAM
253 ------------------------
254
255 Usage::
256
257 keyctl add trusted name "new keylen" ring
258 keyctl add trusted name "load hex_blob" ring
259 keyctl print keyid
260
261 "keyctl print" returns an ASCII hex copy of the sealed key, which is in a
262 CAAM-specific format. The key length for new keys is always in bytes.
263 Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
264
265 Trusted Keys usage: DCP
266 -----------------------
267
268 Usage::
269
270 keyctl add trusted name "new keylen" ring
271 keyctl add trusted name "load hex_blob" ring
272 keyctl print keyid
273
274 "keyctl print" returns an ASCII hex copy of the sealed key, which is in format
275 specific to this DCP key-blob implementation. The key length for new keys is
276 always in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
277
278 Encrypted Keys usage
279 --------------------
280
281 The decrypted portion of encrypted keys can contain either a simple symmetric
282 key or a more complex structure. The format of the more complex structure is
283 application specific, which is identified by 'format'.
284
285 Usage::
286
287 keyctl add encrypted name "new [format] key-type:master-key-name keylen"
288 ring
289 keyctl add encrypted name "new [format] key-type:master-key-name keylen
290 decrypted-data" ring
291 keyctl add encrypted name "load hex_blob" ring
292 keyctl update keyid "update key-type:master-key-name"
293
294 Where::
295
296 format:= 'default | ecryptfs | enc32'
297 key-type:= 'trusted' | 'user'
298
299 Examples of trusted and encrypted key usage
300 -------------------------------------------
301
302 Create and save a trusted key named "kmk" of length 32 bytes.
303
304 Note: When using a TPM 2.0 with a persistent key with handle 0x81000001,
305 append 'keyhandle=0x81000001' to statements between quotes, such as
306 "new 32 keyhandle=0x81000001".
307
308 ::
309
310 $ keyctl add trusted kmk "new 32" @u
311 440502848
312
313 $ keyctl show
314 Session Keyring
315 -3 --alswrv 500 500 keyring: _ses
316 97833714 --alswrv 500 -1 \_ keyring: _uid.500
317 440502848 --alswrv 500 500 \_ trusted: kmk
318
319 $ keyctl print 440502848
320 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
321 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
322 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
323 a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
324 d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
325 dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
326 f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
327 e4a8aea2b607ec96931e6f4d4fe563ba
328
329 $ keyctl pipe 440502848 > kmk.blob
330
331 Load a trusted key from the saved blob::
332
333 $ keyctl add trusted kmk "load `cat kmk.blob`" @u
334 268728824
335
336 $ keyctl print 268728824
337 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
338 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
339 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
340 a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
341 d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
342 dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
343 f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
344 e4a8aea2b607ec96931e6f4d4fe563ba
345
346 Reseal (TPM specific) a trusted key under new PCR values::
347
348 $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
349 $ keyctl print 268728824
350 010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
351 77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
352 d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
353 df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
354 9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
355 e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
356 94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
357 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
358 df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8
359
360
361 The initial consumer of trusted keys is EVM, which at boot time needs a high
362 quality symmetric key for HMAC protection of file metadata. The use of a
363 trusted key provides strong guarantees that the EVM key has not been
364 compromised by a user level problem, and when sealed to a platform integrity
365 state, protects against boot and offline attacks. Create and save an
366 encrypted key "evm" using the above trusted key "kmk":
367
368 option 1: omitting 'format'::
369
370 $ keyctl add encrypted evm "new trusted:kmk 32" @u
371 159771175
372
373 option 2: explicitly defining 'format' as 'default'::
374
375 $ keyctl add encrypted evm "new default trusted:kmk 32" @u
376 159771175
377
378 $ keyctl print 159771175
379 default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
380 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
381 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
382
383 $ keyctl pipe 159771175 > evm.blob
384
385 Load an encrypted key "evm" from saved blob::
386
387 $ keyctl add encrypted evm "load `cat evm.blob`" @u
388 831684262
389
390 $ keyctl print 831684262
391 default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
392 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
393 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
394
395 Instantiate an encrypted key "evm" using user-provided decrypted data::
396
397 $ evmkey=$(dd if=/dev/urandom bs=1 count=32 | xxd -c32 -p)
398 $ keyctl add encrypted evm "new default user:kmk 32 $evmkey" @u
399 794890253
400
401 $ keyctl print 794890253
402 default user:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382d
403 bbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0247
404 17c64 5972dcb82ab2dde83376d82b2e3c09ffc
405
406 Other uses for trusted and encrypted keys, such as for disk and file encryption
407 are anticipated. In particular the new format 'ecryptfs' has been defined
408 in order to use encrypted keys to mount an eCryptfs filesystem. More details
409 about the usage can be found in the file
410 ``Documentation/security/keys/ecryptfs.rst``.
411
412 Another new format 'enc32' has been defined in order to support encrypted keys
413 with payload size of 32 bytes. This will initially be used for nvdimm security
414 but may expand to other usages that require 32 bytes payload.
415
416
417 TPM 2.0 ASN.1 Key Format
418 ------------------------
419
420 The TPM 2.0 ASN.1 key format is designed to be easily recognisable,
421 even in binary form (fixing a problem we had with the TPM 1.2 ASN.1
422 format) and to be extensible for additions like importable keys and
423 policy::
424
425 TPMKey ::= SEQUENCE {
426 type OBJECT IDENTIFIER
427 emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL
428 parent INTEGER
429 pubkey OCTET STRING
430 privkey OCTET STRING
431 }
432
433 type is what distinguishes the key even in binary form since the OID
434 is provided by the TCG to be unique and thus forms a recognizable
435 binary pattern at offset 3 in the key. The OIDs currently made
436 available are::
437
438 2.23.133.10.1.3 TPM Loadable key. This is an asymmetric key (Usually
439 RSA2048 or Elliptic Curve) which can be imported by a
440 TPM2_Load() operation.
441
442 2.23.133.10.1.4 TPM Importable Key. This is an asymmetric key (Usually
443 RSA2048 or Elliptic Curve) which can be imported by a
444 TPM2_Import() operation.
445
446 2.23.133.10.1.5 TPM Sealed Data. This is a set of data (up to 128
447 bytes) which is sealed by the TPM. It usually
448 represents a symmetric key and must be unsealed before
449 use.
450
451 The trusted key code only uses the TPM Sealed Data OID.
452
453 emptyAuth is true if the key has well known authorization "". If it
454 is false or not present, the key requires an explicit authorization
455 phrase. This is used by most user space consumers to decide whether
456 to prompt for a password.
457
458 parent represents the parent key handle, either in the 0x81 MSO space,
459 like 0x81000001 for the RSA primary storage key. Userspace programmes
460 also support specifying the primary handle in the 0x40 MSO space. If
461 this happens the Elliptic Curve variant of the primary key using the
462 TCG defined template will be generated on the fly into a volatile
463 object and used as the parent. The current kernel code only supports
464 the 0x81 MSO form.
465
466 pubkey is the binary representation of TPM2B_PRIVATE excluding the
467 initial TPM2B header, which can be reconstructed from the ASN.1 octet
468 string length.
469
470 privkey is the binary representation of TPM2B_PUBLIC excluding the
471 initial TPM2B header which can be reconstructed from the ASN.1 octed
472 string length.
473
474 DCP Blob Format
475 ---------------
476
477 .. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
478 :doc: dcp blob format
479
480 .. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
481 :identifiers: struct dcp_blob_fmt
482

3. 한국어 전문 번역

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

두 키 유형의 공통점과 차이

1-13

Trusted Key와 Encrypted Key는 기존 커널 keyring 서비스에 추가된 가변 길이 대칭 키 유형이다. 두 유형 모두 실제 키를 커널 안에서 생성하며, 사용자 공간에는 암호화된 blob만 보여 주고 저장하거나 다시 불러오게 한다. 따라서 평문 키가 일반적인 사용자 공간 인터페이스를 통과하지 않는다.

Trusted Key는 더 강한 보호를 위해 TPM, TEE, CAAM, DCP 같은 trust source가 필요하지만, Encrypted Key는 그런 하드웨어나 격리 환경이 없는 시스템에서도 사용할 수 있다. 사용자 수준 blob은 편의를 위해 모두 16진 ASCII로 표시하고 입력하며, 불러올 때 무결성을 검증한다.

두 키 유형 비교
항목Trusted KeyEncrypted Key
신뢰 기반TPM, TEE, CAAM, DCP지정한 trusted/user master key
평문 키 생성커널 및 trust source커널 난수 또는 사용자 제공 데이터
사용자 공간암호화된 blob만 취급암호화된 blob만 취급

생성 위치와 사용자 공간 노출 방식은 같지만 신뢰 기반이 다르다.

==========================
Trusted and Encrypted Keys
==========================

Trusted and Encrypted Keys are two new key types added to the existing kernel
key ring service.  Both of these new types are variable length symmetric keys,
and in both cases all keys are created in the kernel, and user space sees,
stores, and loads only encrypted blobs.  Trusted Keys require the availability
of a Trust Source for greater security, while Encrypted Keys can be used on any
system. All user level blobs, are displayed and loaded in hex ASCII for
convenience, and are integrity verified.

저장 신뢰 루트와 실행 격리

14-73

trust source는 Trusted Key의 보안 근거를 제공한다. 충분히 안전한지는 구현의 강도와 정확성, 그리고 실제 위협 환경에 달려 있다. 커널은 사용 환경이나 신뢰도를 수치로 알 수 없으므로, Trusted Key 소비자가 선택한 trust source가 용도에 맞게 안전한지 판단해야 한다.

TPM은 장치 밖으로 나오지 않는 Storage Root Key(SRK)에 저장 신뢰 루트를 두고 암호 연산을 수행한다. OP-TEE 기반 TEE는 보통 온칩 퓨즈에 기록되어 TEE만 접근할 수 있는 Hardware Unique Key(HUK)를 사용한다. CAAM은 High Assurance Boot(HAB)가 켜지고 secure mode일 때 제조 과정에서 SoC마다 무작위로 생성해 퓨징한 비공개 256비트 OTPMK에 뿌리를 둔다. 이 조건이 아니면 공통 고정 시험 키를 사용하므로 보안 속성이 크게 달라진다.

DCP는 온칩 퓨즈의 one-time programmable key를 DCP 암호화 엔진만 접근하게 한다. 신뢰 루트로 OTP key와 UNIQUE key를 제공하며 기본값은 UNIQUE key다. 모듈 매개변수 `dcp_use_otp_key`로 OTP key를 선택할 수 있다.

TPM, CAAM, DCP는 격리된 실행 환경에서 고정된 연산 집합을 수행하고, TEE는 Secure/Trusted boot로 검증된 격리 환경에서 사용자 정의 연산 집합을 수행할 수 있다. DCP 내부에서는 기본 blob key 암호화만 실행하며, 실제 key sealing과 unsealing은 주 프로세서의 커널 공간에서 수행한다.

저장 신뢰 루트
소스루트 키격리 특성
TPMStorage Root Key (SRK)TPM 내부 고정 연산
TEEHardware Unique Key (HUK)Secure/Trusted boot로 검증된 OP-TEE
CAAMsecure mode의 OTPMKSoC 내부 고정 연산
DCPUNIQUE 또는 OTP keyDCP 내부 blob 암호화

각 구현이 비밀을 고정하는 하드웨어 또는 격리 경계를 비교한다.

Trust Source
============

A trust source provides the source of security for Trusted Keys.  This
section lists currently supported trust sources, along with their security
considerations.  Whether or not a trust source is sufficiently safe depends
on the strength and correctness of its implementation, as well as the threat
environment for a specific use case.  Since the kernel doesn't know what the
environment is, and there is no metric of trust, it is dependent on the
consumer of the Trusted Keys to determine if the trust source is sufficiently
safe.

  *  Root of trust for storage

     (1) TPM (Trusted Platform Module: hardware device)

         Rooted to Storage Root Key (SRK) which never leaves the TPM that
         provides crypto operation to establish root of trust for storage.

     (2) TEE (Trusted Execution Environment: OP-TEE based on Arm TrustZone)

         Rooted to Hardware Unique Key (HUK) which is generally burnt in on-chip
         fuses and is accessible to TEE only.

     (3) CAAM (Cryptographic Acceleration and Assurance Module: IP on NXP SoCs)

         When High Assurance Boot (HAB) is enabled and the CAAM is in secure
         mode, trust is rooted to the OTPMK, a never-disclosed 256-bit key
         randomly generated and fused into each SoC at manufacturing time.
         Otherwise, a common fixed test key is used instead.

     (4) DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)

         Rooted to a one-time programmable key (OTP) that is generally burnt
         in the on-chip fuses and is accessible to the DCP encryption engine only.
         DCP provides two keys that can be used as root of trust: the OTP key
         and the UNIQUE key. Default is to use the UNIQUE key, but selecting
         the OTP key can be done via a module parameter (dcp_use_otp_key).

  *  Execution isolation

     (1) TPM

         Fixed set of operations running in isolated execution environment.

     (2) TEE

         Customizable set of operations running in isolated execution
         environment verified via Secure/Trusted boot process.

     (3) CAAM

         Fixed set of operations running in isolated execution environment.

     (4) DCP

         Fixed set of cryptographic operations running in isolated execution
         environment. Only basic blob key encryption is executed there.
         The actual key sealing/unsealing is done on main processor/kernel space.

플랫폼 무결성 결합과 인터페이스

74-126

TPM 키는 지정한 PCR(integrity measurement) 값에 선택적으로 seal할 수 있다. 이후 PCR 값과 blob 무결성 검사가 모두 일치해야 TPM이 unseal한다. 이미 적재된 Trusted Key는 커널이나 initramfs 갱신 뒤 사용할 미래 PCR 값으로 업데이트할 수 있고, 같은 키를 여러 PCR 값에 대응하는 여러 blob으로 저장해 복수 부팅 구성을 지원할 수 있다.

TEE는 Secure/Trusted boot에 플랫폼 무결성을 의존하며 TEE 기반 measured boot로 확장할 수 있다. CAAM은 NXP SoC의 HAB, DCP는 공급자가 HAB라고 부르는 Secure/Trusted boot 과정에 의존한다.

TPM은 표준화되고 문서화된 인터페이스와 API를 제공한다. TEE도 표준 client interface와 API를 제공하며 자세한 내용은 `Documentation/driver-api/tee.rst`에 있다. 반면 CAAM 인터페이스는 실리콘 공급자 전용이고, DCP API는 `drivers/crypto/mxs-dcp.c`의 암호 드라이버 일부로 구현된 공급자 전용 인터페이스다. 보안 관련 데이터를 보호할 때는 이러한 차이와 위협 모델을 용도별로 평가해야 한다.

PCR 결합 키 갱신
현재 PCR 값에 키 seal암호화 blob 저장커널 또는 initramfs 업데이트적재된 키를 미래 PCR 값으로 update새 PCR용 blob 저장

플랫폼 업데이트 전후에 같은 키를 새로운 측정 상태로 안전하게 옮긴다.

  * Optional binding to platform integrity state

     (1) TPM

         Keys can be optionally sealed to specified PCR (integrity measurement)
         values, and only unsealed by the TPM, if PCRs and blob integrity
         verifications match. A loaded Trusted Key can be updated with new
         (future) PCR values, so keys are easily migrated to new PCR values,
         such as when the kernel and initramfs are updated. The same key can
         have many saved blobs under different PCR values, so multiple boots are
         easily supported.

     (2) TEE

         Relies on Secure/Trusted boot process for platform integrity. It can
         be extended with TEE based measured boot process.

     (3) CAAM

         Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs
         for platform integrity.

     (4) DCP

         Relies on Secure/Trusted boot process (called HAB by vendor) for
         platform integrity.

  *  Interfaces and APIs

     (1) TPM

         TPMs have well-documented, standardized interfaces and APIs.

     (2) TEE

         TEEs have well-documented, standardized client interface and APIs. For
         more details refer to ``Documentation/driver-api/tee.rst``.

     (3) CAAM

         Interface is specific to silicon vendor.

     (4) DCP

         Vendor-specific API that is implemented as part of the DCP crypto driver in
         ``drivers/crypto/mxs-dcp.c``.

  *  Threat model

     The strength and appropriateness of a particular trust source for a given
     purpose must be assessed when using them to protect security-relevant data.

Trusted Key 생성과 난수원

127-165

새 Trusted Key는 난수에서 만들고 storage key hierarchy의 child key로 암호화하거나 복호화한다. 그 child key에 대한 암복호화 접근은 trust source 내부의 강한 접근 제어 정책으로 보호해야 한다.

TPM은 장치 내부 하드웨어 RNG로 키를 생성하지만 난수 강도는 제조사마다 다를 수 있다. OP-TEE의 RNG는 플랫폼 요구에 맞게 구성할 수 있으며, 플랫폼 전용 하드웨어 RNG의 직접 출력이나 여러 엔트로피 소스로 seed하는 소프트웨어 Fortuna CSPRNG를 사용할 수 있다.

CAAM은 일반 커널 RNG를 사용한다. CAAM HWRNG로 커널 RNG를 seed하려면 `CRYPTO_DEV_FSL_CAAM_RNG_API`를 켜고 장치가 probe되었는지 확인해야 한다. DCP 자체에는 전용 RNG 인터페이스가 없어 기본 커널 RNG를 사용하지만, i.MX6ULL처럼 DCP와 독립된 하드웨어 RNG가 있는 SoC에서는 이를 켜 커널 RNG를 뒷받침할 수 있다. 선택한 trust source의 기본 동작 대신 커널 난수 풀을 강제하려면 커널 명령줄에 `trusted.rng=kernel`을 지정한다.

Trusted Key 난수원
소스기본 난수원비고
TPMTPM 하드웨어 RNG제조사별 강도 차이 가능
TEE하드웨어 RNG 또는 Fortuna CSPRNG플랫폼별 구성
CAAM커널 RNGCAAM HWRNG로 seed 가능
DCP커널 RNG독립 i.MX HWRNG 사용 가능

trust source마다 새 키 재료를 얻는 위치가 다르다.

Key Generation
==============

Trusted Keys
------------

New keys are created from random numbers. They are encrypted/decrypted using
a child key in the storage key hierarchy. Encryption and decryption of the
child key must be protected by a strong access control policy within the
trust source. The random number generator in use differs according to the
selected trust source:

  *  TPM: hardware device based RNG

     Keys are generated within the TPM. Strength of random numbers may vary
     from one device manufacturer to another.

  *  TEE: OP-TEE based on Arm TrustZone based RNG

     RNG is customizable as per platform needs. It can either be direct output
     from platform specific hardware RNG or a software based Fortuna CSPRNG
     which can be seeded via multiple entropy sources.

  *  CAAM: Kernel RNG

     The normal kernel random number generator is used. To seed it from the
     CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device
     is probed.

  *  DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)

     The DCP hardware device itself does not provide a dedicated RNG interface,
     so the kernel default RNG is used. SoCs with DCP like the i.MX6ULL do have
     a dedicated hardware RNG that is independent from DCP which can be enabled
     to back the kernel RNG.

Users may override this by specifying ``trusted.rng=kernel`` on the kernel
command-line to override the used RNG with the kernel's random number pool.

Encrypted Key 생성과 master key

166-178

Encrypted Key는 trust source에 의존하지 않고 AES로 암호화와 복호화를 수행하므로 더 빠르다. 새 키의 평문 부분은 커널이 생성한 난수 또는 사용자가 제공한 복호화 데이터로 만들고, 지정한 `master` key로 암호화한다.

master key는 `trusted` 또는 `user` 유형일 수 있다. Trusted Key를 뿌리로 삼지 않으면 Encrypted Key의 보안 수준은 이를 암호화하는 user key의 보안 수준을 넘을 수 없다. 따라서 master user key는 가능한 안전한 방식으로, 가급적 부팅 초기에 적재해야 한다.

Encrypted Keys
--------------

Encrypted keys do not depend on a trust source, and are faster, as they use AES
for encryption/decryption. New keys are created either from kernel-generated
random numbers or user-provided decrypted data, and are encrypted/decrypted
using a specified ‘master’ key. The ‘master’ key can either be a trusted-key or
user-key type. The main disadvantage of encrypted keys is that if they are not
rooted in a trusted key, they are only as secure as the user key encrypting
them. The master user key should therefore be loaded in as secure a way as
possible, preferably early in boot.

TPM Trusted Key 사용법과 옵션

179-238

TPM 1.2에서는 기본적으로 Trusted Key를 SRK 아래에 seal하며 SRK의 기본 authorization 값은 0 바이트 20개다. 소유권을 설정할 때 TrouSerS의 `tpm_takeownership -u -z`로 이를 지정할 수 있다. TPM 2.0에서는 재부팅 뒤에도 쓸 수 있도록 storage key를 먼저 만들고 persistent handle에 등록해야 한다. 문서는 IBM TSS 2의 `tsscreateprimary`와 `tssevictcontrol`, Intel TSS 2의 `tpm2_createprimary`와 `tpm2_evictcontrol` 예를 제시하며 `0x81000001`을 persistent handle로 사용한다.

`keyctl add trusted`는 `new keylen [options]` 또는 `load hex_blob [pcrlock=pcrnum]`을 받고, `keyctl update`는 기존 키를 새 옵션으로 갱신한다. `keyhandle=`은 sealing key의 16진 handle이며 TPM 1.2 기본값은 SRK `0x40000000`이고 TPM 2.0에는 기본값이 없어 매번 전달해야 한다. `keyauth=`와 `blobauth=`는 각각 sealing key와 sealed data의 ASCII hex authorization이며 기본값은 40개의 ASCII 0이다.

`pcrinfo=`는 `PCR_INFO` 또는 `PCR_INFO_LONG`의 ASCII hex이고 기본값은 없다. `pcrlock=`은 blob을 잠그기 위해 extend할 PCR 번호다. `migratable=`은 새 PCR 값으로 reseal할 수 있는지 나타내며 `0|1`, 기본값 1이다. `hash=`는 TPM 1.x에서 `sha1`만, TPM 2.x에서는 `sha1`, `sha256`, `sha384`, `sha512`, `sm3-256`을 허용한다. `policydigest=`는 같은 해시 알고리즘으로 계산한 authorization policy digest이고, `policyhandle=`은 seal할 때와 같은 정책과 해시 알고리즘을 정의한 authorization policy session handle이다.

`keyctl print`는 표준 `TPM_STORED_DATA` 형식의 sealed key를 ASCII hex로 반환한다. 새 키 길이 단위는 항상 바이트이며 허용 범위는 32~128바이트(256~1024비트)다. 상한은 필요한 구조와 padding을 포함한 데이터가 2048비트 RSA SRK 안에 들어가도록 정해졌다.

TPM 옵션
옵션의미기본/제약
keyhandle=sealing key handleTPM 1.2: 0x40000000, TPM 2.0: 필수
keyauth= / blobauth=키와 blob authorization각 40 ASCII zeros
pcrinfo= / pcrlock=PCR 결합 정보와 잠금 PCRpcrinfo 기본값 없음
migratable=새 PCR로 reseal 허용기본 1
hash=정책 해시TPM 버전별 허용 목록
policydigest= / policyhandle=authorization policy동일 해시와 정책 필요

생성, 적재, 갱신에 사용되는 핵심 옵션이다.

Usage
=====

Trusted Keys usage: TPM
-----------------------

TPM 1.2: By default, trusted keys are sealed under the SRK, which has the
default authorization value (20 bytes of 0s).  This can be set at takeownership
time with the TrouSerS utility: "tpm_takeownership -u -z".

TPM 2.0: The user must first create a storage key and make it persistent, so the
key is available after reboot. This can be done using the following commands.

With the IBM TSS 2 stack::

  #> tsscreateprimary -hi o -st
  Handle 80000000
  #> tssevictcontrol -hi o -ho 80000000 -hp 81000001

Or with the Intel TSS 2 stack::

  #> tpm2_createprimary --hierarchy o -G rsa2048 -c key.ctxt
  [...]
  #> tpm2_evictcontrol -c key.ctxt 0x81000001
  persistentHandle: 0x81000001

Usage::

    keyctl add trusted name "new keylen [options]" ring
    keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
    keyctl update key "update [options]"
    keyctl print keyid

    options:
       keyhandle=    ascii hex value of sealing key
                       TPM 1.2: default 0x40000000 (SRK)
                       TPM 2.0: no default; must be passed every time
       keyauth=             ascii hex auth for sealing key default 0x00...i
                     (40 ascii zeros)
       blobauth=     ascii hex auth for sealed data default 0x00...
                     (40 ascii zeros)
       pcrinfo=             ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
       pcrlock=             pcr number to be extended to "lock" blob
       migratable=   0|1 indicating permission to reseal to new PCR values,
                     default 1 (resealing allowed)
       hash=         hash algorithm name as a string. For TPM 1.x the only
                     allowed value is sha1. For TPM 2.x the allowed values
                     are sha1, sha256, sha384, sha512 and sm3-256.
       policydigest= digest for the authorization policy. must be calculated
                     with the same hash algorithm as specified by the 'hash='
                     option.
       policyhandle= handle to an authorization policy session that defines the
                     same policy and with the same hash algorithm as was used to
                     seal the key.

"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
TPM_STORED_DATA format.  The key length for new keys are always in bytes.
Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit
within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding.

TEE, CAAM, DCP Trusted Key 사용법

239-277

TEE, CAAM, DCP는 공통으로 `keyctl add trusted name "new keylen" ring`, `keyctl add trusted name "load hex_blob" ring`, `keyctl print keyid` 형태를 사용한다. 새 키 길이는 바이트 단위이며 세 구현 모두 32~128바이트(256~1024비트)를 허용한다.

`keyctl print`가 돌려주는 ASCII hex sealed blob의 내부 형식은 trust source별로 다르다. TEE는 TEE 장치 구현 전용 형식, CAAM은 CAAM 전용 형식, DCP는 이 DCP key-blob 구현 전용 형식을 사용하므로 서로 교환 가능한 표준 blob으로 간주해서는 안 된다.

구현별 sealed blob
소스출력 형식키 길이
TEETEE 장치 구현 전용32~128바이트
CAAMCAAM 전용32~128바이트
DCPDCP key-blob 구현 전용32~128바이트

명령 표면은 같지만 저장 형식은 구현에 종속된다.

Trusted Keys usage: TEE
-----------------------

Usage::

    keyctl add trusted name "new keylen" ring
    keyctl add trusted name "load hex_blob" ring
    keyctl print keyid

"keyctl print" returns an ASCII hex copy of the sealed key, which is in format
specific to TEE device implementation.  The key length for new keys is always
in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).

Trusted Keys usage: CAAM
------------------------

Usage::

    keyctl add trusted name "new keylen" ring
    keyctl add trusted name "load hex_blob" ring
    keyctl print keyid

"keyctl print" returns an ASCII hex copy of the sealed key, which is in a
CAAM-specific format.  The key length for new keys is always in bytes.
Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).

Trusted Keys usage: DCP
-----------------------

Usage::

    keyctl add trusted name "new keylen" ring
    keyctl add trusted name "load hex_blob" ring
    keyctl print keyid

"keyctl print" returns an ASCII hex copy of the sealed key, which is in format
specific to this DCP key-blob implementation.  The key length for new keys is
always in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).

Encrypted Key 명령 문법과 format

278-298

Encrypted Key의 복호화 부분은 단순 대칭 키일 수도 있고 응용 프로그램 전용 복합 구조일 수도 있다. 복합 구조의 형식은 `format`으로 식별한다.

생성 명령은 `new [format] key-type:master-key-name keylen`이며, 끝에 `decrypted-data`를 더해 사용자가 제공한 평문 재료로 인스턴스화할 수도 있다. 저장 blob은 `load hex_blob`으로 적재하고, `keyctl update keyid "update key-type:master-key-name"`으로 master key를 바꾼다. `format`은 `default | ecryptfs | enc32`, `key-type`은 `trusted | user` 중 하나다.

Encrypted Key 수명 주기
format과 master key 선택커널 난수 또는 decrypted-data 입력Encrypted Key 생성keyctl pipe로 blob 저장load로 재적재 또는 update로 master 변경

평문 데이터는 커널 안에서 master key로 감싸지고 blob으로만 반출된다.

Encrypted Keys usage
--------------------

The decrypted portion of encrypted keys can contain either a simple symmetric
key or a more complex structure. The format of the more complex structure is
application specific, which is identified by 'format'.

Usage::

    keyctl add encrypted name "new [format] key-type:master-key-name keylen"
        ring
    keyctl add encrypted name "new [format] key-type:master-key-name keylen
        decrypted-data" ring
    keyctl add encrypted name "load hex_blob" ring
    keyctl update keyid "update key-type:master-key-name"

Where::

        format:= 'default | ecryptfs | enc32'
        key-type:= 'trusted' | 'user'

kmk 생성, 저장, 재적재

299-345

예제는 길이 32바이트의 Trusted Key `kmk`를 user keyring `@u`에 만든다. TPM 2.0에서 persistent key handle `0x81000001`을 쓴다면 따옴표 안의 각 명령에 `keyhandle=0x81000001`을 덧붙여야 한다. `keyctl show`에서 `trusted: kmk`와 serial을 확인하고, `keyctl print`로 sealed blob의 16진 표현을 확인한다.

`keyctl pipe 440502848 > kmk.blob`은 blob을 파일로 보존한다. 이후 `keyctl add trusted kmk "load `cat kmk.blob`" @u`로 같은 키를 새 serial에 적재할 수 있으며, 다시 출력한 blob은 원래 저장한 sealed 데이터와 일치한다. 예제의 긴 16진 데이터와 serial 값은 설명을 위한 실제 출력이므로 원문 코드 블록에 그대로 보존한다.

Trusted kmk 보존
new 32로 kmk 생성keyctl show/print로 확인keyctl pipe로 kmk.blob 저장load `cat kmk.blob`로 재적재새 serial로 동일 키 사용

평문 kmk를 내보내지 않고 sealed blob만 저장하고 복구한다.

Examples of trusted and encrypted key usage
-------------------------------------------

Create and save a trusted key named "kmk" of length 32 bytes.

Note: When using a TPM 2.0 with a persistent key with handle 0x81000001,
append 'keyhandle=0x81000001' to statements between quotes, such as
"new 32 keyhandle=0x81000001".

::

    $ keyctl add trusted kmk "new 32" @u
    440502848

    $ keyctl show
    Session Keyring
           -3 --alswrv    500   500  keyring: _ses
     97833714 --alswrv    500    -1   \_ keyring: _uid.500
    440502848 --alswrv    500   500       \_ trusted: kmk

    $ keyctl print 440502848
    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
    e4a8aea2b607ec96931e6f4d4fe563ba

    $ keyctl pipe 440502848 > kmk.blob

Load a trusted key from the saved blob::

    $ keyctl add trusted kmk "load `cat kmk.blob`" @u
    268728824

    $ keyctl print 268728824
    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
    e4a8aea2b607ec96931e6f4d4fe563ba

새 PCR 값으로 reseal

346-360

TPM 전용 예제는 적재한 Trusted Key에 `keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"`을 실행해 새 PCR 값 아래로 reseal한다. 이어서 `keyctl print`로 출력하면 새 PCR 정보와 함께 다시 봉인된 blob을 얻는다.

이 갱신은 키의 평문을 사용자 공간에 노출하는 작업이 아니라, 이미 적재된 키가 허용하는 경우 보호 정책을 새 플랫폼 상태로 이동하는 작업이다. 출력된 전체 16진 blob은 PCR 정책이 반영된 결과로 원문 좌표와 함께 보존한다.

Reseal (TPM specific) a trusted key under new PCR values::

    $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
    $ keyctl print 268728824
    010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
    77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
    d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
    df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
    9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
    e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
    94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
    7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
    df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8

EVM 소비자와 encrypted evm 예제

361-416

Trusted Key의 초기 소비자는 EVM이다. EVM은 부팅 때 파일 메타데이터를 HMAC으로 보호할 고품질 대칭 키가 필요하다. Trusted Key를 사용하면 사용자 수준 문제로 EVM 키가 손상되지 않았다는 강한 보장을 얻고, 플랫폼 무결성 상태에 seal하면 부팅 공격과 오프라인 공격에도 대응할 수 있다.

앞서 만든 `trusted:kmk`를 master로 `encrypted:evm`을 만들 때 format을 생략한 `new trusted:kmk 32`와 `new default trusted:kmk 32`는 같은 default 형식을 뜻한다. 출력 blob은 format, master 설명, 키 길이와 암호화·무결성 데이터를 포함하며 `keyctl pipe`로 `evm.blob`에 저장한 뒤 `load`로 재적재할 수 있다.

사용자 제공 복호화 데이터를 쓰는 예제는 `/dev/urandom`에서 32바이트를 읽어 hex로 만든 뒤 `new default user:kmk 32 $evmkey`로 인스턴스화한다. 디스크와 파일 암호화 같은 다른 용도도 예상된다. `ecryptfs` format은 eCryptfs 파일시스템 mount용이며 자세한 사용법은 `Documentation/security/keys/ecryptfs.rst`에 있다. `enc32` format은 32바이트 payload를 지원하기 위해 추가되었고 처음에는 nvdimm 보안에 사용하지만 다른 32바이트 payload 용도로 확장할 수 있다.

Encrypted Key format
format용도
default일반 대칭 키 또는 기본 payload
ecryptfseCryptfs mount용 authentication token
enc32nvdimm 등 32바이트 payload

복호화 payload의 구조와 초기 소비자를 구분한다.

The initial consumer of trusted keys is EVM, which at boot time needs a high
quality symmetric key for HMAC protection of file metadata. The use of a
trusted key provides strong guarantees that the EVM key has not been
compromised by a user level problem, and when sealed to a platform integrity
state, protects against boot and offline attacks. Create and save an
encrypted key "evm" using the above trusted key "kmk":

option 1: omitting 'format'::

    $ keyctl add encrypted evm "new trusted:kmk 32" @u
    159771175

option 2: explicitly defining 'format' as 'default'::

    $ keyctl add encrypted evm "new default trusted:kmk 32" @u
    159771175

    $ keyctl print 159771175
    default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
    82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
    24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

    $ keyctl pipe 159771175 > evm.blob

Load an encrypted key "evm" from saved blob::

    $ keyctl add encrypted evm "load `cat evm.blob`" @u
    831684262

    $ keyctl print 831684262
    default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
    82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
    24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

Instantiate an encrypted key "evm" using user-provided decrypted data::

    $ evmkey=$(dd if=/dev/urandom bs=1 count=32 | xxd -c32 -p)
    $ keyctl add encrypted evm "new default user:kmk 32 $evmkey" @u
    794890253

    $ keyctl print 794890253
    default user:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382d
    bbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0247
    17c64 5972dcb82ab2dde83376d82b2e3c09ffc

Other uses for trusted and encrypted keys, such as for disk and file encryption
are anticipated.  In particular the new format 'ecryptfs' has been defined
in order to use encrypted keys to mount an eCryptfs filesystem.  More details
about the usage can be found in the file
``Documentation/security/keys/ecryptfs.rst``.

Another new format 'enc32' has been defined in order to support encrypted keys
with payload size of 32 bytes. This will initially be used for nvdimm security
but may expand to other usages that require 32 bytes payload.

TPM 2.0 ASN.1 구조와 OID

417-451

TPM 2.0 ASN.1 key format은 이진 데이터에서도 쉽게 식별할 수 있고, importable key나 policy 같은 확장 항목을 추가할 수 있도록 설계했다. `TPMKey ::= SEQUENCE`는 `type` OBJECT IDENTIFIER, 선택적 explicit BOOLEAN인 `emptyAuth`, `parent` INTEGER, `pubkey`와 `privkey` OCTET STRING으로 구성된다.

`type`의 OID는 TCG가 고유하게 부여하므로 key의 offset 3에서 알아볼 수 있는 이진 패턴을 이룬다. `2.23.133.10.1.3`은 `TPM2_Load()`로 불러올 수 있는 보통 RSA2048 또는 타원곡선 비대칭 Loadable key, `2.23.133.10.1.4`는 `TPM2_Import()`로 가져올 수 있는 비대칭 Importable Key다. `2.23.133.10.1.5`는 최대 128바이트 데이터를 TPM으로 봉인하는 Sealed Data로 보통 대칭 키를 나타내며 사용 전에 unseal해야 한다. Trusted Key 코드는 이 가운데 TPM Sealed Data OID만 사용한다.

TPM 2.0 OID
OID종류연산/특성
2.23.133.10.1.3TPM Loadable keyTPM2_Load()
2.23.133.10.1.4TPM Importable KeyTPM2_Import()
2.23.133.10.1.5TPM Sealed Data최대 128바이트, Trusted Key 사용

ASN.1 type 필드가 blob의 종류와 허용 연산을 식별한다.

TPM 2.0 ASN.1 Key Format
------------------------

The TPM 2.0 ASN.1 key format is designed to be easily recognisable,
even in binary form (fixing a problem we had with the TPM 1.2 ASN.1
format) and to be extensible for additions like importable keys and
policy::

    TPMKey ::= SEQUENCE {
        type                OBJECT IDENTIFIER
        emptyAuth        [0] EXPLICIT BOOLEAN OPTIONAL
        parent                INTEGER
        pubkey                OCTET STRING
        privkey                OCTET STRING
    }

type is what distinguishes the key even in binary form since the OID
is provided by the TCG to be unique and thus forms a recognizable
binary pattern at offset 3 in the key.  The OIDs currently made
available are::

    2.23.133.10.1.3 TPM Loadable key.  This is an asymmetric key (Usually
                    RSA2048 or Elliptic Curve) which can be imported by a
                    TPM2_Load() operation.

    2.23.133.10.1.4 TPM Importable Key.  This is an asymmetric key (Usually
                    RSA2048 or Elliptic Curve) which can be imported by a
                    TPM2_Import() operation.

    2.23.133.10.1.5 TPM Sealed Data.  This is a set of data (up to 128
                    bytes) which is sealed by the TPM.  It usually
                    represents a symmetric key and must be unsealed before
                    use.

The trusted key code only uses the TPM Sealed Data OID.

ASN.1 authorization, parent, 공개·비공개 필드

452-473

`emptyAuth`가 true면 key의 authorization은 잘 알려진 빈 문자열이다. false이거나 필드가 없으면 명시적 authorization 문구가 필요하다. 사용자 공간 소비자는 이 값을 보고 비밀번호를 물을지 결정한다.

`parent`는 상위 key handle을 나타낸다. RSA primary storage key의 `0x81000001`처럼 0x81 MSO 공간의 handle을 쓸 수 있다. 사용자 공간 프로그램은 0x40 MSO 공간의 primary handle도 지원하며, 이 경우 TCG template의 타원곡선 primary key를 휘발성 object로 즉석 생성해 parent로 사용한다. 현재 커널 코드는 0x81 MSO 형식만 지원한다.

원문 정의에 따르면 `pubkey`는 최초 TPM2B header를 제외한 `TPM2B_PRIVATE`의 이진 표현이고, `privkey`는 최초 header를 제외한 `TPM2B_PUBLIC`의 이진 표현이다. 두 header는 ASN.1 octet string 길이에서 복원할 수 있다. 필드 이름과 TPM2B 유형의 대응은 원문 표기를 그대로 옮긴 것이다.

TPMKey 해석
offset 3의 type OID 식별emptyAuth로 인증 요구 판단0x81 MSO parent handle 확인OCTET STRING 길이 확인TPM2B_PRIVATE/TPM2B_PUBLIC header 복원

OID와 authorization, parent를 읽은 뒤 길이로 TPM2B header를 복원한다.


emptyAuth is true if the key has well known authorization "".  If it
is false or not present, the key requires an explicit authorization
phrase.  This is used by most user space consumers to decide whether
to prompt for a password.

parent represents the parent key handle, either in the 0x81 MSO space,
like 0x81000001 for the RSA primary storage key.  Userspace programmes
also support specifying the primary handle in the 0x40 MSO space.  If
this happens the Elliptic Curve variant of the primary key using the
TCG defined template will be generated on the fly into a volatile
object and used as the parent.  The current kernel code only supports
the 0x81 MSO form.

pubkey is the binary representation of TPM2B_PRIVATE excluding the
initial TPM2B header, which can be reconstructed from the ASN.1 octet
string length.

privkey is the binary representation of TPM2B_PUBLIC excluding the
initial TPM2B header which can be reconstructed from the ASN.1 octed
string length.

DCP blob 형식의 구현 문서

474-481

DCP Blob Format 절은 별도의 설명을 중복하지 않고 `security/keys/trusted-keys/trusted_dcp.c`에서 kernel-doc을 가져온다. `:doc: dcp blob format`으로 형식 설명을 포함하고, `:identifiers: struct dcp_blob_fmt`으로 실제 `struct dcp_blob_fmt` 정의를 문서에 연결한다.

따라서 이 절의 세부 레이아웃은 빌드 시 해당 소스의 kernel-doc 주석과 구조체 정의를 기준으로 유지된다. 문서와 구현의 구조가 어긋나지 않도록 소스 경로와 식별자를 그대로 보존해야 한다.

DCP Blob Format
---------------

.. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
   :doc: dcp blob format

.. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
   :identifiers: struct dcp_blob_fmt