Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto/krb5: Add an API to alloc and prepare a crypto object

Add an API by which users of the krb5 crypto library can get an allocated
and keyed crypto object.

For encryption-mode operation, an AEAD object is returned; for
checksum-mode operation, a synchronous hash object is returned.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: "David S. Miller" <davem@davemloft.net>
cc: Chuck Lever <chuck.lever@oracle.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: linux-nfs@vger.kernel.org
cc: linux-crypto@vger.kernel.org
cc: netdev@vger.kernel.org

+161
+10
crypto/krb5/internal.h
··· 110 110 #define krb5_digest_size(TFM) \ 111 111 crypto_roundup(crypto_shash_digestsize(TFM)) 112 112 #define round16(x) (((x) + 15) & ~15) 113 + 114 + /* 115 + * krb5_api.c 116 + */ 117 + struct crypto_aead *krb5_prepare_encryption(const struct krb5_enctype *krb5, 118 + const struct krb5_buffer *keys, 119 + gfp_t gfp); 120 + struct crypto_shash *krb5_prepare_checksum(const struct krb5_enctype *krb5, 121 + const struct krb5_buffer *Kc, 122 + gfp_t gfp);
+144
crypto/krb5/krb5_api.c
··· 148 148 } 149 149 } 150 150 EXPORT_SYMBOL(crypto_krb5_where_is_the_data); 151 + 152 + /* 153 + * Prepare the encryption with derived key data. 154 + */ 155 + struct crypto_aead *krb5_prepare_encryption(const struct krb5_enctype *krb5, 156 + const struct krb5_buffer *keys, 157 + gfp_t gfp) 158 + { 159 + struct crypto_aead *ci = NULL; 160 + int ret = -ENOMEM; 161 + 162 + ci = crypto_alloc_aead(krb5->encrypt_name, 0, 0); 163 + if (IS_ERR(ci)) { 164 + ret = PTR_ERR(ci); 165 + if (ret == -ENOENT) 166 + ret = -ENOPKG; 167 + goto err; 168 + } 169 + 170 + ret = crypto_aead_setkey(ci, keys->data, keys->len); 171 + if (ret < 0) { 172 + pr_err("Couldn't set AEAD key %s: %d\n", krb5->encrypt_name, ret); 173 + goto err_ci; 174 + } 175 + 176 + ret = crypto_aead_setauthsize(ci, krb5->cksum_len); 177 + if (ret < 0) { 178 + pr_err("Couldn't set AEAD authsize %s: %d\n", krb5->encrypt_name, ret); 179 + goto err_ci; 180 + } 181 + 182 + return ci; 183 + err_ci: 184 + crypto_free_aead(ci); 185 + err: 186 + return ERR_PTR(ret); 187 + } 188 + 189 + /** 190 + * crypto_krb5_prepare_encryption - Prepare AEAD crypto object for encryption-mode 191 + * @krb5: The encoding to use. 192 + * @TK: The transport key to use. 193 + * @usage: The usage constant for key derivation. 194 + * @gfp: Allocation flags. 195 + * 196 + * Allocate a crypto object that does all the necessary crypto, key it and set 197 + * its parameters and return the crypto handle to it. This can then be used to 198 + * dispatch encrypt and decrypt operations. 199 + */ 200 + struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5, 201 + const struct krb5_buffer *TK, 202 + u32 usage, gfp_t gfp) 203 + { 204 + struct crypto_aead *ci = NULL; 205 + struct krb5_buffer keys = {}; 206 + int ret; 207 + 208 + ret = krb5->profile->derive_encrypt_keys(krb5, TK, usage, &keys, gfp); 209 + if (ret < 0) 210 + goto err; 211 + 212 + ci = krb5_prepare_encryption(krb5, &keys, gfp); 213 + if (IS_ERR(ci)) { 214 + ret = PTR_ERR(ci); 215 + goto err; 216 + } 217 + 218 + kfree(keys.data); 219 + return ci; 220 + err: 221 + kfree(keys.data); 222 + return ERR_PTR(ret); 223 + } 224 + EXPORT_SYMBOL(crypto_krb5_prepare_encryption); 225 + 226 + /* 227 + * Prepare the checksum with derived key data. 228 + */ 229 + struct crypto_shash *krb5_prepare_checksum(const struct krb5_enctype *krb5, 230 + const struct krb5_buffer *Kc, 231 + gfp_t gfp) 232 + { 233 + struct crypto_shash *ci = NULL; 234 + int ret = -ENOMEM; 235 + 236 + ci = crypto_alloc_shash(krb5->cksum_name, 0, 0); 237 + if (IS_ERR(ci)) { 238 + ret = PTR_ERR(ci); 239 + if (ret == -ENOENT) 240 + ret = -ENOPKG; 241 + goto err; 242 + } 243 + 244 + ret = crypto_shash_setkey(ci, Kc->data, Kc->len); 245 + if (ret < 0) { 246 + pr_err("Couldn't set shash key %s: %d\n", krb5->cksum_name, ret); 247 + goto err_ci; 248 + } 249 + 250 + return ci; 251 + err_ci: 252 + crypto_free_shash(ci); 253 + err: 254 + return ERR_PTR(ret); 255 + } 256 + 257 + /** 258 + * crypto_krb5_prepare_checksum - Prepare AEAD crypto object for checksum-mode 259 + * @krb5: The encoding to use. 260 + * @TK: The transport key to use. 261 + * @usage: The usage constant for key derivation. 262 + * @gfp: Allocation flags. 263 + * 264 + * Allocate a crypto object that does all the necessary crypto, key it and set 265 + * its parameters and return the crypto handle to it. This can then be used to 266 + * dispatch get_mic and verify_mic operations. 267 + */ 268 + struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5, 269 + const struct krb5_buffer *TK, 270 + u32 usage, gfp_t gfp) 271 + { 272 + struct crypto_shash *ci = NULL; 273 + struct krb5_buffer keys = {}; 274 + int ret; 275 + 276 + ret = krb5->profile->derive_checksum_key(krb5, TK, usage, &keys, gfp); 277 + if (ret < 0) { 278 + pr_err("get_Kc failed %d\n", ret); 279 + goto err; 280 + } 281 + 282 + ci = krb5_prepare_checksum(krb5, &keys, gfp); 283 + if (IS_ERR(ci)) { 284 + ret = PTR_ERR(ci); 285 + goto err; 286 + } 287 + 288 + kfree(keys.data); 289 + return ci; 290 + err: 291 + kfree(keys.data); 292 + return ERR_PTR(ret); 293 + } 294 + EXPORT_SYMBOL(crypto_krb5_prepare_checksum);
+7
include/crypto/krb5.h
··· 10 10 11 11 #include <linux/crypto.h> 12 12 #include <crypto/aead.h> 13 + #include <crypto/hash.h> 13 14 14 15 struct crypto_shash; 15 16 struct scatterlist; ··· 111 110 void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5, 112 111 enum krb5_crypto_mode mode, 113 112 size_t *_offset, size_t *_len); 113 + struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5, 114 + const struct krb5_buffer *TK, 115 + u32 usage, gfp_t gfp); 116 + struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5, 117 + const struct krb5_buffer *TK, 118 + u32 usage, gfp_t gfp); 114 119 115 120 #endif /* _CRYPTO_KRB5_H */