@@ -33,6 +33,7 @@ static const struct dm_inlinecrypt_cipher {
3333 * preceded by @iv_offset 512-byte sectors.
3434 * @sector_size: crypto sector size in bytes (usually 4096)
3535 * @sector_bits: log2(sector_size)
36+ * @key_type: type of the key -- either raw or hardware-wrapped
3637 * @key: the encryption key to use
3738 * @max_dun: the maximum DUN that may be used (computed from other params)
3839 */
@@ -44,6 +45,7 @@ struct inlinecrypt_ctx {
4445 u64 iv_offset ;
4546 unsigned int sector_size ;
4647 unsigned int sector_bits ;
48+ enum blk_crypto_key_type key_type ;
4749 struct blk_crypto_key key ;
4850 u64 max_dun ;
4951};
@@ -83,32 +85,32 @@ static bool contains_whitespace(const char *str)
8385 return false;
8486}
8587
86- static int set_key_user (struct key * key , char * bin_key ,
87- const unsigned int bin_key_size )
88+ static int set_key_user (struct key * key , char * key_bytes ,
89+ const unsigned int key_bytes_size )
8890{
8991 const struct user_key_payload * ukp ;
9092
9193 ukp = user_key_payload_locked (key );
9294 if (!ukp )
9395 return - EKEYREVOKED ;
9496
95- if (bin_key_size != ukp -> datalen )
97+ if (key_bytes_size != ukp -> datalen )
9698 return - EINVAL ;
9799
98- memcpy (bin_key , ukp -> data , bin_key_size );
100+ memcpy (key_bytes , ukp -> data , key_bytes_size );
99101
100102 return 0 ;
101103}
102104
103- static int inlinecrypt_get_keyring_key (const char * key_string , u8 * bin_key ,
104- const unsigned int bin_key_size )
105+ static int inlinecrypt_get_keyring_key (const char * key_string , u8 * key_bytes ,
106+ const unsigned int key_bytes_size )
105107{
106108 char * key_desc ;
107109 int ret ;
108110 struct key_type * type ;
109111 struct key * key ;
110- int (* set_key )(struct key * key , char * bin_key ,
111- const unsigned int bin_key_size );
112+ int (* set_key )(struct key * key , char * key_bytes ,
113+ const unsigned int key_bytes_size );
112114
113115 /*
114116 * Reject key_string with whitespace. dm core currently lacks code for
@@ -137,7 +139,7 @@ static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key,
137139
138140 down_read (& key -> sem );
139141
140- ret = set_key (key , (char * )bin_key , bin_key_size );
142+ ret = set_key (key , (char * )key_bytes , key_bytes_size );
141143
142144 up_read (& key -> sem );
143145 key_put (key );
@@ -178,8 +180,8 @@ static int get_key_size(char **key_string)
178180
179181#else
180182
181- static int inlinecrypt_get_keyring_key (const char * key_string , u8 * bin_key ,
182- const unsigned int bin_key_size )
183+ static int inlinecrypt_get_keyring_key (const char * key_string , u8 * key_bytes ,
184+ const unsigned int key_bytes_size )
183185{
184186 return - EINVAL ;
185187}
@@ -234,7 +236,7 @@ static int inlinecrypt_ctr_optional(struct dm_target *ti,
234236 struct inlinecrypt_ctx * ctx = ti -> private ;
235237 struct dm_arg_set as ;
236238 static const struct dm_arg _args [] = {
237- {0 , 3 , "Invalid number of feature args" },
239+ {0 , 4 , "Invalid number of feature args" },
238240 };
239241 unsigned int opt_params ;
240242 const char * opt_string ;
@@ -255,7 +257,23 @@ static int inlinecrypt_ctr_optional(struct dm_target *ti,
255257 ti -> error = "Not enough feature arguments" ;
256258 return - EINVAL ;
257259 }
258- if (!strcmp (opt_string , "allow_discards" )) {
260+ if (str_has_prefix (opt_string , "keytype:" )) {
261+ const char * val = opt_string + strlen ("keytype:" );
262+
263+ if (!* val ) {
264+ ti -> error = "Invalid block key type" ;
265+ return - EINVAL ;
266+ }
267+
268+ if (!strcmp (val , "raw" )) {
269+ ctx -> key_type = BLK_CRYPTO_KEY_TYPE_RAW ;
270+ } else if (!strcmp (val , "hw-wrapped" )) {
271+ ctx -> key_type = BLK_CRYPTO_KEY_TYPE_HW_WRAPPED ;
272+ } else {
273+ ti -> error = "Invalid block key type" ;
274+ return - EINVAL ;
275+ }
276+ } else if (!strcmp (opt_string , "allow_discards" )) {
259277 ti -> num_discard_bios = 1 ;
260278 } else if (sscanf (opt_string , "sector_size:%u%c" ,
261279 & ctx -> sector_size , & dummy ) == 1 ) {
@@ -293,7 +311,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
293311{
294312 struct inlinecrypt_ctx * ctx ;
295313 const struct dm_inlinecrypt_cipher * cipher ;
296- u8 raw_key [BLK_CRYPTO_MAX_ANY_KEY_SIZE ];
314+ u8 key_bytes [BLK_CRYPTO_MAX_ANY_KEY_SIZE ];
297315 unsigned int dun_bytes ;
298316 unsigned long long tmpll ;
299317 char dummy ;
@@ -333,7 +351,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
333351 }
334352 ctx -> key_size = err ;
335353
336- err = inlinecrypt_get_key (argv [1 ], raw_key , ctx -> key_size );
354+ err = inlinecrypt_get_key (argv [1 ], key_bytes , ctx -> key_size );
337355 if (err ) {
338356 ti -> error = "Malformed key string" ;
339357 goto bad ;
@@ -365,6 +383,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
365383
366384 /* optional arguments */
367385 ctx -> sector_size = SECTOR_SIZE ;
386+ ctx -> key_type = BLK_CRYPTO_KEY_TYPE_RAW ;
368387 if (argc > 5 ) {
369388 err = inlinecrypt_ctr_optional (ti , argc - 5 , & argv [5 ]);
370389 if (err )
@@ -385,10 +404,9 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
385404 (ctx -> sector_bits - SECTOR_SHIFT );
386405 dun_bytes = DIV_ROUND_UP (fls64 (ctx -> max_dun ), 8 );
387406
388- err = blk_crypto_init_key (& ctx -> key , raw_key , ctx -> key_size ,
389- BLK_CRYPTO_KEY_TYPE_RAW ,
390- cipher -> mode_num , dun_bytes ,
391- ctx -> sector_size );
407+ err = blk_crypto_init_key (& ctx -> key , key_bytes , ctx -> key_size ,
408+ ctx -> key_type , cipher -> mode_num ,
409+ dun_bytes , ctx -> sector_size );
392410 if (err ) {
393411 ti -> error = "Error initializing blk-crypto key" ;
394412 goto bad ;
@@ -408,7 +426,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
408426bad :
409427 inlinecrypt_dtr (ti );
410428out :
411- memzero_explicit (raw_key , sizeof (raw_key ));
429+ memzero_explicit (key_bytes , sizeof (key_bytes ));
412430 return err ;
413431}
414432
@@ -502,8 +520,9 @@ static void inlinecrypt_status(struct dm_target *ti, status_type_t type,
502520 * the returned table. Userspace is responsible for redacting
503521 * the key when needed.
504522 */
505- DMEMIT ("%s %*phN %llu %s %llu" , ctx -> cipher_string ,
506- ctx -> key .size , ctx -> key .bytes , ctx -> iv_offset ,
523+ DMEMIT ("%s %*phN %u %llu %s %llu" , ctx -> cipher_string ,
524+ ctx -> key .size , ctx -> key .bytes ,
525+ ctx -> key_type , ctx -> iv_offset ,
507526 ctx -> dev -> name , ctx -> start );
508527 num_feature_args += !!ti -> num_discard_bios ;
509528 if (ctx -> sector_size != SECTOR_SIZE )
0 commit comments