1*4882a593Smuzhiyun=================== 2*4882a593SmuzhiyunKey Request Service 3*4882a593Smuzhiyun=================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThe key request service is part of the key retention service (refer to 6*4882a593SmuzhiyunDocumentation/security/keys/core.rst). This document explains more fully how 7*4882a593Smuzhiyunthe requesting algorithm works. 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunThe process starts by either the kernel requesting a service by calling 10*4882a593Smuzhiyun``request_key*()``:: 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun struct key *request_key(const struct key_type *type, 13*4882a593Smuzhiyun const char *description, 14*4882a593Smuzhiyun const char *callout_info); 15*4882a593Smuzhiyun 16*4882a593Smuzhiyunor:: 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun struct key *request_key_tag(const struct key_type *type, 19*4882a593Smuzhiyun const char *description, 20*4882a593Smuzhiyun const struct key_tag *domain_tag, 21*4882a593Smuzhiyun const char *callout_info); 22*4882a593Smuzhiyun 23*4882a593Smuzhiyunor:: 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun struct key *request_key_with_auxdata(const struct key_type *type, 26*4882a593Smuzhiyun const char *description, 27*4882a593Smuzhiyun const struct key_tag *domain_tag, 28*4882a593Smuzhiyun const char *callout_info, 29*4882a593Smuzhiyun size_t callout_len, 30*4882a593Smuzhiyun void *aux); 31*4882a593Smuzhiyun 32*4882a593Smuzhiyunor:: 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun struct key *request_key_rcu(const struct key_type *type, 35*4882a593Smuzhiyun const char *description, 36*4882a593Smuzhiyun const struct key_tag *domain_tag); 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunOr by userspace invoking the request_key system call:: 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun key_serial_t request_key(const char *type, 41*4882a593Smuzhiyun const char *description, 42*4882a593Smuzhiyun const char *callout_info, 43*4882a593Smuzhiyun key_serial_t dest_keyring); 44*4882a593Smuzhiyun 45*4882a593SmuzhiyunThe main difference between the access points is that the in-kernel interface 46*4882a593Smuzhiyundoes not need to link the key to a keyring to prevent it from being immediately 47*4882a593Smuzhiyundestroyed. The kernel interface returns a pointer directly to the key, and 48*4882a593Smuzhiyunit's up to the caller to destroy the key. 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunThe request_key_tag() call is like the in-kernel request_key(), except that it 51*4882a593Smuzhiyunalso takes a domain tag that allows keys to be separated by namespace and 52*4882a593Smuzhiyunkilled off as a group. 53*4882a593Smuzhiyun 54*4882a593SmuzhiyunThe request_key_with_auxdata() calls is like the request_key_tag() call, except 55*4882a593Smuzhiyunthat they permit auxiliary data to be passed to the upcaller (the default is 56*4882a593SmuzhiyunNULL). This is only useful for those key types that define their own upcall 57*4882a593Smuzhiyunmechanism rather than using /sbin/request-key. 58*4882a593Smuzhiyun 59*4882a593SmuzhiyunThe request_key_rcu() call is like the request_key_tag() call, except that it 60*4882a593Smuzhiyundoesn't check for keys that are under construction and doesn't attempt to 61*4882a593Smuzhiyunconstruct missing keys. 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunThe userspace interface links the key to a keyring associated with the process 64*4882a593Smuzhiyunto prevent the key from going away, and returns the serial number of the key to 65*4882a593Smuzhiyunthe caller. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun 68*4882a593SmuzhiyunThe following example assumes that the key types involved don't define their 69*4882a593Smuzhiyunown upcall mechanisms. If they do, then those should be substituted for the 70*4882a593Smuzhiyunforking and execution of /sbin/request-key. 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunThe Process 74*4882a593Smuzhiyun=========== 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunA request proceeds in the following manner: 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun 1) Process A calls request_key() [the userspace syscall calls the kernel 79*4882a593Smuzhiyun interface]. 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun 2) request_key() searches the process's subscribed keyrings to see if there's 82*4882a593Smuzhiyun a suitable key there. If there is, it returns the key. If there isn't, 83*4882a593Smuzhiyun and callout_info is not set, an error is returned. Otherwise the process 84*4882a593Smuzhiyun proceeds to the next step. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun 3) request_key() sees that A doesn't have the desired key yet, so it creates 87*4882a593Smuzhiyun two things: 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun a) An uninstantiated key U of requested type and description. 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun b) An authorisation key V that refers to key U and notes that process A 92*4882a593Smuzhiyun is the context in which key U should be instantiated and secured, and 93*4882a593Smuzhiyun from which associated key requests may be satisfied. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun 4) request_key() then forks and executes /sbin/request-key with a new session 96*4882a593Smuzhiyun keyring that contains a link to auth key V. 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun 5) /sbin/request-key assumes the authority associated with key U. 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun 6) /sbin/request-key execs an appropriate program to perform the actual 101*4882a593Smuzhiyun instantiation. 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun 7) The program may want to access another key from A's context (say a 104*4882a593Smuzhiyun Kerberos TGT key). It just requests the appropriate key, and the keyring 105*4882a593Smuzhiyun search notes that the session keyring has auth key V in its bottom level. 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun This will permit it to then search the keyrings of process A with the 108*4882a593Smuzhiyun UID, GID, groups and security info of process A as if it was process A, 109*4882a593Smuzhiyun and come up with key W. 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun 8) The program then does what it must to get the data with which to 112*4882a593Smuzhiyun instantiate key U, using key W as a reference (perhaps it contacts a 113*4882a593Smuzhiyun Kerberos server using the TGT) and then instantiates key U. 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun 9) Upon instantiating key U, auth key V is automatically revoked so that it 116*4882a593Smuzhiyun may not be used again. 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun 10) The program then exits 0 and request_key() deletes key V and returns key 119*4882a593Smuzhiyun U to the caller. 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunThis also extends further. If key W (step 7 above) didn't exist, key W would 122*4882a593Smuzhiyunbe created uninstantiated, another auth key (X) would be created (as per step 123*4882a593Smuzhiyun3) and another copy of /sbin/request-key spawned (as per step 4); but the 124*4882a593Smuzhiyuncontext specified by auth key X will still be process A, as it was in auth key 125*4882a593SmuzhiyunV. 126*4882a593Smuzhiyun 127*4882a593SmuzhiyunThis is because process A's keyrings can't simply be attached to 128*4882a593Smuzhiyun/sbin/request-key at the appropriate places because (a) execve will discard two 129*4882a593Smuzhiyunof them, and (b) it requires the same UID/GID/Groups all the way through. 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun 132*4882a593SmuzhiyunNegative Instantiation And Rejection 133*4882a593Smuzhiyun==================================== 134*4882a593Smuzhiyun 135*4882a593SmuzhiyunRather than instantiating a key, it is possible for the possessor of an 136*4882a593Smuzhiyunauthorisation key to negatively instantiate a key that's under construction. 137*4882a593SmuzhiyunThis is a short duration placeholder that causes any attempt at re-requesting 138*4882a593Smuzhiyunthe key while it exists to fail with error ENOKEY if negated or the specified 139*4882a593Smuzhiyunerror if rejected. 140*4882a593Smuzhiyun 141*4882a593SmuzhiyunThis is provided to prevent excessive repeated spawning of /sbin/request-key 142*4882a593Smuzhiyunprocesses for a key that will never be obtainable. 143*4882a593Smuzhiyun 144*4882a593SmuzhiyunShould the /sbin/request-key process exit anything other than 0 or die on a 145*4882a593Smuzhiyunsignal, the key under construction will be automatically negatively 146*4882a593Smuzhiyuninstantiated for a short amount of time. 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun 149*4882a593SmuzhiyunThe Search Algorithm 150*4882a593Smuzhiyun==================== 151*4882a593Smuzhiyun 152*4882a593SmuzhiyunA search of any particular keyring proceeds in the following fashion: 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun 1) When the key management code searches for a key (keyring_search_rcu) it 155*4882a593Smuzhiyun firstly calls key_permission(SEARCH) on the keyring it's starting with, 156*4882a593Smuzhiyun if this denies permission, it doesn't search further. 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun 2) It considers all the non-keyring keys within that keyring and, if any key 159*4882a593Smuzhiyun matches the criteria specified, calls key_permission(SEARCH) on it to see 160*4882a593Smuzhiyun if the key is allowed to be found. If it is, that key is returned; if 161*4882a593Smuzhiyun not, the search continues, and the error code is retained if of higher 162*4882a593Smuzhiyun priority than the one currently set. 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun 3) It then considers all the keyring-type keys in the keyring it's currently 165*4882a593Smuzhiyun searching. It calls key_permission(SEARCH) on each keyring, and if this 166*4882a593Smuzhiyun grants permission, it recurses, executing steps (2) and (3) on that 167*4882a593Smuzhiyun keyring. 168*4882a593Smuzhiyun 169*4882a593SmuzhiyunThe process stops immediately a valid key is found with permission granted to 170*4882a593Smuzhiyunuse it. Any error from a previous match attempt is discarded and the key is 171*4882a593Smuzhiyunreturned. 172*4882a593Smuzhiyun 173*4882a593SmuzhiyunWhen request_key() is invoked, if CONFIG_KEYS_REQUEST_CACHE=y, a per-task 174*4882a593Smuzhiyunone-key cache is first checked for a match. 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunWhen search_process_keyrings() is invoked, it performs the following searches 177*4882a593Smuzhiyununtil one succeeds: 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun 1) If extant, the process's thread keyring is searched. 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun 2) If extant, the process's process keyring is searched. 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun 3) The process's session keyring is searched. 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun 4) If the process has assumed the authority associated with a request_key() 186*4882a593Smuzhiyun authorisation key then: 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun a) If extant, the calling process's thread keyring is searched. 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun b) If extant, the calling process's process keyring is searched. 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun c) The calling process's session keyring is searched. 193*4882a593Smuzhiyun 194*4882a593SmuzhiyunThe moment one succeeds, all pending errors are discarded and the found key is 195*4882a593Smuzhiyunreturned. If CONFIG_KEYS_REQUEST_CACHE=y, then that key is placed in the 196*4882a593Smuzhiyunper-task cache, displacing the previous key. The cache is cleared on exit or 197*4882a593Smuzhiyunjust prior to resumption of userspace. 198*4882a593Smuzhiyun 199*4882a593SmuzhiyunOnly if all these fail does the whole thing fail with the highest priority 200*4882a593Smuzhiyunerror. Note that several errors may have come from LSM. 201*4882a593Smuzhiyun 202*4882a593SmuzhiyunThe error priority is:: 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun EKEYREVOKED > EKEYEXPIRED > ENOKEY 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunEACCES/EPERM are only returned on a direct search of a specific keyring where 207*4882a593Smuzhiyunthe basal keyring does not grant Search permission. 208