@@ -517,6 +517,65 @@ static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c)
517
517
return sup ;
518
518
}
519
519
520
+ static int authenticate_sb_node (struct ubifs_info * c ,
521
+ const struct ubifs_sb_node * sup )
522
+ {
523
+ unsigned int sup_flags = le32_to_cpu (sup -> flags );
524
+ u8 hmac_wkm [UBIFS_HMAC_ARR_SZ ];
525
+ int authenticated = !!(sup_flags & UBIFS_FLG_AUTHENTICATION );
526
+ int hash_algo ;
527
+ int err ;
528
+
529
+ if (c -> authenticated && !authenticated ) {
530
+ ubifs_err (c , "authenticated FS forced, but found FS without authentication" );
531
+ return - EINVAL ;
532
+ }
533
+
534
+ if (!c -> authenticated && authenticated ) {
535
+ ubifs_err (c , "authenticated FS found, but no key given" );
536
+ return - EINVAL ;
537
+ }
538
+
539
+ ubifs_msg (c , "Mounting in %sauthenticated mode" ,
540
+ c -> authenticated ? "" : "un" );
541
+
542
+ if (!c -> authenticated )
543
+ return 0 ;
544
+
545
+ if (!IS_ENABLED (CONFIG_UBIFS_FS_AUTHENTICATION ))
546
+ return - EOPNOTSUPP ;
547
+
548
+ hash_algo = le16_to_cpu (sup -> hash_algo );
549
+ if (hash_algo >= HASH_ALGO__LAST ) {
550
+ ubifs_err (c , "superblock uses unknown hash algo %d" ,
551
+ hash_algo );
552
+ return - EINVAL ;
553
+ }
554
+
555
+ if (strcmp (hash_algo_name [hash_algo ], c -> auth_hash_name )) {
556
+ ubifs_err (c , "This filesystem uses %s for hashing,"
557
+ " but %s is specified" , hash_algo_name [hash_algo ],
558
+ c -> auth_hash_name );
559
+ return - EINVAL ;
560
+ }
561
+
562
+ err = ubifs_hmac_wkm (c , hmac_wkm );
563
+ if (err )
564
+ return err ;
565
+
566
+ if (ubifs_check_hmac (c , hmac_wkm , sup -> hmac_wkm )) {
567
+ ubifs_err (c , "provided key does not fit" );
568
+ return - ENOKEY ;
569
+ }
570
+
571
+ err = ubifs_node_verify_hmac (c , sup , sizeof (* sup ),
572
+ offsetof(struct ubifs_sb_node , hmac ));
573
+ if (err )
574
+ ubifs_err (c , "Failed to authenticate superblock: %d" , err );
575
+
576
+ return err ;
577
+ }
578
+
520
579
/**
521
580
* ubifs_write_sb_node - write superblock node.
522
581
* @c: UBIFS file-system description object
@@ -527,8 +586,13 @@ static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c)
527
586
int ubifs_write_sb_node (struct ubifs_info * c , struct ubifs_sb_node * sup )
528
587
{
529
588
int len = ALIGN (UBIFS_SB_NODE_SZ , c -> min_io_size );
589
+ int err ;
590
+
591
+ err = ubifs_prepare_node_hmac (c , sup , UBIFS_SB_NODE_SZ ,
592
+ offsetof(struct ubifs_sb_node , hmac ), 1 );
593
+ if (err )
594
+ return err ;
530
595
531
- ubifs_prepare_node (c , sup , UBIFS_SB_NODE_SZ , 1 );
532
596
return ubifs_leb_change (c , UBIFS_SB_LNUM , sup , len );
533
597
}
534
598
@@ -642,6 +706,10 @@ int ubifs_read_superblock(struct ubifs_info *c)
642
706
c -> double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH );
643
707
c -> encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION );
644
708
709
+ err = authenticate_sb_node (c , sup );
710
+ if (err )
711
+ goto out ;
712
+
645
713
if ((sup_flags & ~UBIFS_FLG_MASK ) != 0 ) {
646
714
ubifs_err (c , "Unknown feature flags found: %#x" ,
647
715
sup_flags & ~UBIFS_FLG_MASK );
0 commit comments