← Documents Documentation/security/keys/core.rst GitHub 원문 ↗

Linux 6.18.37 · Security

커널 키 보존 서비스

Linux key retention의 객체·권한·keyring 수명, 사용자 공간 KEYCTL API, 커널 참조·payload 동시성·key_type callback과 GC를 설명합니다.

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

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

1. 요약·해설

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

요약·해설

core.rst:1-1849

커널 키 보존 서비스의 데이터 모델과 권한, 표준 keyring 수명, 모든 주요 KEYCTL 명령, 커널 참조 관리와 RCU payload 규칙, key_type callback별 lock·sleep 계약, request-key upcall과 garbage collection을 하나의 수명 주기로 연결해 설명합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ============================
2 Kernel Key Retention Service
3 ============================
4
5 This service allows cryptographic keys, authentication tokens, cross-domain
6 user mappings, and similar to be cached in the kernel for the use of
7 filesystems and other kernel services.
8
9 Keyrings are permitted; these are a special type of key that can hold links to
10 other keys. Processes each have three standard keyring subscriptions that a
11 kernel service can search for relevant keys.
12
13 The key service can be configured on by enabling:
14
15 "Security options"/"Enable access key retention support" (CONFIG_KEYS)
16
17 This document has the following sections:
18
19 .. contents:: :local:
20
21
22 Key Overview
23 ============
24
25 In this context, keys represent units of cryptographic data, authentication
26 tokens, keyrings, etc.. These are represented in the kernel by struct key.
27
28 Each key has a number of attributes:
29
30 - A serial number.
31 - A type.
32 - A description (for matching a key in a search).
33 - Access control information.
34 - An expiry time.
35 - A payload.
36 - State.
37
38
39 * Each key is issued a serial number of type key_serial_t that is unique for
40 the lifetime of that key. All serial numbers are positive non-zero 32-bit
41 integers.
42
43 Userspace programs can use a key's serial numbers as a way to gain access
44 to it, subject to permission checking.
45
46 * Each key is of a defined "type". Types must be registered inside the
47 kernel by a kernel service (such as a filesystem) before keys of that type
48 can be added or used. Userspace programs cannot define new types directly.
49
50 Key types are represented in the kernel by struct key_type. This defines a
51 number of operations that can be performed on a key of that type.
52
53 Should a type be removed from the system, all the keys of that type will
54 be invalidated.
55
56 * Each key has a description. This should be a printable string. The key
57 type provides an operation to perform a match between the description on a
58 key and a criterion string.
59
60 * Each key has an owner user ID, a group ID and a permissions mask. These
61 are used to control what a process may do to a key from userspace, and
62 whether a kernel service will be able to find the key.
63
64 * Each key can be set to expire at a specific time by the key type's
65 instantiation function. Keys can also be immortal.
66
67 * Each key can have a payload. This is a quantity of data that represent the
68 actual "key". In the case of a keyring, this is a list of keys to which
69 the keyring links; in the case of a user-defined key, it's an arbitrary
70 blob of data.
71
72 Having a payload is not required; and the payload can, in fact, just be a
73 value stored in the struct key itself.
74
75 When a key is instantiated, the key type's instantiation function is
76 called with a blob of data, and that then creates the key's payload in
77 some way.
78
79 Similarly, when userspace wants to read back the contents of the key, if
80 permitted, another key type operation will be called to convert the key's
81 attached payload back into a blob of data.
82
83 * Each key can be in one of a number of basic states:
84
85 * Uninstantiated. The key exists, but does not have any data attached.
86 Keys being requested from userspace will be in this state.
87
88 * Instantiated. This is the normal state. The key is fully formed, and
89 has data attached.
90
91 * Negative. This is a relatively short-lived state. The key acts as a
92 note saying that a previous call out to userspace failed, and acts as
93 a throttle on key lookups. A negative key can be updated to a normal
94 state.
95
96 * Expired. Keys can have lifetimes set. If their lifetime is exceeded,
97 they traverse to this state. An expired key can be updated back to a
98 normal state.
99
100 * Revoked. A key is put in this state by userspace action. It can't be
101 found or operated upon (apart from by unlinking it).
102
103 * Dead. The key's type was unregistered, and so the key is now useless.
104
105 Keys in the last three states are subject to garbage collection. See the
106 section on "Garbage collection".
107
108
109 Key Service Overview
110 ====================
111
112 The key service provides a number of features besides keys:
113
114 * The key service defines three special key types:
115
116 (+) "keyring"
117
118 Keyrings are special keys that contain a list of other keys. Keyring
119 lists can be modified using various system calls. Keyrings should not
120 be given a payload when created.
121
122 (+) "user"
123
124 A key of this type has a description and a payload that are arbitrary
125 blobs of data. These can be created, updated and read by userspace,
126 and aren't intended for use by kernel services.
127
128 (+) "logon"
129
130 Like a "user" key, a "logon" key has a payload that is an arbitrary
131 blob of data. It is intended as a place to store secrets which are
132 accessible to the kernel but not to userspace programs.
133
134 The description can be arbitrary, but must be prefixed with a non-zero
135 length string that describes the key "subclass". The subclass is
136 separated from the rest of the description by a ':'. "logon" keys can
137 be created and updated from userspace, but the payload is only
138 readable from kernel space.
139
140 * Each process subscribes to three keyrings: a thread-specific keyring, a
141 process-specific keyring, and a session-specific keyring.
142
143 The thread-specific keyring is discarded from the child when any sort of
144 clone, fork, vfork or execve occurs. A new keyring is created only when
145 required.
146
147 The process-specific keyring is replaced with an empty one in the child on
148 clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
149 shared. execve also discards the process's process keyring and creates a
150 new one.
151
152 The session-specific keyring is persistent across clone, fork, vfork and
153 execve, even when the latter executes a set-UID or set-GID binary. A
154 process can, however, replace its current session keyring with a new one
155 by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous
156 new one, or to attempt to create or join one of a specific name.
157
158 The ownership of the thread keyring changes when the real UID and GID of
159 the thread changes.
160
161 * Each user ID resident in the system holds two special keyrings: a user
162 specific keyring and a default user session keyring. The default session
163 keyring is initialised with a link to the user-specific keyring.
164
165 When a process changes its real UID, if it used to have no session key, it
166 will be subscribed to the default session key for the new UID.
167
168 If a process attempts to access its session key when it doesn't have one,
169 it will be subscribed to the default for its current UID.
170
171 * Each user has two quotas against which the keys they own are tracked. One
172 limits the total number of keys and keyrings, the other limits the total
173 amount of description and payload space that can be consumed.
174
175 The user can view information on this and other statistics through procfs
176 files. The root user may also alter the quota limits through sysctl files
177 (see the section "New procfs files").
178
179 Process-specific and thread-specific keyrings are not counted towards a
180 user's quota.
181
182 If a system call that modifies a key or keyring in some way would put the
183 user over quota, the operation is refused and error EDQUOT is returned.
184
185 * There's a system call interface by which userspace programs can create and
186 manipulate keys and keyrings.
187
188 * There's a kernel interface by which services can register types and search
189 for keys.
190
191 * There's a way for the a search done from the kernel to call back to
192 userspace to request a key that can't be found in a process's keyrings.
193
194 * An optional filesystem is available through which the key database can be
195 viewed and manipulated.
196
197
198 Key Access Permissions
199 ======================
200
201 Keys have an owner user ID, a group access ID, and a permissions mask. The mask
202 has up to eight bits each for possessor, user, group and other access. Only
203 six of each set of eight bits are defined. These permissions granted are:
204
205 * View
206
207 This permits a key or keyring's attributes to be viewed - including key
208 type and description.
209
210 * Read
211
212 This permits a key's payload to be viewed or a keyring's list of linked
213 keys.
214
215 * Write
216
217 This permits a key's payload to be instantiated or updated, or it allows a
218 link to be added to or removed from a keyring.
219
220 * Search
221
222 This permits keyrings to be searched and keys to be found. Searches can
223 only recurse into nested keyrings that have search permission set.
224
225 * Link
226
227 This permits a key or keyring to be linked to. To create a link from a
228 keyring to a key, a process must have Write permission on the keyring and
229 Link permission on the key.
230
231 * Set Attribute
232
233 This permits a key's UID, GID and permissions mask to be changed.
234
235 For changing the ownership, group ID or permissions mask, being the owner of
236 the key or having the sysadmin capability is sufficient.
237
238
239 SELinux Support
240 ===============
241
242 The security class "key" has been added to SELinux so that mandatory access
243 controls can be applied to keys created within various contexts. This support
244 is preliminary, and is likely to change quite significantly in the near future.
245 Currently, all of the basic permissions explained above are provided in SELinux
246 as well; SELinux is simply invoked after all basic permission checks have been
247 performed.
248
249 The value of the file /proc/self/attr/keycreate influences the labeling of
250 newly-created keys. If the contents of that file correspond to an SELinux
251 security context, then the key will be assigned that context. Otherwise, the
252 key will be assigned the current context of the task that invoked the key
253 creation request. Tasks must be granted explicit permission to assign a
254 particular context to newly-created keys, using the "create" permission in the
255 key security class.
256
257 The default keyrings associated with users will be labeled with the default
258 context of the user if and only if the login programs have been instrumented to
259 properly initialize keycreate during the login process. Otherwise, they will
260 be labeled with the context of the login program itself.
261
262 Note, however, that the default keyrings associated with the root user are
263 labeled with the default kernel context, since they are created early in the
264 boot process, before root has a chance to log in.
265
266 The keyrings associated with new threads are each labeled with the context of
267 their associated thread, and both session and process keyrings are handled
268 similarly.
269
270
271 New ProcFS Files
272 ================
273
274 Two files have been added to procfs by which an administrator can find out
275 about the status of the key service:
276
277 * /proc/keys
278
279 This lists the keys that are currently viewable by the task reading the
280 file, giving information about their type, description and permissions.
281 It is not possible to view the payload of the key this way, though some
282 information about it may be given.
283
284 The only keys included in the list are those that grant View permission to
285 the reading process whether or not it possesses them. Note that LSM
286 security checks are still performed, and may further filter out keys that
287 the current process is not authorised to view.
288
289 The contents of the file look like this::
290
291 SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
292 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4
293 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty
294 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty
295 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty
296 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4
297 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty
298 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
299 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0
300 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0
301
302 The flags are::
303
304 I Instantiated
305 R Revoked
306 D Dead
307 Q Contributes to user's quota
308 U Under construction by callback to userspace
309 N Negative key
310
311
312 * /proc/key-users
313
314 This file lists the tracking data for each user that has at least one key
315 on the system. Such data includes quota information and statistics::
316
317 [root@andromeda root]# cat /proc/key-users
318 0: 46 45/45 1/100 13/10000
319 29: 2 2/2 2/100 40/10000
320 32: 2 2/2 2/100 40/10000
321 38: 2 2/2 2/100 40/10000
322
323 The format of each line is::
324
325 <UID>: User ID to which this applies
326 <usage> Structure refcount
327 <inst>/<keys> Total number of keys and number instantiated
328 <keys>/<max> Key count quota
329 <bytes>/<max> Key size quota
330
331
332 Four new sysctl files have been added also for the purpose of controlling the
333 quota limits on keys:
334
335 * /proc/sys/kernel/keys/root_maxkeys
336 /proc/sys/kernel/keys/root_maxbytes
337
338 These files hold the maximum number of keys that root may have and the
339 maximum total number of bytes of data that root may have stored in those
340 keys.
341
342 * /proc/sys/kernel/keys/maxkeys
343 /proc/sys/kernel/keys/maxbytes
344
345 These files hold the maximum number of keys that each non-root user may
346 have and the maximum total number of bytes of data that each of those
347 users may have stored in their keys.
348
349 Root may alter these by writing each new limit as a decimal number string to
350 the appropriate file.
351
352
353 Userspace System Call Interface
354 ===============================
355
356 Userspace can manipulate keys directly through three new syscalls: add_key,
357 request_key and keyctl. The latter provides a number of functions for
358 manipulating keys.
359
360 When referring to a key directly, userspace programs should use the key's
361 serial number (a positive 32-bit integer). However, there are some special
362 values available for referring to special keys and keyrings that relate to the
363 process making the call::
364
365 CONSTANT VALUE KEY REFERENCED
366 ============================== ====== ===========================
367 KEY_SPEC_THREAD_KEYRING -1 thread-specific keyring
368 KEY_SPEC_PROCESS_KEYRING -2 process-specific keyring
369 KEY_SPEC_SESSION_KEYRING -3 session-specific keyring
370 KEY_SPEC_USER_KEYRING -4 UID-specific keyring
371 KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring
372 KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring
373 KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key()
374 authorisation key
375
376
377 The main syscalls are:
378
379 * Create a new key of given type, description and payload and add it to the
380 nominated keyring::
381
382 key_serial_t add_key(const char *type, const char *desc,
383 const void *payload, size_t plen,
384 key_serial_t keyring);
385
386 If a key of the same type and description as that proposed already exists
387 in the keyring, this will try to update it with the given payload, or it
388 will return error EEXIST if that function is not supported by the key
389 type. The process must also have permission to write to the key to be able
390 to update it. The new key will have all user permissions granted and no
391 group or third party permissions.
392
393 Otherwise, this will attempt to create a new key of the specified type and
394 description, and to instantiate it with the supplied payload and attach it
395 to the keyring. In this case, an error will be generated if the process
396 does not have permission to write to the keyring.
397
398 If the key type supports it, if the description is NULL or an empty
399 string, the key type will try and generate a description from the content
400 of the payload.
401
402 The payload is optional, and the pointer can be NULL if not required by
403 the type. The payload is plen in size, and plen can be zero for an empty
404 payload.
405
406 A new keyring can be generated by setting type "keyring", the keyring name
407 as the description (or NULL) and setting the payload to NULL.
408
409 User defined keys can be created by specifying type "user". It is
410 recommended that a user defined key's description by prefixed with a type
411 ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting
412 ticket.
413
414 Any other type must have been registered with the kernel in advance by a
415 kernel service such as a filesystem.
416
417 The ID of the new or updated key is returned if successful.
418
419
420 * Search the process's keyrings for a key, potentially calling out to
421 userspace to create it::
422
423 key_serial_t request_key(const char *type, const char *description,
424 const char *callout_info,
425 key_serial_t dest_keyring);
426
427 This function searches all the process's keyrings in the order thread,
428 process, session for a matching key. This works very much like
429 KEYCTL_SEARCH, including the optional attachment of the discovered key to
430 a keyring.
431
432 If a key cannot be found, and if callout_info is not NULL, then
433 /sbin/request-key will be invoked in an attempt to obtain a key. The
434 callout_info string will be passed as an argument to the program.
435
436 To link a key into the destination keyring the key must grant link
437 permission on the key to the caller and the keyring must grant write
438 permission.
439
440 See also Documentation/security/keys/request-key.rst.
441
442
443 The keyctl syscall functions are:
444
445 * Map a special key ID to a real key ID for this process::
446
447 key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
448 int create);
449
450 The special key specified by "id" is looked up (with the key being created
451 if necessary) and the ID of the key or keyring thus found is returned if
452 it exists.
453
454 If the key does not yet exist, the key will be created if "create" is
455 non-zero; and the error ENOKEY will be returned if "create" is zero.
456
457
458 * Replace the session keyring this process subscribes to with a new one::
459
460 key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name);
461
462 If name is NULL, an anonymous keyring is created attached to the process
463 as its session keyring, displacing the old session keyring.
464
465 If name is not NULL, if a keyring of that name exists, the process
466 attempts to attach it as the session keyring, returning an error if that
467 is not permitted; otherwise a new keyring of that name is created and
468 attached as the session keyring.
469
470 To attach to a named keyring, the keyring must have search permission for
471 the process's ownership.
472
473 The ID of the new session keyring is returned if successful.
474
475
476 * Update the specified key::
477
478 long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload,
479 size_t plen);
480
481 This will try to update the specified key with the given payload, or it
482 will return error EOPNOTSUPP if that function is not supported by the key
483 type. The process must also have permission to write to the key to be able
484 to update it.
485
486 The payload is of length plen, and may be absent or empty as for
487 add_key().
488
489
490 * Revoke a key::
491
492 long keyctl(KEYCTL_REVOKE, key_serial_t key);
493
494 This makes a key unavailable for further operations. Further attempts to
495 use the key will be met with error EKEYREVOKED, and the key will no longer
496 be findable.
497
498
499 * Change the ownership of a key::
500
501 long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
502
503 This function permits a key's owner and group ID to be changed. Either one
504 of uid or gid can be set to -1 to suppress that change.
505
506 Only the superuser can change a key's owner to something other than the
507 key's current owner. Similarly, only the superuser can change a key's
508 group ID to something other than the calling process's group ID or one of
509 its group list members.
510
511
512 * Change the permissions mask on a key::
513
514 long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm);
515
516 This function permits the owner of a key or the superuser to change the
517 permissions mask on a key.
518
519 Only bits the available bits are permitted; if any other bits are set,
520 error EINVAL will be returned.
521
522
523 * Describe a key::
524
525 long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer,
526 size_t buflen);
527
528 This function returns a summary of the key's attributes (but not its
529 payload data) as a string in the buffer provided.
530
531 Unless there's an error, it always returns the amount of data it could
532 produce, even if that's too big for the buffer, but it won't copy more
533 than requested to userspace. If the buffer pointer is NULL then no copy
534 will take place.
535
536 A process must have view permission on the key for this function to be
537 successful.
538
539 If successful, a string is placed in the buffer in the following format::
540
541 <type>;<uid>;<gid>;<perm>;<description>
542
543 Where type and description are strings, uid and gid are decimal, and perm
544 is hexadecimal. A NUL character is included at the end of the string if
545 the buffer is sufficiently big.
546
547 This can be parsed with::
548
549 sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc);
550
551
552 * Clear out a keyring::
553
554 long keyctl(KEYCTL_CLEAR, key_serial_t keyring);
555
556 This function clears the list of keys attached to a keyring. The calling
557 process must have write permission on the keyring, and it must be a
558 keyring (or else error ENOTDIR will result).
559
560 This function can also be used to clear special kernel keyrings if they
561 are appropriately marked if the user has CAP_SYS_ADMIN capability. The
562 DNS resolver cache keyring is an example of this.
563
564
565 * Link a key into a keyring::
566
567 long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
568
569 This function creates a link from the keyring to the key. The process must
570 have write permission on the keyring and must have link permission on the
571 key.
572
573 Should the keyring not be a keyring, error ENOTDIR will result; and if the
574 keyring is full, error ENFILE will result.
575
576 The link procedure checks the nesting of the keyrings, returning ELOOP if
577 it appears too deep or EDEADLK if the link would introduce a cycle.
578
579 Any links within the keyring to keys that match the new key in terms of
580 type and description will be discarded from the keyring as the new one is
581 added.
582
583
584 * Move a key from one keyring to another::
585
586 long keyctl(KEYCTL_MOVE,
587 key_serial_t id,
588 key_serial_t from_ring_id,
589 key_serial_t to_ring_id,
590 unsigned int flags);
591
592 Move the key specified by "id" from the keyring specified by
593 "from_ring_id" to the keyring specified by "to_ring_id". If the two
594 keyrings are the same, nothing is done.
595
596 "flags" can have KEYCTL_MOVE_EXCL set in it to cause the operation to fail
597 with EEXIST if a matching key exists in the destination keyring, otherwise
598 such a key will be replaced.
599
600 A process must have link permission on the key for this function to be
601 successful and write permission on both keyrings. Any errors that can
602 occur from KEYCTL_LINK also apply on the destination keyring here.
603
604
605 * Unlink a key or keyring from another keyring::
606
607 long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key);
608
609 This function looks through the keyring for the first link to the
610 specified key, and removes it if found. Subsequent links to that key are
611 ignored. The process must have write permission on the keyring.
612
613 If the keyring is not a keyring, error ENOTDIR will result; and if the key
614 is not present, error ENOENT will be the result.
615
616
617 * Search a keyring tree for a key::
618
619 key_serial_t keyctl(KEYCTL_SEARCH, key_serial_t keyring,
620 const char *type, const char *description,
621 key_serial_t dest_keyring);
622
623 This searches the keyring tree headed by the specified keyring until a key
624 is found that matches the type and description criteria. Each keyring is
625 checked for keys before recursion into its children occurs.
626
627 The process must have search permission on the top level keyring, or else
628 error EACCES will result. Only keyrings that the process has search
629 permission on will be recursed into, and only keys and keyrings for which
630 a process has search permission can be matched. If the specified keyring
631 is not a keyring, ENOTDIR will result.
632
633 If the search succeeds, the function will attempt to link the found key
634 into the destination keyring if one is supplied (non-zero ID). All the
635 constraints applicable to KEYCTL_LINK apply in this case too.
636
637 Error ENOKEY, EKEYREVOKED or EKEYEXPIRED will be returned if the search
638 fails. On success, the resulting key ID will be returned.
639
640
641 * Read the payload data from a key::
642
643 long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
644 size_t buflen);
645
646 This function attempts to read the payload data from the specified key
647 into the buffer. The process must have read permission on the key to
648 succeed.
649
650 The returned data will be processed for presentation by the key type. For
651 instance, a keyring will return an array of key_serial_t entries
652 representing the IDs of all the keys to which it is subscribed. The user
653 defined key type will return its data as is. If a key type does not
654 implement this function, error EOPNOTSUPP will result.
655
656 If the specified buffer is too small, then the size of the buffer required
657 will be returned. Note that in this case, the contents of the buffer may
658 have been overwritten in some undefined way.
659
660 Otherwise, on success, the function will return the amount of data copied
661 into the buffer.
662
663 * Instantiate a partially constructed key::
664
665 long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
666 const void *payload, size_t plen,
667 key_serial_t keyring);
668 long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key,
669 const struct iovec *payload_iov, unsigned ioc,
670 key_serial_t keyring);
671
672 If the kernel calls back to userspace to complete the instantiation of a
673 key, userspace should use this call to supply data for the key before the
674 invoked process returns, or else the key will be marked negative
675 automatically.
676
677 The process must have write access on the key to be able to instantiate
678 it, and the key must be uninstantiated.
679
680 If a keyring is specified (non-zero), the key will also be linked into
681 that keyring, however all the constraints applying in KEYCTL_LINK apply in
682 this case too.
683
684 The payload and plen arguments describe the payload data as for add_key().
685
686 The payload_iov and ioc arguments describe the payload data in an iovec
687 array instead of a single buffer.
688
689
690 * Negatively instantiate a partially constructed key::
691
692 long keyctl(KEYCTL_NEGATE, key_serial_t key,
693 unsigned timeout, key_serial_t keyring);
694 long keyctl(KEYCTL_REJECT, key_serial_t key,
695 unsigned timeout, unsigned error, key_serial_t keyring);
696
697 If the kernel calls back to userspace to complete the instantiation of a
698 key, userspace should use this call mark the key as negative before the
699 invoked process returns if it is unable to fulfill the request.
700
701 The process must have write access on the key to be able to instantiate
702 it, and the key must be uninstantiated.
703
704 If a keyring is specified (non-zero), the key will also be linked into
705 that keyring, however all the constraints applying in KEYCTL_LINK apply in
706 this case too.
707
708 If the key is rejected, future searches for it will return the specified
709 error code until the rejected key expires. Negating the key is the same
710 as rejecting the key with ENOKEY as the error code.
711
712
713 * Set the default request-key destination keyring::
714
715 long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
716
717 This sets the default keyring to which implicitly requested keys will be
718 attached for this thread. reqkey_defl should be one of these constants::
719
720 CONSTANT VALUE NEW DEFAULT KEYRING
721 ====================================== ====== =======================
722 KEY_REQKEY_DEFL_NO_CHANGE -1 No change
723 KEY_REQKEY_DEFL_DEFAULT 0 Default[1]
724 KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring
725 KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring
726 KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring
727 KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring
728 KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring
729 KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring
730
731 The old default will be returned if successful and error EINVAL will be
732 returned if reqkey_defl is not one of the above values.
733
734 The default keyring can be overridden by the keyring indicated to the
735 request_key() system call.
736
737 Note that this setting is inherited across fork/exec.
738
739 [1] The default is: the thread keyring if there is one, otherwise
740 the process keyring if there is one, otherwise the session keyring if
741 there is one, otherwise the user default session keyring.
742
743
744 * Set the timeout on a key::
745
746 long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);
747
748 This sets or clears the timeout on a key. The timeout can be 0 to clear
749 the timeout or a number of seconds to set the expiry time that far into
750 the future.
751
752 The process must have attribute modification access on a key to set its
753 timeout. Timeouts may not be set with this function on negative, revoked
754 or expired keys.
755
756
757 * Assume the authority granted to instantiate a key::
758
759 long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);
760
761 This assumes or divests the authority required to instantiate the
762 specified key. Authority can only be assumed if the thread has the
763 authorisation key associated with the specified key in its keyrings
764 somewhere.
765
766 Once authority is assumed, searches for keys will also search the
767 requester's keyrings using the requester's security label, UID, GID and
768 groups.
769
770 If the requested authority is unavailable, error EPERM will be returned,
771 likewise if the authority has been revoked because the target key is
772 already instantiated.
773
774 If the specified key is 0, then any assumed authority will be divested.
775
776 The assumed authoritative key is inherited across fork and exec.
777
778
779 * Get the LSM security context attached to a key::
780
781 long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
782 size_t buflen)
783
784 This function returns a string that represents the LSM security context
785 attached to a key in the buffer provided.
786
787 Unless there's an error, it always returns the amount of data it could
788 produce, even if that's too big for the buffer, but it won't copy more
789 than requested to userspace. If the buffer pointer is NULL then no copy
790 will take place.
791
792 A NUL character is included at the end of the string if the buffer is
793 sufficiently big. This is included in the returned count. If no LSM is
794 in force then an empty string will be returned.
795
796 A process must have view permission on the key for this function to be
797 successful.
798
799
800 * Install the calling process's session keyring on its parent::
801
802 long keyctl(KEYCTL_SESSION_TO_PARENT);
803
804 This functions attempts to install the calling process's session keyring
805 on to the calling process's parent, replacing the parent's current session
806 keyring.
807
808 The calling process must have the same ownership as its parent, the
809 keyring must have the same ownership as the calling process, the calling
810 process must have LINK permission on the keyring and the active LSM module
811 mustn't deny permission, otherwise error EPERM will be returned.
812
813 Error ENOMEM will be returned if there was insufficient memory to complete
814 the operation, otherwise 0 will be returned to indicate success.
815
816 The keyring will be replaced next time the parent process leaves the
817 kernel and resumes executing userspace.
818
819
820 * Invalidate a key::
821
822 long keyctl(KEYCTL_INVALIDATE, key_serial_t key);
823
824 This function marks a key as being invalidated and then wakes up the
825 garbage collector. The garbage collector immediately removes invalidated
826 keys from all keyrings and deletes the key when its reference count
827 reaches zero.
828
829 Keys that are marked invalidated become invisible to normal key operations
830 immediately, though they are still visible in /proc/keys until deleted
831 (they're marked with an 'i' flag).
832
833 A process must have search permission on the key for this function to be
834 successful.
835
836 * Compute a Diffie-Hellman shared secret or public key::
837
838 long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
839 char *buffer, size_t buflen, struct keyctl_kdf_params *kdf);
840
841 The params struct contains serial numbers for three keys::
842
843 - The prime, p, known to both parties
844 - The local private key
845 - The base integer, which is either a shared generator or the
846 remote public key
847
848 The value computed is::
849
850 result = base ^ private (mod prime)
851
852 If the base is the shared generator, the result is the local
853 public key. If the base is the remote public key, the result is
854 the shared secret.
855
856 If the parameter kdf is NULL, the following applies:
857
858 - The buffer length must be at least the length of the prime, or zero.
859
860 - If the buffer length is nonzero, the length of the result is
861 returned when it is successfully calculated and copied in to the
862 buffer. When the buffer length is zero, the minimum required
863 buffer length is returned.
864
865 The kdf parameter allows the caller to apply a key derivation function
866 (KDF) on the Diffie-Hellman computation where only the result
867 of the KDF is returned to the caller. The KDF is characterized with
868 struct keyctl_kdf_params as follows:
869
870 - ``char *hashname`` specifies the NUL terminated string identifying
871 the hash used from the kernel crypto API and applied for the KDF
872 operation. The KDF implementation complies with SP800-56A as well
873 as with SP800-108 (the counter KDF).
874
875 - ``char *otherinfo`` specifies the OtherInfo data as documented in
876 SP800-56A section 5.8.1.2. The length of the buffer is given with
877 otherinfolen. The format of OtherInfo is defined by the caller.
878 The otherinfo pointer may be NULL if no OtherInfo shall be used.
879
880 This function will return error EOPNOTSUPP if the key type is not
881 supported, error ENOKEY if the key could not be found, or error
882 EACCES if the key is not readable by the caller. In addition, the
883 function will return EMSGSIZE when the parameter kdf is non-NULL
884 and either the buffer length or the OtherInfo length exceeds the
885 allowed length.
886
887
888 * Restrict keyring linkage::
889
890 long keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring,
891 const char *type, const char *restriction);
892
893 An existing keyring can restrict linkage of additional keys by evaluating
894 the contents of the key according to a restriction scheme.
895
896 "keyring" is the key ID for an existing keyring to apply a restriction
897 to. It may be empty or may already have keys linked. Existing linked keys
898 will remain in the keyring even if the new restriction would reject them.
899
900 "type" is a registered key type.
901
902 "restriction" is a string describing how key linkage is to be restricted.
903 The format varies depending on the key type, and the string is passed to
904 the lookup_restriction() function for the requested type. It may specify
905 a method and relevant data for the restriction such as signature
906 verification or constraints on key payload. If the requested key type is
907 later unregistered, no keys may be added to the keyring after the key type
908 is removed.
909
910 To apply a keyring restriction the process must have Set Attribute
911 permission and the keyring must not be previously restricted.
912
913 One application of restricted keyrings is to verify X.509 certificate
914 chains or individual certificate signatures using the asymmetric key type.
915 See Documentation/crypto/asymmetric-keys.rst for specific restrictions
916 applicable to the asymmetric key type.
917
918
919 * Query an asymmetric key::
920
921 long keyctl(KEYCTL_PKEY_QUERY,
922 key_serial_t key_id, unsigned long reserved,
923 const char *params,
924 struct keyctl_pkey_query *info);
925
926 Get information about an asymmetric key. Specific algorithms and
927 encodings may be queried by using the ``params`` argument. This is a
928 string containing a space- or tab-separated string of key-value pairs.
929 Currently supported keys include ``enc`` and ``hash``. The information
930 is returned in the keyctl_pkey_query struct::
931
932 __u32 supported_ops;
933 __u32 key_size;
934 __u16 max_data_size;
935 __u16 max_sig_size;
936 __u16 max_enc_size;
937 __u16 max_dec_size;
938 __u32 __spare[10];
939
940 ``supported_ops`` contains a bit mask of flags indicating which ops are
941 supported. This is constructed from a bitwise-OR of::
942
943 KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
944
945 ``key_size`` indicated the size of the key in bits.
946
947 ``max_*_size`` indicate the maximum sizes in bytes of a blob of data to be
948 signed, a signature blob, a blob to be encrypted and a blob to be
949 decrypted.
950
951 ``__spare[]`` must be set to 0. This is intended for future use to hand
952 over one or more passphrases needed unlock a key.
953
954 If successful, 0 is returned. If the key is not an asymmetric key,
955 EOPNOTSUPP is returned.
956
957
958 * Encrypt, decrypt, sign or verify a blob using an asymmetric key::
959
960 long keyctl(KEYCTL_PKEY_ENCRYPT,
961 const struct keyctl_pkey_params *params,
962 const char *info,
963 const void *in,
964 void *out);
965
966 long keyctl(KEYCTL_PKEY_DECRYPT,
967 const struct keyctl_pkey_params *params,
968 const char *info,
969 const void *in,
970 void *out);
971
972 long keyctl(KEYCTL_PKEY_SIGN,
973 const struct keyctl_pkey_params *params,
974 const char *info,
975 const void *in,
976 void *out);
977
978 long keyctl(KEYCTL_PKEY_VERIFY,
979 const struct keyctl_pkey_params *params,
980 const char *info,
981 const void *in,
982 const void *in2);
983
984 Use an asymmetric key to perform a public-key cryptographic operation a
985 blob of data. For encryption and verification, the asymmetric key may
986 only need the public parts to be available, but for decryption and signing
987 the private parts are required also.
988
989 The parameter block pointed to by params contains a number of integer
990 values::
991
992 __s32 key_id;
993 __u32 in_len;
994 __u32 out_len;
995 __u32 in2_len;
996
997 ``key_id`` is the ID of the asymmetric key to be used. ``in_len`` and
998 ``in2_len`` indicate the amount of data in the in and in2 buffers and
999 ``out_len`` indicates the size of the out buffer as appropriate for the
1000 above operations.
1002 For a given operation, the in and out buffers are used as follows::
1004 Operation ID in,in_len out,out_len in2,in2_len
1005 ======================= =============== =============== ===============
1006 KEYCTL_PKEY_ENCRYPT Raw data Encrypted data -
1007 KEYCTL_PKEY_DECRYPT Encrypted data Raw data -
1008 KEYCTL_PKEY_SIGN Raw data Signature -
1009 KEYCTL_PKEY_VERIFY Raw data - Signature
1011 ``info`` is a string of key=value pairs that supply supplementary
1012 information. These include:
1014 ``enc=<encoding>`` The encoding of the encrypted/signature blob. This
1015 can be "pkcs1" for RSASSA-PKCS1-v1.5 or
1016 RSAES-PKCS1-v1.5; "pss" for "RSASSA-PSS"; "oaep" for
1017 "RSAES-OAEP". If omitted or is "raw", the raw output
1018 of the encryption function is specified.
1020 ``hash=<algo>`` If the data buffer contains the output of a hash
1021 function and the encoding includes some indication of
1022 which hash function was used, the hash function can be
1023 specified with this, eg. "hash=sha256".
1025 The ``__spare[]`` space in the parameter block must be set to 0. This is
1026 intended, amongst other things, to allow the passing of passphrases
1027 required to unlock a key.
1029 If successful, encrypt, decrypt and sign all return the amount of data
1030 written into the output buffer. Verification returns 0 on success.
1033 * Watch a key or keyring for changes::
1035 long keyctl(KEYCTL_WATCH_KEY, key_serial_t key, int queue_fd,
1036 const struct watch_notification_filter *filter);
1038 This will set or remove a watch for changes on the specified key or
1039 keyring.
1041 "key" is the ID of the key to be watched.
1043 "queue_fd" is a file descriptor referring to an open pipe which
1044 manages the buffer into which notifications will be delivered.
1046 "filter" is either NULL to remove a watch or a filter specification to
1047 indicate what events are required from the key.
1049 See Documentation/core-api/watch_queue.rst for more information.
1051 Note that only one watch may be emplaced for any particular { key,
1052 queue_fd } combination.
1054 Notification records look like::
1056 struct key_notification {
1057 struct watch_notification watch;
1058 __u32 key_id;
1059 __u32 aux;
1060 };
1062 In this, watch::type will be "WATCH_TYPE_KEY_NOTIFY" and subtype will be
1063 one of::
1065 NOTIFY_KEY_INSTANTIATED
1066 NOTIFY_KEY_UPDATED
1067 NOTIFY_KEY_LINKED
1068 NOTIFY_KEY_UNLINKED
1069 NOTIFY_KEY_CLEARED
1070 NOTIFY_KEY_REVOKED
1071 NOTIFY_KEY_INVALIDATED
1072 NOTIFY_KEY_SETATTR
1074 Where these indicate a key being instantiated/rejected, updated, a link
1075 being made in a keyring, a link being removed from a keyring, a keyring
1076 being cleared, a key being revoked, a key being invalidated or a key
1077 having one of its attributes changed (user, group, perm, timeout,
1078 restriction).
1080 If a watched key is deleted, a basic watch_notification will be issued
1081 with "type" set to WATCH_TYPE_META and "subtype" set to
1082 watch_meta_removal_notification. The watchpoint ID will be set in the
1083 "info" field.
1085 This needs to be configured by enabling:
1087 "Provide key/keyring change notifications" (KEY_NOTIFICATIONS)
1090 Kernel Services
1091 ===============
1093 The kernel services for key management are fairly simple to deal with. They can
1094 be broken down into two areas: keys and key types.
1096 Dealing with keys is fairly straightforward. Firstly, the kernel service
1097 registers its type, then it searches for a key of that type. It should retain
1098 the key as long as it has need of it, and then it should release it. For a
1099 filesystem or device file, a search would probably be performed during the open
1100 call, and the key released upon close. How to deal with conflicting keys due to
1101 two different users opening the same file is left to the filesystem author to
1102 solve.
1104 To access the key manager, the following header must be #included::
1106 <linux/key.h>
1108 Specific key types should have a header file under include/keys/ that should be
1109 used to access that type. For keys of type "user", for example, that would be::
1111 <keys/user-type.h>
1113 Note that there are two different types of pointers to keys that may be
1114 encountered:
1116 * struct key *
1118 This simply points to the key structure itself. Key structures will be at
1119 least four-byte aligned.
1121 * key_ref_t
1123 This is equivalent to a ``struct key *``, but the least significant bit is set
1124 if the caller "possesses" the key. By "possession" it is meant that the
1125 calling processes has a searchable link to the key from one of its
1126 keyrings. There are three functions for dealing with these::
1128 key_ref_t make_key_ref(const struct key *key, bool possession);
1130 struct key *key_ref_to_ptr(const key_ref_t key_ref);
1132 bool is_key_possessed(const key_ref_t key_ref);
1134 The first function constructs a key reference from a key pointer and
1135 possession information (which must be true or false).
1137 The second function retrieves the key pointer from a reference and the
1138 third retrieves the possession flag.
1140 When accessing a key's payload contents, certain precautions must be taken to
1141 prevent access vs modification races. See the section "Notes on accessing
1142 payload contents" for more information.
1144 * To search for a key, call::
1146 struct key *request_key(const struct key_type *type,
1147 const char *description,
1148 const char *callout_info);
1150 This is used to request a key or keyring with a description that matches
1151 the description specified according to the key type's match_preparse()
1152 method. This permits approximate matching to occur. If callout_string is
1153 not NULL, then /sbin/request-key will be invoked in an attempt to obtain
1154 the key from userspace. In that case, callout_string will be passed as an
1155 argument to the program.
1157 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
1158 returned.
1160 If successful, the key will have been attached to the default keyring for
1161 implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
1163 See also Documentation/security/keys/request-key.rst.
1166 * To search for a key in a specific domain, call::
1168 struct key *request_key_tag(const struct key_type *type,
1169 const char *description,
1170 struct key_tag *domain_tag,
1171 const char *callout_info);
1173 This is identical to request_key(), except that a domain tag may be
1174 specifies that causes search algorithm to only match keys matching that
1175 tag. The domain_tag may be NULL, specifying a global domain that is
1176 separate from any nominated domain.
1179 * To search for a key, passing auxiliary data to the upcaller, call::
1181 struct key *request_key_with_auxdata(const struct key_type *type,
1182 const char *description,
1183 struct key_tag *domain_tag,
1184 const void *callout_info,
1185 size_t callout_len,
1186 void *aux);
1188 This is identical to request_key_tag(), except that the auxiliary data is
1189 passed to the key_type->request_key() op if it exists, and the
1190 callout_info is a blob of length callout_len, if given (the length may be
1191 0).
1194 * To search for a key under RCU conditions, call::
1196 struct key *request_key_rcu(const struct key_type *type,
1197 const char *description,
1198 struct key_tag *domain_tag);
1200 which is similar to request_key_tag() except that it does not check for
1201 keys that are under construction and it will not call out to userspace to
1202 construct a key if it can't find a match.
1205 * When it is no longer required, the key should be released using::
1207 void key_put(struct key *key);
1209 Or::
1211 void key_ref_put(key_ref_t key_ref);
1213 These can be called from interrupt context. If CONFIG_KEYS is not set then
1214 the argument will not be parsed.
1217 * Extra references can be made to a key by calling one of the following
1218 functions::
1220 struct key *__key_get(struct key *key);
1221 struct key *key_get(struct key *key);
1223 Keys so references will need to be disposed of by calling key_put() when
1224 they've been finished with. The key pointer passed in will be returned.
1226 In the case of key_get(), if the pointer is NULL or CONFIG_KEYS is not set
1227 then the key will not be dereferenced and no increment will take place.
1230 * A key's serial number can be obtained by calling::
1232 key_serial_t key_serial(struct key *key);
1234 If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the
1235 latter case without parsing the argument).
1238 * If a keyring was found in the search, this can be further searched by::
1240 key_ref_t keyring_search(key_ref_t keyring_ref,
1241 const struct key_type *type,
1242 const char *description,
1243 bool recurse)
1245 This searches the specified keyring only (recurse == false) or keyring tree
1246 (recurse == true) specified for a matching key. Error ENOKEY is returned
1247 upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned
1248 key will need to be released.
1250 The possession attribute from the keyring reference is used to control
1251 access through the permissions mask and is propagated to the returned key
1252 reference pointer if successful.
1255 * A keyring can be created by::
1257 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
1258 const struct cred *cred,
1259 key_perm_t perm,
1260 struct key_restriction *restrict_link,
1261 unsigned long flags,
1262 struct key *dest);
1264 This creates a keyring with the given attributes and returns it. If dest
1265 is not NULL, the new keyring will be linked into the keyring to which it
1266 points. No permission checks are made upon the destination keyring.
1268 Error EDQUOT can be returned if the keyring would overload the quota (pass
1269 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
1270 towards the user's quota). Error ENOMEM can also be returned.
1272 If restrict_link is not NULL, it should point to a structure that contains
1273 the function that will be called each time an attempt is made to link a
1274 key into the new keyring. The structure may also contain a key pointer
1275 and an associated key type. The function is called to check whether a key
1276 may be added into the keyring or not. The key type is used by the garbage
1277 collector to clean up function or data pointers in this structure if the
1278 given key type is unregistered. Callers of key_create_or_update() within
1279 the kernel can pass KEY_ALLOC_BYPASS_RESTRICTION to suppress the check.
1280 An example of using this is to manage rings of cryptographic keys that are
1281 set up when the kernel boots where userspace is also permitted to add keys
1282 - provided they can be verified by a key the kernel already has.
1284 When called, the restriction function will be passed the keyring being
1285 added to, the key type, the payload of the key being added, and data to be
1286 used in the restriction check. Note that when a new key is being created,
1287 this is called between payload preparsing and actual key creation. The
1288 function should return 0 to allow the link or an error to reject it.
1290 A convenience function, restrict_link_reject, exists to always return
1291 -EPERM to in this case.
1294 * To check the validity of a key, this function can be called::
1296 int validate_key(struct key *key);
1298 This checks that the key in question hasn't expired or and hasn't been
1299 revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will
1300 be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be
1301 returned (in the latter case without parsing the argument).
1304 * To register a key type, the following function should be called::
1306 int register_key_type(struct key_type *type);
1308 This will return error EEXIST if a type of the same name is already
1309 present.
1312 * To unregister a key type, call::
1314 void unregister_key_type(struct key_type *type);
1317 Under some circumstances, it may be desirable to deal with a bundle of keys.
1318 The facility provides access to the keyring type for managing such a bundle::
1320 struct key_type key_type_keyring;
1322 This can be used with a function such as request_key() to find a specific
1323 keyring in a process's keyrings. A keyring thus found can then be searched
1324 with keyring_search(). Note that it is not possible to use request_key() to
1325 search a specific keyring, so using keyrings in this way is of limited utility.
1328 Notes On Accessing Payload Contents
1329 ===================================
1331 The simplest payload is just data stored in key->payload directly. In this
1332 case, there's no need to indulge in RCU or locking when accessing the payload.
1334 More complex payload contents must be allocated and pointers to them set in the
1335 key->payload.data[] array. One of the following ways must be selected to
1336 access the data:
1338 1) Unmodifiable key type.
1340 If the key type does not have a modify method, then the key's payload can
1341 be accessed without any form of locking, provided that it's known to be
1342 instantiated (uninstantiated keys cannot be "found").
1344 2) The key's semaphore.
1346 The semaphore could be used to govern access to the payload and to control
1347 the payload pointer. It must be write-locked for modifications and would
1348 have to be read-locked for general access. The disadvantage of doing this
1349 is that the accessor may be required to sleep.
1351 3) RCU.
1353 RCU must be used when the semaphore isn't already held; if the semaphore
1354 is held then the contents can't change under you unexpectedly as the
1355 semaphore must still be used to serialise modifications to the key. The
1356 key management code takes care of this for the key type.
1358 However, this means using::
1360 rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
1362 to read the pointer, and::
1364 rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
1366 to set the pointer and dispose of the old contents after a grace period.
1367 Note that only the key type should ever modify a key's payload.
1369 Furthermore, an RCU controlled payload must hold a struct rcu_head for the
1370 use of call_rcu() and, if the payload is of variable size, the length of
1371 the payload. key->datalen cannot be relied upon to be consistent with the
1372 payload just dereferenced if the key's semaphore is not held.
1374 Note that key->payload.data[0] has a shadow that is marked for __rcu
1375 usage. This is called key->payload.rcu_data0. The following accessors
1376 wrap the RCU calls to this element:
1378 a) Set or change the first payload pointer::
1380 rcu_assign_keypointer(struct key *key, void *data);
1382 b) Read the first payload pointer with the key semaphore held::
1384 [const] void *dereference_key_locked([const] struct key *key);
1386 Note that the return value will inherit its constness from the key
1387 parameter. Static analysis will give an error if it things the lock
1388 isn't held.
1390 c) Read the first payload pointer with the RCU read lock held::
1392 const void *dereference_key_rcu(const struct key *key);
1395 Defining a Key Type
1396 ===================
1398 A kernel service may want to define its own key type. For instance, an AFS
1399 filesystem might want to define a Kerberos 5 ticket key type. To do this, it
1400 author fills in a key_type struct and registers it with the system.
1402 Source files that implement key types should include the following header file::
1404 <linux/key-type.h>
1406 The structure has a number of fields, some of which are mandatory:
1408 * ``const char *name``
1410 The name of the key type. This is used to translate a key type name
1411 supplied by userspace into a pointer to the structure.
1414 * ``size_t def_datalen``
1416 This is optional - it supplies the default payload data length as
1417 contributed to the quota. If the key type's payload is always or almost
1418 always the same size, then this is a more efficient way to do things.
1420 The data length (and quota) on a particular key can always be changed
1421 during instantiation or update by calling::
1423 int key_payload_reserve(struct key *key, size_t datalen);
1425 With the revised data length. Error EDQUOT will be returned if this is not
1426 viable.
1429 * ``int (*vet_description)(const char *description);``
1431 This optional method is called to vet a key description. If the key type
1432 doesn't approve of the key description, it may return an error, otherwise
1433 it should return 0.
1436 * ``int (*preparse)(struct key_preparsed_payload *prep);``
1438 This optional method permits the key type to attempt to parse payload
1439 before a key is created (add key) or the key semaphore is taken (update or
1440 instantiate key). The structure pointed to by prep looks like::
1442 struct key_preparsed_payload {
1443 char *description;
1444 union key_payload payload;
1445 const void *data;
1446 size_t datalen;
1447 size_t quotalen;
1448 time_t expiry;
1449 };
1451 Before calling the method, the caller will fill in data and datalen with
1452 the payload blob parameters; quotalen will be filled in with the default
1453 quota size from the key type; expiry will be set to TIME_T_MAX and the
1454 rest will be cleared.
1456 If a description can be proposed from the payload contents, that should be
1457 attached as a string to the description field. This will be used for the
1458 key description if the caller of add_key() passes NULL or "".
1460 The method can attach anything it likes to payload. This is merely passed
1461 along to the instantiate() or update() operations. If set, the expiry
1462 time will be applied to the key if it is instantiated from this data.
1464 The method should return 0 if successful or a negative error code
1465 otherwise.
1468 * ``void (*free_preparse)(struct key_preparsed_payload *prep);``
1470 This method is only required if the preparse() method is provided,
1471 otherwise it is unused. It cleans up anything attached to the description
1472 and payload fields of the key_preparsed_payload struct as filled in by the
1473 preparse() method. It will always be called after preparse() returns
1474 successfully, even if instantiate() or update() succeed.
1477 * ``int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);``
1479 This method is called to attach a payload to a key during construction.
1480 The payload attached need not bear any relation to the data passed to this
1481 function.
1483 The prep->data and prep->datalen fields will define the original payload
1484 blob. If preparse() was supplied then other fields may be filled in also.
1486 If the amount of data attached to the key differs from the size in
1487 keytype->def_datalen, then key_payload_reserve() should be called.
1489 This method does not have to lock the key in order to attach a payload.
1490 The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
1491 anything else from gaining access to the key.
1493 It is safe to sleep in this method.
1495 generic_key_instantiate() is provided to simply copy the data from
1496 prep->payload.data[] to key->payload.data[], with RCU-safe assignment on
1497 the first element. It will then clear prep->payload.data[] so that the
1498 free_preparse method doesn't release the data.
1501 * ``int (*update)(struct key *key, const void *data, size_t datalen);``
1503 If this type of key can be updated, then this method should be provided.
1504 It is called to update a key's payload from the blob of data provided.
1506 The prep->data and prep->datalen fields will define the original payload
1507 blob. If preparse() was supplied then other fields may be filled in also.
1509 key_payload_reserve() should be called if the data length might change
1510 before any changes are actually made. Note that if this succeeds, the type
1511 is committed to changing the key because it's already been altered, so all
1512 memory allocation must be done first.
1514 The key will have its semaphore write-locked before this method is called,
1515 but this only deters other writers; any changes to the key's payload must
1516 be made under RCU conditions, and call_rcu() must be used to dispose of
1517 the old payload.
1519 key_payload_reserve() should be called before the changes are made, but
1520 after all allocations and other potentially failing function calls are
1521 made.
1523 It is safe to sleep in this method.
1526 * ``int (*match_preparse)(struct key_match_data *match_data);``
1528 This method is optional. It is called when a key search is about to be
1529 performed. It is given the following structure::
1531 struct key_match_data {
1532 bool (*cmp)(const struct key *key,
1533 const struct key_match_data *match_data);
1534 const void *raw_data;
1535 void *preparsed;
1536 unsigned lookup_type;
1537 };
1539 On entry, raw_data will be pointing to the criteria to be used in matching
1540 a key by the caller and should not be modified. ``(*cmp)()`` will be pointing
1541 to the default matcher function (which does an exact description match
1542 against raw_data) and lookup_type will be set to indicate a direct lookup.
1544 The following lookup_type values are available:
1546 * KEYRING_SEARCH_LOOKUP_DIRECT - A direct lookup hashes the type and
1547 description to narrow down the search to a small number of keys.
1549 * KEYRING_SEARCH_LOOKUP_ITERATE - An iterative lookup walks all the
1550 keys in the keyring until one is matched. This must be used for any
1551 search that's not doing a simple direct match on the key description.
1553 The method may set cmp to point to a function of its choice that does some
1554 other form of match, may set lookup_type to KEYRING_SEARCH_LOOKUP_ITERATE
1555 and may attach something to the preparsed pointer for use by ``(*cmp)()``.
1556 ``(*cmp)()`` should return true if a key matches and false otherwise.
1558 If preparsed is set, it may be necessary to use the match_free() method to
1559 clean it up.
1561 The method should return 0 if successful or a negative error code
1562 otherwise.
1564 It is permitted to sleep in this method, but ``(*cmp)()`` may not sleep as
1565 locks will be held over it.
1567 If match_preparse() is not provided, keys of this type will be matched
1568 exactly by their description.
1571 * ``void (*match_free)(struct key_match_data *match_data);``
1573 This method is optional. If given, it called to clean up
1574 match_data->preparsed after a successful call to match_preparse().
1577 * ``void (*revoke)(struct key *key);``
1579 This method is optional. It is called to discard part of the payload
1580 data upon a key being revoked. The caller will have the key semaphore
1581 write-locked.
1583 It is safe to sleep in this method, though care should be taken to avoid
1584 a deadlock against the key semaphore.
1587 * ``void (*destroy)(struct key *key);``
1589 This method is optional. It is called to discard the payload data on a key
1590 when it is being destroyed.
1592 This method does not need to lock the key to access the payload; it can
1593 consider the key as being inaccessible at this time. Note that the key's
1594 type may have been changed before this function is called.
1596 It is not safe to sleep in this method; the caller may hold spinlocks.
1599 * ``void (*describe)(const struct key *key, struct seq_file *p);``
1601 This method is optional. It is called during /proc/keys reading to
1602 summarise a key's description and payload in text form.
1604 This method will be called with the RCU read lock held. rcu_dereference()
1605 should be used to read the payload pointer if the payload is to be
1606 accessed. key->datalen cannot be trusted to stay consistent with the
1607 contents of the payload.
1609 The description will not change, though the key's state may.
1611 It is not safe to sleep in this method; the RCU read lock is held by the
1612 caller.
1615 * ``long (*read)(const struct key *key, char __user *buffer, size_t buflen);``
1617 This method is optional. It is called by KEYCTL_READ to translate the
1618 key's payload into something a blob of data for userspace to deal with.
1619 Ideally, the blob should be in the same format as that passed in to the
1620 instantiate and update methods.
1622 If successful, the blob size that could be produced should be returned
1623 rather than the size copied.
1625 This method will be called with the key's semaphore read-locked. This will
1626 prevent the key's payload changing. It is not necessary to use RCU locking
1627 when accessing the key's payload. It is safe to sleep in this method, such
1628 as might happen when the userspace buffer is accessed.
1631 * ``int (*request_key)(struct key_construction *cons, const char *op, void *aux);``
1633 This method is optional. If provided, request_key() and friends will
1634 invoke this function rather than upcalling to /sbin/request-key to operate
1635 upon a key of this type.
1637 The aux parameter is as passed to request_key_async_with_auxdata() and
1638 similar or is NULL otherwise. Also passed are the construction record for
1639 the key to be operated upon and the operation type (currently only
1640 "create").
1642 This method is permitted to return before the upcall is complete, but the
1643 following function must be called under all circumstances to complete the
1644 instantiation process, whether or not it succeeds, whether or not there's
1645 an error::
1647 void complete_request_key(struct key_construction *cons, int error);
1649 The error parameter should be 0 on success, -ve on error. The
1650 construction record is destroyed by this action and the authorisation key
1651 will be revoked. If an error is indicated, the key under construction
1652 will be negatively instantiated if it wasn't already instantiated.
1654 If this method returns an error, that error will be returned to the
1655 caller of request_key*(). complete_request_key() must be called prior to
1656 returning.
1658 The key under construction and the authorisation key can be found in the
1659 key_construction struct pointed to by cons:
1661 * ``struct key *key;``
1663 The key under construction.
1665 * ``struct key *authkey;``
1667 The authorisation key.
1670 * ``struct key_restriction *(*lookup_restriction)(const char *params);``
1672 This optional method is used to enable userspace configuration of keyring
1673 restrictions. The restriction parameter string (not including the key type
1674 name) is passed in, and this method returns a pointer to a key_restriction
1675 structure containing the relevant functions and data to evaluate each
1676 attempted key link operation. If there is no match, -EINVAL is returned.
1679 * ``asym_eds_op`` and ``asym_verify_signature``::
1681 int (*asym_eds_op)(struct kernel_pkey_params *params,
1682 const void *in, void *out);
1683 int (*asym_verify_signature)(struct kernel_pkey_params *params,
1684 const void *in, const void *in2);
1686 These methods are optional. If provided the first allows a key to be
1687 used to encrypt, decrypt or sign a blob of data, and the second allows a
1688 key to verify a signature.
1690 In all cases, the following information is provided in the params block::
1692 struct kernel_pkey_params {
1693 struct key *key;
1694 const char *encoding;
1695 const char *hash_algo;
1696 char *info;
1697 __u32 in_len;
1698 union {
1699 __u32 out_len;
1700 __u32 in2_len;
1701 };
1702 enum kernel_pkey_operation op : 8;
1703 };
1705 This includes the key to be used; a string indicating the encoding to use
1706 (for instance, "pkcs1" may be used with an RSA key to indicate
1707 RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding or "raw" if no encoding);
1708 the name of the hash algorithm used to generate the data for a signature
1709 (if appropriate); the sizes of the input and output (or second input)
1710 buffers; and the ID of the operation to be performed.
1712 For a given operation ID, the input and output buffers are used as
1713 follows::
1715 Operation ID in,in_len out,out_len in2,in2_len
1716 ======================= =============== =============== ===============
1717 kernel_pkey_encrypt Raw data Encrypted data -
1718 kernel_pkey_decrypt Encrypted data Raw data -
1719 kernel_pkey_sign Raw data Signature -
1720 kernel_pkey_verify Raw data - Signature
1722 asym_eds_op() deals with encryption, decryption and signature creation as
1723 specified by params->op. Note that params->op is also set for
1724 asym_verify_signature().
1726 Encrypting and signature creation both take raw data in the input buffer
1727 and return the encrypted result in the output buffer. Padding may have
1728 been added if an encoding was set. In the case of signature creation,
1729 depending on the encoding, the padding created may need to indicate the
1730 digest algorithm - the name of which should be supplied in hash_algo.
1732 Decryption takes encrypted data in the input buffer and returns the raw
1733 data in the output buffer. Padding will get checked and stripped off if
1734 an encoding was set.
1736 Verification takes raw data in the input buffer and the signature in the
1737 second input buffer and checks that the one matches the other. Padding
1738 will be validated. Depending on the encoding, the digest algorithm used
1739 to generate the raw data may need to be indicated in hash_algo.
1741 If successful, asym_eds_op() should return the number of bytes written
1742 into the output buffer. asym_verify_signature() should return 0.
1744 A variety of errors may be returned, including EOPNOTSUPP if the operation
1745 is not supported; EKEYREJECTED if verification fails; ENOPKG if the
1746 required crypto isn't available.
1749 * ``asym_query``::
1751 int (*asym_query)(const struct kernel_pkey_params *params,
1752 struct kernel_pkey_query *info);
1754 This method is optional. If provided it allows information about the
1755 public or asymmetric key held in the key to be determined.
1757 The parameter block is as for asym_eds_op() and co. but in_len and out_len
1758 are unused. The encoding and hash_algo fields should be used to reduce
1759 the returned buffer/data sizes as appropriate.
1761 If successful, the following information is filled in::
1763 struct kernel_pkey_query {
1764 __u32 supported_ops;
1765 __u32 key_size;
1766 __u16 max_data_size;
1767 __u16 max_sig_size;
1768 __u16 max_enc_size;
1769 __u16 max_dec_size;
1770 };
1772 The supported_ops field will contain a bitmask indicating what operations
1773 are supported by the key, including encryption of a blob, decryption of a
1774 blob, signing a blob and verifying the signature on a blob. The following
1775 constants are defined for this::
1777 KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
1779 The key_size field is the size of the key in bits. max_data_size and
1780 max_sig_size are the maximum raw data and signature sizes for creation and
1781 verification of a signature; max_enc_size and max_dec_size are the maximum
1782 raw data and signature sizes for encryption and decryption. The
1783 max_*_size fields are measured in bytes.
1785 If successful, 0 will be returned. If the key doesn't support this,
1786 EOPNOTSUPP will be returned.
1789 Request-Key Callback Service
1790 ============================
1792 To create a new key, the kernel will attempt to execute the following command
1793 line::
1795 /sbin/request-key create <key> <uid> <gid> \
1796 <threadring> <processring> <sessionring> <callout_info>
1798 <key> is the key being constructed, and the three keyrings are the process
1799 keyrings from the process that caused the search to be issued. These are
1800 included for two reasons:
1802 1 There may be an authentication token in one of the keyrings that is
1803 required to obtain the key, eg: a Kerberos Ticket-Granting Ticket.
1805 2 The new key should probably be cached in one of these rings.
1807 This program should set it UID and GID to those specified before attempting to
1808 access any more keys. It may then look around for a user specific process to
1809 hand the request off to (perhaps a path held in placed in another key by, for
1810 example, the KDE desktop manager).
1812 The program (or whatever it calls) should finish construction of the key by
1813 calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to
1814 cache the key in one of the keyrings (probably the session ring) before
1815 returning. Alternatively, the key can be marked as negative with KEYCTL_NEGATE
1816 or KEYCTL_REJECT; this also permits the key to be cached in one of the
1817 keyrings.
1819 If it returns with the key remaining in the unconstructed state, the key will
1820 be marked as being negative, it will be added to the session keyring, and an
1821 error will be returned to the key requestor.
1823 Supplementary information may be provided from whoever or whatever invoked this
1824 service. This will be passed as the <callout_info> parameter. If no such
1825 information was made available, then "-" will be passed as this parameter
1826 instead.
1829 Similarly, the kernel may attempt to update an expired or a soon to expire key
1830 by executing::
1832 /sbin/request-key update <key> <uid> <gid> \
1833 <threadring> <processring> <sessionring>
1835 In this case, the program isn't required to actually attach the key to a ring;
1836 the rings are provided for reference.
1839 Garbage Collection
1840 ==================
1842 Dead keys (for which the type has been removed) will be automatically unlinked
1843 from those keyrings that point to them and deleted as soon as possible by a
1844 background garbage collector.
1846 Similarly, revoked and expired keys will be garbage collected, but only after a
1847 certain amount of time has passed. This time is set as a number of seconds in::
1849 /proc/sys/kernel/keys/gc_delay

3. 한국어 전문 번역

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

키 보존 서비스와 CONFIG_KEYS

1-21

커널 키 보존 서비스는 암호화 키, 인증 토큰, 도메인 간 사용자 매핑 등을 커널에 캐시해 파일 시스템과 다른 커널 서비스가 사용하게 한다. 다른 키로 향하는 링크를 담는 특수 키인 keyring을 지원하며, 각 프로세스는 커널 서비스가 관련 키를 검색할 수 있는 세 표준 keyring 구독을 가진다.

기능은 `Security options`의 `Enable access key retention support`, 즉 `CONFIG_KEYS`로 활성화한다. 이 문서는 키 모델, 사용자 공간 API, 커널 서비스와 key type, request-key callback, garbage collection까지 다룬다.

============================
Kernel Key Retention Service
============================

This service allows cryptographic keys, authentication tokens, cross-domain
user mappings, and similar to be cached in the kernel for the use of
filesystems and other kernel services.

Keyrings are permitted; these are a special type of key that can hold links to
other keys. Processes each have three standard keyring subscriptions that a
kernel service can search for relevant keys.

The key service can be configured on by enabling:

        "Security options"/"Enable access key retention support" (CONFIG_KEYS)

This document has the following sections:

.. contents:: :local:

struct key의 속성과 상태

22-108

이 문맥에서 key는 암호 데이터, 인증 토큰, keyring 등의 단위이며 커널에서는 `struct key`로 표현된다. 각 key에는 serial number, type, 검색용 description, 접근 제어 정보, 만료 시각, payload, 상태가 있다. `key_serial_t` serial은 key 수명 동안 고유한 양의 0이 아닌 32비트 정수이며 사용자 공간은 권한 검사 아래 이 번호로 key를 참조한다.

key type은 해당 종류의 key가 추가·사용되기 전에 파일 시스템 같은 커널 서비스가 `struct key_type`으로 등록해야 하며 사용자 공간은 새 type을 직접 정의할 수 없다. type이 제거되면 그 type의 모든 key가 invalidated된다. printable description은 type별 match 연산으로 검색 기준 문자열과 비교한다. owner UID, group ID, permission mask는 사용자 공간 연산과 커널 검색 가능 여부를 통제한다.

type의 instantiate 함수는 key를 특정 시각에 만료되게 하거나 immortal로 둘 수 있고 입력 blob에서 payload를 만든다. payload는 keyring의 링크 목록이나 user key의 임의 blob일 수 있으며 없어도 되고 `struct key` 안의 값일 수도 있다. read 연산은 내부 payload를 사용자 공간 blob으로 변환한다.

상태는 payload가 없는 `Uninstantiated`, 정상 완성 상태인 `Instantiated`, 사용자 공간 요청 실패를 잠시 기록해 검색을 throttle하는 `Negative`, lifetime이 지난 `Expired`, 사용자 동작으로 더 이상 검색·연산할 수 없는 `Revoked`, type unregister로 쓸 수 없어진 `Dead`가 있다. Negative와 Expired는 update로 정상 상태가 될 수 있고, Expired·Revoked·Dead는 garbage collection 대상이다.

Key 상태
상태의미복구 또는 처리
Uninstantiated객체만 있고 payload 없음instantiate 또는 자동 negative
Instantiated정상 payload 보유일반 사용
Negative이전 user-space 요청 실패 cacheupdate 가능
Expiredlifetime 초과update 가능, GC 대상
Revoked사용자가 폐기unlink만 가능, GC 대상
Deadtype unregisterGC 대상

키 생성·요청·만료·폐기의 주요 상태다.

Key Overview
============

In this context, keys represent units of cryptographic data, authentication
tokens, keyrings, etc.. These are represented in the kernel by struct key.

Each key has a number of attributes:

        - A serial number.
        - A type.
        - A description (for matching a key in a search).
        - Access control information.
        - An expiry time.
        - A payload.
        - State.


  *  Each key is issued a serial number of type key_serial_t that is unique for
     the lifetime of that key. All serial numbers are positive non-zero 32-bit
     integers.

     Userspace programs can use a key's serial numbers as a way to gain access
     to it, subject to permission checking.

  *  Each key is of a defined "type". Types must be registered inside the
     kernel by a kernel service (such as a filesystem) before keys of that type
     can be added or used. Userspace programs cannot define new types directly.

     Key types are represented in the kernel by struct key_type. This defines a
     number of operations that can be performed on a key of that type.

     Should a type be removed from the system, all the keys of that type will
     be invalidated.

  *  Each key has a description. This should be a printable string. The key
     type provides an operation to perform a match between the description on a
     key and a criterion string.

  *  Each key has an owner user ID, a group ID and a permissions mask. These
     are used to control what a process may do to a key from userspace, and
     whether a kernel service will be able to find the key.

  *  Each key can be set to expire at a specific time by the key type's
     instantiation function. Keys can also be immortal.

  *  Each key can have a payload. This is a quantity of data that represent the
     actual "key". In the case of a keyring, this is a list of keys to which
     the keyring links; in the case of a user-defined key, it's an arbitrary
     blob of data.

     Having a payload is not required; and the payload can, in fact, just be a
     value stored in the struct key itself.

     When a key is instantiated, the key type's instantiation function is
     called with a blob of data, and that then creates the key's payload in
     some way.

     Similarly, when userspace wants to read back the contents of the key, if
     permitted, another key type operation will be called to convert the key's
     attached payload back into a blob of data.

  *  Each key can be in one of a number of basic states:

      *  Uninstantiated. The key exists, but does not have any data attached.
              Keys being requested from userspace will be in this state.

      *  Instantiated. This is the normal state. The key is fully formed, and
         has data attached.

      *  Negative. This is a relatively short-lived state. The key acts as a
         note saying that a previous call out to userspace failed, and acts as
         a throttle on key lookups. A negative key can be updated to a normal
         state.

      *  Expired. Keys can have lifetimes set. If their lifetime is exceeded,
         they traverse to this state. An expired key can be updated back to a
         normal state.

      *  Revoked. A key is put in this state by userspace action. It can't be
         found or operated upon (apart from by unlinking it).

      *  Dead. The key's type was unregistered, and so the key is now useless.

Keys in the last three states are subject to garbage collection.  See the
section on "Garbage collection".

표준 key type, 프로세스 keyring과 quota

109-197

서비스는 `keyring`, `user`, `logon` 세 특수 type을 정의한다. `keyring`은 다른 key 링크 목록이며 system call로 수정하고 생성 payload를 주지 않는다. `user`는 임의 description과 payload blob을 사용자 공간이 생성·update·read하며 커널 서비스용은 아니다. `logon`은 kernel이 읽고 사용자 공간은 읽지 못하는 secret 저장소다. description은 길이 0이 아닌 subclass와 `:` 접두사가 필요하며 사용자 공간은 생성·update할 수 있다.

각 프로세스는 thread·process·session keyring을 구독한다. thread keyring은 clone·fork·vfork·execve 때 자식에서 버리고 필요할 때 새로 만든다. process keyring은 `CLONE_THREAD`이면 공유하지만 그 밖의 clone·fork·vfork에서는 자식이 빈 keyring으로 교체하고 execve도 새로 만든다. session keyring은 set-UID/set-GID 실행을 포함해 이 연산들을 넘어 유지되며 `PR_JOIN_SESSION_KEYRING`으로 익명 또는 이름 있는 keyring을 만들거나 join할 수 있다. 실제 UID/GID가 바뀌면 thread keyring 소유권도 바뀐다.

시스템에 존재하는 각 UID는 user-specific keyring과 default user session keyring을 가지며 후자는 전자로의 링크로 초기화된다. session key가 없던 프로세스가 실제 UID를 바꾸거나 session key에 접근하면 현재 UID의 기본 session keyring을 구독한다.

사용자별 quota는 소유한 key·keyring 수와 description·payload 총 바이트를 제한한다. process·thread keyring은 quota에 세지 않는다. 수정 연산이 한도를 넘으면 `EDQUOT`다. 상태와 통계는 procfs에서 보고 root는 sysctl로 한도를 바꾼다. 사용자 공간 system call, 커널 type 등록·검색, 찾지 못한 key의 사용자 공간 callback, 선택적 key database 파일 시스템도 제공된다.

표준 key type
typepayload사용 주체
keyring다른 key 링크 목록사용자·커널
user임의 blob사용자 공간 read/update
logonsecret blob사용자 공간 생성/update, 커널만 read

내장 type의 payload 공개 범위가 다르다.

프로세스 keyring 수명
keyringclone/fork/vforkexecve
thread자식에서 폐기폐기
processCLONE_THREAD만 공유, 그 외 빈 ring새 ring
session유지set-ID 실행도 유지

fork 계열과 execve에서 구독이 어떻게 변하는지 요약한다.

Key Service Overview
====================

The key service provides a number of features besides keys:

  *  The key service defines three special key types:

     (+) "keyring"

         Keyrings are special keys that contain a list of other keys. Keyring
         lists can be modified using various system calls. Keyrings should not
         be given a payload when created.

     (+) "user"

         A key of this type has a description and a payload that are arbitrary
         blobs of data. These can be created, updated and read by userspace,
         and aren't intended for use by kernel services.

     (+) "logon"

         Like a "user" key, a "logon" key has a payload that is an arbitrary
         blob of data. It is intended as a place to store secrets which are
         accessible to the kernel but not to userspace programs.

         The description can be arbitrary, but must be prefixed with a non-zero
         length string that describes the key "subclass". The subclass is
         separated from the rest of the description by a ':'. "logon" keys can
         be created and updated from userspace, but the payload is only
         readable from kernel space.

  *  Each process subscribes to three keyrings: a thread-specific keyring, a
     process-specific keyring, and a session-specific keyring.

     The thread-specific keyring is discarded from the child when any sort of
     clone, fork, vfork or execve occurs. A new keyring is created only when
     required.

     The process-specific keyring is replaced with an empty one in the child on
     clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
     shared. execve also discards the process's process keyring and creates a
     new one.

     The session-specific keyring is persistent across clone, fork, vfork and
     execve, even when the latter executes a set-UID or set-GID binary. A
     process can, however, replace its current session keyring with a new one
     by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous
     new one, or to attempt to create or join one of a specific name.

     The ownership of the thread keyring changes when the real UID and GID of
     the thread changes.

  *  Each user ID resident in the system holds two special keyrings: a user
     specific keyring and a default user session keyring. The default session
     keyring is initialised with a link to the user-specific keyring.

     When a process changes its real UID, if it used to have no session key, it
     will be subscribed to the default session key for the new UID.

     If a process attempts to access its session key when it doesn't have one,
     it will be subscribed to the default for its current UID.

  *  Each user has two quotas against which the keys they own are tracked. One
     limits the total number of keys and keyrings, the other limits the total
     amount of description and payload space that can be consumed.

     The user can view information on this and other statistics through procfs
     files.  The root user may also alter the quota limits through sysctl files
     (see the section "New procfs files").

     Process-specific and thread-specific keyrings are not counted towards a
     user's quota.

     If a system call that modifies a key or keyring in some way would put the
     user over quota, the operation is refused and error EDQUOT is returned.

  *  There's a system call interface by which userspace programs can create and
     manipulate keys and keyrings.

  *  There's a kernel interface by which services can register types and search
     for keys.

  *  There's a way for the a search done from the kernel to call back to
     userspace to request a key that can't be found in a process's keyrings.

  *  An optional filesystem is available through which the key database can be
     viewed and manipulated.

Possessor·User·Group·Other 권한

198-238

key에는 owner UID, group access ID, permission mask가 있다. mask는 possessor·user·group·other마다 최대 8비트를 두지만 각 집합에서 6비트만 정의된다. `View`는 type·description 같은 속성, `Read`는 payload 또는 keyring 링크 목록, `Write`는 payload instantiate/update나 keyring 링크 추가·제거를 허용한다.

`Search`는 keyring 검색과 key 발견을 허용하며 search 권한이 있는 중첩 keyring으로만 재귀한다. `Link`는 해당 key로 링크를 만들 권한이다. keyring에서 key로 링크하려면 keyring의 Write와 key의 Link가 모두 필요하다. `Set Attribute`는 UID·GID·permission mask 변경을 허용한다. 소유권·그룹·mask 변경은 key owner이거나 sysadmin capability가 있으면 충분하다.

Key 권한 6종
권한허용 동작
Viewtype·description 등 속성 보기
Readpayload 또는 링크 목록 읽기
Writepayload 변경, 링크 추가·제거
Searchkeyring 검색과 재귀
Link해당 key로 링크 생성
Set AttributeUID·GID·permission mask 변경

권한은 possessor·user·group·other 각각에 적용된다.

Key Access Permissions
======================

Keys have an owner user ID, a group access ID, and a permissions mask. The mask
has up to eight bits each for possessor, user, group and other access. Only
six of each set of eight bits are defined. These permissions granted are:

  *  View

     This permits a key or keyring's attributes to be viewed - including key
     type and description.

  *  Read

     This permits a key's payload to be viewed or a keyring's list of linked
     keys.

  *  Write

     This permits a key's payload to be instantiated or updated, or it allows a
     link to be added to or removed from a keyring.

  *  Search

     This permits keyrings to be searched and keys to be found. Searches can
     only recurse into nested keyrings that have search permission set.

  *  Link

     This permits a key or keyring to be linked to. To create a link from a
     keyring to a key, a process must have Write permission on the keyring and
     Link permission on the key.

  *  Set Attribute

     This permits a key's UID, GID and permissions mask to be changed.

For changing the ownership, group ID or permissions mask, being the owner of
the key or having the sysadmin capability is sufficient.

SELinux key class와 keycreate

239-270

SELinux에는 여러 문맥에서 생성된 key에 MAC을 적용하도록 `key` security class가 추가됐다. 문서 시점의 지원은 초기 단계다. 앞의 기본 권한 검사를 모두 수행한 뒤 SELinux 검사를 호출하며 기본 권한 6종도 SELinux에 제공된다.

`/proc/self/attr/keycreate` 값이 SELinux security context이면 새 key에 그 문맥을 붙이고, 아니면 생성 요청 태스크의 현재 문맥을 쓴다. 새 key에 특정 문맥을 지정하려면 key class의 `create` 권한을 명시적으로 받아야 한다. 로그인 프로그램이 login 중 keycreate를 올바르게 초기화한 경우에만 사용자 기본 keyring이 사용자 기본 문맥을 가지며, 아니면 로그인 프로그램 문맥을 가진다.

root의 기본 keyring은 root 로그인 전에 부팅 초기에 생성되므로 default kernel context를 쓴다. 새 thread의 keyring은 해당 thread 문맥, session·process keyring도 각각 연결된 문맥으로 레이블된다.

SELinux Support
===============

The security class "key" has been added to SELinux so that mandatory access
controls can be applied to keys created within various contexts.  This support
is preliminary, and is likely to change quite significantly in the near future.
Currently, all of the basic permissions explained above are provided in SELinux
as well; SELinux is simply invoked after all basic permission checks have been
performed.

The value of the file /proc/self/attr/keycreate influences the labeling of
newly-created keys.  If the contents of that file correspond to an SELinux
security context, then the key will be assigned that context.  Otherwise, the
key will be assigned the current context of the task that invoked the key
creation request.  Tasks must be granted explicit permission to assign a
particular context to newly-created keys, using the "create" permission in the
key security class.

The default keyrings associated with users will be labeled with the default
context of the user if and only if the login programs have been instrumented to
properly initialize keycreate during the login process.  Otherwise, they will
be labeled with the context of the login program itself.

Note, however, that the default keyrings associated with the root user are
labeled with the default kernel context, since they are created early in the
boot process, before root has a chance to log in.

The keyrings associated with new threads are each labeled with the context of
their associated thread, and both session and process keyrings are handled
similarly.

/proc/keys, key-users와 quota sysctl

271-352

`/proc/keys`는 읽는 태스크가 View 권한을 가진 key만 type·description·permission과 함께 나열한다. payload 자체는 볼 수 없지만 요약 정보가 포함될 수 있다. possession 여부와 무관하게 View를 허용한 key만 대상이며 LSM 검사가 추가로 필터링한다. 표의 flag는 `I` instantiated, `R` revoked, `D` dead, `Q` quota 기여, `U` 사용자 공간 callback으로 construction 중, `N` negative를 뜻한다.

`/proc/key-users`는 적어도 하나의 key가 있는 사용자별 추적 자료를 보여 준다. 각 줄은 UID, 구조체 reference count, instantiated/전체 key 수, key 수 quota, byte quota를 기록한다.

root용 한도는 `/proc/sys/kernel/keys/root_maxkeys`와 `root_maxbytes`, non-root 사용자별 한도는 `maxkeys`와 `maxbytes`에 있다. root는 해당 파일에 새 10진 숫자 문자열을 써서 최대 key 수와 총 저장 바이트를 변경할 수 있다.

/proc/keys flag
flag의미
IInstantiated
RRevoked
DDead
Q사용자 quota에 포함
Uupcall construction 중
NNegative key

키 목록의 상태 표식이다.

New ProcFS Files
================

Two files have been added to procfs by which an administrator can find out
about the status of the key service:

  *  /proc/keys

     This lists the keys that are currently viewable by the task reading the
     file, giving information about their type, description and permissions.
     It is not possible to view the payload of the key this way, though some
     information about it may be given.

     The only keys included in the list are those that grant View permission to
     the reading process whether or not it possesses them.  Note that LSM
     security checks are still performed, and may further filter out keys that
     the current process is not authorised to view.

     The contents of the file look like this::

        SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
        00000001 I-----    39 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
        00000002 I-----     2 perm 1f3f0000     0     0 keyring   _uid.0: empty
        00000007 I-----     1 perm 1f3f0000     0     0 keyring   _pid.1: empty
        0000018d I-----     1 perm 1f3f0000     0     0 keyring   _pid.412: empty
        000004d2 I--Q--     1 perm 1f3f0000    32    -1 keyring   _uid.32: 1/4
        000004d3 I--Q--     3 perm 1f3f0000    32    -1 keyring   _uid_ses.32: empty
        00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
        00000893 I--Q-N     1  35s 1f3f0000     0     0 user      metal:silver: 0
        00000894 I--Q--     1  10h 003f0000     0     0 user      metal:gold: 0

     The flags are::

        I        Instantiated
        R        Revoked
        D        Dead
        Q        Contributes to user's quota
        U        Under construction by callback to userspace
        N        Negative key


  *  /proc/key-users

     This file lists the tracking data for each user that has at least one key
     on the system.  Such data includes quota information and statistics::

        [root@andromeda root]# cat /proc/key-users
        0:     46 45/45 1/100 13/10000
        29:     2 2/2 2/100 40/10000
        32:     2 2/2 2/100 40/10000
        38:     2 2/2 2/100 40/10000

     The format of each line is::

        <UID>:                        User ID to which this applies
        <usage>                        Structure refcount
        <inst>/<keys>                Total number of keys and number instantiated
        <keys>/<max>                Key count quota
        <bytes>/<max>                Key size quota


Four new sysctl files have been added also for the purpose of controlling the
quota limits on keys:

  *  /proc/sys/kernel/keys/root_maxkeys
     /proc/sys/kernel/keys/root_maxbytes

     These files hold the maximum number of keys that root may have and the
     maximum total number of bytes of data that root may have stored in those
     keys.

  *  /proc/sys/kernel/keys/maxkeys
     /proc/sys/kernel/keys/maxbytes

     These files hold the maximum number of keys that each non-root user may
     have and the maximum total number of bytes of data that each of those
     users may have stored in their keys.

Root may alter these by writing each new limit as a decimal number string to
the appropriate file.

특수 ID와 add_key()·request_key()

353-442

사용자 공간은 `add_key`, `request_key`, `keyctl` 세 system call로 key를 직접 조작한다. 일반 key는 양의 32비트 serial로 참조하고, 음수 특수 ID `KEY_SPEC_THREAD_KEYRING`(-1), `PROCESS`(-2), `SESSION`(-3), `USER`(-4), `USER_SESSION`(-5), `GROUP`(-6), `REQKEY_AUTH_KEY`(-7)로 현재 프로세스 관련 keyring과 request authorization key를 가리킨다.

`add_key(type, desc, payload, plen, keyring)`는 동일 type·description key가 있으면 Write 권한 아래 update를 시도하며 type이 update를 지원하지 않으면 `EEXIST`다. 없으면 지정 type과 description으로 생성·instantiate하고 keyring에 붙이며 keyring Write가 필요하다. 새 key는 user 권한을 모두 받고 group·other 권한은 없다. type이 지원하면 비어 있는 description을 payload에서 만들 수 있고 payload는 선택적이다. `keyring` type과 NULL payload로 새 keyring, `user` type으로 user key를 만든다. user key description은 Kerberos TGT의 `krb5tgt:`처럼 type ID와 colon 접두사를 권장한다. 성공하면 새 key 또는 update된 key ID를 반환한다.

`request_key(type, description, callout_info, dest_keyring)`는 thread→process→session 순서로 keyring을 검색하며 `KEYCTL_SEARCH`와 같은 방식으로 선택적 destination link를 만든다. 찾지 못하고 callout 정보가 있으면 `/sbin/request-key`를 인자와 함께 실행한다. destination link에는 key의 Link와 keyring의 Write 권한이 모두 필요하며 자세한 내용은 `Documentation/security/keys/request-key.rst`에 있다.

특수 key ID
상수대상
KEY_SPEC_THREAD_KEYRING-1thread keyring
KEY_SPEC_PROCESS_KEYRING-2process keyring
KEY_SPEC_SESSION_KEYRING-3session keyring
KEY_SPEC_USER_KEYRING-4UID keyring
KEY_SPEC_USER_SESSION_KEYRING-5UID session keyring
KEY_SPEC_GROUP_KEYRING-6GID keyring
KEY_SPEC_REQKEY_AUTH_KEY-7request authorization key

현재 프로세스와 관련된 keyring을 음수 상수로 참조한다.

Userspace System Call Interface
===============================

Userspace can manipulate keys directly through three new syscalls: add_key,
request_key and keyctl. The latter provides a number of functions for
manipulating keys.

When referring to a key directly, userspace programs should use the key's
serial number (a positive 32-bit integer). However, there are some special
values available for referring to special keys and keyrings that relate to the
process making the call::

        CONSTANT                        VALUE        KEY REFERENCED
        ==============================        ======        ===========================
        KEY_SPEC_THREAD_KEYRING                -1        thread-specific keyring
        KEY_SPEC_PROCESS_KEYRING        -2        process-specific keyring
        KEY_SPEC_SESSION_KEYRING        -3        session-specific keyring
        KEY_SPEC_USER_KEYRING                -4        UID-specific keyring
        KEY_SPEC_USER_SESSION_KEYRING        -5        UID-session keyring
        KEY_SPEC_GROUP_KEYRING                -6        GID-specific keyring
        KEY_SPEC_REQKEY_AUTH_KEY        -7        assumed request_key()
                                                  authorisation key


The main syscalls are:

  *  Create a new key of given type, description and payload and add it to the
     nominated keyring::

        key_serial_t add_key(const char *type, const char *desc,
                             const void *payload, size_t plen,
                             key_serial_t keyring);

     If a key of the same type and description as that proposed already exists
     in the keyring, this will try to update it with the given payload, or it
     will return error EEXIST if that function is not supported by the key
     type. The process must also have permission to write to the key to be able
     to update it. The new key will have all user permissions granted and no
     group or third party permissions.

     Otherwise, this will attempt to create a new key of the specified type and
     description, and to instantiate it with the supplied payload and attach it
     to the keyring. In this case, an error will be generated if the process
     does not have permission to write to the keyring.

     If the key type supports it, if the description is NULL or an empty
     string, the key type will try and generate a description from the content
     of the payload.

     The payload is optional, and the pointer can be NULL if not required by
     the type. The payload is plen in size, and plen can be zero for an empty
     payload.

     A new keyring can be generated by setting type "keyring", the keyring name
     as the description (or NULL) and setting the payload to NULL.

     User defined keys can be created by specifying type "user". It is
     recommended that a user defined key's description by prefixed with a type
     ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting
     ticket.

     Any other type must have been registered with the kernel in advance by a
     kernel service such as a filesystem.

     The ID of the new or updated key is returned if successful.


  *  Search the process's keyrings for a key, potentially calling out to
     userspace to create it::

        key_serial_t request_key(const char *type, const char *description,
                                 const char *callout_info,
                                 key_serial_t dest_keyring);

     This function searches all the process's keyrings in the order thread,
     process, session for a matching key. This works very much like
     KEYCTL_SEARCH, including the optional attachment of the discovered key to
     a keyring.

     If a key cannot be found, and if callout_info is not NULL, then
     /sbin/request-key will be invoked in an attempt to obtain a key. The
     callout_info string will be passed as an argument to the program.

     To link a key into the destination keyring the key must grant link
     permission on the key to the caller and the keyring must grant write
     permission.

     See also Documentation/security/keys/request-key.rst.

기본 keyctl 연산

443-550

`KEYCTL_GET_KEYRING_ID`는 특수 ID를 실제 ID로 변환하며 key가 없을 때 `create`가 0이 아니면 만들고 0이면 `ENOKEY`다. `KEYCTL_JOIN_SESSION_KEYRING`은 이름이 NULL이면 익명 session keyring, 이름이 있으면 search 권한 아래 기존 ring에 join하거나 새 ring을 만들어 현재 session ring을 교체하고 ID를 반환한다.

`KEYCTL_UPDATE`는 Write 권한 아래 payload를 바꾸며 type이 지원하지 않으면 `EOPNOTSUPP`다. `KEYCTL_REVOKE`는 이후 연산을 `EKEYREVOKED`로 실패시키고 검색되지 않게 한다. `KEYCTL_CHOWN`은 owner·group을 바꾸고 -1은 해당 변경을 생략한다. superuser만 owner를 다른 UID로 바꿀 수 있고 group도 호출자의 group 또는 보조 group 밖으로 바꿀 수 있다. `KEYCTL_SETPERM`은 owner 또는 superuser가 정의된 bit만 설정하며 다른 bit는 `EINVAL`이다.

`KEYCTL_DESCRIBE`는 payload를 제외한 속성을 `<type>;<uid>;<gid>;<perm>;<description>` 문자열로 반환한다. buffer가 작아도 생성 가능한 전체 길이를 반환하고 요청 길이 이상 복사하지 않으며 NULL buffer면 복사하지 않는다. View 권한이 필요하고 충분한 buffer에는 NUL도 포함된다. 원문의 `sscanf()` parse 예제를 보존한다.

기본 keyctl
명령주요 권한 또는 결과
GET_KEYRING_ID특수 ID 변환, 선택적 생성
JOIN_SESSION_KEYRINGsession ring 교체
UPDATEWrite, 미지원 EOPNOTSUPP
REVOKE향후 EKEYREVOKED
CHOWNowner/group 변경
SETPERMowner 또는 superuser
DESCRIBEView, 속성 문자열

식별·session·payload·속성 조작 명령이다.

The keyctl syscall functions are:

  *  Map a special key ID to a real key ID for this process::

        key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
                            int create);

     The special key specified by "id" is looked up (with the key being created
     if necessary) and the ID of the key or keyring thus found is returned if
     it exists.

     If the key does not yet exist, the key will be created if "create" is
     non-zero; and the error ENOKEY will be returned if "create" is zero.


  *  Replace the session keyring this process subscribes to with a new one::

        key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name);

     If name is NULL, an anonymous keyring is created attached to the process
     as its session keyring, displacing the old session keyring.

     If name is not NULL, if a keyring of that name exists, the process
     attempts to attach it as the session keyring, returning an error if that
     is not permitted; otherwise a new keyring of that name is created and
     attached as the session keyring.

     To attach to a named keyring, the keyring must have search permission for
     the process's ownership.

     The ID of the new session keyring is returned if successful.


  *  Update the specified key::

        long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload,
                    size_t plen);

     This will try to update the specified key with the given payload, or it
     will return error EOPNOTSUPP if that function is not supported by the key
     type. The process must also have permission to write to the key to be able
     to update it.

     The payload is of length plen, and may be absent or empty as for
     add_key().


  *  Revoke a key::

        long keyctl(KEYCTL_REVOKE, key_serial_t key);

     This makes a key unavailable for further operations. Further attempts to
     use the key will be met with error EKEYREVOKED, and the key will no longer
     be findable.


  *  Change the ownership of a key::

        long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);

     This function permits a key's owner and group ID to be changed. Either one
     of uid or gid can be set to -1 to suppress that change.

     Only the superuser can change a key's owner to something other than the
     key's current owner. Similarly, only the superuser can change a key's
     group ID to something other than the calling process's group ID or one of
     its group list members.


  *  Change the permissions mask on a key::

        long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm);

     This function permits the owner of a key or the superuser to change the
     permissions mask on a key.

     Only bits the available bits are permitted; if any other bits are set,
     error EINVAL will be returned.


  *  Describe a key::

        long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer,
                    size_t buflen);

     This function returns a summary of the key's attributes (but not its
     payload data) as a string in the buffer provided.

     Unless there's an error, it always returns the amount of data it could
     produce, even if that's too big for the buffer, but it won't copy more
     than requested to userspace. If the buffer pointer is NULL then no copy
     will take place.

     A process must have view permission on the key for this function to be
     successful.

     If successful, a string is placed in the buffer in the following format::

        <type>;<uid>;<gid>;<perm>;<description>

     Where type and description are strings, uid and gid are decimal, and perm
     is hexadecimal. A NUL character is included at the end of the string if
     the buffer is sufficiently big.

     This can be parsed with::

        sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc);

payload read와 positive·negative instantiate

641-712

`KEYCTL_READ`는 Read 권한 아래 type별 표현으로 payload를 buffer에 쓴다. keyring은 연결 key ID의 `key_serial_t` 배열, user type은 원본 데이터를 반환한다. type이 read를 구현하지 않으면 `EOPNOTSUPP`다. buffer가 작으면 필요 크기를 반환하지만 buffer 내용은 정의되지 않게 덮일 수 있고, 성공 시 복사 바이트 수를 반환한다.

사용자 공간 callback으로 부분 생성 key를 완성할 때 `KEYCTL_INSTANTIATE` 또는 iovec 버전 `KEYCTL_INSTANTIATE_IOV`를 호출한다. callback 프로세스가 돌아오기 전에 payload를 제공하지 않으면 자동으로 negative가 된다. uninstantiated key에 대한 Write가 필요하고 destination keyring이 있으면 LINK 제약도 적용된다. 단일 buffer는 `payload`·`plen`, 배열은 `payload_iov`·`ioc`로 설명한다.

요청을 충족할 수 없으면 `KEYCTL_NEGATE` 또는 `KEYCTL_REJECT`로 negative instantiate한다. Write와 uninstantiated 상태가 필요하며 선택적 keyring link도 같은 제약을 따른다. reject된 key는 timeout까지 지정 error를 검색 결과로 돌려주고, negate는 error가 `ENOKEY`인 reject와 같다.

Construction 완료
명령결과
INSTANTIATE단일 buffer payload로 완성
INSTANTIATE_IOViovec payload로 완성
REJECT지정 error를 가진 negative key
NEGATEENOKEY negative key

callback은 성공 또는 실패 상태를 명시해야 한다.

  *  Read the payload data from a key::

        long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
                    size_t buflen);

     This function attempts to read the payload data from the specified key
     into the buffer. The process must have read permission on the key to
     succeed.

     The returned data will be processed for presentation by the key type. For
     instance, a keyring will return an array of key_serial_t entries
     representing the IDs of all the keys to which it is subscribed. The user
     defined key type will return its data as is. If a key type does not
     implement this function, error EOPNOTSUPP will result.

     If the specified buffer is too small, then the size of the buffer required
     will be returned.  Note that in this case, the contents of the buffer may
     have been overwritten in some undefined way.

     Otherwise, on success, the function will return the amount of data copied
     into the buffer.

  *  Instantiate a partially constructed key::

        long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
                    const void *payload, size_t plen,
                    key_serial_t keyring);
        long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key,
                    const struct iovec *payload_iov, unsigned ioc,
                    key_serial_t keyring);

     If the kernel calls back to userspace to complete the instantiation of a
     key, userspace should use this call to supply data for the key before the
     invoked process returns, or else the key will be marked negative
     automatically.

     The process must have write access on the key to be able to instantiate
     it, and the key must be uninstantiated.

     If a keyring is specified (non-zero), the key will also be linked into
     that keyring, however all the constraints applying in KEYCTL_LINK apply in
     this case too.

     The payload and plen arguments describe the payload data as for add_key().

     The payload_iov and ioc arguments describe the payload data in an iovec
     array instead of a single buffer.


  *  Negatively instantiate a partially constructed key::

        long keyctl(KEYCTL_NEGATE, key_serial_t key,
                    unsigned timeout, key_serial_t keyring);
        long keyctl(KEYCTL_REJECT, key_serial_t key,
                    unsigned timeout, unsigned error, key_serial_t keyring);

     If the kernel calls back to userspace to complete the instantiation of a
     key, userspace should use this call mark the key as negative before the
     invoked process returns if it is unable to fulfill the request.

     The process must have write access on the key to be able to instantiate
     it, and the key must be uninstantiated.

     If a keyring is specified (non-zero), the key will also be linked into
     that keyring, however all the constraints applying in KEYCTL_LINK apply in
     this case too.

     If the key is rejected, future searches for it will return the specified
     error code until the rejected key expires.  Negating the key is the same
     as rejecting the key with ENOKEY as the error code.

request destination, timeout과 authority

713-778

`KEYCTL_SET_REQKEY_KEYRING`은 이 thread가 암묵적으로 요청한 key를 붙일 기본 ring을 정한다. 상수는 NO_CHANGE(-1), DEFAULT(0), THREAD(1), PROCESS(2), SESSION(3), USER(4), USER_SESSION(5), GROUP(6)이며 성공하면 이전 기본값, 잘못된 값이면 `EINVAL`이다. `request_key()`의 destination이 이를 덮어쓸 수 있고 설정은 fork·exec를 넘어 상속된다. DEFAULT는 존재하는 thread→process→session→user default session 순서다.

`KEYCTL_SET_TIMEOUT`은 Set Attribute 권한 아래 0으로 timeout을 지우거나 초 단위 미래 expiry를 설정한다. negative·revoked·expired key에는 설정할 수 없다.

`KEYCTL_ASSUME_AUTHORITY`는 특정 key를 instantiate할 권한을 취하거나 내려놓는다. thread keyring 어딘가에 해당 authorization key가 있어야 한다. authority를 취하면 requester의 security label, UID, GID, groups로 requester keyring도 검색한다. 없거나 target이 이미 instantiated되어 authority가 revoke됐으면 `EPERM`; key 0은 현재 authority를 내려놓는다. authority key는 fork와 exec를 넘어 상속된다.

request-key 기본 ring
상수
NO_CHANGE-1
DEFAULT0
THREAD1
PROCESS2
SESSION3
USER4
USER_SESSION5
GROUP6

암묵적 요청 결과를 붙일 위치 상수다.

  *  Set the default request-key destination keyring::

        long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);

     This sets the default keyring to which implicitly requested keys will be
     attached for this thread. reqkey_defl should be one of these constants::

        CONSTANT                                VALUE        NEW DEFAULT KEYRING
        ======================================        ======        =======================
        KEY_REQKEY_DEFL_NO_CHANGE                -1        No change
        KEY_REQKEY_DEFL_DEFAULT                        0        Default[1]
        KEY_REQKEY_DEFL_THREAD_KEYRING                1        Thread keyring
        KEY_REQKEY_DEFL_PROCESS_KEYRING                2        Process keyring
        KEY_REQKEY_DEFL_SESSION_KEYRING                3        Session keyring
        KEY_REQKEY_DEFL_USER_KEYRING                4        User keyring
        KEY_REQKEY_DEFL_USER_SESSION_KEYRING        5        User session keyring
        KEY_REQKEY_DEFL_GROUP_KEYRING                6        Group keyring

     The old default will be returned if successful and error EINVAL will be
     returned if reqkey_defl is not one of the above values.

     The default keyring can be overridden by the keyring indicated to the
     request_key() system call.

     Note that this setting is inherited across fork/exec.

     [1] The default is: the thread keyring if there is one, otherwise
     the process keyring if there is one, otherwise the session keyring if
     there is one, otherwise the user default session keyring.


  *  Set the timeout on a key::

        long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);

     This sets or clears the timeout on a key. The timeout can be 0 to clear
     the timeout or a number of seconds to set the expiry time that far into
     the future.

     The process must have attribute modification access on a key to set its
     timeout. Timeouts may not be set with this function on negative, revoked
     or expired keys.


  *  Assume the authority granted to instantiate a key::

        long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);

     This assumes or divests the authority required to instantiate the
     specified key. Authority can only be assumed if the thread has the
     authorisation key associated with the specified key in its keyrings
     somewhere.

     Once authority is assumed, searches for keys will also search the
     requester's keyrings using the requester's security label, UID, GID and
     groups.

     If the requested authority is unavailable, error EPERM will be returned,
     likewise if the authority has been revoked because the target key is
     already instantiated.

     If the specified key is 0, then any assumed authority will be divested.

     The assumed authoritative key is inherited across fork and exec.

LSM context, parent session과 invalidate

779-835

`KEYCTL_GET_SECURITY`는 key에 붙은 LSM security context 문자열을 반환한다. buffer 크기보다 커도 생성 가능한 전체 크기를 반환하고 NULL이면 복사하지 않는다. 충분한 buffer에서는 NUL이 반환 count에 포함되며 LSM이 없으면 빈 문자열이다. View 권한이 필요하다.

`KEYCTL_SESSION_TO_PARENT`는 호출 프로세스의 session keyring을 parent에 설치해 기존 ring을 교체한다. parent와 caller의 ownership이 같고 keyring도 caller 소유이며 caller에게 Link 권한이 있고 LSM이 허용해야 한다. 위반은 `EPERM`, 메모리 부족은 `ENOMEM`, 성공은 0이며 parent가 다음에 커널에서 사용자 공간으로 돌아갈 때 교체된다.

`KEYCTL_INVALIDATE`는 key를 invalidated로 표시하고 garbage collector를 깨운다. collector는 모든 keyring에서 즉시 unlink하고 reference count가 0이면 삭제한다. 일반 연산에는 즉시 보이지 않지만 삭제 전 `/proc/keys`에는 `i` flag로 남는다. Search 권한이 필요하다.

  *  Get the LSM security context attached to a key::

        long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
                    size_t buflen)

     This function returns a string that represents the LSM security context
     attached to a key in the buffer provided.

     Unless there's an error, it always returns the amount of data it could
     produce, even if that's too big for the buffer, but it won't copy more
     than requested to userspace. If the buffer pointer is NULL then no copy
     will take place.

     A NUL character is included at the end of the string if the buffer is
     sufficiently big.  This is included in the returned count.  If no LSM is
     in force then an empty string will be returned.

     A process must have view permission on the key for this function to be
     successful.


  *  Install the calling process's session keyring on its parent::

        long keyctl(KEYCTL_SESSION_TO_PARENT);

     This functions attempts to install the calling process's session keyring
     on to the calling process's parent, replacing the parent's current session
     keyring.

     The calling process must have the same ownership as its parent, the
     keyring must have the same ownership as the calling process, the calling
     process must have LINK permission on the keyring and the active LSM module
     mustn't deny permission, otherwise error EPERM will be returned.

     Error ENOMEM will be returned if there was insufficient memory to complete
     the operation, otherwise 0 will be returned to indicate success.

     The keyring will be replaced next time the parent process leaves the
     kernel and resumes executing userspace.


  *  Invalidate a key::

        long keyctl(KEYCTL_INVALIDATE, key_serial_t key);

     This function marks a key as being invalidated and then wakes up the
     garbage collector.  The garbage collector immediately removes invalidated
     keys from all keyrings and deletes the key when its reference count
     reaches zero.

     Keys that are marked invalidated become invisible to normal key operations
     immediately, though they are still visible in /proc/keys until deleted
     (they're marked with an 'i' flag).

     A process must have search permission on the key for this function to be
     successful.

Diffie-Hellman과 KDF

836-887

`KEYCTL_DH_COMPUTE`는 prime `p`, local private key, shared generator 또는 remote public key인 base의 세 key serial로 `base ^ private (mod prime)`을 계산한다. base가 generator면 local public key, remote public key면 shared secret이다.

`kdf`가 NULL이면 buffer는 prime 길이 이상이거나 길이 0이어야 한다. 0이 아니면 계산·복사한 결과 길이, 0이면 최소 buffer 길이를 반환한다. `struct keyctl_kdf_params`를 주면 호출자에게 DH 원값 대신 KDF 결과만 반환한다. NUL 종료 `hashname`은 kernel crypto API hash를 정하고 SP800-56A와 SP800-108 counter KDF를 따른다. `otherinfo`와 `otherinfolen`은 SP800-56A 5.8.1.2의 caller-defined OtherInfo이며 사용하지 않으면 NULL이다.

지원하지 않는 type은 `EOPNOTSUPP`, key 없음은 `ENOKEY`, Read 불가는 `EACCES`다. kdf 사용 시 buffer 또는 OtherInfo 길이가 한도를 넘으면 `EMSGSIZE`다.

DH 계산
prime·private·base key 조회base^private mod primegenerator면 local public keyremote public key면 shared secret선택적 SP800 KDF

base의 종류에 따라 public key 또는 shared secret을 얻고 선택적으로 KDF를 적용한다.

  *  Compute a Diffie-Hellman shared secret or public key::

        long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
                    char *buffer, size_t buflen, struct keyctl_kdf_params *kdf);

     The params struct contains serial numbers for three keys::

         - The prime, p, known to both parties
         - The local private key
         - The base integer, which is either a shared generator or the
           remote public key

     The value computed is::

        result = base ^ private (mod prime)

     If the base is the shared generator, the result is the local
     public key.  If the base is the remote public key, the result is
     the shared secret.

     If the parameter kdf is NULL, the following applies:

         - The buffer length must be at least the length of the prime, or zero.

         - If the buffer length is nonzero, the length of the result is
           returned when it is successfully calculated and copied in to the
           buffer. When the buffer length is zero, the minimum required
           buffer length is returned.

     The kdf parameter allows the caller to apply a key derivation function
     (KDF) on the Diffie-Hellman computation where only the result
     of the KDF is returned to the caller. The KDF is characterized with
     struct keyctl_kdf_params as follows:

         - ``char *hashname`` specifies the NUL terminated string identifying
           the hash used from the kernel crypto API and applied for the KDF
           operation. The KDF implementation complies with SP800-56A as well
           as with SP800-108 (the counter KDF).

         - ``char *otherinfo`` specifies the OtherInfo data as documented in
           SP800-56A section 5.8.1.2. The length of the buffer is given with
           otherinfolen. The format of OtherInfo is defined by the caller.
           The otherinfo pointer may be NULL if no OtherInfo shall be used.

     This function will return error EOPNOTSUPP if the key type is not
     supported, error ENOKEY if the key could not be found, or error
     EACCES if the key is not readable by the caller. In addition, the
     function will return EMSGSIZE when the parameter kdf is non-NULL
     and either the buffer length or the OtherInfo length exceeds the
     allowed length.

KEYCTL_RESTRICT_KEYRING

888-918

`KEYCTL_RESTRICT_KEYRING`은 기존 keyring에 앞으로 연결할 key를 restriction scheme으로 제한한다. 기존 링크는 새 제한에 맞지 않아도 유지된다. `type`은 등록된 key type이고 `restriction` 문자열 형식은 type마다 다르며 해당 type의 `lookup_restriction()`에 전달된다. 서명 검증 방식이나 payload 제약을 지정할 수 있다. 이후 type이 unregister되면 새 key를 더 추가할 수 없다.

restriction 적용에는 Set Attribute 권한이 필요하고 이미 제한된 keyring에는 다시 적용할 수 없다. 대표 용도는 asymmetric key type으로 X.509 certificate chain 또는 개별 서명을 검증하는 것이며 세부 제약은 `Documentation/crypto/asymmetric-keys.rst`에 있다.

  *  Restrict keyring linkage::

        long keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring,
                    const char *type, const char *restriction);

     An existing keyring can restrict linkage of additional keys by evaluating
     the contents of the key according to a restriction scheme.

     "keyring" is the key ID for an existing keyring to apply a restriction
     to. It may be empty or may already have keys linked. Existing linked keys
     will remain in the keyring even if the new restriction would reject them.

     "type" is a registered key type.

     "restriction" is a string describing how key linkage is to be restricted.
     The format varies depending on the key type, and the string is passed to
     the lookup_restriction() function for the requested type.  It may specify
     a method and relevant data for the restriction such as signature
     verification or constraints on key payload. If the requested key type is
     later unregistered, no keys may be added to the keyring after the key type
     is removed.

     To apply a keyring restriction the process must have Set Attribute
     permission and the keyring must not be previously restricted.

     One application of restricted keyrings is to verify X.509 certificate
     chains or individual certificate signatures using the asymmetric key type.
     See Documentation/crypto/asymmetric-keys.rst for specific restrictions
     applicable to the asymmetric key type.

Asymmetric key 조회와 암호 연산

919-1032

`KEYCTL_PKEY_QUERY`는 asymmetric key의 알고리즘·encoding 정보를 `params`의 공백 또는 tab 구분 key-value(`enc`, `hash`)로 질의한다. 결과 `keyctl_pkey_query`에는 supported operation bitmask, bit 단위 key size, sign data·signature·encrypt·decrypt 최대 byte 크기와 미래 passphrase 전달용 0으로 채운 `__spare[10]`이 있다. operation bit는 `KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}`의 OR다. 성공 0, asymmetric key가 아니면 `EOPNOTSUPP`다.

`KEYCTL_PKEY_ENCRYPT`, `DECRYPT`, `SIGN`, `VERIFY`는 `keyctl_pkey_params`의 key ID와 input/output/second input 길이를 사용한다. encrypt는 raw→encrypted, decrypt는 encrypted→raw, sign은 raw→signature, verify는 raw와 두 번째 signature를 비교한다. encrypt·verify는 public 부분만으로 가능할 수 있지만 decrypt·sign에는 private 부분도 필요하다.

`info`의 `enc=`는 `pkcs1`(RSASSA/RSAES-PKCS1-v1.5), `pss`(RSASSA-PSS), `oaep`(RSAES-OAEP), 생략 또는 `raw`를 정한다. `hash=`는 입력이 hash 결과이고 encoding이 hash 종류를 담을 때 `sha256` 같은 알고리즘을 지정한다. parameter spare는 0이어야 한다. encrypt·decrypt·sign은 output byte 수, verify는 성공 0을 반환한다.

PKEY buffer 역할
operationinoutin2
ENCRYPTraw dataencrypted data-
DECRYPTencrypted dataraw data-
SIGNraw datasignature-
VERIFYraw data-signature

operation별 입력·출력·두 번째 입력의 의미다.

  *  Query an asymmetric key::

        long keyctl(KEYCTL_PKEY_QUERY,
                    key_serial_t key_id, unsigned long reserved,
                    const char *params,
                    struct keyctl_pkey_query *info);

     Get information about an asymmetric key.  Specific algorithms and
     encodings may be queried by using the ``params`` argument.  This is a
     string containing a space- or tab-separated string of key-value pairs.
     Currently supported keys include ``enc`` and ``hash``.  The information
     is returned in the keyctl_pkey_query struct::

        __u32        supported_ops;
        __u32        key_size;
        __u16        max_data_size;
        __u16        max_sig_size;
        __u16        max_enc_size;
        __u16        max_dec_size;
        __u32        __spare[10];

     ``supported_ops`` contains a bit mask of flags indicating which ops are
     supported.  This is constructed from a bitwise-OR of::

        KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

     ``key_size`` indicated the size of the key in bits.

     ``max_*_size`` indicate the maximum sizes in bytes of a blob of data to be
     signed, a signature blob, a blob to be encrypted and a blob to be
     decrypted.

     ``__spare[]`` must be set to 0.  This is intended for future use to hand
     over one or more passphrases needed unlock a key.

     If successful, 0 is returned.  If the key is not an asymmetric key,
     EOPNOTSUPP is returned.


  *  Encrypt, decrypt, sign or verify a blob using an asymmetric key::

        long keyctl(KEYCTL_PKEY_ENCRYPT,
                    const struct keyctl_pkey_params *params,
                    const char *info,
                    const void *in,
                    void *out);

        long keyctl(KEYCTL_PKEY_DECRYPT,
                    const struct keyctl_pkey_params *params,
                    const char *info,
                    const void *in,
                    void *out);

        long keyctl(KEYCTL_PKEY_SIGN,
                    const struct keyctl_pkey_params *params,
                    const char *info,
                    const void *in,
                    void *out);

        long keyctl(KEYCTL_PKEY_VERIFY,
                    const struct keyctl_pkey_params *params,
                    const char *info,
                    const void *in,
                    const void *in2);

     Use an asymmetric key to perform a public-key cryptographic operation a
     blob of data.  For encryption and verification, the asymmetric key may
     only need the public parts to be available, but for decryption and signing
     the private parts are required also.

     The parameter block pointed to by params contains a number of integer
     values::

        __s32                key_id;
        __u32                in_len;
        __u32                out_len;
        __u32                in2_len;

     ``key_id`` is the ID of the asymmetric key to be used.  ``in_len`` and
     ``in2_len`` indicate the amount of data in the in and in2 buffers and
     ``out_len`` indicates the size of the out buffer as appropriate for the
     above operations.

     For a given operation, the in and out buffers are used as follows::

        Operation ID                in,in_len        out,out_len        in2,in2_len
        =======================        ===============        ===============        ===============
        KEYCTL_PKEY_ENCRYPT        Raw data        Encrypted data        -
        KEYCTL_PKEY_DECRYPT        Encrypted data        Raw data        -
        KEYCTL_PKEY_SIGN        Raw data        Signature        -
        KEYCTL_PKEY_VERIFY        Raw data        -                Signature

     ``info`` is a string of key=value pairs that supply supplementary
     information.  These include:

        ``enc=<encoding>`` The encoding of the encrypted/signature blob.  This
                        can be "pkcs1" for RSASSA-PKCS1-v1.5 or
                        RSAES-PKCS1-v1.5; "pss" for "RSASSA-PSS"; "oaep" for
                        "RSAES-OAEP".  If omitted or is "raw", the raw output
                        of the encryption function is specified.

        ``hash=<algo>``        If the data buffer contains the output of a hash
                        function and the encoding includes some indication of
                        which hash function was used, the hash function can be
                        specified with this, eg. "hash=sha256".

     The ``__spare[]`` space in the parameter block must be set to 0.  This is
     intended, amongst other things, to allow the passing of passphrases
     required to unlock a key.

     If successful, encrypt, decrypt and sign all return the amount of data
     written into the output buffer.  Verification returns 0 on success.

Key 변경 notification

1033-1089

`KEYCTL_WATCH_KEY`는 특정 key 또는 keyring 변경 watch를 설치하거나 제거한다. `key`는 대상 ID, `queue_fd`는 notification buffer를 관리하는 열린 pipe FD, `filter`는 필요한 event 지정 또는 watch 제거용 NULL이다. 자세한 watch queue는 `Documentation/core-api/watch_queue.rst`에 있으며 `{key, queue_fd}` 조합마다 하나만 설치할 수 있다.

`struct key_notification`은 기본 `watch_notification`, `key_id`, `aux`를 담는다. type은 `WATCH_TYPE_KEY_NOTIFY`, subtype은 INSTANTIATED, UPDATED, LINKED, UNLINKED, CLEARED, REVOKED, INVALIDATED, SETATTR 중 하나다. SETATTR에는 user·group·perm·timeout·restriction 변경이 포함된다. watched key 삭제 시 `WATCH_TYPE_META`와 `watch_meta_removal_notification`, info의 watchpoint ID를 보낸다. `KEY_NOTIFICATIONS` 설정이 필요하다.

Key notification subtype
subtype변경
INSTANTIATEDinstantiate 또는 reject
UPDATEDpayload update
LINKED / UNLINKEDkeyring link 변경
CLEAREDkeyring clear
REVOKED / INVALIDATEDkey 폐기
SETATTR소유자·권한·timeout·restriction 변경

watch가 보고하는 변경 종류다.

  *  Watch a key or keyring for changes::

        long keyctl(KEYCTL_WATCH_KEY, key_serial_t key, int queue_fd,
                    const struct watch_notification_filter *filter);

     This will set or remove a watch for changes on the specified key or
     keyring.

     "key" is the ID of the key to be watched.

     "queue_fd" is a file descriptor referring to an open pipe which
     manages the buffer into which notifications will be delivered.

     "filter" is either NULL to remove a watch or a filter specification to
     indicate what events are required from the key.

     See Documentation/core-api/watch_queue.rst for more information.

     Note that only one watch may be emplaced for any particular { key,
     queue_fd } combination.

     Notification records look like::

        struct key_notification {
                struct watch_notification watch;
                __u32        key_id;
                __u32        aux;
        };

     In this, watch::type will be "WATCH_TYPE_KEY_NOTIFY" and subtype will be
     one of::

        NOTIFY_KEY_INSTANTIATED
        NOTIFY_KEY_UPDATED
        NOTIFY_KEY_LINKED
        NOTIFY_KEY_UNLINKED
        NOTIFY_KEY_CLEARED
        NOTIFY_KEY_REVOKED
        NOTIFY_KEY_INVALIDATED
        NOTIFY_KEY_SETATTR

     Where these indicate a key being instantiated/rejected, updated, a link
     being made in a keyring, a link being removed from a keyring, a keyring
     being cleared, a key being revoked, a key being invalidated or a key
     having one of its attributes changed (user, group, perm, timeout,
     restriction).

     If a watched key is deleted, a basic watch_notification will be issued
     with "type" set to WATCH_TYPE_META and "subtype" set to
     watch_meta_removal_notification.  The watchpoint ID will be set in the
     "info" field.

     This needs to be configured by enabling:

        "Provide key/keyring change notifications" (KEY_NOTIFICATIONS)

커널 포인터와 possession

1090-1143

커널 서비스는 key type을 등록하고 해당 type key를 검색해 필요한 동안 참조를 유지한 뒤 해제한다. 파일 시스템이나 device file은 보통 open 때 검색하고 close 때 해제한다. 서로 다른 사용자가 같은 파일을 열어 충돌하는 key를 제공할 때의 해결은 파일 시스템 작성자의 책임이다. 기본 API는 `<linux/key.h>`, type별 API는 `include/keys/` 아래 header를 사용하며 user type은 `<keys/user-type.h>`다.

`struct key *`는 최소 4바이트 정렬의 실제 key 포인터다. `key_ref_t`는 동등한 포인터의 최하위 bit에 caller가 key를 `possess`하는지를 기록한다. possession은 프로세스 keyring 중 하나에서 검색 가능한 링크가 있다는 뜻이다. `make_key_ref()`는 포인터와 bool로 reference를 만들고, `key_ref_to_ptr()`는 포인터, `is_key_possessed()`는 flag를 얻는다. payload 접근은 수정 경합을 막는 별도 규칙을 따라야 한다.

커널 key reference
형식내용
struct key *실제 key 구조체 포인터
key_ref_t포인터 + 최하위 possession bit

key_ref_t는 정렬 여유 bit에 possession을 함께 운반한다.

Kernel Services
===============

The kernel services for key management are fairly simple to deal with. They can
be broken down into two areas: keys and key types.

Dealing with keys is fairly straightforward. Firstly, the kernel service
registers its type, then it searches for a key of that type. It should retain
the key as long as it has need of it, and then it should release it. For a
filesystem or device file, a search would probably be performed during the open
call, and the key released upon close. How to deal with conflicting keys due to
two different users opening the same file is left to the filesystem author to
solve.

To access the key manager, the following header must be #included::

        <linux/key.h>

Specific key types should have a header file under include/keys/ that should be
used to access that type.  For keys of type "user", for example, that would be::

        <keys/user-type.h>

Note that there are two different types of pointers to keys that may be
encountered:

  *  struct key *

     This simply points to the key structure itself. Key structures will be at
     least four-byte aligned.

  *  key_ref_t

     This is equivalent to a ``struct key *``, but the least significant bit is set
     if the caller "possesses" the key. By "possession" it is meant that the
     calling processes has a searchable link to the key from one of its
     keyrings. There are three functions for dealing with these::

        key_ref_t make_key_ref(const struct key *key, bool possession);

        struct key *key_ref_to_ptr(const key_ref_t key_ref);

        bool is_key_possessed(const key_ref_t key_ref);

     The first function constructs a key reference from a key pointer and
     possession information (which must be true or false).

     The second function retrieves the key pointer from a reference and the
     third retrieves the possession flag.

When accessing a key's payload contents, certain precautions must be taken to
prevent access vs modification races. See the section "Notes on accessing
payload contents" for more information.

커널 request_key 계열

1144-1203

커널 `request_key(type, description, callout_info)`는 type의 `match_preparse()` 규칙으로 description을 검색해 근사 match도 허용한다. callout 정보가 있으면 `/sbin/request-key`로 사용자 공간에서 key를 얻고, 실패는 `ENOKEY`, `EKEYEXPIRED`, `EKEYREVOKED`다. 성공 결과는 `KEYCTL_SET_REQKEY_KEYRING`으로 정한 암묵적 기본 keyring에 붙는다.

`request_key_tag()`는 동일하지만 `domain_tag`와 일치하는 key만 찾는다. NULL tag는 지정 domain들과 분리된 global domain이다. `request_key_with_auxdata()`는 callout 정보를 길이 있는 blob으로 받고 `key_type->request_key()`에 aux를 전달한다.

`request_key_rcu()`는 RCU 조건에서 domain 검색을 하지만 construction 중 key를 검사하지 않고, 찾지 못해도 사용자 공간을 호출해 만들지 않는다.

 *  To search for a key, call::

        struct key *request_key(const struct key_type *type,
                                const char *description,
                                const char *callout_info);

    This is used to request a key or keyring with a description that matches
    the description specified according to the key type's match_preparse()
    method. This permits approximate matching to occur. If callout_string is
    not NULL, then /sbin/request-key will be invoked in an attempt to obtain
    the key from userspace. In that case, callout_string will be passed as an
    argument to the program.

    Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
    returned.

    If successful, the key will have been attached to the default keyring for
    implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.

    See also Documentation/security/keys/request-key.rst.


 *  To search for a key in a specific domain, call::

        struct key *request_key_tag(const struct key_type *type,
                                    const char *description,
                                    struct key_tag *domain_tag,
                                    const char *callout_info);

    This is identical to request_key(), except that a domain tag may be
    specifies that causes search algorithm to only match keys matching that
    tag.  The domain_tag may be NULL, specifying a global domain that is
    separate from any nominated domain.


 *  To search for a key, passing auxiliary data to the upcaller, call::

        struct key *request_key_with_auxdata(const struct key_type *type,
                                             const char *description,
                                             struct key_tag *domain_tag,
                                             const void *callout_info,
                                             size_t callout_len,
                                             void *aux);

    This is identical to request_key_tag(), except that the auxiliary data is
    passed to the key_type->request_key() op if it exists, and the
    callout_info is a blob of length callout_len, if given (the length may be
    0).


 *  To search for a key under RCU conditions, call::

        struct key *request_key_rcu(const struct key_type *type,
                                    const char *description,
                                    struct key_tag *domain_tag);

    which is similar to request_key_tag() except that it does not check for
    keys that are under construction and it will not call out to userspace to
    construct a key if it can't find a match.

커널 참조 수명과 keyring_search()

1204-1254

더 이상 필요 없는 `struct key *`는 `key_put()`, `key_ref_t`는 `key_ref_put()`으로 해제하며 interrupt context에서도 호출할 수 있다. `CONFIG_KEYS`가 없으면 인자도 parse하지 않는다. `__key_get()`과 `key_get()`은 추가 reference를 만들고 반환 포인터를 돌려주며 나중에 `key_put()`이 필요하다. `key_get()`은 NULL이거나 CONFIG_KEYS가 없으면 dereference·증가하지 않는다. `key_serial()`은 serial을 반환하고 NULL 또는 비활성 설정이면 0이다.

`keyring_search(keyring_ref, type, description, recurse)`는 지정 ring만 또는 전체 tree에서 일치 key를 찾는다. 실패는 `ERR_PTR(ENOKEY)`이므로 `IS_ERR/PTR_ERR`를 사용하고 성공 reference는 해제해야 한다. 입력 keyring reference의 possession이 permission mask 접근에 쓰이고 성공 결과에도 전파된다.


 *  When it is no longer required, the key should be released using::

        void key_put(struct key *key);

    Or::

        void key_ref_put(key_ref_t key_ref);

    These can be called from interrupt context. If CONFIG_KEYS is not set then
    the argument will not be parsed.


 *  Extra references can be made to a key by calling one of the following
    functions::

        struct key *__key_get(struct key *key);
        struct key *key_get(struct key *key);

    Keys so references will need to be disposed of by calling key_put() when
    they've been finished with.  The key pointer passed in will be returned.

    In the case of key_get(), if the pointer is NULL or CONFIG_KEYS is not set
    then the key will not be dereferenced and no increment will take place.


 *  A key's serial number can be obtained by calling::

        key_serial_t key_serial(struct key *key);

    If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the
    latter case without parsing the argument).


 *  If a keyring was found in the search, this can be further searched by::

        key_ref_t keyring_search(key_ref_t keyring_ref,
                                 const struct key_type *type,
                                 const char *description,
                                 bool recurse)

    This searches the specified keyring only (recurse == false) or keyring tree
    (recurse == true) specified for a matching key. Error ENOKEY is returned
    upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned
    key will need to be released.

    The possession attribute from the keyring reference is used to control
    access through the permissions mask and is propagated to the returned key
    reference pointer if successful.

keyring_alloc(), validity와 type 등록

1255-1327

`keyring_alloc()`은 description·UID·GID·cred·permission·link restriction·flags로 keyring을 만든다. `dest`가 있으면 permission 검사 없이 destination ring에 link한다. quota 초과는 `EDQUOT`, 메모리 부족은 `ENOMEM`; quota에서 제외하려면 `KEY_ALLOC_NOT_IN_QUOTA`를 쓴다.

`restrict_link`가 있으면 새 key link마다 허용 여부를 검사하는 함수와 선택적 key·type을 담는다. type 정보는 unregister 때 garbage collector가 함수·데이터 포인터를 정리하는 데 쓴다. 커널의 `key_create_or_update()` caller는 `KEY_ALLOC_BYPASS_RESTRICTION`으로 검사를 우회할 수 있다. 부팅 때 만든 암호 keyring에 사용자 공간이 기존 kernel key로 검증 가능한 key만 추가하게 하는 것이 예다. restriction 함수는 destination ring, type, 새 payload와 검사 데이터를 받아 허용 0 또는 거부 오류를 반환하며 `restrict_link_reject`는 항상 `-EPERM`이다.

`validate_key()`는 expiry와 revoke를 검사해 `EKEYEXPIRED` 또는 `EKEYREVOKED`를 반환하고 NULL·비활성 CONFIG_KEYS면 0이다. `register_key_type()`은 같은 이름이면 `EEXIST`, `unregister_key_type()`은 type을 제거한다. `key_type_keyring`과 `request_key()`로 특정 keyring을 찾고 `keyring_search()`로 내부를 검색할 수 있지만 request_key로 특정 ring 하나를 직접 검색할 수 없어 활용은 제한적이다.

제한 keyring link
새 key payload preparserestrict_link callback허용 0 또는 오류허용 시 실제 key 생성·link

새 payload를 ring에 넣기 전에 restriction callback이 검증한다.

 *  A keyring can be created by::

        struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
                                  const struct cred *cred,
                                  key_perm_t perm,
                                  struct key_restriction *restrict_link,
                                  unsigned long flags,
                                  struct key *dest);

    This creates a keyring with the given attributes and returns it.  If dest
    is not NULL, the new keyring will be linked into the keyring to which it
    points.  No permission checks are made upon the destination keyring.

    Error EDQUOT can be returned if the keyring would overload the quota (pass
    KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
    towards the user's quota).  Error ENOMEM can also be returned.

    If restrict_link is not NULL, it should point to a structure that contains
    the function that will be called each time an attempt is made to link a
    key into the new keyring.  The structure may also contain a key pointer
    and an associated key type.  The function is called to check whether a key
    may be added into the keyring or not.  The key type is used by the garbage
    collector to clean up function or data pointers in this structure if the
    given key type is unregistered.  Callers of key_create_or_update() within
    the kernel can pass KEY_ALLOC_BYPASS_RESTRICTION to suppress the check.
    An example of using this is to manage rings of cryptographic keys that are
    set up when the kernel boots where userspace is also permitted to add keys
    - provided they can be verified by a key the kernel already has.

    When called, the restriction function will be passed the keyring being
    added to, the key type, the payload of the key being added, and data to be
    used in the restriction check.  Note that when a new key is being created,
    this is called between payload preparsing and actual key creation.  The
    function should return 0 to allow the link or an error to reject it.

    A convenience function, restrict_link_reject, exists to always return
    -EPERM to in this case.


 *  To check the validity of a key, this function can be called::

        int validate_key(struct key *key);

    This checks that the key in question hasn't expired or and hasn't been
    revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will
    be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be
    returned (in the latter case without parsing the argument).


 *  To register a key type, the following function should be called::

        int register_key_type(struct key_type *type);

    This will return error EEXIST if a type of the same name is already
    present.


 *  To unregister a key type, call::

        void unregister_key_type(struct key_type *type);


Under some circumstances, it may be desirable to deal with a bundle of keys.
The facility provides access to the keyring type for managing such a bundle::

        struct key_type key_type_keyring;

This can be used with a function such as request_key() to find a specific
keyring in a process's keyrings.  A keyring thus found can then be searched
with keyring_search().  Note that it is not possible to use request_key() to
search a specific keyring, so using keyrings in this way is of limited utility.

Payload 동시성 접근 규칙

1328-1394

payload가 `key->payload`에 직접 든 단순 값이면 RCU나 lock 없이 읽을 수 있다. 복잡한 payload는 별도 할당하고 포인터를 `key->payload.data[]`에 저장하므로 세 방법 중 하나를 택한다. modify method가 없는 type은 instantiated임을 안다면 lock 없이 접근할 수 있다. key semaphore를 쓰면 수정은 write lock, 일반 접근은 read lock이지만 accessor가 sleep해야 할 수 있다.

semaphore를 이미 보유하지 않았다면 RCU를 사용한다. 수정도 semaphore로 직렬화하므로 보유 중에는 예기치 않게 내용이 바뀌지 않는다. 읽기는 `rcu_read_lock()`·`rcu_dereference()`·`rcu_read_unlock()`, 교체는 `rcu_dereference()`·`rcu_assign_pointer()`·`call_rcu()`로 grace period 뒤 이전 payload를 버린다. payload 수정은 key type만 해야 한다.

RCU payload는 `struct rcu_head`와 가변 크기라면 자체 length를 가져야 한다. semaphore 없이 dereference한 payload와 `key->datalen`의 일관성은 보장되지 않는다. 첫 포인터의 `__rcu` shadow는 `key->payload.rcu_data0`이며 `rcu_assign_keypointer()`로 설정, semaphore 보유 중 `dereference_key_locked()`, RCU read lock 중 `dereference_key_rcu()`로 읽는다.

Payload 접근 방식
방식조건특징
직접inline 또는 unmodifiable payloadlock 불필요
key semaphoresleep 가능read/write lock
RCUlock 없는 read 경로grace period 뒤 이전 데이터 해제

type의 변경 가능성과 caller context에 따라 선택한다.

Notes On Accessing Payload Contents
===================================

The simplest payload is just data stored in key->payload directly.  In this
case, there's no need to indulge in RCU or locking when accessing the payload.

More complex payload contents must be allocated and pointers to them set in the
key->payload.data[] array.  One of the following ways must be selected to
access the data:

  1) Unmodifiable key type.

     If the key type does not have a modify method, then the key's payload can
     be accessed without any form of locking, provided that it's known to be
     instantiated (uninstantiated keys cannot be "found").

  2) The key's semaphore.

     The semaphore could be used to govern access to the payload and to control
     the payload pointer. It must be write-locked for modifications and would
     have to be read-locked for general access. The disadvantage of doing this
     is that the accessor may be required to sleep.

  3) RCU.

     RCU must be used when the semaphore isn't already held; if the semaphore
     is held then the contents can't change under you unexpectedly as the
     semaphore must still be used to serialise modifications to the key. The
     key management code takes care of this for the key type.

     However, this means using::

        rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()

     to read the pointer, and::

        rcu_dereference() ... rcu_assign_pointer() ... call_rcu()

     to set the pointer and dispose of the old contents after a grace period.
     Note that only the key type should ever modify a key's payload.

     Furthermore, an RCU controlled payload must hold a struct rcu_head for the
     use of call_rcu() and, if the payload is of variable size, the length of
     the payload. key->datalen cannot be relied upon to be consistent with the
     payload just dereferenced if the key's semaphore is not held.

     Note that key->payload.data[0] has a shadow that is marked for __rcu
     usage.  This is called key->payload.rcu_data0.  The following accessors
     wrap the RCU calls to this element:

     a) Set or change the first payload pointer::

                rcu_assign_keypointer(struct key *key, void *data);

     b) Read the first payload pointer with the key semaphore held::

                [const] void *dereference_key_locked([const] struct key *key);

         Note that the return value will inherit its constness from the key
         parameter.  Static analysis will give an error if it things the lock
         isn't held.

     c) Read the first payload pointer with the RCU read lock held::

                const void *dereference_key_rcu(const struct key *key);

key_type의 이름·quota·description 검증

1395-1435

파일 시스템 등 커널 서비스는 `<linux/key-type.h>`를 포함하고 `struct key_type`을 채워 등록해 자체 type을 정의한다. 예를 들어 AFS는 Kerberos 5 ticket type을 만들 수 있다. 필수 `name`은 사용자 공간 type 문자열을 구조체 포인터로 변환할 때 쓴다.

선택적 `def_datalen`은 payload가 거의 고정 크기일 때 quota에 기본 반영할 길이다. 특정 key의 길이와 quota는 `key_payload_reserve(key, datalen)`로 바꾸며 불가능하면 `EDQUOT`다. 선택적 `vet_description()`은 description을 승인하면 0, 거부하면 오류를 반환한다.

Defining a Key Type
===================

A kernel service may want to define its own key type. For instance, an AFS
filesystem might want to define a Kerberos 5 ticket key type. To do this, it
author fills in a key_type struct and registers it with the system.

Source files that implement key types should include the following header file::

        <linux/key-type.h>

The structure has a number of fields, some of which are mandatory:

  *  ``const char *name``

     The name of the key type. This is used to translate a key type name
     supplied by userspace into a pointer to the structure.


  *  ``size_t def_datalen``

     This is optional - it supplies the default payload data length as
     contributed to the quota. If the key type's payload is always or almost
     always the same size, then this is a more efficient way to do things.

     The data length (and quota) on a particular key can always be changed
     during instantiation or update by calling::

        int key_payload_reserve(struct key *key, size_t datalen);

     With the revised data length. Error EDQUOT will be returned if this is not
     viable.


  *  ``int (*vet_description)(const char *description);``

     This optional method is called to vet a key description.  If the key type
     doesn't approve of the key description, it may return an error, otherwise
     it should return 0.

preparse·free_preparse·instantiate

1436-1500

선택적 `preparse(prep)`는 add에서는 key 생성 전, update·instantiate에서는 semaphore 획득 전에 payload를 parse한다. `key_preparsed_payload`에는 description, union payload, 원본 data·datalen, quota 길이, expiry가 있다. 호출 전 data·datalen은 입력 blob, quotalen은 type 기본값, expiry는 `TIME_T_MAX`, 나머지는 0이다. payload에서 description을 만들 수 있으면 문자열을 붙여 `add_key()`가 NULL 또는 빈 description을 줬을 때 사용한다. parse한 자료는 payload에 붙여 instantiate/update로 전달하고 expiry도 적용하며 성공 0 또는 음수 오류를 반환한다.

`free_preparse()`는 preparse가 있을 때 필요하며 성공한 preparse 뒤 instantiate/update 성공 여부와 무관하게 항상 호출되어 description·payload의 임시 자원을 정리한다.

`instantiate(key, prep)`는 construction 중 payload를 붙인다. 원본 blob과 다른 내부 표현도 가능하고 실제 길이가 `def_datalen`과 다르면 `key_payload_reserve()`를 호출한다. `KEY_FLAG_INSTANTIATED`가 아직 없어 외부 접근이 차단되므로 별도 key lock 없이 붙일 수 있고 sleep 가능하다. `generic_key_instantiate()`는 prep payload 배열을 key payload로 복사하며 첫 원소는 RCU-safe하게 지정하고 prep 배열을 지워 free_preparse가 데이터를 해제하지 않게 한다.

Key 생성 callback
preparse 입력 blobdescription·payload·quota·expiry 준비instantiate로 key payload 부착free_preparse로 임시 자원 정리

parse 임시 자료는 instantiate 뒤 반드시 정리된다.

  *  ``int (*preparse)(struct key_preparsed_payload *prep);``

     This optional method permits the key type to attempt to parse payload
     before a key is created (add key) or the key semaphore is taken (update or
     instantiate key).  The structure pointed to by prep looks like::

        struct key_preparsed_payload {
                char                *description;
                union key_payload payload;
                const void        *data;
                size_t                datalen;
                size_t                quotalen;
                time_t                expiry;
        };

     Before calling the method, the caller will fill in data and datalen with
     the payload blob parameters; quotalen will be filled in with the default
     quota size from the key type; expiry will be set to TIME_T_MAX and the
     rest will be cleared.

     If a description can be proposed from the payload contents, that should be
     attached as a string to the description field.  This will be used for the
     key description if the caller of add_key() passes NULL or "".

     The method can attach anything it likes to payload.  This is merely passed
     along to the instantiate() or update() operations.  If set, the expiry
     time will be applied to the key if it is instantiated from this data.

     The method should return 0 if successful or a negative error code
     otherwise.


  *  ``void (*free_preparse)(struct key_preparsed_payload *prep);``

     This method is only required if the preparse() method is provided,
     otherwise it is unused.  It cleans up anything attached to the description
     and payload fields of the key_preparsed_payload struct as filled in by the
     preparse() method.  It will always be called after preparse() returns
     successfully, even if instantiate() or update() succeed.


  *  ``int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);``

     This method is called to attach a payload to a key during construction.
     The payload attached need not bear any relation to the data passed to this
     function.

     The prep->data and prep->datalen fields will define the original payload
     blob.  If preparse() was supplied then other fields may be filled in also.

     If the amount of data attached to the key differs from the size in
     keytype->def_datalen, then key_payload_reserve() should be called.

     This method does not have to lock the key in order to attach a payload.
     The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
     anything else from gaining access to the key.

     It is safe to sleep in this method.

     generic_key_instantiate() is provided to simply copy the data from
     prep->payload.data[] to key->payload.data[], with RCU-safe assignment on
     the first element.  It will then clear prep->payload.data[] so that the
     free_preparse method doesn't release the data.

update callback의 실패 경계와 RCU

1501-1525

type이 update 가능하면 `update()`를 제공해 입력 blob으로 payload를 바꾼다. 길이가 달라질 수 있으면 실제 변경 전에 `key_payload_reserve()`를 호출해야 한다. reserve 성공은 quota가 이미 바뀌어 type이 key 변경을 완료해야 한다는 뜻이므로 모든 메모리 할당과 실패 가능한 호출을 먼저 끝낸 뒤 reserve하고 변경한다.

호출 전 key semaphore는 write-lock 상태지만 이는 다른 writer만 막는다. reader와 안전하게 payload를 바꾸려면 RCU 조건에서 교체하고 `call_rcu()`로 이전 payload를 폐기한다. 이 method는 sleep 가능하다.

  *  ``int (*update)(struct key *key, const void *data, size_t datalen);``

     If this type of key can be updated, then this method should be provided.
     It is called to update a key's payload from the blob of data provided.

     The prep->data and prep->datalen fields will define the original payload
     blob.  If preparse() was supplied then other fields may be filled in also.

     key_payload_reserve() should be called if the data length might change
     before any changes are actually made. Note that if this succeeds, the type
     is committed to changing the key because it's already been altered, so all
     memory allocation must be done first.

     The key will have its semaphore write-locked before this method is called,
     but this only deters other writers; any changes to the key's payload must
     be made under RCU conditions, and call_rcu() must be used to dispose of
     the old payload.

     key_payload_reserve() should be called before the changes are made, but
     after all allocations and other potentially failing function calls are
     made.

     It is safe to sleep in this method.

검색 preparse와 비교 함수

1526-1576

선택적 `match_preparse(match_data)`는 검색 직전에 호출된다. `raw_data`는 caller 검색 기준으로 수정하면 안 된다. 기본 `cmp`는 description과 정확히 비교하고 `lookup_type`은 direct다. `KEYRING_SEARCH_LOOKUP_DIRECT`는 type·description hash로 후보를 줄이고, `ITERATE`는 ring의 모든 key를 순회하므로 단순 description match가 아닌 검색은 ITERATE를 써야 한다.

method는 자체 `cmp`, ITERATE lookup, 비교용 `preparsed` 자료를 설정할 수 있다. cmp는 일치 true, 불일치 false이며 lock 아래 호출되어 sleep할 수 없다. match_preparse 자체는 sleep 가능하고 성공 0 또는 음수 오류를 반환한다. 임시 자료는 선택적 `match_free()`가 정리한다. match_preparse가 없으면 description exact match다.

검색 방식
lookup_type동작
DIRECTtype·description hash로 후보 축소
ITERATEkeyring 전체 순회와 custom cmp

description exact match 여부에 따라 lookup 전략이 달라진다.

  *  ``int (*match_preparse)(struct key_match_data *match_data);``

     This method is optional.  It is called when a key search is about to be
     performed.  It is given the following structure::

        struct key_match_data {
                bool (*cmp)(const struct key *key,
                            const struct key_match_data *match_data);
                const void        *raw_data;
                void                *preparsed;
                unsigned        lookup_type;
        };

     On entry, raw_data will be pointing to the criteria to be used in matching
     a key by the caller and should not be modified.  ``(*cmp)()`` will be pointing
     to the default matcher function (which does an exact description match
     against raw_data) and lookup_type will be set to indicate a direct lookup.

     The following lookup_type values are available:

       *  KEYRING_SEARCH_LOOKUP_DIRECT - A direct lookup hashes the type and
                description to narrow down the search to a small number of keys.

       *  KEYRING_SEARCH_LOOKUP_ITERATE - An iterative lookup walks all the
                keys in the keyring until one is matched.  This must be used for any
                search that's not doing a simple direct match on the key description.

     The method may set cmp to point to a function of its choice that does some
     other form of match, may set lookup_type to KEYRING_SEARCH_LOOKUP_ITERATE
     and may attach something to the preparsed pointer for use by ``(*cmp)()``.
     ``(*cmp)()`` should return true if a key matches and false otherwise.

     If preparsed is set, it may be necessary to use the match_free() method to
     clean it up.

     The method should return 0 if successful or a negative error code
     otherwise.

     It is permitted to sleep in this method, but ``(*cmp)()`` may not sleep as
     locks will be held over it.

     If match_preparse() is not provided, keys of this type will be matched
     exactly by their description.


  *  ``void (*match_free)(struct key_match_data *match_data);``

     This method is optional.  If given, it called to clean up
     match_data->preparsed after a successful call to match_preparse().

revoke·destroy·describe·read callback

1577-1630

선택적 `revoke()`는 revoke 때 payload 일부를 버리며 caller가 key semaphore를 write-lock한다. sleep 가능하지만 semaphore deadlock을 피해야 한다. `destroy()`는 key 파괴 때 payload를 버리고 더 이상 접근할 수 없으므로 lock이 필요 없지만 caller가 spinlock을 보유할 수 있어 sleep하면 안 된다. 호출 전에 key type이 바뀌었을 수도 있다.

`describe()`는 `/proc/keys`용 텍스트 요약을 만든다. RCU read lock 아래 호출되므로 payload 포인터는 `rcu_dereference()`로 읽고 `key->datalen` 일관성을 믿으면 안 된다. description은 불변이지만 상태는 바뀔 수 있고 sleep 금지다.

`read()`는 `KEYCTL_READ`에 내부 payload를 사용자 공간 blob으로 변환하며 가능하면 instantiate/update 입력 형식과 같게 한다. 복사량이 아니라 만들 수 있는 전체 blob 크기를 반환해야 한다. key semaphore read-lock 아래라 payload가 바뀌지 않으므로 RCU lock은 불필요하고 사용자 buffer 접근 중 sleep할 수 있다.

Lifecycle callback context
callbackcaller 상태sleep
revokekey semaphore write-lock가능, deadlock 주의
destroykey 비접근 상태, spinlock 가능불가
describeRCU read lock불가
readkey semaphore read-lock가능

각 callback의 lock과 sleep 조건이다.

  *  ``void (*revoke)(struct key *key);``

     This method is optional.  It is called to discard part of the payload
     data upon a key being revoked.  The caller will have the key semaphore
     write-locked.

     It is safe to sleep in this method, though care should be taken to avoid
     a deadlock against the key semaphore.


  *  ``void (*destroy)(struct key *key);``

     This method is optional. It is called to discard the payload data on a key
     when it is being destroyed.

     This method does not need to lock the key to access the payload; it can
     consider the key as being inaccessible at this time. Note that the key's
     type may have been changed before this function is called.

     It is not safe to sleep in this method; the caller may hold spinlocks.


  *  ``void (*describe)(const struct key *key, struct seq_file *p);``

     This method is optional. It is called during /proc/keys reading to
     summarise a key's description and payload in text form.

     This method will be called with the RCU read lock held. rcu_dereference()
     should be used to read the payload pointer if the payload is to be
     accessed. key->datalen cannot be trusted to stay consistent with the
     contents of the payload.

     The description will not change, though the key's state may.

     It is not safe to sleep in this method; the RCU read lock is held by the
     caller.


  *  ``long (*read)(const struct key *key, char __user *buffer, size_t buflen);``

     This method is optional. It is called by KEYCTL_READ to translate the
     key's payload into something a blob of data for userspace to deal with.
     Ideally, the blob should be in the same format as that passed in to the
     instantiate and update methods.

     If successful, the blob size that could be produced should be returned
     rather than the size copied.

     This method will be called with the key's semaphore read-locked. This will
     prevent the key's payload changing. It is not necessary to use RCU locking
     when accessing the key's payload. It is safe to sleep in this method, such
     as might happen when the userspace buffer is accessed.

type별 request_key와 restriction parser

1631-1678

선택적 `key_type->request_key(cons, op, aux)`가 있으면 `request_key()` 계열은 `/sbin/request-key` 대신 이 callback을 호출한다. aux는 auxdata 요청에서 전달한 값, op는 현재 `create`, cons는 construction record다. 비동기로 먼저 반환할 수 있지만 성공·실패·오류 여부와 무관하게 반드시 `complete_request_key(cons, error)`를 호출해야 한다.

complete의 error는 성공 0, 실패 음수다. 호출하면 construction record를 파괴하고 authorization key를 revoke하며, 오류 시 아직 완성되지 않은 key를 negative instantiate한다. callback이 오류를 직접 반환할 때도 반환 전 complete를 호출해야 한다. cons에는 construction 중 `key`와 `authkey`가 있다.

선택적 `lookup_restriction(params)`는 사용자 공간이 keyring restriction을 설정하게 한다. type 이름을 뺀 parameter 문자열을 해석해 link 시도마다 평가할 함수·데이터가 든 `key_restriction`을 반환하고 일치 방식이 없으면 `-EINVAL`이다.

Type별 비동기 request
request_key callback선택적 비동기 작업성공 또는 오류 결정complete_request_key()authkey revoke와 construction 정리

어떤 종료 경로에서도 construction을 명시적으로 완료한다.

  *  ``int (*request_key)(struct key_construction *cons, const char *op, void *aux);``

     This method is optional.  If provided, request_key() and friends will
     invoke this function rather than upcalling to /sbin/request-key to operate
     upon a key of this type.

     The aux parameter is as passed to request_key_async_with_auxdata() and
     similar or is NULL otherwise.  Also passed are the construction record for
     the key to be operated upon and the operation type (currently only
     "create").

     This method is permitted to return before the upcall is complete, but the
     following function must be called under all circumstances to complete the
     instantiation process, whether or not it succeeds, whether or not there's
     an error::

        void complete_request_key(struct key_construction *cons, int error);

     The error parameter should be 0 on success, -ve on error.  The
     construction record is destroyed by this action and the authorisation key
     will be revoked.  If an error is indicated, the key under construction
     will be negatively instantiated if it wasn't already instantiated.

     If this method returns an error, that error will be returned to the
     caller of request_key*().  complete_request_key() must be called prior to
     returning.

     The key under construction and the authorisation key can be found in the
     key_construction struct pointed to by cons:

      *  ``struct key *key;``

              The key under construction.

      *  ``struct key *authkey;``

              The authorisation key.


  *  ``struct key_restriction *(*lookup_restriction)(const char *params);``

     This optional method is used to enable userspace configuration of keyring
     restrictions. The restriction parameter string (not including the key type
     name) is passed in, and this method returns a pointer to a key_restriction
     structure containing the relevant functions and data to evaluate each
     attempted key link operation. If there is no match, -EINVAL is returned.

asym_eds_op와 signature verification

1679-1748

선택적 `asym_eds_op()`는 encrypt·decrypt·sign, `asym_verify_signature()`는 signature verify를 수행한다. `kernel_pkey_params`에는 사용할 key, encoding(`pkcs1` 또는 `raw` 등), signature data를 만든 hash algorithm, 보조 info, input과 output 또는 second input 길이, operation ID가 있다.

operation별 buffer는 사용자 공간 PKEY와 같다. encrypt와 sign은 raw input을 encrypted result 또는 signature output으로 만들며 encoding이 있으면 padding을 추가하고 sign padding이 digest algorithm을 표시해야 하면 `hash_algo`를 사용한다. decrypt는 encrypted input을 raw output으로 만들며 padding을 검사·제거한다. verify는 raw input과 second input의 signature를 비교하고 padding과 필요한 hash algorithm을 검증한다.

성공 시 `asym_eds_op()`는 output byte 수, verify는 0을 반환한다. 미지원은 `EOPNOTSUPP`, 검증 실패는 `EKEYREJECTED`, 필요한 crypto package가 없으면 `ENOPKG` 등 오류를 반환할 수 있다.

  *  ``asym_eds_op`` and ``asym_verify_signature``::

       int (*asym_eds_op)(struct kernel_pkey_params *params,
                          const void *in, void *out);
       int (*asym_verify_signature)(struct kernel_pkey_params *params,
                                    const void *in, const void *in2);

     These methods are optional.  If provided the first allows a key to be
     used to encrypt, decrypt or sign a blob of data, and the second allows a
     key to verify a signature.

     In all cases, the following information is provided in the params block::

        struct kernel_pkey_params {
                struct key        *key;
                const char        *encoding;
                const char        *hash_algo;
                char                *info;
                __u32                in_len;
                union {
                        __u32        out_len;
                        __u32        in2_len;
                };
                enum kernel_pkey_operation op : 8;
        };

     This includes the key to be used; a string indicating the encoding to use
     (for instance, "pkcs1" may be used with an RSA key to indicate
     RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding or "raw" if no encoding);
     the name of the hash algorithm used to generate the data for a signature
     (if appropriate); the sizes of the input and output (or second input)
     buffers; and the ID of the operation to be performed.

     For a given operation ID, the input and output buffers are used as
     follows::

        Operation ID                in,in_len        out,out_len        in2,in2_len
        =======================        ===============        ===============        ===============
        kernel_pkey_encrypt        Raw data        Encrypted data        -
        kernel_pkey_decrypt        Encrypted data        Raw data        -
        kernel_pkey_sign        Raw data        Signature        -
        kernel_pkey_verify        Raw data        -                Signature

     asym_eds_op() deals with encryption, decryption and signature creation as
     specified by params->op.  Note that params->op is also set for
     asym_verify_signature().

     Encrypting and signature creation both take raw data in the input buffer
     and return the encrypted result in the output buffer.  Padding may have
     been added if an encoding was set.  In the case of signature creation,
     depending on the encoding, the padding created may need to indicate the
     digest algorithm - the name of which should be supplied in hash_algo.

     Decryption takes encrypted data in the input buffer and returns the raw
     data in the output buffer.  Padding will get checked and stripped off if
     an encoding was set.

     Verification takes raw data in the input buffer and the signature in the
     second input buffer and checks that the one matches the other.  Padding
     will be validated.  Depending on the encoding, the digest algorithm used
     to generate the raw data may need to be indicated in hash_algo.

     If successful, asym_eds_op() should return the number of bytes written
     into the output buffer.  asym_verify_signature() should return 0.

     A variety of errors may be returned, including EOPNOTSUPP if the operation
     is not supported; EKEYREJECTED if verification fails; ENOPKG if the
     required crypto isn't available.

asym_query 결과

1749-1788

선택적 `asym_query(params, info)`는 key가 가진 public 또는 asymmetric key 정보를 알아낸다. parameter는 암호 연산과 같지만 input/output 길이는 쓰지 않고 encoding·hash algorithm으로 적절한 buffer/data 최대 크기를 좁힌다.

성공 결과 `kernel_pkey_query`는 supported operation bitmask, bit 단위 key size, signature 생성·검증의 raw data와 signature 최대 크기, encrypt·decrypt의 최대 크기를 byte 단위로 제공한다. 지원 bit는 `KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}`다. 성공 0, 미지원은 `EOPNOTSUPP`다.

  *  ``asym_query``::

       int (*asym_query)(const struct kernel_pkey_params *params,
                         struct kernel_pkey_query *info);

     This method is optional.  If provided it allows information about the
     public or asymmetric key held in the key to be determined.

     The parameter block is as for asym_eds_op() and co. but in_len and out_len
     are unused.  The encoding and hash_algo fields should be used to reduce
     the returned buffer/data sizes as appropriate.

     If successful, the following information is filled in::

        struct kernel_pkey_query {
                __u32                supported_ops;
                __u32                key_size;
                __u16                max_data_size;
                __u16                max_sig_size;
                __u16                max_enc_size;
                __u16                max_dec_size;
        };

     The supported_ops field will contain a bitmask indicating what operations
     are supported by the key, including encryption of a blob, decryption of a
     blob, signing a blob and verifying the signature on a blob.  The following
     constants are defined for this::

        KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

     The key_size field is the size of the key in bits.  max_data_size and
     max_sig_size are the maximum raw data and signature sizes for creation and
     verification of a signature; max_enc_size and max_dec_size are the maximum
     raw data and signature sizes for encryption and decryption.  The
     max_*_size fields are measured in bytes.

     If successful, 0 will be returned.  If the key doesn't support this,
     EOPNOTSUPP will be returned.

/sbin/request-key callback protocol

1789-1838

새 key가 필요하면 커널은 `/sbin/request-key create <key> <uid> <gid> <threadring> <processring> <sessionring> <callout_info>`를 실행한다. 세 ring은 요청을 일으킨 프로세스의 keyring이며 필요한 Kerberos TGT 같은 인증 token을 찾고 새 key를 cache할 위치를 제공한다.

프로그램은 추가 key에 접근하기 전에 지정 UID·GID로 전환하고, KDE desktop manager가 다른 key에 둔 경로처럼 사용자별 프로세스에 요청을 넘길 수 있다. 완료하려면 `KEYCTL_INSTANTIATE` 또는 IOV 버전으로 key를 만들고 보통 session ring에 cache한다. 실패는 `KEYCTL_NEGATE` 또는 `REJECT`로 표시·cache한다. unconstructed 상태로 반환하면 자동 negative, session keyring link, requester 오류가 발생한다. 추가 정보가 없으면 callout_info에 `-`가 전달된다.

expired 또는 곧 만료될 key update에는 `/sbin/request-key update <key> <uid> <gid> <threadring> <processring> <sessionring>`을 실행한다. 이 경우 ring은 참고용이며 실제 link는 요구되지 않는다.

request-key upcall
keyring 검색 실패/sbin/request-key create 실행지정 UID·GID와 기존 ring으로 자격 확보INSTANTIATE 또는 NEGATE/REJECT선택적 keyring cache

커널 요청은 사용자 공간 helper가 positive 또는 negative로 반드시 종결한다.

Request-Key Callback Service
============================

To create a new key, the kernel will attempt to execute the following command
line::

        /sbin/request-key create <key> <uid> <gid> \
                <threadring> <processring> <sessionring> <callout_info>

<key> is the key being constructed, and the three keyrings are the process
keyrings from the process that caused the search to be issued. These are
included for two reasons:

   1  There may be an authentication token in one of the keyrings that is
      required to obtain the key, eg: a Kerberos Ticket-Granting Ticket.

   2  The new key should probably be cached in one of these rings.

This program should set it UID and GID to those specified before attempting to
access any more keys. It may then look around for a user specific process to
hand the request off to (perhaps a path held in placed in another key by, for
example, the KDE desktop manager).

The program (or whatever it calls) should finish construction of the key by
calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to
cache the key in one of the keyrings (probably the session ring) before
returning.  Alternatively, the key can be marked as negative with KEYCTL_NEGATE
or KEYCTL_REJECT; this also permits the key to be cached in one of the
keyrings.

If it returns with the key remaining in the unconstructed state, the key will
be marked as being negative, it will be added to the session keyring, and an
error will be returned to the key requestor.

Supplementary information may be provided from whoever or whatever invoked this
service. This will be passed as the <callout_info> parameter. If no such
information was made available, then "-" will be passed as this parameter
instead.


Similarly, the kernel may attempt to update an expired or a soon to expire key
by executing::

        /sbin/request-key update <key> <uid> <gid> \
                <threadring> <processring> <sessionring>

In this case, the program isn't required to actually attach the key to a ring;
the rings are provided for reference.

Dead·Revoked·Expired key 수거

1839-1849

type이 제거된 dead key는 background garbage collector가 자신을 가리키는 모든 keyring에서 자동 unlink하고 가능한 빨리 삭제한다. revoked와 expired key도 수거하지만 일정 지연 뒤 처리하며 지연 초는 `/proc/sys/kernel/keys/gc_delay`에 설정한다.

Garbage collection
상태처리
Dead가능한 즉시 unlink·삭제
Revokedgc_delay 뒤 수거
Expiredgc_delay 뒤 수거

상태별 수거 시점이다.

Garbage Collection
==================

Dead keys (for which the type has been removed) will be automatically unlinked
from those keyrings that point to them and deleted as soon as possible by a
background garbage collector.

Similarly, revoked and expired keys will be garbage collected, but only after a
certain amount of time has passed.  This time is set as a number of seconds in::

        /proc/sys/kernel/keys/gc_delay