57
57
#define IN_S_HANDLE_CONTROL_REMAINDER 3
58
58
#define IN_S_PREPARE_READ_DATA 4
59
59
#define IN_S_PREPARE_READ_DATA_CONT 5
60
- #define IN_S_HANDLE_EPILOGUE 6
61
- #define IN_S_FINISH_SKIP 7
60
+ #define IN_S_PREPARE_READ_ENC_PAGE 6
61
+ #define IN_S_HANDLE_EPILOGUE 7
62
+ #define IN_S_FINISH_SKIP 8
62
63
63
64
#define OUT_S_QUEUE_DATA 1
64
65
#define OUT_S_QUEUE_DATA_CONT 2
@@ -1032,22 +1033,41 @@ static int decrypt_control_remainder(struct ceph_connection *con)
1032
1033
padded_len (rem_len ) + CEPH_GCM_TAG_LEN );
1033
1034
}
1034
1035
1035
- static int decrypt_message (struct ceph_connection * con )
1036
+ static int decrypt_tail (struct ceph_connection * con )
1036
1037
{
1038
+ struct sg_table enc_sgt = {};
1037
1039
struct sg_table sgt = {};
1040
+ int tail_len ;
1038
1041
int ret ;
1039
1042
1043
+ tail_len = tail_onwire_len (con -> in_msg , true);
1044
+ ret = sg_alloc_table_from_pages (& enc_sgt , con -> v2 .in_enc_pages ,
1045
+ con -> v2 .in_enc_page_cnt , 0 , tail_len ,
1046
+ GFP_NOIO );
1047
+ if (ret )
1048
+ goto out ;
1049
+
1040
1050
ret = setup_message_sgs (& sgt , con -> in_msg , FRONT_PAD (con -> v2 .in_buf ),
1041
1051
MIDDLE_PAD (con -> v2 .in_buf ), DATA_PAD (con -> v2 .in_buf ),
1042
1052
con -> v2 .in_buf , true);
1043
1053
if (ret )
1044
1054
goto out ;
1045
1055
1046
- ret = gcm_crypt (con , false, sgt .sgl , sgt .sgl ,
1047
- tail_onwire_len (con -> in_msg , true));
1056
+ dout ("%s con %p msg %p enc_page_cnt %d sg_cnt %d\n" , __func__ , con ,
1057
+ con -> in_msg , con -> v2 .in_enc_page_cnt , sgt .orig_nents );
1058
+ ret = gcm_crypt (con , false, enc_sgt .sgl , sgt .sgl , tail_len );
1059
+ if (ret )
1060
+ goto out ;
1061
+
1062
+ WARN_ON (!con -> v2 .in_enc_page_cnt );
1063
+ ceph_release_page_vector (con -> v2 .in_enc_pages ,
1064
+ con -> v2 .in_enc_page_cnt );
1065
+ con -> v2 .in_enc_pages = NULL ;
1066
+ con -> v2 .in_enc_page_cnt = 0 ;
1048
1067
1049
1068
out :
1050
1069
sg_free_table (& sgt );
1070
+ sg_free_table (& enc_sgt );
1051
1071
return ret ;
1052
1072
}
1053
1073
@@ -1737,8 +1757,7 @@ static void prepare_read_data(struct ceph_connection *con)
1737
1757
{
1738
1758
struct bio_vec bv ;
1739
1759
1740
- if (!con_secure (con ))
1741
- con -> in_data_crc = -1 ;
1760
+ con -> in_data_crc = -1 ;
1742
1761
ceph_msg_data_cursor_init (& con -> v2 .in_cursor , con -> in_msg ,
1743
1762
data_len (con -> in_msg ));
1744
1763
@@ -1751,11 +1770,10 @@ static void prepare_read_data_cont(struct ceph_connection *con)
1751
1770
{
1752
1771
struct bio_vec bv ;
1753
1772
1754
- if (!con_secure (con ))
1755
- con -> in_data_crc = ceph_crc32c_page (con -> in_data_crc ,
1756
- con -> v2 .in_bvec .bv_page ,
1757
- con -> v2 .in_bvec .bv_offset ,
1758
- con -> v2 .in_bvec .bv_len );
1773
+ con -> in_data_crc = ceph_crc32c_page (con -> in_data_crc ,
1774
+ con -> v2 .in_bvec .bv_page ,
1775
+ con -> v2 .in_bvec .bv_offset ,
1776
+ con -> v2 .in_bvec .bv_len );
1759
1777
1760
1778
ceph_msg_data_advance (& con -> v2 .in_cursor , con -> v2 .in_bvec .bv_len );
1761
1779
if (con -> v2 .in_cursor .total_resid ) {
@@ -1766,21 +1784,94 @@ static void prepare_read_data_cont(struct ceph_connection *con)
1766
1784
}
1767
1785
1768
1786
/*
1769
- * We've read all data. Prepare to read data padding (if any)
1770
- * and epilogue.
1787
+ * We've read all data. Prepare to read epilogue.
1771
1788
*/
1772
1789
reset_in_kvecs (con );
1773
- if (con_secure (con )) {
1774
- if (need_padding (data_len (con -> in_msg )))
1775
- add_in_kvec (con , DATA_PAD (con -> v2 .in_buf ),
1776
- padding_len (data_len (con -> in_msg )));
1777
- add_in_kvec (con , con -> v2 .in_buf , CEPH_EPILOGUE_SECURE_LEN );
1790
+ add_in_kvec (con , con -> v2 .in_buf , CEPH_EPILOGUE_PLAIN_LEN );
1791
+ con -> v2 .in_state = IN_S_HANDLE_EPILOGUE ;
1792
+ }
1793
+
1794
+ static void prepare_read_tail_plain (struct ceph_connection * con )
1795
+ {
1796
+ struct ceph_msg * msg = con -> in_msg ;
1797
+
1798
+ if (!front_len (msg ) && !middle_len (msg )) {
1799
+ WARN_ON (!data_len (msg ));
1800
+ prepare_read_data (con );
1801
+ return ;
1802
+ }
1803
+
1804
+ reset_in_kvecs (con );
1805
+ if (front_len (msg )) {
1806
+ add_in_kvec (con , msg -> front .iov_base , front_len (msg ));
1807
+ WARN_ON (msg -> front .iov_len != front_len (msg ));
1808
+ }
1809
+ if (middle_len (msg )) {
1810
+ add_in_kvec (con , msg -> middle -> vec .iov_base , middle_len (msg ));
1811
+ WARN_ON (msg -> middle -> vec .iov_len != middle_len (msg ));
1812
+ }
1813
+
1814
+ if (data_len (msg )) {
1815
+ con -> v2 .in_state = IN_S_PREPARE_READ_DATA ;
1778
1816
} else {
1779
1817
add_in_kvec (con , con -> v2 .in_buf , CEPH_EPILOGUE_PLAIN_LEN );
1818
+ con -> v2 .in_state = IN_S_HANDLE_EPILOGUE ;
1819
+ }
1820
+ }
1821
+
1822
+ static void prepare_read_enc_page (struct ceph_connection * con )
1823
+ {
1824
+ struct bio_vec bv ;
1825
+
1826
+ dout ("%s con %p i %d resid %d\n" , __func__ , con , con -> v2 .in_enc_i ,
1827
+ con -> v2 .in_enc_resid );
1828
+ WARN_ON (!con -> v2 .in_enc_resid );
1829
+
1830
+ bv .bv_page = con -> v2 .in_enc_pages [con -> v2 .in_enc_i ];
1831
+ bv .bv_offset = 0 ;
1832
+ bv .bv_len = min (con -> v2 .in_enc_resid , (int )PAGE_SIZE );
1833
+
1834
+ set_in_bvec (con , & bv );
1835
+ con -> v2 .in_enc_i ++ ;
1836
+ con -> v2 .in_enc_resid -= bv .bv_len ;
1837
+
1838
+ if (con -> v2 .in_enc_resid ) {
1839
+ con -> v2 .in_state = IN_S_PREPARE_READ_ENC_PAGE ;
1840
+ return ;
1780
1841
}
1842
+
1843
+ /*
1844
+ * We are set to read the last piece of ciphertext (ending
1845
+ * with epilogue) + auth tag.
1846
+ */
1847
+ WARN_ON (con -> v2 .in_enc_i != con -> v2 .in_enc_page_cnt );
1781
1848
con -> v2 .in_state = IN_S_HANDLE_EPILOGUE ;
1782
1849
}
1783
1850
1851
+ static int prepare_read_tail_secure (struct ceph_connection * con )
1852
+ {
1853
+ struct page * * enc_pages ;
1854
+ int enc_page_cnt ;
1855
+ int tail_len ;
1856
+
1857
+ tail_len = tail_onwire_len (con -> in_msg , true);
1858
+ WARN_ON (!tail_len );
1859
+
1860
+ enc_page_cnt = calc_pages_for (0 , tail_len );
1861
+ enc_pages = ceph_alloc_page_vector (enc_page_cnt , GFP_NOIO );
1862
+ if (IS_ERR (enc_pages ))
1863
+ return PTR_ERR (enc_pages );
1864
+
1865
+ WARN_ON (con -> v2 .in_enc_pages || con -> v2 .in_enc_page_cnt );
1866
+ con -> v2 .in_enc_pages = enc_pages ;
1867
+ con -> v2 .in_enc_page_cnt = enc_page_cnt ;
1868
+ con -> v2 .in_enc_resid = tail_len ;
1869
+ con -> v2 .in_enc_i = 0 ;
1870
+
1871
+ prepare_read_enc_page (con );
1872
+ return 0 ;
1873
+ }
1874
+
1784
1875
static void __finish_skip (struct ceph_connection * con )
1785
1876
{
1786
1877
con -> in_seq ++ ;
@@ -2589,46 +2680,26 @@ static int __handle_control(struct ceph_connection *con, void *p)
2589
2680
}
2590
2681
2591
2682
msg = con -> in_msg ; /* set in process_message_header() */
2592
- if (!front_len (msg ) && !middle_len (msg )) {
2593
- if (!data_len (msg ))
2594
- return process_message (con );
2595
-
2596
- prepare_read_data (con );
2597
- return 0 ;
2598
- }
2599
-
2600
- reset_in_kvecs (con );
2601
2683
if (front_len (msg )) {
2602
2684
WARN_ON (front_len (msg ) > msg -> front_alloc_len );
2603
- add_in_kvec (con , msg -> front .iov_base , front_len (msg ));
2604
2685
msg -> front .iov_len = front_len (msg );
2605
-
2606
- if (con_secure (con ) && need_padding (front_len (msg )))
2607
- add_in_kvec (con , FRONT_PAD (con -> v2 .in_buf ),
2608
- padding_len (front_len (msg )));
2609
2686
} else {
2610
2687
msg -> front .iov_len = 0 ;
2611
2688
}
2612
2689
if (middle_len (msg )) {
2613
2690
WARN_ON (middle_len (msg ) > msg -> middle -> alloc_len );
2614
- add_in_kvec (con , msg -> middle -> vec .iov_base , middle_len (msg ));
2615
2691
msg -> middle -> vec .iov_len = middle_len (msg );
2616
-
2617
- if (con_secure (con ) && need_padding (middle_len (msg )))
2618
- add_in_kvec (con , MIDDLE_PAD (con -> v2 .in_buf ),
2619
- padding_len (middle_len (msg )));
2620
2692
} else if (msg -> middle ) {
2621
2693
msg -> middle -> vec .iov_len = 0 ;
2622
2694
}
2623
2695
2624
- if (data_len (msg )) {
2625
- con -> v2 .in_state = IN_S_PREPARE_READ_DATA ;
2626
- } else {
2627
- add_in_kvec (con , con -> v2 .in_buf ,
2628
- con_secure (con ) ? CEPH_EPILOGUE_SECURE_LEN :
2629
- CEPH_EPILOGUE_PLAIN_LEN );
2630
- con -> v2 .in_state = IN_S_HANDLE_EPILOGUE ;
2631
- }
2696
+ if (!front_len (msg ) && !middle_len (msg ) && !data_len (msg ))
2697
+ return process_message (con );
2698
+
2699
+ if (con_secure (con ))
2700
+ return prepare_read_tail_secure (con );
2701
+
2702
+ prepare_read_tail_plain (con );
2632
2703
return 0 ;
2633
2704
}
2634
2705
@@ -2717,7 +2788,7 @@ static int handle_epilogue(struct ceph_connection *con)
2717
2788
int ret ;
2718
2789
2719
2790
if (con_secure (con )) {
2720
- ret = decrypt_message (con );
2791
+ ret = decrypt_tail (con );
2721
2792
if (ret ) {
2722
2793
if (ret == - EBADMSG )
2723
2794
con -> error_msg = "integrity error, bad epilogue auth tag" ;
@@ -2792,6 +2863,10 @@ static int populate_in_iter(struct ceph_connection *con)
2792
2863
prepare_read_data_cont (con );
2793
2864
ret = 0 ;
2794
2865
break ;
2866
+ case IN_S_PREPARE_READ_ENC_PAGE :
2867
+ prepare_read_enc_page (con );
2868
+ ret = 0 ;
2869
+ break ;
2795
2870
case IN_S_HANDLE_EPILOGUE :
2796
2871
ret = handle_epilogue (con );
2797
2872
break ;
@@ -3326,20 +3401,16 @@ void ceph_con_v2_revoke(struct ceph_connection *con)
3326
3401
3327
3402
static void revoke_at_prepare_read_data (struct ceph_connection * con )
3328
3403
{
3329
- int remaining ; /* data + [data padding] + epilogue */
3404
+ int remaining ;
3330
3405
int resid ;
3331
3406
3407
+ WARN_ON (con_secure (con ));
3332
3408
WARN_ON (!data_len (con -> in_msg ));
3333
3409
WARN_ON (!iov_iter_is_kvec (& con -> v2 .in_iter ));
3334
3410
resid = iov_iter_count (& con -> v2 .in_iter );
3335
3411
WARN_ON (!resid );
3336
3412
3337
- if (con_secure (con ))
3338
- remaining = padded_len (data_len (con -> in_msg )) +
3339
- CEPH_EPILOGUE_SECURE_LEN ;
3340
- else
3341
- remaining = data_len (con -> in_msg ) + CEPH_EPILOGUE_PLAIN_LEN ;
3342
-
3413
+ remaining = data_len (con -> in_msg ) + CEPH_EPILOGUE_PLAIN_LEN ;
3343
3414
dout ("%s con %p resid %d remaining %d\n" , __func__ , con , resid ,
3344
3415
remaining );
3345
3416
con -> v2 .in_iter .count -= resid ;
@@ -3350,8 +3421,9 @@ static void revoke_at_prepare_read_data(struct ceph_connection *con)
3350
3421
static void revoke_at_prepare_read_data_cont (struct ceph_connection * con )
3351
3422
{
3352
3423
int recved , resid ; /* current piece of data */
3353
- int remaining ; /* [data padding] + epilogue */
3424
+ int remaining ;
3354
3425
3426
+ WARN_ON (con_secure (con ));
3355
3427
WARN_ON (!data_len (con -> in_msg ));
3356
3428
WARN_ON (!iov_iter_is_bvec (& con -> v2 .in_iter ));
3357
3429
resid = iov_iter_count (& con -> v2 .in_iter );
@@ -3363,24 +3435,34 @@ static void revoke_at_prepare_read_data_cont(struct ceph_connection *con)
3363
3435
ceph_msg_data_advance (& con -> v2 .in_cursor , recved );
3364
3436
WARN_ON (resid > con -> v2 .in_cursor .total_resid );
3365
3437
3366
- if (con_secure (con ))
3367
- remaining = padding_len (data_len (con -> in_msg )) +
3368
- CEPH_EPILOGUE_SECURE_LEN ;
3369
- else
3370
- remaining = CEPH_EPILOGUE_PLAIN_LEN ;
3371
-
3438
+ remaining = CEPH_EPILOGUE_PLAIN_LEN ;
3372
3439
dout ("%s con %p total_resid %zu remaining %d\n" , __func__ , con ,
3373
3440
con -> v2 .in_cursor .total_resid , remaining );
3374
3441
con -> v2 .in_iter .count -= resid ;
3375
3442
set_in_skip (con , con -> v2 .in_cursor .total_resid + remaining );
3376
3443
con -> v2 .in_state = IN_S_FINISH_SKIP ;
3377
3444
}
3378
3445
3446
+ static void revoke_at_prepare_read_enc_page (struct ceph_connection * con )
3447
+ {
3448
+ int resid ; /* current enc page (not necessarily data) */
3449
+
3450
+ WARN_ON (!con_secure (con ));
3451
+ WARN_ON (!iov_iter_is_bvec (& con -> v2 .in_iter ));
3452
+ resid = iov_iter_count (& con -> v2 .in_iter );
3453
+ WARN_ON (!resid || resid > con -> v2 .in_bvec .bv_len );
3454
+
3455
+ dout ("%s con %p resid %d enc_resid %d\n" , __func__ , con , resid ,
3456
+ con -> v2 .in_enc_resid );
3457
+ con -> v2 .in_iter .count -= resid ;
3458
+ set_in_skip (con , resid + con -> v2 .in_enc_resid );
3459
+ con -> v2 .in_state = IN_S_FINISH_SKIP ;
3460
+ }
3461
+
3379
3462
static void revoke_at_handle_epilogue (struct ceph_connection * con )
3380
3463
{
3381
3464
int resid ;
3382
3465
3383
- WARN_ON (!iov_iter_is_kvec (& con -> v2 .in_iter ));
3384
3466
resid = iov_iter_count (& con -> v2 .in_iter );
3385
3467
WARN_ON (!resid );
3386
3468
@@ -3399,6 +3481,9 @@ void ceph_con_v2_revoke_incoming(struct ceph_connection *con)
3399
3481
case IN_S_PREPARE_READ_DATA_CONT :
3400
3482
revoke_at_prepare_read_data_cont (con );
3401
3483
break ;
3484
+ case IN_S_PREPARE_READ_ENC_PAGE :
3485
+ revoke_at_prepare_read_enc_page (con );
3486
+ break ;
3402
3487
case IN_S_HANDLE_EPILOGUE :
3403
3488
revoke_at_handle_epilogue (con );
3404
3489
break ;
@@ -3432,6 +3517,13 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con)
3432
3517
clear_out_sign_kvecs (con );
3433
3518
free_conn_bufs (con );
3434
3519
3520
+ if (con -> v2 .in_enc_pages ) {
3521
+ WARN_ON (!con -> v2 .in_enc_page_cnt );
3522
+ ceph_release_page_vector (con -> v2 .in_enc_pages ,
3523
+ con -> v2 .in_enc_page_cnt );
3524
+ con -> v2 .in_enc_pages = NULL ;
3525
+ con -> v2 .in_enc_page_cnt = 0 ;
3526
+ }
3435
3527
if (con -> v2 .out_enc_pages ) {
3436
3528
WARN_ON (!con -> v2 .out_enc_page_cnt );
3437
3529
ceph_release_page_vector (con -> v2 .out_enc_pages ,
0 commit comments