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: generalize ceph_x_encrypt_offset() and ceph_x_encrypt_buflen()

- introduce the notion of a data offset for ceph_x_encrypt_offset()
to allow for e.g. confounder to be prepended before the encryption
header in the future. For CEPH_CRYPTO_AES, the data offset is 0
(i.e. nothing is prepended).

- adjust ceph_x_encrypt_buflen() accordingly and make it account for
PKCS#7 padding that is used by CEPH_CRYPTO_AES precisely instead of
just always adding 16.

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

+56 -15
+29 -15
net/ceph/auth_x.c
··· 44 44 return !!need; 45 45 } 46 46 47 - static int ceph_x_encrypt_offset(void) 47 + static int __ceph_x_encrypt_offset(const struct ceph_crypto_key *key) 48 48 { 49 - return sizeof(u32) + sizeof(struct ceph_x_encrypt_header); 49 + return ceph_crypt_data_offset(key) + 50 + sizeof(struct ceph_x_encrypt_header); 50 51 } 51 52 52 - static int ceph_x_encrypt_buflen(int ilen) 53 + static int ceph_x_encrypt_offset(const struct ceph_crypto_key *key) 53 54 { 54 - return ceph_x_encrypt_offset() + ilen + 16; 55 + return sizeof(u32) + __ceph_x_encrypt_offset(key); 56 + } 57 + 58 + /* 59 + * AES: ciphertext_len | hdr | data... | padding 60 + */ 61 + static int ceph_x_encrypt_buflen(const struct ceph_crypto_key *key, 62 + int data_len) 63 + { 64 + int encrypt_len = sizeof(struct ceph_x_encrypt_header) + data_len; 65 + return sizeof(u32) + ceph_crypt_buflen(key, encrypt_len); 55 66 } 56 67 57 68 static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, 58 69 int buf_len, int plaintext_len) 59 70 { 60 - struct ceph_x_encrypt_header *hdr = buf + sizeof(u32); 71 + struct ceph_x_encrypt_header *hdr; 61 72 int ciphertext_len; 62 73 int ret; 63 74 75 + hdr = buf + sizeof(u32) + ceph_crypt_data_offset(secret); 64 76 hdr->struct_v = 1; 65 77 hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC); 66 78 ··· 89 77 static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p, 90 78 int ciphertext_len) 91 79 { 92 - struct ceph_x_encrypt_header *hdr = p; 80 + struct ceph_x_encrypt_header *hdr; 93 81 int plaintext_len; 94 82 int ret; 95 83 ··· 98 86 if (ret) 99 87 return ret; 100 88 89 + hdr = p + ceph_crypt_data_offset(secret); 101 90 if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) { 102 91 pr_err("%s bad magic\n", __func__); 103 92 return -EINVAL; ··· 206 193 } 207 194 208 195 /* blob for me */ 209 - dp = *p + ceph_x_encrypt_offset(); 196 + dp = *p + ceph_x_encrypt_offset(secret); 210 197 ret = ceph_x_decrypt(secret, p, end); 211 198 if (ret < 0) 212 199 goto out; ··· 233 220 ceph_decode_8_safe(p, end, is_enc, bad); 234 221 if (is_enc) { 235 222 /* encrypted */ 236 - tp = *p + ceph_x_encrypt_offset(); 223 + tp = *p + ceph_x_encrypt_offset(&th->session_key); 237 224 ret = ceph_x_decrypt(&th->session_key, p, end); 238 225 if (ret < 0) 239 226 goto out; ··· 325 312 p = (void *)(msg_a + 1) + le32_to_cpu(msg_a->ticket_blob.blob_len); 326 313 end = au->buf->vec.iov_base + au->buf->vec.iov_len; 327 314 328 - msg_b = p + ceph_x_encrypt_offset(); 315 + msg_b = p + ceph_x_encrypt_offset(&au->session_key); 329 316 msg_b->struct_v = 2; 330 317 msg_b->nonce = cpu_to_le64(au->nonce); 331 318 if (server_challenge) { ··· 381 368 goto out_au; 382 369 383 370 maxlen = sizeof(*msg_a) + ticket_blob_len + 384 - ceph_x_encrypt_buflen(sizeof(*msg_b)); 371 + ceph_x_encrypt_buflen(&au->session_key, sizeof(*msg_b)); 385 372 dout(" need len %d\n", maxlen); 386 373 if (au->buf && au->buf->alloc_len < maxlen) { 387 374 ceph_buffer_put(au->buf); ··· 520 507 struct ceph_x_authenticate *auth = (void *)(head + 1); 521 508 void *enc_buf = xi->auth_authorizer.enc_buf; 522 509 struct ceph_x_challenge_blob *blob = enc_buf + 523 - ceph_x_encrypt_offset(); 510 + ceph_x_encrypt_offset(&xi->secret); 524 511 u64 *u; 525 512 526 513 p = auth + 1; ··· 647 634 ceph_decode_need(p, end, len, e_inval); 648 635 dout("%s connection secret blob len %d\n", __func__, len); 649 636 if (len > 0) { 650 - dp = *p + ceph_x_encrypt_offset(); 637 + dp = *p + ceph_x_encrypt_offset(&th->session_key); 651 638 ret = ceph_x_decrypt(&th->session_key, p, *p + len); 652 639 if (ret < 0) 653 640 return ret; ··· 817 804 return ret; 818 805 819 806 dout("%s decrypted %d bytes\n", __func__, ret); 820 - dp = challenge + sizeof(struct ceph_x_encrypt_header); 807 + dp = challenge + __ceph_x_encrypt_offset(secret); 821 808 dend = dp + ret; 822 809 823 810 ceph_decode_skip_8(&dp, dend, e_inval); /* struct_v */ ··· 864 851 u8 struct_v; 865 852 int ret; 866 853 867 - dp = *p + ceph_x_encrypt_offset(); 854 + dp = *p + ceph_x_encrypt_offset(secret); 868 855 ret = ceph_x_decrypt(secret, p, end); 869 856 if (ret < 0) 870 857 return ret; ··· 987 974 __le32 front_crc; 988 975 __le32 middle_crc; 989 976 __le32 data_crc; 990 - } __packed *sigblock = enc_buf + ceph_x_encrypt_offset(); 977 + } __packed *sigblock = enc_buf + 978 + ceph_x_encrypt_offset(&au->session_key); 991 979 992 980 sigblock->len = cpu_to_le32(4*sizeof(u32)); 993 981 sigblock->header_crc = msg->hdr.crc;
+25
net/ceph/crypto.c
··· 285 285 } 286 286 } 287 287 288 + int ceph_crypt_data_offset(const struct ceph_crypto_key *key) 289 + { 290 + switch (key->type) { 291 + case CEPH_CRYPTO_NONE: 292 + case CEPH_CRYPTO_AES: 293 + return 0; 294 + default: 295 + BUG(); 296 + } 297 + } 298 + 299 + int ceph_crypt_buflen(const struct ceph_crypto_key *key, int data_len) 300 + { 301 + switch (key->type) { 302 + case CEPH_CRYPTO_NONE: 303 + return data_len; 304 + case CEPH_CRYPTO_AES: 305 + /* PKCS#7 padding at the end */ 306 + return data_len + AES_BLOCK_SIZE - 307 + (data_len & (AES_BLOCK_SIZE - 1)); 308 + default: 309 + BUG(); 310 + } 311 + } 312 + 288 313 static int ceph_key_preparse(struct key_preparsed_payload *prep) 289 314 { 290 315 struct ceph_crypto_key *ckey;
+2
net/ceph/crypto.h
··· 28 28 /* crypto.c */ 29 29 int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, 30 30 void *buf, int buf_len, int in_len, int *pout_len); 31 + int ceph_crypt_data_offset(const struct ceph_crypto_key *key); 32 + int ceph_crypt_buflen(const struct ceph_crypto_key *key, int data_len); 31 33 int ceph_crypto_init(void); 32 34 void ceph_crypto_shutdown(void); 33 35