@@ -151,6 +151,34 @@ static int __get_heap_obj(struct libnvme_global_ctx *ctx,
151151 descriptor->obj, is_string, \
152152 output)
153153
154+ /* Point at a raw (non-string) heap object and return its length. */
155+ static int __get_heap_obj_raw (struct libnvme_global_ctx * ctx ,
156+ struct nbft_header * header , const char * filename ,
157+ const char * descriptorname , const char * fieldname ,
158+ struct nbft_heap_obj obj , unsigned char * * output , __u16 * length )
159+ {
160+ __u16 obj_length = le16_to_cpu (obj .length );
161+
162+ * output = NULL ;
163+ * length = 0 ;
164+ if (obj_length == 0 )
165+ return 0 ;
166+ if (!in_heap (header , obj )) {
167+ libnvme_msg (ctx , LIBNVME_LOG_DEBUG ,
168+ "file %s: field '%s' in descriptor '%s' has invalid offset or length\n" ,
169+ filename , fieldname , descriptorname );
170+ return - EINVAL ;
171+ }
172+ * output = (unsigned char * )header + le32_to_cpu (obj .offset );
173+ * length = obj_length ;
174+ return 0 ;
175+ }
176+
177+ #define get_heap_obj_raw (descriptor , obj , output , length ) \
178+ __get_heap_obj_raw(ctx, header, nbft->filename, \
179+ stringify(descriptor), stringify(obj), \
180+ descriptor->obj, output, length)
181+
154182static struct libnbft_discovery * discovery_from_index (struct libnbft_info * nbft ,
155183 int i )
156184{
@@ -583,7 +611,63 @@ static int read_security(struct libnvme_global_ctx *ctx, struct libnbft_info *nb
583611 struct nbft_security * raw_security ,
584612 struct libnbft_security * * s )
585613{
586- return - EINVAL ;
614+ struct nbft_header * header = (struct nbft_header * )nbft -> raw_nbft ;
615+ struct libnbft_security * security ;
616+ __u16 flags = le16_to_cpu (raw_security -> flags );
617+ int ret ;
618+
619+ if (!(flags & NBFT_SECURITY_VALID ))
620+ return - EINVAL ;
621+ verify (ctx , raw_security -> structure_id == NBFT_DESC_SECURITY ,
622+ "invalid ID in security descriptor" );
623+
624+ security = calloc (1 , sizeof (* security ));
625+ if (!security )
626+ return - ENOMEM ;
627+
628+ security -> index = raw_security -> index ;
629+ security -> flags = flags ;
630+ security -> secret_type = raw_security -> secret_type ;
631+
632+ /* Policy lists point into the raw NBFT heap when enabled. */
633+ ret = 0 ;
634+ if ((flags & NBFT_SECURITY_SEC_POLICY_LIST_MASK ) !=
635+ NBFT_SECURITY_SEC_POLICY_LIST_NOT_SUPPORTED )
636+ ret = get_heap_obj_raw (raw_security , sec_chan_alg_obj ,
637+ & security -> sec_chan_algs ,
638+ & security -> sec_chan_algs_len );
639+ if (!ret && (flags & NBFT_SECURITY_AUTH_POLICY_LIST_MASK ) !=
640+ NBFT_SECURITY_AUTH_POLICY_LIST_NOT_SUPPORTED )
641+ ret = get_heap_obj_raw (raw_security , auth_proto_obj ,
642+ & security -> auth_protocols ,
643+ & security -> auth_protocols_len );
644+ if (!ret && (flags & NBFT_SECURITY_CIPHER_RESTRICTED ))
645+ ret = get_heap_obj_raw (raw_security , cipher_suite_obj ,
646+ & security -> cipher_suites ,
647+ & security -> cipher_suites_len );
648+ if (!ret && (flags & NBFT_SECURITY_AUTH_DH_GROUPS_RESTRICTED ))
649+ ret = get_heap_obj_raw (raw_security , dh_grp_obj ,
650+ & security -> dh_groups ,
651+ & security -> dh_groups_len );
652+ if (!ret && (flags & NBFT_SECURITY_SEC_HASH_FUNC_POLICY_LIST ))
653+ ret = get_heap_obj_raw (raw_security , sec_hash_func_obj ,
654+ & security -> sec_hash_funcs ,
655+ & security -> sec_hash_funcs_len );
656+ if (ret ) {
657+ free (security );
658+ return ret ;
659+ }
660+
661+ /* The key URI also points into the heap. An absent URI is valid. */
662+ ret = get_heap_obj (ctx , raw_security , sec_keypath_obj , 1 ,
663+ & security -> secret_keypath );
664+ if (ret && ret != - ENOENT ) {
665+ free (security );
666+ return ret ;
667+ }
668+
669+ * s = security ;
670+ return 0 ;
587671}
588672
589673static void read_hfi_descriptors (struct libnvme_global_ctx * ctx ,
0 commit comments