@@ -47,6 +47,9 @@ struct bdev_rbd {
4747 char * user_id ;
4848 char * pool_name ;
4949 char * namespace_name ;
50+ uint32_t encryption_entries_count ;
51+ uint32_t * encryption_format ;
52+ char * * passphrase ;
5053 char * * config ;
5154
5255 rados_t cluster ;
@@ -231,6 +234,8 @@ bdev_rbd_free(struct bdev_rbd *rbd)
231234 free (rbd -> user_id );
232235 free (rbd -> pool_name );
233236 free (rbd -> namespace_name );
237+ free (rbd -> encryption_format );
238+ bdev_rbd_free_passphrase (rbd -> passphrase );
234239 bdev_rbd_free_config (rbd -> config );
235240
236241 if (rbd -> cluster_name ) {
@@ -290,6 +295,19 @@ bdev_rbd_dup_config(const char *const *config)
290295 return copy ;
291296}
292297
298+ void
299+ bdev_rbd_free_passphrase (char * * passphrase )
300+ {
301+ char * * entry ;
302+
303+ if (passphrase ) {
304+ for (entry = passphrase ; * entry ; entry ++ ) {
305+ free (* entry );
306+ }
307+ free (passphrase );
308+ }
309+ }
310+
293311static int
294312bdev_rados_cluster_init (const char * user_id , const char * const * config ,
295313 rados_t * cluster )
@@ -461,6 +479,61 @@ bdev_rbd_get_pool_ctx(rados_t *cluster_p, const char *name, const char *namespac
461479 return -1 ;
462480}
463481
482+ static void
483+ bdev_rbd_free_encryption_specs (rbd_encryption_spec_t * specs , uint32_t count )
484+ {
485+ uint32_t i ;
486+
487+ if (!specs )
488+ return ;
489+
490+ for (i = 0 ; i < count ; i ++ ) {
491+ if (specs [i ].format == RBD_ENCRYPTION_FORMAT_LUKS1 ) {
492+ free ((void * )(((rbd_encryption_luks1_format_options_t * )specs [i ].opts )-> passphrase ));
493+ }
494+ else if (specs [i ].format == RBD_ENCRYPTION_FORMAT_LUKS2 ) {
495+ free ((void * )(((rbd_encryption_luks2_format_options_t * )specs [i ].opts )-> passphrase ));
496+ }
497+ else if (specs [i ].format == RBD_ENCRYPTION_FORMAT_LUKS ) {
498+ free ((void * )(((rbd_encryption_luks_format_options_t * )specs [i ].opts )-> passphrase ));
499+ }
500+ free (specs [i ].opts );
501+ }
502+ free (specs );
503+ }
504+
505+ static int
506+ bdev_rbd_set_passphrase (char * * out , size_t * phrasesize , const char * phrase )
507+ {
508+ * out = strdup (phrase );
509+ if (!* out ) {
510+ SPDK_ERRLOG ("Cannot allocate memory for encryption pass phrase\n" );
511+ return -1 ;
512+ }
513+ * phrasesize = strlen (phrase );
514+ return 0 ;
515+ }
516+
517+ #define SET_ENC_ENTRY (_specs , _rbd , _index , _fstring , _fmt , _upfmt ) \
518+ if ((_rbd)->encryption_format[_index] == RBD_ENCRYPTION_FORMAT_##_upfmt ) { \
519+ rbd_encryption_##_fmt##_format_options_t *opts; \
520+ strcat(_fstring, #_upfmt " "); \
521+ opts = calloc(1, sizeof(*opts)); \
522+ if (!opts) { \
523+ SPDK_ERRLOG("Cannot allocate memory for encryption format options\n"); \
524+ bdev_rbd_free_encryption_specs(_specs, (_rbd)->encryption_entries_count); \
525+ return NULL; \
526+ } \
527+ if (bdev_rbd_set_passphrase((char **)&opts->passphrase, &opts->passphrase_size, (_rbd->passphrase[_index]))) { \
528+ free((char *)opts->passphrase); \
529+ free(opts); \
530+ bdev_rbd_free_encryption_specs(_specs, (_rbd)->encryption_entries_count); \
531+ return NULL; \
532+ } \
533+ _specs[_index].opts = (rbd_encryption_options_t)opts; \
534+ _specs[_index].opts_size = sizeof(*opts); \
535+ }
536+
464537static void *
465538bdev_rbd_init_context (void * arg )
466539{
@@ -498,9 +571,52 @@ bdev_rbd_init_context(void *arg)
498571 }
499572 if (rc < 0 ) {
500573 SPDK_ERRLOG ("Failed to open specified rbd device\n" );
574+ rbd -> image = NULL ;
501575 return NULL ;
502576 }
503577
578+ if (rbd -> encryption_entries_count > 0 ) {
579+ uint32_t i ;
580+ rbd_encryption_spec_t * specs ;
581+ char * formats_string ;
582+
583+ formats_string = calloc (rbd -> encryption_entries_count , strlen ("LUKSx" ) + 1 );
584+ if (!formats_string ) {
585+ SPDK_ERRLOG ("Cannot allocate memory for encryption formats string\n" );
586+ return NULL ;
587+ }
588+ specs = calloc (rbd -> encryption_entries_count , sizeof (* specs ));
589+ if (!specs ) {
590+ SPDK_ERRLOG ("Cannot allocate memory for encryption specs\n" );
591+ free (formats_string );
592+ return NULL ;
593+ }
594+ for (i = 0 ; i < rbd -> encryption_entries_count ; i ++ ) {
595+ specs [i ].format = rbd -> encryption_format [i ];
596+ SET_ENC_ENTRY (specs , rbd , i , formats_string , luks1 , LUKS1 )
597+ SET_ENC_ENTRY (specs , rbd , i , formats_string , luks2 , LUKS2 )
598+ SET_ENC_ENTRY (specs , rbd , i , formats_string , luks , LUKS )
599+ if (!specs [i ].opts ) {
600+ SPDK_ERRLOG ("Invalid encryption format %d\n" , rbd -> encryption_format [i ]);
601+ bdev_rbd_free_encryption_specs (specs , rbd -> encryption_entries_count );
602+ free (formats_string );
603+ return NULL ;
604+ }
605+ }
606+
607+ SPDK_DEBUGLOG (bdev_rbd , "Will use encryption load for image %s/%s, using encryption format(s) %s\n" ,
608+ rbd -> pool_name , rbd -> rbd_name , formats_string );
609+ rc = rbd_encryption_load2 (rbd -> image , specs , rbd -> encryption_entries_count );
610+ bdev_rbd_free_encryption_specs (specs , rbd -> encryption_entries_count );
611+ if (rc != 0 ) {
612+ SPDK_ERRLOG ("Error %d trying to encryption load image %s/%s using format(s) %s\n" , rc ,
613+ rbd -> pool_name , rbd -> rbd_name , formats_string );
614+ free (formats_string );
615+ return NULL ;
616+ }
617+ free (formats_string );
618+ }
619+
504620 rc = rbd_update_watch (rbd -> image , & rbd -> rbd_watch_handle , rbd_update_callback , (void * )rbd );
505621 if (rc < 0 ) {
506622 SPDK_ERRLOG ("Failed to set up watch %d\n" , rc );
@@ -1061,6 +1177,27 @@ bdev_rbd_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w
10611177 spdk_json_write_named_string (w , "user_id" , rbd -> user_id );
10621178 }
10631179
1180+ if (rbd -> encryption_format && rbd -> encryption_entries_count > 0 ) {
1181+ uint32_t i ;
1182+
1183+ spdk_json_write_named_object_begin (w , "encryption_format" );
1184+ for (i = 0 ; i < rbd -> encryption_entries_count ; i ++ ) {
1185+ spdk_json_write_uint32 (w , rbd -> encryption_format [i ]);
1186+ }
1187+ spdk_json_write_object_end (w );
1188+ }
1189+
1190+ if (rbd -> passphrase && rbd -> encryption_entries_count > 0 ) {
1191+ uint32_t i ;
1192+
1193+ spdk_json_write_named_object_begin (w , "passphrase" );
1194+ for (i = 0 ; i < rbd -> encryption_entries_count ; i ++ ) {
1195+ /* souldn't write the real pass phrase, it's a security breach */
1196+ spdk_json_write_string (w , "*" );
1197+ }
1198+ spdk_json_write_object_end (w );
1199+ }
1200+
10641201 if (rbd -> config ) {
10651202 char * * entry = rbd -> config ;
10661203
@@ -1499,10 +1636,14 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
14991636 uint32_t block_size ,
15001637 const char * cluster_name ,
15011638 const struct spdk_uuid * uuid ,
1502- bool read_only )
1639+ bool read_only ,
1640+ uint32_t encryption_entries_count ,
1641+ const uint32_t * encryption_format ,
1642+ const char * * passphrase )
15031643{
15041644 struct bdev_rbd * rbd ;
15051645 int ret ;
1646+ uint32_t i ;
15061647
15071648 if ((pool_name == NULL ) || (rbd_name == NULL ) || (block_size == 0 )) {
15081649 return - EINVAL ;
@@ -1549,6 +1690,28 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
15491690 }
15501691 }
15511692
1693+ rbd -> encryption_entries_count = encryption_entries_count ;
1694+ if (encryption_entries_count > 0 ) {
1695+ rbd -> encryption_format = calloc (encryption_entries_count , sizeof (uint32_t ));
1696+ if (!rbd -> encryption_format ) {
1697+ bdev_rbd_free (rbd );
1698+ return - ENOMEM ;
1699+ }
1700+ rbd -> passphrase = calloc (encryption_entries_count + 1 , sizeof (char * ));
1701+ if (!rbd -> passphrase ) {
1702+ bdev_rbd_free (rbd );
1703+ return - ENOMEM ;
1704+ }
1705+ for (i = 0 ; i < encryption_entries_count ; i ++ ) {
1706+ rbd -> encryption_format [i ] = encryption_format [i ];
1707+ rbd -> passphrase [i ] = strdup (passphrase [i ]);
1708+ if (!rbd -> passphrase [i ]) {
1709+ bdev_rbd_free (rbd );
1710+ return - ENOMEM ;
1711+ }
1712+ }
1713+ }
1714+
15521715 if (config && !(rbd -> config = bdev_rbd_dup_config (config ))) {
15531716 bdev_rbd_free (rbd );
15541717 return - ENOMEM ;
0 commit comments