@@ -120,6 +120,10 @@ struct iv_tcw_private {
120
120
u8 * whitening ;
121
121
};
122
122
123
+ struct iv_eboiv_private {
124
+ struct crypto_cipher * tfm ;
125
+ };
126
+
123
127
/*
124
128
* Crypt: maps a linear range of a block device
125
129
* and encrypts / decrypts at the same time.
@@ -159,6 +163,7 @@ struct crypt_config {
159
163
struct iv_benbi_private benbi ;
160
164
struct iv_lmk_private lmk ;
161
165
struct iv_tcw_private tcw ;
166
+ struct iv_eboiv_private eboiv ;
162
167
} iv_gen_private ;
163
168
u64 iv_offset ;
164
169
unsigned int iv_size ;
@@ -290,6 +295,10 @@ static struct crypto_aead *any_tfm_aead(struct crypt_config *cc)
290
295
* is calculated from initial key, sector number and mixed using CRC32.
291
296
* Note that this encryption scheme is vulnerable to watermarking attacks
292
297
* and should be used for old compatible containers access only.
298
+ *
299
+ * eboiv: Encrypted byte-offset IV (used in Bitlocker in CBC mode)
300
+ * The IV is encrypted little-endian byte-offset (with the same key
301
+ * and cipher as the volume).
293
302
*/
294
303
295
304
static int crypt_iv_plain_gen (struct crypt_config * cc , u8 * iv ,
@@ -838,6 +847,67 @@ static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,
838
847
return 0 ;
839
848
}
840
849
850
+ static void crypt_iv_eboiv_dtr (struct crypt_config * cc )
851
+ {
852
+ struct iv_eboiv_private * eboiv = & cc -> iv_gen_private .eboiv ;
853
+
854
+ crypto_free_cipher (eboiv -> tfm );
855
+ eboiv -> tfm = NULL ;
856
+ }
857
+
858
+ static int crypt_iv_eboiv_ctr (struct crypt_config * cc , struct dm_target * ti ,
859
+ const char * opts )
860
+ {
861
+ struct iv_eboiv_private * eboiv = & cc -> iv_gen_private .eboiv ;
862
+ struct crypto_cipher * tfm ;
863
+
864
+ tfm = crypto_alloc_cipher (cc -> cipher , 0 , 0 );
865
+ if (IS_ERR (tfm )) {
866
+ ti -> error = "Error allocating crypto tfm for EBOIV" ;
867
+ return PTR_ERR (tfm );
868
+ }
869
+
870
+ if (crypto_cipher_blocksize (tfm ) != cc -> iv_size ) {
871
+ ti -> error = "Block size of EBOIV cipher does "
872
+ "not match IV size of block cipher" ;
873
+ crypto_free_cipher (tfm );
874
+ return - EINVAL ;
875
+ }
876
+
877
+ eboiv -> tfm = tfm ;
878
+ return 0 ;
879
+ }
880
+
881
+ static int crypt_iv_eboiv_init (struct crypt_config * cc )
882
+ {
883
+ struct iv_eboiv_private * eboiv = & cc -> iv_gen_private .eboiv ;
884
+ int err ;
885
+
886
+ err = crypto_cipher_setkey (eboiv -> tfm , cc -> key , cc -> key_size );
887
+ if (err )
888
+ return err ;
889
+
890
+ return 0 ;
891
+ }
892
+
893
+ static int crypt_iv_eboiv_wipe (struct crypt_config * cc )
894
+ {
895
+ /* Called after cc->key is set to random key in crypt_wipe() */
896
+ return crypt_iv_eboiv_init (cc );
897
+ }
898
+
899
+ static int crypt_iv_eboiv_gen (struct crypt_config * cc , u8 * iv ,
900
+ struct dm_crypt_request * dmreq )
901
+ {
902
+ struct iv_eboiv_private * eboiv = & cc -> iv_gen_private .eboiv ;
903
+
904
+ memset (iv , 0 , cc -> iv_size );
905
+ * (__le64 * )iv = cpu_to_le64 (dmreq -> iv_sector * cc -> sector_size );
906
+ crypto_cipher_encrypt_one (eboiv -> tfm , iv , iv );
907
+
908
+ return 0 ;
909
+ }
910
+
841
911
static const struct crypt_iv_operations crypt_iv_plain_ops = {
842
912
.generator = crypt_iv_plain_gen
843
913
};
@@ -890,6 +960,14 @@ static struct crypt_iv_operations crypt_iv_random_ops = {
890
960
.generator = crypt_iv_random_gen
891
961
};
892
962
963
+ static struct crypt_iv_operations crypt_iv_eboiv_ops = {
964
+ .ctr = crypt_iv_eboiv_ctr ,
965
+ .dtr = crypt_iv_eboiv_dtr ,
966
+ .init = crypt_iv_eboiv_init ,
967
+ .wipe = crypt_iv_eboiv_wipe ,
968
+ .generator = crypt_iv_eboiv_gen
969
+ };
970
+
893
971
/*
894
972
* Integrity extensions
895
973
*/
@@ -2293,6 +2371,8 @@ static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode)
2293
2371
cc -> iv_gen_ops = & crypt_iv_benbi_ops ;
2294
2372
else if (strcmp (ivmode , "null" ) == 0 )
2295
2373
cc -> iv_gen_ops = & crypt_iv_null_ops ;
2374
+ else if (strcmp (ivmode , "eboiv" ) == 0 )
2375
+ cc -> iv_gen_ops = & crypt_iv_eboiv_ops ;
2296
2376
else if (strcmp (ivmode , "lmk" ) == 0 ) {
2297
2377
cc -> iv_gen_ops = & crypt_iv_lmk_ops ;
2298
2378
/*
@@ -3093,7 +3173,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
3093
3173
3094
3174
static struct target_type crypt_target = {
3095
3175
.name = "crypt" ,
3096
- .version = {1 , 18 , 1 },
3176
+ .version = {1 , 19 , 0 },
3097
3177
.module = THIS_MODULE ,
3098
3178
.ctr = crypt_ctr ,
3099
3179
.dtr = crypt_dtr ,
0 commit comments