Skip to content

Commit f7ae3f0

Browse files
sikkamukulsmuellerDD
authored andcommitted
Support_DRBG_OpenSSL3.0
Signed-off-by: Stephan Mueller <[email protected]>
1 parent 62073c9 commit f7ae3f0

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

backends/backend_openssl3.c

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,3 +539,232 @@ static void openssl_ecdh_backend(void)
539539
{
540540
register_ecdh_impl(&openssl_ecdh);
541541
}
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

Comments
 (0)