keyctl(2) System Calls Manual keyctl(2) keyctl - LIBRARY Standard C library (libc, -lc) Alternatively, Linux Key Management Utilities (libkeyutils, -lkeyutils); see VERSIONS. #include /* KEY* */ #include /* SYS_* */ #include long syscall(SYS_keyctl, int operation, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); Note: glibc provides no wrapper for keyctl(), necessitating the use of syscall(2). keyctl() . , keyctl(), operation. libkeyutils ( keyutils) ( ), . operation: KEYCTL_GET_KEYRING_ID ( Linux 2.6.10) . , arg2 ( key_serial_t). , . arg2 : KEY_SPEC_THREAD_KEYRING . thread-keyring(7). KEY_SPEC_PROCESS_KEYRING . process-keyring(7). KEY_SPEC_SESSION_KEYRING . session-keyring(7). KEY_SPEC_USER_KEYRING UID . user-keyring(7). KEY_SPEC_USER_SESSION_KEYRING UID . user-session-keyring(7). KEY_SPEC_REQKEY_AUTH_KEY ( Linux 2.6.16) , request_key(2) , . , request-key(8), , , ; request_key(2). KEY_SPEC_REQUESTOR_KEYRING ( Linux 2.6.29) request_key(2). , request-key(8), , , ; request_key(2). The behavior if the key specified in arg2 does not exist depends on the value of arg3 (cast to int). If arg3 contains a nonzero value, then--if it is appropriate to do so (e.g., when looking up the user, user-session, or session key)--a new key is created and its real key ID returned as the function result. Otherwise, the operation fails with the error ENOKEY. arg2 , . , ENOKEY. . arg4 arg5 . libkeyutils keyctl_get_keyring_ID(3). KEYCTL_JOIN_SESSION_KEYRING ( Linux 2.6.10) . arg2 NULL, <<_ses>> , . , arg2 ( char *) () : o , , , ; , . , . o , , . arg3, arg4 arg5 . libkeyutils keyctl_join_session_keyring(3). KEYCTL_UPDATE ( Linux 2.6.10) . arg2 ( key_serial_t) . arg3 ( void *) , arg4 ( size_t) . , . ( KEYCTL_REJECT) . arg5 . libkeyutils keyctl_update(3). KEYCTL_REVOKE ( Linux 2.6.10) arg2 ( key_serial_t). ; , . EKEYREVOKED. . arg3, arg4 arg5 . libkeyutils keyctl_revoke(3). KEYCTL_CHOWN ( Linux 2.6.10) ( ) . arg2 ( key_serial_t) . arg3 ( uid_t) ( -1, ). arg4 ( gid_t) ( -1, ). . UID GID, , CAP_SYS_ADMIN ( capabilities(7)). UID, . , . arg5 . libkeyutils keyctl_chown(3). KEYCTL_SETPERM ( Linux 2.6.10) arg2 ( key_serial_t) , arg3 ( key_perm_t). CAP_SYS_ADMIN, , (, UID UID ). . arg3 : ( Linux 2.6.14) , ( ); keyrings(7). , UID UID . , GID GID GID . , . , : , , ; , , . , , . , . : . KEYCTL_DESCRIBE. KEY_POS_VIEW, KEY_USR_VIEW, KEY_GRP_VIEW KEY_OTH_VIEW. . KEYCTL_READ. KEY_POS_READ, KEY_USR_READ, KEY_GRP_READ KEY_OTH_READ. . . KEYCTL_UPDATE, KEYCTL_REVOKE, KEYCTL_CLEAR, KEYCTL_LINK KEYCTL_UNLINK. KEY_POS_WRITE, KEY_USR_WRITE, KEY_GRP_WRITE KEY_OTH_WRITE. . , . KEYCTL_GET_KEYRING_ID, KEYCTL_JOIN_SESSION_KEYRING, KEYCTL_SEARCH KEYCTL_INVALIDATE. KEY_POS_SEARCH, KEY_USR_SEARCH, KEY_GRP_SEARCH KEY_OTH_SEARCH. . KEYCTL_LINK KEYCTL_SESSION_TO_PARENT. KEY_POS_LINK, KEY_USR_LINK, KEY_GRP_LINK KEY_OTH_LINK. setattr ( Linux 2.6.15). UID, GID . KEYCTL_REVOKE, KEYCTL_CHOWN KEYCTL_SETPERM. KEY_POS_SETATTR, KEY_USR_SETATTR, KEY_GRP_SETATTR KEY_OTH_SETATTR. , : KEY_POS_ALL, KEY_USR_ALL KEY_GRP_ALL KEY_OTH_ALL. arg4 arg5 . libkeyutils keyctl_setperm(3). KEYCTL_DESCRIBE ( Linux 2.6.10) , . arg2 ( key_serial_t). , arg3 ( char *); arg4 ( size_t) . . null : ;uid;gid;; , uid gid -- , -- . : %s;%d;%d;%08x;%s : , . , ; . . arg3 NULL ( null). , , , arg4. arg5 . libkeyutils keyctl_describe(3). KEYCTL_CLEAR (. ., ). ( ) arg2 ( key_serial_t). . arg3, arg4 arg5 . libkeyutils keyctl_clear(3). KEYCTL_LINK ( Linux 2.6.10) . arg2 ( key_serial_t); arg3 ( key_serial_t). , . , , ( KEYRING_SEARCH_MAX_DEPTH, 6 ). (link) . arg4 arg5 . libkeyutils keyctl_link(3). KEYCTL_UNLINK ( Linux 2.6.10) . arg2 ( key_serial_t); , , arg3 ( key_serial_t). , . , . , . arg4 arg5 . libkeyutils keyctl_unlink(3). KEYCTL_SEARCH ( Linux 2.6.10) , , , . , , arg2 ( key_serial_t). . arg3 arg4 : arg3 ( char *) ( 32 null), arg4 ( char *) ( 4096 null). . , . , . , . arg5 ( key_serial_t) , KEYCTL_LINK , arg5. , arg5, , , . (arg2) (arg5) , KEYCTL_GET_KEYRING_ID. libkeyutils keyctl_search(3). KEYCTL_READ ( Linux 2.6.10) . , , arg2 ( key_serial_t). , KEYCTL_GET_KEYRING_ID. , arg3 ( char *); arg4 ( size_t). . , key_serial_t, . user . , EOPNOTSUPP. arg3 NULL, . . , , , arg4. , (. ., ). arg5 . libkeyutils keyctl_read(3). KEYCTL_INSTANTIATE ( Linux 2.6.10) . arg2 ( key_serial_t). , arg3 ( void *); arg4 ( size_t). The payload may be a null pointer and the buffer size may be 0 if this is supported by the key type (e.g., it is a keyring). , . arg5 ( key_serial_t) , KEYCTL_LINK , arg5. . , , request-key(8). request_key(2) . libkeyutils keyctl_instantiate(3). KEYCTL_NEGATE ( Linux 2.6.10) . : keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4); arg5 . libkeyutils keyctl_negate(3). KEYCTL_SET_REQKEY_KEYRING ( Linux 2.6.13) , , . , , , AFS NFS. ; request_key(2). arg2 ( int) , : KEY_REQKEY_DEFL_NO_CHANGE . ( ). KEY_REQKEY_DEFL_DEFAULT , , , , , , , , UID, . KEY_REQKEY_DEFL_THREAD_KEYRING (thread-keyring(7)). KEY_REQKEY_DEFL_PROCESS_KEYRING (process-keyring(7)). KEY_REQKEY_DEFL_SESSION_KEYRING (session-keyring(7)). KEY_REQKEY_DEFL_USER_KEYRING UID (user-keyring(7)). KEY_REQKEY_DEFL_USER_SESSION_KEYRING UID (user-session-keyring(7)). KEY_REQKEY_DEFL_REQUESTOR_KEYRING ( Linux 2.6.29) . . arg3, arg4 arg5 . , , fork(2) execve(2). libkeyutils keyctl_set_reqkey_keyring(3). KEYCTL_SET_TIMEOUT ( Linux 2.6.16) . arg2 ( key_serial_t). arg3 ( unsigned int). . 0 . /proc/keys ( ). ( request_key(2)). . EKEYEXPIRED. , . arg4 arg5 . libkeyutils keyctl_set_timeout(3). KEYCTL_ASSUME_AUTHORITY ( Linux 2.6.16) ( ) . arg2 ( key_serial_t) 0 . arg2 , . KEYCTL_INSTANTIATE, KEYCTL_INSTANTIATE_IOV, KEYCTL_REJECT KEYCTL_NEGATE. , . , , ( , KEYCTL_ASSUME_AUTHORITY , request-key(8); request_key(2) ). . , . (KEYCTL_READ) , request_key(2). arg2 0, ( 0. KEYCTL_ASSUME_AUTHORITY , request-key(8) , request_key(2). request_key(2) Documentation/security/keys-request-key.txt. arg3, arg4 arg5 . libkeyutils keyctl_assume_authority(3). KEYCTL_GET_SECURITY ( Linux 2.6.26) LSM ( Linux) . arg2 ( key_serial_t) , . ( null) , arg3 ( char *); arg4 ( size_t). arg3 NULL , arg4, , ( null) . . , LSM. , SELinux : unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 LSM , . arg5 . libkeyutils keyctl_get_security(3) keyctl_get_security_alloc(3). KEYCTL_SESSION_TO_PARENT ( Linux 2.6.32) . . . set-user-ID set-group-ID. UID ( ), UID UID . , , , , , ( , new_session keyctl(1)). arg2, arg3, arg4 arg5 . libkeyutils keyctl_session_to_parent(3). KEYCTL_REJECT ( Linux 2.6.39) . KEYCTL_NEGATE, . arg2 ( key_serial_t). arg3 ( unsigned int) . arg4 ( unsigned int) , -- EKEYREJECTED, EKEYREVOKED EKEYEXPIRED. arg5 ( key_serial_t) , KEYCTL_LINK , arg5. . , , request-key(8). request_key(2). . , , request-key(8). request_key(2) . libkeyutils keyctl_reject(3). KEYCTL_INSTANTIATE_IOV ( Linux 2.6.39) , . This operation is the same as KEYCTL_INSTANTIATE, but the payload data is specified as an array of iovec structures (see iovec(3type)). arg3 ( const struct iovec *). arg4 ( unsigned int). arg2 ( ) arg5 ( ) KEYCTL_INSTANTIATE. libkeyutils keyctl_instantiate_iov(3). KEYCTL_INVALIDATE ( Linux 3.5) . , , arg2 ( key_serial_t). , . . , 0. , . , , , /proc/keys ( <>) . arg3, arg4 arg5 . libkeyutils keyctl_invalidate(3). KEYCTL_GET_PERSISTENT ( Linux 3.13) (persistent-keyring(7)) . arg2 ( uid_t). -1, . arg3 ( key_serial_t). CAP_SETUID , . , arg3. . , . KEYCTL_GET_PERSISTENT : /proc/sys/kernel/keys/persistent_keyring_expiry . Persistent keyrings were added in Linux 3.13. arg4 arg5 . libkeyutils keyctl_get_persistent(3). KEYCTL_DH_COMPUTE ( Linux 4.7) -, (key derivation function, KDF). arg2 , "user", -, : struct keyctl_dh_params { int32_t private; /* */ int32_t prime; /* , */ int32_t base; /* : */ }; . - : base ^ private mod prime , . , . arg3 ( char *) , . arg4 ( size_t). , . arg4 , (. ., ). - , (MPI). MPI . DH keyctl() , DH ; DH ( ). arg5 NULL, DH. ( Linux 4.12), , KDF: struct keyctl_kdf_params { char *hashname; /* */ char *otherinfo; /* SP800-56A OtherInfo */ __u32 otherinfolen; /* otherinfo */ __u32 __spare[8]; /* */ }; hashname , null, ( ; ; <> CRYPTO_ALG_TYPE_SHASH ) DH KDF. otherinfo OtherInfo, SP800-56A, 5.8.1.2, . DH KDF. otherinfolen KEYCTL_KDF_MAX_OI_LEN, security/keys/internal.h 64. __spare . Linux 4.13 ( , ), , Linux 4.13, . KDF SP800-56A, SP800-108 ( KDF). This operation is exposed by libkeyutils (from libkeyutils 1.5.10 onwards) via the functions keyctl_dh_compute(3) and keyctl_dh_compute_alloc(3). KEYCTL_RESTRICT_KEYRING ( Linux 4.12) , arg2 ( key_serial_t). setattr . arg3 NULL, ; , arg4 , , . Linux 4.12 <>: builtin_trusted (<<.builtin_trusted_keys>>) , . builtin_and_secondary_trusted (<<.secondary_trusted_keys>>) , , , , . __: __::chain <>, , . , , . <<:chain>> , ( , arg2). , ; , . arg5 . : KEYCTL_GET_KEYRING_ID . KEYCTL_JOIN_SESSION_KEYRING . KEYCTL_DESCRIBE ( null), . KEYCTL_SEARCH . KEYCTL_READ , , . KEYCTL_SET_REQKEY_KEYRING , ( KEY_REQKEY_DEFL_USER_*). KEYCTL_ASSUME_AUTHORITY 0, 0, , , . KEYCTL_GET_SECURITY LSM ( null), . KEYCTL_GET_PERSISTENT . KEYCTL_DH_COMPUTE , , , arg4 0. . -1, errno . EACCES . EAGAIN operation KEYCTL_DH_COMPUTE . EDEADLK operation KEYCTL_LINK . EDEADLK operation KEYCTL_RESTRICT_KEYRING . EDQUOT , . EEXIST operation KEYCTL_RESTRICT_KEYRING arg2 . EFAULT operation KEYCTL_DH_COMPUTE : o struct keyctl_dh_params, arg2, o struct keyctl_kdf_params, arg5 NULL, (, KDF DH) o , hashname struct keyctl_kdf_params o , otherinfo struct keyctl_kdf_params otherinfolen o EINVAL operation KEYCTL_SETPERM arg3 . EINVAL operation was KEYCTL_SEARCH and the size of the description in arg4 (including the terminating null byte) exceeded 4096 bytes. EINVAL size of the string (including the terminating null byte) specified in arg3 (the key type) or arg4 (the key description) exceeded the limit (32 bytes and 4096 bytes respectively). EINVAL (before Linux 4.12) operation KEYCTL_DH_COMPUTE arg5 NULL. EINVAL operation KEYCTL_DH_COMPUTE . EINVAL operation KEYCTL_DH_COMPUTE, . 0 , . EINVAL operation KEYCTL_DH_COMPUTE hashname struct keyctl_kdf_params, arg5, ( , ). EINVAL operation KEYCTL_DH_COMPUTE __spare struct keyctl_kdf_params, arg5, . EKEYEXPIRED . EKEYREJECTED (rejected) . EKEYREVOKED . ELOOP operation KEYCTL_LINK . EMSGSIZE operation KEYCTL_DH_COMPUTE KEYCTL_KDF_MAX_OUTPUT_LEN ( 1024) otherinfolen struct keyctl_kdf_parms, arg5, KEYCTL_KDF_MAX_OI_LEN ( 64). ENFILE (before Linux 3.13) operation KEYCTL_LINK ( Linux 3.13 ; Linux 3.13 ). ENOENT operation KEYCTL_UNLINK . ENOENT operation KEYCTL_DH_COMPUTE , hashname struct keyctl_kdf_params, arg5, . ENOENT operation KEYCTL_RESTRICT_KEYRING arg3 . ENOKEY . ENOKEY operation KEYCTL_GET_KEYRING_ID, , arg2, arg3 ( , , ). ENOMEM . ENOTDIR , . EOPNOTSUPP operation KEYCTL_READ (, "login"). EOPNOTSUPP operation KEYCTL_UPDATE . EOPNOTSUPP operation KEYCTL_RESTRICT_KEYRING, arg3 <> , , arg4, <> <>. EPERM operation KEYCTL_GET_PERSISTENT, arg2 UID, UID , CAP_SETUID. EPERM operation KEYCTL_SESSION_TO_PARENT : UID (GID) UID (GID) ; UID UID UID ; ; init(1) . ETIMEDOUT operation KEYCTL_DH_COMPUTE . A wrapper is provided in the libkeyutils library. (The accompanying package provides the header file.) However, rather than using this system call directly, you probably want to use the various library functions mentioned in the descriptions of individual operations above. Linux. Linux 2.6.10. , , request-key(8) keyutils. . request_key(2), request-key(8) , . . . . , request-key(8) (, request-key(8) ). , , request_key(2) . $ cc -o key_instantiate key_instantiate.c -lkeyutils $ sudo mv /sbin/request-key /sbin/request-key.backup $ sudo cp key_instantiate /sbin/request-key $ ./t_request_key user mykey somepayloaddata 20d035bf $ sudo mv /sbin/request-key.backup /sbin/request-key , , , : $ cat /tmp/key_instantiate.log Time: Mon Nov 7 13:06:47 2016 Command line arguments: argv[0]: /sbin/request-key operation: create key_to_instantiate: 20d035bf UID: 1000 GID: 1000 thread_keyring: 0 process_keyring: 0 session_keyring: 256e6a6 Key description: user;1000;1000;3f010000;mykey Auth key payload: somepayloaddata Destination keyring: 256e6a6 Auth key description: .request_key_auth;1000;1000;0b010000;20d035bf , : o , (mykey); o , (somepayloaddata), request_key(2); o , request_key(2); o , , , (20d035bf). request_key(2) KEY_SPEC_SESSION_KEYRING. /proc/keys, , (0256e6a6), ; mykey 20d035bf. $ cat /proc/keys | egrep 'mykey|256e6a6' 0256e6a6 I--Q--- 194 perm 3f030000 1000 1000 keyring _ses: 3 20d035bf I--Q--- 1 perm 3f010000 1000 1000 user mykey: 16 /* key_instantiate.c */ #include #include #include #include #include #include #include #include #ifndef KEY_SPEC_REQUESTOR_KEYRING #define KEY_SPEC_REQUESTOR_KEYRING (-8) #endif int main(int argc, char *argv[]) { int akp_size; /* Size of auth_key_payload */ int auth_key; char dbuf[256]; char auth_key_payload[256]; char *operation; FILE *fp; gid_t gid; uid_t uid; time_t t; key_serial_t key_to_instantiate, dest_keyring; key_serial_t thread_keyring, process_keyring, session_keyring; if (argc != 8) { fprintf(stderr, "Usage: %s op key uid gid thread_keyring " "process_keyring session_keyring\n", argv[0]); exit(EXIT_FAILURE); } fp = fopen("/tmp/key_instantiate.log", "w"); if (fp == NULL) exit(EXIT_FAILURE); setbuf(fp, NULL); t = time(NULL); fprintf(fp, "Time: %s\n", ctime(&t)); /* * The kernel passes a fixed set of arguments to the program * that it execs; fetch them. */ operation = argv[1]; key_to_instantiate = atoi(argv[2]); uid = atoi(argv[3]); gid = atoi(argv[4]); thread_keyring = atoi(argv[5]); process_keyring = atoi(argv[6]); session_keyring = atoi(argv[7]); fprintf(fp, "Command line arguments:\n"); fprintf(fp, " argv[0]: %s\n", argv[0]); fprintf(fp, " operation: %s\n", operation); fprintf(fp, " key_to_instantiate: %jx\n", (uintmax_t) key_to_instantiate); fprintf(fp, " UID: %jd\n", (intmax_t) uid); fprintf(fp, " GID: %jd\n", (intmax_t) gid); fprintf(fp, " thread_keyring: %jx\n", (uintmax_t) thread_keyring); fprintf(fp, " process_keyring: %jx\n", (uintmax_t) process_keyring); fprintf(fp, " session_keyring: %jx\n", (uintmax_t) session_keyring); fprintf(fp, "\n"); /* * Assume the authority to instantiate the key named in argv[2]. */ if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) { fprintf(fp, "KEYCTL_ASSUME_AUTHORITY failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } /* * Fetch the description of the key that is to be instantiated. */ if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate, dbuf, sizeof(dbuf)) == -1) { fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(fp, "Key description: %s\n", dbuf); /* * Fetch the payload of the authorization key, which is * actually the callout data given to request_key(). */ akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY, auth_key_payload, sizeof(auth_key_payload)); if (akp_size == -1) { fprintf(fp, "KEYCTL_READ failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } auth_key_payload[akp_size] = '\0'; fprintf(fp, "Auth key payload: %s\n", auth_key_payload); /* * For interest, get the ID of the authorization key and * display it. */ auth_key = keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_REQKEY_AUTH_KEY); if (auth_key == -1) { fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(fp, "Auth key ID: %jx\n", (uintmax_t) auth_key); /* * Fetch key ID for the request_key(2) destination keyring. */ dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_REQUESTOR_KEYRING); if (dest_keyring == -1) { fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(fp, "Destination keyring: %jx\n", (uintmax_t) dest_keyring); /* * Fetch the description of the authorization key. This * allows us to see the key type, UID, GID, permissions, * and description (name) of the key. Among other things, * we will see that the name of the key is a hexadecimal * string representing the ID of the key to be instantiated. */ if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY, dbuf, sizeof(dbuf)) == -1) { fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(fp, "Auth key description: %s\n", dbuf); /* * Instantiate the key using the callout data that was supplied * in the payload of the authorization key. */ if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate, auth_key_payload, akp_size + 1, dest_keyring) == -1) { fprintf(fp, "KEYCTL_INSTANTIATE failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } . keyctl(1), add_key(2), request_key(2), keyctl(3), keyctl_assume_authority(3), keyctl_chown(3), keyctl_clear(3), keyctl_describe(3), keyctl_describe_alloc(3), keyctl_dh_compute(3), keyctl_dh_compute_alloc(3), keyctl_get_keyring_ID(3), keyctl_get_persistent(3), keyctl_get_security(3), keyctl_get_security_alloc(3), keyctl_instantiate(3), keyctl_instantiate_iov(3), keyctl_invalidate(3), keyctl_join_session_keyring(3), keyctl_link(3), keyctl_negate(3), keyctl_read(3), keyctl_read_alloc(3), keyctl_reject(3), keyctl_revoke(3), keyctl_search(3), keyctl_session_to_parent(3), keyctl_set_reqkey_keyring(3), keyctl_set_timeout(3), keyctl_setperm(3), keyctl_unlink(3), keyctl_update(3), recursive_key_scan(3), recursive_session_key_scan(3), capabilities(7), credentials(7), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user_namespaces(7), user-session-keyring(7), request-key(8) Documentation/security/keys/ ( Linux 4.13 -- Documentation/security/keys.txt). Alex Nik , Azamat Hackimov , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 1 2023 . keyctl(2)