@@ -539,3 +539,232 @@ static void openssl_ecdh_backend(void)
539
539
{
540
540
register_ecdh_impl (& openssl_ecdh );
541
541
}
542
+
543
+ /************************************************
544
+ * DRBG cipher interface functions
545
+ ************************************************/
546
+ static int openssl_get_drbg_name (struct drbg_data * data , char * cipher ,
547
+ char * drbg_name )
548
+ {
549
+ logger (LOGGER_DEBUG , "cipher: %" PRIu64 "\n" , data -> cipher );
550
+ if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA1 ) {
551
+ strcpy (cipher , "SHA1" );
552
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
553
+ "HMAC-DRBG" : "HASH-DRBG" );
554
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA224 ) {
555
+ strcpy (cipher , "SHA224" );
556
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
557
+ "HMAC-DRBG" : "HASH-DRBG" );
558
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA256 ) {
559
+ strcpy (cipher , "SHA256" );
560
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
561
+ "HMAC-DRBG" : "HASH-DRBG" );
562
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA384 ) {
563
+ strcpy (cipher , "SHA384" );
564
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
565
+ "HMAC-DRBG" : "HASH-DRBG" );
566
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA512224 ) {
567
+ strcpy (cipher , "SHA512-224" );
568
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
569
+ "HMAC-DRBG" : "HASH-DRBG" );
570
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA512256 ) {
571
+ strcpy (cipher , "SHA512-256" );
572
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
573
+ "HMAC-DRBG" : "HASH-DRBG" );
574
+ } else if ((data -> cipher & ACVP_HASHMASK ) == ACVP_SHA512 ) {
575
+ strcpy (cipher , "SHA512" );
576
+ strcpy (drbg_name , ((data -> type & ACVP_DRBGMASK ) == ACVP_DRBGHMAC ) ?
577
+ "HMAC-DRBG" : "HASH-DRBG" );
578
+ } else if ((data -> cipher & ACVP_AESMASK ) == ACVP_AES128 ) {
579
+ strcpy (cipher , "AES-128-CTR" );
580
+ strcpy (drbg_name , "CTR-DRBG" );
581
+ } else if ((data -> cipher & ACVP_AESMASK ) == ACVP_AES192 ) {
582
+ strcpy (cipher , "AES-192-CTR" );
583
+ strcpy (drbg_name , "CTR-DRBG" );
584
+ } else if ((data -> cipher & ACVP_AESMASK ) == ACVP_AES256 ) {
585
+ strcpy (cipher , "AES-256-CTR" );
586
+ strcpy (drbg_name , "CTR-DRBG" );
587
+ } else {
588
+ logger (LOGGER_WARN , "DRBG with unhandled cipher detected\n" );
589
+ return - EFAULT ;
590
+ }
591
+ return 0 ;
592
+ }
593
+
594
+ static int openssl_drbg_generate (struct drbg_data * data , flags_t parsed_flags )
595
+ {
596
+
597
+ OSSL_PARAM params [4 ];
598
+ char cipher [50 ];
599
+ char drbg_name [50 ];
600
+ EVP_RAND * rand = NULL ;
601
+ EVP_RAND_CTX * ctx = NULL , * parent = NULL ;
602
+ int df = 0 ;
603
+ int ret = 0 ;
604
+ unsigned int strength = 256 ;
605
+ unsigned char * z ;
606
+ int res = 0 ;
607
+ (void )parsed_flags ;
608
+
609
+ if (openssl_get_drbg_name (data , cipher , drbg_name ) < 0 )
610
+ goto out ;
611
+ df = !!data -> df ;
612
+
613
+ /* Create the seed source */
614
+ rand = EVP_RAND_fetch (NULL , "TEST-RAND" , "-fips" );
615
+ CKNULL (rand , - ENOMEM );
616
+ parent = EVP_RAND_CTX_new (rand , NULL );
617
+ CKNULL (parent , - ENOMEM );
618
+ EVP_RAND_free (rand );
619
+ rand = NULL ;
620
+
621
+ params [0 ] = OSSL_PARAM_construct_uint (OSSL_RAND_PARAM_STRENGTH , & strength );
622
+ params [1 ] = OSSL_PARAM_construct_end ();
623
+ CKINT (EVP_RAND_CTX_set_params (parent , params ));
624
+ /* Get the DRBG */
625
+ rand = EVP_RAND_fetch (NULL , drbg_name , NULL );
626
+ CKNULL (rand , - ENOMEM );
627
+ ctx = EVP_RAND_CTX_new (rand , parent );
628
+ CKNULL (ctx , - ENOMEM );
629
+ /* Set the DRBG up */
630
+ strength = EVP_RAND_get_strength (ctx );
631
+ params [0 ] = OSSL_PARAM_construct_int (OSSL_DRBG_PARAM_USE_DF ,
632
+ (int * )(& df ));
633
+ if (!strcmp (drbg_name ,"CTR-DRBG" )){
634
+ params [1 ] = OSSL_PARAM_construct_utf8_string (OSSL_DRBG_PARAM_CIPHER ,
635
+ (char * )cipher , 0 );
636
+ }
637
+ else {
638
+ params [1 ] = OSSL_PARAM_construct_utf8_string (OSSL_DRBG_PARAM_DIGEST ,
639
+ (char * )cipher , strlen (cipher ));
640
+ }
641
+
642
+ params [2 ] = OSSL_PARAM_construct_utf8_string (OSSL_DRBG_PARAM_MAC , "HMAC" , 0 );
643
+ params [3 ] = OSSL_PARAM_construct_end ();
644
+
645
+ CKINT (EVP_RAND_CTX_set_params (ctx , params ));
646
+ /* Feed in the entropy and nonce */
647
+ logger_binary (LOGGER_DEBUG , data -> entropy .buf , data -> entropy .len , "entropy" );
648
+ logger_binary (LOGGER_DEBUG , data -> nonce .buf , data -> nonce .len , "nonce" );
649
+
650
+ params [0 ] = OSSL_PARAM_construct_octet_string (OSSL_RAND_PARAM_TEST_ENTROPY ,
651
+ (void * )data -> entropy .buf ,
652
+ data -> entropy .len );
653
+ params [1 ] = OSSL_PARAM_construct_octet_string (OSSL_RAND_PARAM_TEST_NONCE ,
654
+ (void * )data -> nonce .buf ,
655
+ data -> nonce .len );
656
+ params [2 ] = OSSL_PARAM_construct_end ();
657
+
658
+ if (!EVP_RAND_instantiate (parent , strength , 0 , NULL , 0 , params )) {
659
+ EVP_RAND_CTX_free (ctx );
660
+ goto out ;
661
+ }
662
+ /*
663
+ * Run the test
664
+ * A NULL personalisation string defaults to the built in so something
665
+ * non-NULL is needed if there is no personalisation string
666
+ */
667
+ logger_binary (LOGGER_DEBUG , data -> pers .buf , data -> pers .len ,
668
+ "personalization string" );
669
+
670
+ z = data -> pers .buf != NULL ? data -> pers .buf : (unsigned char * )"" ;
671
+ if (!EVP_RAND_instantiate (ctx , strength , data -> pr , z , data -> pers .len , NULL )) {
672
+ logger (LOGGER_DEBUG , "DRBG instantiation failed: %s\n" ,
673
+ ERR_error_string (ERR_get_error (), NULL ));
674
+ EVP_RAND_CTX_free (ctx );
675
+ goto out ;
676
+ }
677
+
678
+ if (data -> entropy_reseed .buffers [0 ].len ) {
679
+ logger_binary (LOGGER_DEBUG ,
680
+ data -> entropy_reseed .buffers [0 ].buf ,
681
+ data -> entropy_reseed .buffers [0 ].len ,
682
+ "entropy reseed" );
683
+
684
+ params [0 ] = OSSL_PARAM_construct_octet_string
685
+ (OSSL_RAND_PARAM_TEST_ENTROPY , data -> entropy_reseed .buffers [0 ].buf ,
686
+ data -> entropy_reseed .buffers [0 ].len );
687
+ params [1 ] = OSSL_PARAM_construct_end ();
688
+ CKINT (EVP_RAND_CTX_set_params (parent , params ));
689
+ if (data -> addtl_reseed .buffers [0 ].len ) {
690
+ logger_binary (LOGGER_DEBUG ,
691
+ data -> addtl_reseed .buffers [0 ].buf ,
692
+ data -> addtl_reseed .buffers [0 ].len ,
693
+ "addtl reseed" );
694
+ }
695
+ CKINT_O (EVP_RAND_reseed (ctx ,data -> pr ,
696
+ NULL , 0 ,
697
+ data -> addtl_reseed .buffers [0 ].buf ,
698
+ data -> addtl_reseed .buffers [0 ].len ));
699
+ }
700
+ if (data -> entropy_generate .buffers [0 ].len ) {
701
+ logger_binary (LOGGER_DEBUG ,
702
+ data -> entropy_generate .buffers [0 ].buf ,
703
+ data -> entropy_generate .buffers [0 ].len ,
704
+ "entropy generate 1" );
705
+ params [0 ] = OSSL_PARAM_construct_octet_string
706
+ (OSSL_RAND_PARAM_TEST_ENTROPY ,
707
+ data -> entropy_generate .buffers [0 ].buf ,
708
+ data -> entropy_generate .buffers [0 ].len );
709
+ params [1 ] = OSSL_PARAM_construct_end ();
710
+ CKINT (EVP_RAND_CTX_set_params (parent , params ));
711
+ }
712
+
713
+ logger_binary (LOGGER_DEBUG , data -> addtl_generate .buffers [0 ].buf ,
714
+ data -> addtl_generate .buffers [0 ].len , "addtl generate 1" );
715
+ CKINT (alloc_buf (data -> rnd_data_bits_len / 8 , & data -> random ));
716
+ CKINT_O_LOG (EVP_RAND_generate (ctx , data -> random .buf , data -> random .len , strength ,
717
+ data -> entropy_generate .buffers [0 ].len ?1 :0 ,
718
+ data -> addtl_generate .buffers [0 ].buf ,
719
+ data -> addtl_generate .buffers [0 ].len ),
720
+ "FIPS_drbg_generate failed\n" );
721
+ logger_binary (LOGGER_DEBUG , data -> random .buf , data -> random .len ,
722
+ "random tmp" );
723
+ if (data -> entropy_generate .buffers [1 ].len ) {
724
+ logger_binary (LOGGER_DEBUG , data -> entropy_generate .buffers [1 ].buf ,
725
+ data -> entropy_generate .buffers [1 ].len ,
726
+ "entropy generate 1" );
727
+ params [0 ] = OSSL_PARAM_construct_octet_string
728
+ (OSSL_RAND_PARAM_TEST_ENTROPY ,
729
+ data -> entropy_generate .buffers [1 ].buf ,
730
+ data -> entropy_generate .buffers [1 ].len );
731
+ params [1 ] = OSSL_PARAM_construct_end ();
732
+ CKINT (EVP_RAND_CTX_set_params (parent , params ));
733
+ }
734
+
735
+ logger_binary (LOGGER_DEBUG , data -> addtl_generate .buffers [1 ].buf ,
736
+ data -> addtl_generate .buffers [1 ].len , "addtl generate 2" );
737
+ CKINT_O_LOG (EVP_RAND_generate (ctx , data -> random .buf , data -> random .len , strength ,
738
+ data -> entropy_generate .buffers [1 ].len ?1 :0 ,
739
+ data -> addtl_generate .buffers [1 ].buf ,
740
+ data -> addtl_generate .buffers [1 ].len ),
741
+ "FIPS_drbg_generate failed\n" );
742
+ logger_binary (LOGGER_DEBUG , data -> random .buf , data -> random .len ,
743
+ "random" );
744
+
745
+ /* Verify the output */
746
+ res = 0 ;
747
+ out :
748
+ if (ctx ) {
749
+ EVP_RAND_uninstantiate (ctx );
750
+ EVP_RAND_CTX_free (ctx );
751
+ }
752
+ if (parent ) {
753
+ EVP_RAND_uninstantiate (parent );
754
+ EVP_RAND_CTX_free (parent );
755
+ }
756
+ if (rand )
757
+ EVP_RAND_free (rand );
758
+ return res ;
759
+ }
760
+
761
+ static struct drbg_backend openssl_drbg =
762
+ {
763
+ openssl_drbg_generate , /* drbg_generate */
764
+ };
765
+
766
+ ACVP_DEFINE_CONSTRUCTOR (openssl_drbg_backend )
767
+ static void openssl_drbg_backend (void )
768
+ {
769
+ register_drbg_impl (& openssl_drbg );
770
+ }
0 commit comments