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

Configure Feed

Select the types of activity you want to include in your feed.

libceph: add support for CEPH_CRYPTO_AES256KRB5

This is based on AES256-CTS-HMAC384-192 crypto algorithm per RFC 8009
(i.e. Kerberos 5, hence the name) with custom-defined key usage numbers.
The implementation allows a given key to have/be linked to between one
and three usage numbers.

The existing CEPH_CRYPTO_AES remains in place and unchanged. The
usage_slot parameter that needed to be added to ceph_crypt() and its
wrappers is simply ignored there.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

+257 -48
+3 -2
include/linux/ceph/ceph_fs.h
··· 89 89 } __attribute__ ((packed)); 90 90 91 91 /* crypto algorithms */ 92 - #define CEPH_CRYPTO_NONE 0x0 93 - #define CEPH_CRYPTO_AES 0x1 92 + #define CEPH_CRYPTO_NONE 0x0 93 + #define CEPH_CRYPTO_AES 0x1 94 + #define CEPH_CRYPTO_AES256KRB5 0x2 /* AES256-CTS-HMAC384-192 */ 94 95 95 96 #define CEPH_AES_IV "cephsageyudagreg" 96 97
+1
net/ceph/Kconfig
··· 6 6 select CRYPTO_AES 7 7 select CRYPTO_CBC 8 8 select CRYPTO_GCM 9 + select CRYPTO_KRB5 9 10 select CRYPTO_LIB_SHA256 10 11 select CRYPTO 11 12 select KEYS
+61 -27
net/ceph/auth_x.c
··· 17 17 #include "auth_x.h" 18 18 #include "auth_x_protocol.h" 19 19 20 + static const u32 ticket_key_usages[] = { 21 + CEPHX_KEY_USAGE_TICKET_SESSION_KEY, 22 + CEPHX_KEY_USAGE_TICKET_BLOB, 23 + CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET 24 + }; 25 + 26 + static const u32 authorizer_key_usages[] = { 27 + CEPHX_KEY_USAGE_AUTHORIZE, 28 + CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE, 29 + CEPHX_KEY_USAGE_AUTHORIZE_REPLY 30 + }; 31 + 32 + static const u32 client_key_usages[] = { 33 + CEPHX_KEY_USAGE_TICKET_SESSION_KEY 34 + }; 35 + 20 36 static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); 21 37 22 38 static int ceph_x_is_authenticated(struct ceph_auth_client *ac) ··· 73 57 74 58 /* 75 59 * AES: ciphertext_len | hdr | data... | padding 60 + * AES256KRB5: ciphertext_len | confounder | hdr | data... | hmac 76 61 */ 77 62 static int ceph_x_encrypt_buflen(const struct ceph_crypto_key *key, 78 63 int data_len) ··· 82 65 return sizeof(u32) + ceph_crypt_buflen(key, encrypt_len); 83 66 } 84 67 85 - static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, 86 - int buf_len, int plaintext_len) 68 + static int ceph_x_encrypt(const struct ceph_crypto_key *key, int usage_slot, 69 + void *buf, int buf_len, int plaintext_len) 87 70 { 88 71 struct ceph_x_encrypt_header *hdr; 89 72 int ciphertext_len; 90 73 int ret; 91 74 92 - hdr = buf + sizeof(u32) + ceph_crypt_data_offset(secret); 75 + hdr = buf + sizeof(u32) + ceph_crypt_data_offset(key); 93 76 hdr->struct_v = 1; 94 77 hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC); 95 78 96 - ret = ceph_crypt(secret, true, buf + sizeof(u32), buf_len - sizeof(u32), 97 - plaintext_len + sizeof(struct ceph_x_encrypt_header), 79 + ret = ceph_crypt(key, usage_slot, true, buf + sizeof(u32), 80 + buf_len - sizeof(u32), plaintext_len + sizeof(*hdr), 98 81 &ciphertext_len); 99 82 if (ret) 100 83 return ret; ··· 103 86 return sizeof(u32) + ciphertext_len; 104 87 } 105 88 106 - static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p, 107 - int ciphertext_len) 89 + static int __ceph_x_decrypt(const struct ceph_crypto_key *key, int usage_slot, 90 + void *p, int ciphertext_len) 108 91 { 109 92 struct ceph_x_encrypt_header *hdr; 110 93 int plaintext_len; 111 94 int ret; 112 95 113 - ret = ceph_crypt(secret, false, p, ciphertext_len, ciphertext_len, 114 - &plaintext_len); 96 + ret = ceph_crypt(key, usage_slot, false, p, ciphertext_len, 97 + ciphertext_len, &plaintext_len); 115 98 if (ret) 116 99 return ret; 117 100 118 - hdr = p + ceph_crypt_data_offset(secret); 101 + hdr = p + ceph_crypt_data_offset(key); 119 102 if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) { 120 103 pr_err("%s bad magic\n", __func__); 121 104 return -EINVAL; ··· 124 107 return plaintext_len - sizeof(*hdr); 125 108 } 126 109 127 - static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end) 110 + static int ceph_x_decrypt(const struct ceph_crypto_key *key, int usage_slot, 111 + void **p, void *end) 128 112 { 129 113 int ciphertext_len; 130 114 int ret; ··· 133 115 ceph_decode_32_safe(p, end, ciphertext_len, e_inval); 134 116 ceph_decode_need(p, end, ciphertext_len, e_inval); 135 117 136 - ret = __ceph_x_decrypt(secret, *p, ciphertext_len); 118 + ret = __ceph_x_decrypt(key, usage_slot, *p, ciphertext_len); 137 119 if (ret < 0) 138 120 return ret; 139 121 ··· 225 207 226 208 /* blob for me */ 227 209 dp = *p + ceph_x_encrypt_offset(secret); 228 - ret = ceph_x_decrypt(secret, p, end); 210 + ret = ceph_x_decrypt(secret, 211 + 0 /* CEPHX_KEY_USAGE_TICKET_SESSION_KEY */, 212 + p, end); 229 213 if (ret < 0) 230 214 goto out; 231 215 dout(" decrypted %d bytes\n", ret); ··· 241 221 if (ret) 242 222 goto out; 243 223 244 - ret = ceph_crypto_key_prepare(&new_session_key); 224 + ret = ceph_crypto_key_prepare(&new_session_key, ticket_key_usages, 225 + ARRAY_SIZE(ticket_key_usages)); 245 226 if (ret) 246 227 goto out; 247 228 ··· 259 238 if (is_enc) { 260 239 /* encrypted */ 261 240 tp = *p + ceph_x_encrypt_offset(&th->session_key); 262 - ret = ceph_x_decrypt(&th->session_key, p, end); 241 + ret = ceph_x_decrypt(&th->session_key, 242 + 1 /* CEPHX_KEY_USAGE_TICKET_BLOB */, 243 + p, end); 263 244 if (ret < 0) 264 245 goto out; 265 246 dout(" encrypted ticket, decrypted %d bytes\n", ret); ··· 364 341 msg_b->server_challenge_plus_one = 0; 365 342 } 366 343 367 - ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b)); 344 + ret = ceph_x_encrypt(&au->session_key, 345 + 0 /* CEPHX_KEY_USAGE_AUTHORIZE */, 346 + p, end - p, sizeof(*msg_b)); 368 347 if (ret < 0) 369 348 return ret; 370 349 ··· 409 384 if (ret) 410 385 goto out_au; 411 386 412 - ret = ceph_crypto_key_prepare(&au->session_key); 387 + ret = ceph_crypto_key_prepare(&au->session_key, authorizer_key_usages, 388 + ARRAY_SIZE(authorizer_key_usages)); 413 389 if (ret) 414 390 goto out_au; 415 391 ··· 568 542 get_random_bytes(&auth->client_challenge, sizeof(u64)); 569 543 blob->client_challenge = auth->client_challenge; 570 544 blob->server_challenge = cpu_to_le64(xi->server_challenge); 571 - ret = ceph_x_encrypt(&xi->secret, enc_buf, CEPHX_AU_ENC_BUF_LEN, 545 + ret = ceph_x_encrypt(&xi->secret, 0 /* dummy */, 546 + enc_buf, CEPHX_AU_ENC_BUF_LEN, 572 547 sizeof(*blob)); 573 548 if (ret < 0) 574 549 return ret; ··· 683 656 dout("%s connection secret blob len %d\n", __func__, len); 684 657 if (len > 0) { 685 658 dp = *p + ceph_x_encrypt_offset(&th->session_key); 686 - ret = ceph_x_decrypt(&th->session_key, p, *p + len); 659 + ret = ceph_x_decrypt(&th->session_key, 660 + 2 /* CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET */, 661 + p, *p + len); 687 662 if (ret < 0) 688 663 return ret; 689 664 ··· 849 820 int ret; 850 821 851 822 /* no leading len */ 852 - ret = __ceph_x_decrypt(secret, challenge, challenge_len); 823 + ret = __ceph_x_decrypt(secret, 824 + 1 /* CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE */, 825 + challenge, challenge_len); 853 826 if (ret < 0) 854 827 return ret; 855 828 ··· 904 873 int ret; 905 874 906 875 dp = *p + ceph_x_encrypt_offset(secret); 907 - ret = ceph_x_decrypt(secret, p, end); 876 + ret = ceph_x_decrypt(secret, 2 /* CEPHX_KEY_USAGE_AUTHORIZE_REPLY */, 877 + p, end); 908 878 if (ret < 0) 909 879 return ret; 910 880 ··· 1036 1004 sigblock->middle_crc = msg->footer.middle_crc; 1037 1005 sigblock->data_crc = msg->footer.data_crc; 1038 1006 1039 - ret = ceph_x_encrypt(&au->session_key, enc_buf, 1040 - CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock)); 1007 + ret = ceph_x_encrypt(&au->session_key, 0 /* dummy */, 1008 + enc_buf, CEPHX_AU_ENC_BUF_LEN, 1009 + sizeof(*sigblock)); 1041 1010 if (ret < 0) 1042 1011 return ret; 1043 1012 ··· 1069 1036 sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq; 1070 1037 1071 1038 /* no leading len, no ceph_x_encrypt_header */ 1072 - ret = ceph_crypt(&au->session_key, true, enc_buf, 1073 - CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock), 1074 - &ciphertext_len); 1039 + ret = ceph_crypt(&au->session_key, 0 /* dummy */, 1040 + true, enc_buf, CEPHX_AU_ENC_BUF_LEN, 1041 + sizeof(*sigblock), &ciphertext_len); 1075 1042 if (ret) 1076 1043 return ret; 1077 1044 ··· 1163 1130 goto err_xi; 1164 1131 } 1165 1132 1166 - ret = ceph_crypto_key_prepare(&xi->secret); 1133 + ret = ceph_crypto_key_prepare(&xi->secret, client_key_usages, 1134 + ARRAY_SIZE(client_key_usages)); 1167 1135 if (ret) { 1168 1136 pr_err("cannot prepare key: %d\n", ret); 1169 1137 goto err_secret;
+38
net/ceph/auth_x_protocol.h
··· 6 6 #define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200 7 7 #define CEPHX_GET_ROTATING_KEY 0x0400 8 8 9 + /* Client <-> AuthMonitor */ 10 + /* 11 + * The AUTH session's connection secret: encrypted with the AUTH 12 + * ticket session key 13 + */ 14 + #define CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET 0x03 15 + /* 16 + * The ticket's blob for the client ("blob for me", contains the 17 + * session key): encrypted with the client's secret key in case of 18 + * the AUTH ticket and the AUTH ticket session key in case of other 19 + * service tickets 20 + */ 21 + #define CEPHX_KEY_USAGE_TICKET_SESSION_KEY 0x04 22 + /* 23 + * The ticket's blob for the service (ceph_x_ticket_blob): possibly 24 + * encrypted with the old AUTH ticket session key in case of the AUTH 25 + * ticket and not encrypted in case of other service tickets 26 + */ 27 + #define CEPHX_KEY_USAGE_TICKET_BLOB 0x05 28 + 29 + /* Client <-> Service */ 30 + /* 31 + * The client's authorization request (ceph_x_authorize_b): 32 + * encrypted with the service ticket session key 33 + */ 34 + #define CEPHX_KEY_USAGE_AUTHORIZE 0x10 35 + /* 36 + * The service's challenge (ceph_x_authorize_challenge): 37 + * encrypted with the service ticket session key 38 + */ 39 + #define CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE 0x11 40 + /* 41 + * The service's final reply (ceph_x_authorize_reply + the service 42 + * session's connection secret): encrypted with the service ticket 43 + * session key 44 + */ 45 + #define CEPHX_KEY_USAGE_AUTHORIZE_REPLY 0x12 46 + 9 47 /* common bits */ 10 48 struct ceph_x_ticket_blob { 11 49 __u8 struct_v;
+142 -15
net/ceph/crypto.c
··· 7 7 #include <linux/sched.h> 8 8 #include <linux/slab.h> 9 9 #include <crypto/aes.h> 10 + #include <crypto/krb5.h> 10 11 #include <crypto/skcipher.h> 11 12 #include <linux/key-type.h> 12 13 #include <linux/sched/mm.h> ··· 23 22 int ret; 24 23 25 24 noio_flag = memalloc_noio_save(); 26 - key->tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); 25 + key->aes_tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); 27 26 memalloc_noio_restore(noio_flag); 28 - if (IS_ERR(key->tfm)) { 29 - ret = PTR_ERR(key->tfm); 30 - key->tfm = NULL; 27 + if (IS_ERR(key->aes_tfm)) { 28 + ret = PTR_ERR(key->aes_tfm); 29 + key->aes_tfm = NULL; 31 30 return ret; 32 31 } 33 32 34 - ret = crypto_sync_skcipher_setkey(key->tfm, key->key, key->len); 33 + ret = crypto_sync_skcipher_setkey(key->aes_tfm, key->key, key->len); 35 34 if (ret) 36 35 return ret; 37 36 38 37 return 0; 39 38 } 40 39 41 - int ceph_crypto_key_prepare(struct ceph_crypto_key *key) 40 + static int set_krb5_tfms(struct ceph_crypto_key *key, const u32 *key_usages, 41 + int key_usage_cnt) 42 + { 43 + struct krb5_buffer TK = { .len = key->len, .data = key->key }; 44 + unsigned int noio_flag; 45 + int ret = 0; 46 + int i; 47 + 48 + if (WARN_ON_ONCE(key_usage_cnt > ARRAY_SIZE(key->krb5_tfms))) 49 + return -EINVAL; 50 + 51 + key->krb5_type = crypto_krb5_find_enctype( 52 + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192); 53 + if (!key->krb5_type) 54 + return -ENOPKG; 55 + 56 + /* 57 + * Despite crypto_krb5_prepare_encryption() taking a gfp mask, 58 + * crypto_alloc_aead() inside of it allocates with GFP_KERNEL. 59 + */ 60 + noio_flag = memalloc_noio_save(); 61 + for (i = 0; i < key_usage_cnt; i++) { 62 + key->krb5_tfms[i] = crypto_krb5_prepare_encryption( 63 + key->krb5_type, &TK, key_usages[i], 64 + GFP_NOIO); 65 + if (IS_ERR(key->krb5_tfms[i])) { 66 + ret = PTR_ERR(key->krb5_tfms[i]); 67 + key->krb5_tfms[i] = NULL; 68 + goto out_flag; 69 + } 70 + } 71 + 72 + out_flag: 73 + memalloc_noio_restore(noio_flag); 74 + return ret; 75 + } 76 + 77 + int ceph_crypto_key_prepare(struct ceph_crypto_key *key, 78 + const u32 *key_usages, int key_usage_cnt) 42 79 { 43 80 switch (key->type) { 44 81 case CEPH_CRYPTO_NONE: 45 82 return 0; /* nothing to do */ 46 83 case CEPH_CRYPTO_AES: 47 84 return set_aes_tfm(key); 85 + case CEPH_CRYPTO_AES256KRB5: 86 + return set_krb5_tfms(key, key_usages, key_usage_cnt); 48 87 default: 49 88 return -ENOTSUPP; 50 89 } ··· 164 123 165 124 void ceph_crypto_key_destroy(struct ceph_crypto_key *key) 166 125 { 167 - if (key) { 168 - kfree_sensitive(key->key); 169 - key->key = NULL; 170 - if (key->tfm) { 171 - crypto_free_sync_skcipher(key->tfm); 172 - key->tfm = NULL; 126 + int i; 127 + 128 + if (!key) 129 + return; 130 + 131 + kfree_sensitive(key->key); 132 + key->key = NULL; 133 + 134 + if (key->type == CEPH_CRYPTO_AES) { 135 + if (key->aes_tfm) { 136 + crypto_free_sync_skcipher(key->aes_tfm); 137 + key->aes_tfm = NULL; 138 + } 139 + } else if (key->type == CEPH_CRYPTO_AES256KRB5) { 140 + for (i = 0; i < ARRAY_SIZE(key->krb5_tfms); i++) { 141 + if (key->krb5_tfms[i]) { 142 + crypto_free_aead(key->krb5_tfms[i]); 143 + key->krb5_tfms[i] = NULL; 144 + } 173 145 } 174 146 } 175 147 } ··· 262 208 static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, 263 209 void *buf, int buf_len, int in_len, int *pout_len) 264 210 { 265 - SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm); 211 + SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->aes_tfm); 266 212 struct sg_table sgt; 267 213 struct scatterlist prealloc_sg; 268 214 char iv[AES_BLOCK_SIZE] __aligned(8); ··· 278 224 return ret; 279 225 280 226 memcpy(iv, aes_iv, AES_BLOCK_SIZE); 281 - skcipher_request_set_sync_tfm(req, key->tfm); 227 + skcipher_request_set_sync_tfm(req, key->aes_tfm); 282 228 skcipher_request_set_callback(req, 0, NULL, NULL); 283 229 skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv); 284 230 ··· 323 269 return ret; 324 270 } 325 271 326 - int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, 272 + static int ceph_krb5_encrypt(const struct ceph_crypto_key *key, int usage_slot, 273 + void *buf, int buf_len, int in_len, int *pout_len) 274 + { 275 + struct sg_table sgt; 276 + struct scatterlist prealloc_sg; 277 + int ret; 278 + 279 + if (WARN_ON_ONCE(usage_slot >= ARRAY_SIZE(key->krb5_tfms))) 280 + return -EINVAL; 281 + 282 + ret = setup_sgtable(&sgt, &prealloc_sg, buf, buf_len); 283 + if (ret) 284 + return ret; 285 + 286 + ret = crypto_krb5_encrypt(key->krb5_type, key->krb5_tfms[usage_slot], 287 + sgt.sgl, sgt.nents, buf_len, AES_BLOCK_SIZE, 288 + in_len, false); 289 + if (ret < 0) { 290 + pr_err("%s encrypt failed: %d\n", __func__, ret); 291 + goto out_sgt; 292 + } 293 + 294 + *pout_len = ret; 295 + ret = 0; 296 + 297 + out_sgt: 298 + teardown_sgtable(&sgt); 299 + return ret; 300 + } 301 + 302 + static int ceph_krb5_decrypt(const struct ceph_crypto_key *key, int usage_slot, 303 + void *buf, int buf_len, int in_len, int *pout_len) 304 + { 305 + struct sg_table sgt; 306 + struct scatterlist prealloc_sg; 307 + size_t data_off = 0; 308 + size_t data_len = in_len; 309 + int ret; 310 + 311 + if (WARN_ON_ONCE(usage_slot >= ARRAY_SIZE(key->krb5_tfms))) 312 + return -EINVAL; 313 + 314 + ret = setup_sgtable(&sgt, &prealloc_sg, buf, in_len); 315 + if (ret) 316 + return ret; 317 + 318 + ret = crypto_krb5_decrypt(key->krb5_type, key->krb5_tfms[usage_slot], 319 + sgt.sgl, sgt.nents, &data_off, &data_len); 320 + if (ret) { 321 + pr_err("%s decrypt failed: %d\n", __func__, ret); 322 + goto out_sgt; 323 + } 324 + 325 + WARN_ON(data_off != AES_BLOCK_SIZE); 326 + *pout_len = data_len; 327 + 328 + out_sgt: 329 + teardown_sgtable(&sgt); 330 + return ret; 331 + } 332 + 333 + int ceph_crypt(const struct ceph_crypto_key *key, int usage_slot, bool encrypt, 327 334 void *buf, int buf_len, int in_len, int *pout_len) 328 335 { 329 336 switch (key->type) { ··· 393 278 return 0; 394 279 case CEPH_CRYPTO_AES: 395 280 return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len, 281 + pout_len); 282 + case CEPH_CRYPTO_AES256KRB5: 283 + return encrypt ? 284 + ceph_krb5_encrypt(key, usage_slot, buf, buf_len, in_len, 285 + pout_len) : 286 + ceph_krb5_decrypt(key, usage_slot, buf, buf_len, in_len, 396 287 pout_len); 397 288 default: 398 289 return -ENOTSUPP; ··· 411 290 case CEPH_CRYPTO_NONE: 412 291 case CEPH_CRYPTO_AES: 413 292 return 0; 293 + case CEPH_CRYPTO_AES256KRB5: 294 + /* confounder */ 295 + return AES_BLOCK_SIZE; 414 296 default: 415 297 BUG(); 416 298 } ··· 428 304 /* PKCS#7 padding at the end */ 429 305 return data_len + AES_BLOCK_SIZE - 430 306 (data_len & (AES_BLOCK_SIZE - 1)); 307 + case CEPH_CRYPTO_AES256KRB5: 308 + /* confounder at the beginning and 192-bit HMAC at the end */ 309 + return AES_BLOCK_SIZE + data_len + 24; 431 310 default: 432 311 BUG(); 433 312 }
+12 -4
net/ceph/crypto.h
··· 5 5 #include <linux/ceph/types.h> 6 6 #include <linux/ceph/buffer.h> 7 7 8 - #define CEPH_MAX_KEY_LEN 16 8 + #define CEPH_MAX_KEY_LEN 32 9 9 #define CEPH_MAX_CON_SECRET_LEN 64 10 10 11 11 /* ··· 16 16 struct ceph_timespec created; 17 17 int len; 18 18 void *key; 19 - struct crypto_sync_skcipher *tfm; 19 + 20 + union { 21 + struct crypto_sync_skcipher *aes_tfm; 22 + struct { 23 + const struct krb5_enctype *krb5_type; 24 + struct crypto_aead *krb5_tfms[3]; 25 + }; 26 + }; 20 27 }; 21 28 22 - int ceph_crypto_key_prepare(struct ceph_crypto_key *key); 29 + int ceph_crypto_key_prepare(struct ceph_crypto_key *key, 30 + const u32 *key_usages, int key_usage_cnt); 23 31 int ceph_crypto_key_clone(struct ceph_crypto_key *dst, 24 32 const struct ceph_crypto_key *src); 25 33 int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end); ··· 35 27 void ceph_crypto_key_destroy(struct ceph_crypto_key *key); 36 28 37 29 /* crypto.c */ 38 - int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, 30 + int ceph_crypt(const struct ceph_crypto_key *key, int usage_slot, bool encrypt, 39 31 void *buf, int buf_len, int in_len, int *pout_len); 40 32 int ceph_crypt_data_offset(const struct ceph_crypto_key *key); 41 33 int ceph_crypt_buflen(const struct ceph_crypto_key *key, int data_len);