|
| 1 | +.. SPDX-License-Identifier: GPL-2.0 |
| 2 | +
|
| 3 | +=========================== |
| 4 | +Kerberos V Cryptography API |
| 5 | +=========================== |
| 6 | + |
| 7 | +.. Contents: |
| 8 | +
|
| 9 | + - Overview. |
| 10 | + - Small Buffer. |
| 11 | + - Encoding Type. |
| 12 | + - Key Derivation. |
| 13 | + - PRF+ Calculation. |
| 14 | + - Kc, Ke And Ki Derivation. |
| 15 | + - Crypto Functions. |
| 16 | + - Preparation Functions. |
| 17 | + - Encryption Mode. |
| 18 | + - Checksum Mode. |
| 19 | + - The krb5enc AEAD algorithm |
| 20 | +
|
| 21 | +Overview |
| 22 | +======== |
| 23 | + |
| 24 | +This API provides Kerberos 5-style cryptography for key derivation, encryption |
| 25 | +and checksumming for use in network filesystems and can be used to implement |
| 26 | +the low-level crypto that's needed for GSSAPI. |
| 27 | + |
| 28 | +The following crypto types are supported:: |
| 29 | + |
| 30 | + KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 |
| 31 | + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 |
| 32 | + KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128 |
| 33 | + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192 |
| 34 | + KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC |
| 35 | + KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC |
| 36 | + |
| 37 | + KRB5_CKSUMTYPE_HMAC_SHA1_96_AES128 |
| 38 | + KRB5_CKSUMTYPE_HMAC_SHA1_96_AES256 |
| 39 | + KRB5_CKSUMTYPE_CMAC_CAMELLIA128 |
| 40 | + KRB5_CKSUMTYPE_CMAC_CAMELLIA256 |
| 41 | + KRB5_CKSUMTYPE_HMAC_SHA256_128_AES128 |
| 42 | + KRB5_CKSUMTYPE_HMAC_SHA384_192_AES256 |
| 43 | + |
| 44 | +The API can be included by:: |
| 45 | + |
| 46 | + #include <crypto/krb5.h> |
| 47 | + |
| 48 | +Small Buffer |
| 49 | +------------ |
| 50 | + |
| 51 | +To pass small pieces of data about, such as keys, a buffer structure is |
| 52 | +defined, giving a pointer to the data and the size of that data:: |
| 53 | + |
| 54 | + struct krb5_buffer { |
| 55 | + unsigned int len; |
| 56 | + void *data; |
| 57 | + }; |
| 58 | + |
| 59 | +Encoding Type |
| 60 | +============= |
| 61 | + |
| 62 | +The encoding type is defined by the following structure:: |
| 63 | + |
| 64 | + struct krb5_enctype { |
| 65 | + int etype; |
| 66 | + int ctype; |
| 67 | + const char *name; |
| 68 | + u16 key_bytes; |
| 69 | + u16 key_len; |
| 70 | + u16 Kc_len; |
| 71 | + u16 Ke_len; |
| 72 | + u16 Ki_len; |
| 73 | + u16 prf_len; |
| 74 | + u16 block_len; |
| 75 | + u16 conf_len; |
| 76 | + u16 cksum_len; |
| 77 | + ... |
| 78 | + }; |
| 79 | + |
| 80 | +The fields of interest to the user of the API are as follows: |
| 81 | + |
| 82 | + * ``etype`` and ``ctype`` indicate the protocol number for this encoding |
| 83 | + type for encryption and checksumming respectively. They hold |
| 84 | + ``KRB5_ENCTYPE_*`` and ``KRB5_CKSUMTYPE_*`` constants. |
| 85 | + |
| 86 | + * ``name`` is the formal name of the encoding. |
| 87 | + |
| 88 | + * ``key_len`` and ``key_bytes`` are the input key length and the derived key |
| 89 | + length. (I think they only differ for DES, which isn't supported here). |
| 90 | + |
| 91 | + * ``Kc_len``, ``Ke_len`` and ``Ki_len`` are the sizes of the derived Kc, Ke |
| 92 | + and Ki keys. Kc is used for in checksum mode; Ke and Ki are used in |
| 93 | + encryption mode. |
| 94 | + |
| 95 | + * ``prf_len`` is the size of the result from the PRF+ function calculation. |
| 96 | + |
| 97 | + * ``block_len``, ``conf_len`` and ``cksum_len`` are the encryption block |
| 98 | + length, confounder length and checksum length respectively. All three are |
| 99 | + used in encryption mode, but only the checksum length is used in checksum |
| 100 | + mode. |
| 101 | + |
| 102 | +The encoding type is looked up by number using the following function:: |
| 103 | + |
| 104 | + const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype); |
| 105 | + |
| 106 | +Key Derivation |
| 107 | +============== |
| 108 | + |
| 109 | +Once the application has selected an encryption type, the keys that will be |
| 110 | +used to do the actual crypto can be derived from the transport key. |
| 111 | + |
| 112 | +PRF+ Calculation |
| 113 | +---------------- |
| 114 | + |
| 115 | +To aid in key derivation, a function to calculate the Kerberos GSSAPI |
| 116 | +mechanism's PRF+ is provided:: |
| 117 | + |
| 118 | + int crypto_krb5_calc_PRFplus(const struct krb5_enctype *krb5, |
| 119 | + const struct krb5_buffer *K, |
| 120 | + unsigned int L, |
| 121 | + const struct krb5_buffer *S, |
| 122 | + struct krb5_buffer *result, |
| 123 | + gfp_t gfp); |
| 124 | + |
| 125 | +This can be used to derive the transport key from a source key plus additional |
| 126 | +data to limit its use. |
| 127 | + |
| 128 | +Crypto Functions |
| 129 | +================ |
| 130 | + |
| 131 | +Once the keys have been derived, crypto can be performed on the data. The |
| 132 | +caller must leave gaps in the buffer for the storage of the confounder (if |
| 133 | +needed) and the checksum when preparing a message for transmission. An enum |
| 134 | +and a pair of functions are provided to aid in this:: |
| 135 | + |
| 136 | + enum krb5_crypto_mode { |
| 137 | + KRB5_CHECKSUM_MODE, |
| 138 | + KRB5_ENCRYPT_MODE, |
| 139 | + }; |
| 140 | + |
| 141 | + size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5, |
| 142 | + enum krb5_crypto_mode mode, |
| 143 | + size_t data_size, size_t *_offset); |
| 144 | + |
| 145 | + size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5, |
| 146 | + enum krb5_crypto_mode mode, |
| 147 | + size_t *_buffer_size, size_t *_offset); |
| 148 | + |
| 149 | +All these functions take the encoding type and an indication the mode of crypto |
| 150 | +(checksum-only or full encryption). |
| 151 | + |
| 152 | +The first function returns how big the buffer will need to be to house a given |
| 153 | +amount of data; the second function returns how much data will fit in a buffer |
| 154 | +of a particular size, and adjusts down the size of the required buffer |
| 155 | +accordingly. In both cases, the offset of the data within the buffer is also |
| 156 | +returned. |
| 157 | + |
| 158 | +When a message has been received, the location and size of the data with the |
| 159 | +message can be determined by calling:: |
| 160 | + |
| 161 | + void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5, |
| 162 | + enum krb5_crypto_mode mode, |
| 163 | + size_t *_offset, size_t *_len); |
| 164 | + |
| 165 | +The caller provides the offset and length of the message to the function, which |
| 166 | +then alters those values to indicate the region containing the data (plus any |
| 167 | +padding). It is up to the caller to determine how much padding there is. |
| 168 | + |
| 169 | +Preparation Functions |
| 170 | +--------------------- |
| 171 | + |
| 172 | +Two functions are provided to allocated and prepare a crypto object for use by |
| 173 | +the action functions:: |
| 174 | + |
| 175 | + struct crypto_aead * |
| 176 | + crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5, |
| 177 | + const struct krb5_buffer *TK, |
| 178 | + u32 usage, gfp_t gfp); |
| 179 | + struct crypto_shash * |
| 180 | + crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5, |
| 181 | + const struct krb5_buffer *TK, |
| 182 | + u32 usage, gfp_t gfp); |
| 183 | + |
| 184 | +Both of these functions take the encoding type, the transport key and the usage |
| 185 | +value used to derive the appropriate subkey(s). They create an appropriate |
| 186 | +crypto object, an AEAD template for encryption and a synchronous hash for |
| 187 | +checksumming, set the key(s) on it and configure it. The caller is expected to |
| 188 | +pass these handles to the action functions below. |
| 189 | + |
| 190 | +Encryption Mode |
| 191 | +--------------- |
| 192 | + |
| 193 | +A pair of functions are provided to encrypt and decrypt a message:: |
| 194 | + |
| 195 | + ssize_t crypto_krb5_encrypt(const struct krb5_enctype *krb5, |
| 196 | + struct crypto_aead *aead, |
| 197 | + struct scatterlist *sg, unsigned int nr_sg, |
| 198 | + size_t sg_len, |
| 199 | + size_t data_offset, size_t data_len, |
| 200 | + bool preconfounded); |
| 201 | + int crypto_krb5_decrypt(const struct krb5_enctype *krb5, |
| 202 | + struct crypto_aead *aead, |
| 203 | + struct scatterlist *sg, unsigned int nr_sg, |
| 204 | + size_t *_offset, size_t *_len); |
| 205 | + |
| 206 | +In both cases, the input and output buffers are indicated by the same |
| 207 | +scatterlist. |
| 208 | + |
| 209 | +For the encryption function, the output buffer may be larger than is needed |
| 210 | +(the amount of output generated is returned) and the location and size of the |
| 211 | +data are indicated (which must match the encoding). If no confounder is set, |
| 212 | +the function will insert one. |
| 213 | + |
| 214 | +For the decryption function, the offset and length of the message in buffer are |
| 215 | +supplied and these are shrunk to fit the data. The decryption function will |
| 216 | +verify any checksums within the message and give an error if they don't match. |
| 217 | + |
| 218 | +Checksum Mode |
| 219 | +------------- |
| 220 | + |
| 221 | +A pair of function are provided to generate the checksum on a message and to |
| 222 | +verify that checksum:: |
| 223 | + |
| 224 | + ssize_t crypto_krb5_get_mic(const struct krb5_enctype *krb5, |
| 225 | + struct crypto_shash *shash, |
| 226 | + const struct krb5_buffer *metadata, |
| 227 | + struct scatterlist *sg, unsigned int nr_sg, |
| 228 | + size_t sg_len, |
| 229 | + size_t data_offset, size_t data_len); |
| 230 | + int crypto_krb5_verify_mic(const struct krb5_enctype *krb5, |
| 231 | + struct crypto_shash *shash, |
| 232 | + const struct krb5_buffer *metadata, |
| 233 | + struct scatterlist *sg, unsigned int nr_sg, |
| 234 | + size_t *_offset, size_t *_len); |
| 235 | + |
| 236 | +In both cases, the input and output buffers are indicated by the same |
| 237 | +scatterlist. Additional metadata can be passed in which will get added to the |
| 238 | +hash before the data. |
| 239 | + |
| 240 | +For the get_mic function, the output buffer may be larger than is needed (the |
| 241 | +amount of output generated is returned) and the location and size of the data |
| 242 | +are indicated (which must match the encoding). |
| 243 | + |
| 244 | +For the verification function, the offset and length of the message in buffer |
| 245 | +are supplied and these are shrunk to fit the data. An error will be returned |
| 246 | +if the checksums don't match. |
| 247 | + |
| 248 | +The krb5enc AEAD algorithm |
| 249 | +========================== |
| 250 | + |
| 251 | +A template AEAD crypto algorithm, called "krb5enc", is provided that hashes the |
| 252 | +plaintext before encrypting it (the reverse of authenc). The handle returned |
| 253 | +by ``crypto_krb5_prepare_encryption()`` may be one of these, but there's no |
| 254 | +requirement for the user of this API to interact with it directly. |
| 255 | + |
| 256 | +For reference, its key format begins with a BE32 of the format number. Only |
| 257 | +format 1 is provided and that continues with a BE32 of the Ke key length |
| 258 | +followed by a BE32 of the Ki key length, followed by the bytes from the Ke key |
| 259 | +and then the Ki key. |
| 260 | + |
| 261 | +Using specifically ordered words means that the static test data doesn't |
| 262 | +require byteswapping. |
0 commit comments